]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/core/mad.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[linux-2.6-omap-h63xx.git] / drivers / infiniband / core / mad.c
index 6b8faca02f8a169c779d56f547e5308bb398930c..1adf2efd3cb392b84800241ccca3fbc4d1ffb4ac 100644 (file)
@@ -701,7 +701,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
        }
 
        /* Check to post send on QP or process locally */
-       if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD)
+       if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD &&
+           smi_check_local_returning_smp(smp, device) == IB_SMI_DISCARD)
                goto out;
 
        local = kmalloc(sizeof *local, GFP_ATOMIC);
@@ -746,14 +747,15 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
                break;
        case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
                kmem_cache_free(ib_mad_cache, mad_priv);
-               break;
+               kfree(local);
+               ret = 1;
+               goto out;
        case IB_MAD_RESULT_SUCCESS:
                /* Treat like an incoming receive MAD */
                port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
                                            mad_agent_priv->agent.port_num);
                if (port_priv) {
-                       mad_priv->mad.mad.mad_hdr.tid =
-                               ((struct ib_mad *)smp)->mad_hdr.tid;
+                       memcpy(&mad_priv->mad.mad, smp, sizeof(struct ib_mad));
                        recv_mad_agent = find_mad_agent(port_priv,
                                                        &mad_priv->mad.mad);
                }
@@ -1100,7 +1102,9 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
                mad_send_wr->tid = ((struct ib_mad_hdr *) send_buf->mad)->tid;
                /* Timeout will be updated after send completes */
                mad_send_wr->timeout = msecs_to_jiffies(send_buf->timeout_ms);
-               mad_send_wr->retries = send_buf->retries;
+               mad_send_wr->max_retries = send_buf->retries;
+               mad_send_wr->retries_left = send_buf->retries;
+               send_buf->retries = 0;
                /* Reference for work request to QP + response */
                mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0);
                mad_send_wr->status = IB_WC_SUCCESS;
@@ -1842,16 +1846,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
 {
        struct ib_mad_qp_info *qp_info;
        struct ib_mad_private_header *mad_priv_hdr;
-       struct ib_mad_private *recv, *response;
+       struct ib_mad_private *recv, *response = NULL;
        struct ib_mad_list_head *mad_list;
        struct ib_mad_agent_private *mad_agent;
        int port_num;
 
-       response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
-       if (!response)
-               printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
-                      "for response buffer\n");
-
        mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
        qp_info = mad_list->mad_queue->qp_info;
        dequeue_mad(mad_list);
@@ -1879,6 +1878,13 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
        if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
                goto out;
 
+       response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
+       if (!response) {
+               printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
+                      "for response buffer\n");
+               goto out;
+       }
+
        if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH)
                port_num = wc->port_num;
        else
@@ -1914,12 +1920,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
                        response->header.recv_wc.recv_buf.mad = &response->mad.mad;
                        response->header.recv_wc.recv_buf.grh = &response->grh;
 
-                       if (!agent_send_response(&response->mad.mad,
-                                                &response->grh, wc,
-                                                port_priv->device,
-                                                smi_get_fwd_port(&recv->mad.smp),
-                                                qp_info->qp->qp_num))
-                               response = NULL;
+                       agent_send_response(&response->mad.mad,
+                                           &response->grh, wc,
+                                           port_priv->device,
+                                           smi_get_fwd_port(&recv->mad.smp),
+                                           qp_info->qp->qp_num);
 
                        goto out;
                }
@@ -1930,15 +1935,6 @@ local:
        if (port_priv->device->process_mad) {
                int ret;
 
-               if (!response) {
-                       printk(KERN_ERR PFX "No memory for response MAD\n");
-                       /*
-                        * Is it better to assume that
-                        * it wouldn't be processed ?
-                        */
-                       goto out;
-               }
-
                ret = port_priv->device->process_mad(port_priv->device, 0,
                                                     port_priv->port_num,
                                                     wc, &recv->grh,
@@ -2281,8 +2277,6 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)
 
        /* Empty wait list to prevent receives from finding a request */
        list_splice_init(&mad_agent_priv->wait_list, &cancel_list);
-       /* Empty local completion list as well */
-       list_splice_init(&mad_agent_priv->local_list, &cancel_list);
        spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 
        /* Report all cancelled requests */
@@ -2444,9 +2438,12 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr)
 {
        int ret;
 
-       if (!mad_send_wr->retries--)
+       if (!mad_send_wr->retries_left)
                return -ETIMEDOUT;
 
+       mad_send_wr->retries_left--;
+       mad_send_wr->send_buf.retries++;
+
        mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms);
 
        if (mad_send_wr->mad_agent_priv->agent.rmpp_version) {
@@ -2998,7 +2995,6 @@ static int __init ib_mad_init_module(void)
                                         sizeof(struct ib_mad_private),
                                         0,
                                         SLAB_HWCACHE_ALIGN,
-                                        NULL,
                                         NULL);
        if (!ib_mad_cache) {
                printk(KERN_ERR PFX "Couldn't create ib_mad cache\n");