diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 167 |
1 files changed, 141 insertions, 26 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9093c7261f33..de6c60320f6f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
50 | #include <linux/string_helpers.h> | 50 | #include <linux/string_helpers.h> |
51 | #include <linux/async.h> | 51 | #include <linux/async.h> |
52 | #include <linux/slab.h> | ||
52 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
53 | #include <asm/unaligned.h> | 54 | #include <asm/unaligned.h> |
54 | 55 | ||
@@ -264,6 +265,15 @@ sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, | |||
264 | return snprintf(buf, 20, "%u\n", sdkp->ATO); | 265 | return snprintf(buf, 20, "%u\n", sdkp->ATO); |
265 | } | 266 | } |
266 | 267 | ||
268 | static ssize_t | ||
269 | sd_show_thin_provisioning(struct device *dev, struct device_attribute *attr, | ||
270 | char *buf) | ||
271 | { | ||
272 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
273 | |||
274 | return snprintf(buf, 20, "%u\n", sdkp->thin_provisioning); | ||
275 | } | ||
276 | |||
267 | static struct device_attribute sd_disk_attrs[] = { | 277 | static struct device_attribute sd_disk_attrs[] = { |
268 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 278 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
269 | sd_store_cache_type), | 279 | sd_store_cache_type), |
@@ -274,6 +284,7 @@ static struct device_attribute sd_disk_attrs[] = { | |||
274 | sd_store_manage_start_stop), | 284 | sd_store_manage_start_stop), |
275 | __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), | 285 | __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), |
276 | __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), | 286 | __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), |
287 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), | ||
277 | __ATTR_NULL, | 288 | __ATTR_NULL, |
278 | }; | 289 | }; |
279 | 290 | ||
@@ -399,6 +410,57 @@ static void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif) | |||
399 | } | 410 | } |
400 | 411 | ||
401 | /** | 412 | /** |
413 | * sd_prepare_discard - unmap blocks on thinly provisioned device | ||
414 | * @rq: Request to prepare | ||
415 | * | ||
416 | * Will issue either UNMAP or WRITE SAME(16) depending on preference | ||
417 | * indicated by target device. | ||
418 | **/ | ||
419 | static int sd_prepare_discard(struct request *rq) | ||
420 | { | ||
421 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | ||
422 | struct bio *bio = rq->bio; | ||
423 | sector_t sector = bio->bi_sector; | ||
424 | unsigned int num = bio_sectors(bio); | ||
425 | |||
426 | if (sdkp->device->sector_size == 4096) { | ||
427 | sector >>= 3; | ||
428 | num >>= 3; | ||
429 | } | ||
430 | |||
431 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | ||
432 | rq->timeout = SD_TIMEOUT; | ||
433 | |||
434 | memset(rq->cmd, 0, rq->cmd_len); | ||
435 | |||
436 | if (sdkp->unmap) { | ||
437 | char *buf = kmap_atomic(bio_page(bio), KM_USER0); | ||
438 | |||
439 | rq->cmd[0] = UNMAP; | ||
440 | rq->cmd[8] = 24; | ||
441 | rq->cmd_len = 10; | ||
442 | |||
443 | /* Ensure that data length matches payload */ | ||
444 | rq->__data_len = bio->bi_size = bio->bi_io_vec->bv_len = 24; | ||
445 | |||
446 | put_unaligned_be16(6 + 16, &buf[0]); | ||
447 | put_unaligned_be16(16, &buf[2]); | ||
448 | put_unaligned_be64(sector, &buf[8]); | ||
449 | put_unaligned_be32(num, &buf[16]); | ||
450 | |||
451 | kunmap_atomic(buf, KM_USER0); | ||
452 | } else { | ||
453 | rq->cmd[0] = WRITE_SAME_16; | ||
454 | rq->cmd[1] = 0x8; /* UNMAP */ | ||
455 | put_unaligned_be64(sector, &rq->cmd[2]); | ||
456 | put_unaligned_be32(num, &rq->cmd[10]); | ||
457 | rq->cmd_len = 16; | ||
458 | } | ||
459 | |||
460 | return BLKPREP_OK; | ||
461 | } | ||
462 | |||
463 | /** | ||
402 | * sd_init_command - build a scsi (read or write) command from | 464 | * sd_init_command - build a scsi (read or write) command from |
403 | * information in the request structure. | 465 | * information in the request structure. |
404 | * @SCpnt: pointer to mid-level's per scsi command structure that | 466 | * @SCpnt: pointer to mid-level's per scsi command structure that |
@@ -418,6 +480,13 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
418 | int ret, host_dif; | 480 | int ret, host_dif; |
419 | unsigned char protect; | 481 | unsigned char protect; |
420 | 482 | ||
483 | /* | ||
484 | * Discard request come in as REQ_TYPE_FS but we turn them into | ||
485 | * block PC requests to make life easier. | ||
486 | */ | ||
487 | if (blk_discard_rq(rq)) | ||
488 | ret = sd_prepare_discard(rq); | ||
489 | |||
421 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | 490 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { |
422 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | 491 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); |
423 | goto out; | 492 | goto out; |
@@ -971,6 +1040,7 @@ static void sd_prepare_flush(struct request_queue *q, struct request *rq) | |||
971 | { | 1040 | { |
972 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 1041 | rq->cmd_type = REQ_TYPE_BLOCK_PC; |
973 | rq->timeout = SD_TIMEOUT; | 1042 | rq->timeout = SD_TIMEOUT; |
1043 | rq->retries = SD_MAX_RETRIES; | ||
974 | rq->cmd[0] = SYNCHRONIZE_CACHE; | 1044 | rq->cmd[0] = SYNCHRONIZE_CACHE; |
975 | rq->cmd_len = 10; | 1045 | rq->cmd_len = 10; |
976 | } | 1046 | } |
@@ -1128,19 +1198,10 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1128 | SCpnt->result = 0; | 1198 | SCpnt->result = 0; |
1129 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 1199 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
1130 | break; | 1200 | break; |
1131 | case ABORTED_COMMAND: | 1201 | case ABORTED_COMMAND: /* DIF: Target detected corruption */ |
1132 | if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ | 1202 | case ILLEGAL_REQUEST: /* DIX: Host detected corruption */ |
1133 | scsi_print_result(SCpnt); | 1203 | if (sshdr.asc == 0x10) |
1134 | scsi_print_sense("sd", SCpnt); | ||
1135 | good_bytes = sd_completed_bytes(SCpnt); | 1204 | good_bytes = sd_completed_bytes(SCpnt); |
1136 | } | ||
1137 | break; | ||
1138 | case ILLEGAL_REQUEST: | ||
1139 | if (sshdr.asc == 0x10) { /* DIX: HBA detected corruption */ | ||
1140 | scsi_print_result(SCpnt); | ||
1141 | scsi_print_sense("sd", SCpnt); | ||
1142 | good_bytes = sd_completed_bytes(SCpnt); | ||
1143 | } | ||
1144 | break; | 1205 | break; |
1145 | default: | 1206 | default: |
1146 | break; | 1207 | break; |
@@ -1150,8 +1211,19 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1150 | sd_dif_complete(SCpnt, good_bytes); | 1211 | sd_dif_complete(SCpnt, good_bytes); |
1151 | 1212 | ||
1152 | if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) | 1213 | if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) |
1153 | == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) | 1214 | == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) { |
1215 | |||
1216 | /* We have to print a failed command here as the | ||
1217 | * extended CDB gets freed before scsi_io_completion() | ||
1218 | * is called. | ||
1219 | */ | ||
1220 | if (result) | ||
1221 | scsi_print_command(SCpnt); | ||
1222 | |||
1154 | mempool_free(SCpnt->cmnd, sd_cdb_pool); | 1223 | mempool_free(SCpnt->cmnd, sd_cdb_pool); |
1224 | SCpnt->cmnd = NULL; | ||
1225 | SCpnt->cmd_len = 0; | ||
1226 | } | ||
1155 | 1227 | ||
1156 | return good_bytes; | 1228 | return good_bytes; |
1157 | } | 1229 | } |
@@ -1432,6 +1504,19 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1432 | sd_printk(KERN_NOTICE, sdkp, | 1504 | sd_printk(KERN_NOTICE, sdkp, |
1433 | "physical block alignment offset: %u\n", alignment); | 1505 | "physical block alignment offset: %u\n", alignment); |
1434 | 1506 | ||
1507 | if (buffer[14] & 0x80) { /* TPE */ | ||
1508 | struct request_queue *q = sdp->request_queue; | ||
1509 | |||
1510 | sdkp->thin_provisioning = 1; | ||
1511 | q->limits.discard_granularity = sdkp->hw_sector_size; | ||
1512 | q->limits.max_discard_sectors = 0xffffffff; | ||
1513 | |||
1514 | if (buffer[14] & 0x40) /* TPRZ */ | ||
1515 | q->limits.discard_zeroes_data = 1; | ||
1516 | |||
1517 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | ||
1518 | } | ||
1519 | |||
1435 | sdkp->capacity = lba + 1; | 1520 | sdkp->capacity = lba + 1; |
1436 | return sector_size; | 1521 | return sector_size; |
1437 | } | 1522 | } |
@@ -1863,20 +1948,47 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) | |||
1863 | */ | 1948 | */ |
1864 | static void sd_read_block_limits(struct scsi_disk *sdkp) | 1949 | static void sd_read_block_limits(struct scsi_disk *sdkp) |
1865 | { | 1950 | { |
1951 | struct request_queue *q = sdkp->disk->queue; | ||
1866 | unsigned int sector_sz = sdkp->device->sector_size; | 1952 | unsigned int sector_sz = sdkp->device->sector_size; |
1867 | char *buffer; | 1953 | const int vpd_len = 64; |
1954 | unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); | ||
1868 | 1955 | ||
1869 | /* Block Limits VPD */ | 1956 | if (!buffer || |
1870 | buffer = scsi_get_vpd_page(sdkp->device, 0xb0); | 1957 | /* Block Limits VPD */ |
1871 | 1958 | scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len)) | |
1872 | if (buffer == NULL) | 1959 | goto out; |
1873 | return; | ||
1874 | 1960 | ||
1875 | blk_queue_io_min(sdkp->disk->queue, | 1961 | blk_queue_io_min(sdkp->disk->queue, |
1876 | get_unaligned_be16(&buffer[6]) * sector_sz); | 1962 | get_unaligned_be16(&buffer[6]) * sector_sz); |
1877 | blk_queue_io_opt(sdkp->disk->queue, | 1963 | blk_queue_io_opt(sdkp->disk->queue, |
1878 | get_unaligned_be32(&buffer[12]) * sector_sz); | 1964 | get_unaligned_be32(&buffer[12]) * sector_sz); |
1879 | 1965 | ||
1966 | /* Thin provisioning enabled and page length indicates TP support */ | ||
1967 | if (sdkp->thin_provisioning && buffer[3] == 0x3c) { | ||
1968 | unsigned int lba_count, desc_count, granularity; | ||
1969 | |||
1970 | lba_count = get_unaligned_be32(&buffer[20]); | ||
1971 | desc_count = get_unaligned_be32(&buffer[24]); | ||
1972 | |||
1973 | if (lba_count) { | ||
1974 | q->limits.max_discard_sectors = | ||
1975 | lba_count * sector_sz >> 9; | ||
1976 | |||
1977 | if (desc_count) | ||
1978 | sdkp->unmap = 1; | ||
1979 | } | ||
1980 | |||
1981 | granularity = get_unaligned_be32(&buffer[28]); | ||
1982 | |||
1983 | if (granularity) | ||
1984 | q->limits.discard_granularity = granularity * sector_sz; | ||
1985 | |||
1986 | if (buffer[32] & 0x80) | ||
1987 | q->limits.discard_alignment = | ||
1988 | get_unaligned_be32(&buffer[32]) & ~(1 << 31); | ||
1989 | } | ||
1990 | |||
1991 | out: | ||
1880 | kfree(buffer); | 1992 | kfree(buffer); |
1881 | } | 1993 | } |
1882 | 1994 | ||
@@ -1886,20 +1998,23 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
1886 | */ | 1998 | */ |
1887 | static void sd_read_block_characteristics(struct scsi_disk *sdkp) | 1999 | static void sd_read_block_characteristics(struct scsi_disk *sdkp) |
1888 | { | 2000 | { |
1889 | char *buffer; | 2001 | unsigned char *buffer; |
1890 | u16 rot; | 2002 | u16 rot; |
2003 | const int vpd_len = 64; | ||
1891 | 2004 | ||
1892 | /* Block Device Characteristics VPD */ | 2005 | buffer = kmalloc(vpd_len, GFP_KERNEL); |
1893 | buffer = scsi_get_vpd_page(sdkp->device, 0xb1); | ||
1894 | 2006 | ||
1895 | if (buffer == NULL) | 2007 | if (!buffer || |
1896 | return; | 2008 | /* Block Device Characteristics VPD */ |
2009 | scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len)) | ||
2010 | goto out; | ||
1897 | 2011 | ||
1898 | rot = get_unaligned_be16(&buffer[4]); | 2012 | rot = get_unaligned_be16(&buffer[4]); |
1899 | 2013 | ||
1900 | if (rot == 1) | 2014 | if (rot == 1) |
1901 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue); | 2015 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue); |
1902 | 2016 | ||
2017 | out: | ||
1903 | kfree(buffer); | 2018 | kfree(buffer); |
1904 | } | 2019 | } |
1905 | 2020 | ||
@@ -1998,7 +2113,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1998 | * which is followed by sdaaa. | 2113 | * which is followed by sdaaa. |
1999 | * | 2114 | * |
2000 | * This is basically 26 base counting with one extra 'nil' entry | 2115 | * This is basically 26 base counting with one extra 'nil' entry |
2001 | * at the beggining from the second digit on and can be | 2116 | * at the beginning from the second digit on and can be |
2002 | * determined using similar method as 26 base conversion with the | 2117 | * determined using similar method as 26 base conversion with the |
2003 | * index shifted -1 after each digit is computed. | 2118 | * index shifted -1 after each digit is computed. |
2004 | * | 2119 | * |
@@ -2072,7 +2187,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
2072 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); | 2187 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); |
2073 | 2188 | ||
2074 | gd->driverfs_dev = &sdp->sdev_gendev; | 2189 | gd->driverfs_dev = &sdp->sdev_gendev; |
2075 | gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS; | 2190 | gd->flags = GENHD_FL_EXT_DEVT; |
2076 | if (sdp->removable) | 2191 | if (sdp->removable) |
2077 | gd->flags |= GENHD_FL_REMOVABLE; | 2192 | gd->flags |= GENHD_FL_REMOVABLE; |
2078 | 2193 | ||