From f87146bba523cad0196aa8e80ca9e8243d7a6c0c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 29 Mar 2010 09:29:24 +0200 Subject: [SCSI] sd: quiet spurious error messages in READ_CAPACITY(16) sd always tries to submit a READ_CAPACITY(16) CDB, regardless whether the host actually supports it. queuecommand() will then return DID_ABORT, which is not qualified enough to detect the true cause here. So better check in sd_try_rc16 first if the cdblen is supported. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 58c62ff42ab3..7955bc226125 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1573,6 +1573,8 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, static int sd_try_rc16_first(struct scsi_device *sdp) { + if (sdp->host->max_cmd_len < 16) + return 0; if (sdp->scsi_level > SCSI_SPC_2) return 1; if (scsi_device_protection(sdp)) -- cgit v1.2.3 From 3233ac19811fe17033b537832ca7b59df8bf4aa9 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 1 Apr 2010 10:30:01 -0400 Subject: [SCSI] sd: retry read_capacity on UNIT_ATTENTION Hazard testing uncovered yet another bug in sd. Under heavy reset activity the retry counter might be exhausted and the command will be returned with sense UNIT_ATTENTION/0x29/00 (POWER ON, RESET, OR BUS DEVICE RESET OCCURRED). In those cases we should just increase the retry counter again, retrying one more to clear up this Unit Attention state. [jejb: update to work with RC16 devices and not to loop endlessly] Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 7955bc226125..015a597a852e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1433,6 +1433,8 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, #error RC16_LEN must not be more than SD_BUF_SIZE #endif +#define READ_CAPACITY_RETRIES_ON_RESET 10 + static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, unsigned char *buffer) { @@ -1440,7 +1442,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, struct scsi_sense_hdr sshdr; int sense_valid = 0; int the_result; - int retries = 3; + int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET; unsigned int alignment; unsigned long long lba; unsigned sector_size; @@ -1469,6 +1471,13 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, * Invalid Field in CDB, just retry * silently with RC10 */ return -EINVAL; + if (sense_valid && + sshdr.sense_key == UNIT_ATTENTION && + sshdr.asc == 0x29 && sshdr.ascq == 0x00) + /* Device reset might occur several times, + * give it one more chance */ + if (--reset_retries > 0) + continue; } retries--; @@ -1527,7 +1536,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, struct scsi_sense_hdr sshdr; int sense_valid = 0; int the_result; - int retries = 3; + int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET; sector_t lba; unsigned sector_size; @@ -1543,8 +1552,16 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, if (media_not_present(sdkp, &sshdr)) return -ENODEV; - if (the_result) + if (the_result) { sense_valid = scsi_sense_valid(&sshdr); + if (sense_valid && + sshdr.sense_key == UNIT_ATTENTION && + sshdr.asc == 0x29 && sshdr.ascq == 0x00) + /* Device reset might occur several times, + * give it one more chance */ + if (--reset_retries > 0) + continue; + } retries--; } while (the_result && retries); -- cgit v1.2.3