diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-22 14:14:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-22 14:14:54 -0500 |
commit | a2d2eda7bf8fd3a5fa44557162715dbfabbc8239 (patch) | |
tree | 8bed3e9906f23d21fa96b266aa01808a594ef721 | |
parent | 0e0f092ef0c474c3996c8e023d1724f4f72132ad (diff) | |
parent | 5db44863b6ebbb400c5e61d56ebe8f21ef48b1bd (diff) |
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley:
"This is a set of four bug fixes.
The isci one is an obvious thinko (using request buffer instead of
response buffer) which causes a command to fail.
The three others are DIF/DIX updates which are required because
they're part of a series of ten patches, the other seven of which went
into the block layer during the merge window meaning our current
DIF/DIX implementation is broken without these three.
Signed-off-by: James Bottomley <JBottomley@Parallels.com>"
* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
[SCSI] sd: Implement support for WRITE SAME
[SCSI] sd: Permit merged discard requests
[SCSI] Add a report opcode helper
[SCSI] isci: copy fis 0x34 response into proper buffer
-rw-r--r-- | drivers/ata/libata-scsi.c | 2 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 45 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 22 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 202 | ||||
-rw-r--r-- | drivers/scsi/sd.h | 7 | ||||
-rw-r--r-- | drivers/usb/storage/scsiglue.c | 6 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 4 |
9 files changed, 263 insertions, 29 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e3bda074fa12..a6df6a351d6e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) | |||
1052 | { | 1052 | { |
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; | ||
1056 | sdev->no_write_same = 1; | ||
1055 | 1057 | ||
1056 | /* Schedule policy is determined by ->qc_defer() callback and | 1058 | /* Schedule policy is determined by ->qc_defer() callback and |
1057 | * 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 1162d6b3bf85..bb1b392f5cda 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) | |||
1546 | struct sbp2_logical_unit *lu = sdev->hostdata; | 1546 | struct sbp2_logical_unit *lu = sdev->hostdata; |
1547 | 1547 | ||
1548 | sdev->use_10_for_rw = 1; | 1548 | sdev->use_10_for_rw = 1; |
1549 | sdev->no_report_opcodes = 1; | ||
1550 | sdev->no_write_same = 1; | ||
1549 | 1551 | ||
1550 | if (sbp2_param_exclusive_login) | 1552 | if (sbp2_param_exclusive_login) |
1551 | sdev->manage_start_stop = 1; | 1553 | sdev->manage_start_stop = 1; |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index c1bafc3f3fb1..9594ab62702b 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, | |||
1972 | frame_index, | 1972 | frame_index, |
1973 | (void **)&frame_buffer); | 1973 | (void **)&frame_buffer); |
1974 | 1974 | ||
1975 | sci_controller_copy_sata_response(&ireq->stp.req, | 1975 | sci_controller_copy_sata_response(&ireq->stp.rsp, |
1976 | frame_header, | 1976 | frame_header, |
1977 | frame_buffer); | 1977 | frame_buffer); |
1978 | 1978 | ||
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2936b447cae9..2c0d0ec8150b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/cpu.h> | 55 | #include <linux/cpu.h> |
56 | #include <linux/mutex.h> | 56 | #include <linux/mutex.h> |
57 | #include <linux/async.h> | 57 | #include <linux/async.h> |
58 | #include <asm/unaligned.h> | ||
58 | 59 | ||
59 | #include <scsi/scsi.h> | 60 | #include <scsi/scsi.h> |
60 | #include <scsi/scsi_cmnd.h> | 61 | #include <scsi/scsi_cmnd.h> |
@@ -1062,6 +1063,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, | |||
1062 | EXPORT_SYMBOL_GPL(scsi_get_vpd_page); | 1063 | EXPORT_SYMBOL_GPL(scsi_get_vpd_page); |
1063 | 1064 | ||
1064 | /** | 1065 | /** |
1066 | * scsi_report_opcode - Find out if a given command opcode is supported | ||
1067 | * @sdev: scsi device to query | ||
1068 | * @buffer: scratch buffer (must be at least 20 bytes long) | ||
1069 | * @len: length of buffer | ||
1070 | * @opcode: opcode for command to look up | ||
1071 | * | ||
1072 | * Uses the REPORT SUPPORTED OPERATION CODES to look up the given | ||
1073 | * opcode. Returns 0 if RSOC fails or if the command opcode is | ||
1074 | * unsupported. Returns 1 if the device claims to support the command. | ||
1075 | */ | ||
1076 | int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, | ||
1077 | unsigned int len, unsigned char opcode) | ||
1078 | { | ||
1079 | unsigned char cmd[16]; | ||
1080 | struct scsi_sense_hdr sshdr; | ||
1081 | int result; | ||
1082 | |||
1083 | if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) | ||
1084 | return 0; | ||
1085 | |||
1086 | memset(cmd, 0, 16); | ||
1087 | cmd[0] = MAINTENANCE_IN; | ||
1088 | cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES; | ||
1089 | cmd[2] = 1; /* One command format */ | ||
1090 | cmd[3] = opcode; | ||
1091 | put_unaligned_be32(len, &cmd[6]); | ||
1092 | memset(buffer, 0, len); | ||
1093 | |||
1094 | result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, | ||
1095 | &sshdr, 30 * HZ, 3, NULL); | ||
1096 | |||
1097 | if (result && scsi_sense_valid(&sshdr) && | ||
1098 | sshdr.sense_key == ILLEGAL_REQUEST && | ||
1099 | (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) | ||
1100 | return 0; | ||
1101 | |||
1102 | if ((buffer[1] & 3) == 3) /* Command supported */ | ||
1103 | return 1; | ||
1104 | |||
1105 | return 0; | ||
1106 | } | ||
1107 | EXPORT_SYMBOL(scsi_report_opcode); | ||
1108 | |||
1109 | /** | ||
1065 | * scsi_device_get - get an additional reference to a scsi_device | 1110 | * scsi_device_get - get an additional reference to a scsi_device |
1066 | * @sdev: device to get a reference to | 1111 | * @sdev: device to get a reference to |
1067 | * | 1112 | * |
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 12f6fdfc1147..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 | } |
@@ -583,29 +629,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) | |||
583 | } | 629 | } |
584 | 630 | ||
585 | /** | 631 | /** |
586 | * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device | 632 | * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device |
587 | * @sdp: scsi device to operate one | 633 | * @sdp: scsi device to operate one |
588 | * @rq: Request to prepare | 634 | * @rq: Request to prepare |
589 | * | 635 | * |
590 | * Will issue either UNMAP or WRITE SAME(16) depending on preference | 636 | * Will issue either UNMAP or WRITE SAME(16) depending on preference |
591 | * indicated by target device. | 637 | * indicated by target device. |
592 | **/ | 638 | **/ |
593 | static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | 639 | static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) |
594 | { | 640 | { |
595 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); | 641 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
596 | struct bio *bio = rq->bio; | 642 | sector_t sector = blk_rq_pos(rq); |
597 | sector_t sector = bio->bi_sector; | 643 | unsigned int nr_sectors = blk_rq_sectors(rq); |
598 | unsigned int nr_sectors = bio_sectors(bio); | 644 | unsigned int nr_bytes = blk_rq_bytes(rq); |
599 | unsigned int len; | 645 | unsigned int len; |
600 | int ret; | 646 | int ret; |
601 | char *buf; | 647 | char *buf; |
602 | struct page *page; | 648 | struct page *page; |
603 | 649 | ||
604 | if (sdkp->device->sector_size == 4096) { | 650 | sector >>= ilog2(sdp->sector_size) - 9; |
605 | sector >>= 3; | 651 | nr_sectors >>= ilog2(sdp->sector_size) - 9; |
606 | nr_sectors >>= 3; | ||
607 | } | ||
608 | |||
609 | rq->timeout = SD_TIMEOUT; | 652 | rq->timeout = SD_TIMEOUT; |
610 | 653 | ||
611 | memset(rq->cmd, 0, rq->cmd_len); | 654 | memset(rq->cmd, 0, rq->cmd_len); |
@@ -660,6 +703,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) | |||
660 | blk_add_request_payload(rq, page, len); | 703 | blk_add_request_payload(rq, page, len); |
661 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | 704 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); |
662 | rq->buffer = page_address(page); | 705 | rq->buffer = page_address(page); |
706 | rq->__data_len = nr_bytes; | ||
663 | 707 | ||
664 | out: | 708 | out: |
665 | if (ret != BLKPREP_OK) { | 709 | if (ret != BLKPREP_OK) { |
@@ -669,6 +713,83 @@ out: | |||
669 | return ret; | 713 | return ret; |
670 | } | 714 | } |
671 | 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 | |||
672 | 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) |
673 | { | 794 | { |
674 | rq->timeout = SD_FLUSH_TIMEOUT; | 795 | rq->timeout = SD_FLUSH_TIMEOUT; |
@@ -712,7 +833,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
712 | * block PC requests to make life easier. | 833 | * block PC requests to make life easier. |
713 | */ | 834 | */ |
714 | if (rq->cmd_flags & REQ_DISCARD) { | 835 | if (rq->cmd_flags & REQ_DISCARD) { |
715 | ret = scsi_setup_discard_cmnd(sdp, rq); | 836 | ret = sd_setup_discard_cmnd(sdp, rq); |
837 | goto out; | ||
838 | } else if (rq->cmd_flags & REQ_WRITE_SAME) { | ||
839 | ret = sd_setup_write_same_cmnd(sdp, rq); | ||
716 | goto out; | 840 | goto out; |
717 | } else if (rq->cmd_flags & REQ_FLUSH) { | 841 | } else if (rq->cmd_flags & REQ_FLUSH) { |
718 | ret = scsi_setup_flush_cmnd(sdp, rq); | 842 | ret = scsi_setup_flush_cmnd(sdp, rq); |
@@ -1482,12 +1606,21 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1482 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); | 1606 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); |
1483 | struct scsi_sense_hdr sshdr; | 1607 | struct scsi_sense_hdr sshdr; |
1484 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); | 1608 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); |
1609 | struct request *req = SCpnt->request; | ||
1485 | int sense_valid = 0; | 1610 | int sense_valid = 0; |
1486 | int sense_deferred = 0; | 1611 | int sense_deferred = 0; |
1487 | unsigned char op = SCpnt->cmnd[0]; | 1612 | unsigned char op = SCpnt->cmnd[0]; |
1613 | unsigned char unmap = SCpnt->cmnd[1] & 8; | ||
1488 | 1614 | ||
1489 | if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) | 1615 | if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { |
1490 | scsi_set_resid(SCpnt, 0); | 1616 | if (!result) { |
1617 | good_bytes = blk_rq_bytes(req); | ||
1618 | scsi_set_resid(SCpnt, 0); | ||
1619 | } else { | ||
1620 | good_bytes = 0; | ||
1621 | scsi_set_resid(SCpnt, blk_rq_bytes(req)); | ||
1622 | } | ||
1623 | } | ||
1491 | 1624 | ||
1492 | if (result) { | 1625 | if (result) { |
1493 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); | 1626 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); |
@@ -1536,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1536 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ | 1669 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ |
1537 | good_bytes = sd_completed_bytes(SCpnt); | 1670 | good_bytes = sd_completed_bytes(SCpnt); |
1538 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ | 1671 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
1539 | if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && | 1672 | if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
1540 | (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) | 1673 | switch (op) { |
1541 | 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 | } | ||
1542 | break; | 1691 | break; |
1543 | default: | 1692 | default: |
1544 | break; | 1693 | break; |
@@ -2374,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
2374 | if (buffer[3] == 0x3c) { | 2523 | if (buffer[3] == 0x3c) { |
2375 | unsigned int lba_count, desc_count; | 2524 | unsigned int lba_count, desc_count; |
2376 | 2525 | ||
2377 | sdkp->max_ws_blocks = | 2526 | sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); |
2378 | (u32) min_not_zero(get_unaligned_be64(&buffer[36]), | ||
2379 | (u64)0xffffffff); | ||
2380 | 2527 | ||
2381 | if (!sdkp->lbpme) | 2528 | if (!sdkp->lbpme) |
2382 | goto out; | 2529 | goto out; |
@@ -2469,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) | |||
2469 | kfree(buffer); | 2616 | kfree(buffer); |
2470 | } | 2617 | } |
2471 | 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 | |||
2472 | static int sd_try_extended_inquiry(struct scsi_device *sdp) | 2626 | static int sd_try_extended_inquiry(struct scsi_device *sdp) |
2473 | { | 2627 | { |
2474 | /* | 2628 | /* |
@@ -2528,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
2528 | sd_read_write_protect_flag(sdkp, buffer); | 2682 | sd_read_write_protect_flag(sdkp, buffer); |
2529 | sd_read_cache_type(sdkp, buffer); | 2683 | sd_read_cache_type(sdkp, buffer); |
2530 | sd_read_app_tag_own(sdkp, buffer); | 2684 | sd_read_app_tag_own(sdkp, buffer); |
2685 | sd_read_write_same(sdkp, buffer); | ||
2531 | } | 2686 | } |
2532 | 2687 | ||
2533 | sdkp->first_scan = 0; | 2688 | sdkp->first_scan = 0; |
@@ -2545,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
2545 | blk_queue_flush(sdkp->disk->queue, flush); | 2700 | blk_queue_flush(sdkp->disk->queue, flush); |
2546 | 2701 | ||
2547 | set_capacity(disk, sdkp->capacity); | 2702 | set_capacity(disk, sdkp->capacity); |
2703 | sd_config_write_same(sdkp); | ||
2548 | kfree(buffer); | 2704 | kfree(buffer); |
2549 | 2705 | ||
2550 | 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 a3d54366afcc..92f35abee92d 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -186,6 +186,12 @@ static int slave_configure(struct scsi_device *sdev) | |||
186 | /* Some devices don't handle VPD pages correctly */ | 186 | /* Some devices don't handle VPD pages correctly */ |
187 | sdev->skip_vpd_pages = 1; | 187 | sdev->skip_vpd_pages = 1; |
188 | 188 | ||
189 | /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ | ||
190 | sdev->no_report_opcodes = 1; | ||
191 | |||
192 | /* Do not attempt to use WRITE SAME */ | ||
193 | sdev->no_write_same = 1; | ||
194 | |||
189 | /* Some disks return the total number of blocks in response | 195 | /* Some disks return the total number of blocks in response |
190 | * to READ CAPACITY rather than the highest block number. | 196 | * to READ CAPACITY rather than the highest block number. |
191 | * If this device makes that mistake, tell the sd driver. */ | 197 | * If this device makes that mistake, tell the sd driver. */ |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 88fae8d20154..55367b04dc94 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -135,6 +135,8 @@ struct scsi_device { | |||
135 | * because we did a bus reset. */ | 135 | * because we did a bus reset. */ |
136 | unsigned use_10_for_rw:1; /* first try 10-byte read / write */ | 136 | unsigned use_10_for_rw:1; /* first try 10-byte read / write */ |
137 | unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ | 137 | unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ |
138 | unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ | ||
139 | unsigned no_write_same:1; /* no WRITE SAME command */ | ||
138 | unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ | 140 | unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ |
139 | unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ | 141 | unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ |
140 | unsigned skip_vpd_pages:1; /* do not read VPD pages */ | 142 | unsigned skip_vpd_pages:1; /* do not read VPD pages */ |
@@ -362,6 +364,8 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, | |||
362 | int retries, struct scsi_sense_hdr *sshdr); | 364 | int retries, struct scsi_sense_hdr *sshdr); |
363 | extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, | 365 | extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, |
364 | int buf_len); | 366 | int buf_len); |
367 | extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, | ||
368 | unsigned int len, unsigned char opcode); | ||
365 | extern int scsi_device_set_state(struct scsi_device *sdev, | 369 | extern int scsi_device_set_state(struct scsi_device *sdev, |
366 | enum scsi_device_state state); | 370 | enum scsi_device_state state); |
367 | extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, | 371 | extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, |