|
@@ -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);
|