summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_dh.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-08-27 14:16:58 +0200
committerJames Bottomley <JBottomley@Odin.com>2015-08-28 22:14:56 +0200
commitd95dbff2a41e934cd8789734b34dc591e78ba11c (patch)
treeca293978ae9c923ba143a5c1d00aba07616a8ef1 /drivers/scsi/scsi_dh.c
parentscsi_dh: integrate into the core SCSI code (diff)
downloadlinux-d95dbff2a41e934cd8789734b34dc591e78ba11c.tar.xz
linux-d95dbff2a41e934cd8789734b34dc591e78ba11c.zip
scsi_dh: move device matching to the core code
Add a single list of devices that need non-ALUA device handlers to the core scsi_dh code so that we can autoload the modules for them at probe time. While this is a little ugly in terms of architecture it actually significantly simplifies the code in addition to the new autoloading functionality. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Acked-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/scsi_dh.c')
-rw-r--r--drivers/scsi/scsi_dh.c84
1 files changed, 66 insertions, 18 deletions
diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index f0dfdccc060e..9c153309c96b 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -29,6 +29,67 @@
static DEFINE_SPINLOCK(list_lock);
static LIST_HEAD(scsi_dh_list);
+struct scsi_dh_blist {
+ const char *vendor;
+ const char *model;
+ const char *driver;
+};
+
+static const struct scsi_dh_blist scsi_dh_blist[] = {
+ {"DGC", "RAID", "clariion" },
+ {"DGC", "DISK", "clariion" },
+ {"DGC", "VRAID", "clariion" },
+
+ {"COMPAQ", "MSA1000 VOLUME", "hp_sw" },
+ {"COMPAQ", "HSV110", "hp_sw" },
+ {"HP", "HSV100", "hp_sw"},
+ {"DEC", "HSG80", "hp_sw"},
+
+ {"IBM", "1722", "rdac", },
+ {"IBM", "1724", "rdac", },
+ {"IBM", "1726", "rdac", },
+ {"IBM", "1742", "rdac", },
+ {"IBM", "1745", "rdac", },
+ {"IBM", "1746", "rdac", },
+ {"IBM", "1813", "rdac", },
+ {"IBM", "1814", "rdac", },
+ {"IBM", "1815", "rdac", },
+ {"IBM", "1818", "rdac", },
+ {"IBM", "3526", "rdac", },
+ {"SGI", "TP9", "rdac", },
+ {"SGI", "IS", "rdac", },
+ {"STK", "OPENstorage D280", "rdac", },
+ {"STK", "FLEXLINE 380", "rdac", },
+ {"SUN", "CSM", "rdac", },
+ {"SUN", "LCSM100", "rdac", },
+ {"SUN", "STK6580_6780", "rdac", },
+ {"SUN", "SUN_6180", "rdac", },
+ {"SUN", "ArrayStorage", "rdac", },
+ {"DELL", "MD3", "rdac", },
+ {"NETAPP", "INF-01-00", "rdac", },
+ {"LSI", "INF-01-00", "rdac", },
+ {"ENGENIO", "INF-01-00", "rdac", },
+ {NULL, NULL, NULL },
+};
+
+static const char *
+scsi_dh_find_driver(struct scsi_device *sdev)
+{
+ const struct scsi_dh_blist *b;
+
+ if (scsi_device_tpgs(sdev))
+ return "alua";
+
+ for (b = scsi_dh_blist; b->vendor; b++) {
+ if (!strncmp(sdev->vendor, b->vendor, strlen(b->vendor)) &&
+ !strncmp(sdev->model, b->model, strlen(b->model))) {
+ return b->driver;
+ }
+ }
+ return NULL;
+}
+
+
static struct scsi_device_handler *__scsi_dh_lookup(const char *name)
{
struct scsi_device_handler *tmp, *found = NULL;
@@ -57,22 +118,6 @@ static struct scsi_device_handler *scsi_dh_lookup(const char *name)
return dh;
}
-static struct scsi_device_handler *
-device_handler_match(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;
-}
-
/*
* scsi_dh_handler_attach - Attach a device handler to a device
* @sdev - SCSI device the device handler should attach to
@@ -184,14 +229,17 @@ static struct device_attribute scsi_dh_state_attr =
int scsi_dh_add_device(struct scsi_device *sdev)
{
- struct scsi_device_handler *devinfo;
+ struct scsi_device_handler *devinfo = NULL;
+ const char *drv;
int err;
err = device_create_file(&sdev->sdev_gendev, &scsi_dh_state_attr);
if (err)
return err;
- devinfo = device_handler_match(sdev);
+ drv = scsi_dh_find_driver(sdev);
+ if (drv)
+ devinfo = scsi_dh_lookup(drv);
if (devinfo)
err = scsi_dh_handler_attach(sdev, devinfo);
return err;