diff options
-rw-r--r-- | drivers/scsi/sd.c | 12 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 1 |
2 files changed, 13 insertions, 0 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ffa0689ee84..ff4c9a3aa5b 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 " |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index e8c2433ad8a..85867dcde33 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -149,6 +149,7 @@ struct scsi_device { | |||
149 | unsigned last_sector_bug:1; /* do not use multisector accesses on | 149 | unsigned last_sector_bug:1; /* do not use multisector accesses on |
150 | SD_LAST_BUGGY_SECTORS */ | 150 | SD_LAST_BUGGY_SECTORS */ |
151 | unsigned no_read_disc_info:1; /* Avoid READ_DISC_INFO cmds */ | 151 | unsigned no_read_disc_info:1; /* Avoid READ_DISC_INFO cmds */ |
152 | unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */ | ||
152 | unsigned is_visible:1; /* is the device visible in sysfs */ | 153 | unsigned is_visible:1; /* is the device visible in sysfs */ |
153 | 154 | ||
154 | DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ | 155 | DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ |