Address Greg's VmBus audit comments: 1) Leverage driver_data field in struct hv_vmbus_device_id to simplify driver code. 2) Make the util driver conform to the Linux Driver Model. 3) Get rid of the ext field in struct hv_device by using the driver specific data functionality. 4) Other general cleanup. Regards, K. Y
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 01/25] Staging: hv: vmbus: Rename vmbus_child_device_create
The vmbus devices are NOT child devices; rename vmbus_child_device_create
to reflect this.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |    2 +-
 drivers/staging/hv/hyperv_vmbus.h |    2 +-
 drivers/staging/hv/vmbus_drv.c    |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/hv/channel_mgmt.c
b/drivers/staging/hv/channel_mgmt.c
index 11beb41..f99b944 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -383,7 +383,7 @@ static void vmbus_process_offer(struct work_struct *work)
 	 * We need to set the DeviceObject field before calling
 	 * vmbus_child_dev_add()
 	 */
-	newchannel->device_obj = vmbus_child_device_create(
+	newchannel->device_obj = vmbus_device_create(
 		&newchannel->offermsg.offer.if_type,
 		&newchannel->offermsg.offer.if_instance,
 		newchannel);
diff --git a/drivers/staging/hv/hyperv_vmbus.h
b/drivers/staging/hv/hyperv_vmbus.h
index 16ca90d..e97e2cf 100644
--- a/drivers/staging/hv/hyperv_vmbus.h
+++ b/drivers/staging/hv/hyperv_vmbus.h
@@ -601,7 +601,7 @@ extern struct vmbus_connection vmbus_connection;
 
 /* General vmbus interface */
 
-struct hv_device *vmbus_child_device_create(uuid_le *type,
+struct hv_device *vmbus_device_create(uuid_le *type,
 					 uuid_le *instance,
 					 struct vmbus_channel *channel);
 
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index c0f3b7a..382baee 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -594,10 +594,10 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver)
 EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
 
 /*
- * vmbus_child_device_create - Creates and registers a new child device
+ * vmbus_device_create - Creates and registers a new child device
  * on the vmbus.
  */
-struct hv_device *vmbus_child_device_create(uuid_le *type,
+struct hv_device *vmbus_device_create(uuid_le *type,
 					    uuid_le *instance,
 					    struct vmbus_channel *channel)
 {
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 03/25] Staging: hv: vmbus: Rename vmbus_child_device_unregister
The vmbus devices are NOT child devices; rename vmbus_child_device_unregister
to reflect this.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |    2 +-
 drivers/staging/hv/hyperv_vmbus.h |    2 +-
 drivers/staging/hv/vmbus_drv.c    |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/hv/channel_mgmt.c
b/drivers/staging/hv/channel_mgmt.c
index a927046..60ce1d1 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -333,7 +333,7 @@ static void vmbus_process_rescind_offer(struct work_struct
*work)
 						     struct vmbus_channel,
 						     work);
 
-	vmbus_child_device_unregister(channel->device_obj);
+	vmbus_device_unregister(channel->device_obj);
 }
 
 /*
diff --git a/drivers/staging/hv/hyperv_vmbus.h
b/drivers/staging/hv/hyperv_vmbus.h
index b2dfcd6..3d2d836 100644
--- a/drivers/staging/hv/hyperv_vmbus.h
+++ b/drivers/staging/hv/hyperv_vmbus.h
@@ -606,7 +606,7 @@ struct hv_device *vmbus_device_create(uuid_le *type,
 					 struct vmbus_channel *channel);
 
 int vmbus_device_register(struct hv_device *child_device_obj);
-void vmbus_child_device_unregister(struct hv_device *device_obj);
+void vmbus_device_unregister(struct hv_device *device_obj);
 
 /* static void */
 /* VmbusChildDeviceDestroy( */
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 6d54ea1..375e451 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -650,10 +650,10 @@ int vmbus_device_register(struct hv_device
*child_device_obj)
 }
 
 /*
- * vmbus_child_device_unregister - Remove the specified child device
+ * vmbus_device_unregister - Remove the specified child device
  * from the vmbus.
  */
-void vmbus_child_device_unregister(struct hv_device *device_obj)
+void vmbus_device_unregister(struct hv_device *device_obj)
 {
 	/*
 	 * Kick off the process of unregistering the device.
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 04/25] Staging: hv: vmbus: Cleanup dated comments in channel_mgmt.c
Cleanup dated comments in channel_mgmt.c.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/hv/channel_mgmt.c
b/drivers/staging/hv/channel_mgmt.c
index 60ce1d1..c68e5fa 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -433,9 +433,6 @@ static void vmbus_process_offer(struct work_struct *work)
 /*
  * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
  *
- * We ignore all offers except network and storage offers. For each network and
- * storage offers, we create a channel object and queue a work item to the
- * channel object to process the offer synchronously
  */
 static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
 {
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 06/25] Staging: hv: storvsc: Use the driver_data to identify ide
Use the driver_data to identify ide devices in storvsc_probe().
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index fff1e5b..e2c63e5 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1366,10 +1366,12 @@ static struct scsi_host_template scsi_driver = {
 static const struct hv_vmbus_device_id id_table[] = {
 	/* SCSI guid */
 	{ VMBUS_DEVICE(0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
-		       0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) },
+		       0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
+	  .driver_data = 0 },
 	/* IDE guid */
 	{ VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
-		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) },
+		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
+	  .driver_data = 1 },
 	{ },
 };
 
@@ -1387,15 +1389,10 @@ static int storvsc_probe(struct hv_device *device,
 	struct Scsi_Host *host;
 	struct hv_host_device *host_dev;
 	struct storvsc_device_info device_info;
-	bool dev_is_ide;
+	bool dev_is_ide = ((dev_id->driver_data == 1) ? true : false);
 	int path = 0;
 	int target = 0;
 
-	if (!memcmp(&device->dev_type.b, id_table[1].guid, sizeof(uuid_le)))
-		dev_is_ide = true;
-	else
-		dev_is_ide = false;
-
 	host = scsi_host_alloc(&scsi_driver,
 			       sizeof(struct hv_host_device));
 	if (!host)
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 07/25] Staging: hv: vmbus: Change the signature of struct hv_driver remove() function
In preparation for leveraging the driver_data in  struct
hv_vmbus_device_id, change the signature of struct hv_driver remove() function.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/hv_mouse.c    |    3 ++-
 drivers/staging/hv/hv_util.c     |    3 ++-
 drivers/staging/hv/hyperv.h      |    2 +-
 drivers/staging/hv/netvsc_drv.c  |    3 ++-
 drivers/staging/hv/storvsc_drv.c |    3 ++-
 drivers/staging/hv/vmbus_drv.c   |    9 ++++++++-
 6 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
index 5ff8a03..d60f287 100644
--- a/drivers/staging/hv/hv_mouse.c
+++ b/drivers/staging/hv/hv_mouse.c
@@ -847,7 +847,8 @@ static int mousevsc_probe(struct hv_device *dev,
 	return 0;
 }
 
-static int mousevsc_remove(struct hv_device *dev)
+static int mousevsc_remove(struct hv_device *dev,
+				const struct hv_vmbus_device_id *dev_id)
 {
 	struct input_device_context *input_dev_ctx;
 	int ret;
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index d9460fdd..661631d 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -245,7 +245,8 @@ static int util_probe(struct hv_device *dev,
 	return 0;
 }
 
-static int util_remove(struct hv_device *dev)
+static int util_remove(struct hv_device *dev,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	return 0;
 }
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
index caa3a7b..cf02ae1 100644
--- a/drivers/staging/hv/hyperv.h
+++ b/drivers/staging/hv/hyperv.h
@@ -811,7 +811,7 @@ struct hv_driver {
 	struct device_driver driver;
 
 	int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *);
-	int (*remove)(struct hv_device *);
+	int (*remove)(struct hv_device *, const struct hv_vmbus_device_id *);
 	void (*shutdown)(struct hv_device *);
 
 };
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index d06cde2..d0189a3 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -384,7 +384,8 @@ out:
 	return ret;
 }
 
