Staging: hv: netvsc: Get rid of the usage of the ext field in struct hv_device
[linux-2.6-block.git] / drivers / staging / hv / netvsc.c
index dc5e5c488e3b139e6bcb9bd83186b6b6ea9d615f..2bcc8b2b9b371e8aba7e588f3a35f8d99115bc1c 100644 (file)
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/netdevice.h>
 
-#include "hyperv.h"
 #include "hyperv_net.h"
 
 
-/* Globals */
-static const char *driver_name = "netvsc";
-
-/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
-static const struct hv_guid netvsc_device_type = {
-       .data = {
-               0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
-               0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
-       }
-};
-
-
 static struct netvsc_device *alloc_net_device(struct hv_device *device)
 {
        struct netvsc_device *net_device;
+       struct net_device *ndev = hv_get_drvdata(device);
 
        net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
        if (!net_device)
                return NULL;
 
-       /* Set to 2 to allow both inbound and outbound traffic */
-       atomic_cmpxchg(&net_device->refcnt, 0, 2);
 
+       net_device->destroy = false;
        net_device->dev = device;
-       device->ext = net_device;
+       net_device->ndev = ndev;
 
+       hv_set_drvdata(device, net_device);
        return net_device;
 }
 
-static void free_net_device(struct netvsc_device *device)
-{
-       WARN_ON(atomic_read(&device->refcnt) != 0);
-       device->dev->ext = NULL;
-       kfree(device);
-}
-
-
-/* Get the net device object iff exists and its refcount > 1 */
 static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
 {
        struct netvsc_device *net_device;
 
-       net_device = device->ext;
-       if (net_device && atomic_read(&net_device->refcnt) > 1)
-               atomic_inc(&net_device->refcnt);
-       else
+       net_device = hv_get_drvdata(device);
+       if (net_device && net_device->destroy)
                net_device = NULL;
 
        return net_device;
 }
 
-/* Get the net device object iff exists and its refcount > 0 */
 static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
 {
        struct netvsc_device *net_device;
 
-       net_device = device->ext;
-       if (net_device && atomic_read(&net_device->refcnt))
-               atomic_inc(&net_device->refcnt);
-       else
-               net_device = NULL;
+       net_device = hv_get_drvdata(device);
 
-       return net_device;
-}
-
-static void put_net_device(struct hv_device *device)
-{
-       struct netvsc_device *net_device;
-
-       net_device = device->ext;
-
-       atomic_dec(&net_device->refcnt);
-}
-
-static struct netvsc_device *release_outbound_net_device(
-               struct hv_device *device)
-{
-       struct netvsc_device *net_device;
-
-       net_device = device->ext;
-       if (net_device == NULL)
-               return NULL;
+       if (!net_device)
+               goto get_in_err;
 
-       /* Busy wait until the ref drop to 2, then set it to 1 */
-       while (atomic_cmpxchg(&net_device->refcnt, 2, 1) != 2)
-               udelay(100);
+       if (net_device->destroy &&
+               atomic_read(&net_device->num_outstanding_sends) == 0)
+               net_device = NULL;
 
+get_in_err:
        return net_device;
 }
 
-static struct netvsc_device *release_inbound_net_device(
-               struct hv_device *device)
-{
-       struct netvsc_device *net_device;
-
-       net_device = device->ext;
-       if (net_device == NULL)
-               return NULL;
-
-       /* Busy wait until the ref drop to 1, then set it to 0 */
-       while (atomic_cmpxchg(&net_device->refcnt, 1, 0) != 1)
-               udelay(100);
-
-       device->ext = NULL;
-       return net_device;
-}
 
 static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
 {
        struct nvsp_message *revoke_packet;
        int ret = 0;
+       struct net_device *ndev = net_device->ndev;
 
        /*
         * If we got a section count, it means we received a
@@ -170,9 +111,9 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
                 * have a leak rather than continue and a bugchk
                 */
                if (ret != 0) {
-                       dev_err(&net_device->dev->device, "unable to send "
-                               "revoke receive buffer to netvsp");
-                       return -1;
+                       netdev_err(ndev, "unable to send "
+                               "revoke receive buffer to netvsp\n");
+                       return ret;
                }
        }
 
@@ -185,9 +126,9 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
                 * rather than continue and a bugchk
                 */
                if (ret != 0) {
-                       dev_err(&net_device->dev->device,
-                                  "unable to teardown receive buffer's gpadl");
-                       return -1;
+                       netdev_err(ndev,
+                                  "unable to teardown receive buffer's gpadl\n");
+                       return ret;
                }
                net_device->recv_buf_gpadl_handle = 0;
        }
