linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device()
  2011-08-27 18:31 [PATCH 0000/0046] Staging: hv: Driver cleanup K. Y. Srinivasan
@ 2011-08-27 18:31 ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 02/46] Staging: hv: storvsc: Do not aquire an unnecessary reference on stor_device K. Y. Srinivasan
                     ` (44 more replies)
  2011-08-29 18:15 ` [PATCH 0000/0046] Staging: hv: Driver cleanup Greg KH
  2011-08-30 12:48 ` Olaf Hering
  2 siblings, 45 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Inline the code for  free_stor_device() and get rid of the function.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc.c |    8 ++------
 1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 827b6a3..8c62829 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -51,10 +51,6 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 	return stor_device;
 }
 
-static inline void free_stor_device(struct storvsc_device *device)
-{
-	kfree(device);
-}
 
 /* Get the stordevice object iff exists and its refcount > 0 */
 static inline struct storvsc_device *must_get_stor_device(
@@ -394,7 +390,7 @@ int storvsc_dev_add(struct hv_device *device,
 	/* Send it back up */
 	ret = storvsc_connect_to_vsp(device, device_info->ring_buffer_size);
 	if (ret) {
-		free_stor_device(stor_device);
+		kfree(stor_device);
 		return ret;
 	}
 	device_info->path_id = stor_device->path_id;
@@ -422,7 +418,7 @@ int storvsc_dev_remove(struct hv_device *device)
 	/* Close the channel */
 	vmbus_close(device->channel);
 
-	free_stor_device(stor_device);
+	kfree(stor_device);
 	return 0;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 02/46] Staging: hv: storvsc: Do not aquire an unnecessary reference on stor_device
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 03/46] Staging: hv: storvsc: Rename must_get_stor_device() K. Y. Srinivasan
                     ` (43 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

On entry into storvsc_on_io_completion() we have already acquired a reference
on the stor_device; there is no need to acquire an additional reference here.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 8c62829..cd38cd6 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -232,9 +232,7 @@ static void storvsc_on_io_completion(struct hv_device *device,
 	struct storvsc_device *stor_device;
 	struct vstor_packet *stor_pkt;
 
-	stor_device = must_get_stor_device(device);
-	if (!stor_device)
-		return;
+	stor_device = (struct storvsc_device *)device->ext;
 
 	stor_pkt = &request->vstor_packet;
 
@@ -279,7 +277,6 @@ static void storvsc_on_io_completion(struct hv_device *device,
 		wake_up(&stor_device->waiting_to_drain);
 
 
-	put_stor_device(device);
 }
 
 static void storvsc_on_receive(struct hv_device *device,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 03/46] Staging: hv: storvsc: Rename must_get_stor_device()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 02/46] Staging: hv: storvsc: Do not aquire an unnecessary reference on stor_device K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 04/46] Staging: hv: storvsc: Rename get_stor_device() K. Y. Srinivasan
                     ` (42 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

In preparation for cleaning up how we manage reference counts on the stor
device, clearly distinguish why we are attempting to acquire a reference.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index cd38cd6..89708b1 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -41,7 +41,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 		return NULL;
 
 	/* Set to 2 to allow both inbound and outbound traffics */
-	/* (ie get_stor_device() and must_get_stor_device()) to proceed. */
+	/* (ie get_stor_device() and get_in_stor_device()) to proceed. */
 	atomic_cmpxchg(&stor_device->ref_count, 0, 2);
 
 	init_waitqueue_head(&stor_device->waiting_to_drain);
@@ -53,7 +53,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 
 
 /* Get the stordevice object iff exists and its refcount > 0 */
-static inline struct storvsc_device *must_get_stor_device(
+static inline struct storvsc_device *get_in_stor_device(
 					struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
@@ -305,7 +305,7 @@ static void storvsc_on_channel_callback(void *context)
 	int ret;
 
 
-	stor_device = must_get_stor_device(device);
+	stor_device = get_in_stor_device(device);
 	if (!stor_device)
 		return;
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 04/46] Staging: hv: storvsc: Rename get_stor_device()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 02/46] Staging: hv: storvsc: Do not aquire an unnecessary reference on stor_device K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 03/46] Staging: hv: storvsc: Rename must_get_stor_device() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 05/46] Staging: hv: storvsc: Cleanup alloc_stor_device() K. Y. Srinivasan
                     ` (41 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

In preparation for cleaning up how we manage reference counts on the stor
device, clearly distinguish why we are attempting to acquire a reference.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hyperv_storage.h |    3 ++-
 drivers/staging/hv/storvsc.c        |    8 ++++----
 drivers/staging/hv/storvsc_drv.c    |    2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h
index a01f9a0..a224413 100644
--- a/drivers/staging/hv/hyperv_storage.h
+++ b/drivers/staging/hv/hyperv_storage.h
@@ -288,7 +288,8 @@ struct storvsc_device {
 
 
 /* Get the stordevice object iff exists and its refcount > 1 */
-static inline struct storvsc_device *get_stor_device(struct hv_device *device)
+static inline struct storvsc_device *get_out_stor_device(
+					struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
 
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 89708b1..313a3f8 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -41,7 +41,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 		return NULL;
 
 	/* Set to 2 to allow both inbound and outbound traffics */
-	/* (ie get_stor_device() and get_in_stor_device()) to proceed. */
+	/* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */
 	atomic_cmpxchg(&stor_device->ref_count, 0, 2);
 
 	init_waitqueue_head(&stor_device->waiting_to_drain);
@@ -67,7 +67,7 @@ static inline struct storvsc_device *get_in_stor_device(
 	return stor_device;
 }
 
-/* Drop ref count to 1 to effectively disable get_stor_device() */
+/* Drop ref count to 1 to effectively disable get_out_stor_device() */
 static inline struct storvsc_device *release_stor_device(
 					struct hv_device *device)
 {
@@ -105,7 +105,7 @@ static int storvsc_channel_init(struct hv_device *device)
 	struct vstor_packet *vstor_packet;
 	int ret, t;
 
-	stor_device = get_stor_device(device);
+	stor_device = get_out_stor_device(device);
 	if (!stor_device)
 		return -ENODEV;
 
@@ -427,7 +427,7 @@ int storvsc_do_io(struct hv_device *device,
 	int ret = 0;
 
 	vstor_packet = &request->vstor_packet;
-	stor_device = get_stor_device(device);
+	stor_device = get_out_stor_device(device);
 
 	if (!stor_device)
 		return -ENODEV;
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index faa8d57..5b2004f 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -344,7 +344,7 @@ static int storvsc_host_reset(struct hv_device *device)
 	int ret, t;
 
 
-	stor_device = get_stor_device(device);
+	stor_device = get_out_stor_device(device);
 	if (!stor_device)
 		return -ENODEV;
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 05/46] Staging: hv: storvsc: Cleanup alloc_stor_device()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (2 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 04/46] Staging: hv: storvsc: Rename get_stor_device() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 06/46] Staging: hv: storvsc: Introduce state to manage the lifecycle of stor device K. Y. Srinivasan
                     ` (40 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Cleanup alloc_stor_device(), we can set the ref_count directly.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 313a3f8..48bd8da 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -42,7 +42,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 
 	/* Set to 2 to allow both inbound and outbound traffics */
 	/* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */
-	atomic_cmpxchg(&stor_device->ref_count, 0, 2);
+	atomic_set(&stor_device->ref_count, 2);
 
 	init_waitqueue_head(&stor_device->waiting_to_drain);
 	stor_device->device = device;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 06/46] Staging: hv: storvsc: Introduce state to manage the lifecycle of stor device
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (3 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 05/46] Staging: hv: storvsc: Cleanup alloc_stor_device() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 07/46] Staging: hv: storvsc: Prevent outgoing traffic when stor dev is being destroyed K. Y. Srinivasan
                     ` (39 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Introduce state to manage the lifecycle of stor device. This would be the
basis for managing the references on the stor object.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hyperv_storage.h |    2 +-
 drivers/staging/hv/storvsc.c        |    8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h
index a224413..d93bf93 100644
--- a/drivers/staging/hv/hyperv_storage.h
+++ b/drivers/staging/hv/hyperv_storage.h
@@ -266,7 +266,7 @@ struct storvsc_device {
 
 	/* 0 indicates the device is being destroyed */
 	atomic_t ref_count;
-
+	bool	 destroy;
 	bool	 drain_notify;
 	atomic_t num_outstanding_req;
 
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 48bd8da..0f8c609 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -43,7 +43,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 	/* Set to 2 to allow both inbound and outbound traffics */
 	/* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */
 	atomic_set(&stor_device->ref_count, 2);
-
+	stor_device->destroy = false;
 	init_waitqueue_head(&stor_device->waiting_to_drain);
 	stor_device->device = device;
 	device->ext = stor_device;
@@ -399,9 +399,15 @@ int storvsc_dev_add(struct hv_device *device,
 int storvsc_dev_remove(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
+	unsigned long flags;
+
 
 	stor_device = release_stor_device(device);
 
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
+	stor_device->destroy = true;
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+
 	/*
 	 * At this point, all outbound traffic should be disable. We
 	 * only allow inbound traffic (responses) to proceed so that
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 07/46] Staging: hv: storvsc: Prevent outgoing traffic when stor dev is being destroyed
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (4 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 06/46] Staging: hv: storvsc: Introduce state to manage the lifecycle of stor device K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 08/46] Staging: hv: storvsc: Get rid of release_stor_device() by inlining the code K. Y. Srinivasan
                     ` (38 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Prevent outgoing traffic when stor dev is destroyed.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hyperv_storage.h |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h
index d93bf93..1a59ca0 100644
--- a/drivers/staging/hv/hyperv_storage.h
+++ b/drivers/staging/hv/hyperv_storage.h
@@ -294,7 +294,8 @@ static inline struct storvsc_device *get_out_stor_device(
 	struct storvsc_device *stor_device;
 
 	stor_device = (struct storvsc_device *)device->ext;
-	if (stor_device && atomic_read(&stor_device->ref_count) > 1)
+	if (stor_device && (atomic_read(&stor_device->ref_count) > 1) &&
+		!stor_device->destroy)
 		atomic_inc(&stor_device->ref_count);
 	else
 		stor_device = NULL;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 08/46] Staging: hv: storvsc: Get rid of release_stor_device() by inlining the code
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (5 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 07/46] Staging: hv: storvsc: Prevent outgoing traffic when stor dev is being destroyed K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 09/46] Staging: hv: storvsc: Get rid of final_release_stor_device() by inlining code K. Y. Srinivasan
                     ` (37 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of release_stor_device() by inlining the code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc.c |   19 ++-----------------
 1 files changed, 2 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 0f8c609..1976a34 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -67,21 +67,6 @@ static inline struct storvsc_device *get_in_stor_device(
 	return stor_device;
 }
 
-/* Drop ref count to 1 to effectively disable get_out_stor_device() */
-static inline struct storvsc_device *release_stor_device(
-					struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = (struct storvsc_device *)device->ext;
-
-	/* Busy wait until the ref drop to 2, then set it to 1 */
-	while (atomic_cmpxchg(&stor_device->ref_count, 2, 1) != 2)
-		udelay(100);
-
-	return stor_device;
-}
-
 /* Drop ref count to 0. No one can use stor_device object. */
 static inline struct storvsc_device *final_release_stor_device(
 			struct hv_device *device)
@@ -401,8 +386,8 @@ int storvsc_dev_remove(struct hv_device *device)
 	struct storvsc_device *stor_device;
 	unsigned long flags;
 
-
-	stor_device = release_stor_device(device);
+	stor_device = (struct storvsc_device *)device->ext;
+	atomic_dec(&stor_device->ref_count);
 
 	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	stor_device->destroy = true;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 09/46] Staging: hv: storvsc: Get rid of final_release_stor_device() by inlining code
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (6 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 08/46] Staging: hv: storvsc: Get rid of release_stor_device() by inlining the code K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 10/46] Staging: hv: storvsc: Get rid of the reference counting in struct storvsc_device K. Y. Srinivasan
                     ` (36 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of final_release_stor_device() by inlining code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc.c |   23 ++++++-----------------
 1 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 1976a34..3e9829f 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -67,22 +67,6 @@ static inline struct storvsc_device *get_in_stor_device(
 	return stor_device;
 }
 
-/* Drop ref count to 0. No one can use stor_device object. */
-static inline struct storvsc_device *final_release_stor_device(
-			struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = (struct storvsc_device *)device->ext;
-
-	/* Busy wait until the ref drop to 1, then set it to 0 */
-	while (atomic_cmpxchg(&stor_device->ref_count, 1, 0) != 1)
-		udelay(100);
-
-	device->ext = NULL;
-	return stor_device;
-}
-
 static int storvsc_channel_init(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
@@ -401,7 +385,12 @@ int storvsc_dev_remove(struct hv_device *device)
 
 	storvsc_wait_to_drain(stor_device);
 
-	stor_device = final_release_stor_device(device);
+	/*
+	 * Since we have already drained, we don't need to busy wait
+	 * as was done in final_release_stor_device()
+	 */
+	atomic_set(&stor_device->ref_count, 0);
+	device->ext = NULL;
 
 	/* Close the channel */
 	vmbus_close(device->channel);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 10/46] Staging: hv: storvsc: Get rid of the reference counting in struct storvsc_device
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (7 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 09/46] Staging: hv: storvsc: Get rid of final_release_stor_device() by inlining code K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 11/46] Staging: hv: netvsc: Inline the code for free_net_device() K. Y. Srinivasan
                     ` (35 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of the reference counting in struct storvsc_device. We manage the lifecycle with 
the following logic: If the device is marked for destruction, we dot allow any
outgoing traffic on the device. Incoming traffic is allowed only to drain pending
outgoing traffic. Note that while the upper level code in Linux deals with outstanding
I/Os, we may have situations on Hyper-V where some book keeping messages are sent out
that the upper level Linux code may not be aware of.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hyperv_storage.h |   18 ++----------------
 drivers/staging/hv/storvsc.c        |   33 +++++++++++++++++++++------------
 drivers/staging/hv/storvsc_drv.c    |    1 -
 3 files changed, 23 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h
index 1a59ca0..687cdc5 100644
--- a/drivers/staging/hv/hyperv_storage.h
+++ b/drivers/staging/hv/hyperv_storage.h
@@ -264,8 +264,6 @@ struct storvsc_major_info {
 struct storvsc_device {
 	struct hv_device *device;
 
-	/* 0 indicates the device is being destroyed */
-	atomic_t ref_count;
 	bool	 destroy;
 	bool	 drain_notify;
 	atomic_t num_outstanding_req;
@@ -287,32 +285,20 @@ struct storvsc_device {
 };
 
 
-/* Get the stordevice object iff exists and its refcount > 1 */
 static inline struct storvsc_device *get_out_stor_device(
 					struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
 
 	stor_device = (struct storvsc_device *)device->ext;
-	if (stor_device && (atomic_read(&stor_device->ref_count) > 1) &&
-		!stor_device->destroy)
-		atomic_inc(&stor_device->ref_count);
-	else
+
+	if (stor_device && stor_device->destroy)
 		stor_device = NULL;
 
 	return stor_device;
 }
 
 
-static inline void put_stor_device(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = (struct storvsc_device *)device->ext;
-
-	atomic_dec(&stor_device->ref_count);
-}
-
 static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
 {
 	dev->drain_notify = true;
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 3e9829f..fb7b3ca 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -40,9 +40,6 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 	if (!stor_device)
 		return NULL;
 
-	/* Set to 2 to allow both inbound and outbound traffics */
-	/* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */
-	atomic_set(&stor_device->ref_count, 2);
 	stor_device->destroy = false;
 	init_waitqueue_head(&stor_device->waiting_to_drain);
 	stor_device->device = device;
@@ -52,19 +49,31 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 }
 
 
-/* Get the stordevice object iff exists and its refcount > 0 */
 static inline struct storvsc_device *get_in_stor_device(
 					struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
+	unsigned long flags;
 
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	stor_device = (struct storvsc_device *)device->ext;
-	if (stor_device && atomic_read(&stor_device->ref_count))
-		atomic_inc(&stor_device->ref_count);
-	else
+
+	if (!stor_device)
+		goto get_in_err;
+
+	/*
+	 * If the device is being destroyed; allow incoming
+	 * traffic only to cleanup outstanding requests.
+	 */
+
+	if (stor_device->destroy  &&
+		(atomic_read(&stor_device->num_outstanding_req) == 0))
 		stor_device = NULL;
 
+get_in_err:
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 	return stor_device;
+
 }
 
 static int storvsc_channel_init(struct hv_device *device)
@@ -190,7 +199,6 @@ static int storvsc_channel_init(struct hv_device *device)
 
 
 cleanup:
-	put_stor_device(device);
 	return ret;
 }
 
@@ -303,7 +311,6 @@ static void storvsc_on_channel_callback(void *context)
 		}
 	} while (1);
 
-	put_stor_device(device);
 	return;
 }
 
@@ -371,7 +378,6 @@ int storvsc_dev_remove(struct hv_device *device)
 	unsigned long flags;
 
 	stor_device = (struct storvsc_device *)device->ext;
-	atomic_dec(&stor_device->ref_count);
 
 	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	stor_device->destroy = true;
@@ -388,9 +394,13 @@ int storvsc_dev_remove(struct hv_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.
 	 */
-	atomic_set(&stor_device->ref_count, 0);
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	device->ext = NULL;
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 
 	/* Close the channel */
 	vmbus_close(device->channel);
@@ -448,7 +458,6 @@ int storvsc_do_io(struct hv_device *device,
 
 	atomic_inc(&stor_device->num_outstanding_req);
 
-	put_stor_device(device);
 	return ret;
 }
 
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 5b2004f..ae74f50 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -378,7 +378,6 @@ static int storvsc_host_reset(struct hv_device *device)
 	 */
 
 cleanup:
-	put_stor_device(device);
 	return ret;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 11/46] Staging: hv: netvsc: Inline the code for free_net_device()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (8 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 10/46] Staging: hv: storvsc: Get rid of the reference counting in struct storvsc_device K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 12/46] Staging: hv: netvsc: Cleanup alloc_net_device() K. Y. Srinivasan
                     ` (34 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Inline the code for free_net_device().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/netvsc.c |   12 ++----------
 1 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index b6e1fb9..75c6ed7 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -49,14 +49,6 @@ static struct netvsc_device *alloc_net_device(struct hv_device *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)
 {
@@ -438,7 +430,7 @@ int netvsc_device_remove(struct hv_device *device)
 		kfree(netvsc_packet);
 	}
 
-	free_net_device(net_device);
+	kfree(net_device);
 	return 0;
 }
 
@@ -980,7 +972,7 @@ cleanup:
 		release_outbound_net_device(device);
 		release_inbound_net_device(device);
 
-		free_net_device(net_device);
+		kfree(net_device);
 	}
 
 	return ret;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 12/46] Staging: hv: netvsc: Cleanup alloc_net_device()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (9 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 11/46] Staging: hv: netvsc: Inline the code for free_net_device() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 13/46] Staging: hv: netvsc: Introduce state to manage the lifecycle of net device K. Y. Srinivasan
                     ` (33 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Cleanup alloc_net_device(); we can directly set the refcnt.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/netvsc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 75c6ed7..7722102 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -41,7 +41,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
 		return NULL;
 
 	/* Set to 2 to allow both inbound and outbound traffic */
-	atomic_cmpxchg(&net_device->refcnt, 0, 2);
+	atomic_set(&net_device->refcnt, 2);
 
 	net_device->dev = device;
 	device->ext = net_device;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 13/46] Staging: hv: netvsc: Introduce state to manage the lifecycle of net device
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (10 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 12/46] Staging: hv: netvsc: Cleanup alloc_net_device() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 14/46] Staging: hv: netvsc: Prevent outgoing traffic when netvsc dev is destroyed K. Y. Srinivasan
                     ` (32 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Introduce state to manage the lifecycle of net device.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hyperv_net.h |    1 +
 drivers/staging/hv/netvsc.c     |    6 ++++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h
index 5782fea..0b347c1 100644
--- a/drivers/staging/hv/hyperv_net.h
+++ b/drivers/staging/hv/hyperv_net.h
@@ -371,6 +371,7 @@ struct netvsc_device {
 
 	atomic_t refcnt;
 	atomic_t num_outstanding_sends;
+	bool destroy;
 	/*
 	 * List of free preallocated hv_netvsc_packet to represent receive
 	 * packet
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 7722102..8eb4039 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -43,6 +43,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
 	/* Set to 2 to allow both inbound and outbound traffic */
 	atomic_set(&net_device->refcnt, 2);
 
+	net_device->destroy = false;
 	net_device->dev = device;
 	device->ext = net_device;
 
@@ -396,6 +397,7 @@ 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);
@@ -404,6 +406,10 @@ int netvsc_device_remove(struct hv_device *device)
 		return -ENODEV;
 	}
 
+	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,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 14/46] Staging: hv: netvsc: Prevent outgoing traffic when netvsc dev is destroyed
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (11 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 13/46] Staging: hv: netvsc: Introduce state to manage the lifecycle of net device K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 15/46] Staging: hv: netvsc: Get rid of release_outbound_net_device() by inlining the code K. Y. Srinivasan
                     ` (31 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Prevent outgoing traffic when netvsc dev is destroyed.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/netvsc.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 8eb4039..67065c1 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -56,7 +56,8 @@ 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)
+	if (net_device && (atomic_read(&net_device->refcnt) > 1) &&
+		!net_device->destroy)
 		atomic_inc(&net_device->refcnt);
 	else
 		net_device = NULL;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 15/46] Staging: hv: netvsc: Get rid of release_outbound_net_device() by inlining the code
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (12 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 14/46] Staging: hv: netvsc: Prevent outgoing traffic when netvsc dev is destroyed K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 16/46] Staging: hv: netvsc: Get rid of release_inbound_net_device() " K. Y. Srinivasan
                     ` (30 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of release_outbound_net_device() by inlining the code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/netvsc.c |   38 ++++++++++++++------------------------
 1 files changed, 14 insertions(+), 24 deletions(-)

diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 67065c1..e46161d 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -88,22 +88,6 @@ static void put_net_device(struct hv_device *device)
 	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;
-
-	/* Busy wait until the ref drop to 2, then set it to 1 */
-	while (atomic_cmpxchg(&net_device->refcnt, 2, 1) != 2)
-		udelay(100);
-
-	return net_device;
-}
-
 static struct netvsc_device *release_inbound_net_device(
 		struct hv_device *device)
 {
@@ -400,13 +384,8 @@ int netvsc_device_remove(struct hv_device *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 -ENODEV;
-	}
-
+	net_device = (struct netvsc_device *)device->ext;
+	atomic_dec(&net_device->refcnt);
 	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	net_device->destroy = true;
 	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
@@ -424,6 +403,18 @@ int netvsc_device_remove(struct hv_device *device)
 	/* Stop inbound traffic ie receives and sends completions */
 	net_device = release_inbound_net_device(device);
 
+	/*
+	 * Wait until the ref cnt falls to 0.
+	 * We have already stopped any new references
+	 * for outgoing traffic. Also, at this point we don't have any
+	 * incoming traffic as well. So this must be outgoing refrences
+	 * established prior to marking the device as being destroyed.
+	 * Since the send path is non-blocking, it is reasonable to busy
+	 * wait here.
+	 */
+	while (atomic_read(&net_device->refcnt))
+		udelay(100);
+
 	/* At this point, no one should be accessing netDevice except in here */
 	dev_notice(&device->device, "net device safe to remove");
 
@@ -976,7 +967,6 @@ cleanup:
 			kfree(packet);
 		}
 
-		release_outbound_net_device(device);
 		release_inbound_net_device(device);
 
 		kfree(net_device);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 0000/0046] Staging: hv: Driver cleanup
@ 2011-08-27 18:31 K. Y. Srinivasan
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                   ` (2 more replies)
  0 siblings, 3 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization; +Cc: K. Y. Srinivasan

Further cleanup of the hv drivers. 

	1) Cleanup reference counting.

	2) Handle all block devices using the storvsc driver. I have modified
	   the implementation here based on Christoph's feedback on my earlier
	   implementation.

	3) Fix bugs.

	4) Accomodate some host side scsi emulation bugs.

	5) In case of scsi errors off-line the device.

This patch-set further reduces the size of Hyper-V drivers - the code is
about 10% smaller. This reduction is mainly because we have eliminated the
blkvsc driver.


Regards,

K. Y


^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 16/46] Staging: hv: netvsc: Get rid of release_inbound_net_device() by inlining the code
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (13 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 15/46] Staging: hv: netvsc: Get rid of release_outbound_net_device() by inlining the code K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 17/46] Staging: hv: netvsc: Get rid of the refcnt field in struct netvsc_device K. Y. Srinivasan
                     ` (29 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of release_inbound_net_device() by inlining the code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/netvsc.c |   24 ++----------------------
 1 files changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index e46161d..388f083 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -88,23 +88,6 @@ static void put_net_device(struct hv_device *device)
 	atomic_dec(&net_device->refcnt);
 }
 
-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;
@@ -400,9 +383,8 @@ int netvsc_device_remove(struct hv_device *device)
 
 	netvsc_disconnect_vsp(net_device);
 
-	/* Stop inbound traffic ie receives and sends completions */
-	net_device = release_inbound_net_device(device);
-
+	atomic_dec(&net_device->refcnt);
+	device->ext = NULL;
 	/*
 	 * Wait until the ref cnt falls to 0.
 	 * We have already stopped any new references
@@ -967,8 +949,6 @@ cleanup:
 			kfree(packet);
 		}
 
-		release_inbound_net_device(device);
-
 		kfree(net_device);
 	}
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 17/46] Staging: hv: netvsc: Get rid of the refcnt field in struct netvsc_device
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (14 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 16/46] Staging: hv: netvsc: Get rid of release_inbound_net_device() " K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver K. Y. Srinivasan
                     ` (28 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of the refcnt field in struct netvsc_device. We implement the following
logic to manage the life cycle of the device: If the device is being destroyed,
we do not allow any outgoing traffic. Furthermore, if the device is being 
destroyed, we allow incoming traffic only to drain outgoing traffic. Note that
the driver may send some book keeping messages to the host not known to 
upper level Linux code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hyperv_net.h |    1 -
 drivers/staging/hv/netvsc.c     |   62 ++++++++++++--------------------------
 2 files changed, 20 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h
index 0b347c1..af8a37f 100644
--- a/drivers/staging/hv/hyperv_net.h
+++ b/drivers/staging/hv/hyperv_net.h
@@ -369,7 +369,6 @@ struct nvsp_message {
 struct netvsc_device {
 	struct hv_device *dev;
 
-	atomic_t refcnt;
 	atomic_t num_outstanding_sends;
 	bool destroy;
 	/*
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 388f083..9828f0b 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -40,8 +40,6 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
 	if (!net_device)
 		return NULL;
 
-	/* Set to 2 to allow both inbound and outbound traffic */
-	atomic_set(&net_device->refcnt, 2);
 
 	net_device->destroy = false;
 	net_device->dev = device;
@@ -50,43 +48,37 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device)
 	return net_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) &&
-		!net_device->destroy)
-		atomic_inc(&net_device->refcnt);
-	else
+	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;
+	unsigned long flags;
 
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	net_device = device->ext;
-	if (net_device && atomic_read(&net_device->refcnt))
-		atomic_inc(&net_device->refcnt);
-	else
+
+	if (!net_device)
+		goto get_in_err;
+
+	if (net_device->destroy &&
+		atomic_read(&net_device->num_outstanding_sends) == 0)
 		net_device = NULL;
 
