summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler/scsi_dh.c
diff options
context:
space:
mode:
authorChristoph Hellwig2014-09-14 20:08:21 +0200
committerChristoph Hellwig2014-11-12 11:19:36 +0100
commit1d5203284d8acbdfdf9b478d434450b34f338f28 (patch)
treed92c80714458eb41581d4ff45c7ffb4e93375e7e /drivers/scsi/device_handler/scsi_dh.c
parentscsi: device handlers must have attach and detach methods (diff)
downloadkernel-qcow2-linux-1d5203284d8acbdfdf9b478d434450b34f338f28.tar.gz
kernel-qcow2-linux-1d5203284d8acbdfdf9b478d434450b34f338f28.tar.xz
kernel-qcow2-linux-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.c29
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);
}