diff options
| author | Martin K. Petersen <martin.petersen@oracle.com> | 2012-09-18 12:19:32 -0400 |
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2012-11-14 01:45:42 -0500 |
| commit | 5db44863b6ebbb400c5e61d56ebe8f21ef48b1bd (patch) | |
| tree | a352bab202b6cb40f234bd2fd306b54776543e8b /drivers | |
| parent | 26e85fcd15f68b57d9ba645cd3591117a8ac0e05 (diff) | |
[SCSI] sd: Implement support for WRITE SAME
Implement support for WRITE SAME(10) and WRITE SAME(16) in the SCSI disk
driver.
- We set the default maximum to 0xFFFF because there are several
devices out there that only support two-byte block counts even with
WRITE SAME(16). We only enable transfers bigger than 0xFFFF if the
device explicitly reports MAXIMUM WRITE SAME LENGTH in the BLOCK
LIMITS VPD.
- max_write_same_blocks can be overriden per-device basis in sysfs.
- The UNMAP discovery heuristics remain unchanged but the discard
limits are tweaked to match the "real" WRITE SAME commands.
- In the error handling logic we now distinguish between WRITE SAME
with and without UNMAP set.
The discovery process heuristics are:
- If the device reports a SCSI level of SPC-3 or greater we'll issue
READ SUPPORTED OPERATION CODES to find out whether WRITE SAME(16) is
supported. If that's the case we will use it.
- If the device supports the block limits VPD and reports a MAXIMUM
WRITE SAME LENGTH bigger than 0xFFFF we will use WRITE SAME(16).
- Otherwise we will use WRITE SAME(10) unless the target LBA is beyond
0xFFFFFFFF or the block count exceeds 0xFFFF.
- no_write_same is set for ATA, FireWire and USB.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Mike Snitzer <snitzer@redhat.com>
Reviewed-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ata/libata-scsi.c | 1 | ||||
| -rw-r--r-- | drivers/firewire/sbp2.c | 1 | ||||
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 22 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 172 | ||||
| -rw-r--r-- | drivers/scsi/sd.h | 7 | ||||
| -rw-r--r-- | drivers/usb/storage/scsiglue.c | 3 |
6 files changed, 190 insertions, 16 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7c2dead60518..a6df6a351d6e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -1053,6 +1053,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) | |||
| 1053 | sdev->use_10_for_rw = 1; | 1053 | sdev->use_10_for_rw = 1; |
| 1054 | sdev->use_10_for_ms = 1; | 1054 | sdev->use_10_for_ms = 1; |
| 1055 | sdev->no_report_opcodes = 1; | 1055 | sdev->no_report_opcodes = 1; |
| 1056 | sdev->no_write_same = 1; | ||
| 1056 | 1057 | ||
| 1057 | /* Schedule policy is determined by ->qc_defer() callback and | 1058 | /* Schedule policy is determined by ->qc_defer() callback and |
| 1058 | * it needs to see every deferred qc. Set dev_blocked to 1 to | 1059 | * it needs to see every deferred qc. Set dev_blocked to 1 to |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index f82e9d4295d0..bb1b392f5cda 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
| @@ -1547,6 +1547,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) | |||
| 1547 | 1547 | ||
| 1548 | sdev->use_10_for_rw = 1; | 1548 | sdev->use_10_for_rw = 1; |
| 1549 | sdev->no_report_opcodes = 1; | 1549 | sdev->no_report_opcodes = 1; |
| 1550 | sdev->no_write_same = 1; | ||
| 1550 | 1551 | ||
| 1551 | if (sbp2_param_exclusive_login) | 1552 | if (sbp2_param_exclusive_login) |
| 1552 | sdev->manage_start_stop = 1; | 1553 | sdev->manage_start_stop = 1; |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index da36a3a81a9e..9032e910bca3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
| 900 | action = ACTION_FAIL; | 900 | action = ACTION_FAIL; |
| 901 | error = -EILSEQ; | 901 | error = -EILSEQ; |
| 902 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | 902 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
| 903 | } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | 903 | } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
| 904 | (cmd->cmnd[0] == UNMAP || | 904 | switch (cmd->cmnd[0]) { |
| 905 | cmd->cmnd[0] == WRITE_SAME_16 || | 905 | case UNMAP: |
| 906 | cmd->cmnd[0] == WRITE_SAME)) { | 906 | description = "Discard failure"; |
| 907 | description = "Discard failure"; | 907 | break; |
| 908 | case WRITE_SAME: | ||
| 909 | case WRITE_SAME_16: | ||
| 910 | if (cmd->cmnd[1] & 0x8) | ||
| 911 | description = "Discard failure"; | ||
| 912 | else | ||
| 913 | description = | ||
| 914 | "Write same failure"; | ||
| 915 | break; | ||
| 916 | default: | ||
| 917 | description = "Invalid command failure"; | ||
| 918 | break; | ||
| 919 | } | ||
| 908 | action = ACTION_FAIL; | 920 | action = ACTION_FAIL; |
| 909 | error = -EREMOTEIO; | 921 | error = -EREMOTEIO; |
| 910 | } else | 922 | } else |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c6af4c1a9ca3..352bc77b7c88 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | |||
| 99 | #endif | 99 | #endif |
| 100 | 100 | ||
| 101 | static void sd_config_discard(struct scsi_disk *, unsigned int); | 101 | static void sd_config_discard(struct scsi_disk *, unsigned int); |
| 102 | static void sd_config_write_same(struct scsi_disk *); | ||
| 102 | static int sd_revalidate_disk(struct gendisk *); | 103 | static int sd_revalidate_disk(struct gendisk *); |
| 103 | static void sd_unlock_native_capacity(struct gendisk *disk); | 104 | static void sd_unlock_native_capacity(struct gendisk *disk); |
| 104 | static int sd_probe(struct device *); | 105 | static int sd_probe(struct device *); |
| @@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev, | |||
| 395 | return err ? err : count; | 396 | return err ? err : count; |
| 396 | } | 397 | } |
| 397 | 398 | ||
| 399 | static ssize_t | ||
| 400 | sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, | ||
| 401 | char *buf) | ||
| 402 | { | ||
| 403 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 404 | |||
| 405 | return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); | ||
| 406 | } | ||
| 407 | |||
| 408 | static ssize_t | ||
| 409 | sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, | ||
| 410 | const char *buf, size_t count) | ||
| 411 | { | ||
| 412 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 413 | struct scsi_device *sdp = sdkp->device; | ||
| 414 | unsigned long max; | ||
| 415 | int err; | ||
| 416 | |||
| 417 | if (!capable(CAP_SYS_ADMIN)) | ||
| 418 | return -EACCES; | ||
| 419 | |||
| 420 | if (sdp->type != TYPE_DISK) | ||
| 421 | return -EINVAL; | ||
| 422 | |||
| 423 | err = kstrtoul(buf, 10, &max); | ||
| 424 | |||
| 425 | if (err) | ||
| 426 | return err; | ||
| 427 | |||
| 428 | if (max == 0) | ||
| 429 | sdp->no_write_same = 1; | ||
| 430 | else if (max <= SD_MAX_WS16_BLOCKS) | ||
| 431 | sdkp->max_ws_blocks = max; | ||
| 432 | |||
| 433 | sd_config_write_same(sdkp); | ||
| 434 | |||
| 435 | return count; | ||
| 436 | } | ||
| 437 | |||
| 398 | static struct device_attribute sd_disk_attrs[] = { | 438 | static struct device_attribute sd_disk_attrs[] = { |
| 399 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 439 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
| 400 | sd_store_cache_type), | 440 | sd_store_cache_type), |
| @@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = { | |||
| 410 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), | 450 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), |
| 411 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, | 451 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, |
| 412 | sd_store_provisioning_mode), | 452 | sd_store_provisioning_mode), |
| 453 | __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, | ||
| 454 | sd_show_write_same_blocks, sd_store_write_same_blocks), | ||
| 413 | __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, | 455 | __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, |
| 414 | sd_show_max_medium_access_timeouts, | 456 | sd_show_max_medium_access_timeouts, |
| 415 | sd_store_max_medium_access_timeouts), | 457 | sd_store_max_medium_access_timeouts), |
| @@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
| 561 | return; | 603 | return; |
| 562 | 604 | ||
| 563 | case SD_LBP_UNMAP: | 605 | case SD_LBP_UNMAP: |
| 564 | max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); | 606 | max_blocks = min_not_zero(sdkp->max_unmap_blocks, |
| 607 | (u32)SD_MAX_WS16_BLOCKS); | ||
| 565 | break; | 608 | break; |
| 566 | 609 | ||
| 567 | case SD_LBP_WS16: | 610 | case SD_LBP_WS16: |
| 568 | max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); | 611 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 612 | (u32)SD_MAX_WS16_BLOCKS); | ||
| 569 | break; | 613 | break; |
| 570 | 614 | ||
| 571 | case SD_LBP_WS10: | 615 | case SD_LBP_WS10: |
| 572 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | 616 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 617 | (u32)SD_MAX_WS10_BLOCKS); | ||
| 573 | break; | 618 | break; |
| 574 | 619 | ||
| 575 | case SD_LBP_ZERO: | 620 | case SD_LBP_ZERO: |
| 576 | max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); | 621 | max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 622 | (u32)SD_MAX_WS10_BLOCKS); | ||
| 577 | q->limits.discard_zeroes_data = 1; | 623 | q->limits.discard_zeroes_data = 1; |
| 578 | break; | 624 | break; |
| 579 | } | 625 | } |
| @@ -667,6 +713,83 @@ out: | |||
| 667 | return ret; | 713 | return ret; |
| 668 | } | 714 | } |
| 669 | 715 | ||
| 716 | static void sd_config_write_same(struct scsi_disk *sdkp) | ||
| 717 | { | ||
| 718 | struct request_queue *q = sdkp->disk->queue; | ||
| 719 | unsigned int logical_block_size = sdkp->device->sector_size; | ||
| 720 | unsigned int blocks = 0; | ||
| 721 | |||
| 722 | if (sdkp->device->no_write_same) { | ||
| 723 | sdkp->max_ws_blocks = 0; | ||
| 724 | goto out; | ||
| 725 | } | ||
| 726 | |||
| 727 | /* Some devices can not handle block counts above 0xffff despite | ||
| 728 | * supporting WRITE SAME(16). Consequently we default to 64k | ||
| 729 | * blocks per I/O unless the device explicitly advertises a | ||
| 730 | * bigger limit. | ||
| 731 | */ | ||
| 732 | if (sdkp->max_ws_blocks == 0) | ||
| 733 | sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; | ||
| 734 | |||
| 735 | if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) | ||
| 736 | blocks = min_not_zero(sdkp->max_ws_blocks, | ||
| 737 | (u32)SD_MAX_WS16_BLOCKS); | ||
| 738 | else | ||
| 739 | blocks = min_not_zero(sdkp->max_ws_blocks, | ||
| 740 | (u32)SD_MAX_WS10_BLOCKS); | ||
| 741 | |||
| 742 | out: | ||
| 743 | blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); | ||
| 744 | } | ||
| 745 | |||
| 746 | /** | ||
| 747 | * sd_setup_write_same_cmnd - write the same data to multiple blocks | ||
| 748 | * @sdp: scsi device to operate one | ||
| 749 | * @rq: Request to prepare | ||
| 750 | * | ||
| 751 | * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on | ||
| 752 | * preference indicated by target device. | ||
| 753 | **/ | ||
| 754 | static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq) | ||
| 755 | { | ||
| 756 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | ||
| 757 | struct bio *bio = rq->bio; | ||
| 758 | sector_t sector = blk_rq_pos(rq); | ||
| 759 | unsigned int nr_sectors = blk_rq_sectors(rq); | ||
| 760 | unsigned int nr_bytes = blk_rq_bytes(rq); | ||
| 761 | int ret; | ||
| 762 | |||
| 763 | if (sdkp->device->no_write_same) | ||
| 764 | return BLKPREP_KILL; | ||
| 765 | |||
| 766 | BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size); | ||
| 767 | |||
| 768 | sector >>= ilog2(sdp->sector_size) - 9; | ||
| 769 | nr_sectors >>= ilog2(sdp->sector_size) - 9; | ||
| 770 | |||
| 771 | rq->__data_len = sdp->sector_size; | ||
| 772 | rq->timeout = SD_WRITE_SAME_TIMEOUT; | ||
| 773 | memset(rq->cmd, 0, rq->cmd_len); | ||
| 774 | |||
| 775 | if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) { | ||
| 776 | rq->cmd_len = 16; | ||
| 777 | rq->cmd[0] = WRITE_SAME_16; | ||
| 778 | put_unaligned_be64(sector, &rq->cmd[2]); | ||
| 779 | put_unaligned_be32(nr_sectors, &rq->cmd[10]); | ||
| 780 | } else { | ||
| 781 | rq->cmd_len = 10; | ||
| 782 | rq->cmd[0] = WRITE_SAME; | ||
| 783 | put_unaligned_be32(sector, &rq->cmd[2]); | ||
| 784 | put_unaligned_be16(nr_sectors, &rq->cmd[7]); | ||
| 785 | } | ||
| 786 | |||
| 787 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
| 788 | rq->__data_len = nr_bytes; | ||
| 789 | |||
| 790 | return ret; | ||
| 791 | } | ||
| 792 | |||
| 670 | static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) | 793 | static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) |
| 671 | { | 794 | { |
| 672 | rq->timeout = SD_FLUSH_TIMEOUT; | 795 | rq->timeout = SD_FLUSH_TIMEOUT; |
| @@ -712,6 +835,9 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
| 712 | if (rq->cmd_flags & REQ_DISCARD) { | 835 | if (rq->cmd_flags & REQ_DISCARD) { |
| 713 | ret = sd_setup_discard_cmnd(sdp, rq); | 836 | ret = sd_setup_discard_cmnd(sdp, rq); |
| 714 | goto out; | 837 | goto out; |
| 838 | } else if (rq->cmd_flags & REQ_WRITE_SAME) { | ||
| 839 | ret = sd_setup_write_same_cmnd(sdp, rq); | ||
| 840 | goto out; | ||
| 715 | } else if (rq->cmd_flags & REQ_FLUSH) { | 841 | } else if (rq->cmd_flags & REQ_FLUSH) { |
| 716 | ret = scsi_setup_flush_cmnd(sdp, rq); | 842 | ret = scsi_setup_flush_cmnd(sdp, rq); |
| 717 | goto out; | 843 | goto out; |
| @@ -1484,8 +1610,9 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
| 1484 | int sense_valid = 0; | 1610 | int sense_valid = 0; |
| 1485 | int sense_deferred = 0; | 1611 | int sense_deferred = 0; |
| 1486 | unsigned char op = SCpnt->cmnd[0]; | 1612 | unsigned char op = SCpnt->cmnd[0]; |
| 1613 | unsigned char unmap = SCpnt->cmnd[1] & 8; | ||
| 1487 | 1614 | ||
| 1488 | if (req->cmd_flags & REQ_DISCARD) { | 1615 | if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { |
| 1489 | if (!result) { | 1616 | if (!result) { |
| 1490 | good_bytes = blk_rq_bytes(req); | 1617 | good_bytes = blk_rq_bytes(req); |
| 1491 | scsi_set_resid(SCpnt, 0); | 1618 | scsi_set_resid(SCpnt, 0); |
| @@ -1542,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
| 1542 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ | 1669 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ |
| 1543 | good_bytes = sd_completed_bytes(SCpnt); | 1670 | good_bytes = sd_completed_bytes(SCpnt); |
| 1544 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | 1671 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
| 1545 | if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | 1672 | if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
| 1546 | (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) | 1673 | switch (op) { |
| 1547 | sd_config_discard(sdkp, SD_LBP_DISABLE); | 1674 | case UNMAP: |
| 1675 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
| 1676 | break; | ||
| 1677 | case WRITE_SAME_16: | ||
| 1678 | case WRITE_SAME: | ||
| 1679 | if (unmap) | ||
| 1680 | sd_config_discard(sdkp, SD_LBP_DISABLE); | ||
| 1681 | else { | ||
| 1682 | sdkp->device->no_write_same = 1; | ||
| 1683 | sd_config_write_same(sdkp); | ||
| 1684 | |||
| 1685 | good_bytes = 0; | ||
| 1686 | req->__data_len = blk_rq_bytes(req); | ||
| 1687 | req->cmd_flags |= REQ_QUIET; | ||
| 1688 | } | ||
| 1689 | } | ||
| 1690 | } | ||
| 1548 | break; | 1691 | break; |
| 1549 | default: | 1692 | default: |
| 1550 | break; | 1693 | break; |
| @@ -2380,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
| 2380 | if (buffer[3] == 0x3c) { | 2523 | if (buffer[3] == 0x3c) { |
| 2381 | unsigned int lba_count, desc_count; | 2524 | unsigned int lba_count, desc_count; |
| 2382 | 2525 | ||
| 2383 | sdkp->max_ws_blocks = | 2526 | sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); |
| 2384 | (u32) min_not_zero(get_unaligned_be64(&buffer[36]), | ||
| 2385 | (u64)0xffffffff); | ||
| 2386 | 2527 | ||
| 2387 | if (!sdkp->lbpme) | 2528 | if (!sdkp->lbpme) |
| 2388 | goto out; | 2529 | goto out; |
| @@ -2475,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) | |||
| 2475 | kfree(buffer); | 2616 | kfree(buffer); |
| 2476 | } | 2617 | } |
| 2477 | 2618 | ||
| 2619 | static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) | ||
| 2620 | { | ||
| 2621 | if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, | ||
| 2622 | WRITE_SAME_16)) | ||
| 2623 | sdkp->ws16 = 1; | ||
| 2624 | } | ||
| 2625 | |||
| 2478 | static int sd_try_extended_inquiry(struct scsi_device *sdp) | 2626 | static int sd_try_extended_inquiry(struct scsi_device *sdp) |
| 2479 | { | 2627 | { |
| 2480 | /* | 2628 | /* |
| @@ -2534,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
| 2534 | sd_read_write_protect_flag(sdkp, buffer); | 2682 | sd_read_write_protect_flag(sdkp, buffer); |
| 2535 | sd_read_cache_type(sdkp, buffer); | 2683 | sd_read_cache_type(sdkp, buffer); |
| 2536 | sd_read_app_tag_own(sdkp, buffer); | 2684 | sd_read_app_tag_own(sdkp, buffer); |
| 2685 | sd_read_write_same(sdkp, buffer); | ||
| 2537 | } | 2686 | } |
| 2538 | 2687 | ||
| 2539 | sdkp->first_scan = 0; | 2688 | sdkp->first_scan = 0; |
| @@ -2551,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
| 2551 | blk_queue_flush(sdkp->disk->queue, flush); | 2700 | blk_queue_flush(sdkp->disk->queue, flush); |
| 2552 | 2701 | ||
| 2553 | set_capacity(disk, sdkp->capacity); | 2702 | set_capacity(disk, sdkp->capacity); |
| 2703 | sd_config_write_same(sdkp); | ||
| 2554 | kfree(buffer); | 2704 | kfree(buffer); |
| 2555 | 2705 | ||
| 2556 | out: | 2706 | out: |
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 47c52a6d733c..74a1e4ca5401 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #define SD_TIMEOUT (30 * HZ) | 14 | #define SD_TIMEOUT (30 * HZ) |
| 15 | #define SD_MOD_TIMEOUT (75 * HZ) | 15 | #define SD_MOD_TIMEOUT (75 * HZ) |
| 16 | #define SD_FLUSH_TIMEOUT (60 * HZ) | 16 | #define SD_FLUSH_TIMEOUT (60 * HZ) |
| 17 | #define SD_WRITE_SAME_TIMEOUT (120 * HZ) | ||
| 17 | 18 | ||
| 18 | /* | 19 | /* |
| 19 | * Number of allowed retries | 20 | * Number of allowed retries |
| @@ -39,6 +40,11 @@ enum { | |||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | enum { | 42 | enum { |
| 43 | SD_MAX_WS10_BLOCKS = 0xffff, | ||
| 44 | SD_MAX_WS16_BLOCKS = 0x7fffff, | ||
| 45 | }; | ||
| 46 | |||
| 47 | enum { | ||
| 42 | SD_LBP_FULL = 0, /* Full logical block provisioning */ | 48 | SD_LBP_FULL = 0, /* Full logical block provisioning */ |
| 43 | SD_LBP_UNMAP, /* Use UNMAP command */ | 49 | SD_LBP_UNMAP, /* Use UNMAP command */ |
| 44 | SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ | 50 | SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ |
| @@ -77,6 +83,7 @@ struct scsi_disk { | |||
| 77 | unsigned lbpws : 1; | 83 | unsigned lbpws : 1; |
| 78 | unsigned lbpws10 : 1; | 84 | unsigned lbpws10 : 1; |
| 79 | unsigned lbpvpd : 1; | 85 | unsigned lbpvpd : 1; |
| 86 | unsigned ws16 : 1; | ||
| 80 | }; | 87 | }; |
| 81 | #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) | 88 | #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) |
| 82 | 89 | ||
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 6ab376a7c501..92f35abee92d 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
| @@ -189,6 +189,9 @@ static int slave_configure(struct scsi_device *sdev) | |||
| 189 | /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ | 189 | /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ |
| 190 | sdev->no_report_opcodes = 1; | 190 | sdev->no_report_opcodes = 1; |
| 191 | 191 | ||
| 192 | /* Do not attempt to use WRITE SAME */ | ||
| 193 | sdev->no_write_same = 1; | ||
| 194 | |||
| 192 | /* Some disks return the total number of blocks in response | 195 | /* Some disks return the total number of blocks in response |
| 193 | * to READ CAPACITY rather than the highest block number. | 196 | * to READ CAPACITY rather than the highest block number. |
| 194 | * If this device makes that mistake, tell the sd driver. */ | 197 | * If this device makes that mistake, tell the sd driver. */ |