+get_in_err:
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 	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 int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
 {
@@ -268,7 +260,6 @@ cleanup:
 	netvsc_destroy_recv_buf(net_device);
 
 exit:
-	put_net_device(device);
 	return ret;
 }
 
@@ -349,7 +340,6 @@ static int netvsc_connect_vsp(struct hv_device *device)
 	ret = netvsc_init_recv_buf(device);
 
 cleanup:
-	put_net_device(device);
 	return ret;
 }
 
@@ -368,7 +358,6 @@ int netvsc_device_remove(struct hv_device *device)
 	unsigned long flags;
 
 	net_device = (struct netvsc_device *)device->ext;
-	atomic_dec(&net_device->refcnt);
 	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	net_device->destroy = true;
 	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
@@ -383,19 +372,17 @@ int netvsc_device_remove(struct hv_device *device)
 
 	netvsc_disconnect_vsp(net_device);
 
-	atomic_dec(&net_device->refcnt);
-	device->ext = NULL;
 	/*
-	 * Wait until the ref cnt falls to 0.
-	 * We have already stopped any new references
-	 * for outgoing traffic. Also, at this point we don't have any
-	 * incoming traffic as well. So this must be outgoing refrences
-	 * established prior to marking the device as being destroyed.
-	 * Since the send path is non-blocking, it is reasonable to busy
-	 * wait here.
+	 * 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.
 	 */
-	while (atomic_read(&net_device->refcnt))
-		udelay(100);
+
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
+	device->ext = 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");
@@ -456,7 +443,6 @@ static void netvsc_send_completion(struct hv_device *device,
 			   "%d received!!", nvsp_packet->hdr.msg_type);
 	}
 
-	put_net_device(device);
 }
 
 int netvsc_send(struct hv_device *device,
@@ -509,7 +495,6 @@ int netvsc_send(struct hv_device *device,
 			   packet, ret);
 
 	atomic_inc(&net_device->num_outstanding_sends);
-	put_net_device(device);
 	return ret;
 }
 
@@ -602,7 +587,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,
@@ -636,7 +620,6 @@ static void netvsc_receive(struct hv_device *device,
 	if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) {
 		dev_err(&device->device, "Unknown packet type received - %d",
 			   packet->type);
-		put_net_device(device);
 		return;
 	}
 
@@ -648,7 +631,6 @@ static void netvsc_receive(struct hv_device *device,
 	    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);
 		return;
 	}
 
@@ -658,7 +640,6 @@ static void netvsc_receive(struct hv_device *device,
 		dev_err(&device->device, "Invalid xfer page set id - "
 			   "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
 			   vmxferpage_packet->xfer_pageset_id);
-		put_net_device(device);
 		return;
 	}
 
@@ -698,7 +679,6 @@ static void netvsc_receive(struct hv_device *device,
 		netvsc_send_recv_completion(device,
 					    vmxferpage_packet->d.trans_id);
 
-		put_net_device(device);
 		return;
 	}
 
@@ -786,7 +766,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)
@@ -869,7 +848,6 @@ static void netvsc_channel_cb(void *context)
 		}
 	} while (1);
 
-	put_net_device(device);
 out:
 	kfree(buffer);
 	return;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (15 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 17/46] Staging: hv: netvsc: Get rid of the refcnt field in struct netvsc_device K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-30 11:07     ` Dan Carpenter
  2011-08-27 18:31   ` [PATCH 19/46] Staging: hv: storvsc: Handle " K. Y. Srinivasan
                     ` (27 subsequent siblings)
  44 siblings, 1 reply; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Add code to handle IDE devices using the storvsc driver. The storvsc_probe()
is modified so that the storvsc driver can surface all disks presented to the
guest as scsi devices using generic upper level Linux scsi drivers.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   60 ++++++++++++++++++++++++++++++++-----
 1 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index ae74f50..f434200 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -59,6 +59,17 @@ struct storvsc_cmd_request {
 	struct hv_storvsc_request request;
 };
 
+static void storvsc_get_ide_info(struct hv_device *dev, int *target, int *path)
+{
+	*target =
+		dev->dev_instance.b[5] << 8 | dev->dev_instance.b[4];
+
+	*path =
+		dev->dev_instance.b[3] << 24 |
+		dev->dev_instance.b[2] << 16 |
+		dev->dev_instance.b[1] << 8  | dev->dev_instance.b[0];
+}
+
 
 static int storvsc_device_alloc(struct scsi_device *sdevice)
 {
@@ -642,6 +653,20 @@ static const struct hv_vmbus_device_id id_table[] = {
 };
 
 MODULE_DEVICE_TABLE(vmbus, id_table);
+
+/*
+ * This declaration is temporary; once we get the
+ * infrastructure in place, we will integrate with
+ * id_table.
+ */
+
+static const uuid_le ide_blk_guid = {
+	.b = {
+		0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
+		0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
+	}
+};
+
 /*
  * storvsc_probe - Add a new device for this driver
  */
@@ -652,6 +677,14 @@ 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;
+	int path = 0;
+	int target = 0;
+
+	if (!uuid_le_cmp(device->dev_type, ide_blk_guid))
+		dev_is_ide = true;
+	else
+		dev_is_ide = false;
 
 	host = scsi_host_alloc(&scsi_driver,
 			       sizeof(struct hv_host_device));
@@ -687,6 +720,9 @@ static int storvsc_probe(struct hv_device *device)
 		return -ENODEV;
 	}
 
+	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;
 
@@ -699,17 +735,25 @@ static int storvsc_probe(struct hv_device *device)
 
 	/* Register the HBA and start the scsi bus scan */
 	ret = scsi_add_host(host, &device->device);
-	if (ret != 0) {
-
-		storvsc_dev_remove(device);
+	if (ret != 0)
+		goto err_out;
 
-		kmem_cache_destroy(host_dev->request_pool);
-		scsi_host_put(host);
-		return -ENODEV;
+	if (!dev_is_ide) {
+		scsi_scan_host(host);
+		return 0;
+	}
+	ret = scsi_add_device(host, 0, target, 0);
+	if (ret) {
+		scsi_remove_host(host);
+		goto err_out;
 	}
+	return 0;
 
-	scsi_scan_host(host);
-	return ret;
+err_out:
+	storvsc_dev_remove(device);
+	kmem_cache_destroy(host_dev->request_pool);
+	scsi_host_put(host);
+	return -ENODEV;
 }
 
 /* The one and only one */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 19/46]  Staging: hv: storvsc: Handle IDE devices using the storvsc driver
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (16 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 20/46] Staging: hv: blkvsc: Get rid of blkvsc_drv.c as this code is not used K. Y. Srinivasan
                     ` (26 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Now, enable handling of all IDE devices by extending the storvsc
device id table to handle IDE guid. As part of this cleanup Kconfig
and Hyper-V Makefile to not build the IDE driver (blkvsc).

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/Kconfig       |    7 -------
 drivers/staging/hv/Makefile      |    2 --
 drivers/staging/hv/storvsc_drv.c |   21 ++++++++-------------
 3 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig
index 5e0c9f6..26b5064 100644
--- a/drivers/staging/hv/Kconfig
+++ b/drivers/staging/hv/Kconfig
@@ -15,13 +15,6 @@ config HYPERV_STORAGE
 	help
 	 Select this option to enable the Hyper-V virtual storage driver.
 
-config HYPERV_BLOCK
-	tristate "Microsoft Hyper-V virtual block driver"
-	depends on BLOCK && SCSI && (LBDAF || 64BIT)
-	default HYPERV
-	help
-	  Select this option to enable the Hyper-V virtual block driver.
-
 config HYPERV_NET
 	tristate "Microsoft Hyper-V virtual network driver"
 	depends on NET
diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile
index 3004674..bb89437 100644
--- a/drivers/staging/hv/Makefile
+++ b/drivers/staging/hv/Makefile
@@ -1,6 +1,5 @@
 obj-$(CONFIG_HYPERV)		+= hv_vmbus.o hv_timesource.o
 obj-$(CONFIG_HYPERV_STORAGE)	+= hv_storvsc.o
-obj-$(CONFIG_HYPERV_BLOCK)	+= hv_blkvsc.o
 obj-$(CONFIG_HYPERV_NET)	+= hv_netvsc.o
 obj-$(CONFIG_HYPERV_UTILS)	+= hv_utils.o
 obj-$(CONFIG_HYPERV_MOUSE)	+= hv_mouse.o
@@ -9,6 +8,5 @@ hv_vmbus-y := vmbus_drv.o \
 		 hv.o connection.o channel.o \
 		 channel_mgmt.o ring_buffer.o
 hv_storvsc-y := storvsc_drv.o storvsc.o
-hv_blkvsc-y := blkvsc_drv.o  storvsc.o
 hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o
 hv_utils-y := hv_util.o hv_kvp.o
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index f434200..9464f99 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -645,27 +645,22 @@ static struct scsi_host_template scsi_driver = {
 	.dma_boundary =		PAGE_SIZE-1,
 };
 
+/*
+ * The storvsc_probe function assumes that the IDE guid
+ * is the second entry.
+ */
 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) },
+	/* IDE guid */
+	{ VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
+		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) },
 	{ },
 };
 
 MODULE_DEVICE_TABLE(vmbus, id_table);
 
