{
struct cma_work *work = context;
struct rdma_route *route;
+ struct rdma_id_private *id_priv = work->id;
route = &work->id->id.route;
route->num_paths = 1;
*route->path_rec = *path_rec;
} else {
+ if (status != -EBUSY && status != -ETIMEDOUT)
+ if (printk_ratelimit())
+ cma_warn(id_priv, "bad status %d from path query\n", status);
work->old_state = RDMA_CM_ROUTE_QUERY;
work->new_state = RDMA_CM_ADDR_RESOLVED;
work->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
query = mad_buf->context[0];
if (query->callback) {
- if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
- query->callback(query,
- mad_recv_wc->recv_buf.mad->mad_hdr.status ?
- -EINVAL : 0,
+ if (mad_recv_wc->wc->status == IB_WC_SUCCESS) {
+ int mad_status = mad_recv_wc->recv_buf.mad->mad_hdr.status;
+ int status = 0;
+
+ if ((mad_status & IB_MGMT_MAD_STATUS_BUSY) && (mad_status & \
+ ~(IB_MGMT_MAD_STATUS_BUSY|IB_MGMT_MAD_STATUS_REDIRECT_REQD)) == 0)
+ status = -EBUSY;
+ else if (mad_status)
+ status = -EINVAL;
+ query->callback(query, status,
(struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
- else
+ } else
query->callback(query, -EIO, NULL);
}