]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/hyperv/netvsc.c
Merge branches 'hidraw', 'magicmouse', 'multitouch', 'roccat', 'suspend-fixes' and...
[karo-tx-linux.git] / drivers / net / hyperv / netvsc.c
index 8b919471472fb1dba4d34ffcf0bfe5b4c723af7b..0c569831db5aeb0de77ef9a4d81d6d7e7f3281b8 100644 (file)
@@ -42,6 +42,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
        if (!net_device)
                return NULL;
 
+       init_waitqueue_head(&net_device->wait_drain);
        net_device->start_remove = false;
        net_device->destroy = false;
        net_device->dev = device;
@@ -387,12 +388,8 @@ int netvsc_device_remove(struct hv_device *device)
        spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 
        /* Wait for all send completions */
-       while (atomic_read(&net_device->num_outstanding_sends)) {
-               dev_info(&device->device,
-                       "waiting for %d requests to complete...\n",
-                       atomic_read(&net_device->num_outstanding_sends));
-               udelay(100);
-       }
+       wait_event(net_device->wait_drain,
+                  atomic_read(&net_device->num_outstanding_sends) == 0);
 
        netvsc_disconnect_vsp(net_device);
 
@@ -486,6 +483,9 @@ static void netvsc_send_completion(struct hv_device *device,
                num_outstanding_sends =
                        atomic_dec_return(&net_device->num_outstanding_sends);
 
+               if (net_device->destroy && num_outstanding_sends == 0)
+                       wake_up(&net_device->wait_drain);
+
                if (netif_queue_stopped(ndev) && !net_device->start_remove &&
                        (hv_ringbuf_avail_percent(&device->channel->outbound)
                        > RING_AVAIL_PERCENT_HIWATER ||