summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2015-12-01 10:16:54 +0100
committerMartin K. Petersen <martin.petersen@oracle.com>2015-12-02 22:38:20 +0100
commite2d817db32027c25a1702f667fbf0bf6a73fc68c (patch)
tree0b30835bceaedf3b6b7bb05502fd4be842e12798 /drivers/scsi/device_handler
parentscsi_dh_alua: rework alua_check_tpgs() to return the tpgs mode (diff)
downloadlinux-e2d817db32027c25a1702f667fbf0bf6a73fc68c.tar.xz
linux-e2d817db32027c25a1702f667fbf0bf6a73fc68c.zip
scsi_dh_alua: simplify sense code handling
Most sense code is already handled in the generic code, so we shouldn't be adding special cases here. However, when doing so we need to check for unit attention whenever we're sending an internal command. Signed-off-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Ewan Milne <emilne@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/device_handler')
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c45
1 files changed, 17 insertions, 28 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 7a34ffb41382..39654b1703b3 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -85,7 +85,6 @@ struct alua_dh_data {
#define ALUA_POLICY_SWITCH_ALL 1
static char print_alua_state(int);
-static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
static int realloc_buffer(struct alua_dh_data *h, unsigned len)
{
@@ -189,8 +188,13 @@ static void stpg_endio(struct request *req, int error)
if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
&sense_hdr)) {
- err = alua_check_sense(h->sdev, &sense_hdr);
- if (err == ADD_TO_MLQUEUE) {
+ if (sense_hdr.sense_key == NOT_READY &&
+ sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) {
+ /* ALUA state transition already in progress */
+ err = SCSI_DH_OK;
+ goto done;
+ }
+ if (sense_hdr.sense_key == UNIT_ATTENTION) {
err = SCSI_DH_RETRY;
goto done;
}
@@ -399,28 +403,6 @@ static int alua_check_sense(struct scsi_device *sdev,
* LUN Not Accessible - ALUA state transition
*/
return ADD_TO_MLQUEUE;
- if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b)
- /*
- * LUN Not Accessible -- Target port in standby state
- */
- return SUCCESS;
- if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c)
- /*
- * LUN Not Accessible -- Target port in unavailable state
- */
- return SUCCESS;
- if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x12)
- /*
- * LUN Not Ready -- Offline
- */
- return SUCCESS;
- if (sdev->allow_restart &&
- sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x02)
- /*
- * if the device is not started, we need to wake
- * the error handler to start the motor
- */
- return FAILED;
break;
case UNIT_ATTENTION:
if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
@@ -517,9 +499,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_
h->flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
goto retry;
}
-
- err = alua_check_sense(sdev, &sense_hdr);
- if (err == ADD_TO_MLQUEUE && time_before(jiffies, expiry)) {
+ /*
+ * Retry on ALUA state transition or if any
+ * UNIT ATTENTION occurred.
+ */
+ if (sense_hdr.sense_key == NOT_READY &&
+ sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
+ err = SCSI_DH_RETRY;
+ else if (sense_hdr.sense_key == UNIT_ATTENTION)
+ err = SCSI_DH_RETRY;
+ if (err == SCSI_DH_RETRY && time_before(jiffies, expiry)) {
sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n",
ALUA_DH_NAME);
scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);