-/*
- * This declaration is temporary; once we get the
- * infrastructure in place, we will integrate with
- * id_table.
- */
-
-static const uuid_le ide_blk_guid = {
-	.b = {
-		0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
-		0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
-	}
-};
 
 /*
  * storvsc_probe - Add a new device for this driver
@@ -681,7 +676,7 @@ static int storvsc_probe(struct hv_device *device)
 	int path = 0;
 	int target = 0;
 
-	if (!uuid_le_cmp(device->dev_type, ide_blk_guid))
+	if (!memcmp(&device->dev_type.b, id_table[1].guid, sizeof(uuid_le)))
 		dev_is_ide = true;
 	else
 		dev_is_ide = false;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 20/46] Staging: hv: blkvsc: Get rid of blkvsc_drv.c as this code is not used
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (17 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 19/46] Staging: hv: storvsc: Handle " K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 21/46] Staging: hv: storvsc: Optimize bounce buffer handling for the "write" case K. Y. Srinivasan
                     ` (25 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Now that blkvsc driver is no longer needed, remove blkvsc_drv.c

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/blkvsc_drv.c | 1014 ---------------------------------------
 1 files changed, 0 insertions(+), 1014 deletions(-)
 delete mode 100644 drivers/staging/hv/blkvsc_drv.c

diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
deleted file mode 100644
index 2b41eb6..0000000
--- a/drivers/staging/hv/blkvsc_drv.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- * Copyright (c) 2009, Microsoft Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *   K. Y. Srinivasan <kys@microsoft.com>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/blkdev.h>
-#include <linux/major.h>
-#include <linux/delay.h>
-#include <linux/hdreg.h>
-#include <linux/slab.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_dbg.h>
-
-#include "hyperv.h"
-#include "hyperv_storage.h"
-
-
-#define BLKVSC_MINORS	64
-
-enum blkvsc_device_type {
-	UNKNOWN_DEV_TYPE,
-	HARDDISK_TYPE,
-	DVD_TYPE,
-};
-
-enum blkvsc_op_type {
-	DO_INQUIRY,
-	DO_CAPACITY,
-	DO_FLUSH,
-};
-
-/*
- * This request ties the struct request and struct
- * blkvsc_request/hv_storvsc_request together A struct request may be
- * represented by 1 or more struct blkvsc_request
- */
-struct blkvsc_request_group {
-	int outstanding;
-	int status;
-	struct list_head blkvsc_req_list;	/* list of blkvsc_requests */
-};
-
-struct blkvsc_request {
-	/* blkvsc_request_group.blkvsc_req_list */
-	struct list_head req_entry;
-
-	/* block_device_context.pending_list */
-	struct list_head pend_entry;
-
-	/* This may be null if we generate a request internally */
-	struct request *req;
-
-	struct block_device_context *dev;
-
-	/* The group this request is part of. Maybe null */
-	struct blkvsc_request_group *group;
-
-	int write;
-	sector_t sector_start;
-	unsigned long sector_count;
-
-	unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
-	unsigned char cmd_len;
-	unsigned char cmnd[MAX_COMMAND_SIZE];
-
-	struct hv_storvsc_request request;
-};
-
-/* Per device structure */
-struct block_device_context {
-	/* point back to our device context */
-	struct hv_device *device_ctx;
-	struct kmem_cache *request_pool;
-	spinlock_t lock;
-	struct gendisk *gd;
-	enum blkvsc_device_type	device_type;
-	struct list_head pending_list;
-
-	unsigned char device_id[64];
-	unsigned int device_id_len;
-	int num_outstanding_reqs;
-	int shutting_down;
-	unsigned int sector_size;
-	sector_t capacity;
-	unsigned int port;
-	unsigned char path;
-	unsigned char target;
-	int users;
-};
-
-
-/*
- * There is a circular dependency involving blkvsc_request_completion()
- * and blkvsc_do_request().
- */
-static void blkvsc_request_completion(struct hv_storvsc_request *request);
-
-static int blkvsc_ringbuffer_size = BLKVSC_RING_BUFFER_SIZE;
-
-module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(ring_size, "Ring buffer size (in bytes)");
-
-/*
- * There is a circular dependency involving blkvsc_probe()
- * and block_ops.
- */
-static int blkvsc_probe(struct hv_device *dev);
-
-static int blkvsc_device_add(struct hv_device *device,
-				void *additional_info)
-{
-	struct storvsc_device_info *device_info;
-	int ret = 0;
-
-	device_info = (struct storvsc_device_info *)additional_info;
-
-	device_info->ring_buffer_size = blkvsc_ringbuffer_size;
-
-	ret = storvsc_dev_add(device, additional_info);
-	if (ret != 0)
-		return ret;
-
-	/*
-	 * We need to use the device instance guid to set the path and target
-	 * id. For IDE devices, the device instance id is formatted as
-	 * <bus id> * - <device id> - 8899 - 000000000000.
-	 */
-	device_info->path_id = device->dev_instance.b[3] << 24 |
-			     device->dev_instance.b[2] << 16 |
-			     device->dev_instance.b[1] << 8  |
-			     device->dev_instance.b[0];
-
-	device_info->target_id = device->dev_instance.b[5] << 8 |
-			       device->dev_instance.b[4];
-
-	return ret;
-}
-
-static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
-			void (*request_completion)(struct hv_storvsc_request *))
-{
-	struct block_device_context *blkdev = blkvsc_req->dev;
-	struct hv_storvsc_request *storvsc_req;
-	struct vmscsi_request *vm_srb;
-	int ret;
-
-
-	storvsc_req = &blkvsc_req->request;
-	vm_srb = &storvsc_req->vstor_packet.vm_srb;
-
-	vm_srb->data_in = blkvsc_req->write ? WRITE_TYPE : READ_TYPE;
-
-	storvsc_req->on_io_completion = request_completion;
-	storvsc_req->context = blkvsc_req;
-
-	vm_srb->port_number = blkdev->port;
-	vm_srb->path_id = blkdev->path;
-	vm_srb->target_id = blkdev->target;
-	vm_srb->lun = 0;	 /* this is not really used at all */
-
-	vm_srb->cdb_length = blkvsc_req->cmd_len;
-
-	memcpy(vm_srb->cdb, blkvsc_req->cmnd, vm_srb->cdb_length);
-
-	storvsc_req->sense_buffer = blkvsc_req->sense_buffer;
-
-	ret =  storvsc_do_io(blkdev->device_ctx,
-					   &blkvsc_req->request);
-	if (ret == 0)
-		blkdev->num_outstanding_reqs++;
-
-	return ret;
-}
-
-
-static int blkvsc_open(struct block_device *bdev, fmode_t mode)
-{
-	struct block_device_context *blkdev = bdev->bd_disk->private_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-
-	blkdev->users++;
-
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-
-	return 0;
-}
-
-
-static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg)
-{
-	sector_t nsect = get_capacity(bd->bd_disk);
-	sector_t cylinders = nsect;
-
-	/*
-	 * We are making up these values; let us keep it simple.
-	 */
-	hg->heads = 0xff;
-	hg->sectors = 0x3f;
-	sector_div(cylinders, hg->heads * hg->sectors);
-	hg->cylinders = cylinders;
-	if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
-		hg->cylinders = 0xffff;
-	return 0;
-
-}
-
-
-static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req)
-{
-
-	blkvsc_req->cmd_len = 16;
-
-	if (rq_data_dir(blkvsc_req->req)) {
-		blkvsc_req->write = 1;
-		blkvsc_req->cmnd[0] = WRITE_16;
-	} else {
-		blkvsc_req->write = 0;
-		blkvsc_req->cmnd[0] = READ_16;
-	}
-
-	blkvsc_req->cmnd[1] |=
-	(blkvsc_req->req->cmd_flags & REQ_FUA) ? 0x8 : 0;
-
-	*(unsigned long long *)&blkvsc_req->cmnd[2] =
-	cpu_to_be64(blkvsc_req->sector_start);
-	*(unsigned int *)&blkvsc_req->cmnd[10] =
-	cpu_to_be32(blkvsc_req->sector_count);
-}
-
-
-static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
-			unsigned cmd, unsigned long arg)
-{
-	struct block_device_context *blkdev = bd->bd_disk->private_data;
-	int ret = 0;
-
-	switch (cmd) {
-	case HDIO_GET_IDENTITY:
-		if (copy_to_user((void __user *)arg, blkdev->device_id,
-				 blkdev->device_id_len))
-			ret = -EFAULT;
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static void blkvsc_cmd_completion(struct hv_storvsc_request *request)
-{
-	struct blkvsc_request *blkvsc_req =
-			(struct blkvsc_request *)request->context;
-	struct block_device_context *blkdev =
-			(struct block_device_context *)blkvsc_req->dev;
-	struct scsi_sense_hdr sense_hdr;
-	struct vmscsi_request *vm_srb;
-	unsigned long flags;
-
-
-	vm_srb = &blkvsc_req->request.vstor_packet.vm_srb;
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-	blkdev->num_outstanding_reqs--;
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-
-	if (vm_srb->scsi_status)
-		if (scsi_normalize_sense(blkvsc_req->sense_buffer,
-					 SCSI_SENSE_BUFFERSIZE, &sense_hdr))
-			scsi_print_sense_hdr("blkvsc", &sense_hdr);
-
-	complete(&blkvsc_req->request.wait_event);
-}
-
-
-static int blkvsc_do_operation(struct block_device_context *blkdev,
-				enum blkvsc_op_type op)
-{
-	struct blkvsc_request *blkvsc_req;
-	struct page *page_buf;
-	unsigned char *buf;
-	unsigned char device_type;
-	struct scsi_sense_hdr sense_hdr;
-	struct vmscsi_request *vm_srb;
-	unsigned long flags;
-
-	int ret = 0;
-
-	blkvsc_req = kmem_cache_zalloc(blkdev->request_pool, GFP_KERNEL);
-	if (!blkvsc_req)
-		return -ENOMEM;
-
-	page_buf = alloc_page(GFP_KERNEL);
-	if (!page_buf) {
-		kmem_cache_free(blkdev->request_pool, blkvsc_req);
-		return -ENOMEM;
-	}
-
-	vm_srb = &blkvsc_req->request.vstor_packet.vm_srb;
-	init_completion(&blkvsc_req->request.wait_event);
-	blkvsc_req->dev = blkdev;
-	blkvsc_req->req = NULL;
-	blkvsc_req->write = 0;
-
-	blkvsc_req->request.data_buffer.pfn_array[0] =
-	page_to_pfn(page_buf);
-	blkvsc_req->request.data_buffer.offset = 0;
-
-	switch (op) {
-	case DO_INQUIRY:
-		blkvsc_req->cmnd[0] = INQUIRY;
-		blkvsc_req->cmnd[1] = 0x1;		/* Get product data */
-		blkvsc_req->cmnd[2] = 0x83;		/* mode page 83 */
-		blkvsc_req->cmnd[4] = 64;
-		blkvsc_req->cmd_len = 6;
-		blkvsc_req->request.data_buffer.len = 64;
-		break;
-
-	case DO_CAPACITY:
-		blkdev->sector_size = 0;
-		blkdev->capacity = 0;
-
-		blkvsc_req->cmnd[0] = READ_CAPACITY;
-		blkvsc_req->cmd_len = 16;
-		blkvsc_req->request.data_buffer.len = 8;
-		break;
-
-	case DO_FLUSH:
-		blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE;
-		blkvsc_req->cmd_len = 10;
-		blkvsc_req->request.data_buffer.pfn_array[0] = 0;
-		blkvsc_req->request.data_buffer.len = 0;
-		break;
-	default:
-		ret = -EINVAL;
-		goto cleanup;
-	}
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-
-	wait_for_completion_interruptible(&blkvsc_req->request.wait_event);
-
-	/* check error */
-	if (vm_srb->scsi_status) {
-		scsi_normalize_sense(blkvsc_req->sense_buffer,
-				     SCSI_SENSE_BUFFERSIZE, &sense_hdr);
-
-		return 0;
-	}
-
-	buf = kmap(page_buf);
-
-	switch (op) {
-	case DO_INQUIRY:
-		device_type = buf[0] & 0x1F;
-
-		if (device_type == 0x0)
-			blkdev->device_type = HARDDISK_TYPE;
-		 else
-			blkdev->device_type = UNKNOWN_DEV_TYPE;
-
-		blkdev->device_id_len = buf[7];
-		if (blkdev->device_id_len > 64)
-			blkdev->device_id_len = 64;
-
-		memcpy(blkdev->device_id, &buf[8], blkdev->device_id_len);
-		break;
-
-	case DO_CAPACITY:
-		/* be to le */
-		blkdev->capacity =
-		((buf[0] << 24) | (buf[1] << 16) |
-		(buf[2] << 8) | buf[3]) + 1;
-
-		blkdev->sector_size =
-		(buf[4] << 24) | (buf[5] << 16) |
-		(buf[6] << 8) | buf[7];
-		break;
-	default:
-		break;
-
-	}
-
-cleanup:
-
-	kunmap(page_buf);
-
-	__free_page(page_buf);
-
-	kmem_cache_free(blkdev->request_pool, blkvsc_req);
-
-	return ret;
-}
-
-
-static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev)
-{
-	struct blkvsc_request *pend_req, *tmp;
-	struct blkvsc_request *comp_req, *tmp2;
-	struct vmscsi_request *vm_srb;
-
-	int ret = 0;
-
-
-	/* Flush the pending list first */
-	list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
-				 pend_entry) {
-		/*
-		 * The pend_req could be part of a partially completed
-		 * request. If so, complete those req first until we
-		 * hit the pend_req
-		 */
-		list_for_each_entry_safe(comp_req, tmp2,
-					 &pend_req->group->blkvsc_req_list,
-					 req_entry) {
-
-			if (comp_req == pend_req)
-				break;
-
-			list_del(&comp_req->req_entry);
-
-			if (comp_req->req) {
-				vm_srb =
-				&comp_req->request.vstor_packet.
-				vm_srb;
-				ret = __blk_end_request(comp_req->req,
-					(!vm_srb->scsi_status ? 0 : -EIO),
-					comp_req->sector_count *
-					blkdev->sector_size);
-
-				/* FIXME: shouldn't this do more than return? */
-				if (ret)
-					goto out;
-			}
-
-			kmem_cache_free(blkdev->request_pool, comp_req);
-		}
-
-		list_del(&pend_req->pend_entry);
-
-		list_del(&pend_req->req_entry);
-
-		if (comp_req->req) {
-			if (!__blk_end_request(pend_req->req, -EIO,
-					       pend_req->sector_count *
-					       blkdev->sector_size)) {
-				/*
-				 * All the sectors have been xferred ie the
-				 * request is done
-				 */
-				kmem_cache_free(blkdev->request_pool,
-						pend_req->group);
-			}
-		}
-
-		kmem_cache_free(blkdev->request_pool, pend_req);
-	}
-
-out:
-	return ret;
-}
-
-
-/*
- * blkvsc_remove() - Callback when our device is removed
- */
-static int blkvsc_remove(struct hv_device *dev)
-{
-	struct block_device_context *blkdev = dev_get_drvdata(&dev->device);
-	unsigned long flags;
-
-
-	/* Get to a known state */
-	spin_lock_irqsave(&blkdev->lock, flags);
-
-	blkdev->shutting_down = 1;
-
-	blk_stop_queue(blkdev->gd->queue);
-
-	blkvsc_cancel_pending_reqs(blkdev);
-
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-
-	blkvsc_do_operation(blkdev, DO_FLUSH);
-
-	if (blkdev->users == 0) {
-		del_gendisk(blkdev->gd);
-		put_disk(blkdev->gd);
-		blk_cleanup_queue(blkdev->gd->queue);
-
-		storvsc_dev_remove(blkdev->device_ctx);
-
-		kmem_cache_destroy(blkdev->request_pool);
-		kfree(blkdev);
-	}
-
-	return 0;
-}
-
-static void blkvsc_shutdown(struct hv_device *dev)
-{
-	struct block_device_context *blkdev = dev_get_drvdata(&dev->device);
-	unsigned long flags;
-
-	if (!blkdev)
-		return;
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-
-	blkdev->shutting_down = 1;
-
-	blk_stop_queue(blkdev->gd->queue);
-
-	blkvsc_cancel_pending_reqs(blkdev);
-
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-
-	blkvsc_do_operation(blkdev, DO_FLUSH);
-
-	/*
-	 * Now wait for all outgoing I/O to be drained.
-	 */
-	storvsc_wait_to_drain((struct storvsc_device *)dev->ext);
-
-}
-
-static int blkvsc_release(struct gendisk *disk, fmode_t mode)
-{
-	struct block_device_context *blkdev = disk->private_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-
-	if ((--blkdev->users == 0) && (blkdev->shutting_down)) {
-		blk_stop_queue(blkdev->gd->queue);
-		spin_unlock_irqrestore(&blkdev->lock, flags);
-
-		blkvsc_do_operation(blkdev, DO_FLUSH);
-		del_gendisk(blkdev->gd);
-		put_disk(blkdev->gd);
-		blk_cleanup_queue(blkdev->gd->queue);
-
-		storvsc_dev_remove(blkdev->device_ctx);
-
-		kmem_cache_destroy(blkdev->request_pool);
-		kfree(blkdev);
-	} else
-		spin_unlock_irqrestore(&blkdev->lock, flags);
-
-	return 0;
-}
-
-
-/*
- * We break the request into 1 or more blkvsc_requests and submit
- * them.  If we cant submit them all, we put them on the
- * pending_list. The blkvsc_request() will work on the pending_list.
- */
-static int blkvsc_do_request(struct block_device_context *blkdev,
-			     struct request *req)
-{
-	struct bio *bio = NULL;
-	struct bio_vec *bvec = NULL;
-	struct bio_vec *prev_bvec = NULL;
-	struct blkvsc_request *blkvsc_req = NULL;
-	struct blkvsc_request *tmp;
-	int databuf_idx = 0;
-	int seg_idx = 0;
-	sector_t start_sector;
-	unsigned long num_sectors = 0;
-	int ret = 0;
-	int pending = 0;
-	struct blkvsc_request_group *group = NULL;
-
-	/* Create a group to tie req to list of blkvsc_reqs */
-	group = kmem_cache_zalloc(blkdev->request_pool, GFP_ATOMIC);
-	if (!group)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&group->blkvsc_req_list);
-	group->outstanding = group->status = 0;
-
-	start_sector = blk_rq_pos(req);
-
-	/* foreach bio in the request */
-	if (req->bio) {
-		for (bio = req->bio; bio; bio = bio->bi_next) {
-			/*
-			 * Map this bio into an existing or new storvsc request
-			 */
-			bio_for_each_segment(bvec, bio, seg_idx) {
-				/* Get a new storvsc request */
-				/* 1st-time */
-				if ((!blkvsc_req) ||
-				    (databuf_idx >= MAX_MULTIPAGE_BUFFER_COUNT)
-				    /* hole at the begin of page */
-				    || (bvec->bv_offset != 0) ||
-				    /* hold at the end of page */
-				    (prev_bvec &&
-				     (prev_bvec->bv_len != PAGE_SIZE))) {
-					/* submit the prev one */
-					if (blkvsc_req) {
-						blkvsc_req->sector_start =
-						start_sector;
-						sector_div(
-						blkvsc_req->sector_start,
-						(blkdev->sector_size >> 9));
-
-						blkvsc_req->sector_count =
-						num_sectors /
-						(blkdev->sector_size >> 9);
-						blkvsc_init_rw(blkvsc_req);
-					}
-
-					/*
-					 * Create new blkvsc_req to represent
-					 * the current bvec
-					 */
-					blkvsc_req =
-					kmem_cache_zalloc(
-					blkdev->request_pool, GFP_ATOMIC);
-					if (!blkvsc_req) {
-						/* free up everything */
-						list_for_each_entry_safe(
-							blkvsc_req, tmp,
-							&group->blkvsc_req_list,
-							req_entry) {
-							list_del(
-							&blkvsc_req->req_entry);
-							kmem_cache_free(
-							blkdev->request_pool,
-							blkvsc_req);
-						}
-
-						kmem_cache_free(
-						blkdev->request_pool, group);
-						return -ENOMEM;
-					}
-
-					memset(blkvsc_req, 0,
-					       sizeof(struct blkvsc_request));
-
-					blkvsc_req->dev = blkdev;
-					blkvsc_req->req = req;
-					blkvsc_req->request.
-					data_buffer.offset
-					= bvec->bv_offset;
-					blkvsc_req->request.
-					data_buffer.len = 0;
-
-					/* Add to the group */
-					blkvsc_req->group = group;
-					blkvsc_req->group->outstanding++;
-					list_add_tail(&blkvsc_req->req_entry,
-					&blkvsc_req->group->blkvsc_req_list);
-
-					start_sector += num_sectors;
-					num_sectors = 0;
-					databuf_idx = 0;
-				}
-
-				/*
-				 * Add the curr bvec/segment to the curr
-				 * blkvsc_req
-				 */
-				blkvsc_req->request.data_buffer.
-					pfn_array[databuf_idx]
-						= page_to_pfn(bvec->bv_page);
-				blkvsc_req->request.data_buffer.len
-					+= bvec->bv_len;
-
-				prev_bvec = bvec;
-
-				databuf_idx++;
-				num_sectors += bvec->bv_len >> 9;
-
-			} /* bio_for_each_segment */
-
-		} /* rq_for_each_bio */
-	}
-
-	/* Handle the last one */
-	if (blkvsc_req) {
-		blkvsc_req->sector_start = start_sector;
-		sector_div(blkvsc_req->sector_start,
-			   (blkdev->sector_size >> 9));
-
-		blkvsc_req->sector_count = num_sectors /
-					   (blkdev->sector_size >> 9);
-
-		blkvsc_init_rw(blkvsc_req);
-	}
-
-	list_for_each_entry(blkvsc_req, &group->blkvsc_req_list, req_entry) {
-		if (pending) {
-
-			list_add_tail(&blkvsc_req->pend_entry,
-				      &blkdev->pending_list);
-		} else {
-			ret = blkvsc_submit_request(blkvsc_req,
-						    blkvsc_request_completion);
-			if (ret == -EAGAIN) {
-				pending = 1;
-				list_add_tail(&blkvsc_req->pend_entry,
-					      &blkdev->pending_list);
-			}
-
-		}
-	}
-
-	return pending;
-}
-
-static int blkvsc_do_pending_reqs(struct block_device_context *blkdev)
-{
-	struct blkvsc_request *pend_req, *tmp;
-	int ret = 0;
-
-	/* Flush the pending list first */
-	list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
-				 pend_entry) {
-
-		ret = blkvsc_submit_request(pend_req,
-					    blkvsc_request_completion);
-		if (ret != 0)
-			break;
-		else
-			list_del(&pend_req->pend_entry);
-	}
-
-	return ret;
-}
-
-
-static void blkvsc_request(struct request_queue *queue)
-{
-	struct block_device_context *blkdev = NULL;
-	struct request *req;
-	int ret = 0;
-
-	while ((req = blk_peek_request(queue)) != NULL) {
-
-		blkdev = req->rq_disk->private_data;
-		if (blkdev->shutting_down || req->cmd_type != REQ_TYPE_FS) {
-			__blk_end_request_cur(req, 0);
-			continue;
-		}
-
-		ret = blkvsc_do_pending_reqs(blkdev);
-
-		if (ret != 0) {
-			blk_stop_queue(queue);
-			break;
-		}
-
-		blk_start_request(req);
-
-		ret = blkvsc_do_request(blkdev, req);
-		if (ret > 0) {
-			blk_stop_queue(queue);
-			break;
-		} else if (ret < 0) {
-			blk_requeue_request(queue, req);
-			blk_stop_queue(queue);
-			break;
-		}
-	}
-}
-
-static const struct hv_vmbus_device_id id_table[] = {
-	/* IDE guid */
-	{ VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
-		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) },
-	{ },
-};
-
-MODULE_DEVICE_TABLE(vmbus, id_table);
-
-/* The one and only one */
-static  struct hv_driver blkvsc_drv = {
-	.name = "blkvsc",
-	.id_table = id_table,
-	.probe =  blkvsc_probe,
-	.remove =  blkvsc_remove,
-	.shutdown = blkvsc_shutdown,
-};
-
-static const struct block_device_operations block_ops = {
-	.owner = THIS_MODULE,
-	.open = blkvsc_open,
-	.release = blkvsc_release,
-	.getgeo = blkvsc_getgeo,
-	.ioctl  = blkvsc_ioctl,
-};
-
-/*
- * blkvsc_drv_init -  BlkVsc driver initialization.
- */
-static int blkvsc_drv_init(void)
-{
-	BUILD_BUG_ON(sizeof(sector_t) != 8);
-	return vmbus_driver_register(&blkvsc_drv);
-}
-
-static void blkvsc_drv_exit(void)
-{
-	vmbus_driver_unregister(&blkvsc_drv);
-}
-
-/*
- * blkvsc_probe - Add a new device for this driver
- */
-static int blkvsc_probe(struct hv_device *dev)
-{
-	struct block_device_context *blkdev = NULL;
-	struct storvsc_device_info device_info;
-	struct storvsc_major_info major_info;
-	int ret = 0;
-
-	blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL);
-	if (!blkdev) {
-		ret = -ENOMEM;
-		goto cleanup;
-	}
-
-	INIT_LIST_HEAD(&blkdev->pending_list);
-
-	/* Initialize what we can here */
-	spin_lock_init(&blkdev->lock);
-
-
-	blkdev->request_pool = kmem_cache_create(dev_name(&dev->device),
-					sizeof(struct blkvsc_request), 0,
-					SLAB_HWCACHE_ALIGN, NULL);
-	if (!blkdev->request_pool) {
-		ret = -ENOMEM;
-		goto cleanup;
-	}
-
-
-	ret = blkvsc_device_add(dev, &device_info);
-	if (ret != 0)
-		goto cleanup;
-
-	blkdev->device_ctx = dev;
-	/* this identified the device 0 or 1 */
-	blkdev->target = device_info.target_id;
-	/* this identified the ide ctrl 0 or 1 */
-	blkdev->path = device_info.path_id;
-
-	dev_set_drvdata(&dev->device, blkdev);
-
-	ret = storvsc_get_major_info(&device_info, &major_info);
-
-	if (ret)
-		goto cleanup;
-
-	if (major_info.do_register) {
-		ret = register_blkdev(major_info.major, major_info.devname);
-
-		if (ret != 0) {
-			DPRINT_ERR(BLKVSC_DRV,
-				   "register_blkdev() failed! ret %d", ret);
-			goto remove;
-		}
-	}
-
-	DPRINT_INFO(BLKVSC_DRV, "blkvsc registered for major %d!!",
-			major_info.major);
-
-	blkdev->gd = alloc_disk(BLKVSC_MINORS);
-	if (!blkdev->gd) {
-		ret = -1;
-		goto cleanup;
-	}
-
-	blkdev->gd->queue = blk_init_queue(blkvsc_request, &blkdev->lock);
-
-	blk_queue_max_segment_size(blkdev->gd->queue, PAGE_SIZE);
-	blk_queue_max_segments(blkdev->gd->queue, MAX_MULTIPAGE_BUFFER_COUNT);
-	blk_queue_segment_boundary(blkdev->gd->queue, PAGE_SIZE-1);
-	blk_queue_bounce_limit(blkdev->gd->queue, BLK_BOUNCE_ANY);
-	blk_queue_dma_alignment(blkdev->gd->queue, 511);
-
-	blkdev->gd->major = major_info.major;
-	if (major_info.index == 1 || major_info.index == 3)
-		blkdev->gd->first_minor = BLKVSC_MINORS;
-	else
-		blkdev->gd->first_minor = 0;
-	blkdev->gd->fops = &block_ops;
-	blkdev->gd->private_data = blkdev;
-	blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device);
-	sprintf(blkdev->gd->disk_name, "hd%c", 'a' + major_info.index);
-
-	blkvsc_do_operation(blkdev, DO_INQUIRY);
-	blkvsc_do_operation(blkdev, DO_CAPACITY);
-
-	set_capacity(blkdev->gd, blkdev->capacity * (blkdev->sector_size/512));
-	blk_queue_logical_block_size(blkdev->gd->queue, blkdev->sector_size);
-	/* go! */
-	add_disk(blkdev->gd);
-
-	DPRINT_INFO(BLKVSC_DRV, "%s added!! capacity %lu sector_size %d",
-		    blkdev->gd->disk_name, (unsigned long)blkdev->capacity,
-		    blkdev->sector_size);
-
-	return ret;
-
-remove:
-	storvsc_dev_remove(dev);
-
-cleanup:
-	if (blkdev) {
-		if (blkdev->request_pool) {
-			kmem_cache_destroy(blkdev->request_pool);
-			blkdev->request_pool = NULL;
-		}
-		kfree(blkdev);
-		blkdev = NULL;
-	}
-
-	return ret;
-}
-
-static void blkvsc_request_completion(struct hv_storvsc_request *request)
-{
-	struct blkvsc_request *blkvsc_req =
-			(struct blkvsc_request *)request->context;
-	struct block_device_context *blkdev =
-			(struct block_device_context *)blkvsc_req->dev;
-	unsigned long flags;
-	struct blkvsc_request *comp_req, *tmp;
-	struct vmscsi_request *vm_srb;
-
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-
-	blkdev->num_outstanding_reqs--;
-	blkvsc_req->group->outstanding--;
-
-	/*
-	 * Only start processing when all the blkvsc_reqs are
-	 * completed. This guarantees no out-of-order blkvsc_req
-	 * completion when calling end_that_request_first()
-	 */
-	if (blkvsc_req->group->outstanding == 0) {
-		list_for_each_entry_safe(comp_req, tmp,
-					 &blkvsc_req->group->blkvsc_req_list,
-					 req_entry) {
-
-			list_del(&comp_req->req_entry);
-
-			vm_srb =
-			&comp_req->request.vstor_packet.vm_srb;
-			if (!__blk_end_request(comp_req->req,
-				(!vm_srb->scsi_status ? 0 : -EIO),
-				comp_req->sector_count * blkdev->sector_size)) {
-				/*
-				 * All the sectors have been xferred ie the
-				 * request is done
-				 */
-				kmem_cache_free(blkdev->request_pool,
-						comp_req->group);
-			}
-
-			kmem_cache_free(blkdev->request_pool, comp_req);
-		}
-
-		if (!blkdev->shutting_down) {
-			blkvsc_do_pending_reqs(blkdev);
-			blk_start_queue(blkdev->gd->queue);
-			blkvsc_request(blkdev->gd->queue);
-		}
-	}
-
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-}
-
-static void __exit blkvsc_exit(void)
-{
-	blkvsc_drv_exit();
-}
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION(HV_DRV_VERSION);
-MODULE_DESCRIPTION("Microsoft Hyper-V virtual block driver");
-module_init(blkvsc_drv_init);
-module_exit(blkvsc_exit);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 21/46] Staging: hv: storvsc: Optimize bounce buffer handling for the "write" case
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (18 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 20/46] Staging: hv: blkvsc: Get rid of blkvsc_drv.c as this code is not used K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 22/46] Staging: hv: storvsc: Optimize the bounce buffer handling in the "read" case K. Y. Srinivasan
                     ` (24 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Optimize bounce buffer handling for the "write" case.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 9464f99..90b91ad 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -425,17 +425,17 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request)
 	struct scsi_sense_hdr sense_hdr;
 	struct vmscsi_request *vm_srb;
 
+	vm_srb = &request->vstor_packet.vm_srb;
 	if (cmd_request->bounce_sgl_count) {
-
-		/* FIXME: We can optimize on writes by just skipping this */
-		copy_from_bounce_buffer(scsi_sglist(scmnd),
+		if (vm_srb->data_in == READ_TYPE) {
+			copy_from_bounce_buffer(scsi_sglist(scmnd),
 					cmd_request->bounce_sgl,
 					scsi_sg_count(scmnd));
-		destroy_bounce_buffer(cmd_request->bounce_sgl,
-				      cmd_request->bounce_sgl_count);
+			destroy_bounce_buffer(cmd_request->bounce_sgl,
+					cmd_request->bounce_sgl_count);
+		}
 	}
 
-	vm_srb = &request->vstor_packet.vm_srb;
 	scmnd->result = vm_srb->scsi_status;
 
 	if (scmnd->result) {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 22/46] Staging: hv: storvsc: Optimize the bounce buffer handling in the "read" case
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (19 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 21/46] Staging: hv: storvsc: Optimize bounce buffer handling for the "write" case K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 23/46] Staging: hv: storvsc: Include storvsc.c in storvsc_drv.c K. Y. Srinivasan
                     ` (23 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Optimize the bounce buffer handling in the "read" case.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 90b91ad..3e00e70 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -560,12 +560,10 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
 				ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
 					PAGE_SHIFT;
 
-			/*
-			 * FIXME: We can optimize on reads by just skipping
-			 * this
-			 */
-			copy_to_bounce_buffer(sgl, cmd_request->bounce_sgl,
-					      scsi_sg_count(scmnd));
+			if (vm_srb->data_in == WRITE_TYPE)
+				copy_to_bounce_buffer(sgl,
+					cmd_request->bounce_sgl,
+					scsi_sg_count(scmnd));
 
 			sgl = cmd_request->bounce_sgl;
 			sg_count = cmd_request->bounce_sgl_count;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 23/46] Staging: hv: storvsc: Include storvsc.c in storvsc_drv.c
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (20 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 22/46] Staging: hv: storvsc: Optimize the bounce buffer handling in the "read" case K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 24/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of storvsc.c K. Y. Srinivasan
                     ` (22 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

As part of further cleanup of our storage drivers, include the content
of storvsc.c into storvsc_drv.c and delete storvsc.c and do the necessary
adjustments.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/Makefile      |    2 +-
 drivers/staging/hv/storvsc.c     |  528 -------------------------------------
 drivers/staging/hv/storvsc_drv.c |  529 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 530 insertions(+), 529 deletions(-)
 delete mode 100644 drivers/staging/hv/storvsc.c

diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile
index bb89437..bd176b1 100644
--- a/drivers/staging/hv/Makefile
+++ b/drivers/staging/hv/Makefile
@@ -7,6 +7,6 @@ obj-$(CONFIG_HYPERV_MOUSE)	+= hv_mouse.o
 hv_vmbus-y := vmbus_drv.o \
 		 hv.o connection.o channel.o \
 		 channel_mgmt.o ring_buffer.o
-hv_storvsc-y := storvsc_drv.o storvsc.o
+hv_storvsc-y := storvsc_drv.o
 hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o
 hv_utils-y := hv_util.o hv_kvp.o
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
deleted file mode 100644
index fb7b3ca..0000000
--- a/drivers/staging/hv/storvsc.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright (c) 2009, Microsoft Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *   K. Y. Srinivasan <kys@microsoft.com>
- *
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/completion.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-
-#include "hyperv.h"
-#include "hyperv_storage.h"
-
-
-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)
-{
-	struct storvsc_device *stor_device;
-	unsigned long flags;
-
-	spin_lock_irqsave(&device->channel->inbound_lock, flags);
-	stor_device = (struct storvsc_device *)device->ext;
-
-	if (!stor_device)
-		goto get_in_err;
-
-	/*
-	 * If the device is being destroyed; allow incoming
-	 * traffic only to cleanup outstanding requests.
-	 */
-
-	if (stor_device->destroy  &&
-		(atomic_read(&stor_device->num_outstanding_req) == 0))
-		stor_device = NULL;
-
-get_in_err:
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
-	return stor_device;
-
-}
-
-static int storvsc_channel_init(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-	struct hv_storvsc_request *request;
-	struct vstor_packet *vstor_packet;
-	int ret, t;
-
-	stor_device = get_out_stor_device(device);
-	if (!stor_device)
-		return -ENODEV;
-
-	request = &stor_device->init_request;
-	vstor_packet = &request->vstor_packet;
-
-	/*
-	 * Now, initiate the vsc/vsp initialization protocol on the open
-	 * channel
-	 */
-	memset(request, 0, sizeof(struct hv_storvsc_request));
-	init_completion(&request->wait_event);
-	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-
-	/* reuse the packet for version range supported */
-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
-	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT;
-	FILL_VMSTOR_REVISION(vstor_packet->version.revision);
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-
-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
-	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-	vstor_packet->storage_channel_properties.port_number =
-					stor_device->port_number;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-	stor_device->path_id = vstor_packet->storage_channel_properties.path_id;
-	stor_device->target_id
-		= vstor_packet->storage_channel_properties.target_id;
-
-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
-	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-
-cleanup:
-	return ret;
-}
-
-static void storvsc_on_io_completion(struct hv_device *device,
-				  struct vstor_packet *vstor_packet,
-				  struct hv_storvsc_request *request)
-{
-	struct storvsc_device *stor_device;
-	struct vstor_packet *stor_pkt;
-
-	stor_device = (struct storvsc_device *)device->ext;
-
-	stor_pkt = &request->vstor_packet;
-
-
-	/* Copy over the status...etc */
-	stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status;
-	stor_pkt->vm_srb.srb_status = vstor_packet->vm_srb.srb_status;
-	stor_pkt->vm_srb.sense_info_length =
-	vstor_packet->vm_srb.sense_info_length;
-
-	if (vstor_packet->vm_srb.scsi_status != 0 ||
-		vstor_packet->vm_srb.srb_status != 1){
-		DPRINT_WARN(STORVSC,
-			    "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
-			    stor_pkt->vm_srb.cdb[0],
-			    vstor_packet->vm_srb.scsi_status,
-			    vstor_packet->vm_srb.srb_status);
-	}
-
-	if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) {
-		/* CHECK_CONDITION */
-		if (vstor_packet->vm_srb.srb_status & 0x80) {
-			/* autosense data available */
-			DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data "
-				    "valid - len %d\n", request,
-				    vstor_packet->vm_srb.sense_info_length);
-
-			memcpy(request->sense_buffer,
-			       vstor_packet->vm_srb.sense_data,
-			       vstor_packet->vm_srb.sense_info_length);
-
-		}
-	}
-
-	stor_pkt->vm_srb.data_transfer_length =
-	vstor_packet->vm_srb.data_transfer_length;
-
-	request->on_io_completion(request);
-
-	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
-		stor_device->drain_notify)
-		wake_up(&stor_device->waiting_to_drain);
-
-
-}
-
-static void storvsc_on_receive(struct hv_device *device,
-			     struct vstor_packet *vstor_packet,
-			     struct hv_storvsc_request *request)
-{
-	switch (vstor_packet->operation) {
-	case VSTOR_OPERATION_COMPLETE_IO:
-		storvsc_on_io_completion(device, vstor_packet, request);
-		break;
-	case VSTOR_OPERATION_REMOVE_DEVICE:
-
-	default:
-		break;
-	}
-}
-
-static void storvsc_on_channel_callback(void *context)
-{
-	struct hv_device *device = (struct hv_device *)context;
-	struct storvsc_device *stor_device;
-	u32 bytes_recvd;
-	u64 request_id;
-	unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)];
-	struct hv_storvsc_request *request;
-	int ret;
-
-
-	stor_device = get_in_stor_device(device);
-	if (!stor_device)
-		return;
-
-	do {
-		ret = vmbus_recvpacket(device->channel, packet,
-				       ALIGN(sizeof(struct vstor_packet), 8),
-				       &bytes_recvd, &request_id);
-		if (ret == 0 && bytes_recvd > 0) {
-
-			request = (struct hv_storvsc_request *)
-					(unsigned long)request_id;
-
-			if ((request == &stor_device->init_request) ||
-			    (request == &stor_device->reset_request)) {
-
-				memcpy(&request->vstor_packet, packet,
-				       sizeof(struct vstor_packet));
-				complete(&request->wait_event);
-			} else {
-				storvsc_on_receive(device,
-						(struct vstor_packet *)packet,
-						request);
-			}
-		} else {
-			break;
-		}
-	} while (1);
-
-	return;
-}
-
-static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
-{
-	struct vmstorage_channel_properties props;
-	int ret;
-
-	memset(&props, 0, sizeof(struct vmstorage_channel_properties));
-
-	/* Open the channel */
-	ret = vmbus_open(device->channel,
-			 ring_size,
-			 ring_size,
-			 (void *)&props,
-			 sizeof(struct vmstorage_channel_properties),
-			 storvsc_on_channel_callback, device);
-
-	if (ret != 0)
-		return ret;
-
-	ret = storvsc_channel_init(device);
-
-	return ret;
-}
-
-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;
-}
-
-int storvsc_dev_remove(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-	unsigned long flags;
-
-	stor_device = (struct storvsc_device *)device->ext;
-
-	spin_lock_irqsave(&device->channel->inbound_lock, flags);
-	stor_device->destroy = true;
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
-
-	/*
-	 * At this point, all outbound traffic should be disable. We
-	 * only allow inbound traffic (responses) to proceed so that
-	 * outstanding requests can be completed.
-	 */
-
-	storvsc_wait_to_drain(stor_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);
-	device->ext = NULL;
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
-
-	/* Close the channel */
-	vmbus_close(device->channel);
-
-	kfree(stor_device);
-	return 0;
-}
-
-int storvsc_do_io(struct hv_device *device,
-			      struct hv_storvsc_request *request)
-{
-	struct storvsc_device *stor_device;
-	struct vstor_packet *vstor_packet;
-	int ret = 0;
-
-	vstor_packet = &request->vstor_packet;
-	stor_device = get_out_stor_device(device);
-
-	if (!stor_device)
-		return -ENODEV;
-
-
-	request->device  = device;
-
-
-	vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
-
-	vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
-
-
-	vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE;
-
-
-	vstor_packet->vm_srb.data_transfer_length =
-	request->data_buffer.len;
-
-	vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
-
-	if (request->data_buffer.len) {
-		ret = vmbus_sendpacket_multipagebuffer(device->channel,
-				&request->data_buffer,
-				vstor_packet,
-				sizeof(struct vstor_packet),
-				(unsigned long)request);
-	} else {
-		ret = vmbus_sendpacket(device->channel, vstor_packet,
-				       sizeof(struct vstor_packet),
-				       (unsigned long)request,
-				       VM_PKT_DATA_INBAND,
-				       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	}
-
-	if (ret != 0)
-		return ret;
-
-	atomic_inc(&stor_device->num_outstanding_req);
-
-	return ret;
-}
-
-/*
- * The channel properties uniquely specify how the device is to be
- * presented to the guest. Map this information for use by the block
- * driver. For Linux guests on Hyper-V, we emulate a scsi HBA in the guest
- * (storvsc_drv) and so scsi devices in the guest  are handled by
- * native upper level Linux drivers. Consequently, Hyper-V
- * block driver, while being a generic block driver, presently does not
- * deal with anything other than devices that would need to be presented
- * to the guest as an IDE disk.
- *
- * This function maps the channel properties as embedded in the input
- * parameter device_info onto information necessary to register the
- * corresponding block device.
- *
- * Currently, there is no way to stop the emulation of the block device
- * on the host side. And so, to prevent the native IDE drivers in Linux
- * from taking over these devices (to be managedby Hyper-V block
- * driver), we will take over if need be the major of the IDE controllers.
- *
- */
-
-int storvsc_get_major_info(struct storvsc_device_info *device_info,
-			    struct storvsc_major_info *major_info)
-{
-	static bool ide0_registered;
-	static bool ide1_registered;
-
-	/*
-	 * For now we only support IDE disks.
-	 */
-	major_info->devname = "ide";
-	major_info->diskname = "hd";
-
-	if (device_info->path_id) {
-		major_info->major = 22;
-		if (!ide1_registered) {
-			major_info->do_register = true;
-			ide1_registered = true;
-		} else
-			major_info->do_register = false;
-
-		if (device_info->target_id)
-			major_info->index = 3;
-		else
-			major_info->index = 2;
-
-		return 0;
-	} else {
-		major_info->major = 3;
-		if (!ide0_registered) {
-			major_info->do_register = true;
-			ide0_registered = true;
-		} else
-			major_info->do_register = false;
-
-		if (device_info->target_id)
-			major_info->index = 1;
-		else
-			major_info->index = 0;
-
-		return 0;
-	}
-
-	return -ENODEV;
-}
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 3e00e70..ddb31cf 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -36,6 +36,535 @@
 #include "hyperv.h"
 #include "hyperv_storage.h"
 
+
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+
+#include "hyperv.h"
+#include "hyperv_storage.h"
+
+
+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)
+{
+	struct storvsc_device *stor_device;
+	unsigned long flags;
+
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
+	stor_device = (struct storvsc_device *)device->ext;
+
+	if (!stor_device)
+		goto get_in_err;
+
+	/*
+	 * If the device is being destroyed; allow incoming
+	 * traffic only to cleanup outstanding requests.
+	 */
+
+	if (stor_device->destroy  &&
+		(atomic_read(&stor_device->num_outstanding_req) == 0))
+		stor_device = NULL;
+
+get_in_err:
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+	return stor_device;
+
+}
+
+static int storvsc_channel_init(struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+	struct hv_storvsc_request *request;
+	struct vstor_packet *vstor_packet;
+	int ret, t;
+
+	stor_device = get_out_stor_device(device);
+	if (!stor_device)
+		return -ENODEV;
+
+	request = &stor_device->init_request;
+	vstor_packet = &request->vstor_packet;
+
+	/*
+	 * Now, initiate the vsc/vsp initialization protocol on the open
+	 * channel
+	 */
+	memset(request, 0, sizeof(struct hv_storvsc_request));
+	init_completion(&request->wait_event);
+	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+
+	/* reuse the packet for version range supported */
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+
+	vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT;
+	FILL_VMSTOR_REVISION(vstor_packet->version.revision);
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+	vstor_packet->storage_channel_properties.port_number =
+					stor_device->port_number;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+	stor_device->path_id = vstor_packet->storage_channel_properties.path_id;
+	stor_device->target_id
+		= vstor_packet->storage_channel_properties.target_id;
+
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+
+cleanup:
+	return ret;
+}
+
+static void storvsc_on_io_completion(struct hv_device *device,
+				  struct vstor_packet *vstor_packet,
+				  struct hv_storvsc_request *request)
+{
+	struct storvsc_device *stor_device;
+	struct vstor_packet *stor_pkt;
+
+	stor_device = (struct storvsc_device *)device->ext;
+
+	stor_pkt = &request->vstor_packet;
+
+
+	/* Copy over the status...etc */
+	stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status;
+	stor_pkt->vm_srb.srb_status = vstor_packet->vm_srb.srb_status;
+	stor_pkt->vm_srb.sense_info_length =
+	vstor_packet->vm_srb.sense_info_length;
+
+	if (vstor_packet->vm_srb.scsi_status != 0 ||
+		vstor_packet->vm_srb.srb_status != 1){
+		DPRINT_WARN(STORVSC,
+			    "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
+			    stor_pkt->vm_srb.cdb[0],
+			    vstor_packet->vm_srb.scsi_status,
+			    vstor_packet->vm_srb.srb_status);
+	}
+
+	if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) {
+		/* CHECK_CONDITION */
+		if (vstor_packet->vm_srb.srb_status & 0x80) {
+			/* autosense data available */
+			DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data "
+				    "valid - len %d\n", request,
+				    vstor_packet->vm_srb.sense_info_length);
+
+			memcpy(request->sense_buffer,
+			       vstor_packet->vm_srb.sense_data,
+			       vstor_packet->vm_srb.sense_info_length);
+
+		}
+	}
+
+	stor_pkt->vm_srb.data_transfer_length =
+	vstor_packet->vm_srb.data_transfer_length;
+
+	request->on_io_completion(request);
+
+	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
+		stor_device->drain_notify)
+		wake_up(&stor_device->waiting_to_drain);
+
+
+}
+
+static void storvsc_on_receive(struct hv_device *device,
+			     struct vstor_packet *vstor_packet,
+			     struct hv_storvsc_request *request)
+{
+	switch (vstor_packet->operation) {
+	case VSTOR_OPERATION_COMPLETE_IO:
+		storvsc_on_io_completion(device, vstor_packet, request);
+		break;
+	case VSTOR_OPERATION_REMOVE_DEVICE:
+
+	default:
+		break;
+	}
+}
+
+static void storvsc_on_channel_callback(void *context)
+{
+	struct hv_device *device = (struct hv_device *)context;
+	struct storvsc_device *stor_device;
+	u32 bytes_recvd;
+	u64 request_id;
+	unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)];
+	struct hv_storvsc_request *request;
+	int ret;
+
+
+	stor_device = get_in_stor_device(device);
+	if (!stor_device)
+		return;
+
+	do {
+		ret = vmbus_recvpacket(device->channel, packet,
+				       ALIGN(sizeof(struct vstor_packet), 8),
+				       &bytes_recvd, &request_id);
+		if (ret == 0 && bytes_recvd > 0) {
+
+			request = (struct hv_storvsc_request *)
+					(unsigned long)request_id;
+
+			if ((request == &stor_device->init_request) ||
+			    (request == &stor_device->reset_request)) {
+
+				memcpy(&request->vstor_packet, packet,
+				       sizeof(struct vstor_packet));
+				complete(&request->wait_event);
+			} else {
+				storvsc_on_receive(device,
+						(struct vstor_packet *)packet,
+						request);
+			}
+		} else {
+			break;
+		}
+	} while (1);
+
+	return;
+}
+
+static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
+{
+	struct vmstorage_channel_properties props;
+	int ret;
+
+	memset(&props, 0, sizeof(struct vmstorage_channel_properties));
+
+	/* Open the channel */
+	ret = vmbus_open(device->channel,
+			 ring_size,
+			 ring_size,
+			 (void *)&props,
+			 sizeof(struct vmstorage_channel_properties),
+			 storvsc_on_channel_callback, device);
+
+	if (ret != 0)
+		return ret;
+
+	ret = storvsc_channel_init(device);
+
+	return ret;
+}
+
+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;
+}
+
+int storvsc_dev_remove(struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+	unsigned long flags;
+
+	stor_device = (struct storvsc_device *)device->ext;
+
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
+	stor_device->destroy = true;
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+
+	/*
+	 * At this point, all outbound traffic should be disable. We
+	 * only allow inbound traffic (responses) to proceed so that
+	 * outstanding requests can be completed.
+	 */
+
+	storvsc_wait_to_drain(stor_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);
+	device->ext = NULL;
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+
+	/* Close the channel */
+	vmbus_close(device->channel);
+
+	kfree(stor_device);
+	return 0;
+}
+
+int storvsc_do_io(struct hv_device *device,
+			      struct hv_storvsc_request *request)
+{
+	struct storvsc_device *stor_device;
+	struct vstor_packet *vstor_packet;
+	int ret = 0;
+
+	vstor_packet = &request->vstor_packet;
+	stor_device = get_out_stor_device(device);
+
+	if (!stor_device)
+		return -ENODEV;
+
+
+	request->device  = device;
+
+
+	vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
+
+	vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
+
+
+	vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE;
+
+
+	vstor_packet->vm_srb.data_transfer_length =
+	request->data_buffer.len;
+
+	vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
+
+	if (request->data_buffer.len) {
+		ret = vmbus_sendpacket_multipagebuffer(device->channel,
+				&request->data_buffer,
+				vstor_packet,
+				sizeof(struct vstor_packet),
+				(unsigned long)request);
+	} else {
+		ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	}
+
+	if (ret != 0)
+		return ret;
+
+	atomic_inc(&stor_device->num_outstanding_req);
+
+	return ret;
+}
+
+/*
+ * The channel properties uniquely specify how the device is to be
+ * presented to the guest. Map this information for use by the block
+ * driver. For Linux guests on Hyper-V, we emulate a scsi HBA in the guest
+ * (storvsc_drv) and so scsi devices in the guest  are handled by
+ * native upper level Linux drivers. Consequently, Hyper-V
+ * block driver, while being a generic block driver, presently does not
+ * deal with anything other than devices that would need to be presented
+ * to the guest as an IDE disk.
+ *
+ * This function maps the channel properties as embedded in the input
+ * parameter device_info onto information necessary to register the
+ * corresponding block device.
+ *
+ * Currently, there is no way to stop the emulation of the block device
+ * on the host side. And so, to prevent the native IDE drivers in Linux
+ * from taking over these devices (to be managedby Hyper-V block
+ * driver), we will take over if need be the major of the IDE controllers.
+ *
+ */
+
+int storvsc_get_major_info(struct storvsc_device_info *device_info,
+			    struct storvsc_major_info *major_info)
+{
+	static bool ide0_registered;
+	static bool ide1_registered;
+
+	/*
+	 * For now we only support IDE disks.
+	 */
+	major_info->devname = "ide";
+	major_info->diskname = "hd";
+
+	if (device_info->path_id) {
+		major_info->major = 22;
+		if (!ide1_registered) {
+			major_info->do_register = true;
+			ide1_registered = true;
+		} else
+			major_info->do_register = false;
+
+		if (device_info->target_id)
+			major_info->index = 3;
+		else
+			major_info->index = 2;
+
+		return 0;
+	} else {
+		major_info->major = 3;
+		if (!ide0_registered) {
+			major_info->do_register = true;
+			ide0_registered = true;
+		} else
+			major_info->do_register = false;
+
+		if (device_info->target_id)
+			major_info->index = 1;
+		else
+			major_info->index = 0;
+
+		return 0;
+	}
+
+	return -ENODEV;
+}
 static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
 
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 24/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of storvsc.c
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (21 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 23/46] Staging: hv: storvsc: Include storvsc.c in storvsc_drv.c K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 25/46] Staging: hv: storvsc: Add the contents of hyperv_storage.h to storvsc_drv.c K. Y. Srinivasan
                     ` (21 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Cleanup storvsc_drv.c after adding the contents of storvsc.c.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |  147 +++++++-------------------------------
 1 files changed, 27 insertions(+), 120 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index ddb31cf..096f615 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -19,11 +19,17 @@
  *   Hank Janssen  <hjanssen@microsoft.com>
  *   K. Y. Srinivasan <kys@microsoft.com>
  */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/device.h>
-#include <linux/blkdev.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
@@ -37,39 +43,28 @@
 #include "hyperv_storage.h"
 
 
-/*
- * Copyright (c) 2009, Microsoft Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *   K. Y. Srinivasan <kys@microsoft.com>
- *
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/completion.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
+static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
 
-#include "hyperv.h"
-#include "hyperv_storage.h"
+module_param(storvsc_ringbuffer_size, int, S_IRUGO);
+MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
+
+struct hv_host_device {
+	struct hv_device *dev;
+	struct kmem_cache *request_pool;
+	unsigned int port;
+	unsigned char path;
+	unsigned char target;
+};
+
+struct storvsc_cmd_request {
+	struct list_head entry;
+	struct scsi_cmnd *cmd;
 
+	unsigned int bounce_sgl_count;
+	struct scatterlist *bounce_sgl;
+
+	struct hv_storvsc_request request;
+};
 
 static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 {
@@ -500,94 +495,6 @@ int storvsc_do_io(struct hv_device *device,
 	return ret;
 }
 
-/*
- * The channel properties uniquely specify how the device is to be
- * presented to the guest. Map this information for use by the block
- * driver. For Linux guests on Hyper-V, we emulate a scsi HBA in the guest
- * (storvsc_drv) and so scsi devices in the guest  are handled by
- * native upper level Linux drivers. Consequently, Hyper-V
- * block driver, while being a generic block driver, presently does not
- * deal with anything other than devices that would need to be presented
- * to the guest as an IDE disk.
- *
- * This function maps the channel properties as embedded in the input
- * parameter device_info onto information necessary to register the
- * corresponding block device.
- *
- * Currently, there is no way to stop the emulation of the block device
- * on the host side. And so, to prevent the native IDE drivers in Linux
- * from taking over these devices (to be managedby Hyper-V block
- * driver), we will take over if need be the major of the IDE controllers.
- *
- */
-
-int storvsc_get_major_info(struct storvsc_device_info *device_info,
-			    struct storvsc_major_info *major_info)
-{
-	static bool ide0_registered;
-	static bool ide1_registered;
-
-	/*
-	 * For now we only support IDE disks.
-	 */
-	major_info->devname = "ide";
-	major_info->diskname = "hd";
-
-	if (device_info->path_id) {
-		major_info->major = 22;
-		if (!ide1_registered) {
-			major_info->do_register = true;
-			ide1_registered = true;
-		} else
-			major_info->do_register = false;
-
-		if (device_info->target_id)
-			major_info->index = 3;
-		else
-			major_info->index = 2;
-
-		return 0;
-	} else {
-		major_info->major = 3;
-		if (!ide0_registered) {
-			major_info->do_register = true;
-			ide0_registered = true;
-		} else
-			major_info->do_register = false;
-
-		if (device_info->target_id)
-			major_info->index = 1;
-		else
-			major_info->index = 0;
-
-		return 0;
-	}
-
-	return -ENODEV;
-}
-static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
-
-module_param(storvsc_ringbuffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
-
-struct hv_host_device {
-	struct hv_device *dev;
-	struct kmem_cache *request_pool;
-	unsigned int port;
-	unsigned char path;
-	unsigned char target;
-};
-
-struct storvsc_cmd_request {
-	struct list_head entry;
-	struct scsi_cmnd *cmd;
-
-	unsigned int bounce_sgl_count;
-	struct scatterlist *bounce_sgl;
-
-	struct hv_storvsc_request request;
-};
-
 static void storvsc_get_ide_info(struct hv_device *dev, int *target, int *path)
 {
 	*target =
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 25/46] Staging: hv: storvsc: Add the contents of hyperv_storage.h to storvsc_drv.c
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (22 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 24/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of storvsc.c K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 26/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h K. Y. Srinivasan
                     ` (20 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

As part of further cleanup of storvsc, add the contents of hyperv_storage.h
to storvsc_drv.c and do the necessary adjustments.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hyperv_storage.h |  322 -----------------------------------
 drivers/staging/hv/storvsc_drv.c    |  277 ++++++++++++++++++++++++++++++-
 2 files changed, 276 insertions(+), 323 deletions(-)
 delete mode 100644 drivers/staging/hv/hyperv_storage.h

diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h
deleted file mode 100644
index 687cdc5..0000000
--- a/drivers/staging/hv/hyperv_storage.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- *
- * Copyright (c) 2011, Microsoft Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *   K. Y. Srinivasan <kys@microsoft.com>
- *
- */
-
-#ifndef _HYPERV_STORAGE_H
-#define _HYPERV_STORAGE_H
-
-
-/* vstorage.w revision number.  This is used in the case of a version match, */
-/* to alert the user that structure sizes may be mismatched even though the */
-/* protocol versions match. */
-
-
-#define REVISION_STRING(REVISION_) #REVISION_
-#define FILL_VMSTOR_REVISION(RESULT_LVALUE_)				\
-	do {								\
-		char *revision_string					\
-			= REVISION_STRING($Rev : 6 $) + 6;		\
-		RESULT_LVALUE_ = 0;					\
-		while (*revision_string >= '0'				\
-			&& *revision_string <= '9') {			\
-			RESULT_LVALUE_ *= 10;				\
-			RESULT_LVALUE_ += *revision_string - '0';	\
-			revision_string++;				\
-		}							\
-	} while (0)
-
-/* Major/minor macros.  Minor version is in LSB, meaning that earlier flat */
-/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
-#define VMSTOR_PROTOCOL_MAJOR(VERSION_)		(((VERSION_) >> 8) & 0xff)
-#define VMSTOR_PROTOCOL_MINOR(VERSION_)		(((VERSION_))      & 0xff)
-#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
-						 (((MINOR_) & 0xff)))
-#define VMSTOR_INVALID_PROTOCOL_VERSION		(-1)
-
-/* Version history: */
-/* V1 Beta                    0.1 */
-/* V1 RC < 2008/1/31          1.0 */
-/* V1 RC > 2008/1/31          2.0 */
-#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
-
-
-
-
-/*  This will get replaced with the max transfer length that is possible on */
-/*  the host adapter. */
-/*  The max transfer length will be published when we offer a vmbus channel. */
-#define MAX_TRANSFER_LENGTH	0x40000
-#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) +	\
-			sizeof(struct vstor_packet) +		\
-			sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
-
-
-/*  Packet structure describing virtual storage requests. */
-enum vstor_packet_operation {
-	VSTOR_OPERATION_COMPLETE_IO		= 1,
-	VSTOR_OPERATION_REMOVE_DEVICE		= 2,
-	VSTOR_OPERATION_EXECUTE_SRB		= 3,
-	VSTOR_OPERATION_RESET_LUN		= 4,
-	VSTOR_OPERATION_RESET_ADAPTER		= 5,
-	VSTOR_OPERATION_RESET_BUS		= 6,
-	VSTOR_OPERATION_BEGIN_INITIALIZATION	= 7,
-	VSTOR_OPERATION_END_INITIALIZATION	= 8,
-	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
-	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
-	VSTOR_OPERATION_MAXIMUM			= 10
-};
-
-/*
- * Platform neutral description of a scsi request -
- * this remains the same across the write regardless of 32/64 bit
- * note: it's patterned off the SCSI_PASS_THROUGH structure
- */
-#define CDB16GENERIC_LENGTH			0x10
-
-#ifndef SENSE_BUFFER_SIZE
-#define SENSE_BUFFER_SIZE			0x12
-#endif
-
-#define MAX_DATA_BUF_LEN_WITH_PADDING		0x14
-
-struct vmscsi_request {
-	unsigned short length;
-	unsigned char srb_status;
-	unsigned char scsi_status;
-
-	unsigned char port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-	unsigned char lun;
-
-	unsigned char cdb_length;
-	unsigned char sense_info_length;
-	unsigned char data_in;
-	unsigned char reserved;
-
-	unsigned int data_transfer_length;
-
-	union {
-		unsigned char cdb[CDB16GENERIC_LENGTH];
-		unsigned char sense_data[SENSE_BUFFER_SIZE];
-		unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING];
-	};
-} __attribute((packed));
-
-
-/*
- * This structure is sent during the intialization phase to get the different
- * properties of the channel.
- */
-struct vmstorage_channel_properties {
-	unsigned short protocol_version;
-	unsigned char path_id;
-	unsigned char target_id;
-
-	/* Note: port number is only really known on the client side */
-	unsigned int port_number;
-	unsigned int flags;
-	unsigned int max_transfer_bytes;
-
-	/*  This id is unique for each channel and will correspond with */
-	/*  vendor specific data in the inquirydata */
-	unsigned long long unique_id;
-} __packed;
-
-/*  This structure is sent during the storage protocol negotiations. */
-struct vmstorage_protocol_version {
-	/* Major (MSW) and minor (LSW) version numbers. */
-	unsigned short major_minor;
-
-	/*
-	 * Revision number is auto-incremented whenever this file is changed
-	 * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
-	 * definitely indicate incompatibility--but it does indicate mismatched
-	 * builds.
-	 */
-	unsigned short revision;
-} __packed;
-
-/* Channel Property Flags */
-#define STORAGE_CHANNEL_REMOVABLE_FLAG		0x1
-#define STORAGE_CHANNEL_EMULATED_IDE_FLAG	0x2
-
-struct vstor_packet {
-	/* Requested operation type */
-	enum vstor_packet_operation operation;
-
-	/*  Flags - see below for values */
-	unsigned int flags;
-
-	/* Status of the request returned from the server side. */
-	unsigned int status;
-
-	/* Data payload area */
-	union {
-		/*
-		 * Structure used to forward SCSI commands from the
-		 * client to the server.
-		 */
-		struct vmscsi_request vm_srb;
-
-		/* Structure used to query channel properties. */
-		struct vmstorage_channel_properties storage_channel_properties;
-
-		/* Used during version negotiations. */
-		struct vmstorage_protocol_version version;
-	};
-} __packed;
-
-/* Packet flags */
-/*
- * This flag indicates that the server should send back a completion for this
- * packet.
- */
-#define REQUEST_COMPLETION_FLAG	0x1
-
-/*  This is the set of flags that the vsc can set in any packets it sends */
-#define VSC_LEGAL_FLAGS		(REQUEST_COMPLETION_FLAG)
-
-
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include "hyperv_storage.h"
-#include "hyperv.h"
-
-/* Defines */
-#define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
-#define BLKVSC_RING_BUFFER_SIZE				(20*PAGE_SIZE)
-
-#define STORVSC_MAX_IO_REQUESTS				128
-
-/*
- * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
- * reality, the path/target is not used (ie always set to 0) so our
- * scsi host adapter essentially has 1 bus with 1 target that contains
- * up to 256 luns.
- */
-#define STORVSC_MAX_LUNS_PER_TARGET			64
-#define STORVSC_MAX_TARGETS				1
-#define STORVSC_MAX_CHANNELS				1
-
-struct hv_storvsc_request;
-
-/* Matches Windows-end */
-enum storvsc_request_type {
-	WRITE_TYPE,
-	READ_TYPE,
-	UNKNOWN_TYPE,
-};
-
-
-struct hv_storvsc_request {
-	struct hv_storvsc_request *request;
-	struct hv_device *device;
-
-	/* Synchronize the request/response if needed */
-	struct completion wait_event;
-
-	unsigned char *sense_buffer;
-	void *context;
-	void (*on_io_completion)(struct hv_storvsc_request *request);
-	struct hv_multipage_buffer data_buffer;
-
-	struct vstor_packet vstor_packet;
-};
-
-
-struct storvsc_device_info {
-	u32 ring_buffer_size;
-	unsigned int port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-};
-
-struct storvsc_major_info {
-	int major;
-	int index;
-	bool do_register;
-	char *devname;
-	char *diskname;
-};
-
-/* A storvsc device is a device object that contains a vmbus channel */
-struct storvsc_device {
-	struct hv_device *device;
-
-	bool	 destroy;
-	bool	 drain_notify;
-	atomic_t num_outstanding_req;
-
-	wait_queue_head_t waiting_to_drain;
-
-	/*
-	 * Each unique Port/Path/Target represents 1 channel ie scsi
-	 * controller. In reality, the pathid, targetid is always 0
-	 * and the port is set by us
-	 */
-	unsigned int port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-
-	/* Used for vsc/vsp channel reset process */
-	struct hv_storvsc_request init_request;
-	struct hv_storvsc_request reset_request;
-};
-
-
-static inline struct storvsc_device *get_out_stor_device(
-					struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = (struct storvsc_device *)device->ext;
-
-	if (stor_device && stor_device->destroy)
-		stor_device = NULL;
-
-	return stor_device;
-}
-
-
-static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
-{
-	dev->drain_notify = true;
-	wait_event(dev->waiting_to_drain,
-		   atomic_read(&dev->num_outstanding_req) == 0);
-	dev->drain_notify = false;
-}
-
-/* Interface */
-
-int storvsc_dev_add(struct hv_device *device,
-				void *additional_info);
-int storvsc_dev_remove(struct hv_device *device);
-
-int storvsc_do_io(struct hv_device *device,
-				struct hv_storvsc_request *request);
-
-int storvsc_get_major_info(struct storvsc_device_info *device_info,
-				struct storvsc_major_info *major_info);
-
-#endif /* _HYPERV_STORAGE_H */
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 096f615..4a95f8b 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -21,6 +21,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/completion.h>
 #include <linux/string.h>
@@ -40,7 +41,281 @@
 #include <scsi/scsi_dbg.h>
 
 #include "hyperv.h"
-#include "hyperv_storage.h"
+
+/* to alert the user that structure sizes may be mismatched even though the */
+/* protocol versions match. */
+
+
+#define REVISION_STRING(REVISION_) #REVISION_
+#define FILL_VMSTOR_REVISION(RESULT_LVALUE_)				\
+	do {								\
+		char *revision_string					\
+			= REVISION_STRING($Rev : 6 $) + 6;		\
+		RESULT_LVALUE_ = 0;					\
+		while (*revision_string >= '0'				\
+			&& *revision_string <= '9') {			\
+			RESULT_LVALUE_ *= 10;				\
+			RESULT_LVALUE_ += *revision_string - '0';	\
+			revision_string++;				\
+		}							\
+	} while (0)
+
+/* Major/minor macros.  Minor version is in LSB, meaning that earlier flat */
+/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
+#define VMSTOR_PROTOCOL_MAJOR(VERSION_)		(((VERSION_) >> 8) & 0xff)
+#define VMSTOR_PROTOCOL_MINOR(VERSION_)		(((VERSION_))      & 0xff)
+#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
+						 (((MINOR_) & 0xff)))
+#define VMSTOR_INVALID_PROTOCOL_VERSION		(-1)
+
+/* Version history: */
+/* V1 Beta                    0.1 */
+/* V1 RC < 2008/1/31          1.0 */
+/* V1 RC > 2008/1/31          2.0 */
+#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
+
+
+
+
+/*  This will get replaced with the max transfer length that is possible on */
+/*  the host adapter. */
+/*  The max transfer length will be published when we offer a vmbus channel. */
+#define MAX_TRANSFER_LENGTH	0x40000
+#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) +	\
+			sizeof(struct vstor_packet) +		\
+			sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
+
+
+/*  Packet structure describing virtual storage requests. */
+enum vstor_packet_operation {
+	VSTOR_OPERATION_COMPLETE_IO		= 1,
+	VSTOR_OPERATION_REMOVE_DEVICE		= 2,
+	VSTOR_OPERATION_EXECUTE_SRB		= 3,
+	VSTOR_OPERATION_RESET_LUN		= 4,
+	VSTOR_OPERATION_RESET_ADAPTER		= 5,
+	VSTOR_OPERATION_RESET_BUS		= 6,
+	VSTOR_OPERATION_BEGIN_INITIALIZATION	= 7,
+	VSTOR_OPERATION_END_INITIALIZATION	= 8,
+	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
+	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
+	VSTOR_OPERATION_MAXIMUM			= 10
+};
+
+/*
+ * Platform neutral description of a scsi request -
+ * this remains the same across the write regardless of 32/64 bit
+ * note: it's patterned off the SCSI_PASS_THROUGH structure
+ */
+#define CDB16GENERIC_LENGTH			0x10
+
+#ifndef SENSE_BUFFER_SIZE
+#define SENSE_BUFFER_SIZE			0x12
+#endif
+
+#define MAX_DATA_BUF_LEN_WITH_PADDING		0x14
+
+struct vmscsi_request {
+	unsigned short length;
+	unsigned char srb_status;
+	unsigned char scsi_status;
+
+	unsigned char port_number;
+	unsigned char path_id;
+	unsigned char target_id;
+	unsigned char lun;
+
+	unsigned char cdb_length;
+	unsigned char sense_info_length;
+	unsigned char data_in;
+	unsigned char reserved;
+
+	unsigned int data_transfer_length;
+
+	union {
+		unsigned char cdb[CDB16GENERIC_LENGTH];
+		unsigned char sense_data[SENSE_BUFFER_SIZE];
+		unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING];
+	};
+} __attribute((packed));
+
+
+/*
+ * This structure is sent during the intialization phase to get the different
+ * properties of the channel.
+ */
+struct vmstorage_channel_properties {
+	unsigned short protocol_version;
+	unsigned char path_id;
+	unsigned char target_id;
+
+	/* Note: port number is only really known on the client side */
+	unsigned int port_number;
+	unsigned int flags;
+	unsigned int max_transfer_bytes;
+
+	/*  This id is unique for each channel and will correspond with */
+	/*  vendor specific data in the inquirydata */
+	unsigned long long unique_id;
+} __packed;
+
+/*  This structure is sent during the storage protocol negotiations. */
+struct vmstorage_protocol_version {
+	/* Major (MSW) and minor (LSW) version numbers. */
+	unsigned short major_minor;
+
+	/*
+	 * Revision number is auto-incremented whenever this file is changed
+	 * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
+	 * definitely indicate incompatibility--but it does indicate mismatched
+	 * builds.
+	 */
+	unsigned short revision;
+} __packed;
+
+/* Channel Property Flags */
+#define STORAGE_CHANNEL_REMOVABLE_FLAG		0x1
+#define STORAGE_CHANNEL_EMULATED_IDE_FLAG	0x2
+
+struct vstor_packet {
+	/* Requested operation type */
+	enum vstor_packet_operation operation;
+
+	/*  Flags - see below for values */
+	unsigned int flags;
+
+	/* Status of the request returned from the server side. */
+	unsigned int status;
+
+	/* Data payload area */
+	union {
+		/*
+		 * Structure used to forward SCSI commands from the
+		 * client to the server.
+		 */
+		struct vmscsi_request vm_srb;
+
+		/* Structure used to query channel properties. */
+		struct vmstorage_channel_properties storage_channel_properties;
+
+		/* Used during version negotiations. */
+		struct vmstorage_protocol_version version;
+	};
+} __packed;
+
+/* Packet flags */
+/*
+ * This flag indicates that the server should send back a completion for this
+ * packet.
+ */
+#define REQUEST_COMPLETION_FLAG	0x1
+
+/*  This is the set of flags that the vsc can set in any packets it sends */
+#define VSC_LEGAL_FLAGS		(REQUEST_COMPLETION_FLAG)
+
+
+/* Defines */
+#define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
+#define BLKVSC_RING_BUFFER_SIZE				(20*PAGE_SIZE)
+
+#define STORVSC_MAX_IO_REQUESTS				128
+
+/*
+ * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
+ * reality, the path/target is not used (ie always set to 0) so our
+ * scsi host adapter essentially has 1 bus with 1 target that contains
+ * up to 256 luns.
+ */
+#define STORVSC_MAX_LUNS_PER_TARGET			64
+#define STORVSC_MAX_TARGETS				1
+#define STORVSC_MAX_CHANNELS				1
+
+struct hv_storvsc_request;
+
+/* Matches Windows-end */
+enum storvsc_request_type {
+	WRITE_TYPE,
+	READ_TYPE,
+	UNKNOWN_TYPE,
+};
+
+
+struct hv_storvsc_request {
+	struct hv_storvsc_request *request;
+	struct hv_device *device;
+
+	/* Synchronize the request/response if needed */
+	struct completion wait_event;
+
+	unsigned char *sense_buffer;
+	void *context;
+	void (*on_io_completion)(struct hv_storvsc_request *request);
+	struct hv_multipage_buffer data_buffer;
+
+	struct vstor_packet vstor_packet;
+};
+
+
+struct storvsc_device_info {
+	u32 ring_buffer_size;
+	unsigned int port_number;
+	unsigned char path_id;
+	unsigned char target_id;
+};
+
+struct storvsc_major_info {
+	int major;
+	int index;
+	bool do_register;
+	char *devname;
+	char *diskname;
+};
+
+/* A storvsc device is a device object that contains a vmbus channel */
+struct storvsc_device {
+	struct hv_device *device;
+
+	bool	 destroy;
+	bool	 drain_notify;
+	atomic_t num_outstanding_req;
+
+	wait_queue_head_t waiting_to_drain;
+
+	/*
+	 * Each unique Port/Path/Target represents 1 channel ie scsi
+	 * controller. In reality, the pathid, targetid is always 0
+	 * and the port is set by us
+	 */
+	unsigned int port_number;
+	unsigned char path_id;
+	unsigned char target_id;
+
+	/* Used for vsc/vsp channel reset process */
+	struct hv_storvsc_request init_request;
+	struct hv_storvsc_request reset_request;
+};
+
+
+static inline struct storvsc_device *get_out_stor_device(
+					struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+
+	stor_device = (struct storvsc_device *)device->ext;
+
+	if (stor_device && stor_device->destroy)
+		stor_device = NULL;
+
+	return stor_device;
+}
+
+
+static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
+{
+	dev->drain_notify = true;
+	wait_event(dev->waiting_to_drain,
+		   atomic_read(&dev->num_outstanding_req) == 0);
+	dev->drain_notify = false;
+}
 
 
 static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 26/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (23 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 25/46] Staging: hv: storvsc: Add the contents of hyperv_storage.h to storvsc_drv.c K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 27/46] Staging: hv: storvsc: Fixup srb and scsi status for INQUIRY and MODE_SENSE K. Y. Srinivasan
                     ` (19 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   62 ++++++++++++++++----------------------
 1 files changed, 26 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 4a95f8b..0bb4e0e 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -42,6 +42,12 @@
 
 #include "hyperv.h"
 
+#define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
+static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
+
+module_param(storvsc_ringbuffer_size, int, S_IRUGO);
+MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
+
 /* to alert the user that structure sizes may be mismatched even though the */
 /* protocol versions match. */
 
@@ -214,8 +220,6 @@ struct vstor_packet {
 
 
 /* Defines */
-#define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
-#define BLKVSC_RING_BUFFER_SIZE				(20*PAGE_SIZE)
 
 #define STORVSC_MAX_IO_REQUESTS				128
 
@@ -262,13 +266,6 @@ struct storvsc_device_info {
 	unsigned char target_id;
 };
 
-struct storvsc_major_info {
-	int major;
-	int index;
-	bool do_register;
-	char *devname;
-	char *diskname;
-};
 
 /* A storvsc device is a device object that contains a vmbus channel */
 struct storvsc_device {
@@ -294,6 +291,23 @@ struct storvsc_device {
 	struct hv_storvsc_request reset_request;
 };
 
+struct hv_host_device {
+	struct hv_device *dev;
+	struct kmem_cache *request_pool;
+	unsigned int port;
+	unsigned char path;
+	unsigned char target;
+};
+
+struct storvsc_cmd_request {
+	struct list_head entry;
+	struct scsi_cmnd *cmd;
+
+	unsigned int bounce_sgl_count;
+	struct scatterlist *bounce_sgl;
+
+	struct hv_storvsc_request request;
+};
 
 static inline struct storvsc_device *get_out_stor_device(
 					struct hv_device *device)
@@ -317,30 +331,6 @@ static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
 	dev->drain_notify = false;
 }
 
-
-static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
-
-module_param(storvsc_ringbuffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
-
-struct hv_host_device {
-	struct hv_device *dev;
-	struct kmem_cache *request_pool;
-	unsigned int port;
-	unsigned char path;
-	unsigned char target;
-};
-
-struct storvsc_cmd_request {
-	struct list_head entry;
-	struct scsi_cmnd *cmd;
-
-	unsigned int bounce_sgl_count;
-	struct scatterlist *bounce_sgl;
-
-	struct hv_storvsc_request request;
-};
-
 static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
@@ -646,7 +636,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
 	return ret;
 }
 
-int storvsc_dev_add(struct hv_device *device,
+static int storvsc_dev_add(struct hv_device *device,
 					void *additional_info)
 {
 	struct storvsc_device *stor_device;
@@ -681,7 +671,7 @@ int storvsc_dev_add(struct hv_device *device,
 	return ret;
 }
 
-int storvsc_dev_remove(struct hv_device *device)
+static int storvsc_dev_remove(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
 	unsigned long flags;
@@ -718,7 +708,7 @@ int storvsc_dev_remove(struct hv_device *device)
 	return 0;
 }
 
-int storvsc_do_io(struct hv_device *device,
+static int storvsc_do_io(struct hv_device *device,
 			      struct hv_storvsc_request *request)
 {
 	struct storvsc_device *stor_device;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 27/46] Staging: hv: storvsc: Fixup srb and scsi status for INQUIRY and MODE_SENSE
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (24 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 26/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 28/46] Staging: hv: storvsc: Fix a typo K. Y. Srinivasan
                     ` (18 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

The current VHD handler on the Windows Host does not correctly handle
INQUIRY and MODE_SENSE commands with some options. Fixup srb_status
in these cases since the failure is not fatal.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 0bb4e0e..72ca25c 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -512,6 +512,23 @@ static void storvsc_on_io_completion(struct hv_device *device,
 
 	stor_pkt = &request->vstor_packet;
 
+	/*
+	 * The current SCSI handling on the host side does
+	 * not correctly handle:
+	 * INQUIRY command with page code parameter set to 0x80
+	 * MODE_SENSE command with cmd[2] == 0x1c
+	 *
+	 * Setup srb and scsi status so this won't be fatal.
+	 * We do this so we can distinguish truly fatal failues
+	 * (srb status == 0x4) and off-line the device in that case.
+	 */
+
+	if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
+		(stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) {
+		vstor_packet->vm_srb.scsi_status = 0;
+		vstor_packet->vm_srb.srb_status = 0x1;
+	}
+
 
 	/* Copy over the status...etc */
 	stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 28/46] Staging: hv: storvsc: Fix a typo
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (25 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 27/46] Staging: hv: storvsc: Fixup srb and scsi status for INQUIRY and MODE_SENSE K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 29/46] Staging: hv: storvsc: In case of scsi errors offline the device K. Y. Srinivasan
                     ` (17 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Fix a typo in a function name.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 72ca25c..ad0f9d4 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1130,9 +1130,9 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
 
 
 /*
- * storvsc_commmand_completion - Command completion processing
+ * storvsc_command_completion - Command completion processing
  */
-static void storvsc_commmand_completion(struct hv_storvsc_request *request)
+static void storvsc_command_completion(struct hv_storvsc_request *request)
 {
 	struct storvsc_cmd_request *cmd_request =
 		(struct storvsc_cmd_request *)request->context;
@@ -1240,7 +1240,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
 		break;
 	}
 
-	request->on_io_completion = storvsc_commmand_completion;
+	request->on_io_completion = storvsc_command_completion;
 	request->context = cmd_request;/* scmnd; */
 
 	vm_srb->port_number = host_dev->port;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 29/46] Staging: hv: storvsc: In case of scsi errors offline the device
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (26 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 28/46] Staging: hv: storvsc: Fix a typo K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 30/46] Staging: hv: storvsc: No need to copy from bounce buffer in case of a failure K. Y. Srinivasan
                     ` (16 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

When we do get fatal errors from the host, offline the device since the
host has already tried all possible recovery actions.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index ad0f9d4..22a1d75 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1154,7 +1154,15 @@ static void storvsc_command_completion(struct hv_storvsc_request *request)
 		}
 	}
 
-	scmnd->result = vm_srb->scsi_status;
+	/*
+	 * If there is an error; offline the device since all
+	 * error recovery strategies would have already been
+	 * deployed on the host side.
+	 */
+	if (vm_srb->srb_status == 0x4)
+		scmnd->result = DID_TARGET_FAILURE << 16;
+	else
+		scmnd->result = vm_srb->scsi_status;
 
 	if (scmnd->result) {
 		if (scsi_normalize_sense(scmnd->sense_buffer,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 30/46] Staging: hv: storvsc: No need to copy from bounce buffer in case of a failure
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (27 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 29/46] Staging: hv: storvsc: In case of scsi errors offline the device K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 31/46] Staging: hv: util: Forcefully shutdown when shutdown is requested K. Y. Srinivasan
                     ` (15 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

No need to copy from bounce buffer in case of a failure; cleanup the code
accordingly.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/storvsc_drv.c |   12 ++----------
 1 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 22a1d75..d575bc9 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -1315,17 +1315,9 @@ retry_request:
 	if (ret == -EAGAIN) {
 		/* no more space */
 
-		if (cmd_request->bounce_sgl_count) {
-			/*
-			 * FIXME: We can optimize on writes by just skipping
-			 * this
-			 */
-			copy_from_bounce_buffer(scsi_sglist(scmnd),
-						cmd_request->bounce_sgl,
-						scsi_sg_count(scmnd));
+		if (cmd_request->bounce_sgl_count)
 			destroy_bounce_buffer(cmd_request->bounce_sgl,
-					      cmd_request->bounce_sgl_count);
-		}
+					cmd_request->bounce_sgl_count);
 
 		kmem_cache_free(host_dev->request_pool, cmd_request);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 31/46] Staging: hv: util: Forcefully shutdown when shutdown is requested
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (28 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 30/46] Staging: hv: storvsc: No need to copy from bounce buffer in case of a failure K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 32/46] Staging: hv: util: Adjust guest time in a process context K. Y. Srinivasan
                     ` (14 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

When the host requests a "shutdown", make sure we shutdown!

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv_util.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index f2f456f..876d44a 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -89,7 +89,7 @@ static void shutdown_onchannelcallback(void *context)
 	}
 
 	if (execute_shutdown == true)
-		orderly_poweroff(false);
+		orderly_poweroff(true);
 }
 
 /*
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 32/46] Staging: hv: util: Adjust guest time in a process context
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (29 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 31/46] Staging: hv: util: Forcefully shutdown when shutdown is requested K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 33/46] Staging: hv: vmbus: Check before invoking the channel callback K. Y. Srinivasan
                     ` (13 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

The current code was adjusting guest time in interrupt context; do this
in process context since we may have to initiate cross-processor
interrupts as part of setting time.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv_util.c |   33 ++++++++++++++++++++++++++++++---
 1 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index 876d44a..e29a2a2 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -107,6 +107,24 @@ static inline void do_adj_guesttime(u64 hosttime)
 }
 
 /*
+ * Set the host time in a process context.
+ */
+
+struct adj_time_work {
+	struct work_struct work;
+	u64	host_time;
+};
+
+static void hv_set_host_time(struct work_struct *work)
+{
+	struct adj_time_work	*wrk;
+
+	wrk = container_of(work, struct adj_time_work, work);
+	do_adj_guesttime(wrk->host_time);
+	kfree(wrk);
+}
+
+/*
  * Synchronize time with host after reboot, restore, etc.
  *
  * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM.
@@ -119,17 +137,26 @@ static inline void do_adj_guesttime(u64 hosttime)
  */
 static inline void adj_guesttime(u64 hosttime, u8 flags)
 {
+	struct adj_time_work    *wrk;
 	static s32 scnt = 50;
 
+	wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC);
+	if (wrk == NULL)
+		return;
+
+	wrk->host_time = hosttime;
 	if ((flags & ICTIMESYNCFLAG_SYNC) != 0) {
-		do_adj_guesttime(hosttime);
+		INIT_WORK(&wrk->work, hv_set_host_time);
+		schedule_work(&wrk->work);
 		return;
 	}
 
 	if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
 		scnt--;
-		do_adj_guesttime(hosttime);
-	}
+		INIT_WORK(&wrk->work, hv_set_host_time);
+		schedule_work(&wrk->work);
+	} else
+		kfree(wrk);
 }
 
 /*
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 33/46] Staging: hv: vmbus: Check before invoking the channel callback
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (30 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 32/46] Staging: hv: util: Adjust guest time in a process context K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 34/46] Staging: hv: vmbus: Properly deal with de-registering " K. Y. Srinivasan
                     ` (12 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

When we close a channel, we set the corresponding callback function to NULL.
Check before invoking the channel callback.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/connection.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index a88ad70..7a3ec75 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -222,7 +222,7 @@ static void process_chn_event(u32 relid)
 	 */
 	channel = relid2channel(relid);
 
-	if (channel) {
+	if (channel && (channel->onchannel_callback != NULL)) {
 		channel->onchannel_callback(channel->channel_callback_context);
 	} else {
 		pr_err("channel not found for relid - %u\n", relid);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 34/46] Staging: hv: vmbus: Properly deal with de-registering channel callback
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (31 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 33/46] Staging: hv: vmbus: Check before invoking the channel callback K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 35/46] Staging: hv: Fix a bug in vmbus_match() K. Y. Srinivasan
                     ` (11 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Ensure that we correctly handle racing invocations of the channel callback
when the channel is being closed. We do this using the channel's inbound_lock.
A side-effect of this strategy is that we avoid repeatedly picking up this lock
as we drain the inbound ring-buffer.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/channel.c     |   20 +++++---------------
 drivers/staging/hv/connection.c  |    3 +++
 drivers/staging/hv/netvsc.c      |    3 ---
 drivers/staging/hv/storvsc_drv.c |    3 ---
 4 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c
index ac92c1f..b6f3d38 100644
--- a/drivers/staging/hv/channel.c
+++ b/drivers/staging/hv/channel.c
@@ -513,9 +513,12 @@ void vmbus_close(struct vmbus_channel *channel)
 {
 	struct vmbus_channel_close_channel *msg;
 	int ret;
+	unsigned long flags;
 
 	/* Stop callback and cancel the timer asap */
+	spin_lock_irqsave(&channel->inbound_lock, flags);
 	channel->onchannel_callback = NULL;
+	spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
 	/* Send a closing message */
 
@@ -735,19 +738,15 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
 	u32 packetlen;
 	u32 userlen;
 	int ret;
-	unsigned long flags;
 
 	*buffer_actual_len = 0;
 	*requestid = 0;
 
-	spin_lock_irqsave(&channel->inbound_lock, flags);
 
 	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
 			     sizeof(struct vmpacket_descriptor));
-	if (ret != 0) {
-		spin_unlock_irqrestore(&channel->inbound_lock, flags);
+	if (ret != 0)
 		return 0;
-	}
 
 	packetlen = desc.len8 << 3;
 	userlen = packetlen - (desc.offset8 << 3);
@@ -755,7 +754,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
 	*buffer_actual_len = userlen;
 
 	if (userlen > bufferlen) {
-		spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
 		pr_err("Buffer too small - got %d needs %d\n",
 			   bufferlen, userlen);
@@ -768,7 +766,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
 	ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
 			     (desc.offset8 << 3));
 
-	spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
 	return 0;
 }
@@ -785,19 +782,15 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
 	u32 packetlen;
 	u32 userlen;
 	int ret;
-	unsigned long flags;
 
 	*buffer_actual_len = 0;
 	*requestid = 0;
 
-	spin_lock_irqsave(&channel->inbound_lock, flags);
 
 	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
 			     sizeof(struct vmpacket_descriptor));
-	if (ret != 0) {
-		spin_unlock_irqrestore(&channel->inbound_lock, flags);
+	if (ret != 0)
 		return 0;
-	}
 
 
 	packetlen = desc.len8 << 3;
@@ -806,8 +799,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
 	*buffer_actual_len = packetlen;
 
 	if (packetlen > bufferlen) {
-		spin_unlock_irqrestore(&channel->inbound_lock, flags);
-
 		pr_err("Buffer too small - needed %d bytes but "
 			"got space for only %d bytes\n",
 			packetlen, bufferlen);
@@ -819,7 +810,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
 	/* Copy over the entire packet to the user buffer */
 	ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
 
-	spin_unlock_irqrestore(&channel->inbound_lock, flags);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index 7a3ec75..6aab802 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -215,6 +215,7 @@ struct vmbus_channel *relid2channel(u32 relid)
 static void process_chn_event(u32 relid)
 {
 	struct vmbus_channel *channel;
+	unsigned long flags;
 
 	/*
 	 * Find the channel based on this relid and invokes the
@@ -222,11 +223,13 @@ static void process_chn_event(u32 relid)
 	 */
 	channel = relid2channel(relid);
 
+	spin_lock_irqsave(&channel->inbound_lock, flags);
 	if (channel && (channel->onchannel_callback != NULL)) {
 		channel->onchannel_callback(channel->channel_callback_context);
 	} else {
 		pr_err("channel not found for relid - %u\n", relid);
 	}
+	spin_unlock_irqrestore(&channel->inbound_lock, flags);
 }
 
 /*
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index 9828f0b..e4cc40a 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -62,9 +62,7 @@ static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
 static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
 {
 	struct netvsc_device *net_device;
-	unsigned long flags;
 
-	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	net_device = device->ext;
 
 	if (!net_device)
@@ -75,7 +73,6 @@ static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
 		net_device = NULL;
 
 get_in_err:
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 	return net_device;
 }
 
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index d575bc9..3686d10 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -352,9 +352,7 @@ static inline struct storvsc_device *get_in_stor_device(
 					struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
-	unsigned long flags;
 
-	spin_lock_irqsave(&device->channel->inbound_lock, flags);
 	stor_device = (struct storvsc_device *)device->ext;
 
 	if (!stor_device)
@@ -370,7 +368,6 @@ static inline struct storvsc_device *get_in_stor_device(
 		stor_device = NULL;
 
 get_in_err:
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
 	return stor_device;
 
 }
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 35/46] Staging: hv: Fix a bug in vmbus_match()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (32 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 34/46] Staging: hv: vmbus: Properly deal with de-registering " K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-29 18:00     ` Greg KH
  2011-08-27 18:31   ` [PATCH 36/46] Staging: hv: vmbus: Get rid of vmbus_on_isr() by inlining the code K. Y. Srinivasan
                     ` (10 subsequent siblings)
  44 siblings, 1 reply; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

The recent checkin that add a private pointer to hv_vmbus_device_id
introduced this bug in vmbus_match; fix it.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index be62b62..51002c0 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -273,7 +273,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
 
 	for (; !is_null_guid(id_array->guid); id_array++)
 		if (!memcmp(&id_array->guid, &hv_dev->dev_type.b,
-				sizeof(struct hv_vmbus_device_id)))
+				sizeof(uuid_le)))
 			return 1;
 
 	return 0;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 36/46] Staging: hv: vmbus: Get rid of vmbus_on_isr() by inlining the code
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (33 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 35/46] Staging: hv: Fix a bug in vmbus_match() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 37/46] Staging: hv: vmbus: Check for events before messages K. Y. Srinivasan
                     ` (9 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of vmbus_on_isr() by inlining the code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |   41 +++++++++++----------------------------
 1 files changed, 12 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 51002c0..5dcc8c3 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -437,53 +437,36 @@ static void vmbus_on_msg_dpc(unsigned long data)
 	}
 }
 
-/*
- * vmbus_on_isr - ISR routine
- */
-static int vmbus_on_isr(void)
+static irqreturn_t vmbus_isr(int irq, void *dev_id)
 {
-	int ret = 0;
 	int cpu = smp_processor_id();
 	void *page_addr;
 	struct hv_message *msg;
 	union hv_synic_event_flags *event;
+	bool handled = false;
 
 	page_addr = hv_context.synic_message_page[cpu];
 	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Check if there are actual msgs to be process */
-	if (msg->header.message_type != HVMSG_NONE)
-		ret |= 0x1;
+	if (msg->header.message_type != HVMSG_NONE) {
+		handled = true;
+		tasklet_schedule(&msg_dpc);
+	}
 
 	page_addr = hv_context.synic_event_page[cpu];
 	event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Since we are a child, we only need to check bit 0 */
-	if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0]))
-		ret |= 0x2;
-
-	return ret;
-}
-
-
-static irqreturn_t vmbus_isr(int irq, void *dev_id)
-{
-	int ret;
-
-	ret = vmbus_on_isr();
-
-	/* Schedules a dpc if necessary */
-	if (ret > 0) {
-		if (test_bit(0, (unsigned long *)&ret))
-			tasklet_schedule(&msg_dpc);
-
-		if (test_bit(1, (unsigned long *)&ret))
-			tasklet_schedule(&event_dpc);
+	if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) {
+		handled = true;
+		tasklet_schedule(&event_dpc);
+	}
 
+	if (handled)
 		return IRQ_HANDLED;
-	} else {
+	else
 		return IRQ_NONE;
-	}
 }
 
 /*
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 37/46] Staging: hv: vmbus: Check for events before messages
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (34 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 36/46] Staging: hv: vmbus: Get rid of vmbus_on_isr() by inlining the code K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-29 18:05     ` Greg KH
  2011-08-27 18:31   ` [PATCH 38/46] Staging: hv: vmbus: Do not enable auto eoi K. Y. Srinivasan
                     ` (8 subsequent siblings)
  44 siblings, 1 reply; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Conform to Windows specification by checking for events before messages.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 5dcc8c3..4e07d4f 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -445,15 +445,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
 	union hv_synic_event_flags *event;
 	bool handled = false;
 
