diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 20:54:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 20:54:40 -0400 |
commit | c55d267de274d308927b60c3e740c1a826832317 (patch) | |
tree | 21b53a8c725d9f9650f60d94b349459d5b8dae10 /drivers/scsi/sd.c | |
parent | 61ef46fd45c3c62dc7c880a45dd2aa841b9af8fb (diff) | |
parent | bc898c97f7ba24def788d9f80786cf028a197122 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (170 commits)
[SCSI] scsi_dh_rdac: Add MD36xxf into device list
[SCSI] scsi_debug: add consecutive medium errors
[SCSI] libsas: fix ata list corruption issue
[SCSI] hpsa: export resettable host attribute
[SCSI] hpsa: move device attributes to avoid forward declarations
[SCSI] scsi_debug: Logical Block Provisioning (SBC3r26)
[SCSI] sd: Logical Block Provisioning update
[SCSI] Include protection operation in SCSI command trace
[SCSI] hpsa: fix incorrect PCI IDs and add two new ones (2nd try)
[SCSI] target: Fix volume size misreporting for volumes > 2TB
[SCSI] bnx2fc: Broadcom FCoE offload driver
[SCSI] fcoe: fix broken fcoe interface reset
[SCSI] fcoe: precedence bug in fcoe_filter_frames()
[SCSI] libfcoe: Remove stale fcoe-netdev entries
[SCSI] libfcoe: Move FCOE_MTU definition from fcoe.h to libfcoe.h
[SCSI] libfc: introduce __fc_fill_fc_hdr that accepts fc_hdr as an argument
[SCSI] fcoe, libfc: initialize EM anchors list and then update npiv EMs
[SCSI] Revert "[SCSI] libfc: fix exchange being deleted when the abort itself is timed out"
[SCSI] libfc: Fixing a memory leak when destroying an interface
[SCSI] megaraid_sas: Version and Changelog update
...
Fix up trivial conflicts due to whitespace differences in
drivers/scsi/libsas/{sas_ata.c,sas_scsi_host.c}
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 229 |
1 files changed, 176 insertions, 53 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e56730214c05..3be5db5d6343 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -96,6 +96,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | |||
96 | #define SD_MINORS 0 | 96 | #define SD_MINORS 0 |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | static void sd_config_discard(struct scsi_disk *, unsigned int); | ||
99 | static int sd_revalidate_disk(struct gendisk *); | 100 | static int sd_revalidate_disk(struct gendisk *); |
100 | static void sd_unlock_native_capacity(struct gendisk *disk); | 101 | static void sd_unlock_native_capacity(struct gendisk *disk); |
101 | static int sd_probe(struct device *); | 102 | static int sd_probe(struct device *); |
@@ -294,7 +295,54 @@ sd_show_thin_provisioning(struct device *dev, struct device_attribute *attr, | |||
294 | { | 295 | { |
295 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 296 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
296 | 297 | ||
297 | return snprintf(buf, 20, "%u\n", sdkp->thin_provisioning); | 298 | return snprintf(buf, 20, "%u\n", sdkp->lbpme); |
299 | } | ||
300 | |||
301 | static const char *lbp_mode[] = { | ||
302 | [SD_LBP_FULL] = "full", | ||
303 | [SD_LBP_UNMAP] = "unmap", | ||
304 | [SD_LBP_WS16] = "writesame_16", | ||
305 | [SD_LBP_WS10] = "writesame_10", | ||
306 | [SD_LBP_ZERO] = "writesame_zero", | ||
307 | [SD_LBP_DISABLE] = "disabled", | ||
308 | }; | ||
309 | |||
310 | static ssize_t | ||
311 | sd_show_provisioning_mode(struct device *dev, struct device_attribute *attr, | ||
312 | char *buf) | ||
313 | { | ||
314 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
315 | |||
316 | return snprintf(buf, 20, "%s\n", lbp_mode[sdkp->provisioning_mode]); | ||
317 | } | ||
318 | |||
319 | static ssize_t | ||
320 | sd_store_provisioning_mode(struct device *dev, struct device_attribute *attr, | ||
321 | const char *buf, size_t count) | ||
322 | { | ||
323 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
324 | struct scsi_device *sdp = sdkp->device; | ||
325 | |||
326 | if (!capable(CAP_SYS_ADMIN)) | ||
327 | return -EACCES; | ||
328 | |||
329 | if (sdp->type != TYPE_DISK) | ||
330 | return -EINVAL; | ||
331 | |||
332 | if (!strncmp(buf, lbp_mode[SD_LBP_UNMAP], 20)) | ||
333 | sd_config_discard(sdkp, SD_LBP_UNMAP); | ||
334 | else if (!strncmp(buf, lbp_mode[SD_LBP_WS16], 20)) | ||
335 | sd_config_discard(sdkp, SD_LBP_WS16); | ||
336 | else if (!strncmp(buf, lbp_mode[SD_LBP_WS10], 20)) | ||
337 | sd_config_discard(sdkp, SD_LBP_WS10); | ||
338 | else if (!strncmp(buf, lbp_mode[SD_LBP_ZERO], 20)) | ||
339 | sd_config_discard(sdkp, SD_LBP_ZERO); | ||
340 | else if (!strncmp(buf, lbp_mode[SD_LBP_DISABLE], 20)) | ||
341 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
342 | else | ||
343 | return -EINVAL; | ||
344 | |||
345 | return count; | ||
298 | } | 346 | } |
299 | 347 | ||
300 | static struct device_attribute sd_disk_attrs[] = { | 348 | static struct device_attribute sd_disk_attrs[] = { |
@@ -309,6 +357,8 @@ static struct device_attribute sd_disk_attrs[] = { | |||
309 | __ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL), | 357 | __ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL), |
310 | __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), | 358 | __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), |
311 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), | 359 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), |
360 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, | ||
361 | sd_store_provisioning_mode), | ||
312 | __ATTR_NULL, | 362 | __ATTR_NULL, |
313 | }; | 363 | }; |
314 | 364 | ||
@@ -433,6 +483,49 @@ static void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif) | |||
433 | scsi_set_prot_type(scmd, dif); | 483 | scsi_set_prot_type(scmd, dif); |
434 | } | 484 | } |
435 | 485 | ||
486 | static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | ||
487 | { | ||
488 | struct request_queue *q = sdkp->disk->queue; | ||
489 | unsigned int logical_block_size = sdkp->device->sector_size; | ||
490 | unsigned int max_blocks = 0; | ||
491 | |||
492 | q->limits.discard_zeroes_data = sdkp->lbprz; | ||
493 | q->limits.discard_alignment = sdkp->unmap_alignment; | ||
494 | q->limits.discard_granularity = | ||
495 | max(sdkp->physical_block_size, | ||
496 | sdkp->unmap_granularity * logical_block_size); | ||
497 | |||
498 | switch (mode) { | ||
499 | |||
500 | case SD_LBP_DISABLE: | ||
501 | q->limits.max_discard_sectors = 0; | ||
502 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | ||
503 | return; | ||
504 | |||
505 | case SD_LBP_UNMAP: | ||
506 | max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); | ||
507 | break; | ||
508 | |||
509 | case SD_LBP_WS16: | ||
510 | max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); | ||
511 | break; | ||
512 | |||
513 | case SD_LBP_WS10: | ||
514 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | ||
515 | break; | ||
516 | |||
517 | case SD_LBP_ZERO: | ||
518 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | ||
519 | q->limits.discard_zeroes_data = 1; | ||
520 | break; | ||
521 | } | ||
522 | |||
523 | q->limits.max_discard_sectors = max_blocks * (logical_block_size >> 9); | ||
524 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | ||
525 | |||
526 | sdkp->provisioning_mode = mode; | ||
527 | } | ||
528 | |||
436 | /** | 529 | /** |
437 | * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device | 530 | * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device |
438 | * @sdp: scsi device to operate one | 531 | * @sdp: scsi device to operate one |
@@ -449,6 +542,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
449 | unsigned int nr_sectors = bio_sectors(bio); | 542 | unsigned int nr_sectors = bio_sectors(bio); |
450 | unsigned int len; | 543 | unsigned int len; |
451 | int ret; | 544 | int ret; |
545 | char *buf; | ||
452 | struct page *page; | 546 | struct page *page; |
453 | 547 | ||
454 | if (sdkp->device->sector_size == 4096) { | 548 | if (sdkp->device->sector_size == 4096) { |
@@ -464,8 +558,9 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
464 | if (!page) | 558 | if (!page) |
465 | return BLKPREP_DEFER; | 559 | return BLKPREP_DEFER; |
466 | 560 | ||
467 | if (sdkp->unmap) { | 561 | switch (sdkp->provisioning_mode) { |
468 | char *buf = page_address(page); | 562 | case SD_LBP_UNMAP: |
563 | buf = page_address(page); | ||
469 | 564 | ||
470 | rq->cmd_len = 10; | 565 | rq->cmd_len = 10; |
471 | rq->cmd[0] = UNMAP; | 566 | rq->cmd[0] = UNMAP; |
@@ -477,7 +572,9 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
477 | put_unaligned_be32(nr_sectors, &buf[16]); | 572 | put_unaligned_be32(nr_sectors, &buf[16]); |
478 | 573 | ||
479 | len = 24; | 574 | len = 24; |
480 | } else { | 575 | break; |
576 | |||
577 | case SD_LBP_WS16: | ||
481 | rq->cmd_len = 16; | 578 | rq->cmd_len = 16; |
482 | rq->cmd[0] = WRITE_SAME_16; | 579 | rq->cmd[0] = WRITE_SAME_16; |
483 | rq->cmd[1] = 0x8; /* UNMAP */ | 580 | rq->cmd[1] = 0x8; /* UNMAP */ |
@@ -485,11 +582,29 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
485 | put_unaligned_be32(nr_sectors, &rq->cmd[10]); | 582 | put_unaligned_be32(nr_sectors, &rq->cmd[10]); |
486 | 583 | ||
487 | len = sdkp->device->sector_size; | 584 | len = sdkp->device->sector_size; |
585 | break; | ||
586 | |||
587 | case SD_LBP_WS10: | ||
588 | case SD_LBP_ZERO: | ||
589 | rq->cmd_len = 10; | ||
590 | rq->cmd[0] = WRITE_SAME; | ||
591 | if (sdkp->provisioning_mode == SD_LBP_WS10) | ||
592 | rq->cmd[1] = 0x8; /* UNMAP */ | ||
593 | put_unaligned_be32(sector, &rq->cmd[2]); | ||
594 | put_unaligned_be16(nr_sectors, &rq->cmd[7]); | ||
595 | |||
596 | len = sdkp->device->sector_size; | ||
597 | break; | ||
598 | |||
599 | default: | ||
600 | goto out; | ||
488 | } | 601 | } |
489 | 602 | ||
490 | blk_add_request_payload(rq, page, len); | 603 | blk_add_request_payload(rq, page, len); |
491 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | 604 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); |
492 | rq->buffer = page_address(page); | 605 | rq->buffer = page_address(page); |
606 | |||
607 | out: | ||
493 | if (ret != BLKPREP_OK) { | 608 | if (ret != BLKPREP_OK) { |
494 | __free_page(page); | 609 | __free_page(page); |
495 | rq->buffer = NULL; | 610 | rq->buffer = NULL; |
@@ -1251,12 +1366,10 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1251 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); | 1366 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); |
1252 | int sense_valid = 0; | 1367 | int sense_valid = 0; |
1253 | int sense_deferred = 0; | 1368 | int sense_deferred = 0; |
1369 | unsigned char op = SCpnt->cmnd[0]; | ||
1254 | 1370 | ||
1255 | if (SCpnt->request->cmd_flags & REQ_DISCARD) { | 1371 | if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) |
1256 | if (!result) | 1372 | scsi_set_resid(SCpnt, 0); |
1257 | scsi_set_resid(SCpnt, 0); | ||
1258 | return good_bytes; | ||
1259 | } | ||
1260 | 1373 | ||
1261 | if (result) { | 1374 | if (result) { |
1262 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); | 1375 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); |
@@ -1295,10 +1408,17 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1295 | SCpnt->result = 0; | 1408 | SCpnt->result = 0; |
1296 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 1409 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
1297 | break; | 1410 | break; |
1298 | case ABORTED_COMMAND: /* DIF: Target detected corruption */ | 1411 | case ABORTED_COMMAND: |
1299 | case ILLEGAL_REQUEST: /* DIX: Host detected corruption */ | 1412 | if (sshdr.asc == 0x10) /* DIF: Target detected corruption */ |
1300 | if (sshdr.asc == 0x10) | 1413 | good_bytes = sd_completed_bytes(SCpnt); |
1414 | break; | ||
1415 | case ILLEGAL_REQUEST: | ||
1416 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ | ||
1301 | good_bytes = sd_completed_bytes(SCpnt); | 1417 | good_bytes = sd_completed_bytes(SCpnt); |
1418 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | ||
1419 | if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | ||
1420 | (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) | ||
1421 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
1302 | break; | 1422 | break; |
1303 | default: | 1423 | default: |
1304 | break; | 1424 | break; |
@@ -1596,17 +1716,13 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1596 | sd_printk(KERN_NOTICE, sdkp, | 1716 | sd_printk(KERN_NOTICE, sdkp, |
1597 | "physical block alignment offset: %u\n", alignment); | 1717 | "physical block alignment offset: %u\n", alignment); |
1598 | 1718 | ||
1599 | if (buffer[14] & 0x80) { /* TPE */ | 1719 | if (buffer[14] & 0x80) { /* LBPME */ |
1600 | struct request_queue *q = sdp->request_queue; | 1720 | sdkp->lbpme = 1; |
1601 | 1721 | ||
1602 | sdkp->thin_provisioning = 1; | 1722 | if (buffer[14] & 0x40) /* LBPRZ */ |
1603 | q->limits.discard_granularity = sdkp->physical_block_size; | 1723 | sdkp->lbprz = 1; |
1604 | q->limits.max_discard_sectors = 0xffffffff; | ||
1605 | 1724 | ||
1606 | if (buffer[14] & 0x40) /* TPRZ */ | 1725 | sd_config_discard(sdkp, SD_LBP_WS16); |
1607 | q->limits.discard_zeroes_data = 1; | ||
1608 | |||
1609 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | ||
1610 | } | 1726 | } |
1611 | 1727 | ||
1612 | sdkp->capacity = lba + 1; | 1728 | sdkp->capacity = lba + 1; |
@@ -2091,7 +2207,6 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2091 | */ | 2207 | */ |
2092 | static void sd_read_block_limits(struct scsi_disk *sdkp) | 2208 | static void sd_read_block_limits(struct scsi_disk *sdkp) |
2093 | { | 2209 | { |
2094 | struct request_queue *q = sdkp->disk->queue; | ||
2095 | unsigned int sector_sz = sdkp->device->sector_size; | 2210 | unsigned int sector_sz = sdkp->device->sector_size; |
2096 | const int vpd_len = 64; | 2211 | const int vpd_len = 64; |
2097 | unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); | 2212 | unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); |
@@ -2106,39 +2221,46 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
2106 | blk_queue_io_opt(sdkp->disk->queue, | 2221 | blk_queue_io_opt(sdkp->disk->queue, |
2107 | get_unaligned_be32(&buffer[12]) * sector_sz); | 2222 | get_unaligned_be32(&buffer[12]) * sector_sz); |
2108 | 2223 | ||
2109 | /* Thin provisioning enabled and page length indicates TP support */ | 2224 | if (buffer[3] == 0x3c) { |
2110 | if (sdkp->thin_provisioning && buffer[3] == 0x3c) { | 2225 | unsigned int lba_count, desc_count; |
2111 | unsigned int lba_count, desc_count, granularity; | ||
2112 | 2226 | ||
2113 | lba_count = get_unaligned_be32(&buffer[20]); | 2227 | sdkp->max_ws_blocks = |
2114 | desc_count = get_unaligned_be32(&buffer[24]); | 2228 | (u32) min_not_zero(get_unaligned_be64(&buffer[36]), |
2115 | 2229 | (u64)0xffffffff); | |
2116 | if (lba_count && desc_count) { | ||
2117 | if (sdkp->tpvpd && !sdkp->tpu) | ||
2118 | sdkp->unmap = 0; | ||
2119 | else | ||
2120 | sdkp->unmap = 1; | ||
2121 | } | ||
2122 | 2230 | ||
2123 | if (sdkp->tpvpd && !sdkp->tpu && !sdkp->tpws) { | 2231 | if (!sdkp->lbpme) |
2124 | sd_printk(KERN_ERR, sdkp, "Thin provisioning is " \ | ||
2125 | "enabled but neither TPU, nor TPWS are " \ | ||
2126 | "set. Disabling discard!\n"); | ||
2127 | goto out; | 2232 | goto out; |
2128 | } | ||
2129 | 2233 | ||
2130 | if (lba_count) | 2234 | lba_count = get_unaligned_be32(&buffer[20]); |
2131 | q->limits.max_discard_sectors = | 2235 | desc_count = get_unaligned_be32(&buffer[24]); |
2132 | lba_count * sector_sz >> 9; | ||
2133 | 2236 | ||
2134 | granularity = get_unaligned_be32(&buffer[28]); | 2237 | if (lba_count && desc_count) |
2238 | sdkp->max_unmap_blocks = lba_count; | ||
2135 | 2239 | ||
2136 | if (granularity) | 2240 | sdkp->unmap_granularity = get_unaligned_be32(&buffer[28]); |
2137 | q->limits.discard_granularity = granularity * sector_sz; | ||
2138 | 2241 | ||
2139 | if (buffer[32] & 0x80) | 2242 | if (buffer[32] & 0x80) |
2140 | q->limits.discard_alignment = | 2243 | sdkp->unmap_alignment = |
2141 | get_unaligned_be32(&buffer[32]) & ~(1 << 31); | 2244 | get_unaligned_be32(&buffer[32]) & ~(1 << 31); |
2245 | |||
2246 | if (!sdkp->lbpvpd) { /* LBP VPD page not provided */ | ||
2247 | |||
2248 | if (sdkp->max_unmap_blocks) | ||
2249 | sd_config_discard(sdkp, SD_LBP_UNMAP); | ||
2250 | else | ||
2251 | sd_config_discard(sdkp, SD_LBP_WS16); | ||
2252 | |||
2253 | } else { /* LBP VPD page tells us what to use */ | ||
2254 | |||
2255 | if (sdkp->lbpu && sdkp->max_unmap_blocks) | ||
2256 | sd_config_discard(sdkp, SD_LBP_UNMAP); | ||
2257 | else if (sdkp->lbpws) | ||
2258 | sd_config_discard(sdkp, SD_LBP_WS16); | ||
2259 | else if (sdkp->lbpws10) | ||
2260 | sd_config_discard(sdkp, SD_LBP_WS10); | ||
2261 | else | ||
2262 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
2263 | } | ||
2142 | } | 2264 | } |
2143 | 2265 | ||
2144 | out: | 2266 | out: |
@@ -2172,15 +2294,15 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) | |||
2172 | } | 2294 | } |
2173 | 2295 | ||
2174 | /** | 2296 | /** |
2175 | * sd_read_thin_provisioning - Query thin provisioning VPD page | 2297 | * sd_read_block_provisioning - Query provisioning VPD page |
2176 | * @disk: disk to query | 2298 | * @disk: disk to query |
2177 | */ | 2299 | */ |
2178 | static void sd_read_thin_provisioning(struct scsi_disk *sdkp) | 2300 | static void sd_read_block_provisioning(struct scsi_disk *sdkp) |
2179 | { | 2301 | { |
2180 | unsigned char *buffer; | 2302 | unsigned char *buffer; |
2181 | const int vpd_len = 8; | 2303 | const int vpd_len = 8; |
2182 | 2304 | ||
2183 | if (sdkp->thin_provisioning == 0) | 2305 | if (sdkp->lbpme == 0) |
2184 | return; | 2306 | return; |
2185 | 2307 | ||
2186 | buffer = kmalloc(vpd_len, GFP_KERNEL); | 2308 | buffer = kmalloc(vpd_len, GFP_KERNEL); |
@@ -2188,9 +2310,10 @@ static void sd_read_thin_provisioning(struct scsi_disk *sdkp) | |||
2188 | if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len)) | 2310 | if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len)) |
2189 | goto out; | 2311 | goto out; |
2190 | 2312 | ||
2191 | sdkp->tpvpd = 1; | 2313 | sdkp->lbpvpd = 1; |
2192 | sdkp->tpu = (buffer[5] >> 7) & 1; /* UNMAP */ | 2314 | sdkp->lbpu = (buffer[5] >> 7) & 1; /* UNMAP */ |
2193 | sdkp->tpws = (buffer[5] >> 6) & 1; /* WRITE SAME(16) with UNMAP */ | 2315 | sdkp->lbpws = (buffer[5] >> 6) & 1; /* WRITE SAME(16) with UNMAP */ |
2316 | sdkp->lbpws10 = (buffer[5] >> 5) & 1; /* WRITE SAME(10) with UNMAP */ | ||
2194 | 2317 | ||
2195 | out: | 2318 | out: |
2196 | kfree(buffer); | 2319 | kfree(buffer); |
@@ -2247,7 +2370,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
2247 | sd_read_capacity(sdkp, buffer); | 2370 | sd_read_capacity(sdkp, buffer); |
2248 | 2371 | ||
2249 | if (sd_try_extended_inquiry(sdp)) { | 2372 | if (sd_try_extended_inquiry(sdp)) { |
2250 | sd_read_thin_provisioning(sdkp); | 2373 | sd_read_block_provisioning(sdkp); |
2251 | sd_read_block_limits(sdkp); | 2374 | sd_read_block_limits(sdkp); |
2252 | sd_read_block_characteristics(sdkp); | 2375 | sd_read_block_characteristics(sdkp); |
2253 | } | 2376 | } |