diff --git a/[refs] b/[refs] index f8678d3567c9..749341005af0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1469585309bb52869cbaa449c6d2cd1ce9869cca +refs/heads/master: 3233ac19811fe17033b537832ca7b59df8bf4aa9 diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 7955bc226125..015a597a852e 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/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);