@@ -214,21 +155,20 @@ static int netvsc_init_recv_buf(struct hv_device *device)
        int t;
        struct netvsc_device *net_device;
        struct nvsp_message *init_packet;
+       struct net_device *ndev;
 
        net_device = get_outbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "unable to get net device..."
-                          "device being destroyed?");
-               return -1;
-       }
+       if (!net_device)
+               return -ENODEV;
+       ndev = net_device->ndev;
 
        net_device->recv_buf =
                (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
                                get_order(net_device->recv_buf_size));
        if (!net_device->recv_buf) {
-               dev_err(&device->device, "unable to allocate receive "
-                       "buffer of size %d", net_device->recv_buf_size);
-               ret = -1;
+               netdev_err(ndev, "unable to allocate receive "
+                       "buffer of size %d\n", net_device->recv_buf_size);
+               ret = -ENOMEM;
                goto cleanup;
        }
 
@@ -241,8 +181,8 @@ static int netvsc_init_recv_buf(struct hv_device *device)
                                    net_device->recv_buf_size,
                                    &net_device->recv_buf_gpadl_handle);
        if (ret != 0) {
-               dev_err(&device->device,
-                       "unable to establish receive buffer's gpadl");
+               netdev_err(ndev,
+                       "unable to establish receive buffer's gpadl\n");
                goto cleanup;
        }
 
@@ -265,8 +205,8 @@ static int netvsc_init_recv_buf(struct hv_device *device)
                               VM_PKT_DATA_INBAND,
                               VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
        if (ret != 0) {
-               dev_err(&device->device,
-                       "unable to send receive buffer's gpadl to netvsp");
+               netdev_err(ndev,
+                       "unable to send receive buffer's gpadl to netvsp\n");
                goto cleanup;
        }
 
@@ -277,11 +217,11 @@ static int netvsc_init_recv_buf(struct hv_device *device)
        /* Check the response */
        if (init_packet->msg.v1_msg.
            send_recv_buf_complete.status != NVSP_STAT_SUCCESS) {
-               dev_err(&device->device, "Unable to complete receive buffer "
-                          "initialzation with NetVsp - status %d",
+               netdev_err(ndev, "Unable to complete receive buffer "
+                          "initialization with NetVsp - status %d\n",
                           init_packet->msg.v1_msg.
                           send_recv_buf_complete.status);
-               ret = -1;
+               ret = -EINVAL;
                goto cleanup;
        }
 
@@ -293,7 +233,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
        net_device->recv_section = kmalloc(net_device->recv_section_cnt
                * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL);
        if (net_device->recv_section == NULL) {
-               ret = -1;
+               ret = -EINVAL;
                goto cleanup;
        }
 
@@ -309,7 +249,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
         */
        if (net_device->recv_section_cnt != 1 ||
            net_device->recv_section->offset != 0) {
-               ret = -1;
+               ret = -EINVAL;
                goto cleanup;
        }
 
@@ -319,7 +259,6 @@ cleanup:
        netvsc_destroy_recv_buf(net_device);
 
 exit:
-       put_net_device(device);
        return ret;
 }
 
@@ -330,13 +269,12 @@ static int netvsc_connect_vsp(struct hv_device *device)
        struct netvsc_device *net_device;
        struct nvsp_message *init_packet;
        int ndis_version;
+       struct net_device *ndev;
 
        net_device = get_outbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "unable to get net device..."
-                          "device being destroyed?");
-               return -1;
-       }
+       if (!net_device)
+               return -ENODEV;
+       ndev = net_device->ndev;
 
        init_packet = &net_device->channel_init_pkt;
 
@@ -366,13 +304,13 @@ static int netvsc_connect_vsp(struct hv_device *device)
 
        if (init_packet->msg.init_msg.init_complete.status !=
            NVSP_STAT_SUCCESS) {
-               ret = -1;
+               ret = -EINVAL;
                goto cleanup;
        }
 
        if (init_packet->msg.init_msg.init_complete.
            negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) {
-               ret = -1;
+               ret = -EPROTO;
                goto cleanup;
        }
        /* Send the ndis version */
@@ -393,16 +331,13 @@ static int netvsc_connect_vsp(struct hv_device *device)
                                sizeof(struct nvsp_message),
                                (unsigned long)init_packet,
                                VM_PKT_DATA_INBAND, 0);
-       if (ret != 0) {
-               ret = -1;
+       if (ret != 0)
                goto cleanup;
-       }
 
        /* Post the big receive buffer to NetVSP */
        ret = netvsc_init_recv_buf(device);
 
 cleanup:
