diff options
author | Christoph Hellwig <hch@lst.de> | 2014-09-14 11:08:21 -0700 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-12 11:19:36 +0100 |
commit | 1d5203284d8acbdfdf9b478d434450b34f338f28 (patch) | |
tree | d92c80714458eb41581d4ff45c7ffb4e93375e7e /drivers/scsi/device_handler/scsi_dh.c | |
parent | 1f12ffa51479741db7c4ac1b7abc21662e4ce119 (diff) | |
download | lwn-1d5203284d8acbdfdf9b478d434450b34f338f28.tar.gz lwn-1d5203284d8acbdfdf9b478d434450b34f338f28.zip |
scsi: handle more device handler setup/teardown in common code
Move all code to set up and tear down sdev->scsi_dh_data to common code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh.c')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index d8a8aac2c3db..1dba62c5cf6a 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c @@ -98,7 +98,7 @@ device_handler_match(struct scsi_device_handler *scsi_dh, static int scsi_dh_handler_attach(struct scsi_device *sdev, struct scsi_device_handler *scsi_dh) { - int err = 0; + struct scsi_dh_data *d; if (sdev->scsi_dh_data) { if (sdev->scsi_dh_data->scsi_dh != scsi_dh) @@ -111,15 +111,22 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev, if (!try_module_get(scsi_dh->module)) return -EINVAL; - err = scsi_dh->attach(sdev); - if (err) { + d = scsi_dh->attach(sdev); + if (IS_ERR(d)) { + sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%ld)\n", + scsi_dh->name, PTR_ERR(d)); module_put(scsi_dh->module); - return err; + return PTR_ERR(d); } - kref_init(&sdev->scsi_dh_data->kref); - sdev->scsi_dh_data->sdev = sdev; - return err; + d->scsi_dh = scsi_dh; + kref_init(&d->kref); + d->sdev = sdev; + + spin_lock_irq(sdev->request_queue->queue_lock); + sdev->scsi_dh_data = d; + spin_unlock_irq(sdev->request_queue->queue_lock); + return 0; } static void __detach_handler (struct kref *kref) @@ -127,8 +134,14 @@ static void __detach_handler (struct kref *kref) struct scsi_dh_data *scsi_dh_data = container_of(kref, struct scsi_dh_data, kref); struct scsi_device_handler *scsi_dh = scsi_dh_data->scsi_dh; + struct scsi_device *sdev = scsi_dh_data->sdev; + + spin_lock_irq(sdev->request_queue->queue_lock); + sdev->scsi_dh_data = NULL; + spin_unlock_irq(sdev->request_queue->queue_lock); - scsi_dh->detach(scsi_dh_data->sdev); + scsi_dh->detach(sdev); + sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", scsi_dh->name); module_put(scsi_dh->module); } |