diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 16:44:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 16:44:18 -0700 |
commit | ec7ae517537ae5c7b0b2cd7f562dfa3e7a05b954 (patch) | |
tree | e6b0c64a51a7c0aa0efd09d4f7a80872e3b1657a /drivers/scsi/device_handler/scsi_dh.c | |
parent | 97d2eb13a019ec09cc1a7ea2d3705c0b117b3c0d (diff) | |
parent | 590134fa78fbdbe5fea78c7ae0b2c3364bc9572f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (204 commits)
[SCSI] qla4xxx: export address/port of connection (fix udev disk names)
[SCSI] ipr: Fix BUG on adapter dump timeout
[SCSI] megaraid_sas: Fix instance access in megasas_reset_timer
[SCSI] hpsa: change confusing message to be more clear
[SCSI] iscsi class: fix vlan configuration
[SCSI] qla4xxx: fix data alignment and use nl helpers
[SCSI] iscsi class: fix link local mispelling
[SCSI] iscsi class: Replace iscsi_get_next_target_id with IDA
[SCSI] aacraid: use lower snprintf() limit
[SCSI] lpfc 8.3.27: Change driver version to 8.3.27
[SCSI] lpfc 8.3.27: T10 additions for SLI4
[SCSI] lpfc 8.3.27: Fix queue allocation failure recovery
[SCSI] lpfc 8.3.27: Change algorithm for getting physical port name
[SCSI] lpfc 8.3.27: Changed worst case mailbox timeout
[SCSI] lpfc 8.3.27: Miscellanous logic and interface fixes
[SCSI] megaraid_sas: Changelog and version update
[SCSI] megaraid_sas: Add driver workaround for PERC5/1068 kdump kernel panic
[SCSI] megaraid_sas: Add multiple MSI-X vector/multiple reply queue support
[SCSI] megaraid_sas: Add support for MegaRAID 9360/9380 12GB/s controllers
[SCSI] megaraid_sas: Clear FUSION_IN_RESET before enabling interrupts
...
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh.c')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index 0119b814779..7c05fd9dccf 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c @@ -60,6 +60,46 @@ static struct scsi_device_handler *get_device_handler_by_idx(int idx) } /* + * device_handler_match_function - Match a device handler to a device + * @sdev - SCSI device to be tested + * + * Tests @sdev against the match function of all registered device_handler. + * Returns the found device handler or NULL if not found. + */ +static struct scsi_device_handler * +device_handler_match_function(struct scsi_device *sdev) +{ + struct scsi_device_handler *tmp_dh, *found_dh = NULL; + + spin_lock(&list_lock); + list_for_each_entry(tmp_dh, &scsi_dh_list, list) { + if (tmp_dh->match && tmp_dh->match(sdev)) { + found_dh = tmp_dh; + break; + } + } + spin_unlock(&list_lock); + return found_dh; +} + +/* + * 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 @@ -72,12 +112,11 @@ static struct scsi_device_handler * device_handler_match(struct scsi_device_handler *scsi_dh, struct scsi_device *sdev) { - struct scsi_device_handler *found_dh = NULL; - int idx; + struct scsi_device_handler *found_dh; - idx = scsi_get_device_flags_keyed(sdev, sdev->vendor, sdev->model, - SCSI_DEVINFO_DH); - found_dh = get_device_handler_by_idx(idx); + 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; @@ -151,6 +190,10 @@ store_dh_state(struct device *dev, struct device_attribute *attr, struct scsi_device_handler *scsi_dh; int err = -EINVAL; + if (sdev->sdev_state == SDEV_CANCEL || + sdev->sdev_state == SDEV_DEL) + return -ENODEV; + if (!sdev->scsi_dh_data) { /* * Attach to a device handler @@ -327,7 +370,7 @@ int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) list_add(&scsi_dh->list, &scsi_dh_list); spin_unlock(&list_lock); - for (i = 0; scsi_dh->devlist[i].vendor; i++) { + 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, @@ -360,7 +403,7 @@ 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[i].vendor; i++) { + 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); @@ -468,7 +511,7 @@ int scsi_dh_handler_exist(const char *name) EXPORT_SYMBOL_GPL(scsi_dh_handler_exist); /* - * scsi_dh_handler_attach - Attach device handler + * scsi_dh_attach - Attach device handler * @sdev - sdev the handler should be attached to * @name - name of the handler to attach */ @@ -498,7 +541,7 @@ int scsi_dh_attach(struct request_queue *q, const char *name) EXPORT_SYMBOL_GPL(scsi_dh_attach); /* - * scsi_dh_handler_detach - Detach device handler + * scsi_dh_detach - Detach device handler * @sdev - sdev the handler should be detached from * * This function will detach the device handler only |