-static int netvsc_remove(struct hv_device *dev)
+static int netvsc_remove(struct hv_device *dev,
+			const struct hv_vmbus_device_id *dev_id)
 {
 	struct net_device *net = dev_get_drvdata(&dev->device);
 	struct net_device_context *ndev_ctx;
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index e2c63e5..e5da758 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1021,7 +1021,8 @@ static unsigned int copy_to_bounce_buffer(struct
scatterlist *orig_sgl,
 }
 
 
-static int storvsc_remove(struct hv_device *dev)
+static int storvsc_remove(struct hv_device *dev,
+				const struct hv_vmbus_device_id *dev_id)
 {
 	struct Scsi_Host *host = dev_get_drvdata(&dev->device);
 	struct hv_host_device *host_dev diff --git a/drivers/staging/hv/vmbus_drv.c
b/drivers/staging/hv/vmbus_drv.c
index c7df7f4..b9aeb76 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -329,12 +329,19 @@ static int vmbus_remove(struct device *child_device)
 	struct hv_driver *drv;
 
 	struct hv_device *dev = device_to_hv_device(child_device);
+	const struct hv_vmbus_device_id *dev_id;
 
 	if (child_device->driver) {
 		drv = drv_to_hv_drv(child_device->driver);
+		dev_id = drv->id_table;
+
+		for (; !is_null_guid(dev_id->guid); dev_id++)
+			if (!memcmp(&dev_id->guid, &dev->dev_type.b,
+					sizeof(uuid_le)))
+				break;
 
 		if (drv->remove) {
-			ret = drv->remove(dev);
+			ret = drv->remove(dev, dev_id);
 		} else {
 			pr_err("remove not set for driver %s\n",
 				dev_name(child_device));
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 08/25] Staging: hv: util: Perform some service specific initialization in util_probe()
In preparation for modifying the util driver to fully conform to the 
Linux Driver Model, perform some service specific initialization in
util_probe() as opposed to in init_hyperv_utils() as is currently done. 
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/hv_util.c |   77 ++++++++++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 25 deletions(-)
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index 661631d..b86128a 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -34,6 +34,13 @@ static u8 *shut_txf_buf;
 static u8 *time_txf_buf;
 static u8 *hbeat_txf_buf;
 
+enum hv_util_services {
+	HV_SHUTDOWN,
+	HV_TIMESYNC,
+	HV_HEARTBEAT,
+	HV_KVP,
+};
+
 static void shutdown_onchannelcallback(void *context)
 {
 	struct vmbus_channel *channel = context;
@@ -242,7 +249,43 @@ static void heartbeat_onchannelcallback(void *context)
 static int util_probe(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
+	void *buf = NULL;
+	int service = dev_id->driver_data;
+
+	switch (service) {
+	case HV_SHUTDOWN:
+		buf = shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!shut_txf_buf)
+			goto error;
+		break;
+
+	case HV_TIMESYNC:
+		buf = time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!time_txf_buf)
+			goto error;
+		break;
+
+	case HV_HEARTBEAT:
+		buf = hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!hbeat_txf_buf)
+			goto error;
+		break;
+
+	case HV_KVP:
+		if (hv_kvp_init())
+			return -ENODEV;
+		break;
+
+	default:
+		pr_err("unknown util service\n");
+		return -ENODEV;
+	}
+
 	return 0;
+
+error:
+	return -ENOMEM;
+
 }
 
 static int util_remove(struct hv_device *dev,
@@ -254,16 +297,20 @@ static int util_remove(struct hv_device *dev,
 static const struct hv_vmbus_device_id id_table[] = {
 	/* Shutdown guid */
 	{ VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
-		       0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB) },
+		       0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB)
+	  .driver_data = HV_SHUTDOWN },
 	/* Time synch guid */
 	{ VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
-		       0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) },
+		       0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
+	  .driver_data = HV_TIMESYNC },
 	/* Heartbeat guid */
 	{ VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
-		       0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) },
+		       0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
+	  .driver_data = HV_HEARTBEAT },
 	/* KVP guid */
 	{ VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
-		       0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6) },
+		       0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6)
+	  .driver_data = HV_KVP },
 	{ },
 };
 
@@ -282,24 +329,10 @@ static int __init init_hyperv_utils(void)
 	int ret;
 	pr_info("Registering HyperV Utility Driver\n");
 
-	if (hv_kvp_init())
-		return -ENODEV;
-
-
-	shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-
-	if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) {
-		pr_info("Unable to allocate memory for receive buffer\n");
-		ret = -ENOMEM;
-		goto err;
-	}
-
 	ret = vmbus_driver_register(&util_drv);
 
 	if (ret != 0)
-		goto err;
+		return ret;
 
 	hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
 
@@ -311,12 +344,6 @@ static int __init init_hyperv_utils(void)
 
 	return 0;
 
-err:
-	kfree(shut_txf_buf);
-	kfree(time_txf_buf);
-	kfree(hbeat_txf_buf);
-
-	return ret;
 }
 
 static void exit_hyperv_utils(void)
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 09/25] Staging: hv: util: Perform some service specific de-initialization in util_remove()
In preparation for modifying the util driver to fully conform to the
Linux Driver Model, perform some service specific de-initialization in
util_remove() as opposed to in exit_hyperv_utils() as is currently done.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/hv_util.c |   29 ++++++++++++++++++++++++-----
 1 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index b86128a..2475ab2 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -291,6 +291,30 @@ error:
 static int util_remove(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
+	int service = dev_id->driver_data;
+
+	switch (service) {
+	case HV_SHUTDOWN:
+		kfree(shut_txf_buf);
+		break;
+
+	case HV_TIMESYNC:
+		kfree(time_txf_buf);
+		break;
+
+	case HV_HEARTBEAT:
+		kfree(hbeat_txf_buf);
+		break;
+
+	case HV_KVP:
+		hv_kvp_deinit();
+		break;
+
+	default:
+		pr_err("unknown util service\n");
+		return -ENODEV;
+	}
+
 	return 0;
 }
 
@@ -370,11 +394,6 @@ static void exit_hyperv_utils(void)
 			&chn_cb_negotiate;
 	hv_cb_utils[HV_KVP_MSG].callback = NULL;
 
-	hv_kvp_deinit();
-
-	kfree(shut_txf_buf);
-	kfree(time_txf_buf);
-	kfree(hbeat_txf_buf);
 	vmbus_driver_unregister(&util_drv);
 }
 
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 10/25] Staging: hv: vmbus: Return proper error code in vmbus_remove()
Return proper error code in vmbus_remove().
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index b9aeb76..95d33a4 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -325,7 +325,7 @@ static int vmbus_probe(struct device *child_device)
  */
 static int vmbus_remove(struct device *child_device)
 {
-	int ret;
+	int ret = 0;
 	struct hv_driver *drv;
 
 	struct hv_device *dev = device_to_hv_device(child_device);
@@ -349,7 +349,7 @@ static int vmbus_remove(struct device *child_device)
 		}
 	}
 
-	return 0;
+	return ret;
 }
 
 
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 12/25] Staging: hv: vmbus: Get rid of hv_cb_utils[] and other unneeded code
Now that the transformation of the util driver is complete,
get rid of hv_cb_utils[] and other unneeded code
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/channel_mgmt.c |   94 -------------------------------------
 drivers/staging/hv/hyperv.h       |    8 ---
 2 files changed, 0 insertions(+), 102 deletions(-)
diff --git a/drivers/staging/hv/channel_mgmt.c
b/drivers/staging/hv/channel_mgmt.c
index 3c67e4c..f20cd84 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -158,100 +158,6 @@ void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
 }
 EXPORT_SYMBOL(prep_negotiate_resp);
 
-/**
- * chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK
- * Hyper-V requests
- * @context: Pointer to argument structure.
- *
- * Set up the default handler for non device driver specific requests
- * from Hyper-V. This stub responds to the default negotiate messages
- * that come in for every non IDE/SCSI/Network request.
- * This behavior is normally overwritten in the hv_utils driver. That
- * driver handles requests like graceful shutdown, heartbeats etc.
- *
- * Mainly used by Hyper-V drivers.
- */
-void chn_cb_negotiate(void *context)
-{
-	struct vmbus_channel *channel = context;
-	u8 *buf;
-	u32 buflen, recvlen;
-	u64 requestid;
-
-	struct icmsg_hdr *icmsghdrp;
-	struct icmsg_negotiate *negop = NULL;
-
-	buflen = PAGE_SIZE;
-	buf = kmalloc(buflen, GFP_ATOMIC);
-
-	vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
-
-	if (recvlen > 0) {
-		icmsghdrp = (struct icmsg_hdr *)&buf[
-			sizeof(struct vmbuspipe_hdr)];
-
-		prep_negotiate_resp(icmsghdrp, negop, buf);
-
-		icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
-			| ICMSGHDRFLAG_RESPONSE;
-
-		vmbus_sendpacket(channel, buf,
-				       recvlen, requestid,
-				       VM_PKT_DATA_INBAND, 0);
-	}
-
-	kfree(buf);
-}
-EXPORT_SYMBOL(chn_cb_negotiate);
-
-/*
- * Function table used for message responses for non IDE/SCSI/Network type
- * messages. (Such as KVP/Shutdown etc)
- */
-struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
-	/* 0E0B6031-5213-4934-818B-38D90CED39DB */
-	/* Shutdown */
-	{
-		.msg_type = HV_SHUTDOWN_MSG,
-		.data.b = {
-			0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
-			0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
-		},
-		.log_msg = "Shutdown channel functionality initialized"
-	},
-
-	/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
-	/* TimeSync */
-	{
-		.msg_type = HV_TIMESYNC_MSG,
-		.data.b = {
-			0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
-			0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
-		},
-		.log_msg = "Timesync channel functionality initialized"
-	},
-	/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
-	/* Heartbeat */
-	{
-		.msg_type = HV_HEARTBEAT_MSG,
-		.data.b = {
-			0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
-			0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
-		},
-		.log_msg = "Heartbeat channel functionality initialized"
-	},
-	/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
-	/* KVP */
-	{
-		.data.b = {
-			0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
-			0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6
-		},
-		.log_msg = "KVP channel functionality initialized"
-	},
-};
-EXPORT_SYMBOL(hv_cb_utils);
-
 /*
  * alloc_channel - Allocate and initialize a vmbus channel object
  */
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
index cf02ae1..685a132 100644
--- a/drivers/staging/hv/hyperv.h
+++ b/drivers/staging/hv/hyperv.h
@@ -941,12 +941,6 @@ struct ictimesync_data {
 	u8 flags;
 } __packed;
 
