aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2011-03-08 02:07:15 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-03-14 19:37:34 -0400
commitc98a0eb0e90d1caa8a92913cd45462102cbd5eaf (patch)
tree2a25be17b0d2806adb00f7c879e86811cc10071a
parent72f7d322fd60ce1a0579136dec7b26b0801ded4b (diff)
[SCSI] sd: Logical Block Provisioning update
SBC3r26 contains many changes to the Logical Block Provisioning interfaces (formerly known as Thin Provisioning ditto). This patch implements support for both the old and new schemes using the same heuristic as before (whether the LBP VPD page is present). The new code also allows the provisioning mode (i.e. choice of command) to be overridden on a per-device basis via sysfs. Two additional modes are supported in this version: - WRITE SAME(10) with the UNMAP bit set - WRITE SAME(10) without the UNMAP bit set. This allows us to support devices that predate the TP/LBP enhancements in SBC3 and which work by way zero-detection Switching between modes has been consolidated in a helper function that also updates the block layer topology according to the limitations of the chosen command. I experimented with trying WRITE SAME(16) if UNMAP fails, WRITE SAME(10) if WRITE SAME(16) fails, etc. but found several devices that got cranky. So for now we'll disable discard if one of the commands fail. The user still has the option of selecting a different mode in sysfs. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/scsi_lib.c7
-rw-r--r--drivers/scsi/sd.c229
-rw-r--r--drivers/scsi/sd.h25
3 files changed, 203 insertions, 58 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index e531acfd98a2..3829bf058aef 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -867,6 +867,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
867 description = "Host Data Integrity Failure"; 867 description = "Host Data Integrity Failure";
868 action = ACTION_FAIL; 868 action = ACTION_FAIL;
869 error = -EILSEQ; 869 error = -EILSEQ;
870 /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
871 } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
872 (cmd->cmnd[0] == UNMAP ||
873 cmd->cmnd[0] == WRITE_SAME_16 ||
874 cmd->cmnd[0] == WRITE_SAME)) {
875 description = "Discard failure";
876 action = ACTION_FAIL;
870 } else 877 } else
871 action = ACTION_FAIL; 878 action = ACTION_FAIL;
872 break; 879 break;
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
99static void sd_config_discard(struct scsi_disk *, unsigned int);
99static int sd_revalidate_disk(struct gendisk *); 100static int sd_revalidate_disk(struct gendisk *);
100static void sd_unlock_native_capacity(struct gendisk *disk); 101static void sd_unlock_native_capacity(struct gendisk *disk);
101static int sd_probe(struct device *); 102static 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
301static 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
310static ssize_t
311sd_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
319static ssize_t
320sd_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
300static struct device_attribute sd_disk_attrs[] = { 348static 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
486static 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
607out:
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 */
2092static void sd_read_block_limits(struct scsi_disk *sdkp) 2208static 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 */
2178static void sd_read_thin_provisioning(struct scsi_disk *sdkp) 2300static 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 }
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index c9d8f6ca49e2..6ad798bfd52a 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -43,6 +43,15 @@ enum {
43 SD_MEMPOOL_SIZE = 2, /* CDB pool size */ 43 SD_MEMPOOL_SIZE = 2, /* CDB pool size */
44}; 44};
45 45
46enum {
47 SD_LBP_FULL = 0, /* Full logical block provisioning */
48 SD_LBP_UNMAP, /* Use UNMAP command */
49 SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */
50 SD_LBP_WS10, /* Use WRITE SAME(10) with UNMAP bit */
51 SD_LBP_ZERO, /* Use WRITE SAME(10) with zero payload */
52 SD_LBP_DISABLE, /* Discard disabled due to failed cmd */
53};
54
46struct scsi_disk { 55struct scsi_disk {
47 struct scsi_driver *driver; /* always &sd_template */ 56 struct scsi_driver *driver; /* always &sd_template */
48 struct scsi_device *device; 57 struct scsi_device *device;
@@ -50,21 +59,27 @@ struct scsi_disk {
50 struct gendisk *disk; 59 struct gendisk *disk;
51 atomic_t openers; 60 atomic_t openers;
52 sector_t capacity; /* size in 512-byte sectors */ 61 sector_t capacity; /* size in 512-byte sectors */
62 u32 max_ws_blocks;
63 u32 max_unmap_blocks;
64 u32 unmap_granularity;
65 u32 unmap_alignment;
53 u32 index; 66 u32 index;
54 unsigned int physical_block_size; 67 unsigned int physical_block_size;
55 u8 media_present; 68 u8 media_present;
56 u8 write_prot; 69 u8 write_prot;
57 u8 protection_type;/* Data Integrity Field */ 70 u8 protection_type;/* Data Integrity Field */
71 u8 provisioning_mode;
58 unsigned ATO : 1; /* state of disk ATO bit */ 72 unsigned ATO : 1; /* state of disk ATO bit */
59 unsigned WCE : 1; /* state of disk WCE bit */ 73 unsigned WCE : 1; /* state of disk WCE bit */
60 unsigned RCD : 1; /* state of disk RCD bit, unused */ 74 unsigned RCD : 1; /* state of disk RCD bit, unused */
61 unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ 75 unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
62 unsigned first_scan : 1; 76 unsigned first_scan : 1;
63 unsigned thin_provisioning : 1; 77 unsigned lbpme : 1;
64 unsigned unmap : 1; 78 unsigned lbprz : 1;
65 unsigned tpws : 1; 79 unsigned lbpu : 1;
66 unsigned tpu : 1; 80 unsigned lbpws : 1;
67 unsigned tpvpd : 1; 81 unsigned lbpws10 : 1;
82 unsigned lbpvpd : 1;
68}; 83};
69#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) 84#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
70 85