mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-21 00:49:00 +07:00
[SCSI] scsi_dh: Implement match callback function
Some device handler types are not tied to the vendor/model but rather to a specific capability. Eg ALUA is supported if the 'TPGS' setting in the standard inquiry is set. This patch implements a 'match' callback for device handler which supersedes the original vendor/model lookup and implements the callback for the ALUA handler. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
2a9ab40f74
commit
6c3633d08a
@ -59,6 +59,46 @@ static struct scsi_device_handler *get_device_handler_by_idx(int idx)
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -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;
|
||||
@ -327,7 +366,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 +399,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);
|
||||
|
@ -677,23 +677,10 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
|
||||
|
||||
}
|
||||
|
||||
static const struct scsi_dh_devlist alua_dev_list[] = {
|
||||
{"HP", "MSA VOLUME" },
|
||||
{"HP", "HSV101" },
|
||||
{"HP", "HSV111" },
|
||||
{"HP", "HSV200" },
|
||||
{"HP", "HSV210" },
|
||||
{"HP", "HSV300" },
|
||||
{"IBM", "2107900" },
|
||||
{"IBM", "2145" },
|
||||
{"Pillar", "Axiom" },
|
||||
{"Intel", "Multi-Flex"},
|
||||
{"NETAPP", "LUN"},
|
||||
{"NETAPP", "LUN C-Mode"},
|
||||
{"AIX", "NVDISK"},
|
||||
{"Promise", "VTrak"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
static bool alua_match(struct scsi_device *sdev)
|
||||
{
|
||||
return (scsi_device_tpgs(sdev) != 0);
|
||||
}
|
||||
|
||||
static int alua_bus_attach(struct scsi_device *sdev);
|
||||
static void alua_bus_detach(struct scsi_device *sdev);
|
||||
@ -701,12 +688,12 @@ static void alua_bus_detach(struct scsi_device *sdev);
|
||||
static struct scsi_device_handler alua_dh = {
|
||||
.name = ALUA_DH_NAME,
|
||||
.module = THIS_MODULE,
|
||||
.devlist = alua_dev_list,
|
||||
.attach = alua_bus_attach,
|
||||
.detach = alua_bus_detach,
|
||||
.prep_fn = alua_prep_fn,
|
||||
.check_sense = alua_check_sense,
|
||||
.activate = alua_activate,
|
||||
.match = alua_match,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -197,6 +197,7 @@ struct scsi_device_handler {
|
||||
int (*activate)(struct scsi_device *, activate_complete, void *);
|
||||
int (*prep_fn)(struct scsi_device *, struct request *);
|
||||
int (*set_params)(struct scsi_device *, const char *);
|
||||
bool (*match)(struct scsi_device *);
|
||||
};
|
||||
|
||||
struct scsi_dh_data {
|
||||
|
Loading…
Reference in New Issue
Block a user