diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2011-11-08 09:01:49 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-26 17:02:08 -0800 |
commit | 126757998a50659f79a3f1ff23fccfc40ff1bf5c (patch) | |
tree | 1342f74a76be125b916ac5a87a9ca9d90141082a /drivers/staging/hv/storvsc_drv.c | |
parent | 2b9525f511791758b394643b61754a9688e0707d (diff) |
Staging: hv: storvsc: Support hot add of scsi disks
Support hot add of scsi disks.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv/storvsc_drv.c')
-rw-r--r-- | drivers/staging/hv/storvsc_drv.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 9153641f794..7c82d148f32 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -304,6 +304,30 @@ struct storvsc_cmd_request { struct hv_storvsc_request request; }; +struct storvsc_scan_work { + struct work_struct work; + struct Scsi_Host *host; + uint lun; +}; + +static void storvsc_bus_scan(struct work_struct *work) +{ + struct storvsc_scan_work *wrk; + int id, order_id; + + wrk = container_of(work, struct storvsc_scan_work, work); + for (id = 0; id < wrk->host->max_id; ++id) { + if (wrk->host->reverse_ordering) + order_id = wrk->host->max_id - id - 1; + else + order_id = id; + + scsi_scan_target(&wrk->host->shost_gendev, 0, + order_id, SCAN_WILD_CARD, 1); + } + kfree(wrk); +} + static inline struct storvsc_device *get_out_stor_device( struct hv_device *device) { @@ -551,11 +575,25 @@ static void storvsc_on_receive(struct hv_device *device, struct vstor_packet *vstor_packet, struct hv_storvsc_request *request) { + struct storvsc_scan_work *work; + struct storvsc_device *stor_device; + switch (vstor_packet->operation) { case VSTOR_OPERATION_COMPLETE_IO: storvsc_on_io_completion(device, vstor_packet, request); break; + case VSTOR_OPERATION_REMOVE_DEVICE: + case VSTOR_OPERATION_ENUMERATE_BUS: + stor_device = get_in_stor_device(device); + work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); + if (!work) + return; + + INIT_WORK(&work->work, storvsc_bus_scan); + work->host = stor_device->host; + schedule_work(&work->work); + break; default: break; |