-       put_net_device(device);
        return ret;
 }
 
@@ -418,29 +353,37 @@ int netvsc_device_remove(struct hv_device *device)
 {
        struct netvsc_device *net_device;
        struct hv_netvsc_packet *netvsc_packet, *pos;
+       unsigned long flags;
 
-       /* Stop outbound traffic ie sends and receives completions */
-       net_device = release_outbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "No net device present!!");
-               return -1;
-       }
+       net_device = hv_get_drvdata(device);
+       spin_lock_irqsave(&device->channel->inbound_lock, flags);
+       net_device->destroy = true;
+       spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 
        /* Wait for all send completions */
        while (atomic_read(&net_device->num_outstanding_sends)) {
-               dev_err(&device->device,
-                       "waiting for %d requests to complete...",
+               dev_info(&device->device,
+                       "waiting for %d requests to complete...\n",
                        atomic_read(&net_device->num_outstanding_sends));
                udelay(100);
        }
 
        netvsc_disconnect_vsp(net_device);
 
-       /* Stop inbound traffic ie receives and sends completions */
-       net_device = release_inbound_net_device(device);
+       /*
+        * Since we have already drained, we don't need to busy wait
+        * as was done in final_release_stor_device()
+        * Note that we cannot set the ext pointer to NULL until
+        * we have drained - to drain the outgoing packets, we need to
+        * allow incoming packets.
+        */
+
+       spin_lock_irqsave(&device->channel->inbound_lock, flags);
+       hv_set_drvdata(device, NULL);
+       spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 
        /* At this point, no one should be accessing netDevice except in here */
-       dev_notice(&device->device, "net device safe to remove");
+       dev_notice(&device->device, "net device safe to remove\n");
 
        /* Now, we can close the channel safely */
        vmbus_close(device->channel);
@@ -452,7 +395,7 @@ int netvsc_device_remove(struct hv_device *device)
                kfree(netvsc_packet);
        }
 
-       free_net_device(net_device);
+       kfree(net_device);
        return 0;
 }
 
@@ -462,13 +405,12 @@ static void netvsc_send_completion(struct hv_device *device,
        struct netvsc_device *net_device;
        struct nvsp_message *nvsp_packet;
        struct hv_netvsc_packet *nvsc_packet;
+       struct net_device *ndev;
 
        net_device = get_inbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "unable to get net device..."
-                          "device being destroyed?");
+       if (!net_device)
                return;
-       }
+       ndev = net_device->ndev;
 
        nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
                        (packet->offset8 << 3));
@@ -494,11 +436,10 @@ static void netvsc_send_completion(struct hv_device *device,
 
                atomic_dec(&net_device->num_outstanding_sends);
        } else {
-               dev_err(&device->device, "Unknown send completion packet type- "
-                          "%d received!!", nvsp_packet->hdr.msg_type);
+               netdev_err(ndev, "Unknown send completion packet type- "
+                          "%d received!!\n", nvsp_packet->hdr.msg_type);
        }
 
