Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2011-08-24 15:55:47 -0400
committerJeff Mahoney <jeffm@suse.com>2011-08-24 15:55:47 -0400
commit58d80737a3c231efc51005fc9de38cc3fbc42ce9 (patch)
treeb6a68c6a5fc16bf2a5690cfe672d7bb57e6c3df4
parent7d43f4b6a85e98439b57b7f25ce76fe903291f52 (diff)
- scsi_dh_alua: always update TPGS status on activate.
- scsi_dh: Check for sdev state in store_dh_state() (bnc#616080). - scsi_dh_alua: Evaluate TPGS setting from inquiry data. - scsi_dh: Implement match callback function. - Delete patches.fixes/scsi-dh-alua-retry-UA. - Delete patches.fixes/scsi-dh-alua-send-stpg.
-rw-r--r--patches.fixes/scsi-dh-alua-always-update-tpgs-status35
-rw-r--r--patches.fixes/scsi-dh-alua-retry-UA53
-rw-r--r--patches.fixes/scsi-dh-alua-send-stpg33
-rw-r--r--patches.fixes/scsi-dh-check-for-sdev-state-in-store_dh_state32
-rw-r--r--patches.fixes/scsi-evaluate-tpgs-setting120
-rw-r--r--patches.suse/scsi-dh-implement-match-callback166
-rw-r--r--series.conf11
7 files changed, 359 insertions, 91 deletions
diff --git a/patches.fixes/scsi-dh-alua-always-update-tpgs-status b/patches.fixes/scsi-dh-alua-always-update-tpgs-status
new file mode 100644
index 0000000000..b8e27bbe33
--- /dev/null
+++ b/patches.fixes/scsi-dh-alua-always-update-tpgs-status
@@ -0,0 +1,35 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Tue, 23 Aug 2011 11:09:48 +0200
+Subject: scsi_dh_alua: always update TPGS status on activate
+Patch-Mainline: submitted to linux-scsi
+
+When activating a patch we should always update the TPGS state
+as it might have changed in between.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/device_handler/scsi_dh_alua.c | 8 +++-----
+ 1 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index f324d49..916caf9 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -658,11 +658,9 @@ static int alua_activate(struct scsi_device *sdev,
+ struct alua_dh_data *h = get_alua_data(sdev);
+ int err = SCSI_DH_OK;
+
+- if (h->group_id != -1) {
+- err = alua_rtpg(sdev, h);
+- if (err != SCSI_DH_OK)
+- goto out;
+- }
++ err = alua_rtpg(sdev, h);
++ if (err != SCSI_DH_OK)
++ goto out;
+
+ if (h->tpgs & TPGS_MODE_EXPLICIT &&
+ h->state != TPGS_STATE_OPTIMIZED &&
+--
+1.6.0.2
+
diff --git a/patches.fixes/scsi-dh-alua-retry-UA b/patches.fixes/scsi-dh-alua-retry-UA
deleted file mode 100644
index 4d18eb4292..0000000000
--- a/patches.fixes/scsi-dh-alua-retry-UA
+++ /dev/null
@@ -1,53 +0,0 @@
-From: Hannes Reinecke <hare@suse.de>
-Subject: Retry ALUA device handler initialization on Unit Attention
-Patch-mainline: not yet
-
-Whenever we receive a UNIT ATTENTION sense code we should just retry
-the command. No point in checking the various sense codes here.
-
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-
----
- drivers/scsi/device_handler/scsi_dh_alua.c | 31 +++--------------------------
- 1 file changed, 4 insertions(+), 27 deletions(-)
-
---- a/drivers/scsi/device_handler/scsi_dh_alua.c
-+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
-@@ -496,33 +496,10 @@ static int alua_check_sense(struct scsi_
- return SUCCESS;
- break;
- case UNIT_ATTENTION:
-- if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
-- /*
-- * Power On, Reset, or Bus Device Reset, just retry.
-- */
-- return ADD_TO_MLQUEUE;
-- if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
-- /*
-- * ALUA state changed
-- */
-- return ADD_TO_MLQUEUE;
-- }
-- if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
-- /*
-- * Implicit ALUA state transition failed
-- */
-- return ADD_TO_MLQUEUE;
-- }
-- if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x0e) {
-- /*
-- * REPORTED_LUNS_DATA_HAS_CHANGED is reported
-- * when switching controllers on targets like
-- * Intel Multi-Flex. We can just retry.
-- */
-- return ADD_TO_MLQUEUE;
-- }
--
-- break;
-+ /*
-+ * Just retry for UNIT_ATTENTION
-+ */
-+ return ADD_TO_MLQUEUE;
- }
-
- return SCSI_RETURN_NOT_HANDLED;
diff --git a/patches.fixes/scsi-dh-alua-send-stpg b/patches.fixes/scsi-dh-alua-send-stpg
deleted file mode 100644
index 610b225171..0000000000
--- a/patches.fixes/scsi-dh-alua-send-stpg
+++ /dev/null
@@ -1,33 +0,0 @@
-From: Hannes Reinecke <hare@suse.de>
-Subject: Always send STPG for explicit tgps mode
-Patch-mainline: not yet
-
-When we are in explicit tgps mode we should always send an STPG
-command to enable the active/optimized mode.
-
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-
----
- drivers/scsi/device_handler/scsi_dh_alua.c | 11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
-
---- a/drivers/scsi/device_handler/scsi_dh_alua.c
-+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
-@@ -602,13 +602,11 @@ static int alua_activate(struct scsi_dev
- struct alua_dh_data *h = get_alua_data(sdev);
- int err = SCSI_DH_OK;
-
-- if (h->group_id != -1) {
-- err = alua_rtpg(sdev, h);
-- if (err != SCSI_DH_OK)
-- goto out;
-- }
-+ err = alua_rtpg(sdev, h);
-+ if (err != SCSI_DH_OK)
-+ goto out;
-
-- if (h->tpgs & TPGS_MODE_EXPLICIT &&
-+ if ((h->tpgs & TPGS_MODE_EXPLICIT) &&
- h->state != TPGS_STATE_OPTIMIZED &&
- h->state != TPGS_STATE_LBA_DEPENDENT) {
- h->callback_fn = fn;
diff --git a/patches.fixes/scsi-dh-check-for-sdev-state-in-store_dh_state b/patches.fixes/scsi-dh-check-for-sdev-state-in-store_dh_state
new file mode 100644
index 0000000000..9175db5e6b
--- /dev/null
+++ b/patches.fixes/scsi-dh-check-for-sdev-state-in-store_dh_state
@@ -0,0 +1,32 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Tue, 23 Aug 2011 12:12:52 +0200
+Subject: scsi_dh: Check for sdev state in store_dh_state()
+References: bnc#616080
+Patch-Mainline: Submitted to linux-scsi
+
+Avoid attaching a hardware handler to a device which is
+already scheduled for deletion.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/device_handler/scsi_dh.c | 4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
+index 458521d..520bcf0 100644
+--- a/drivers/scsi/device_handler/scsi_dh.c
++++ b/drivers/scsi/device_handler/scsi_dh.c
+@@ -190,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
+--
+1.6.0.2
+
diff --git a/patches.fixes/scsi-evaluate-tpgs-setting b/patches.fixes/scsi-evaluate-tpgs-setting
new file mode 100644
index 0000000000..257aa323e1
--- /dev/null
+++ b/patches.fixes/scsi-evaluate-tpgs-setting
@@ -0,0 +1,120 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Tue, 23 Aug 2011 09:12:47 +0200
+Subject: scsi_dh_alua: Evaluate TPGS setting from inquiry data
+Patch-Mainline: Submitted to linux-scsi
+
+Instead of issuing a standard inquiry from within the
+alua device handler we can evaluate the TPGS setting from
+the existing inquiry data of the sdev and save us the I/O.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+ drivers/scsi/device_handler/scsi_dh_alua.c | 55 +++-------------------------
+ include/scsi/scsi_device.h | 5 +++
+ 2 files changed, 11 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index db2432d..a308747 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -129,43 +129,6 @@ static struct request *get_alua_req(struct scsi_device *sdev,
+ }
+
+ /*
+- * submit_std_inquiry - Issue a standard INQUIRY command
+- * @sdev: sdev the command should be send to
+- */
+-static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
+-{
+- struct request *rq;
+- int err = SCSI_DH_RES_TEMP_UNAVAIL;
+-
+- rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ);
+- if (!rq)
+- goto done;
+-
+- /* Prepare the command. */
+- rq->cmd[0] = INQUIRY;
+- rq->cmd[1] = 0;
+- rq->cmd[2] = 0;
+- rq->cmd[4] = ALUA_INQUIRY_SIZE;
+- rq->cmd_len = COMMAND_SIZE(INQUIRY);
+-
+- rq->sense = h->sense;
+- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+- rq->sense_len = h->senselen = 0;
+-
+- err = blk_execute_rq(rq->q, NULL, rq, 1);
+- if (err == -EIO) {
+- sdev_printk(KERN_INFO, sdev,
+- "%s: std inquiry failed with %x\n",
+- ALUA_DH_NAME, rq->errors);
+- h->senselen = rq->sense_len;
+- err = SCSI_DH_IO;
+- }
+- blk_put_request(rq);
+-done:
+- return err;
+-}
+-
+-/*
+ * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command
+ * @sdev: sdev the command should be sent to
+ */
+@@ -347,23 +310,17 @@ static unsigned submit_stpg(struct alua_dh_data *h)
+ }
+
+ /*
+- * alua_std_inquiry - Evaluate standard INQUIRY command
++ * alua_check_tpgs - Evaluate TPGS setting
+ * @sdev: device to be checked
+ *
+- * Just extract the TPGS setting to find out if ALUA
++ * Examine the TPGS setting of the sdev to find out if ALUA
+ * is supported.
+ */
+-static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
++static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h)
+ {
+- int err;
+-
+- err = submit_std_inquiry(sdev, h);
+-
+- if (err != SCSI_DH_OK)
+- return err;
++ int err = SCSI_DH_OK;
+
+- /* Check TPGS setting */
+- h->tpgs = (h->inq[5] >> 4) & 0x3;
++ h->tpgs = scsi_device_tpgs(sdev);
+ switch (h->tpgs) {
+ case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
+ sdev_printk(KERN_INFO, sdev,
+@@ -669,7 +626,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)
+ {
+ int err;
+
+- err = alua_std_inquiry(sdev, h);
++ err = alua_check_tpgs(sdev, h);
+ if (err != SCSI_DH_OK)
+ goto out;
+
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 94ef83c..b1843da 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -472,6 +472,11 @@ static inline int scsi_device_protection(struct scsi_device *sdev)
+ return sdev->scsi_level > SCSI_2 && sdev->inquiry[5] & (1<<0);
+ }
+
++static inline int scsi_device_tpgs(struct scsi_device *sdev)
++{
++ return sdev->inquiry ? (sdev->inquiry[5] >> 4) & 0x3 : 0;
++}
++
+ #define MODULE_ALIAS_SCSI_DEVICE(type) \
+ MODULE_ALIAS("scsi:t-" __stringify(type) "*")
+ #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x"
+--
+1.6.0.2
+
diff --git a/patches.suse/scsi-dh-implement-match-callback b/patches.suse/scsi-dh-implement-match-callback
new file mode 100644
index 0000000000..38de0d7fcc
--- /dev/null
+++ b/patches.suse/scsi-dh-implement-match-callback
@@ -0,0 +1,166 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Tue, 23 Aug 2011 11:00:43 +0200
+Subject: scsi_dh: Implement match callback function
+Patch-Mainline: Submitted to linux-scsi
+
+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>
+---
+ drivers/scsi/device_handler/scsi_dh.c | 53 ++++++++++++++++++++++++----
+ drivers/scsi/device_handler/scsi_dh_alua.c | 23 +++---------
+ include/scsi/scsi_device.h | 1 +
+ 3 files changed, 52 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
+index a801c59..458521d 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;
+@@ -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);
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index a308747..f324d49 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -704,23 +704,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);
+@@ -728,12 +715,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,
+ };
+
+ /*
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index b1843da..840f8b9 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -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 {
+--
+1.6.0.2
+
diff --git a/series.conf b/series.conf
index cb8c3347d2..5df7bd2cf1 100644
--- a/series.conf
+++ b/series.conf
@@ -337,13 +337,14 @@
patches.fixes/scsi-inquiry-too-short-ratelimit
patches.suse/scsi-netlink-ml
- patches.fixes/scsi-dh-queuedata-accessors
- patches.fixes/scsi-dh-alua-retry-UA
-+needs_update-39 patches.fixes/scsi-add-tgps-setting
- patches.fixes/scsi-dh-alua-send-stpg
- patches.fixes/scsi-dh-rdac-add-stk
patches.fixes/scsi-retry-alua-transition-in-progress
+ patches.fixes/scsi-dh-queuedata-accessors
+ patches.fixes/scsi-evaluate-tpgs-setting
+ patches.suse/scsi-dh-implement-match-callback
+ patches.fixes/scsi-dh-alua-always-update-tpgs-status
+ patches.fixes/scsi-dh-check-for-sdev-state-in-store_dh_state
+
patches.fixes/scsi-check-host-lookup-failure
patches.drivers/megaraid-mbox-fix-SG_IO