K. Y. Srinivasan
2011-Apr-26 16:19 UTC
[PATCH 00/25] Staging: hv: Cleanup vmbus driver code
This patch-set addresses some of the bus/driver model cleanup that Greg sugested over the last couple of days. In this patch-set we deal with the following issues: 1) Cleanup unnecessary state in struct hv_device and struct hv_driver to be compliant with the Linux Driver model. 2) Cleanup the vmbus_match() function to conform with the Linux Driver model. 3) Cleanup error handling in the vmbus_probe() and vmbus_child_device_register() functions. Fixed a bug in the probe failure path as part of this cleanup. 4) The Windows host cannot handle the vmbus_driver being unloaded and subsequently loaded. Cleanup the driver with this in mind. 5) Get rid of struct hv_bus that embedded struct bus_type to conform with the LDM. 6) Add probe/remove/shutdown functions to struct hv_driver to conform to LDM. 7) On some older Hyper-V hosts, the Linux PCI sub-sytem is not able to allocate irq resources to the vmbus driver. I recently learnt that the vmbus driver is an acpi enumerated device on the Hyper-V platform. Added code to retrieve irq information from DSDT. Regards, K. Y
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 01/25] Staging: hv: Introduce a function to map a generic driver pointer to a pointer to storvsc_driver_object
In preparation for getting rid of the priv element from struct hv_driver, introduce a function that maps a generic struct driver pointer to struct storvsc_driver_object. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/storvsc_api.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index c98139c..b60a058 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -28,6 +28,7 @@ #include <linux/kernel.h> #include "vstorage.h" #include "vmbus_api.h" +#include "vmbus.h" /* Defines */ #define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) @@ -153,6 +154,13 @@ static inline struct storvsc_driver_object *hvdr_to_stordr(struct hv_driver *d) return container_of(d, struct storvsc_driver_object, base); } +static inline +struct storvsc_driver_object *drv_to_stordrv(struct device_driver *d) +{ + struct hv_driver *hvdrv = drv_to_hv_drv(d); + return hvdr_to_stordr(hvdrv); +} + /* Interface */ int stor_vsc_on_device_add(struct hv_device *device, -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 02/25] Staging: hv: Get rid of the references to the priv element of struct hv_driver in block driver
In preparation for getting rid of the priv element from struct hv_driver, get rid of the references to the priv element of struct hv_driver in blkvsc_drv.c and storvsc.c Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/blkvsc_drv.c | 14 +++----------- drivers/staging/hv/storvsc.c | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index acc5435..ec6a761 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -214,10 +214,8 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, { struct block_device_context *blkdev = blkvsc_req->dev; struct hv_device *device_ctx = blkdev->device_ctx; - struct hv_driver *drv - drv_to_hv_drv(device_ctx->device.driver); struct storvsc_driver_object *storvsc_drv_obj - drv->priv; + drv_to_stordrv(device_ctx->device.driver); struct hv_storvsc_request *storvsc_req; struct vmscsi_request *vm_srb; int ret; @@ -541,10 +539,8 @@ out: */ static int blkvsc_remove(struct device *device) { - struct hv_driver *drv - drv_to_hv_drv(device->driver); struct storvsc_driver_object *storvsc_drv_obj - drv->priv; + drv_to_stordrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct block_device_context *blkdev = dev_get_drvdata(device); unsigned long flags; @@ -881,8 +877,6 @@ static int blkvsc_drv_init(void) storvsc_drv_obj->ring_buffer_size = blkvsc_ringbuffer_size; - drv->priv = storvsc_drv_obj; - /* Callback to client driver to complete the initialization */ blk_vsc_initialize(&storvsc_drv_obj->base); @@ -945,10 +939,8 @@ static void blkvsc_drv_exit(void) */ static int blkvsc_probe(struct device *device) { - struct hv_driver *drv - drv_to_hv_drv(device->driver); struct storvsc_driver_object *storvsc_drv_obj - drv->priv; + drv_to_stordrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct block_device_context *blkdev = NULL; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 85bae5a..d53aa97 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -414,7 +414,7 @@ static int stor_vsc_connect_to_vsp(struct hv_device *device) struct storvsc_driver_object *stor_driver; int ret; - stor_driver = (struct storvsc_driver_object *)device->drv; + stor_driver = drv_to_stordrv(device->device.driver); memset(&props, 0, sizeof(struct vmstorage_channel_properties)); /* Open the channel */ -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 03/25] Staging: hv: Get rid of the references to the priv element of struct hv_driver in hv_mouse.c
In preparation for getting rid of the priv element from struct hv_driver, get rid of the references to the priv element of struct hv_driver in hv_mouse.c Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/hv_mouse.c | 22 +++++++++++++--------- 1 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index bd93548..4333247 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -52,6 +52,13 @@ struct mousevsc_drv_obj { }; +static inline +struct mousevsc_drv_obj *drv_to_mousedrv(struct device_driver *d) +{ + struct hv_driver *hvdrv = drv_to_hv_drv(d); + return container_of(hvdrv, struct mousevsc_drv_obj, base); +} + /* The maximum size of a synthetic input message. */ #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16 @@ -428,7 +435,7 @@ static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, return; } - input_drv = (struct mousevsc_drv_obj *)input_device->device->drv; + input_drv = drv_to_mousedrv(input_device->device->device.driver); inputreport_callback(input_device->device, input_report->buffer, @@ -713,7 +720,7 @@ static int mousevsc_on_device_add(struct hv_device *device, return ret; } - input_drv = (struct mousevsc_drv_obj *)input_dev->device->drv; + input_drv = drv_to_mousedrv(input_dev->device->device.driver); dev_info.vendor = input_dev->hid_dev_info.vendor; dev_info.product = input_dev->hid_dev_info.product; @@ -829,9 +836,8 @@ static int mousevsc_probe(struct device *device) { int ret = 0; - struct hv_driver *drv - drv_to_hv_drv(device->driver); - struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv; + struct mousevsc_drv_obj *mousevsc_drv_obj + drv_to_mousedrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct input_device_context *input_dev_ctx; @@ -857,9 +863,8 @@ static int mousevsc_remove(struct device *device) { int ret = 0; - struct hv_driver *drv - drv_to_hv_drv(device->driver); - struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv; + struct mousevsc_drv_obj *mousevsc_drv_obj + drv_to_mousedrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct input_device_context *input_dev_ctx; @@ -1017,7 +1022,6 @@ static int __init mousevsc_init(void) mouse_vsc_initialize(&input_drv_obj->base); drv->driver.name = input_drv_obj->base.name; - drv->priv = input_drv_obj; drv->driver.probe = mousevsc_probe; drv->driver.remove = mousevsc_remove; -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 04/25] Staging: hv: Introduce a function to map a generic driver pointer to a pointer to struct netvsc_driver
In preparation for getting rid of the priv element from struct hv_driver, introduce a function to map a generic driver pointer to a pointer to struct netvsc_driver. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/netvsc_api.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/staging/hv/netvsc_api.h b/drivers/staging/hv/netvsc_api.h index b4bed36..48b512b 100644 --- a/drivers/staging/hv/netvsc_api.h +++ b/drivers/staging/hv/netvsc_api.h @@ -26,6 +26,7 @@ #define _NETVSC_API_H_ #include "vmbus_api.h" +#include "vmbus.h" /* Fwd declaration */ struct hv_netvsc_packet; @@ -103,6 +104,13 @@ struct netvsc_driver { void *ctx; }; +static inline +struct netvsc_driver *drv_to_netvscdrv(struct device_driver *d) +{ + struct hv_driver *hvdrv = drv_to_hv_drv(d); + return container_of(hvdrv, struct netvsc_driver, base); +} + struct netvsc_device_info { unsigned char mac_adr[6]; bool link_state; /* 0 - link up, 1 - link down */ -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 05/25] Staging: hv: Get rid of the references to the priv element of struct hv_driver in net driver
In preparation for getting rid of the priv element from struct hv_driver, get rid of the references to the priv element of struct hv_driver in network driver. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/netvsc.c | 11 +++++++---- drivers/staging/hv/netvsc_drv.c | 16 ++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index b3e6497..27c7449 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -835,6 +835,9 @@ static void netvsc_receive(struct hv_device *device, int i, j; int count = 0, bytes_remain = 0; unsigned long flags; + struct netvsc_driver *netvsc_drv + drv_to_netvscdrv(device->device.driver); + LIST_HEAD(listHead); net_device = get_inbound_net_device(device); @@ -995,8 +998,7 @@ static void netvsc_receive(struct hv_device *device, } /* Pass it to the upper layer */ - ((struct netvsc_driver *)device->drv)-> - recv_cb(device, netvsc_packet); + netvsc_drv->recv_cb(device, netvsc_packet); netvsc_receive_completion(netvsc_packet-> completion.recv.recv_completion_ctx); @@ -1102,7 +1104,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) struct netvsc_device *net_device; struct hv_netvsc_packet *packet, *pos; struct netvsc_driver *net_driver - (struct netvsc_driver *)device->drv; + drv_to_netvscdrv(device->device.driver); net_device = alloc_net_device(device); if (!net_device) { @@ -1183,7 +1185,8 @@ cleanup: */ int netvsc_initialize(struct hv_driver *drv) { - struct netvsc_driver *driver = (struct netvsc_driver *)drv; + struct netvsc_driver *driver + drv_to_netvscdrv(&drv->driver); drv->name = driver_name; memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid)); diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 096a732..e61eb7e 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -132,9 +132,8 @@ static void netvsc_xmit_completion(void *context) static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); - struct hv_driver *drv - drv_to_hv_drv(net_device_ctx->device_ctx->device.driver); - struct netvsc_driver *net_drv_obj = drv->priv; + struct netvsc_driver *net_drv_obj + drv_to_netvscdrv(net_device_ctx->device_ctx->device.driver); struct hv_netvsc_packet *packet; int ret; unsigned int i, num_pages; @@ -343,9 +342,8 @@ static void netvsc_send_garp(struct work_struct *w) static int netvsc_probe(struct device *device) { - struct hv_driver *drv - drv_to_hv_drv(device->driver); - struct netvsc_driver *net_drv_obj = drv->priv; + struct netvsc_driver *net_drv_obj + drv_to_netvscdrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct net_device *net = NULL; struct net_device_context *net_device_ctx; @@ -413,9 +411,8 @@ static int netvsc_probe(struct device *device) static int netvsc_remove(struct device *device) { - struct hv_driver *drv - drv_to_hv_drv(device->driver); - struct netvsc_driver *net_drv_obj = drv->priv; + struct netvsc_driver *net_drv_obj + drv_to_netvscdrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct net_device *net = dev_get_drvdata(&device_obj->device); int ret; @@ -498,7 +495,6 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) net_drv_obj->ring_buf_size = ring_size * PAGE_SIZE; net_drv_obj->recv_cb = netvsc_recv_callback; net_drv_obj->link_status_change = netvsc_linkstatus_callback; - drv->priv = net_drv_obj; /* Callback to client driver to complete the initialization */ drv_init(&net_drv_obj->base); -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 06/25] Staging: hv: Get rid of the references to the priv element of struct hv_driver in storvsc_drv.c
In preparation for getting rid of the priv element from struct hv_driver, get rid of the references to the priv element of struct hv_driver in storvsc_drv.c. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 17 ++++++----------- 1 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index f819c6a..5ac2904 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -197,8 +197,6 @@ static int storvsc_drv_init(void) /* Callback to client driver to complete the initialization */ stor_vsc_initialize(&storvsc_drv_obj->base); - drv->priv = storvsc_drv_obj; - DPRINT_INFO(STORVSC_DRV, "max outstanding reqs %u", storvsc_drv_obj->max_outstanding_req_per_channel); @@ -325,9 +323,8 @@ static void storvsc_drv_exit(void) static int storvsc_probe(struct device *device) { int ret; - struct hv_driver *drv - drv_to_hv_drv(device->driver); - struct storvsc_driver_object *storvsc_drv_obj = drv->priv; + struct storvsc_driver_object *storvsc_drv_obj + drv_to_stordrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct Scsi_Host *host; struct host_device_context *host_device_ctx; @@ -404,9 +401,8 @@ static int storvsc_probe(struct device *device) */ static int storvsc_remove(struct device *device) { - struct hv_driver *drv - drv_to_hv_drv(device->driver); - struct storvsc_driver_object *storvsc_drv_obj = drv->priv; + struct storvsc_driver_object *storvsc_drv_obj + drv_to_stordrv(device->driver); struct hv_device *device_obj = device_to_hv_device(device); struct Scsi_Host *host = dev_get_drvdata(device); struct host_device_context *host_device_ctx @@ -692,9 +688,8 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, struct host_device_context *host_device_ctx (struct host_device_context *)scmnd->device->host->hostdata; struct hv_device *device_ctx = host_device_ctx->device_ctx; - struct hv_driver *drv - drv_to_hv_drv(device_ctx->device.driver); - struct storvsc_driver_object *storvsc_drv_obj = drv->priv; + struct storvsc_driver_object *storvsc_drv_obj + drv_to_stordrv(device_ctx->device.driver); struct hv_storvsc_request *request; struct storvsc_cmd_request *cmd_request; unsigned int request_size = 0; -- 1.7.4.1
In preparation for getting rid of the priv element from struct hv_driver, cleanup vmbus_match - the setting of the drv field in struct hv_device is not needed. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index c85d796..bf124a7 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -307,12 +307,9 @@ static int vmbus_match(struct device *device, struct device_driver *driver) /* We found our driver ? */ if (memcmp(&device_ctx->dev_type, &drv->dev_type, - sizeof(struct hv_guid)) == 0) { - - device_ctx->drv = drv->priv; - + sizeof(struct hv_guid)) == 0) match = 1; - } + return match; } -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 09/25] Staging: hv: Get rid of vmbus_release_unattached_channels() as it is not used
Since vmbus_release_unattached_channels() is only used in module unload path and since the vmbus driver cannot be unloaded, get rid of this "dead" code. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/channel_mgmt.c | 33 --------------------------------- drivers/staging/hv/channel_mgmt.h | 2 -- 2 files changed, 0 insertions(+), 35 deletions(-) diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index fe32f7e..1929ab3 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -791,37 +791,4 @@ cleanup: return ret; } -/* - * vmbus_release_unattached_channels - Release channels that are - * unattached/unconnected ie (no drivers associated) - */ -void vmbus_release_unattached_channels(void) -{ - struct vmbus_channel *channel, *pos; - struct vmbus_channel *start = NULL; - unsigned long flags; - - spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - - list_for_each_entry_safe(channel, pos, &vmbus_connection.chn_list, - listentry) { - if (channel == start) - break; - - if (!channel->device_obj->drv) { - list_del(&channel->listentry); - - pr_err("Releasing unattached device object\n"); - - vmbus_child_device_unregister(channel->device_obj); - free_channel(channel); - } else { - if (!start) - start = channel; - } - } - - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); -} - /* eof */ diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index 96f74e2..3b2c393 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -315,6 +315,4 @@ void vmbus_onmessage(void *context); int vmbus_request_offers(void); -void vmbus_release_unattached_channels(void); - #endif /* _CHANNEL_MGMT_H_ */ -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 10/25] Staging: hv: Get rid of the priv pointer in struct hv_driver
Now that we have gotten rid of all uses of the priv element in struct hv_driver, get rid of the priv pointer. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_api.h | 10 ---------- 1 files changed, 0 insertions(+), 10 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index f0d96eb..51fa952 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -94,16 +94,6 @@ struct hv_driver { /* the device type supported by this driver */ struct hv_guid dev_type; - /* - * Device type specific drivers (net, blk etc.) - * need a mechanism to get a pointer to - * device type specific driver structure given - * a pointer to the base hyperv driver structure. - * The current code solves this problem using - * a hack. Support this need explicitly - */ - void *priv; - struct device_driver driver; int (*dev_add)(struct hv_device *device, void *data); -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 11/25] Staging: hv: Get rid of the drv field in struct hv_device
Now, we can rid of the drv field in struct hv_device. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_api.h | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 51fa952..02e3587 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -103,9 +103,6 @@ struct hv_driver { /* Base device object */ struct hv_device { - /* the driver for this device */ - struct hv_driver *drv; - char name[64]; struct work_struct probe_failed_work_item; -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 12/25] Staging: hv: Cleanup error handling in vmbus_child_device_register()
Cleanup error handling in vmbus_child_device_register(). Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d597dd4..4d569ad 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -720,11 +720,16 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) */ ret = device_register(&child_device_obj->device); + if (ret) + return ret; + /* vmbus_probe() error does not get propergate to device_register(). */ ret = child_device_obj->probe_error; - if (ret) + if (ret) { pr_err("Unable to register child device\n"); + device_unregister(&child_device_obj->device); + } else pr_info("child device %s registered\n", dev_name(&child_device_obj->device)); -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 14/25] Staging: hv: Properly handle errors in hv_pci_probe()
Much of the vmbus driver initialization is done within the hv_pci_probe() function. Properly handle errors in hv_pci_probe so that we can appropriately deal with loading of the vmbus driver. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 34 +++++++++++++++++++++++++--------- 1 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 248dc8a..a2acbce 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -54,6 +54,8 @@ EXPORT_SYMBOL(vmbus_loglevel); /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */ +static int pci_probe_error; +static struct completion probe_event; static void get_channel_info(struct hv_device *device, struct hv_device_info *info) @@ -732,19 +734,19 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) static int __devinit hv_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err; - hv_pci_dev = pdev; - err = pci_enable_device(pdev); - if (err) - return err; + pci_probe_error = pci_enable_device(pdev); + if (pci_probe_error) + goto probe_cleanup; - err = vmbus_bus_init(pdev); - if (err) + pci_probe_error = vmbus_bus_init(pdev); + if (pci_probe_error) pci_disable_device(pdev); - return err; +probe_cleanup: + complete(&probe_event); + return pci_probe_error; } /* @@ -767,7 +769,21 @@ static struct pci_driver hv_bus_driver = { static int __init hv_pci_init(void) { - return pci_register_driver(&hv_bus_driver); + int ret; + init_completion(&probe_event); + ret = pci_register_driver(&hv_bus_driver); + if (ret) + return ret; + /* + * All the vmbus initialization occurs within the + * hv_pci_probe() function. Wait for hv_pci_probe() + * to complete. + */ + wait_for_completion(&probe_event); + + if (pci_probe_error) + pci_unregister_driver(&hv_bus_driver); + return pci_probe_error; } -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 15/25] Staging: hv: Make hv_pci_dev a static variable
Make hv_pci_dev a static variable. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at 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 a2acbce..f779d4e 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -40,7 +40,7 @@ #include "vmbus_private.h" -struct pci_dev *hv_pci_dev; +static struct pci_dev *hv_pci_dev; /* Main vmbus driver data structure */ struct hv_bus { -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 16/25] Staging: hv: Make msg_dpc a global variable
In preparation for cleaning up (getting rid of) of the hv_bus structure, make msg_dpc a global variable. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index f779d4e..028051d 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -42,10 +42,11 @@ static struct pci_dev *hv_pci_dev; +static struct tasklet_struct msg_dpc; + /* Main vmbus driver data structure */ struct hv_bus { struct bus_type bus; - struct tasklet_struct msg_dpc; struct tasklet_struct event_dpc; }; @@ -517,7 +518,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) /* Schedules a dpc if necessary */ if (ret > 0) { if (test_bit(0, (unsigned long *)&ret)) - tasklet_schedule(&hv_bus.msg_dpc); + tasklet_schedule(&msg_dpc); if (test_bit(1, (unsigned long *)&ret)) tasklet_schedule(&hv_bus.event_dpc); @@ -552,7 +553,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) hv_bus.bus.name = driver_name; /* Initialize the bus context */ - tasklet_init(&hv_bus.msg_dpc, vmbus_on_msg_dpc, 0); + tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0); tasklet_init(&hv_bus.event_dpc, vmbus_on_event, 0); /* Now, register the bus with LDM */ -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 17/25] Staging: hv: Make event_dpc a global variable
In preparation for getting rid of struct hv_bus, Make event_dpc a global variable. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 028051d..a3a7741 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -43,11 +43,11 @@ static struct pci_dev *hv_pci_dev; static struct tasklet_struct msg_dpc; +static struct tasklet_struct event_dpc; /* Main vmbus driver data structure */ struct hv_bus { struct bus_type bus; - struct tasklet_struct event_dpc; }; unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL); @@ -521,7 +521,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) tasklet_schedule(&msg_dpc); if (test_bit(1, (unsigned long *)&ret)) - tasklet_schedule(&hv_bus.event_dpc); + tasklet_schedule(&event_dpc); return IRQ_HANDLED; } else { @@ -554,7 +554,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) /* Initialize the bus context */ tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0); - tasklet_init(&hv_bus.event_dpc, vmbus_on_event, 0); + tasklet_init(&event_dpc, vmbus_on_event, 0); /* Now, register the bus with LDM */ ret = bus_register(&hv_bus.bus); -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 18/25] Staging: hv: Get rid of struct hv_bus
Now, get rid of struct hv_bus. We will no longer be embedding struct bus_type. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 33 ++++++++++++++------------------- 1 files changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index a3a7741..515311c 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -45,11 +45,6 @@ static struct pci_dev *hv_pci_dev; static struct tasklet_struct msg_dpc; static struct tasklet_struct event_dpc; -/* Main vmbus driver data structure */ -struct hv_bus { - struct bus_type bus; -}; - unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL); EXPORT_SYMBOL(vmbus_loglevel); /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ @@ -405,14 +400,14 @@ static void vmbus_device_release(struct device *device) } /* The one and only one */ -static struct hv_bus hv_bus = { - .bus.name = "vmbus", - .bus.match = vmbus_match, - .bus.shutdown = vmbus_shutdown, - .bus.remove = vmbus_remove, - .bus.probe = vmbus_probe, - .bus.uevent = vmbus_uevent, - .bus.dev_attrs = vmbus_device_attrs, +static struct bus_type hv_bus = { + .name = "vmbus", + .match = vmbus_match, + .shutdown = vmbus_shutdown, + .remove = vmbus_remove, + .probe = vmbus_probe, + .uevent = vmbus_uevent, + .dev_attrs = vmbus_device_attrs, }; static const char *driver_name = "hyperv"; @@ -550,14 +545,14 @@ static int vmbus_bus_init(struct pci_dev *pdev) goto cleanup; } - hv_bus.bus.name = driver_name; + hv_bus.name = driver_name; /* 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.bus); + ret = bus_register(&hv_bus); if (ret) { ret = -1; goto cleanup; @@ -572,7 +567,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) pr_err("Unable to request IRQ %d\n", pdev->irq); - bus_unregister(&hv_bus.bus); + bus_unregister(&hv_bus); ret = -1; goto cleanup; @@ -588,7 +583,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) ret = vmbus_connect(); if (ret) { free_irq(pdev->irq, pdev); - bus_unregister(&hv_bus.bus); + bus_unregister(&hv_bus); goto cleanup; } @@ -618,7 +613,7 @@ int vmbus_child_driver_register(struct device_driver *drv) pr_info("child driver registering - name %s\n", drv->name); /* The child driver on this vmbus */ - drv->bus = &hv_bus.bus; + drv->bus = &hv_bus; ret = driver_register(drv); @@ -688,7 +683,7 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) atomic_inc_return(&device_num)); /* The new device belongs to this bus */ - child_device_obj->device.bus = &hv_bus.bus; /* device->dev.bus; */ + child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */ child_device_obj->device.parent = &hv_pci_dev->dev; child_device_obj->device.release = vmbus_device_release; -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 19/25] Staging: hv: Add probe function to struct hv_driver
Add probe function to struct hv_driver. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_api.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index c953d6e..6f3741d 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -99,6 +99,9 @@ struct hv_driver { int (*dev_add)(struct hv_device *device, void *data); int (*dev_rm)(struct hv_device *device); void (*cleanup)(struct hv_driver *driver); + + int (*probe)(struct hv_device *); + }; /* Base device object */ -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 20/25] Staging: hv: Use the probe function in struct hv_driver
Use the newly introduced probe function. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/blkvsc_drv.c | 19 +++++++++---------- drivers/staging/hv/hv_mouse.c | 11 +++++------ drivers/staging/hv/netvsc_drv.c | 19 +++++++++---------- drivers/staging/hv/storvsc_drv.c | 23 +++++++++++------------ drivers/staging/hv/vmbus_drv.c | 5 ++--- 5 files changed, 36 insertions(+), 41 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index ec6a761..20b9a53 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -140,7 +140,7 @@ 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 device *dev); +static int blkvsc_probe(struct hv_device *dev); static int blk_vsc_on_device_add(struct hv_device *device, void *additional_info) @@ -882,7 +882,7 @@ static int blkvsc_drv_init(void) drv->driver.name = storvsc_drv_obj->base.name; - drv->driver.probe = blkvsc_probe; + drv->probe = blkvsc_probe; drv->driver.remove = blkvsc_remove; drv->driver.shutdown = blkvsc_shutdown; @@ -937,11 +937,10 @@ static void blkvsc_drv_exit(void) /* * blkvsc_probe - Add a new device for this driver */ -static int blkvsc_probe(struct device *device) +static int blkvsc_probe(struct hv_device *dev) { struct storvsc_driver_object *storvsc_drv_obj - drv_to_stordrv(device->driver); - struct hv_device *device_obj = device_to_hv_device(device); + drv_to_stordrv(dev->device.driver); struct block_device_context *blkdev = NULL; struct storvsc_device_info device_info; @@ -961,7 +960,7 @@ static int blkvsc_probe(struct device *device) spin_lock_init(&blkdev->lock); - blkdev->request_pool = kmem_cache_create(dev_name(&device_obj->device), + blkdev->request_pool = kmem_cache_create(dev_name(&dev->device), sizeof(struct blkvsc_request), 0, SLAB_HWCACHE_ALIGN, NULL); if (!blkdev->request_pool) { @@ -971,17 +970,17 @@ static int blkvsc_probe(struct device *device) /* Call to the vsc driver to add the device */ - ret = storvsc_drv_obj->base.dev_add(device_obj, &device_info); + ret = storvsc_drv_obj->base.dev_add(dev, &device_info); if (ret != 0) goto cleanup; - blkdev->device_ctx = device_obj; + 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(device, blkdev); + dev_set_drvdata(&dev->device, blkdev); ret = stor_vsc_get_major_info(&device_info, &major_info); @@ -1041,7 +1040,7 @@ static int blkvsc_probe(struct device *device) return ret; remove: - storvsc_drv_obj->base.dev_rm(device_obj); + storvsc_drv_obj->base.dev_rm(dev); cleanup: if (blkdev) { diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 4333247..e2363b3 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -832,23 +832,22 @@ static void mousevsc_hid_close(struct hid_device *hid) { } -static int mousevsc_probe(struct device *device) +static int mousevsc_probe(struct hv_device *dev) { int ret = 0; struct mousevsc_drv_obj *mousevsc_drv_obj - drv_to_mousedrv(device->driver); + drv_to_mousedrv(dev->device.driver); - struct hv_device *device_obj = device_to_hv_device(device); struct input_device_context *input_dev_ctx; input_dev_ctx = kmalloc(sizeof(struct input_device_context), GFP_KERNEL); - dev_set_drvdata(device, input_dev_ctx); + dev_set_drvdata(&dev->device, input_dev_ctx); /* Call to the vsc driver to add the device */ - ret = mousevsc_drv_obj->base.dev_add(device_obj, NULL); + ret = mousevsc_drv_obj->base.dev_add(dev, NULL); if (ret != 0) { DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device"); @@ -1023,7 +1022,7 @@ static int __init mousevsc_init(void) drv->driver.name = input_drv_obj->base.name; - drv->driver.probe = mousevsc_probe; + drv->probe = mousevsc_probe; drv->driver.remove = mousevsc_remove; /* The driver belongs to vmbus */ diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index e61eb7e..685a6f5 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -340,11 +340,10 @@ static void netvsc_send_garp(struct work_struct *w) } -static int netvsc_probe(struct device *device) +static int netvsc_probe(struct hv_device *dev) { struct netvsc_driver *net_drv_obj - drv_to_netvscdrv(device->driver); - struct hv_device *device_obj = device_to_hv_device(device); + drv_to_netvscdrv(dev->device.driver); struct net_device *net = NULL; struct net_device_context *net_device_ctx; struct netvsc_device_info device_info; @@ -361,16 +360,16 @@ static int netvsc_probe(struct device *device) netif_carrier_off(net); net_device_ctx = netdev_priv(net); - net_device_ctx->device_ctx = device_obj; + net_device_ctx->device_ctx = dev; net_device_ctx->avail = ring_size; - dev_set_drvdata(device, net); + dev_set_drvdata(&dev->device, net); INIT_WORK(&net_device_ctx->work, netvsc_send_garp); /* Notify the netvsc driver of the new device */ - ret = net_drv_obj->base.dev_add(device_obj, &device_info); + ret = net_drv_obj->base.dev_add(dev, &device_info); if (ret != 0) { free_netdev(net); - dev_set_drvdata(device, NULL); + dev_set_drvdata(&dev->device, NULL); netdev_err(net, "unable to add netvsc device (ret %d)\n", ret); return ret; @@ -397,12 +396,12 @@ static int netvsc_probe(struct device *device) net->features = NETIF_F_SG; SET_ETHTOOL_OPS(net, ðtool_ops); - SET_NETDEV_DEV(net, device); + SET_NETDEV_DEV(net, &dev->device); ret = register_netdev(net); if (ret != 0) { /* Remove the device and release the resource */ - net_drv_obj->base.dev_rm(device_obj); + net_drv_obj->base.dev_rm(dev); free_netdev(net); } @@ -501,7 +500,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv->driver.name = net_drv_obj->base.name; - drv->driver.probe = netvsc_probe; + drv->probe = netvsc_probe; drv->driver.remove = netvsc_remove; /* The driver belongs to vmbus */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 5ac2904..2060206 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -123,7 +123,7 @@ static int stor_vsc_initialize(struct hv_driver *driver) } /* Static decl */ -static int storvsc_probe(struct device *dev); +static int storvsc_probe(struct hv_device *dev); static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd); static int storvsc_device_alloc(struct scsi_device *); static int storvsc_device_configure(struct scsi_device *); @@ -213,7 +213,7 @@ static int storvsc_drv_init(void) drv->driver.name = storvsc_drv_obj->base.name; - drv->driver.probe = storvsc_probe; + drv->probe = storvsc_probe; drv->driver.remove = storvsc_remove; /* The driver belongs to vmbus */ @@ -320,12 +320,11 @@ static void storvsc_drv_exit(void) /* * storvsc_probe - Add a new device for this driver */ -static int storvsc_probe(struct device *device) +static int storvsc_probe(struct hv_device *device) { int ret; struct storvsc_driver_object *storvsc_drv_obj - drv_to_stordrv(device->driver); - struct hv_device *device_obj = device_to_hv_device(device); + drv_to_stordrv(device->device.driver); struct Scsi_Host *host; struct host_device_context *host_device_ctx; struct storvsc_device_info device_info; @@ -340,16 +339,16 @@ static int storvsc_probe(struct device *device) return -ENOMEM; } - dev_set_drvdata(device, host); + dev_set_drvdata(&device->device, host); host_device_ctx = (struct host_device_context *)host->hostdata; memset(host_device_ctx, 0, sizeof(struct host_device_context)); host_device_ctx->port = host->host_no; - host_device_ctx->device_ctx = device_obj; + host_device_ctx->device_ctx = device; host_device_ctx->request_pool - kmem_cache_create(dev_name(&device_obj->device), + kmem_cache_create(dev_name(&device->device), sizeof(struct storvsc_cmd_request), 0, SLAB_HWCACHE_ALIGN, NULL); @@ -360,8 +359,8 @@ static int storvsc_probe(struct device *device) device_info.port_number = host->host_no; /* Call to the vsc driver to add the device */ - ret = storvsc_drv_obj->base.dev_add(device_obj, - (void *)&device_info); + ret = storvsc_drv_obj->base.dev_add(device, (void *)&device_info); + if (ret != 0) { DPRINT_ERR(STORVSC_DRV, "unable to add scsi vsc device"); kmem_cache_destroy(host_device_ctx->request_pool); @@ -381,11 +380,11 @@ static int storvsc_probe(struct device *device) host->max_channel = STORVSC_MAX_CHANNELS - 1; /* Register the HBA and start the scsi bus scan */ - ret = scsi_add_host(host, device); + ret = scsi_add_host(host, &device->device); if (ret != 0) { DPRINT_ERR(STORVSC_DRV, "unable to add scsi host device"); - storvsc_drv_obj->base.dev_rm(device_obj); + storvsc_drv_obj->base.dev_rm(device); kmem_cache_destroy(host_device_ctx->request_pool); scsi_host_put(host); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 515311c..15e6497 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -321,10 +321,9 @@ static int vmbus_probe(struct device *child_device) drv_to_hv_drv(child_device->driver); struct hv_device *dev = device_to_hv_device(child_device); - /* Let the specific open-source driver handles the probe if it can */ - if (drv->driver.probe) { + if (drv->probe) { ret = dev->probe_error - drv->driver.probe(child_device); + drv->probe(dev); if (ret != 0) pr_err("probe failed for device %s (%d)\n", dev_name(child_device), ret); -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 21/25] Staging: hv: Add remove() function to struct hv_driver
Add remove() function to struct hv_driver. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_api.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 6f3741d..1af1b62 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -101,6 +101,7 @@ struct hv_driver { void (*cleanup)(struct hv_driver *driver); int (*probe)(struct hv_device *); + int (*remove)(struct hv_device *); }; -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 22/25] Staging: hv: Use the remove() function in struct hv_driver
Use the newly introduced remove() function in struct hv_driver. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/blkvsc_drv.c | 11 +++++------ drivers/staging/hv/hv_mouse.c | 11 +++++------ drivers/staging/hv/netvsc_drv.c | 13 ++++++------- drivers/staging/hv/storvsc_drv.c | 13 ++++++------- drivers/staging/hv/vmbus_drv.c | 9 +++------ 5 files changed, 25 insertions(+), 32 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 20b9a53..80f7c0e 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -537,19 +537,18 @@ out: /* * blkvsc_remove() - Callback when our device is removed */ -static int blkvsc_remove(struct device *device) +static int blkvsc_remove(struct hv_device *dev) { struct storvsc_driver_object *storvsc_drv_obj - drv_to_stordrv(device->driver); - struct hv_device *device_obj = device_to_hv_device(device); - struct block_device_context *blkdev = dev_get_drvdata(device); + drv_to_stordrv(dev->device.driver); + struct block_device_context *blkdev = dev_get_drvdata(&dev->device); unsigned long flags; /* * Call to the vsc driver to let it know that the device is being * removed */ - storvsc_drv_obj->base.dev_rm(device_obj); + storvsc_drv_obj->base.dev_rm(dev); /* Get to a known state */ spin_lock_irqsave(&blkdev->lock, flags); @@ -883,7 +882,7 @@ static int blkvsc_drv_init(void) drv->driver.name = storvsc_drv_obj->base.name; drv->probe = blkvsc_probe; - drv->driver.remove = blkvsc_remove; + drv->remove = blkvsc_remove; drv->driver.shutdown = blkvsc_shutdown; /* The driver belongs to vmbus */ diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index e2363b3..d49a51e 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -858,20 +858,19 @@ static int mousevsc_probe(struct hv_device *dev) return 0; } -static int mousevsc_remove(struct device *device) +static int mousevsc_remove(struct hv_device *dev) { int ret = 0; struct mousevsc_drv_obj *mousevsc_drv_obj - drv_to_mousedrv(device->driver); + drv_to_mousedrv(dev->device.driver); - struct hv_device *device_obj = device_to_hv_device(device); struct input_device_context *input_dev_ctx; input_dev_ctx = kmalloc(sizeof(struct input_device_context), GFP_KERNEL); - dev_set_drvdata(device, input_dev_ctx); + dev_set_drvdata(&dev->device, input_dev_ctx); if (input_dev_ctx->connected) { hidinput_disconnect(input_dev_ctx->hid_device); @@ -885,7 +884,7 @@ static int mousevsc_remove(struct device *device) * Call to the vsc driver to let it know that the device * is being removed */ - ret = mousevsc_drv_obj->base.dev_rm(device_obj); + ret = mousevsc_drv_obj->base.dev_rm(dev); if (ret != 0) { DPRINT_ERR(INPUTVSC_DRV, @@ -1023,7 +1022,7 @@ static int __init mousevsc_init(void) drv->driver.name = input_drv_obj->base.name; drv->probe = mousevsc_probe; - drv->driver.remove = mousevsc_remove; + drv->remove = mousevsc_remove; /* The driver belongs to vmbus */ vmbus_child_driver_register(&drv->driver); diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 685a6f5..f4c6000 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -408,16 +408,15 @@ static int netvsc_probe(struct hv_device *dev) return ret; } -static int netvsc_remove(struct device *device) +static int netvsc_remove(struct hv_device *dev) { struct netvsc_driver *net_drv_obj - drv_to_netvscdrv(device->driver); - struct hv_device *device_obj = device_to_hv_device(device); - struct net_device *net = dev_get_drvdata(&device_obj->device); + drv_to_netvscdrv(dev->device.driver); + struct net_device *net = dev_get_drvdata(&dev->device); int ret; if (net == NULL) { - dev_err(device, "No net device to remove\n"); + dev_err(&dev->device, "No net device to remove\n"); return 0; } @@ -434,7 +433,7 @@ static int netvsc_remove(struct device *device) * Call to the vsc driver to let it know that the device is being * removed */ - ret = net_drv_obj->base.dev_rm(device_obj); + ret = net_drv_obj->base.dev_rm(dev); if (ret != 0) { /* TODO: */ netdev_err(net, "unable to remove vsc device (ret %d)\n", ret); @@ -501,7 +500,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv->driver.name = net_drv_obj->base.name; drv->probe = netvsc_probe; - drv->driver.remove = netvsc_remove; + drv->remove = netvsc_remove; /* The driver belongs to vmbus */ ret = vmbus_child_driver_register(&drv->driver); diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 2060206..e449481 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -128,7 +128,7 @@ static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd static int storvsc_device_alloc(struct scsi_device *); static int storvsc_device_configure(struct scsi_device *); static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd); -static int storvsc_remove(struct device *dev); +static int storvsc_remove(struct hv_device *dev); static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count, @@ -214,7 +214,7 @@ static int storvsc_drv_init(void) drv->driver.name = storvsc_drv_obj->base.name; drv->probe = storvsc_probe; - drv->driver.remove = storvsc_remove; + drv->remove = storvsc_remove; /* The driver belongs to vmbus */ ret = vmbus_child_driver_register(&drv->driver); @@ -398,12 +398,11 @@ static int storvsc_probe(struct hv_device *device) /* * storvsc_remove - Callback when our device is removed */ -static int storvsc_remove(struct device *device) +static int storvsc_remove(struct hv_device *dev) { struct storvsc_driver_object *storvsc_drv_obj - drv_to_stordrv(device->driver); - struct hv_device *device_obj = device_to_hv_device(device); - struct Scsi_Host *host = dev_get_drvdata(device); + drv_to_stordrv(dev->device.driver); + struct Scsi_Host *host = dev_get_drvdata(&dev->device); struct host_device_context *host_device_ctx (struct host_device_context *)host->hostdata; @@ -411,7 +410,7 @@ static int storvsc_remove(struct device *device) * Call to the vsc driver to let it know that the device is being * removed */ - storvsc_drv_obj->base.dev_rm(device_obj); + storvsc_drv_obj->base.dev_rm(dev); if (host_device_ctx->request_pool) { kmem_cache_destroy(host_device_ctx->request_pool); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 15e6497..e09b363 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -344,16 +344,13 @@ static int vmbus_remove(struct device *child_device) int ret; struct hv_driver *drv; + struct hv_device *dev = device_to_hv_device(child_device); if (child_device->driver) { drv = drv_to_hv_drv(child_device->driver); - /* - * Let the specific open-source driver handles the removal if - * it can - */ - if (drv->driver.remove) { - ret = drv->driver.remove(child_device); + if (drv->remove) { + ret = drv->remove(dev); } else { pr_err("remove not set for driver %s\n", dev_name(child_device)); -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 23/25] Staging: hv: Add shutdown() function to struct hv_driver
Add shutdown() function to struct hv_driver. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_api.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 1af1b62..0025002 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -102,6 +102,7 @@ struct hv_driver { int (*probe)(struct hv_device *); int (*remove)(struct hv_device *); + void (*shutdown)(struct hv_device *); }; -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 24/25] Staging: hv: Use the shutdown() function in struct hv_driver
Use the newly introduced shutdown() function. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/blkvsc_drv.c | 6 +++--- drivers/staging/hv/vmbus_drv.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 80f7c0e..db44cf6 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -585,9 +585,9 @@ static int blkvsc_remove(struct hv_device *dev) } -static void blkvsc_shutdown(struct device *device) +static void blkvsc_shutdown(struct hv_device *dev) { - struct block_device_context *blkdev = dev_get_drvdata(device); + struct block_device_context *blkdev = dev_get_drvdata(&dev->device); unsigned long flags; if (!blkdev) @@ -883,7 +883,7 @@ static int blkvsc_drv_init(void) drv->probe = blkvsc_probe; drv->remove = blkvsc_remove; - drv->driver.shutdown = blkvsc_shutdown; + drv->shutdown = blkvsc_shutdown; /* The driver belongs to vmbus */ ret = vmbus_child_driver_register(&drv->driver); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index e09b363..f95ec2b 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -368,6 +368,7 @@ static int vmbus_remove(struct device *child_device) static void vmbus_shutdown(struct device *child_device) { struct hv_driver *drv; + struct hv_device *dev = device_to_hv_device(child_device); /* The device may not be attached yet */ @@ -376,9 +377,8 @@ static void vmbus_shutdown(struct device *child_device) drv = drv_to_hv_drv(child_device->driver); - /* Let the specific open-source driver handles the removal if it can */ - if (drv->driver.shutdown) - drv->driver.shutdown(child_device); + if (drv->shutdown) + drv->shutdown(dev); return; } -- 1.7.4.1
K. Y. Srinivasan
2011-Apr-26 16:20 UTC
[PATCH 25/25] Staging: hv: VMBUS is a acpi enumerated device; get irq value from bios.
On some windows hosts, the Linux PCI sub-system is not allocating irq resources to the vmbus driver. It looks like VMBUS is an ACPI enumerated device. Retrieve the irq information from DSDT. Currently we use this bios specified irq, if the PCI sub-system fails to allocate the irq. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> Signed-off-by: Hank Janssen <hjanssen at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 101 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 100 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index f95ec2b..1c5d43a 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -17,8 +17,8 @@ * Authors: * Haiyang Zhang <haiyangz at microsoft.com> * Hank Janssen <hjanssen at microsoft.com> + * K. Y. Srinivasan <kys at microsoft.com> * - * 3/9/2011: K. Y. Srinivasan - Significant restructuring and cleanup */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -31,6 +31,8 @@ #include <linux/pci.h> #include <linux/dmi.h> #include <linux/slab.h> +#include <linux/acpi.h> +#include <acpi/acpi_bus.h> #include <linux/completion.h> #include "version_info.h" #include "hv_api.h" @@ -52,6 +54,7 @@ EXPORT_SYMBOL(vmbus_loglevel); static int pci_probe_error; static struct completion probe_event; +static int irq; static void get_channel_info(struct hv_device *device, struct hv_device_info *info) @@ -723,6 +726,74 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) } +/* + * VMBUS is an acpi enumerated device. Get the the IRQ information + * from DSDT. + */ + +static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *irq) +{ + + if (res->type == ACPI_RESOURCE_TYPE_IRQ) { + struct acpi_resource_irq *irqp; + irqp = &res->data.irq; + + *((unsigned int *)irq) = irqp->interrupts[0]; + } + + return AE_OK; +} + +static int vmbus_acpi_add(struct acpi_device *device) +{ + acpi_status result; + + result + acpi_walk_resources(device->handle, METHOD_NAME__CRS, + vmbus_walk_resources, &irq); + + if (ACPI_FAILURE(result)) { + complete(&probe_event); + return -ENODEV; + } + complete(&probe_event); + return 0; +} + +static const struct acpi_device_id vmbus_acpi_device_ids[] = { + {"VMBUS", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); + +static struct acpi_driver vmbus_acpi_driver = { + .name = "vmbus", + .ids = vmbus_acpi_device_ids, + .ops = { + .add = vmbus_acpi_add, + }, +}; + +static int vmbus_acpi_init(void) +{ + int result; + + + result = acpi_bus_register_driver(&vmbus_acpi_driver); + if (result < 0) + return result; + + return 0; +} + +static void vmbus_acpi_exit(void) +{ + acpi_bus_unregister_driver(&vmbus_acpi_driver); + + return; +} + + static int __devinit hv_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -732,7 +803,16 @@ static int __devinit hv_pci_probe(struct pci_dev *pdev, if (pci_probe_error) goto probe_cleanup; + /* + * If the PCI sub-sytem did not assign us an + * irq, use the bios provided one. + */ + + if (pdev->irq == 0) + pdev->irq = irq; + pci_probe_error = vmbus_bus_init(pdev); + if (pci_probe_error) pci_disable_device(pdev); @@ -762,6 +842,25 @@ static struct pci_driver hv_bus_driver = { static int __init hv_pci_init(void) { int ret; + + init_completion(&probe_event); + + /* + * Get irq resources first. + */ + + ret = vmbus_acpi_init(); + if (ret) + return ret; + + wait_for_completion(&probe_event); + + if (irq <= 0) { + vmbus_acpi_exit(); + return -ENODEV; + } + + vmbus_acpi_exit(); init_completion(&probe_event); ret = pci_register_driver(&hv_bus_driver); if (ret) -- 1.7.4.1
Christoph Hellwig
2011-Apr-26 16:57 UTC
[PATCH 00/25] Staging: hv: Cleanup vmbus driver code
Do you have a repository containing the current state of your patche somewhere? There's been so much cleanup that it's hard to review these patches against the current mainline codebase.
Greg KH
2011-Apr-26 22:50 UTC
[PATCH 12/25] Staging: hv: Cleanup error handling in vmbus_child_device_register()
On Tue, Apr 26, 2011 at 09:20:29AM -0700, K. Y. Srinivasan wrote:> Cleanup error handling in vmbus_child_device_register(). > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> > Signed-off-by: Hank Janssen <hjanssen at microsoft.com> > --- > drivers/staging/hv/vmbus_drv.c | 7 ++++++- > 1 files changed, 6 insertions(+), 1 deletions(-) > > diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c > index d597dd4..4d569ad 100644 > --- a/drivers/staging/hv/vmbus_drv.c > +++ b/drivers/staging/hv/vmbus_drv.c > @@ -720,11 +720,16 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) > */ > ret = device_register(&child_device_obj->device); > > + if (ret) > + return ret; > + > /* vmbus_probe() error does not get propergate to device_register(). */ > ret = child_device_obj->probe_error;Wait, why not? Why is the probe_error have to be saved off like this? That seems like something is wrong here, this patch should not be needed. Well, you should check the return value of device_register, that is needed, but this seems broken somehow.> > - if (ret) > + if (ret) { > pr_err("Unable to register child device\n"); > + device_unregister(&child_device_obj->device); > + } > else} else is the preferred way. Care to send a fixup patch to remove the probe_error field and fix this formatting error up? thanks, greg k-h
On Tue, Apr 26, 2011 at 09:19:45AM -0700, K. Y. Srinivasan wrote:> This patch-set addresses some of the bus/driver model cleanup that > Greg sugested over the last couple of days. In this patch-set we > deal with the following issues: > > 1) Cleanup unnecessary state in struct hv_device and > struct hv_driver to be compliant with the Linux > Driver model. > > 2) Cleanup the vmbus_match() function to conform with the > Linux Driver model. > > 3) Cleanup error handling in the vmbus_probe() and > vmbus_child_device_register() functions. Fixed a > bug in the probe failure path as part of this cleanup. > > 4) The Windows host cannot handle the vmbus_driver being > unloaded and subsequently loaded. Cleanup the driver with > this in mind.I've stopped at this patch (well, I applied one more, but you can see that.) I'd like to get some confirmation that this is really what you all want to do here before applying it. If it is, care to resend them with a bit more information about this issue and why you all are making it? Anyway, other than this one, the series looks good. But you should follow-up with some driver structure changes like what Christoph said to do. After that, do you want another round of review of the code, or do you have more things you want to send in (like the name[64] removal?) thanks, greg k-h
KY Srinivasan
2011-Apr-27 02:11 UTC
[PATCH 12/25] Staging: hv: Cleanup error handling in vmbus_child_device_register()
> -----Original Message----- > From: Greg KH [mailto:greg at kroah.com] > Sent: Tuesday, April 26, 2011 6:51 PM > To: KY Srinivasan > Cc: gregkh at suse.de; linux-kernel at vger.kernel.org; > devel at linuxdriverproject.org; virtualization at lists.osdl.org; Haiyang Zhang; > Abhishek Kane (Mindtree Consulting PVT LTD) > Subject: Re: [PATCH 12/25] Staging: hv: Cleanup error handling in > vmbus_child_device_register() > > On Tue, Apr 26, 2011 at 09:20:29AM -0700, K. Y. Srinivasan wrote: > > Cleanup error handling in vmbus_child_device_register(). > > > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > > Signed-off-by: Abhishek Kane <v-abkane at microsoft.com> > > Signed-off-by: Hank Janssen <hjanssen at microsoft.com> > > --- > > drivers/staging/hv/vmbus_drv.c | 7 ++++++- > > 1 files changed, 6 insertions(+), 1 deletions(-) > > > > diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c > > index d597dd4..4d569ad 100644 > > --- a/drivers/staging/hv/vmbus_drv.c > > +++ b/drivers/staging/hv/vmbus_drv.c > > @@ -720,11 +720,16 @@ int vmbus_child_device_register(struct hv_device > *child_device_obj) > > */ > > ret = device_register(&child_device_obj->device); > > > > + if (ret) > > + return ret; > > + > > /* vmbus_probe() error does not get propergate to device_register(). */ > > ret = child_device_obj->probe_error; > > Wait, why not? Why is the probe_error have to be saved off like this? > That seems like something is wrong here, this patch should not be > needed. > > Well, you should check the return value of device_register, that is > needed, but this seems broken somehow.The current code had comments claiming that the probe error was not correctly propagated. Looking at the kernel side of the code, it was not clear if device_register() could succeed while the probe might fail. In any event, if you can guarantee that device_register() can return any probe related errors, I agree with you that saving the probe error is an overkill. The current code saved the probe error and with new check I added with regards to the return value of device_register, there is no correctness issue with this patch.> > > > > - if (ret) > > + if (ret) { > > pr_err("Unable to register child device\n"); > > + device_unregister(&child_device_obj->device); > > + } > > else > > } else > is the preferred way. > > Care to send a fixup patch to remove the probe_error field and fix this > formatting error up?I will fix up the formatting issue. Regards, K. Y
> -----Original Message----- > From: Christoph Hellwig [mailto:hch at infradead.org] > Sent: Monday, May 02, 2011 4:00 PM > To: KY Srinivasan > Cc: Christoph Hellwig; Greg KH; gregkh at suse.de; linux-kernel at vger.kernel.org; > devel at linuxdriverproject.org; virtualization at lists.osdl.org > Subject: Re: [PATCH 00/25] Staging: hv: Cleanup vmbus driver code > > On Mon, May 02, 2011 at 07:48:38PM +0000, KY Srinivasan wrote: > > By setting up appropriate modprobe rules, this can be addressed. > > That assumes libata is a module, which it is not for many popular > distributions. >As long as you can prevent ata_piix from loading, it should be fine. Regards, K. Y
Christoph Hellwig
2011-May-02 21:35 UTC
[PATCH 00/25] Staging: hv: Cleanup vmbus driver code
On Mon, May 02, 2011 at 09:16:36PM +0000, KY Srinivasan wrote:> > That assumes libata is a module, which it is not for many popular > > distributions. > > > As long as you can prevent ata_piix from loading, it should be fine.Again, this might very well be built in, e.g. take a look at: http://pkgs.fedoraproject.org/gitweb/?p=kernel.git;a=blob;f=config-generic;h=779415bcc036b922ba92de9c4b15b9da64e9707c;hb=HEAD http://gitorious.org/opensuse/kernel-source/blobs/master/config/x86_64/default
Apparently Analagous Threads
- [PATCH 00/25] Staging: hv: Cleanup vmbus driver code
- [RESEND] [PATCH 00/18] Staging: hv: Cleanup vmbus driver code
- [RESEND] [PATCH 00/18] Staging: hv: Cleanup vmbus driver code
- [PATCH 00/12] Staging: hv: Cleanup vmbus driver - Phase II
- [PATCH 00/12] Staging: hv: Cleanup vmbus driver - Phase II