-       put_net_device(device);
 }
 
 int netvsc_send(struct hv_device *device,
@@ -506,15 +447,13 @@ int netvsc_send(struct hv_device *device,
 {
        struct netvsc_device *net_device;
        int ret = 0;
-
        struct nvsp_message sendMessage;
+       struct net_device *ndev;
 
        net_device = get_outbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "net device (%p) shutting down..."
-                          "ignoring outbound packets", net_device);
-               return -2;
-       }
+       if (!net_device)
+               return -ENODEV;
+       ndev = net_device->ndev;
 
        sendMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
        if (packet->is_data_pkt) {
@@ -547,11 +486,11 @@ int netvsc_send(struct hv_device *device,
        }
 
        if (ret != 0)
-               dev_err(&device->device, "Unable to send packet %p ret %d",
+               netdev_err(ndev, "Unable to send packet %p ret %d\n",
                           packet, ret);
+       else
+               atomic_inc(&net_device->num_outstanding_sends);
 
-       atomic_inc(&net_device->num_outstanding_sends);
-       put_net_device(device);
        return ret;
 }
 
@@ -561,6 +500,10 @@ static void netvsc_send_recv_completion(struct hv_device *device,
        struct nvsp_message recvcompMessage;
        int retries = 0;
        int ret;
+       struct net_device *ndev;
+       struct netvsc_device *net_device = hv_get_drvdata(device);
+
+       ndev = net_device->ndev;
 
        recvcompMessage.hdr.msg_type =
                                NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
@@ -577,23 +520,23 @@ retry_send_cmplt:
        if (ret == 0) {
                /* success */
                /* no-op */
-       } else if (ret == -1) {
+       } else if (ret == -EAGAIN) {
                /* no more room...wait a bit and attempt to retry 3 times */
                retries++;
-               dev_err(&device->device, "unable to send receive completion pkt"
-                       " (tid %llx)...retrying %d", transaction_id, retries);
+               netdev_err(ndev, "unable to send receive completion pkt"
+                       " (tid %llx)...retrying %d\n", transaction_id, retries);
 
                if (retries < 4) {
                        udelay(100);
                        goto retry_send_cmplt;
                } else {
-                       dev_err(&device->device, "unable to send receive "
-                               "completion pkt (tid %llx)...give up retrying",
+                       netdev_err(ndev, "unable to send receive "
+                               "completion pkt (tid %llx)...give up retrying\n",
                                transaction_id);
                }
        } else {
-               dev_err(&device->device, "unable to send receive "
-                       "completion pkt - %llx", transaction_id);
+               netdev_err(ndev, "unable to send receive "
+                       "completion pkt - %llx\n", transaction_id);
        }
 }
 
@@ -606,6 +549,7 @@ static void netvsc_receive_completion(void *context)
        u64 transaction_id = 0;
        bool fsend_receive_comp = false;
        unsigned long flags;
+       struct net_device *ndev;
 
        /*
         * Even though it seems logical to do a GetOutboundNetDevice() here to
@@ -613,11 +557,9 @@ static void netvsc_receive_completion(void *context)
         * since we may have disable outbound traffic already.
         */
        net_device = get_inbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "unable to get net device..."
-                          "device being destroyed?");
+       if (!net_device)
                return;
-       }
+       ndev = net_device->ndev;
 
        /* Overloading use of the lock. */
        spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
@@ -644,7 +586,6 @@ static void netvsc_receive_completion(void *context)
        if (fsend_receive_comp)
                netvsc_send_recv_completion(device, transaction_id);
 
-       put_net_device(device);
 }
 
 static void netvsc_receive(struct hv_device *device,
@@ -661,24 +602,22 @@ static void netvsc_receive(struct hv_device *device,
        int i, j;
        int count = 0, bytes_remain = 0;
        unsigned long flags;
+       struct net_device *ndev;
 
        LIST_HEAD(listHead);
 
        net_device = get_inbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "unable to get net device..."
-                          "device being destroyed?");
+       if (!net_device)
                return;
-       }
+       ndev = net_device->ndev;
 
        /*
         * All inbound packets other than send completion should be xfer page
         * packet
         */
        if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) {
-               dev_err(&device->device, "Unknown packet type received - %d",
+               netdev_err(ndev, "Unknown packet type received - %d\n",
                           packet->type);
-               put_net_device(device);
                return;
        }
 
@@ -688,19 +627,17 @@ static void netvsc_receive(struct hv_device *device,
        /* Make sure this is a valid nvsp packet */
        if (nvsp_packet->hdr.msg_type !=
            NVSP_MSG1_TYPE_SEND_RNDIS_PKT) {
-               dev_err(&device->device, "Unknown nvsp packet type received-"
-                       " %d", nvsp_packet->hdr.msg_type);
-               put_net_device(device);
+               netdev_err(ndev, "Unknown nvsp packet type received-"
+                       " %d\n", nvsp_packet->hdr.msg_type);
                return;
        }
 
        vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet;
 
        if (vmxferpage_packet->xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID) {
-               dev_err(&device->device, "Invalid xfer page set id - "
-                          "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
+               netdev_err(ndev, "Invalid xfer page set id - "
+                          "expecting %x got %x\n", NETVSC_RECEIVE_BUFFER_ID,
                           vmxferpage_packet->xfer_pageset_id);
-               put_net_device(device);
                return;
        }
 
@@ -724,8 +661,8 @@ static void netvsc_receive(struct hv_device *device,
         * some of the xfer page packet ranges...
         */
        if (count < 2) {
-               dev_err(&device->device, "Got only %d netvsc pkt...needed "
-                       "%d pkts. Dropping this xfer page packet completely!",
+               netdev_err(ndev, "Got only %d netvsc pkt...needed "
+                       "%d pkts. Dropping this xfer page packet completely!\n",
                        count, vmxferpage_packet->range_cnt + 1);
 
                /* Return it to the freelist */
@@ -740,7 +677,6 @@ static void netvsc_receive(struct hv_device *device,
                netvsc_send_recv_completion(device,
                                            vmxferpage_packet->d.trans_id);
 
-               put_net_device(device);
                return;
        }
 
@@ -752,8 +688,8 @@ static void netvsc_receive(struct hv_device *device,
        xferpage_packet->count = count - 1;
 
        if (xferpage_packet->count != vmxferpage_packet->range_cnt) {
-               dev_err(&device->device, "Needed %d netvsc pkts to satisy "
-                       "this xfer page...got %d",
+               netdev_err(ndev, "Needed %d netvsc pkts to satisfy "
+                       "this xfer page...got %d\n",
                        vmxferpage_packet->range_cnt, xferpage_packet->count);
        }
 
@@ -828,7 +764,6 @@ static void netvsc_receive(struct hv_device *device,
                                completion.recv.recv_completion_ctx);
        }
 
-       put_net_device(device);
 }
 
 static void netvsc_channel_cb(void *context)
@@ -842,6 +777,7 @@ static void netvsc_channel_cb(void *context)
        struct vmpacket_descriptor *desc;
        unsigned char *buffer;
        int bufferlen = NETVSC_PACKET_SIZE;
+       struct net_device *ndev;
 
        packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char),
                         GFP_ATOMIC);
@@ -850,11 +786,9 @@ static void netvsc_channel_cb(void *context)
        buffer = packet;
 
        net_device = get_inbound_net_device(device);
-       if (!net_device) {
-               dev_err(&device->device, "net device (%p) shutting down..."
-                          "ignoring inbound packets", net_device);
+       if (!net_device)
                goto out;
-       }
+       ndev = net_device->ndev;
 
        do {
                ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen,
@@ -872,7 +806,7 @@ static void netvsc_channel_cb(void *context)
                                        break;
 
                                default:
-                                       dev_err(&device->device,
+                                       netdev_err(ndev,
                                                   "unhandled packet type %d, "
                                                   "tid %llx len %d\n",
                                                   desc->type, request_id,
@@ -896,14 +830,14 @@ static void netvsc_channel_cb(void *context)
 
                                break;
                        }
-               } else if (ret == -2) {
+               } else if (ret == -ENOBUFS) {
                        /* Handle large packet */
                        buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
                        if (buffer == NULL) {
                                /* Try again next time around */
-                               dev_err(&device->device,
+                               netdev_err(ndev,
                                           "unable to allocate buffer of size "
-                                          "(%d)!!", bytes_recvd);
+                                          "(%d)!!\n", bytes_recvd);
                                break;
                        }
 
@@ -911,7 +845,6 @@ static void netvsc_channel_cb(void *context)
                }
        } while (1);
 
-       put_net_device(device);
 out:
        kfree(buffer);
        return;
@@ -929,13 +862,23 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
        ((struct netvsc_device_info *)additional_info)->ring_size;
        struct netvsc_device *net_device;
        struct hv_netvsc_packet *packet, *pos;
+       struct net_device *ndev;
 
        net_device = alloc_net_device(device);
        if (!net_device) {
-               ret = -1;
+               ret = -ENOMEM;
                goto cleanup;
        }
 
+       /*
+        * Coming into this function, struct net_device * is
+        * registered as the driver private data.
+        * In alloc_net_device(), we register struct netvsc_device *
+        * as the driver private data and stash away struct net_device *
+        * in struct netvsc_device *.
+        */
+       ndev = net_device->ndev;
+
        /* Initialize the NetVSC channel extension */
        net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
        spin_lock_init(&net_device->recv_pkt_list_lock);
@@ -960,20 +903,18 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
                         netvsc_channel_cb, device);
 
        if (ret != 0) {
-               dev_err(&device->device, "unable to open channel: %d", ret);
-               ret = -1;
+               netdev_err(ndev, "unable to open channel: %d\n", ret);
                goto cleanup;
        }
 
        /* Channel is opened */
-       pr_info("hv_netvsc channel opened successfully");
+       pr_info("hv_netvsc channel opened successfully\n");
 
        /* Connect with the NetVsp */
        ret = netvsc_connect_vsp(device);
        if (ret != 0) {
-               dev_err(&device->device,
-                       "unable to connect to NetVSP - %d", ret);
-               ret = -1;
+               netdev_err(ndev,
+                       "unable to connect to NetVSP - %d\n", ret);
                goto close;
        }
 
@@ -993,23 +934,8 @@ cleanup:
                        kfree(packet);
                }
 
-               release_outbound_net_device(device);
-               release_inbound_net_device(device);
-
-               free_net_device(net_device);
+               kfree(net_device);
        }
 
        return ret;
 }
-
-/*
- * netvsc_initialize - Main entry point
- */
-int netvsc_initialize(struct hv_driver *drv)
-{
-
-       drv->name = driver_name;
-       memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid));
-
-       return 0;
-}