-	page_addr = hv_context.synic_message_page[cpu];
-	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
-
-	/* Check if there are actual msgs to be process */
-	if (msg->header.message_type != HVMSG_NONE) {
-		handled = true;
-		tasklet_schedule(&msg_dpc);
-	}
-
 	page_addr = hv_context.synic_event_page[cpu];
 	event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
 
@@ -463,6 +454,15 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
 		tasklet_schedule(&event_dpc);
 	}
 
+	page_addr = hv_context.synic_message_page[cpu];
+	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
+
+	/* Check if there are actual msgs to be processed */
+	if (msg->header.message_type != HVMSG_NONE) {
+		handled = true;
+		tasklet_schedule(&msg_dpc);
+	}
+
 	if (handled)
 		return IRQ_HANDLED;
 	else
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 38/46] Staging: hv: vmbus: Do not enable auto eoi
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (35 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 37/46] Staging: hv: vmbus: Check for events before messages K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 39/46] Staging: hv: vmbus: Fixup indentation in vmbus_acpi_add() K. Y. Srinivasan
                     ` (7 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Linux interrupt handling code generates the eoi; don't enable auto eoi.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c
index 736794e..06f1e15 100644
--- a/drivers/staging/hv/hv.c
+++ b/drivers/staging/hv/hv.c
@@ -369,7 +369,7 @@ void hv_synic_init(void *irqarg)
 	shared_sint.as_uint64 = 0;
 	shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
 	shared_sint.masked = false;
-	shared_sint.auto_eoi = true;
+	shared_sint.auto_eoi = false;
 
 	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 39/46] Staging: hv: vmbus: Fixup indentation in vmbus_acpi_add()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (36 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 38/46] Staging: hv: vmbus: Do not enable auto eoi K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 40/46] Staging: hv: vmbus: Get rid of some dated/redundant comments K. Y. Srinivasan
                     ` (6 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Fixup indentation in vmbus_acpi_add().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 4e07d4f..d50fa89 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -678,9 +678,8 @@ static int vmbus_acpi_add(struct acpi_device *device)
 
 	hv_acpi_dev = device;
 
-	result =
-	acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-			vmbus_walk_resources, &irq);
+	result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+					vmbus_walk_resources, &irq);
 
 	if (ACPI_FAILURE(result)) {
 		complete(&probe_event);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 40/46] Staging: hv: vmbus: Get rid of some dated/redundant comments
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (37 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 39/46] Staging: hv: vmbus: Fixup indentation in vmbus_acpi_add() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init() K. Y. Srinivasan
                     ` (5 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of some dated/redundant comments in vmbus_drv.c

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |   11 +----------
 1 files changed, 1 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index d50fa89..02edb11 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -391,9 +391,6 @@ static void vmbus_onmessage_work(struct work_struct *work)
 	kfree(ctx);
 }
 
-/*
- * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior
- */
 static void vmbus_on_msg_dpc(unsigned long data)
 {
 	int cpu = smp_processor_id();
@@ -490,16 +487,13 @@ static int vmbus_bus_init(int irq)
 		return ret;
 	}
 
-	/* Initialize the bus context */
 	tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
 	tasklet_init(&event_dpc, vmbus_on_event, 0);
 
-	/* Now, register the bus  with LDM */
 	ret = bus_register(&hv_bus);
 	if (ret)
 		return ret;
 
-	/* Get the interrupt resource */
 	ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
 			driver_name, hv_acpi_dev);
 
@@ -588,7 +582,6 @@ struct hv_device *vmbus_child_device_create(uuid_le *type,
 {
 	struct hv_device *child_device_obj;
 
-	/* Allocate the new child device */
 	child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL);
 	if (!child_device_obj) {
 		pr_err("Unable to allocate device object for child device\n");
@@ -613,12 +606,10 @@ int vmbus_child_device_register(struct hv_device *child_device_obj)
 
 	static atomic_t device_num = ATOMIC_INIT(0);
 
-	/* Set the device name. Otherwise, device_register() will fail. */
 	dev_set_name(&child_device_obj->device, "vmbus_0_%d",
 		     atomic_inc_return(&device_num));
 
-	/* The new device belongs to this bus */
-	child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */
+	child_device_obj->device.bus = &hv_bus;
 	child_device_obj->device.parent = &hv_acpi_dev->dev;
 	child_device_obj->device.release = vmbus_device_release;
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (38 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 40/46] Staging: hv: vmbus: Get rid of some dated/redundant comments K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-29 18:08     ` Greg KH
  2011-08-27 18:31   ` [PATCH 42/46] Staging: hv: vmbus: Get rid of an unnecessary check in vmbus_connect() K. Y. Srinivasan
                     ` (4 subsequent siblings)
  44 siblings, 1 reply; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Fix a bug in error handling in vmbus_bus_init().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/vmbus_drv.c |   21 ++++++++++-----------
 1 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 02edb11..4d1b123 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -492,7 +492,7 @@ static int vmbus_bus_init(int irq)
 
 	ret = bus_register(&hv_bus);
 	if (ret)
