[PATCH] scsi_scan: Continue scan for LUNs in 'unavailable' ALUAstate

From: Hannes Reinecke
Date: Wed Oct 16 2013 - 02:49:15 EST


Some buggy array firmware will terminate the INQUIRY command
when in 'unavailable' ALUA state. This will cause the scan
to be aborted, so devices beyond that LUN will never be
scanned.

While this behaviour is a violation of SPC, we should
nevertheless behave nicely and allow scanning to continue.

Signed-off-by: Hannes Reinecke <hare@xxxxxxx>

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 973a121..ec02f97 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -594,6 +594,16 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
(sshdr.asc == 0x29)) &&
(sshdr.ascq == 0))
continue;
+ /*
+ * Some buggy implementations return
+ * 'target port in unavailable state'
+ * even on INQUIRY.
+ */
+ if ((sshdr.sense_key == NOT_READY) &&
+ (sshdr.asc == 0x04) &&
+ (sshdr.ascq == 0x0c)) {
+ return SCSI_SCAN_TARGET_PRESENT;
+ }
}
} else {
/*
@@ -661,7 +671,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
/* If the last transfer attempt got an error, assume the
* peripheral doesn't exist or is dead. */
if (result)
- return -EIO;
+ return SCSI_SCAN_NO_RESPONSE;

/* Don't report any more data than the device says is valid */
sdev->inquiry_len = min(try_inquiry_len, response_len);
@@ -711,7 +721,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
sdev->scsi_level++;
sdev->sdev_target->scsi_level = sdev->scsi_level;

- return 0;
+ return SCSI_SCAN_LUN_PRESENT;
}

/**
@@ -1046,7 +1056,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
if (!result)
goto out_free_sdev;

- if (scsi_probe_lun(sdev, result, result_len, &bflags))
+ res = scsi_probe_lun(sdev, result, result_len, &bflags);
+ if (res != SCSI_SCAN_LUN_PRESENT)
goto out_free_result;

if (bflagsp)

--------------010300060008020305000903--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/