]> Pileus Git - ~andy/linux/blobdiff - drivers/net/hyperv/netvsc.c
Merge tag 'for_3.7-fixes-pm' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman...
[~andy/linux] / drivers / net / hyperv / netvsc.c
index 4a1a5f58fa73ffd7899429bcaf28062e29f83dc3..1cd77483da50114c2c309ab70a69dff134c3a919 100644 (file)
@@ -558,7 +558,7 @@ int netvsc_send(struct hv_device *device,
 }
 
 static void netvsc_send_recv_completion(struct hv_device *device,
-                                       u64 transaction_id)
+                                       u64 transaction_id, u32 status)
 {
        struct nvsp_message recvcompMessage;
        int retries = 0;
@@ -571,9 +571,7 @@ static void netvsc_send_recv_completion(struct hv_device *device,
        recvcompMessage.hdr.msg_type =
                                NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
 
-       /* FIXME: Pass in the status */
-       recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status =
-               NVSP_STAT_SUCCESS;
+       recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status = status;
 
 retry_send_cmplt:
        /* Send the completion */
@@ -613,6 +611,7 @@ static void netvsc_receive_completion(void *context)
        bool fsend_receive_comp = false;
        unsigned long flags;
        struct net_device *ndev;
+       u32 status = NVSP_STAT_NONE;
 
        /*
         * Even though it seems logical to do a GetOutboundNetDevice() here to
@@ -627,6 +626,9 @@ static void netvsc_receive_completion(void *context)
        /* Overloading use of the lock. */
        spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
 
+       if (packet->status != NVSP_STAT_SUCCESS)
+               packet->xfer_page_pkt->status = NVSP_STAT_FAIL;
+
        packet->xfer_page_pkt->count--;
 
        /*
@@ -636,6 +638,7 @@ static void netvsc_receive_completion(void *context)
        if (packet->xfer_page_pkt->count == 0) {
                fsend_receive_comp = true;
                transaction_id = packet->completion.recv.recv_completion_tid;
+               status = packet->xfer_page_pkt->status;
                list_add_tail(&packet->xfer_page_pkt->list_ent,
                              &net_device->recv_pkt_list);
 
@@ -647,7 +650,7 @@ static void netvsc_receive_completion(void *context)
 
        /* Send a receive completion for the xfer page packet */
        if (fsend_receive_comp)
-               netvsc_send_recv_completion(device, transaction_id);
+               netvsc_send_recv_completion(device, transaction_id, status);
 
 }
 
@@ -736,7 +739,8 @@ static void netvsc_receive(struct hv_device *device,
                                       flags);
 
                netvsc_send_recv_completion(device,
-                                           vmxferpage_packet->d.trans_id);
+                                           vmxferpage_packet->d.trans_id,
+                                           NVSP_STAT_FAIL);
 
                return;
        }
@@ -744,6 +748,7 @@ static void netvsc_receive(struct hv_device *device,
        /* Remove the 1st packet to represent the xfer page packet itself */
        xferpage_packet = (struct xferpage_packet *)listHead.next;
        list_del(&xferpage_packet->list_ent);
+       xferpage_packet->status = NVSP_STAT_SUCCESS;
 
        /* This is how much we can satisfy */
        xferpage_packet->count = count - 1;
@@ -760,6 +765,7 @@ static void netvsc_receive(struct hv_device *device,
                list_del(&netvsc_packet->list_ent);
 
                /* Initialize the netvsc packet */
+               netvsc_packet->status = NVSP_STAT_SUCCESS;
                netvsc_packet->xfer_page_pkt = xferpage_packet;
                netvsc_packet->completion.recv.recv_completion =
                                        netvsc_receive_completion;
@@ -904,9 +910,7 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
        INIT_LIST_HEAD(&net_device->recv_pkt_list);
 
        for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
-               packet = kzalloc(sizeof(struct hv_netvsc_packet) +
-                                (NETVSC_RECEIVE_SG_COUNT *
-                                 sizeof(struct hv_page_buffer)), GFP_KERNEL);
+               packet = kzalloc(sizeof(struct hv_netvsc_packet), GFP_KERNEL);
                if (!packet)
                        break;