-		return ret;
+		goto err1;
 
 	ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
 			driver_name, hv_acpi_dev);
@@ -500,10 +500,7 @@ static int vmbus_bus_init(int irq)
 	if (ret != 0) {
 		pr_err("Unable to request IRQ %d\n",
 			   irq);
-
-		bus_unregister(&hv_bus);
-
-		return ret;
+		goto err2;
 	}
 
 	vector = IRQ0_VECTOR + irq;
@@ -514,16 +511,18 @@ static int vmbus_bus_init(int irq)
 	 */
 	on_each_cpu(hv_synic_init, (void *)&vector, 1);
 	ret = vmbus_connect();
-	if (ret) {
-		free_irq(irq, hv_acpi_dev);
-		bus_unregister(&hv_bus);
-		return ret;
-	}
-
+	if (ret)
+		goto err3;
 
 	vmbus_request_offers();
 
 	return 0;
+
+err3:	free_irq(irq, hv_acpi_dev);
+err2:	bus_unregister(&hv_bus);
+err1:	hv_cleanup();
+
+	return ret;
 }
 
 /**
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 42/46] Staging: hv: vmbus: Get rid of an unnecessary check in vmbus_connect()
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (39 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 43/46] Staging: hv: vmbus: Fix a checkpatch warning in ring_buffer.c K. Y. Srinivasan
                     ` (3 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Get rid of an unnecessary check in vmbus_connect().

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/connection.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index 6aab802..ca92ca3 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -50,10 +50,6 @@ int vmbus_connect(void)
 	struct vmbus_channel_initiate_contact *msg;
 	unsigned long flags;
 
-	/* Make sure we are not connecting or connected */
-	if (vmbus_connection.conn_state != DISCONNECTED)
-		return -EISCONN;
-
 	/* Initialize the vmbus connection */
 	vmbus_connection.conn_state = CONNECTING;
 	vmbus_connection.work_queue = create_workqueue("hv_vmbus_con");
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 43/46] Staging: hv: vmbus: Fix a checkpatch warning in ring_buffer.c
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (40 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 42/46] Staging: hv: vmbus: Get rid of an unnecessary check in vmbus_connect() K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c K. Y. Srinivasan
                     ` (2 subsequent siblings)
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Fix a checkpatch warning in ring_buffer.c

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/ring_buffer.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c
index 9212699..70e2e66 100644
--- a/drivers/staging/hv/ring_buffer.c
+++ b/drivers/staging/hv/ring_buffer.c
@@ -34,7 +34,8 @@
 
 
 /* Amount of space to write to */
-#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
+#define BYTES_AVAIL_TO_WRITE(r, w, z) \
+	((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
 
 
 /*
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (41 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 43/46] Staging: hv: vmbus: Fix a checkpatch warning in ring_buffer.c K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-28  6:56     ` Joe Perches
  2011-08-29 18:09     ` Greg KH
  2011-08-27 18:31   ` [PATCH 45/46] Staging: hv: mousevsc: Fix checkpatch errors and warnings K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 46/46] Staging: hv: Update the TODO file K. Y. Srinivasan
  44 siblings, 2 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Fix checkpatch warnings in connection.c.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/connection.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index ca92ca3..9e99c04 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -220,11 +220,11 @@ static void process_chn_event(u32 relid)
 	channel = relid2channel(relid);
 
 	spin_lock_irqsave(&channel->inbound_lock, flags);
