aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sd.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index dcff84abcdee..8eebaa8c6f52 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1329,8 +1329,17 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
1329 if (media_not_present(sdkp, &sshdr)) 1329 if (media_not_present(sdkp, &sshdr))
1330 return -ENODEV; 1330 return -ENODEV;
1331 1331
1332 if (the_result) 1332 if (the_result) {
1333 sense_valid = scsi_sense_valid(&sshdr); 1333 sense_valid = scsi_sense_valid(&sshdr);
1334 if (sense_valid &&
1335 sshdr.sense_key == ILLEGAL_REQUEST &&
1336 (sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
1337 sshdr.ascq == 0x00)
1338 /* Invalid Command Operation Code or
1339 * Invalid Field in CDB, just retry
1340 * silently with RC10 */
1341 return -EINVAL;
1342 }
1334 retries--; 1343 retries--;
1335 1344
1336 } while (the_result && retries); 1345 } while (the_result && retries);
@@ -1414,6 +1423,15 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
1414 return sector_size; 1423 return sector_size;
1415} 1424}
1416 1425
1426static int sd_try_rc16_first(struct scsi_device *sdp)
1427{
1428 if (sdp->scsi_level > SCSI_SPC_2)
1429 return 1;
1430 if (scsi_device_protection(sdp))
1431 return 1;
1432 return 0;
1433}
1434
1417/* 1435/*
1418 * read disk capacity 1436 * read disk capacity
1419 */ 1437 */
@@ -1423,11 +1441,14 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
1423 int sector_size; 1441 int sector_size;
1424 struct scsi_device *sdp = sdkp->device; 1442 struct scsi_device *sdp = sdkp->device;
1425 1443
1426 /* Force READ CAPACITY(16) when PROTECT=1 */ 1444 if (sd_try_rc16_first(sdp)) {
1427 if (scsi_device_protection(sdp)) {
1428 sector_size = read_capacity_16(sdkp, sdp, buffer); 1445 sector_size = read_capacity_16(sdkp, sdp, buffer);
1429 if (sector_size == -EOVERFLOW) 1446 if (sector_size == -EOVERFLOW)
1430 goto got_data; 1447 goto got_data;
1448 if (sector_size == -ENODEV)
1449 return;
1450 if (sector_size < 0)
1451 sector_size = read_capacity_10(sdkp, sdp, buffer);
1431 if (sector_size < 0) 1452 if (sector_size < 0)
1432 return; 1453 return;
1433 } else { 1454 } else {