diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/sd.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ffa0689ee840..ff4c9a3aa5b2 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1498,6 +1498,9 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1498 | unsigned long long lba; | 1498 | unsigned long long lba; |
1499 | unsigned sector_size; | 1499 | unsigned sector_size; |
1500 | 1500 | ||
1501 | if (sdp->no_read_capacity_16) | ||
1502 | return -EINVAL; | ||
1503 | |||
1501 | do { | 1504 | do { |
1502 | memset(cmd, 0, 16); | 1505 | memset(cmd, 0, 16); |
1503 | cmd[0] = SERVICE_ACTION_IN; | 1506 | cmd[0] = SERVICE_ACTION_IN; |
@@ -1626,6 +1629,15 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1626 | sector_size = get_unaligned_be32(&buffer[4]); | 1629 | sector_size = get_unaligned_be32(&buffer[4]); |
1627 | lba = get_unaligned_be32(&buffer[0]); | 1630 | lba = get_unaligned_be32(&buffer[0]); |
1628 | 1631 | ||
1632 | if (sdp->no_read_capacity_16 && (lba == 0xffffffff)) { | ||
1633 | /* Some buggy (usb cardreader) devices return an lba of | ||
1634 | 0xffffffff when the want to report a size of 0 (with | ||
1635 | which they really mean no media is present) */ | ||
1636 | sdkp->capacity = 0; | ||
1637 | sdkp->hw_sector_size = sector_size; | ||
1638 | return sector_size; | ||
1639 | } | ||
1640 | |||
1629 | if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) { | 1641 | if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) { |
1630 | sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " | 1642 | sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " |
1631 | "kernel compiled with support for large block " | 1643 | "kernel compiled with support for large block " |