-	if (channel && (channel->onchannel_callback != NULL)) {
+	if (channel && (channel->onchannel_callback != NULL))
 		channel->onchannel_callback(channel->channel_callback_context);
-	} else {
+	else
 		pr_err("channel not found for relid - %u\n", relid);
-	}
+
 	spin_unlock_irqrestore(&channel->inbound_lock, flags);
 }
 
@@ -246,16 +246,17 @@ void vmbus_on_event(unsigned long data)
 		if (!recv_int_page[dword])
 			continue;
 		for (bit = 0; bit < 32; bit++) {
-			if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) {
+			if (sync_test_and_clear_bit(bit,
+				(unsigned long *)&recv_int_page[dword])) {
 				relid = (dword << 5) + bit;
 
-				if (relid == 0) {
+				if (relid == 0)
 					/*
 					 * Special case - vmbus
 					 * channel protocol msg
 					 */
 					continue;
-				}
+
 				process_chn_event(relid);
 			}
 		}
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 45/46] Staging: hv: mousevsc: Fix checkpatch errors and warnings
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (42 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-27 18:31   ` [PATCH 46/46] Staging: hv: Update the TODO file K. Y. Srinivasan
  44 siblings, 0 replies; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Fix checkpatch errors and warnings.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/hv_mouse.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
index 090736a..dbb04ee 100644
--- a/drivers/staging/hv/hv_mouse.c
+++ b/drivers/staging/hv/hv_mouse.c
@@ -335,7 +335,8 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
 	input_device->hid_desc = kzalloc(desc->bLength, GFP_KERNEL);
 
 	if (!input_device->hid_desc) {
-		pr_err("unable to allocate hid descriptor - size %d", desc->bLength);
+		pr_err("unable to allocate hid descriptor - size %d",
+			 desc->bLength);
 		goto cleanup;
 	}
 
@@ -598,12 +599,12 @@ static int mousevsc_connect_to_vsp(struct hv_device *device)
 	pr_info("synthhid protocol request...");
 
 	ret = vmbus_sendpacket(device->channel, request,
-					sizeof(struct pipe_prt_msg) -
-					sizeof(unsigned char) +
-					sizeof(struct synthhid_protocol_request),
-					(unsigned long)request,
-					VM_PKT_DATA_INBAND,
-					VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+				sizeof(struct pipe_prt_msg) -
+				sizeof(unsigned char) +
+				sizeof(struct synthhid_protocol_request),
+				(unsigned long)request,
+				VM_PKT_DATA_INBAND,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 	if (ret != 0) {
 		pr_err("unable to send synthhid protocol request.");
 		goto cleanup;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 46/46] Staging: hv: Update the TODO file
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
                     ` (43 preceding siblings ...)
  2011-08-27 18:31   ` [PATCH 45/46] Staging: hv: mousevsc: Fix checkpatch errors and warnings K. Y. Srinivasan
@ 2011-08-27 18:31   ` K. Y. Srinivasan
  2011-08-29 18:12     ` Greg KH
  44 siblings, 1 reply; 77+ messages in thread
From: K. Y. Srinivasan @ 2011-08-27 18:31 UTC (permalink / raw)
  To: gregkh, linux-kernel, devel, virtualization
  Cc: K. Y. Srinivasan, Haiyang Zhang

Update the TODO file.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/staging/hv/TODO |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
index 582fd4a..23c74ed 100644
--- a/drivers/staging/hv/TODO
+++ b/drivers/staging/hv/TODO
@@ -1,14 +1,30 @@
 TODO:
-	- fix remaining checkpatch warnings and errors
 	- audit the vmbus to verify it is working properly with the
 	  driver model
-	- see if the vmbus can be merged with the other virtual busses
-	  in the kernel
+
+		STATUS (July 19, 2011):
+		All outstanding issues (known to us)  with regards
+		to conforming to Linux Driver Model have been addressed.
+
 	- audit the network driver
 	  - checking for carrier inside open is wrong, network device API
             confusion??
+
+		STATUS (July 19, 2011):
+		The network driver has been reviewed by the community.
+		We have addressed the various issues that were raised in this
+		review.
+
 	- audit the block driver
 	- audit the scsi driver
 
+		STATUS (July 19, 2011):
+		One of the longstanding comment on this body of code
+		has been to merge the block and scsi driver. This has been done
+		and patches have been submitted. We have also addressed all the
+		review comments on this body of code.
+
+
 Please send patches for this code to Greg Kroah-Hartman <gregkh@suse.de>,
-Hank Janssen <hjanssen@microsoft.com>, and Haiyang Zhang <haiyangz@microsoft.com>.
+Hank Janssen <hjanssen@microsoft.com>, and Haiyang Zhang <haiyangz@microsoft.com>,
+K. Y. Srinivasan <kys@microsoft.com>.
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
  2011-08-27 18:31   ` [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c K. Y. Srinivasan
@ 2011-08-28  6:56     ` Joe Perches
  2011-08-30 17:03       ` KY Srinivasan
  2011-08-29 18:09     ` Greg KH
  1 sibling, 1 reply; 77+ messages in thread
From: Joe Perches @ 2011-08-28  6:56 UTC (permalink / raw)
  To: K. Y. Srinivasan
  Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Sat, 2011-08-27 at 11:31 -0700, K. Y. Srinivasan wrote:
> Fix checkpatch warnings in connection.c.
[]
> diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
[]
> @@ -220,11 +220,11 @@ static void process_chn_event(u32 relid)
>  	channel = relid2channel(relid);
>  
>  	spin_lock_irqsave(&channel->inbound_lock, flags);
> -	if (channel && (channel->onchannel_callback != NULL)) {
> +	if (channel && (channel->onchannel_callback != NULL))

Useless test for channel or bad placement for spin_lock.
channel has already been dereferenced by the spin_lock.



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 35/46] Staging: hv: Fix a bug in vmbus_match()
  2011-08-27 18:31   ` [PATCH 35/46] Staging: hv: Fix a bug in vmbus_match() K. Y. Srinivasan
@ 2011-08-29 18:00     ` Greg KH
  0 siblings, 0 replies; 77+ messages in thread
From: Greg KH @ 2011-08-29 18:00 UTC (permalink / raw)
  To: K. Y. Srinivasan
  Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Sat, Aug 27, 2011 at 11:31:34AM -0700, K. Y. Srinivasan wrote:
> The recent checkin that add a private pointer to hv_vmbus_device_id
> introduced this bug in vmbus_match; fix it.
> 
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/staging/hv/vmbus_drv.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
> index be62b62..51002c0 100644
> --- a/drivers/staging/hv/vmbus_drv.c
> +++ b/drivers/staging/hv/vmbus_drv.c
> @@ -273,7 +273,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
>  
>  	for (; !is_null_guid(id_array->guid); id_array++)
>  		if (!memcmp(&id_array->guid, &hv_dev->dev_type.b,
> -				sizeof(struct hv_vmbus_device_id)))
> +				sizeof(uuid_le)))

Ick, sorry about this, it was my fault.

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 37/46] Staging: hv: vmbus: Check for events before messages
  2011-08-27 18:31   ` [PATCH 37/46] Staging: hv: vmbus: Check for events before messages K. Y. Srinivasan
@ 2011-08-29 18:05     ` Greg KH
  2011-08-30 17:06       ` KY Srinivasan
  0 siblings, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-29 18:05 UTC (permalink / raw)
  To: K. Y. Srinivasan
  Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Sat, Aug 27, 2011 at 11:31:36AM -0700, K. Y. Srinivasan wrote:
> Conform to Windows specification by checking for events before messages.

What specification?

Care to provide a comment in the code that you are doing this in this
explicit order because of some rule that the hypervisor imposes on us?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
  2011-08-27 18:31   ` [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init() K. Y. Srinivasan
@ 2011-08-29 18:08     ` Greg KH
  2011-08-30 10:29       ` Dan Carpenter
  2011-08-30 17:07       ` KY Srinivasan
  0 siblings, 2 replies; 77+ messages in thread
From: Greg KH @ 2011-08-29 18:08 UTC (permalink / raw)
  To: K. Y. Srinivasan
  Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Sat, Aug 27, 2011 at 11:31:40AM -0700, K. Y. Srinivasan wrote:
> Fix a bug in error handling in vmbus_bus_init().
> 
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/staging/hv/vmbus_drv.c |   21 ++++++++++-----------
>  1 files changed, 10 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
> index 02edb11..4d1b123 100644
> --- a/drivers/staging/hv/vmbus_drv.c
> +++ b/drivers/staging/hv/vmbus_drv.c
> @@ -492,7 +492,7 @@ static int vmbus_bus_init(int irq)
>  
>  	ret = bus_register(&hv_bus);
>  	if (ret)
> -		return ret;
> +		goto err1;
>  
>  	ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
>  			driver_name, hv_acpi_dev);
> @@ -500,10 +500,7 @@ static int vmbus_bus_init(int irq)
>  	if (ret != 0) {
>  		pr_err("Unable to request IRQ %d\n",
>  			   irq);
> -
> -		bus_unregister(&hv_bus);
> -
> -		return ret;
> +		goto err2;
>  	}
>  
>  	vector = IRQ0_VECTOR + irq;
> @@ -514,16 +511,18 @@ static int vmbus_bus_init(int irq)
>  	 */
>  	on_each_cpu(hv_synic_init, (void *)&vector, 1);
>  	ret = vmbus_connect();
> -	if (ret) {
> -		free_irq(irq, hv_acpi_dev);
> -		bus_unregister(&hv_bus);
> -		return ret;
> -	}
> -
> +	if (ret)
> +		goto err3;
>  
>  	vmbus_request_offers();
>  
>  	return 0;
> +
> +err3:	free_irq(irq, hv_acpi_dev);
> +err2:	bus_unregister(&hv_bus);
> +err1:	hv_cleanup();

The traditional way to write this is:

err3:
	free_irq(irq, hv_acpi_dev);
err2:
	bus_unregister(&hv_bus);
err1:
	hv_cleanup();

Care to fix this up and resend it?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
  2011-08-27 18:31   ` [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c K. Y. Srinivasan
  2011-08-28  6:56     ` Joe Perches
@ 2011-08-29 18:09     ` Greg KH
  2011-08-30 17:11       ` KY Srinivasan
  1 sibling, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-29 18:09 UTC (permalink / raw)
  To: K. Y. Srinivasan
  Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Sat, Aug 27, 2011 at 11:31:43AM -0700, K. Y. Srinivasan wrote:
> Fix checkpatch warnings in connection.c.
> 
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/staging/hv/connection.c |   13 +++++++------
>  1 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
> index ca92ca3..9e99c04 100644
> --- a/drivers/staging/hv/connection.c
> +++ b/drivers/staging/hv/connection.c
> @@ -220,11 +220,11 @@ static void process_chn_event(u32 relid)
>  	channel = relid2channel(relid);
>  
>  	spin_lock_irqsave(&channel->inbound_lock, flags);
> -	if (channel && (channel->onchannel_callback != NULL)) {
> +	if (channel && (channel->onchannel_callback != NULL))
>  		channel->onchannel_callback(channel->channel_callback_context);
> -	} else {

I agree with Joe here, if channel really was NULL, you just oopsed.

I'll apply this one, but please send me a follow-on one fixing this bug.

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 46/46] Staging: hv: Update the TODO file
  2011-08-27 18:31   ` [PATCH 46/46] Staging: hv: Update the TODO file K. Y. Srinivasan
@ 2011-08-29 18:12     ` Greg KH
  2011-08-30 17:13       ` KY Srinivasan
  0 siblings, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-29 18:12 UTC (permalink / raw)
  To: K. Y. Srinivasan
  Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Sat, Aug 27, 2011 at 11:31:45AM -0700, K. Y. Srinivasan wrote:
> Update the TODO file.
> 
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/staging/hv/TODO |   24 ++++++++++++++++++++----
>  1 files changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
> index 582fd4a..23c74ed 100644
> --- a/drivers/staging/hv/TODO
> +++ b/drivers/staging/hv/TODO
> @@ -1,14 +1,30 @@
>  TODO:
> -	- fix remaining checkpatch warnings and errors
>  	- audit the vmbus to verify it is working properly with the
>  	  driver model
> -	- see if the vmbus can be merged with the other virtual busses
> -	  in the kernel
> +
> +		STATUS (July 19, 2011):
> +		All outstanding issues (known to us)  with regards
> +		to conforming to Linux Driver Model have been addressed.

The TODO file is not a place to have a "conversation" about what is and
is not completed by having status reports.

Let's discuss this through email, and if we all agree, then the TODO
entries can be removed.

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-27 18:31 [PATCH 0000/0046] Staging: hv: Driver cleanup K. Y. Srinivasan
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
@ 2011-08-29 18:15 ` Greg KH
  2011-08-30 17:27   ` KY Srinivasan
  2011-08-30 12:48 ` Olaf Hering
  2 siblings, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-29 18:15 UTC (permalink / raw)
  To: K. Y. Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization

On Sat, Aug 27, 2011 at 11:31:14AM -0700, K. Y. Srinivasan wrote:
> Further cleanup of the hv drivers. 
> 
> 	1) Cleanup reference counting.
> 
> 	2) Handle all block devices using the storvsc driver. I have modified
> 	   the implementation here based on Christoph's feedback on my earlier
> 	   implementation.
> 
> 	3) Fix bugs.
> 
> 	4) Accomodate some host side scsi emulation bugs.
> 
> 	5) In case of scsi errors off-line the device.
> 
> This patch-set further reduces the size of Hyper-V drivers - the code is
> about 10% smaller. This reduction is mainly because we have eliminated the
> blkvsc driver.

If my tracking is correct, I applied everything in this series except
the following patches
	[PATCH 37/46] Staging: hv: vmbus: Check for events before messages
	[PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
	[PATCH 46/46] Staging: hv: Update the TODO file

Please fix up patches 37 and 41 and resend, and for 46, that should be
totally different as mentioned, but you might want to send a patch that
at the least adds your name to the file at the bottom, as you wanted.
Also note that the MAINTAINERS file should also be adjusted to match.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
  2011-08-29 18:08     ` Greg KH
@ 2011-08-30 10:29       ` Dan Carpenter
  2011-08-30 14:07         ` Greg KH
  2011-08-30 17:07       ` KY Srinivasan
  1 sibling, 1 reply; 77+ messages in thread
From: Dan Carpenter @ 2011-08-30 10:29 UTC (permalink / raw)
  To: Greg KH
  Cc: K. Y. Srinivasan, devel, Haiyang Zhang, gregkh, linux-kernel,
	virtualization

> err3:
> 	free_irq(irq, hv_acpi_dev);
> err2:
> 	bus_unregister(&hv_bus);
> err1:
> 	hv_cleanup();

Also here is an oldbie trick.  You could use multiples of ten like
err30, err20, and err10.  That way if you can add more error handling
in the middle without changing the numbering.  I knew my GW-BASIC
experience would come in handy one day.  :)

The better way to label things is based on what happens when you get
there: err_irq, err_unregister, err_cleanup.

Some people label things based on where the goto is, but that breaks
down if there is more than one goto.  It doesn't really make sense to
name the destination after the starting point.

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver
  2011-08-27 18:31   ` [PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver K. Y. Srinivasan
@ 2011-08-30 11:07     ` Dan Carpenter
  0 siblings, 0 replies; 77+ messages in thread
From: Dan Carpenter @ 2011-08-30 11:07 UTC (permalink / raw)
  To: K. Y. Srinivasan
  Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Sat, Aug 27, 2011 at 11:31:17AM -0700, K. Y. Srinivasan wrote:
> @@ -59,6 +59,17 @@ struct storvsc_cmd_request {
>  	struct hv_storvsc_request request;
>  };
>  
> +static void storvsc_get_ide_info(struct hv_device *dev, int *target, int *path)
> +{
> +	*target =
> +		dev->dev_instance.b[5] << 8 | dev->dev_instance.b[4];
> +
> +	*path =
> +		dev->dev_instance.b[3] << 24 |
> +		dev->dev_instance.b[2] << 16 |
> +		dev->dev_instance.b[1] << 8  | dev->dev_instance.b[0];
> +}
> +