-/* Index for each IC struct in array hv_cb_utils[] */
-#define HV_SHUTDOWN_MSG		0
-#define HV_TIMESYNC_MSG		1
-#define HV_HEARTBEAT_MSG	2
-#define HV_KVP_MSG		3
-
 struct hyperv_service_callback {
 	u8 msg_type;
 	char *log_msg;
@@ -957,7 +951,5 @@ struct hyperv_service_callback {
 
 extern void prep_negotiate_resp(struct icmsg_hdr *,
 				struct icmsg_negotiate *, u8 *);
-extern void chn_cb_negotiate(void *);
-extern struct hyperv_service_callback hv_cb_utils[];
 
 #endif /* _HYPERV_H */
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 13/25] Staging: hv: vmbus: Get rid of the module dependency
Hyper-V modules can be built as part of the kernel (not just as modules). Get rid of the module dependency in Kconfig. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/Kconfig | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 26b5064..815f8c2 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -1,6 +1,6 @@ config HYPERV tristate "Microsoft Hyper-V client drivers" - depends on X86 && ACPI && PCI && m + depends on X86 && ACPI && PCI default n help Select this option to run Linux as a Hyper-V client operating -- 1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 14/25] Staging: hv: vmbus: Introduce functions for setting and getting driver data
In preparation for getting rid of the ext field in the struct hv_device,
introduce vmbus specific wrapper functions to set/get driver specific data.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/hyperv.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
index 685a132..2879750 100644
--- a/drivers/staging/hv/hyperv.h
+++ b/drivers/staging/hv/hyperv.h
@@ -843,6 +843,15 @@ static inline struct hv_driver *drv_to_hv_drv(struct
device_driver *d)
 	return container_of(d, struct hv_driver, driver);
 }
 
+static inline void hv_set_drvdata(struct hv_device *dev, void *data)
+{
+	dev_set_drvdata(&dev->device, data);
+}
+
+static inline void *hv_get_drvdata(struct hv_device *dev)
+{
+	return dev_get_drvdata(&dev->device);
+}
 
 /* Vmbus interface */
 #define vmbus_driver_register(driver)	\
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 15/25] Staging: hv: storvsc: Get rid of storvsc_dev_add() by inlining the code
Get rid of storvsc_dev_add() by inlining the code.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   58 +++++++++----------------------------
 1 files changed, 14 insertions(+), 44 deletions(-)
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index e5da758..ef93205 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -651,41 +651,6 @@ static int storvsc_connect_to_vsp(struct hv_device *device,
u32 ring_size)
 	return ret;
 }
 
