diff options
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh.c')
| -rw-r--r-- | drivers/scsi/device_handler/scsi_dh.c | 96 |
1 files changed, 36 insertions, 60 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index 23149b9e297..33e422e7583 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c @@ -28,7 +28,6 @@ static DEFINE_SPINLOCK(list_lock); static LIST_HEAD(scsi_dh_list); -static int scsi_dh_list_idx = 1; static struct scsi_device_handler *get_device_handler(const char *name) { @@ -45,21 +44,6 @@ static struct scsi_device_handler *get_device_handler(const char *name) return found; } -static struct scsi_device_handler *get_device_handler_by_idx(int idx) -{ - struct scsi_device_handler *tmp, *found = NULL; - - spin_lock(&list_lock); - list_for_each_entry(tmp, &scsi_dh_list, list) { - if (tmp->idx == idx) { - found = tmp; - break; - } - } - spin_unlock(&list_lock); - return found; -} - /* * device_handler_match_function - Match a device handler to a device * @sdev - SCSI device to be tested @@ -84,23 +68,6 @@ device_handler_match_function(struct scsi_device *sdev) } /* - * device_handler_match_devlist - Match a device handler to a device - * @sdev - SCSI device to be tested - * - * Tests @sdev against all device_handler registered in the devlist. - * Returns the found device handler or NULL if not found. - */ -static struct scsi_device_handler * -device_handler_match_devlist(struct scsi_device *sdev) -{ - int idx; - - idx = scsi_get_device_flags_keyed(sdev, sdev->vendor, sdev->model, - SCSI_DEVINFO_DH); - return get_device_handler_by_idx(idx); -} - -/* * device_handler_match - Attach a device handler to a device * @scsi_dh - The device handler to match against or NULL * @sdev - SCSI device to be tested against @scsi_dh @@ -116,8 +83,6 @@ device_handler_match(struct scsi_device_handler *scsi_dh, struct scsi_device_handler *found_dh; found_dh = device_handler_match_function(sdev); - if (!found_dh) - found_dh = device_handler_match_devlist(sdev); if (scsi_dh && found_dh != scsi_dh) found_dh = NULL; @@ -361,25 +326,14 @@ static int scsi_dh_notifier_remove(struct device *dev, void *data) */ int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) { - int i; if (get_device_handler(scsi_dh->name)) return -EBUSY; spin_lock(&list_lock); - scsi_dh->idx = scsi_dh_list_idx++; list_add(&scsi_dh->list, &scsi_dh_list); spin_unlock(&list_lock); - for (i = 0; scsi_dh->devlist && scsi_dh->devlist[i].vendor; i++) { - scsi_dev_info_list_add_keyed(0, - scsi_dh->devlist[i].vendor, - scsi_dh->devlist[i].model, - NULL, - scsi_dh->idx, - SCSI_DEVINFO_DH); - } - bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name); @@ -396,7 +350,6 @@ EXPORT_SYMBOL_GPL(scsi_register_device_handler); */ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) { - int i; if (!get_device_handler(scsi_dh->name)) return -ENODEV; @@ -404,12 +357,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_remove); - for (i = 0; scsi_dh->devlist && scsi_dh->devlist[i].vendor; i++) { - scsi_dev_info_list_del_keyed(scsi_dh->devlist[i].vendor, - scsi_dh->devlist[i].model, - SCSI_DEVINFO_DH); - } - spin_lock(&list_lock); list_del(&scsi_dh->list); spin_unlock(&list_lock); @@ -521,7 +468,8 @@ EXPORT_SYMBOL_GPL(scsi_dh_handler_exist); /* * scsi_dh_attach - Attach device handler - * @sdev - sdev the handler should be attached to + * @q - Request queue that is associated with the scsi_device + * the handler should be attached to * @name - name of the handler to attach */ int scsi_dh_attach(struct request_queue *q, const char *name) @@ -551,7 +499,8 @@ EXPORT_SYMBOL_GPL(scsi_dh_attach); /* * scsi_dh_detach - Detach device handler - * @sdev - sdev the handler should be detached from + * @q - Request queue that is associated with the scsi_device + * the handler should be detached from * * This function will detach the device handler only * if the sdev is not part of the internal list, ie @@ -580,6 +529,38 @@ void scsi_dh_detach(struct request_queue *q) } EXPORT_SYMBOL_GPL(scsi_dh_detach); +/* + * scsi_dh_attached_handler_name - Get attached device handler's name + * @q - Request queue that is associated with the scsi_device + * that may have a device handler attached + * @gfp - the GFP mask used in the kmalloc() call when allocating memory + * + * Returns name of attached handler, NULL if no handler is attached. + * Caller must take care to free the returned string. + */ +const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp) +{ + unsigned long flags; + struct scsi_device *sdev; + const char *handler_name = NULL; + + spin_lock_irqsave(q->queue_lock, flags); + sdev = q->queuedata; + if (!sdev || !get_device(&sdev->sdev_gendev)) + sdev = NULL; + spin_unlock_irqrestore(q->queue_lock, flags); + + if (!sdev) + return NULL; + + if (sdev->scsi_dh_data) + handler_name = kstrdup(sdev->scsi_dh_data->scsi_dh->name, gfp); + + put_device(&sdev->sdev_gendev); + return handler_name; +} +EXPORT_SYMBOL_GPL(scsi_dh_attached_handler_name); + static struct notifier_block scsi_dh_nb = { .notifier_call = scsi_dh_notifier }; @@ -588,10 +569,6 @@ static int __init scsi_dh_init(void) { int r; - r = scsi_dev_info_add_list(SCSI_DEVINFO_DH, "SCSI Device Handler"); - if (r) - return r; - r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb); if (!r) @@ -606,7 +583,6 @@ static void __exit scsi_dh_exit(void) bus_for_each_dev(&scsi_bus_type, NULL, NULL, scsi_dh_sysfs_attr_remove); bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb); - scsi_dev_info_remove_list(SCSI_DEVINFO_DH); } module_init(scsi_dh_init); |