Does endianness matter here?  It seems like *path isn't actually used
anywhere.  Probably target and path should be u32 types?

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-27 18:31 [PATCH 0000/0046] Staging: hv: Driver cleanup K. Y. Srinivasan
  2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
  2011-08-29 18:15 ` [PATCH 0000/0046] Staging: hv: Driver cleanup Greg KH
@ 2011-08-30 12:48 ` Olaf Hering
  2011-08-30 17:22   ` KY Srinivasan
  2 siblings, 1 reply; 77+ messages in thread
From: Olaf Hering @ 2011-08-30 12:48 UTC (permalink / raw)
  To: K. Y. Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization

On Sat, Aug 27, K. Y. Srinivasan wrote:

> 	2) Handle all block devices using the storvsc driver. I have modified
> 	   the implementation here based on Christoph's feedback on my earlier
> 	   implementation.

The upgrade path from hv_blkvsc to hv_storvsc is difficult.

hv_storvsc does not provide the vmbus:hv_block modalias, so mkinitrd
does not know what module to choose when mkinitrd is called in a
previous kernel (like sles11sp1).


In a guest with both SCSI and IDE controllers the IDE disks are
discovered first, so the SCSI drives will also change their names.
Thats not a problem for data partitions because they could be mounted by
UUID or LABEL in fstab.
But its difficult to adjust /boot/grub/device.map for example because
the old  IDE drives do not provide an identifier. What is the best way
to make sure the rename from hd* to sd* in such config files is done
correctly? Is it safe to assume that all drives with a class_id of
32412632-86cb-44a2-9b5c50d1417354f5 are connected to IDE ports?

localhost:~ # head /sys/bus/vmbus/devices/vmbus_0_{1,2,3,10,11}/class_id
==> /sys/bus/vmbus/devices/vmbus_0_1/class_id <==
{32412632-86cb-44a2-9b5c50d1417354f5}

==> /sys/bus/vmbus/devices/vmbus_0_2/class_id <==
{32412632-86cb-44a2-9b5c50d1417354f5}

==> /sys/bus/vmbus/devices/vmbus_0_3/class_id <==
{32412632-86cb-44a2-9b5c50d1417354f5}

==> /sys/bus/vmbus/devices/vmbus_0_10/class_id <==
{ba6163d9-04a1-4d29-b60572e2ffb1dc7f}

==> /sys/bus/vmbus/devices/vmbus_0_11/class_id <==
{ba6163d9-04a1-4d29-b60572e2ffb1dc7f}


In my test system, the IDE drives are now discovered twice, once by
hv_storvsc and once by libata:

localhost:~ # lsscsi 
[0:0:0:0]    disk    Msft     Virtual Disk     1.0   /dev/sda 
[1:0:1:0]    disk    Msft     Virtual Disk     1.0   /dev/sdb 
[2:0:1:0]    disk    Msft     Virtual Disk     1.0   /dev/sdc 
[3:0:0:0]    disk    Msft     Virtual Disk     1.0   /dev/sdd 
[3:0:0:1]    disk    Msft     Virtual Disk     1.0   /dev/sde 
[4:0:0:0]    disk    Msft     Virtual Disk     1.0   /dev/sdf 
[4:0:0:1]    disk    Msft     Virtual Disk     1.0   /dev/sdg 
[5:0:0:0]    disk    ATA      Virtual HD       1.1.  /dev/sdh 
[5:0:1:0]    disk    ATA      Virtual HD       1.1.  /dev/sdi 
[6:0:0:0]    cd/dvd  Msft     Virtual CD/ROM   1.0   /dev/sr0 
[6:0:1:0]    disk    ATA      Virtual HD       1.1.  /dev/sdj 
localhost:~ # blkid
/dev/sda1: UUID="47aebbfb-13ee-49cc-b1e7-bc0c243fe3c0" TYPE="swap" 
/dev/sda2: UUID="ed5a182b-da28-42f2-acff-5649a8fae247" TYPE="ext3" 
/dev/sdh1: UUID="47aebbfb-13ee-49cc-b1e7-bc0c243fe3c0" TYPE="swap" 
/dev/sdh2: UUID="ed5a182b-da28-42f2-acff-5649a8fae247" TYPE="ext3" 

sda/sdh was hda.

Olaf

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
  2011-08-30 10:29       ` Dan Carpenter
@ 2011-08-30 14:07         ` Greg KH
  2011-08-30 17:25           ` KY Srinivasan
  0 siblings, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-30 14:07 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: K. Y. Srinivasan, devel, Haiyang Zhang, gregkh, linux-kernel,
	virtualization

On Tue, Aug 30, 2011 at 01:29:49PM +0300, Dan Carpenter wrote:
> > err3:
> > 	free_irq(irq, hv_acpi_dev);
> > err2:
> > 	bus_unregister(&hv_bus);
> > err1:
> > 	hv_cleanup();
> 
> Also here is an oldbie trick.  You could use multiples of ten like
> err30, err20, and err10.  That way if you can add more error handling
> in the middle without changing the numbering.  I knew my GW-BASIC
> experience would come in handy one day.  :)
> 
> The better way to label things is based on what happens when you get
> there: err_irq, err_unregister, err_cleanup.

Yes, that's the best way to do this, thanks for pointing it out.

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
  2011-08-28  6:56     ` Joe Perches
@ 2011-08-30 17:03       ` KY Srinivasan
  0 siblings, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:03 UTC (permalink / raw)
  To: Joe Perches; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1179 bytes --]



> -----Original Message-----
> From: Joe Perches [mailto:joe@perches.com]
> Sent: Sunday, August 28, 2011 2:57 AM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; Haiyang Zhang
> Subject: Re: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in
> connection.c
> 
> On Sat, 2011-08-27 at 11:31 -0700, K. Y. Srinivasan wrote:
> > Fix checkpatch warnings in connection.c.
> []
> > diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
> []
> > @@ -220,11 +220,11 @@ static void process_chn_event(u32 relid)
> >  	channel = relid2channel(relid);
> >
> >  	spin_lock_irqsave(&channel->inbound_lock, flags);
> > -	if (channel && (channel->onchannel_callback != NULL)) {
> > +	if (channel && (channel->onchannel_callback != NULL))
> 
> Useless test for channel or bad placement for spin_lock.
> channel has already been dereferenced by the spin_lock.
> 
> 
Thanks Joe. I will fix this up.

Regards,

K. Y
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 37/46] Staging: hv: vmbus: Check for events before messages
  2011-08-29 18:05     ` Greg KH
@ 2011-08-30 17:06       ` KY Srinivasan
  2011-08-30 17:38         ` Greg KH
  0 siblings, 1 reply; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:06 UTC (permalink / raw)
  To: Greg KH; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Monday, August 29, 2011 2:05 PM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; Haiyang Zhang
> Subject: Re: [PATCH 37/46] Staging: hv: vmbus: Check for events before
> messages
> 
> On Sat, Aug 27, 2011 at 11:31:36AM -0700, K. Y. Srinivasan wrote:
> > Conform to Windows specification by checking for events before messages.
> 
> What specification?
> 
> Care to provide a comment in the code that you are doing this in this
> explicit order because of some rule that the hypervisor imposes on us?

I am not sure if this is documented anywhere (publicly). In talking to Windows 
guys, they suggested this is the order in which it is done on Windows guests and suggested
I should do the same. I will see if there is some public documentation that specifies this.

Regards,

K. Y
> 
> thanks,
> 
> greg k-h


^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
  2011-08-29 18:08     ` Greg KH
  2011-08-30 10:29       ` Dan Carpenter
@ 2011-08-30 17:07       ` KY Srinivasan
  1 sibling, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:07 UTC (permalink / raw)
  To: Greg KH; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Monday, August 29, 2011 2:09 PM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; Haiyang Zhang
> Subject: Re: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in
> vmbus_bus_init()
> 
> On Sat, Aug 27, 2011 at 11:31:40AM -0700, K. Y. Srinivasan wrote:
> > Fix a bug in error handling in vmbus_bus_init().
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/staging/hv/vmbus_drv.c |   21 ++++++++++-----------
> >  1 files changed, 10 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
> > index 02edb11..4d1b123 100644
> > --- a/drivers/staging/hv/vmbus_drv.c
> > +++ b/drivers/staging/hv/vmbus_drv.c
> > @@ -492,7 +492,7 @@ static int vmbus_bus_init(int irq)
> >
> >  	ret = bus_register(&hv_bus);
> >  	if (ret)
> > -		return ret;
> > +		goto err1;
> >
> >  	ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
> >  			driver_name, hv_acpi_dev);
> > @@ -500,10 +500,7 @@ static int vmbus_bus_init(int irq)
> >  	if (ret != 0) {
> >  		pr_err("Unable to request IRQ %d\n",
> >  			   irq);
> > -
> > -		bus_unregister(&hv_bus);
> > -
> > -		return ret;
> > +		goto err2;
> >  	}
> >
> >  	vector = IRQ0_VECTOR + irq;
> > @@ -514,16 +511,18 @@ static int vmbus_bus_init(int irq)
> >  	 */
> >  	on_each_cpu(hv_synic_init, (void *)&vector, 1);
> >  	ret = vmbus_connect();
> > -	if (ret) {
> > -		free_irq(irq, hv_acpi_dev);
> > -		bus_unregister(&hv_bus);
> > -		return ret;
> > -	}
> > -
> > +	if (ret)
> > +		goto err3;
> >
> >  	vmbus_request_offers();
> >
> >  	return 0;
> > +
> > +err3:	free_irq(irq, hv_acpi_dev);
> > +err2:	bus_unregister(&hv_bus);
> > +err1:	hv_cleanup();
> 
> The traditional way to write this is:
> 
> err3:
> 	free_irq(irq, hv_acpi_dev);
> err2:
> 	bus_unregister(&hv_bus);
> err1:
> 	hv_cleanup();
> 
> Care to fix this up and resend it?

Will do.

Regards,

K. Y


^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
  2011-08-29 18:09     ` Greg KH
@ 2011-08-30 17:11       ` KY Srinivasan
  2011-08-30 17:41         ` Greg KH
  0 siblings, 1 reply; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:11 UTC (permalink / raw)
  To: Greg KH; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Monday, August 29, 2011 2:10 PM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; Haiyang Zhang
> Subject: Re: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in
> connection.c
> 
> On Sat, Aug 27, 2011 at 11:31:43AM -0700, K. Y. Srinivasan wrote:
> > Fix checkpatch warnings in connection.c.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/staging/hv/connection.c |   13 +++++++------
> >  1 files changed, 7 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
> > index ca92ca3..9e99c04 100644
> > --- a/drivers/staging/hv/connection.c
> > +++ b/drivers/staging/hv/connection.c
> > @@ -220,11 +220,11 @@ static void process_chn_event(u32 relid)
> >  	channel = relid2channel(relid);
> >
> >  	spin_lock_irqsave(&channel->inbound_lock, flags);
> > -	if (channel && (channel->onchannel_callback != NULL)) {
> > +	if (channel && (channel->onchannel_callback != NULL))
> >  		channel->onchannel_callback(channel-
> >channel_callback_context);
> > -	} else {
> 
> I agree with Joe here, if channel really was NULL, you just oopsed.
> 
> I'll apply this one, but please send me a follow-on one fixing this bug.

Thanks Greg. I will fix this. I got these patches out just before Hurricane Irene
hit the east coast. While we were lucky that it was not as bad as was predicted,
we lost power and we still don't have power. I have come to a public library in
a nearby town to check my email.  So, my responses will be sporadic over the 
next couple of days (until we get power). I will try to address the issues you
have raised as quickly as possible.

Regards,

K. Y


^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 46/46] Staging: hv: Update the TODO file
  2011-08-29 18:12     ` Greg KH
@ 2011-08-30 17:13       ` KY Srinivasan
  0 siblings, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:13 UTC (permalink / raw)
  To: Greg KH; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Monday, August 29, 2011 2:12 PM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; Haiyang Zhang
> Subject: Re: [PATCH 46/46] Staging: hv: Update the TODO file
> 
> On Sat, Aug 27, 2011 at 11:31:45AM -0700, K. Y. Srinivasan wrote:
> > Update the TODO file.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/staging/hv/TODO |   24 ++++++++++++++++++++----
> >  1 files changed, 20 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
> > index 582fd4a..23c74ed 100644
> > --- a/drivers/staging/hv/TODO
> > +++ b/drivers/staging/hv/TODO
> > @@ -1,14 +1,30 @@
> >  TODO:
> > -	- fix remaining checkpatch warnings and errors
> >  	- audit the vmbus to verify it is working properly with the
> >  	  driver model
> > -	- see if the vmbus can be merged with the other virtual busses
> > -	  in the kernel
> > +
> > +		STATUS (July 19, 2011):
> > +		All outstanding issues (known to us)  with regards
> > +		to conforming to Linux Driver Model have been addressed.
> 
> The TODO file is not a place to have a "conversation" about what is and
> is not completed by having status reports.
> 
> Let's discuss this through email, and if we all agree, then the TODO
> entries can be removed.

Ok; will do.

K. Y
> 
> greg k-h


^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-30 12:48 ` Olaf Hering
@ 2011-08-30 17:22   ` KY Srinivasan
  2011-08-30 17:43     ` Greg KH
  0 siblings, 1 reply; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:22 UTC (permalink / raw)
  To: Olaf Hering; +Cc: gregkh, linux-kernel, devel, virtualization

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2896 bytes --]



> -----Original Message-----
> From: Olaf Hering [mailto:olaf@aepfle.de]
> Sent: Tuesday, August 30, 2011 8:49 AM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org
> Subject: Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
> 
> On Sat, Aug 27, K. Y. Srinivasan wrote:
> 
> > 	2) Handle all block devices using the storvsc driver. I have modified
> > 	   the implementation here based on Christoph's feedback on my earlier
> > 	   implementation.
> 
> The upgrade path from hv_blkvsc to hv_storvsc is difficult.
> 
> hv_storvsc does not provide the vmbus:hv_block modalias, so mkinitrd
> does not know what module to choose when mkinitrd is called in a
> previous kernel (like sles11sp1).
> 
> 
> In a guest with both SCSI and IDE controllers the IDE disks are
> discovered first, so the SCSI drives will also change their names.
> Thats not a problem for data partitions because they could be mounted by
> UUID or LABEL in fstab.
> But its difficult to adjust /boot/grub/device.map for example because
> the old  IDE drives do not provide an identifier. What is the best way
> to make sure the rename from hd* to sd* in such config files is done
> correctly? Is it safe to assume that all drives with a class_id of
> 32412632-86cb-44a2-9b5c50d1417354f5 are connected to IDE ports?

The class_id is invariant as we are returning the guid of the device under class_id.

So, if you see a IDE guid under class_id, you can be sure (a) it is an ide device and (b)
it is a device managed via the PV drivers.

> 
> localhost:~ # head /sys/bus/vmbus/devices/vmbus_0_{1,2,3,10,11}/class_id
> ==> /sys/bus/vmbus/devices/vmbus_0_1/class_id <==
> {32412632-86cb-44a2-9b5c50d1417354f5}
> 
> ==> /sys/bus/vmbus/devices/vmbus_0_2/class_id <==
> {32412632-86cb-44a2-9b5c50d1417354f5}
> 
> ==> /sys/bus/vmbus/devices/vmbus_0_3/class_id <==
> {32412632-86cb-44a2-9b5c50d1417354f5}
> 
> ==> /sys/bus/vmbus/devices/vmbus_0_10/class_id <==
> {ba6163d9-04a1-4d29-b60572e2ffb1dc7f}
> 
> ==> /sys/bus/vmbus/devices/vmbus_0_11/class_id <==
> {ba6163d9-04a1-4d29-b60572e2ffb1dc7f}
> 
> 
> In my test system, the IDE drives are now discovered twice, once by
> hv_storvsc and once by libata:

This is a known (old problem). The way this was handled earlier was to have the 
modprobe rules in place to setup a dependency that would force the load of the
hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV
driver succeeded, we would not load the native driver. In sles11 sp1, we had a rule for 
loading blkvsc. With the merge of blkvsc and storvsc, the only change we need to make
is to have storvsc in the rule (instaed of blkvsc).

Regards,

K. Y
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
  2011-08-30 14:07         ` Greg KH
@ 2011-08-30 17:25           ` KY Srinivasan
  0 siblings, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:25 UTC (permalink / raw)
  To: Greg KH, Dan Carpenter
  Cc: devel, Haiyang Zhang, gregkh, linux-kernel, virtualization



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Tuesday, August 30, 2011 10:07 AM
> To: Dan Carpenter
> Cc: KY Srinivasan; devel@linuxdriverproject.org; Haiyang Zhang; gregkh@suse.de;
> linux-kernel@vger.kernel.org; virtualization@lists.osdl.org
> Subject: Re: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in
> vmbus_bus_init()
> 
> On Tue, Aug 30, 2011 at 01:29:49PM +0300, Dan Carpenter wrote:
> > > err3:
> > > 	free_irq(irq, hv_acpi_dev);
> > > err2:
> > > 	bus_unregister(&hv_bus);
> > > err1:
> > > 	hv_cleanup();
> >
> > Also here is an oldbie trick.  You could use multiples of ten like
> > err30, err20, and err10.  That way if you can add more error handling
> > in the middle without changing the numbering.  I knew my GW-BASIC
> > experience would come in handy one day.  :)
> >
> > The better way to label things is based on what happens when you get
> > there: err_irq, err_unregister, err_cleanup.
> 
> Yes, that's the best way to do this, thanks for pointing it out.

I will fix this up.

Regards,

K. Y
> 
> greg k-h


^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-29 18:15 ` [PATCH 0000/0046] Staging: hv: Driver cleanup Greg KH
@ 2011-08-30 17:27   ` KY Srinivasan
  0 siblings, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-30 17:27 UTC (permalink / raw)
  To: Greg KH; +Cc: gregkh, linux-kernel, devel, virtualization



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Monday, August 29, 2011 2:15 PM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org
> Subject: Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
> 
> On Sat, Aug 27, 2011 at 11:31:14AM -0700, K. Y. Srinivasan wrote:
> > Further cleanup of the hv drivers.
> >
> > 	1) Cleanup reference counting.
> >
> > 	2) Handle all block devices using the storvsc driver. I have modified
> > 	   the implementation here based on Christoph's feedback on my earlier
> > 	   implementation.
> >
> > 	3) Fix bugs.
> >
> > 	4) Accomodate some host side scsi emulation bugs.
> >
> > 	5) In case of scsi errors off-line the device.
> >
> > This patch-set further reduces the size of Hyper-V drivers - the code is
> > about 10% smaller. This reduction is mainly because we have eliminated the
> > blkvsc driver.
> 
> If my tracking is correct, I applied everything in this series except
> the following patches
> 	[PATCH 37/46] Staging: hv: vmbus: Check for events before messages
> 	[PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in
> vmbus_bus_init()
> 	[PATCH 46/46] Staging: hv: Update the TODO file
> 
> Please fix up patches 37 and 41 and resend, and for 46, that should be
> totally different as mentioned, but you might want to send a patch that
> at the least adds your name to the file at the bottom, as you wanted.
> Also note that the MAINTAINERS file should also be adjusted to match.

Thanks Greg. I will try to get these patches back to you as soon as possible.

Regards,

K. Y


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 37/46] Staging: hv: vmbus: Check for events before messages
  2011-08-30 17:06       ` KY Srinivasan
@ 2011-08-30 17:38         ` Greg KH
  2011-08-31 14:22           ` KY Srinivasan
  0 siblings, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-30 17:38 UTC (permalink / raw)
  To: KY Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Tue, Aug 30, 2011 at 05:06:39PM +0000, KY Srinivasan wrote:
> > On Sat, Aug 27, 2011 at 11:31:36AM -0700, K. Y. Srinivasan wrote:
> > > Conform to Windows specification by checking for events before messages.
> > 
> > What specification?
> > 
> > Care to provide a comment in the code that you are doing this in this
> > explicit order because of some rule that the hypervisor imposes on us?
> 
> I am not sure if this is documented anywhere (publicly). In talking to Windows 
> guys, they suggested this is the order in which it is done on Windows guests and suggested
> I should do the same. I will see if there is some public documentation that specifies this.

All you need to do is just document it in the code and I'll be happy.
We don't rely on external documentation for things to be changed, in
fact, there usually isn't any such thing :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
  2011-08-30 17:11       ` KY Srinivasan
@ 2011-08-30 17:41         ` Greg KH
  2011-08-31 14:21           ` KY Srinivasan
  0 siblings, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-30 17:41 UTC (permalink / raw)
  To: KY Srinivasan; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang

On Tue, Aug 30, 2011 at 05:11:57PM +0000, KY Srinivasan wrote:
> Thanks Greg. I will fix this. I got these patches out just before Hurricane Irene
> hit the east coast. While we were lucky that it was not as bad as was predicted,
> we lost power and we still don't have power. I have come to a public library in
> a nearby town to check my email.  So, my responses will be sporadic over the 
> next couple of days (until we get power). I will try to address the issues you
> have raised as quickly as possible.

Ouch, good luck with the power and other cleanup, hopefully you didn't
have any water damage.

I'm in no rush for further patches, that's being driven by your end :)

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-30 17:22   ` KY Srinivasan
@ 2011-08-30 17:43     ` Greg KH
  2011-08-30 18:04       ` Olaf Hering
  2011-08-31 14:18       ` KY Srinivasan
  0 siblings, 2 replies; 77+ messages in thread
From: Greg KH @ 2011-08-30 17:43 UTC (permalink / raw)
  To: KY Srinivasan; +Cc: Olaf Hering, devel, gregkh, linux-kernel, virtualization

On Tue, Aug 30, 2011 at 05:22:54PM +0000, KY Srinivasan wrote:
> 
> 
> > -----Original Message-----
> > From: Olaf Hering [mailto:olaf@aepfle.de]
> > Sent: Tuesday, August 30, 2011 8:49 AM
> > To: KY Srinivasan
> > Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> > devel@linuxdriverproject.org; virtualization@lists.osdl.org
> > Subject: Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
> > 
> > On Sat, Aug 27, K. Y. Srinivasan wrote:
> > 
> > > 	2) Handle all block devices using the storvsc driver. I have modified
> > > 	   the implementation here based on Christoph's feedback on my earlier
> > > 	   implementation.
> > 
> > The upgrade path from hv_blkvsc to hv_storvsc is difficult.
> > 
> > hv_storvsc does not provide the vmbus:hv_block modalias, so mkinitrd
> > does not know what module to choose when mkinitrd is called in a
> > previous kernel (like sles11sp1).
> > 
> > 
> > In a guest with both SCSI and IDE controllers the IDE disks are
> > discovered first, so the SCSI drives will also change their names.
> > Thats not a problem for data partitions because they could be mounted by
> > UUID or LABEL in fstab.
> > But its difficult to adjust /boot/grub/device.map for example because
> > the old  IDE drives do not provide an identifier. What is the best way
> > to make sure the rename from hd* to sd* in such config files is done
> > correctly? Is it safe to assume that all drives with a class_id of
> > 32412632-86cb-44a2-9b5c50d1417354f5 are connected to IDE ports?
> 
> The class_id is invariant as we are returning the guid of the device under class_id.
> 
> So, if you see a IDE guid under class_id, you can be sure (a) it is an ide device and (b)
> it is a device managed via the PV drivers.
> 
> > 
> > localhost:~ # head /sys/bus/vmbus/devices/vmbus_0_{1,2,3,10,11}/class_id
> > ==> /sys/bus/vmbus/devices/vmbus_0_1/class_id <==
> > {32412632-86cb-44a2-9b5c50d1417354f5}
> > 
> > ==> /sys/bus/vmbus/devices/vmbus_0_2/class_id <==
> > {32412632-86cb-44a2-9b5c50d1417354f5}
> > 
> > ==> /sys/bus/vmbus/devices/vmbus_0_3/class_id <==
> > {32412632-86cb-44a2-9b5c50d1417354f5}
> > 
> > ==> /sys/bus/vmbus/devices/vmbus_0_10/class_id <==
> > {ba6163d9-04a1-4d29-b60572e2ffb1dc7f}
> > 
> > ==> /sys/bus/vmbus/devices/vmbus_0_11/class_id <==
> > {ba6163d9-04a1-4d29-b60572e2ffb1dc7f}
> > 
> > 
> > In my test system, the IDE drives are now discovered twice, once by
> > hv_storvsc and once by libata:
> 
> This is a known (old problem). The way this was handled earlier was to have the 
> modprobe rules in place to setup a dependency that would force the load of the
> hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV
> driver succeeded, we would not load the native driver. In sles11 sp1, we had a rule for 
> loading blkvsc. With the merge of blkvsc and storvsc, the only change we need to make
> is to have storvsc in the rule (instaed of blkvsc).

Why do we need a rule at all?  Shouldn't the module dependancy stuff
handle the autoloading of the drivers properly from the initrd now that
the hotplug logic is hooked up properly?

What am I missing here?

Or is the hotplug code not working correctly?

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-30 17:43     ` Greg KH
@ 2011-08-30 18:04       ` Olaf Hering
  2011-08-30 18:19         ` Greg KH
  2011-08-31 14:27         ` [PATCH 0000/0046] Staging: hv: Driver cleanup KY Srinivasan
  2011-08-31 14:18       ` KY Srinivasan
  1 sibling, 2 replies; 77+ messages in thread
From: Olaf Hering @ 2011-08-30 18:04 UTC (permalink / raw)
  To: Greg KH; +Cc: KY Srinivasan, devel, gregkh, linux-kernel, virtualization

On Tue, Aug 30, Greg KH wrote:

> > > In my test system, the IDE drives are now discovered twice, once by
> > > hv_storvsc and once by libata:
> > 
> > This is a known (old problem). The way this was handled earlier was to have the 
> > modprobe rules in place to setup a dependency that would force the load of the
> > hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV
> > driver succeeded, we would not load the native driver. In sles11 sp1, we had a rule for 
> > loading blkvsc. With the merge of blkvsc and storvsc, the only change we need to make
> > is to have storvsc in the rule (instaed of blkvsc).
> 
> Why do we need a rule at all?  Shouldn't the module dependancy stuff
> handle the autoloading of the drivers properly from the initrd now that
> the hotplug logic is hooked up properly?

There is no plan to load hv_vmbus (or xen-platform-pci) earlier than
native drivers.  That was the purpose of the modprobe.conf files. Now
that there is a vmbus, that fact could be checked before any other
attempt to load drivers is made and hv_vmbus should be loaded and all of
its devices have to be probed manually by modprobe `cat modulealias`.

> Or is the hotplug code not working correctly?

There is nothing to hotplug. hv_vmbus has to be loaded first so that it
can take over the devices. But it seems that there is no shutdown of the
emulated hardware, thats why the disk "sda" is shown twice.

I spot a flaw here.
KY, can hv_vmbus shutdown emulated hardware? At least the disks, because
cdroms are appearently still be handled by native drivers?

Olaf

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-30 18:04       ` Olaf Hering
@ 2011-08-30 18:19         ` Greg KH
  2011-08-31  9:11           ` Olaf Hering
  2011-08-31 14:27         ` [PATCH 0000/0046] Staging: hv: Driver cleanup KY Srinivasan
  1 sibling, 1 reply; 77+ messages in thread
From: Greg KH @ 2011-08-30 18:19 UTC (permalink / raw)
  To: Olaf Hering; +Cc: KY Srinivasan, devel, gregkh, linux-kernel, virtualization

On Tue, Aug 30, 2011 at 08:04:34PM +0200, Olaf Hering wrote:
> On Tue, Aug 30, Greg KH wrote:
> 
> > > > In my test system, the IDE drives are now discovered twice, once by
> > > > hv_storvsc and once by libata:
> > > 
> > > This is a known (old problem). The way this was handled earlier was to have the 
> > > modprobe rules in place to setup a dependency that would force the load of the
> > > hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV
> > > driver succeeded, we would not load the native driver. In sles11 sp1, we had a rule for 
> > > loading blkvsc. With the merge of blkvsc and storvsc, the only change we need to make
> > > is to have storvsc in the rule (instaed of blkvsc).
> > 
> > Why do we need a rule at all?  Shouldn't the module dependancy stuff
> > handle the autoloading of the drivers properly from the initrd now that
> > the hotplug logic is hooked up properly?
> 
> There is no plan to load hv_vmbus (or xen-platform-pci) earlier than
> native drivers.

Wait, what do you mean by "native drivers"?

Isn't the hv_vmbus drivers the "native drivers" happening here?

Or are you referring to the "emulated-slow-as-hell drivers" that are
used to boot the machine?

> That was the purpose of the modprobe.conf files. Now
> that there is a vmbus, that fact could be checked before any other
> attempt to load drivers is made and hv_vmbus should be loaded and all of
> its devices have to be probed manually by modprobe `cat modulealias`.

I agree with the first part, but no modprobe should ever need to be
done, the hotplug boot process should properly load those modules when
the vmbus devices are seen by the vmbus core and the hotplug events
generated, which in turn calls modprobe, right?

So there should not need to be any special module.conf file changes for
hv systems, with the exception that the "emulated" drivers should be
added to the blacklist.

> > Or is the hotplug code not working correctly?
> 
> There is nothing to hotplug. hv_vmbus has to be loaded first so that it
> can take over the devices. But it seems that there is no shutdown of the
> emulated hardware, thats why the disk "sda" is shown twice.
> 
> I spot a flaw here.

I agree :)

> KY, can hv_vmbus shutdown emulated hardware? At least the disks, because
> cdroms are appearently still be handled by native drivers?

They are?  Ick, why can't the vmbus storage driver see a cdrom device?
It's just a scsi device, right?

thanks

greg k-h

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-30 18:19         ` Greg KH
@ 2011-08-31  9:11           ` Olaf Hering
  2011-09-01 15:43             ` [PATCH RFC] ata_piix: ignore disks in a hyper-v guest Olaf Hering
  0 siblings, 1 reply; 77+ messages in thread