-static int storvsc_dev_add(struct hv_device *device,
-					void *additional_info)
-{
-	struct storvsc_device *stor_device;
-	struct storvsc_device_info *device_info;
-	int ret = 0;
-
-	device_info = (struct storvsc_device_info *)additional_info;
-	stor_device = alloc_stor_device(device);
-	if (!stor_device)
-		return -ENOMEM;
-
-	/* Save the channel properties to our storvsc channel */
-
-	/*
-	 * If we support more than 1 scsi channel, we need to set the
-	 * port number here to the scsi channel but how do we get the
-	 * scsi channel prior to the bus scan.
-	 *
-	 * The host does not support this.
-	 */
-
-	stor_device->port_number = device_info->port_number;
-	/* Send it back up */
-	ret = storvsc_connect_to_vsp(device, device_info->ring_buffer_size);
-	if (ret) {
-		kfree(stor_device);
-		return ret;
-	}
-	device_info->path_id = stor_device->path_id;
-	device_info->target_id = stor_device->target_id;
-
-	return ret;
-}
-
 static int storvsc_dev_remove(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
@@ -1389,10 +1354,10 @@ static int storvsc_probe(struct hv_device *device,
 	int ret;
 	struct Scsi_Host *host;
 	struct hv_host_device *host_dev;
-	struct storvsc_device_info device_info;
 	bool dev_is_ide = ((dev_id->driver_data == 1) ? true : false);
 	int path = 0;
 	int target = 0;
+	struct storvsc_device *stor_device;
 
 	host = scsi_host_alloc(&scsi_driver,
 			       sizeof(struct hv_host_device));
@@ -1417,22 +1382,27 @@ static int storvsc_probe(struct hv_device *device,
 		return -ENOMEM;
 	}
 
-	device_info.port_number = host->host_no;
-	device_info.ring_buffer_size  = storvsc_ringbuffer_size;
-	/* Call to the vsc driver to add the device */
-	ret = storvsc_dev_add(device, (void *)&device_info);
+	stor_device = alloc_stor_device(device);
+	if (!stor_device) {
+		kmem_cache_destroy(host_dev->request_pool);
+		scsi_host_put(host);
+		return -ENOMEM;
+	}
 
-	if (ret != 0) {
+	stor_device->port_number = host->host_no;
+	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
+	if (ret) {
 		kmem_cache_destroy(host_dev->request_pool);
 		scsi_host_put(host);
-		return -ENODEV;
+		kfree(stor_device);
+		return ret;
 	}
 
 	if (dev_is_ide)
 		storvsc_get_ide_info(device, &target, &path);
 
-	host_dev->path = device_info.path_id;
-	host_dev->target = device_info.target_id;
+	host_dev->path = stor_device->path_id;
+	host_dev->target = stor_device->target_id;
 
 	/* max # of devices per target */
 	host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 16/25] Staging: hv: storvsc: Get rid of alloc_stor_device() by inlining the code
Get rid of alloc_stor_device() by inlining the code.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   24 ++++++------------------
 1 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index ef93205..e7d0f92 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -332,23 +332,6 @@ static inline void storvsc_wait_to_drain(struct
storvsc_device *dev)
 	dev->drain_notify = false;
 }
 
-static inline struct storvsc_device *alloc_stor_device(struct hv_device
*device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
-	if (!stor_device)
-		return NULL;
-
-	stor_device->destroy = false;
-	init_waitqueue_head(&stor_device->waiting_to_drain);
-	stor_device->device = device;
-	device->ext = stor_device;
-
-	return stor_device;
-}
-
-
 static inline struct storvsc_device *get_in_stor_device(
 					struct hv_device *device)
 {
@@ -1382,13 +1365,18 @@ static int storvsc_probe(struct hv_device *device,
 		return -ENOMEM;
 	}
 
-	stor_device = alloc_stor_device(device);
+	stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
 	if (!stor_device) {
 		kmem_cache_destroy(host_dev->request_pool);
 		scsi_host_put(host);
 		return -ENOMEM;
 	}
 
+	stor_device->destroy = false;
+	init_waitqueue_head(&stor_device->waiting_to_drain);
+	stor_device->device = device;
+	device->ext = stor_device;
+
 	stor_device->port_number = host->host_no;
 	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
 	if (ret) {
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 17/25] Staging: hv: storvsc: Get rid of some unnecessary state and definitions
Now, get rid of some unnecessary state and definitions.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |    9 ---------
 1 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index e7d0f92..57c1035 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -245,7 +245,6 @@ enum storvsc_request_type {
 
 
 struct hv_storvsc_request {
-	struct hv_storvsc_request *request;
 	struct hv_device *device;
 
 	/* Synchronize the request/response if needed */
@@ -260,14 +259,6 @@ struct hv_storvsc_request {
 };
 
 
-struct storvsc_device_info {
-	u32 ring_buffer_size;
-	unsigned int port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-};
-
-
 /* A storvsc device is a device object that contains a vmbus channel */
 struct storvsc_device {
 	struct hv_device *device;
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 18/25] Staging: hv: storvsc: Eliminate the usage of ext field in struct hv_device
Now, eliminate the usage of ext field in struct  hv_device for storvsc driver.
We do this by registering pointer to struct storvsc_device as the driver
specific data and eliminating the current usage of driver specific data to
save and retrieve the pointer to struct Scsi_Host.
Additionally, all access to the driver specific data is through
the vmbus wrapper functions.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   24 +++++++++++++++---------
 1 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 57c1035..98d47cd 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -266,6 +266,7 @@ struct storvsc_device {
 	bool	 destroy;
 	bool	 drain_notify;
 	atomic_t num_outstanding_req;
+	struct Scsi_Host *host;
 
 	wait_queue_head_t waiting_to_drain;
 
@@ -306,7 +307,8 @@ static inline struct storvsc_device *get_out_stor_device(
 {
 	struct storvsc_device *stor_device;
 
-	stor_device = (struct storvsc_device *)device->ext;
+	stor_device +		(struct storvsc_device *)hv_get_drvdata(device);
 
 	if (stor_device && stor_device->destroy)
 		stor_device = NULL;
@@ -328,7 +330,8 @@ static inline struct storvsc_device *get_in_stor_device(
 {
 	struct storvsc_device *stor_device;
 
-	stor_device = (struct storvsc_device *)device->ext;
+	stor_device +		(struct storvsc_device *)hv_get_drvdata(device);
 
 	if (!stor_device)
 		goto get_in_err;
@@ -480,7 +483,8 @@ static void storvsc_on_io_completion(struct hv_device
*device,
 	struct storvsc_device *stor_device;
 	struct vstor_packet *stor_pkt;
 
-	stor_device = (struct storvsc_device *)device->ext;
+	stor_device +		(struct storvsc_device *)hv_get_drvdata(device);
 
 	stor_pkt = &request->vstor_packet;
 
@@ -630,7 +634,8 @@ static int storvsc_dev_remove(struct hv_device *device)
 	struct storvsc_device *stor_device;
 	unsigned long flags;
 
-	stor_device = (struct storvsc_device *)device->ext;
+	stor_device +		(struct storvsc_device *)hv_get_drvdata(device);
 
 	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	stor_device->destroy = true;
@@ -652,7 +657,7 @@ static int storvsc_dev_remove(struct hv_device *device)
 	 * allow incoming packets.
 	 */
 	spin_lock_irqsave(&device->channel->inbound_lock, flags);
-	device->ext = NULL;
+	hv_set_drvdata(device, NULL);
 	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 
 	/* Close the channel */
@@ -963,7 +968,9 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist
*orig_sgl,
 static int storvsc_remove(struct hv_device *dev,
 				const struct hv_vmbus_device_id *dev_id)
 {
-	struct Scsi_Host *host = dev_get_drvdata(&dev->device);
+	struct storvsc_device *stor_device +			(struct storvsc_device
*)hv_get_drvdata(dev);
+	struct Scsi_Host *host = stor_device->host;
 	struct hv_host_device *host_dev  			(struct hv_host_device
*)host->hostdata;
 
@@ -1338,8 +1345,6 @@ static int storvsc_probe(struct hv_device *device,
 	if (!host)
 		return -ENOMEM;
 
-	dev_set_drvdata(&device->device, host);
-
 	host_dev = (struct hv_host_device *)host->hostdata;
 	memset(host_dev, 0, sizeof(struct hv_host_device));
 
@@ -1366,7 +1371,8 @@ static int storvsc_probe(struct hv_device *device,
 	stor_device->destroy = false;
 	init_waitqueue_head(&stor_device->waiting_to_drain);
 	stor_device->device = device;
-	device->ext = stor_device;
+	stor_device->host = host;
+	hv_set_drvdata(device, stor_device);
 
 	stor_device->port_number = host->host_no;
 	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 19/25] Staging: hv: netvsc: Get rid of the usage of the ext field in struct hv_device
Now, eliminate the usage of ext field in struct  hv_device for netvsc driver.
We do this by registering pointer to struct netvsc_device as the driver
specific data and eliminating the current usage of driver specific data
to save and retrieve the pointer to struct net_device.
Additionally, all access to the driver specific data is through
the vmbus wrapper functions. As part of this cleanup, we also get rid
of some unnecessary debug print statements.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/hyperv_net.h   |    2 +
 drivers/staging/hv/netvsc.c       |   90 +++++++++++++++++++-----------------
 drivers/staging/hv/netvsc_drv.c   |   29 ++++++++++--
 drivers/staging/hv/rndis_filter.c |   36 +++++++++++----
 4 files changed, 100 insertions(+), 57 deletions(-)
diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h
index af8a37f..366dd2b 100644
--- a/drivers/staging/hv/hyperv_net.h
+++ b/drivers/staging/hv/hyperv_net.h
@@ -392,6 +392,8 @@ struct netvsc_device {
 	struct nvsp_message revoke_packet;
 	/* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
 
+	struct net_device *ndev;
+
 	/* Holds rndis device info */
 	void *extension;
 };
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 115629f..b046873 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -35,6 +35,8 @@
 static struct netvsc_device *alloc_net_device(struct hv_device *device)
 {
 	struct netvsc_device *net_device;
+	struct net_device *ndev +		(struct net_device *)hv_get_drvdata(device);
 
 	net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
 	if (!net_device)
@@ -43,8 +45,9 @@ static struct netvsc_device *alloc_net_device(struct hv_device
*device)
 
 	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;
 }
 
@@ -52,7 +55,8 @@ static struct netvsc_device *get_outbound_net_device(struct
hv_device *device)
 {
 	struct netvsc_device *net_device;
 
-	net_device = device->ext;
+	net_device +		(struct netvsc_device *)hv_get_drvdata(device);
 	if (net_device && net_device->destroy)
 		net_device = NULL;
 
@@ -63,7 +67,8 @@ static struct netvsc_device *get_inbound_net_device(struct
hv_device *device)
 {
 	struct netvsc_device *net_device;
 
-	net_device = device->ext;
+	net_device +		(struct netvsc_device *)hv_get_drvdata(device);
 
 	if (!net_device)
 		goto get_in_err;
@@ -81,7 +86,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device
*net_device)
 {
 	struct nvsp_message *revoke_packet;
 	int ret = 0;
-	struct net_device *ndev = dev_get_drvdata(&net_device->dev->device);
+	struct net_device *ndev = net_device->ndev;
 
 	/*
 	 * If we got a section count, it means we received a
@@ -153,14 +158,12 @@ 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 = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	net_device = get_outbound_net_device(device);
-	if (!net_device) {
-		netdev_err(ndev, "unable to get net device..."
-			   "device being destroyed?\n");
+	if (!net_device)
 		return -ENODEV;
-	}
+	ndev = net_device->ndev;
 
 	net_device->recv_buf  		(void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
@@ -269,14 +272,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 = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	net_device = get_outbound_net_device(device);
-	if (!net_device) {
-		netdev_err(ndev, "unable to get net device..."
-			   "device being destroyed?\n");
+	if (!net_device)
 		return -ENODEV;
-	}
+	ndev = net_device->ndev;
 
 	init_packet = &net_device->channel_init_pkt;
 
@@ -357,7 +358,7 @@ int netvsc_device_remove(struct hv_device *device)
 	struct hv_netvsc_packet *netvsc_packet, *pos;
 	unsigned long flags;
 
-	net_device = (struct netvsc_device *)device->ext;
+	net_device = (struct netvsc_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);
@@ -381,7 +382,7 @@ int netvsc_device_remove(struct hv_device *device)
 	 */
 
 	spin_lock_irqsave(&device->channel->inbound_lock, flags);
-	device->ext = NULL;
+	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 */
@@ -407,14 +408,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 = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	net_device = get_inbound_net_device(device);
-	if (!net_device) {
-		netdev_err(ndev, "unable to get net device..."
-			   "device being destroyed?\n");
+	if (!net_device)
 		return;
-	}
+	ndev = net_device->ndev;
 
 	nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
 			(packet->offset8 << 3));
@@ -452,14 +451,12 @@ int netvsc_send(struct hv_device *device,
 	struct netvsc_device *net_device;
 	int ret = 0;
 	struct nvsp_message sendMessage;
-	struct net_device *ndev = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	net_device = get_outbound_net_device(device);
-	if (!net_device) {
-		netdev_err(ndev, "net device (%p) shutting down..."
-			   "ignoring outbound packets\n", net_device);
+	if (!net_device)
 		return -ENODEV;
-	}
+	ndev = net_device->ndev;
 
 	sendMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
 	if (packet->is_data_pkt) {
@@ -506,7 +503,11 @@ static void netvsc_send_recv_completion(struct hv_device
*device,
 	struct nvsp_message recvcompMessage;
 	int retries = 0;
 	int ret;
-	struct net_device *ndev = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
+	struct netvsc_device *net_device +		(struct netvsc_device
*)hv_get_drvdata(device);
+
+	ndev = net_device->ndev;
 
 	recvcompMessage.hdr.msg_type  				NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
@@ -552,7 +553,7 @@ static void netvsc_receive_completion(void *context)
 	u64 transaction_id = 0;
 	bool fsend_receive_comp = false;
 	unsigned long flags;
-	struct net_device *ndev = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	/*
 	 * Even though it seems logical to do a GetOutboundNetDevice() here to
@@ -560,11 +561,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) {
-		netdev_err(ndev, "unable to get net device..."
-			   "device being destroyed?\n");
+	if (!net_device)
 		return;
-	}
+	ndev = net_device->ndev;
 
 	/* Overloading use of the lock. */
 	spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
@@ -607,16 +606,14 @@ static void netvsc_receive(struct hv_device *device,
 	int i, j;
 	int count = 0, bytes_remain = 0;
 	unsigned long flags;
-	struct net_device *ndev = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	LIST_HEAD(listHead);
 
 	net_device = get_inbound_net_device(device);
-	if (!net_device) {
-		netdev_err(ndev, "unable to get net device..."
-			   "device being destroyed?\n");
+	if (!net_device)
 		return;
-	}
+	ndev = net_device->ndev;
 
 	/*
 	 * All inbound packets other than send completion should be xfer page
@@ -784,7 +781,7 @@ static void netvsc_channel_cb(void *context)
 	struct vmpacket_descriptor *desc;
 	unsigned char *buffer;
 	int bufferlen = NETVSC_PACKET_SIZE;
-	struct net_device *ndev = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char),
 			 GFP_ATOMIC);
@@ -793,11 +790,9 @@ static void netvsc_channel_cb(void *context)
 	buffer = packet;
 
 	net_device = get_inbound_net_device(device);
-	if (!net_device) {
-		netdev_err(ndev, "net device (%p) shutting down..."
-			   "ignoring inbound packets\n", net_device);
+	if (!net_device)
 		goto out;
-	}
+	ndev = net_device->ndev;
 
 	do {
 		ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen,
@@ -871,7 +866,7 @@ 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 = dev_get_drvdata(&device->device);
+	struct net_device *ndev;
 
 	net_device = alloc_net_device(device);
 	if (!net_device) {
@@ -879,6 +874,15 @@ int netvsc_device_add(struct hv_device *device, void
*additional_info)
 		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);
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index d0189a3..917bae5 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -203,8 +203,13 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct
net_device *net)
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
 				       unsigned int status)
 {
-	struct net_device *net = dev_get_drvdata(&device_obj->device);
+	struct net_device *net;
 	struct net_device_context *ndev_ctx;
+	struct netvsc_device *net_device;
+
+	net_device +		(struct netvsc_device *)hv_get_drvdata(device_obj);
+	net = net_device->ndev;
 
 	if (!net) {
 		netdev_err(net, "got link status but net device "
@@ -236,6 +241,11 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 	void *data;
 	int i;
 	unsigned long flags;
+	struct netvsc_device *net_device;
+
+	net_device +		(struct netvsc_device *)hv_get_drvdata(device_obj);
+	net = net_device->ndev;
 
 	if (!net) {
 		netdev_err(net, "got receive callback but net device"
@@ -322,9 +332,13 @@ static void netvsc_send_garp(struct work_struct *w)
 {
 	struct net_device_context *ndev_ctx;
 	struct net_device *net;
+	struct netvsc_device *net_device;
 
 	ndev_ctx = container_of(w, struct net_device_context, dwork.work);
-	net = dev_get_drvdata(&ndev_ctx->device_ctx->device);
+	net_device +		(struct netvsc_device *)
+		hv_get_drvdata(ndev_ctx->device_ctx);
+	net = net_device->ndev;
 	netif_notify_peers(net);
 }
 
@@ -347,7 +361,7 @@ static int netvsc_probe(struct hv_device *dev,
 	net_device_ctx = netdev_priv(net);
 	net_device_ctx->device_ctx = dev;
 	atomic_set(&net_device_ctx->avail, ring_size);
-	dev_set_drvdata(&dev->device, net);
+	hv_set_drvdata(dev, net);
 	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
 
 	net->netdev_ops = &device_ops;
@@ -373,7 +387,7 @@ static int netvsc_probe(struct hv_device *dev,
 		netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
 		unregister_netdev(net);
 		free_netdev(net);
-		dev_set_drvdata(&dev->device, NULL);
+		hv_set_drvdata(dev, NULL);
 		return ret;
 	}
 	memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
@@ -387,8 +401,13 @@ out:
 static int netvsc_remove(struct hv_device *dev,
 			const struct hv_vmbus_device_id *dev_id)
 {
-	struct net_device *net = dev_get_drvdata(&dev->device);
+	struct net_device *net;
 	struct net_device_context *ndev_ctx;
+	struct netvsc_device *net_device;
+
+	net_device +		(struct netvsc_device *)hv_get_drvdata(dev);
+	net = net_device->ndev;
 
 	if (net == NULL) {
 		dev_err(&dev->device, "No net device to remove\n");
diff --git a/drivers/staging/hv/rndis_filter.c
b/drivers/staging/hv/rndis_filter.c
index b325345..79948be 100644
--- a/drivers/staging/hv/rndis_filter.c
+++ b/drivers/staging/hv/rndis_filter.c
@@ -141,7 +141,12 @@ static void put_rndis_request(struct rndis_device *dev,
 static void dump_rndis_message(struct hv_device *hv_dev,
 			struct rndis_message *rndis_msg)
 {
-	struct net_device *netdev = dev_get_drvdata(&hv_dev->device);
+	struct net_device *netdev;
+	struct netvsc_device *net_device;
+
+	net_device +		(struct netvsc_device *)hv_get_drvdata(hv_dev);
+	netdev = net_device->ndev;
 
 	switch (rndis_msg->ndis_msg_type) {
 	case REMOTE_NDIS_PACKET_MSG:
@@ -249,7 +254,9 @@ static void rndis_filter_receive_response(struct
rndis_device *dev,
 	struct rndis_request *request = NULL;
 	bool found = false;
 	unsigned long flags;
-	struct net_device *ndev =
dev_get_drvdata(&dev->net_dev->dev->device);
+	struct net_device *ndev;
+
+	ndev = dev->net_dev->ndev;
 
 	spin_lock_irqsave(&dev->request_lock, flags);
 	list_for_each_entry(request, &dev->req_list, list_ent) {
@@ -356,11 +363,17 @@ static void rndis_filter_receive_data(struct rndis_device
*dev,
 int rndis_filter_receive(struct hv_device *dev,
 				struct hv_netvsc_packet	*pkt)
 {
-	struct netvsc_device *net_dev = dev->ext;
+	struct netvsc_device *net_dev +		(struct netvsc_device *)hv_get_drvdata(dev);
 	struct rndis_device *rndis_dev;
 	struct rndis_message rndis_msg;
 	struct rndis_message *rndis_hdr;
-	struct net_device *ndev = dev_get_drvdata(&dev->device);
+	struct net_device *ndev;
+	struct netvsc_device *net_device;
+
+	net_device +		(struct netvsc_device *)hv_get_drvdata(dev);
+	ndev = net_device->ndev;
 
 	if (!net_dev)
 		return -EINVAL;
@@ -517,7 +530,9 @@ static int rndis_filter_set_packet_filter(struct
rndis_device *dev,
 	struct rndis_set_complete *set_complete;
 	u32 status;
 	int ret, t;
-	struct net_device *ndev =
dev_get_drvdata(&dev->net_dev->dev->device);
+	struct net_device *ndev;
+
+	ndev = dev->net_dev->ndev;
 
 	request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG,
 			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
@@ -700,7 +715,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 
 
 	/* Initialize the rndis device */
-	netDevice = dev->ext;
+	netDevice = (struct netvsc_device *)hv_get_drvdata(dev);
 
 	netDevice->extension = rndisDevice;
 	rndisDevice->net_dev = netDevice;
@@ -737,7 +752,8 @@ int rndis_filter_device_add(struct hv_device *dev,
 
 void rndis_filter_device_remove(struct hv_device *dev)
 {
-	struct netvsc_device *net_dev = dev->ext;
+	struct netvsc_device *net_dev +		(struct netvsc_device *)hv_get_drvdata(dev);
 	struct rndis_device *rndis_dev = net_dev->extension;
 
 	/* Halt and release the rndis device */
@@ -752,7 +768,8 @@ void rndis_filter_device_remove(struct hv_device *dev)
 
 int rndis_filter_open(struct hv_device *dev)
 {
-	struct netvsc_device *netDevice = dev->ext;
+	struct netvsc_device *netDevice +		(struct netvsc_device
*)hv_get_drvdata(dev);
 
 	if (!netDevice)
 		return -EINVAL;
@@ -762,7 +779,8 @@ int rndis_filter_open(struct hv_device *dev)
 
 int rndis_filter_close(struct hv_device *dev)
 {
-	struct netvsc_device *netDevice = dev->ext;
+	struct netvsc_device *netDevice +		(struct netvsc_device
*)hv_get_drvdata(dev);
 
 	if (!netDevice)
 		return -EINVAL;
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 20/25] Staging: hv: mousevsc: Get rid of the usage of the ext field in struct hv_device
Get rid of the usage of the ext field in struct hv_device for the mouse driver.
We do this by using the newly introduced functions to set and and get driver
specific data.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/hv_mouse.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
index d60f287..c6c4024 100644
--- a/drivers/staging/hv/hv_mouse.c
+++ b/drivers/staging/hv/hv_mouse.c
@@ -196,7 +196,7 @@ static struct mousevsc_dev *alloc_input_device(struct
hv_device *device)
 	atomic_cmpxchg(&input_dev->ref_count, 0, 2);
 
 	input_dev->device = device;
-	device->ext = input_dev;
+	hv_set_drvdata(device, input_dev);
 
 	return input_dev;
 }
@@ -214,7 +214,7 @@ static struct mousevsc_dev *get_input_device(struct
hv_device *device)
 {
 	struct mousevsc_dev *input_dev;
 
-	input_dev = (struct mousevsc_dev *)device->ext;
+	input_dev = (struct mousevsc_dev *)hv_get_drvdata(device);
 
 /*
  *	FIXME
@@ -240,7 +240,7 @@ static struct mousevsc_dev *must_get_input_device(struct
hv_device *device)
 {
 	struct mousevsc_dev *input_dev;
 
-	input_dev = (struct mousevsc_dev *)device->ext;
+	input_dev = (struct mousevsc_dev *)hv_get_drvdata(device);
 
 	if (input_dev && atomic_read(&input_dev->ref_count))
 		atomic_inc(&input_dev->ref_count);
@@ -254,7 +254,7 @@ static void put_input_device(struct hv_device *device)
 {
 	struct mousevsc_dev *input_dev;
 
-	input_dev = (struct mousevsc_dev *)device->ext;
+	input_dev = (struct mousevsc_dev *)hv_get_drvdata(device);
 
 	atomic_dec(&input_dev->ref_count);
 }
@@ -266,7 +266,7 @@ static struct mousevsc_dev *release_input_device(struct
hv_device *device)
 {
 	struct mousevsc_dev *input_dev;
 
-	input_dev = (struct mousevsc_dev *)device->ext;
+	input_dev = (struct mousevsc_dev *)hv_get_drvdata(device);
 
 	/* Busy wait until the ref drop to 2, then set it to 1  */
 	while (atomic_cmpxchg(&input_dev->ref_count, 2, 1) != 2)
@@ -282,13 +282,13 @@ static struct mousevsc_dev
*final_release_input_device(struct hv_device *device)
 {
 	struct mousevsc_dev *input_dev;
 
-	input_dev = (struct mousevsc_dev *)device->ext;
+	input_dev = (struct mousevsc_dev *)hv_get_drvdata(device);
 
 	/* Busy wait until the ref drop to 1, then set it to 0  */
 	while (atomic_cmpxchg(&input_dev->ref_count, 1, 0) != 1)
 		udelay(100);
 
-	device->ext = NULL;
+	hv_set_drvdata(device, NULL);
 	return input_dev;
 }
 
@@ -790,7 +790,7 @@ static int mousevsc_on_device_remove(struct hv_device
*device)
 	int ret = 0;
 
 	pr_info("disabling input device (%p)...",
-		    device->ext);
+		    hv_get_drvdata(device));
 
 	input_dev = release_input_device(device);
 
@@ -808,7 +808,7 @@ static int mousevsc_on_device_remove(struct hv_device
*device)
 		udelay(100);
 	}
 
-	pr_info("removing input device (%p)...", device->ext);
+	pr_info("removing input device (%p)...", hv_get_drvdata(device));
 
 	input_dev = final_release_input_device(device);
 
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 21/25] Staging: hv: vmbus: Get rid of the ext field in struct hv_device
Now that we have eliminated all uses of the ext field in struct hv_device,
get rid of the ext field.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/hyperv.h |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
index 2879750..7ba274f 100644
--- a/drivers/staging/hv/hyperv.h
+++ b/drivers/staging/hv/hyperv.h
@@ -827,9 +827,6 @@ struct hv_device {
 	struct device device;
 
 	struct vmbus_channel *channel;
-
-	/* Device extension; */
-	void *ext;
 };
 
 
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 22/25] Staging: hv: vmbus: Do not allocate struct hv_device_info on the stack
struct hv_device_info is about 101 bytes in size. Do not allocate this structure
on the stack.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |  134 ++++++++++++++++++++-------------------
 1 files changed, 69 insertions(+), 65 deletions(-)
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 95d33a4..e39c92d 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -112,101 +112,105 @@ static ssize_t vmbus_show_device_attr(struct device
*dev,
 				      char *buf)
 {
 	struct hv_device *hv_dev = device_to_hv_device(dev);
-	struct hv_device_info device_info;
+	struct hv_device_info *device_info;
 	char alias_name[VMBUS_ALIAS_LEN + 1];
+	int ret = 0;
 
-	memset(&device_info, 0, sizeof(struct hv_device_info));
+	device_info = kzalloc(sizeof(struct hv_device_info), GFP_KERNEL);
+	if (!device_info)
+		return ret;
 
-	get_channel_info(hv_dev, &device_info);
+	get_channel_info(hv_dev, device_info);
 
 	if (!strcmp(dev_attr->attr.name, "class_id")) {
-		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
 			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
-			       device_info.chn_type.b[3],
-			       device_info.chn_type.b[2],
-			       device_info.chn_type.b[1],
-			       device_info.chn_type.b[0],
-			       device_info.chn_type.b[5],
-			       device_info.chn_type.b[4],
-			       device_info.chn_type.b[7],
-			       device_info.chn_type.b[6],
-			       device_info.chn_type.b[8],
-			       device_info.chn_type.b[9],
-			       device_info.chn_type.b[10],
-			       device_info.chn_type.b[11],
-			       device_info.chn_type.b[12],
-			       device_info.chn_type.b[13],
-			       device_info.chn_type.b[14],
-			       device_info.chn_type.b[15]);
+			       device_info->chn_type.b[3],
+			       device_info->chn_type.b[2],
+			       device_info->chn_type.b[1],
+			       device_info->chn_type.b[0],
+			       device_info->chn_type.b[5],
+			       device_info->chn_type.b[4],
+			       device_info->chn_type.b[7],
+			       device_info->chn_type.b[6],
+			       device_info->chn_type.b[8],
+			       device_info->chn_type.b[9],
+			       device_info->chn_type.b[10],
+			       device_info->chn_type.b[11],
+			       device_info->chn_type.b[12],
+			       device_info->chn_type.b[13],
+			       device_info->chn_type.b[14],
+			       device_info->chn_type.b[15]);
 	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
-		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		ret = sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
 			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
-			       device_info.chn_instance.b[3],
-			       device_info.chn_instance.b[2],
-			       device_info.chn_instance.b[1],
-			       device_info.chn_instance.b[0],
-			       device_info.chn_instance.b[5],
-			       device_info.chn_instance.b[4],
-			       device_info.chn_instance.b[7],
-			       device_info.chn_instance.b[6],
-			       device_info.chn_instance.b[8],
-			       device_info.chn_instance.b[9],
-			       device_info.chn_instance.b[10],
-			       device_info.chn_instance.b[11],
-			       device_info.chn_instance.b[12],
-			       device_info.chn_instance.b[13],
-			       device_info.chn_instance.b[14],
-			       device_info.chn_instance.b[15]);
+			       device_info->chn_instance.b[3],
+			       device_info->chn_instance.b[2],
+			       device_info->chn_instance.b[1],
+			       device_info->chn_instance.b[0],
+			       device_info->chn_instance.b[5],
+			       device_info->chn_instance.b[4],
+			       device_info->chn_instance.b[7],
+			       device_info->chn_instance.b[6],
+			       device_info->chn_instance.b[8],
+			       device_info->chn_instance.b[9],
+			       device_info->chn_instance.b[10],
+			       device_info->chn_instance.b[11],
+			       device_info->chn_instance.b[12],
+			       device_info->chn_instance.b[13],
+			       device_info->chn_instance.b[14],
+			       device_info->chn_instance.b[15]);
 	} else if (!strcmp(dev_attr->attr.name, "modalias")) {
 		print_alias_name(hv_dev, alias_name);
-		return sprintf(buf, "vmbus:%s\n", alias_name);
+		ret = sprintf(buf, "vmbus:%s\n", alias_name);
 	} else if (!strcmp(dev_attr->attr.name, "state")) {
-		return sprintf(buf, "%d\n", device_info.chn_state);
+		ret = sprintf(buf, "%d\n", device_info->chn_state);
 	} else if (!strcmp(dev_attr->attr.name, "id")) {
-		return sprintf(buf, "%d\n", device_info.chn_id);
+		ret = sprintf(buf, "%d\n", device_info->chn_id);
 	} else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
-		return sprintf(buf, "%d\n", device_info.outbound.int_mask);
+		ret = sprintf(buf, "%d\n", device_info->outbound.int_mask);
 	} else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
-		return sprintf(buf, "%d\n", device_info.outbound.read_idx);
+		ret = sprintf(buf, "%d\n", device_info->outbound.read_idx);
 	} else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
-		return sprintf(buf, "%d\n", device_info.outbound.write_idx);
+		ret = sprintf(buf, "%d\n", device_info->outbound.write_idx);
 	} else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail"))
{
-		return sprintf(buf, "%d\n",
-			       device_info.outbound.bytes_avail_toread);
+		ret = sprintf(buf, "%d\n",
+			       device_info->outbound.bytes_avail_toread);
 	} else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail"))
{
-		return sprintf(buf, "%d\n",
-			       device_info.outbound.bytes_avail_towrite);
+		ret = sprintf(buf, "%d\n",
+			       device_info->outbound.bytes_avail_towrite);
 	} else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
-		return sprintf(buf, "%d\n", device_info.inbound.int_mask);
+		ret = sprintf(buf, "%d\n", device_info->inbound.int_mask);
 	} else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
-		return sprintf(buf, "%d\n", device_info.inbound.read_idx);
+		ret = sprintf(buf, "%d\n", device_info->inbound.read_idx);
 	} else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
-		return sprintf(buf, "%d\n", device_info.inbound.write_idx);
+		ret = sprintf(buf, "%d\n", device_info->inbound.write_idx);
 	} else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
-		return sprintf(buf, "%d\n",
-			       device_info.inbound.bytes_avail_toread);
+		ret = sprintf(buf, "%d\n",
+			       device_info->inbound.bytes_avail_toread);
 	} else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail"))
{
-		return sprintf(buf, "%d\n",
-			       device_info.inbound.bytes_avail_towrite);
+		ret = sprintf(buf, "%d\n",
+			       device_info->inbound.bytes_avail_towrite);
 	} else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
-		return sprintf(buf, "%d\n", device_info.monitor_id);
+		ret = sprintf(buf, "%d\n", device_info->monitor_id);
 	} else if (!strcmp(dev_attr->attr.name,
"server_monitor_pending")) {
-		return sprintf(buf, "%d\n", device_info.server_monitor_pending);
+		ret = sprintf(buf, "%d\n", device_info->server_monitor_pending);
 	} else if (!strcmp(dev_attr->attr.name,
"server_monitor_latency")) {
-		return sprintf(buf, "%d\n", device_info.server_monitor_latency);
+		ret = sprintf(buf, "%d\n", device_info->server_monitor_latency);
 	} else if (!strcmp(dev_attr->attr.name,
"server_monitor_conn_id")) {
-		return sprintf(buf, "%d\n",
-			       device_info.server_monitor_conn_id);
+		ret = sprintf(buf, "%d\n",
+			       device_info->server_monitor_conn_id);
 	} else if (!strcmp(dev_attr->attr.name,
"client_monitor_pending")) {
-		return sprintf(buf, "%d\n", device_info.client_monitor_pending);
+		ret = sprintf(buf, "%d\n", device_info->client_monitor_pending);
 	} else if (!strcmp(dev_attr->attr.name,
"client_monitor_latency")) {
-		return sprintf(buf, "%d\n", device_info.client_monitor_latency);
+		ret = sprintf(buf, "%d\n", device_info->client_monitor_latency);
 	} else if (!strcmp(dev_attr->attr.name,
"client_monitor_conn_id")) {
-		return sprintf(buf, "%d\n",
-			       device_info.client_monitor_conn_id);
-	} else {
-		return 0;
+		ret = sprintf(buf, "%d\n",
+			       device_info->client_monitor_conn_id);
 	}
+
+	kfree(device_info);
+	return ret;
 }
 
 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 23/25] Staging: hv: netvsc: Rename netDevice as net_device
Rename netDevice as net_device.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/netvsc.c       |    5 ++++-
 drivers/staging/hv/rndis_filter.c |   20 ++++++++++----------
 2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index b046873..4564f13 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -385,7 +385,10 @@ int netvsc_device_remove(struct hv_device *device)
 	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 */
+	/*
+	 * At this point, no one should be accessing net_device
+	 * except in here
+	 */
 	dev_notice(&device->device, "net device safe to remove\n");
 
 	/* Now, we can close the channel safely */
diff --git a/drivers/staging/hv/rndis_filter.c
b/drivers/staging/hv/rndis_filter.c
index 79948be..fb46a88 100644
--- a/drivers/staging/hv/rndis_filter.c
+++ b/drivers/staging/hv/rndis_filter.c
@@ -694,7 +694,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 				  void *additional_info)
 {
 	int ret;
-	struct netvsc_device *netDevice;
+	struct netvsc_device *net_device;
 	struct rndis_device *rndisDevice;
 	struct netvsc_device_info *deviceInfo = additional_info;
 
@@ -715,10 +715,10 @@ int rndis_filter_device_add(struct hv_device *dev,
 
 
 	/* Initialize the rndis device */
-	netDevice = (struct netvsc_device *)hv_get_drvdata(dev);
+	net_device = (struct netvsc_device *)hv_get_drvdata(dev);
 
-	netDevice->extension = rndisDevice;
-	rndisDevice->net_dev = netDevice;
+	net_device->extension = rndisDevice;
+	rndisDevice->net_dev = net_device;
 
 	/* Send the rndis initialization message */
 	ret = rndis_filter_init_device(rndisDevice);
@@ -768,24 +768,24 @@ void rndis_filter_device_remove(struct hv_device *dev)
 
 int rndis_filter_open(struct hv_device *dev)
 {
-	struct netvsc_device *netDevice +	struct netvsc_device *net_device  		(struct
netvsc_device *)hv_get_drvdata(dev);
 
-	if (!netDevice)
+	if (!net_device)
 		return -EINVAL;
 
-	return rndis_filter_open_device(netDevice->extension);
+	return rndis_filter_open_device(net_device->extension);
 }
 
 int rndis_filter_close(struct hv_device *dev)
 {
-	struct netvsc_device *netDevice +	struct netvsc_device *net_device  		(struct
netvsc_device *)hv_get_drvdata(dev);
 
-	if (!netDevice)
+	if (!net_device)
 		return -EINVAL;
 
-	return rndis_filter_close_device(netDevice->extension);
+	return rndis_filter_close_device(net_device->extension);
 }
 
 int rndis_filter_send(struct hv_device *dev,
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 24/25] Staging: hv: netvsc: Rename rndisDevice to rndis_device
Rename rndisDevice to rndis_device.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/rndis_filter.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/staging/hv/rndis_filter.c
b/drivers/staging/hv/rndis_filter.c
index fb46a88..cb9d4f6 100644
--- a/drivers/staging/hv/rndis_filter.c
+++ b/drivers/staging/hv/rndis_filter.c
@@ -695,11 +695,11 @@ int rndis_filter_device_add(struct hv_device *dev,
 {
 	int ret;
 	struct netvsc_device *net_device;
-	struct rndis_device *rndisDevice;
+	struct rndis_device *rndis_device;
 	struct netvsc_device_info *deviceInfo = additional_info;
 
-	rndisDevice = get_rndis_device();
-	if (!rndisDevice)
+	rndis_device = get_rndis_device();
+	if (!rndis_device)
 		return -ENODEV;
 
 	/*
@@ -709,7 +709,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 	 */
 	ret = netvsc_device_add(dev, additional_info);
 	if (ret != 0) {
-		kfree(rndisDevice);
+		kfree(rndis_device);
 		return ret;
 	}
 
@@ -717,11 +717,11 @@ int rndis_filter_device_add(struct hv_device *dev,
 	/* Initialize the rndis device */
 	net_device = (struct netvsc_device *)hv_get_drvdata(dev);
 
-	net_device->extension = rndisDevice;
-	rndisDevice->net_dev = net_device;
+	net_device->extension = rndis_device;
+	rndis_device->net_dev = net_device;
 
 	/* Send the rndis initialization message */
-	ret = rndis_filter_init_device(rndisDevice);
+	ret = rndis_filter_init_device(rndis_device);
 	if (ret != 0) {
 		/*
 		 * TODO: If rndis init failed, we will need to shut down the
@@ -730,21 +730,21 @@ int rndis_filter_device_add(struct hv_device *dev,
 	}
 
 	/* Get the mac address */
-	ret = rndis_filter_query_device_mac(rndisDevice);
+	ret = rndis_filter_query_device_mac(rndis_device);
 	if (ret != 0) {
 		/*
 		 * TODO: shutdown rndis device and the channel
 		 */
 	}
 
-	memcpy(deviceInfo->mac_adr, rndisDevice->hw_mac_adr, ETH_ALEN);
+	memcpy(deviceInfo->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
 
-	rndis_filter_query_device_link_status(rndisDevice);
+	rndis_filter_query_device_link_status(rndis_device);
 
-	deviceInfo->link_state = rndisDevice->link_stat;
+	deviceInfo->link_state = rndis_device->link_stat;
 
 	dev_info(&dev->device, "Device MAC %pM link state %s",
-		 rndisDevice->hw_mac_adr,
+		 rndis_device->hw_mac_adr,
 		 ((deviceInfo->link_state) ? ("down\n") : ("up\n")));
 
 	return ret;
-- 
1.7.4.1
K. Y. Srinivasan
2011-Sep-08  14:24 UTC
[PATCH 25/25] Staging: hv: netvsc: Rename deviceInfo as device_info
Rename deviceInfo as device_info.
Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
---
 drivers/staging/hv/rndis_filter.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/hv/rndis_filter.c
b/drivers/staging/hv/rndis_filter.c
index cb9d4f6..732dfe7 100644
--- a/drivers/staging/hv/rndis_filter.c
+++ b/drivers/staging/hv/rndis_filter.c
@@ -696,7 +696,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 	int ret;
 	struct netvsc_device *net_device;
 	struct rndis_device *rndis_device;
-	struct netvsc_device_info *deviceInfo = additional_info;
+	struct netvsc_device_info *device_info = additional_info;
 
 	rndis_device = get_rndis_device();
 	if (!rndis_device)
@@ -737,15 +737,15 @@ int rndis_filter_device_add(struct hv_device *dev,
 		 */
 	}
 
-	memcpy(deviceInfo->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
+	memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
 
 	rndis_filter_query_device_link_status(rndis_device);
 
-	deviceInfo->link_state = rndis_device->link_stat;
+	device_info->link_state = rndis_device->link_stat;
 
 	dev_info(&dev->device, "Device MAC %pM link state %s",
 		 rndis_device->hw_mac_adr,
-		 ((deviceInfo->link_state) ? ("down\n") : ("up\n")));
+		 ((device_info->link_state) ? ("down\n") : ("up\n")));
 
 	return ret;
 }
-- 
1.7.4.1
Greg KH
2011-Sep-09  20:44 UTC
[PATCH 18/25] Staging: hv: storvsc: Eliminate the usage of ext field in struct hv_device
On Thu, Sep 08, 2011 at 07:24:29AM -0700, K. Y. Srinivasan wrote:> Now, eliminate the usage of ext field in struct hv_device for storvsc driver. > We do this by registering pointer to struct storvsc_device as the driver > specific data and eliminating the current usage of driver specific data to > save and retrieve the pointer to struct Scsi_Host. > Additionally, all access to the driver specific data is through > the vmbus wrapper functions. > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > --- > drivers/staging/hv/storvsc_drv.c | 24 +++++++++++++++--------- > 1 files changed, 15 insertions(+), 9 deletions(-) > > diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c > index 57c1035..98d47cd 100644 > --- a/drivers/staging/hv/storvsc_drv.c > +++ b/drivers/staging/hv/storvsc_drv.c > @@ -266,6 +266,7 @@ struct storvsc_device { > bool destroy; > bool drain_notify; > atomic_t num_outstanding_req; > + struct Scsi_Host *host;You are properly reference counting this pointer, right?> @@ -306,7 +307,8 @@ static inline struct storvsc_device *get_out_stor_device( > { > struct storvsc_device *stor_device; > > - stor_device = (struct storvsc_device *)device->ext; > + stor_device > + (struct storvsc_device *)hv_get_drvdata(device);Casting is not needed at all.> @@ -1366,7 +1371,8 @@ static int storvsc_probe(struct hv_device *device, > stor_device->destroy = false; > init_waitqueue_head(&stor_device->waiting_to_drain); > stor_device->device = device; > - device->ext = stor_device; > + stor_device->host = host; > + hv_set_drvdata(device, stor_device);Lookie there, no reference count incremented, right? Or did I miss it somewhere else? gotta love dynamic pointer lifetime rules... greg k-h
KY Srinivasan
2011-Sep-10  14:16 UTC
[PATCH 18/25] Staging: hv: storvsc: Eliminate the usage of ext field in struct hv_device
> -----Original Message----- > From: Greg KH [mailto:greg at kroah.com] > Sent: Friday, September 09, 2011 4:45 PM > To: KY Srinivasan > Cc: gregkh at suse.de; linux-kernel at vger.kernel.org; > devel at linuxdriverproject.org; virtualization at lists.osdl.org; Haiyang Zhang > Subject: Re: [PATCH 18/25] Staging: hv: storvsc: Eliminate the usage of ext field in > struct hv_device > > On Thu, Sep 08, 2011 at 07:24:29AM -0700, K. Y. Srinivasan wrote: > > Now, eliminate the usage of ext field in struct hv_device for storvsc driver. > > We do this by registering pointer to struct storvsc_device as the driver > > specific data and eliminating the current usage of driver specific data to > > save and retrieve the pointer to struct Scsi_Host. > > Additionally, all access to the driver specific data is through > > the vmbus wrapper functions. > > > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > > --- > > drivers/staging/hv/storvsc_drv.c | 24 +++++++++++++++--------- > > 1 files changed, 15 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c > > index 57c1035..98d47cd 100644 > > --- a/drivers/staging/hv/storvsc_drv.c > > +++ b/drivers/staging/hv/storvsc_drv.c > > @@ -266,6 +266,7 @@ struct storvsc_device { > > bool destroy; > > bool drain_notify; > > atomic_t num_outstanding_req; > > + struct Scsi_Host *host; > > You are properly reference counting this pointer, right?The scsi_host_alloc() which we use to allocate the host structure, gives us the needed reference.> > > @@ -306,7 +307,8 @@ static inline struct storvsc_device > *get_out_stor_device( > > { > > struct storvsc_device *stor_device; > > > > - stor_device = (struct storvsc_device *)device->ext; > > + stor_device > > + (struct storvsc_device *)hv_get_drvdata(device); > > Casting is not needed at all. > > > @@ -1366,7 +1371,8 @@ static int storvsc_probe(struct hv_device *device, > > stor_device->destroy = false; > > init_waitqueue_head(&stor_device->waiting_to_drain); > > stor_device->device = device; > > - device->ext = stor_device; > > + stor_device->host = host; > > + hv_set_drvdata(device, stor_device); > > Lookie there, no reference count incremented, right? Or did I miss it > somewhere else?We are stashing the pointer to a structure on which we already have a reference (that was established at the point of allocating the host). Regards, K. Y
Greg KH
2011-Sep-10  18:28 UTC
[PATCH 18/25] Staging: hv: storvsc: Eliminate the usage of ext field in struct hv_device
On Sat, Sep 10, 2011 at 02:16:14PM +0000, KY Srinivasan wrote:> > > > -----Original Message----- > > From: Greg KH [mailto:greg at kroah.com] > > Sent: Friday, September 09, 2011 4:45 PM > > To: KY Srinivasan > > Cc: gregkh at suse.de; linux-kernel at vger.kernel.org; > > devel at linuxdriverproject.org; virtualization at lists.osdl.org; Haiyang Zhang > > Subject: Re: [PATCH 18/25] Staging: hv: storvsc: Eliminate the usage of ext field in > > struct hv_device > > > > On Thu, Sep 08, 2011 at 07:24:29AM -0700, K. Y. Srinivasan wrote: > > > Now, eliminate the usage of ext field in struct hv_device for storvsc driver. > > > We do this by registering pointer to struct storvsc_device as the driver > > > specific data and eliminating the current usage of driver specific data to > > > save and retrieve the pointer to struct Scsi_Host. > > > Additionally, all access to the driver specific data is through > > > the vmbus wrapper functions. > > > > > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > > > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > > > --- > > > drivers/staging/hv/storvsc_drv.c | 24 +++++++++++++++--------- > > > 1 files changed, 15 insertions(+), 9 deletions(-) > > > > > > diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c > > > index 57c1035..98d47cd 100644 > > > --- a/drivers/staging/hv/storvsc_drv.c > > > +++ b/drivers/staging/hv/storvsc_drv.c > > > @@ -266,6 +266,7 @@ struct storvsc_device { > > > bool destroy; > > > bool drain_notify; > > > atomic_t num_outstanding_req; > > > + struct Scsi_Host *host; > > > > You are properly reference counting this pointer, right? > > The scsi_host_alloc() which we use to allocate the host structure, gives us > the needed reference.Ok, thanks, I missed that. The casting though should be taken out, otherwise the janitor project will just come along and clean it up again... greg k-h