From: Olaf Hering @ 2011-08-31  9:11 UTC (permalink / raw)
  To: Greg KH; +Cc: KY Srinivasan, devel, gregkh, linux-kernel, virtualization

On Tue, Aug 30, Greg KH wrote:

> On Tue, Aug 30, 2011 at 08:04:34PM +0200, Olaf Hering wrote:
> > On Tue, Aug 30, Greg KH wrote:
> > 
> > > > > In my test system, the IDE drives are now discovered twice, once by
> > > > > hv_storvsc and once by libata:
> > > > 
> > > > This is a known (old problem). The way this was handled earlier was to have the 
> > > > modprobe rules in place to setup a dependency that would force the load of the
> > > > hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV
> > > > driver succeeded, we would not load the native driver. In sles11 sp1, we had a rule for 
> > > > loading blkvsc. With the merge of blkvsc and storvsc, the only change we need to make
> > > > is to have storvsc in the rule (instaed of blkvsc).
> > > 
> > > Why do we need a rule at all?  Shouldn't the module dependancy stuff
> > > handle the autoloading of the drivers properly from the initrd now that
> > > the hotplug logic is hooked up properly?
> > 
> > There is no plan to load hv_vmbus (or xen-platform-pci) earlier than
> > native drivers.
> 
> Wait, what do you mean by "native drivers"?

native means drivers for emulated hardware: ata_piix, piix.

> Isn't the hv_vmbus drivers the "native drivers" happening here?
> Or are you referring to the "emulated-slow-as-hell drivers" that are
> used to boot the machine?

Not really. The virtual IDE controllers are emulated hardware, while the
virtual SCSI controllers are paravirtualized hardware. KY, correct my if
I'm wrong here.

> > That was the purpose of the modprobe.conf files. Now
> > that there is a vmbus, that fact could be checked before any other
> > attempt to load drivers is made and hv_vmbus should be loaded and all of
> > its devices have to be probed manually by modprobe `cat modulealias`.
> 
> I agree with the first part, but no modprobe should ever need to be
> done, the hotplug boot process should properly load those modules when
> the vmbus devices are seen by the vmbus core and the hotplug events
> generated, which in turn calls modprobe, right?

With the IDE disks, the module loading order matters because both
ata_piix/piix and hv_storvsc will bind to them. 
With the SCSI disks, only hv_storvsc will bind to them.
 
> So there should not need to be any special module.conf file changes for
> hv systems, with the exception that the "emulated" drivers should be
> added to the blacklist.

I agree, the modprobe.conf rules for hv should be removed. With this
patchset a rule to prevent ata_piix loading would hide all cdrom devices.

> > KY, can hv_vmbus shutdown emulated hardware? At least the disks, because
> > cdroms are appearently still be handled by native drivers?
> 
> They are?  Ick, why can't the vmbus storage driver see a cdrom device?
> It's just a scsi device, right?

The GUI does not seem to offer a way to attach an iso to a virtual SCSI
controller. It looks like one can add up to 4 SCSI controllers, each one
can have up to 64 disk images.
DVD devices can only be attached to the 2 virtual IDE controllers, one
can either attach iso images or physical hardware.


After some more testing it looks like the hv_blkvsc driver claimed the
ide major #3, so the ide_core could not bind to the emulated IDE
hardware. The modprobe.conf rules prevented that ata_piix gets loaded.
If I force a module load order of 'ata_piix ;hv_blkvsc' both ata_piix
and hv_blkvsc will bind to the same drive, just as shown in my previous
mail. So there is appearently no way to shutdown the IDE ports like it
is done with xen_emul_unplug= option for Xen guests.

Maybe some hack is needed for a hyper-v specific unplug if Windows does
indeed lack that feature. Now that ata_piix is compiled into the kernel,
there is nothing to a modprobe.conf rule can "fix".


Olaf

^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-30 17:43     ` Greg KH
  2011-08-30 18:04       ` Olaf Hering
@ 2011-08-31 14:18       ` KY Srinivasan
  1 sibling, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-31 14:18 UTC (permalink / raw)
  To: Greg KH; +Cc: Olaf Hering, devel, gregkh, linux-kernel, virtualization



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Tuesday, August 30, 2011 1:44 PM
> To: KY Srinivasan
> Cc: Olaf Hering; devel@linuxdriverproject.org; gregkh@suse.de; linux-
> kernel@vger.kernel.org; virtualization@lists.osdl.org
> Subject: Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
> 
> On Tue, Aug 30, 2011 at 05:22:54PM +0000, KY Srinivasan wrote:
> >
> >
> > > -----Original Message-----
> > > From: Olaf Hering [mailto:olaf@aepfle.de]
> > > Sent: Tuesday, August 30, 2011 8:49 AM
> > > To: KY Srinivasan
> > > Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> > > devel@linuxdriverproject.org; virtualization@lists.osdl.org
> > > Subject: Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
> > >
> > > On Sat, Aug 27, K. Y. Srinivasan wrote:
> > >
> > > > 	2) Handle all block devices using the storvsc driver. I have modified
> > > > 	   the implementation here based on Christoph's feedback on my earlier
> > > > 	   implementation.
> > >
> > > The upgrade path from hv_blkvsc to hv_storvsc is difficult.
> > >
> > > hv_storvsc does not provide the vmbus:hv_block modalias, so mkinitrd
> > > does not know what module to choose when mkinitrd is called in a
> > > previous kernel (like sles11sp1).
> > >
> > >
> > > In a guest with both SCSI and IDE controllers the IDE disks are
> > > discovered first, so the SCSI drives will also change their names.
> > > Thats not a problem for data partitions because they could be mounted by
> > > UUID or LABEL in fstab.
> > > But its difficult to adjust /boot/grub/device.map for example because
> > > the old  IDE drives do not provide an identifier. What is the best way
> > > to make sure the rename from hd* to sd* in such config files is done
> > > correctly? Is it safe to assume that all drives with a class_id of
> > > 32412632-86cb-44a2-9b5c50d1417354f5 are connected to IDE ports?
> >
> > The class_id is invariant as we are returning the guid of the device under
> class_id.
> >
> > So, if you see a IDE guid under class_id, you can be sure (a) it is an ide device
> and (b)
> > it is a device managed via the PV drivers.
> >
> > >
> > > localhost:~ # head /sys/bus/vmbus/devices/vmbus_0_{1,2,3,10,11}/class_id
> > > ==> /sys/bus/vmbus/devices/vmbus_0_1/class_id <==
> > > {32412632-86cb-44a2-9b5c50d1417354f5}
> > >
> > > ==> /sys/bus/vmbus/devices/vmbus_0_2/class_id <==
> > > {32412632-86cb-44a2-9b5c50d1417354f5}
> > >
> > > ==> /sys/bus/vmbus/devices/vmbus_0_3/class_id <==
> > > {32412632-86cb-44a2-9b5c50d1417354f5}
> > >
> > > ==> /sys/bus/vmbus/devices/vmbus_0_10/class_id <==
> > > {ba6163d9-04a1-4d29-b60572e2ffb1dc7f}
> > >
> > > ==> /sys/bus/vmbus/devices/vmbus_0_11/class_id <==
> > > {ba6163d9-04a1-4d29-b60572e2ffb1dc7f}
> > >
> > >
> > > In my test system, the IDE drives are now discovered twice, once by
> > > hv_storvsc and once by libata:
> >
> > This is a known (old problem). The way this was handled earlier was to have the
> > modprobe rules in place to setup a dependency that would force the load of
> the
> > hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV
> > driver succeeded, we would not load the native driver. In sles11 sp1, we had a
> rule for
> > loading blkvsc. With the merge of blkvsc and storvsc, the only change we need
> to make
> > is to have storvsc in the rule (instaed of blkvsc).
> 
> Why do we need a rule at all?  Shouldn't the module dependancy stuff
> handle the autoloading of the drivers properly from the initrd now that
> the hotplug logic is hooked up properly?
> 
> What am I missing here?

On sles11 the PV drivers are used to manage the root device. Autoloading is not
the issue here; to manage the root device, we want to load the Hyper-V disk driver
before the native Linux disk driver for the emulated IDE device.

> 
> Or is the hotplug code not working correctly?

Hotplug code is working as expected; the issue is taking control of the root device and
preventing the same device being presented once through native drivers and once through
Hyper-V drivers.

Regards,

K. Y 
> 
> greg k-h


^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
  2011-08-30 17:41         ` Greg KH
@ 2011-08-31 14:21           ` KY Srinivasan
  0 siblings, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-31 14:21 UTC (permalink / raw)
  To: Greg KH; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Tuesday, August 30, 2011 1:42 PM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; Haiyang Zhang
> Subject: Re: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in
> connection.c
> 
> On Tue, Aug 30, 2011 at 05:11:57PM +0000, KY Srinivasan wrote:
> > Thanks Greg. I will fix this. I got these patches out just before Hurricane Irene
> > hit the east coast. While we were lucky that it was not as bad as was predicted,
> > we lost power and we still don't have power. I have come to a public library in
> > a nearby town to check my email.  So, my responses will be sporadic over the
> > next couple of days (until we get power). I will try to address the issues you
> > have raised as quickly as possible.
> 
> Ouch, good luck with the power and other cleanup, hopefully you didn't
> have any water damage.
> 
> I'm in no rush for further patches, that's being driven by your end :)

Power was restored early this morning. Fortunately, except for lack power and
a few  broken branches, we did not really feel the brunt of this hurricane. I am starting
work on addressing the issues you and others have raised.

Regards,

K. Y

^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 37/46] Staging: hv: vmbus: Check for events before messages
  2011-08-30 17:38         ` Greg KH
@ 2011-08-31 14:22           ` KY Srinivasan
  0 siblings, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-31 14:22 UTC (permalink / raw)
  To: Greg KH; +Cc: gregkh, linux-kernel, devel, virtualization, Haiyang Zhang



> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Tuesday, August 30, 2011 1:38 PM
> To: KY Srinivasan
> Cc: gregkh@suse.de; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; virtualization@lists.osdl.org; Haiyang Zhang
> Subject: Re: [PATCH 37/46] Staging: hv: vmbus: Check for events before
> messages
> 
> On Tue, Aug 30, 2011 at 05:06:39PM +0000, KY Srinivasan wrote:
> > > On Sat, Aug 27, 2011 at 11:31:36AM -0700, K. Y. Srinivasan wrote:
> > > > Conform to Windows specification by checking for events before messages.
> > >
> > > What specification?
> > >
> > > Care to provide a comment in the code that you are doing this in this
> > > explicit order because of some rule that the hypervisor imposes on us?
> >
> > I am not sure if this is documented anywhere (publicly). In talking to Windows
> > guys, they suggested this is the order in which it is done on Windows guests
> and suggested
> > I should do the same. I will see if there is some public documentation that
> specifies this.
> 
> All you need to do is just document it in the code and I'll be happy.
> We don't rely on external documentation for things to be changed, in
> fact, there usually isn't any such thing :)

Ok; will do.

Regards,

K. Y


^ permalink raw reply	[flat|nested] 77+ messages in thread

* RE: [PATCH 0000/0046] Staging: hv: Driver cleanup
  2011-08-30 18:04       ` Olaf Hering
  2011-08-30 18:19         ` Greg KH
@ 2011-08-31 14:27         ` KY Srinivasan
  1 sibling, 0 replies; 77+ messages in thread
From: KY Srinivasan @ 2011-08-31 14:27 UTC (permalink / raw)
  To: Olaf Hering, Greg KH; +Cc: devel, gregkh, linux-kernel, virtualization

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2443 bytes --]



> -----Original Message-----
> From: Olaf Hering [mailto:olaf@aepfle.de]
> Sent: Tuesday, August 30, 2011 2:05 PM
> To: Greg KH
> Cc: KY Srinivasan; devel@linuxdriverproject.org; gregkh@suse.de; linux-
> kernel@vger.kernel.org; virtualization@lists.osdl.org
> Subject: Re: [PATCH 0000/0046] Staging: hv: Driver cleanup
> 
> On Tue, Aug 30, Greg KH wrote:
> 
> > > > In my test system, the IDE drives are now discovered twice, once by
> > > > hv_storvsc and once by libata:
> > >
> > > This is a known (old problem). The way this was handled earlier was to have
> the
> > > modprobe rules in place to setup a dependency that would force the load of
> the
> > > hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV
> > > driver succeeded, we would not load the native driver. In sles11 sp1, we had a
> rule for
> > > loading blkvsc. With the merge of blkvsc and storvsc, the only change we
> need to make
> > > is to have storvsc in the rule (instaed of blkvsc).
> >
> > Why do we need a rule at all?  Shouldn't the module dependancy stuff
> > handle the autoloading of the drivers properly from the initrd now that
> > the hotplug logic is hooked up properly?
> 
> There is no plan to load hv_vmbus (or xen-platform-pci) earlier than
> native drivers.  That was the purpose of the modprobe.conf files. Now
> that there is a vmbus, that fact could be checked before any other
> attempt to load drivers is made and hv_vmbus should be loaded and all of
> its devices have to be probed manually by modprobe `cat modulealias`.

The strategy I was describing was what was used in sles11 sp1.

> 
> > Or is the hotplug code not working correctly?
> 
> There is nothing to hotplug. hv_vmbus has to be loaded first so that it
> can take over the devices. But it seems that there is no shutdown of the
> emulated hardware, thats why the disk "sda" is shown twice.
> 
> I spot a flaw here.
> KY, can hv_vmbus shutdown emulated hardware? At least the disks, because
> cdroms are appearently still be handled by native drivers?

Olaf, unfortunately the vmbus driver does not stop the emulation of the disk devices.
The earlier modprobe rule was also instrumental in preventing the loading of the
native drivers if the hyperv- driver load succeeded.

Regards,

K. Y 

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH RFC] ata_piix: ignore disks in a hyper-v guest
  2011-08-31  9:11           ` Olaf Hering
@ 2011-09-01 15:43             ` Olaf Hering
  0 siblings, 0 replies; 77+ messages in thread
From: Olaf Hering @ 2011-09-01 15:43 UTC (permalink / raw)
  To: linux-ide; +Cc: KY Srinivasan, devel, gregkh, linux-kernel, virtualization

On Wed, Aug 31, Olaf Hering wrote:

> After some more testing it looks like the hv_blkvsc driver claimed the
> ide major #3, so the ide_core could not bind to the emulated IDE
> hardware. The modprobe.conf rules prevented that ata_piix gets loaded.
> If I force a module load order of 'ata_piix ;hv_blkvsc' both ata_piix
> and hv_blkvsc will bind to the same drive, just as shown in my previous
> mail. So there is appearently no way to shutdown the IDE ports like it
> is done with xen_emul_unplug= option for Xen guests.
> 
> Maybe some hack is needed for a hyper-v specific unplug if Windows does
> indeed lack that feature. Now that ata_piix is compiled into the kernel,
> there is nothing to a modprobe.conf rule can "fix".

Here is an attempt to ignore disks in a hyper-v disks, and let ata_piix
handle only the configured cdrom devices (iso of physical).
If the disks are not ignored, they will appear twice, once through
ata_piix and once through hv_storvsc.

Once hv_storvsc can also handle the configured cdrom devices, the added
piix_pata_read_id() function can be removed again. Only the check in
piix_init() or something similar needs to be done.

Maybe there is a better way enable only ATA_DEV_ATAPI?


Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 drivers/ata/ata_piix.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -98,6 +98,10 @@
 #define DRV_NAME	"ata_piix"
 #define DRV_VERSION	"2.13"
 
+#if defined(CONFIG_HYPERV_STORAGE) || defined(CONFIG_HYPERV_STORAGE_MODULE)
+#define PIIX_IGNORE_ATA_ON_HYPERV 1
+#endif
+
 enum {
 	PIIX_IOCFG		= 0x54, /* IDE I/O configuration register */
 	ICH5_PMR		= 0x90, /* port mapping register */
@@ -164,6 +168,7 @@ struct piix_host_priv {
 static int piix_init_one(struct pci_dev *pdev,
 			 const struct pci_device_id *ent);
 static void piix_remove_one(struct pci_dev *pdev);
+static unsigned int piix_pata_read_id(struct ata_device *adev, struct ata_taskfile *tf, u16 *id);
 static int piix_pata_prereset(struct ata_link *link, unsigned long deadline);
 static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev);
 static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
@@ -346,6 +351,7 @@ static struct ata_port_operations piix_p
 	.set_piomode		= piix_set_piomode,
 	.set_dmamode		= piix_set_dmamode,
 	.prereset		= piix_pata_prereset,
+	.read_id		= piix_pata_read_id,
 };
 
 static struct ata_port_operations piix_vmw_ops = {
@@ -619,6 +625,24 @@ MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
+#if defined(PIIX_IGNORE_ATA_ON_HYPERV)
+static int piix_msft_hyperv(void)
+{
+	static const struct dmi_system_id hv_dmi_ident[]  = {
+		{
+			.ident = "Hyper-V",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
+				DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
+			},
+		},
+		{ }	/* terminate list */
+	};
+	return !!dmi_check_system(hv_dmi_ident);
+}
+#endif
+
 struct ich_laptop {
 	u16 device;
 	u16 subvendor;
@@ -702,6 +726,29 @@ static int piix_pata_prereset(struct ata
 	return ata_sff_prereset(link, deadline);
 }
 
+/**
+ *
+ */
+static unsigned int piix_pata_read_id(struct ata_device *adev, struct ata_taskfile *tf, u16 *id)
+{
+	unsigned int err_mask = ata_do_dev_read_id(adev, tf, id);
+#if defined(PIIX_IGNORE_ATA_ON_HYPERV)
+	/*
+	 * Ignore disks in a hyper-v guest.
+	 * There is no unplug protocol like it is done with xen_emul_unplug= option.
+	 * Emulate the unplug by ignoring disks when the hv_storvsc driver is enabled.
+	 * If the disks are not ignored, they will appear twice: once through piix and once through hv_storvsc.
+	 * Because hv_storvsc does not handle ATAPI devices, the piix driver is still required.
+	 * Once hv_storvsc handles all devices, this function can be removed and the whole driver should be disabled in a hyper-v guest.
+	 */
+	if (ata_id_is_ata(id) && piix_msft_hyperv()) {
+		ata_dev_printk(adev, KERN_WARNING, "ATA device ignored in Hyper-V guest\n");
+		id[ATA_ID_CONFIG] |= (1 << 15);
+	}
+#endif
+	return err_mask;
+}
+
 static DEFINE_SPINLOCK(piix_lock);
 
 /**
@@ -1679,6 +1726,13 @@ static int __init piix_init(void)
 {
 	int rc;
 
+#if defined(PIIX_IGNORE_ATA_ON_HYPERV)
+	/* disabled until hv_storvsc drives also cdrom devices */
+	if (0 && piix_msft_hyperv()) {
+		printk(KERN_DEBUG "%s: hv_storvsc will bind to storage\n", __func__);
+		return -ENODEV;
+	}
+#endif
 	DPRINTK("pci_register_driver\n");
 	rc = pci_register_driver(&piix_pci_driver);
 	if (rc)

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2011-09-01 15:43 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-27 18:31 [PATCH 0000/0046] Staging: hv: Driver cleanup K. Y. Srinivasan
2011-08-27 18:31 ` [PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 02/46] Staging: hv: storvsc: Do not aquire an unnecessary reference on stor_device K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 03/46] Staging: hv: storvsc: Rename must_get_stor_device() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 04/46] Staging: hv: storvsc: Rename get_stor_device() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 05/46] Staging: hv: storvsc: Cleanup alloc_stor_device() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 06/46] Staging: hv: storvsc: Introduce state to manage the lifecycle of stor device K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 07/46] Staging: hv: storvsc: Prevent outgoing traffic when stor dev is being destroyed K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 08/46] Staging: hv: storvsc: Get rid of release_stor_device() by inlining the code K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 09/46] Staging: hv: storvsc: Get rid of final_release_stor_device() by inlining code K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 10/46] Staging: hv: storvsc: Get rid of the reference counting in struct storvsc_device K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 11/46] Staging: hv: netvsc: Inline the code for free_net_device() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 12/46] Staging: hv: netvsc: Cleanup alloc_net_device() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 13/46] Staging: hv: netvsc: Introduce state to manage the lifecycle of net device K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 14/46] Staging: hv: netvsc: Prevent outgoing traffic when netvsc dev is destroyed K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 15/46] Staging: hv: netvsc: Get rid of release_outbound_net_device() by inlining the code K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 16/46] Staging: hv: netvsc: Get rid of release_inbound_net_device() " K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 17/46] Staging: hv: netvsc: Get rid of the refcnt field in struct netvsc_device K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver K. Y. Srinivasan
2011-08-30 11:07     ` Dan Carpenter
2011-08-27 18:31   ` [PATCH 19/46] Staging: hv: storvsc: Handle " K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 20/46] Staging: hv: blkvsc: Get rid of blkvsc_drv.c as this code is not used K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 21/46] Staging: hv: storvsc: Optimize bounce buffer handling for the "write" case K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 22/46] Staging: hv: storvsc: Optimize the bounce buffer handling in the "read" case K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 23/46] Staging: hv: storvsc: Include storvsc.c in storvsc_drv.c K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 24/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of storvsc.c K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 25/46] Staging: hv: storvsc: Add the contents of hyperv_storage.h to storvsc_drv.c K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 26/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 27/46] Staging: hv: storvsc: Fixup srb and scsi status for INQUIRY and MODE_SENSE K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 28/46] Staging: hv: storvsc: Fix a typo K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 29/46] Staging: hv: storvsc: In case of scsi errors offline the device K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 30/46] Staging: hv: storvsc: No need to copy from bounce buffer in case of a failure K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 31/46] Staging: hv: util: Forcefully shutdown when shutdown is requested K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 32/46] Staging: hv: util: Adjust guest time in a process context K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 33/46] Staging: hv: vmbus: Check before invoking the channel callback K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 34/46] Staging: hv: vmbus: Properly deal with de-registering " K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 35/46] Staging: hv: Fix a bug in vmbus_match() K. Y. Srinivasan
2011-08-29 18:00     ` Greg KH
2011-08-27 18:31   ` [PATCH 36/46] Staging: hv: vmbus: Get rid of vmbus_on_isr() by inlining the code K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 37/46] Staging: hv: vmbus: Check for events before messages K. Y. Srinivasan
2011-08-29 18:05     ` Greg KH
2011-08-30 17:06       ` KY Srinivasan
2011-08-30 17:38         ` Greg KH
2011-08-31 14:22           ` KY Srinivasan
2011-08-27 18:31   ` [PATCH 38/46] Staging: hv: vmbus: Do not enable auto eoi K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 39/46] Staging: hv: vmbus: Fixup indentation in vmbus_acpi_add() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 40/46] Staging: hv: vmbus: Get rid of some dated/redundant comments K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init() K. Y. Srinivasan
2011-08-29 18:08     ` Greg KH
2011-08-30 10:29       ` Dan Carpenter
2011-08-30 14:07         ` Greg KH
2011-08-30 17:25           ` KY Srinivasan
2011-08-30 17:07       ` KY Srinivasan
2011-08-27 18:31   ` [PATCH 42/46] Staging: hv: vmbus: Get rid of an unnecessary check in vmbus_connect() K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 43/46] Staging: hv: vmbus: Fix a checkpatch warning in ring_buffer.c K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c K. Y. Srinivasan
2011-08-28  6:56     ` Joe Perches
2011-08-30 17:03       ` KY Srinivasan
2011-08-29 18:09     ` Greg KH
2011-08-30 17:11       ` KY Srinivasan
2011-08-30 17:41         ` Greg KH
2011-08-31 14:21           ` KY Srinivasan
2011-08-27 18:31   ` [PATCH 45/46] Staging: hv: mousevsc: Fix checkpatch errors and warnings K. Y. Srinivasan
2011-08-27 18:31   ` [PATCH 46/46] Staging: hv: Update the TODO file K. Y. Srinivasan
2011-08-29 18:12     ` Greg KH
2011-08-30 17:13       ` KY Srinivasan
2011-08-29 18:15 ` [PATCH 0000/0046] Staging: hv: Driver cleanup Greg KH
2011-08-30 17:27   ` KY Srinivasan
2011-08-30 12:48 ` Olaf Hering
2011-08-30 17:22   ` KY Srinivasan
2011-08-30 17:43     ` Greg KH
2011-08-30 18:04       ` Olaf Hering
2011-08-30 18:19         ` Greg KH
2011-08-31  9:11           ` Olaf Hering
2011-09-01 15:43             ` [PATCH RFC] ata_piix: ignore disks in a hyper-v guest Olaf Hering
2011-08-31 14:27         ` [PATCH 0000/0046] Staging: hv: Driver cleanup KY Srinivasan
2011-08-31 14:18       ` KY Srinivasan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).