aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2013-10-23 06:25:40 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-12 01:36:28 -0500
commit8562d028775e7c88fc7fa8c5deaa791392892778 (patch)
tree8b40e1f29bf66978ef17364bc583f74d3a5fc614
parent5e43e33a63d72c6bd30f9fa14a9e82ffb58be422 (diff)
SCSI: Disable WRITE SAME for RAID and virtual host adapter drivers
commit 54b2b50c20a61b51199bedb6e5d2f8ec2568fb43 upstream. Some host adapters do not pass commands through to the target disk directly. Instead they provide an emulated target which may or may not accurately report its capabilities. In some cases the physical device characteristics are reported even when the host adapter is processing commands on the device's behalf. This can lead to adapter firmware hangs or excessive I/O errors. This patch disables WRITE SAME for devices connected to host adapters that provide an emulated target. Driver writers can disable WRITE SAME by setting the no_write_same flag in the host adapter template. [jejb: fix up rejections due to eh_deadline patch] Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/ata/libata-scsi.c1
-rw-r--r--drivers/firewire/sbp2.c1
-rw-r--r--drivers/scsi/3w-9xxx.c3
-rw-r--r--drivers/scsi/3w-sas.c3
-rw-r--r--drivers/scsi/3w-xxxx.c3
-rw-r--r--drivers/scsi/aacraid/linit.c1
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c1
-rw-r--r--drivers/scsi/gdth.c1
-rw-r--r--drivers/scsi/hosts.c1
-rw-r--r--drivers/scsi/hpsa.c1
-rw-r--r--drivers/scsi/ipr.c3
-rw-r--r--drivers/scsi/ips.c1
-rw-r--r--drivers/scsi/megaraid.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c1
-rw-r--r--drivers/scsi/pmcraid.c1
-rw-r--r--drivers/scsi/sd.c6
-rw-r--r--drivers/scsi/storvsc_drv.c1
-rw-r--r--include/scsi/scsi_host.h6
19 files changed, 33 insertions, 4 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 0101af541436..4abdbdff6943 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3614,6 +3614,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
3614 shost->max_lun = 1; 3614 shost->max_lun = 1;
3615 shost->max_channel = 1; 3615 shost->max_channel = 1;
3616 shost->max_cmd_len = 16; 3616 shost->max_cmd_len = 16;
3617 shost->no_write_same = 1;
3617 3618
3618 /* Schedule policy is determined by ->qc_defer() 3619 /* Schedule policy is determined by ->qc_defer()
3619 * callback and it needs to see every deferred qc. 3620 * callback and it needs to see every deferred qc.
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 47674b913843..c8e3b2c48369 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1626,6 +1626,7 @@ static struct scsi_host_template scsi_driver_template = {
1626 .cmd_per_lun = 1, 1626 .cmd_per_lun = 1,
1627 .can_queue = 1, 1627 .can_queue = 1,
1628 .sdev_attrs = sbp2_scsi_sysfs_attrs, 1628 .sdev_attrs = sbp2_scsi_sysfs_attrs,
1629 .no_write_same = 1,
1629}; 1630};
1630 1631
1631MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>"); 1632MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 5e1e12c0cf42..0a7325361d29 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -2025,7 +2025,8 @@ static struct scsi_host_template driver_template = {
2025 .cmd_per_lun = TW_MAX_CMDS_PER_LUN, 2025 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
2026 .use_clustering = ENABLE_CLUSTERING, 2026 .use_clustering = ENABLE_CLUSTERING,
2027 .shost_attrs = twa_host_attrs, 2027 .shost_attrs = twa_host_attrs,
2028 .emulated = 1 2028 .emulated = 1,
2029 .no_write_same = 1,
2029}; 2030};
2030 2031
2031/* This function will probe and initialize a card */ 2032/* This function will probe and initialize a card */
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index c845bdbeb6c0..4de346017e9f 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -1600,7 +1600,8 @@ static struct scsi_host_template driver_template = {
1600 .cmd_per_lun = TW_MAX_CMDS_PER_LUN, 1600 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1601 .use_clustering = ENABLE_CLUSTERING, 1601 .use_clustering = ENABLE_CLUSTERING,
1602 .shost_attrs = twl_host_attrs, 1602 .shost_attrs = twl_host_attrs,
1603 .emulated = 1 1603 .emulated = 1,
1604 .no_write_same = 1,
1604}; 1605};
1605 1606
1606/* This function will probe and initialize a card */ 1607/* This function will probe and initialize a card */
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 56662ae03dea..430ee3774c3b 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -2277,7 +2277,8 @@ static struct scsi_host_template driver_template = {
2277 .cmd_per_lun = TW_MAX_CMDS_PER_LUN, 2277 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
2278 .use_clustering = ENABLE_CLUSTERING, 2278 .use_clustering = ENABLE_CLUSTERING,
2279 .shost_attrs = tw_host_attrs, 2279 .shost_attrs = tw_host_attrs,
2280 .emulated = 1 2280 .emulated = 1,
2281 .no_write_same = 1,
2281}; 2282};
2282 2283
2283/* This function will probe and initialize a card */ 2284/* This function will probe and initialize a card */
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index f0d432c139d0..4921ed19a027 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1081,6 +1081,7 @@ static struct scsi_host_template aac_driver_template = {
1081#endif 1081#endif
1082 .use_clustering = ENABLE_CLUSTERING, 1082 .use_clustering = ENABLE_CLUSTERING,
1083 .emulated = 1, 1083 .emulated = 1,
1084 .no_write_same = 1,
1084}; 1085};
1085 1086
1086static void __aac_shutdown(struct aac_dev * aac) 1087static void __aac_shutdown(struct aac_dev * aac)
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 33c52bc2c7b4..278c9fa62067 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -137,6 +137,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
137 .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, 137 .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
138 .use_clustering = ENABLE_CLUSTERING, 138 .use_clustering = ENABLE_CLUSTERING,
139 .shost_attrs = arcmsr_host_attrs, 139 .shost_attrs = arcmsr_host_attrs,
140 .no_write_same = 1,
140}; 141};
141static struct pci_device_id arcmsr_device_id_table[] = { 142static struct pci_device_id arcmsr_device_id_table[] = {
142 {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, 143 {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)},
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 6d55b4e7e792..aec3d4da276f 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -4686,6 +4686,7 @@ static struct scsi_host_template gdth_template = {
4686 .cmd_per_lun = GDTH_MAXC_P_L, 4686 .cmd_per_lun = GDTH_MAXC_P_L,
4687 .unchecked_isa_dma = 1, 4687 .unchecked_isa_dma = 1,
4688 .use_clustering = ENABLE_CLUSTERING, 4688 .use_clustering = ENABLE_CLUSTERING,
4689 .no_write_same = 1,
4689}; 4690};
4690 4691
4691#ifdef CONFIG_ISA 4692#ifdef CONFIG_ISA
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index df0c3c71ea43..3cafe0d784b8 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -388,6 +388,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
388 shost->unchecked_isa_dma = sht->unchecked_isa_dma; 388 shost->unchecked_isa_dma = sht->unchecked_isa_dma;
389 shost->use_clustering = sht->use_clustering; 389 shost->use_clustering = sht->use_clustering;
390 shost->ordered_tag = sht->ordered_tag; 390 shost->ordered_tag = sht->ordered_tag;
391 shost->no_write_same = sht->no_write_same;
391 392
392 if (sht->supported_mode == MODE_UNKNOWN) 393 if (sht->supported_mode == MODE_UNKNOWN)
393 /* means we didn't set it ... default to INITIATOR */ 394 /* means we didn't set it ... default to INITIATOR */
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 8e292aa11c0a..0353d7f2172b 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -538,6 +538,7 @@ static struct scsi_host_template hpsa_driver_template = {
538 .sdev_attrs = hpsa_sdev_attrs, 538 .sdev_attrs = hpsa_sdev_attrs,
539 .shost_attrs = hpsa_shost_attrs, 539 .shost_attrs = hpsa_shost_attrs,
540 .max_sectors = 8192, 540 .max_sectors = 8192,
541 .no_write_same = 1,
541}; 542};
542 543
543 544
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 6c4cedb44c07..0ff37a5e286c 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6267,7 +6267,8 @@ static struct scsi_host_template driver_template = {
6267 .use_clustering = ENABLE_CLUSTERING, 6267 .use_clustering = ENABLE_CLUSTERING,
6268 .shost_attrs = ipr_ioa_attrs, 6268 .shost_attrs = ipr_ioa_attrs,
6269 .sdev_attrs = ipr_dev_attrs, 6269 .sdev_attrs = ipr_dev_attrs,
6270 .proc_name = IPR_NAME 6270 .proc_name = IPR_NAME,
6271 .no_write_same = 1,
6271}; 6272};
6272 6273
6273/** 6274/**
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 8d5ea8a1e5a6..52a216f21ae5 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -374,6 +374,7 @@ static struct scsi_host_template ips_driver_template = {
374 .sg_tablesize = IPS_MAX_SG, 374 .sg_tablesize = IPS_MAX_SG,
375 .cmd_per_lun = 3, 375 .cmd_per_lun = 3,
376 .use_clustering = ENABLE_CLUSTERING, 376 .use_clustering = ENABLE_CLUSTERING,
377 .no_write_same = 1,
377}; 378};
378 379
379 380
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 846f475f62c1..60cf7b1f5423 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -4244,6 +4244,7 @@ static struct scsi_host_template megaraid_template = {
4244 .eh_device_reset_handler = megaraid_reset, 4244 .eh_device_reset_handler = megaraid_reset,
4245 .eh_bus_reset_handler = megaraid_reset, 4245 .eh_bus_reset_handler = megaraid_reset,
4246 .eh_host_reset_handler = megaraid_reset, 4246 .eh_host_reset_handler = megaraid_reset,
4247 .no_write_same = 1,
4247}; 4248};
4248 4249
4249static int 4250static int
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e6a1e0b38a19..3316d8031e82 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -367,6 +367,7 @@ static struct scsi_host_template megaraid_template_g = {
367 .eh_host_reset_handler = megaraid_reset_handler, 367 .eh_host_reset_handler = megaraid_reset_handler,
368 .change_queue_depth = megaraid_change_queue_depth, 368 .change_queue_depth = megaraid_change_queue_depth,
369 .use_clustering = ENABLE_CLUSTERING, 369 .use_clustering = ENABLE_CLUSTERING,
370 .no_write_same = 1,
370 .sdev_attrs = megaraid_sdev_attrs, 371 .sdev_attrs = megaraid_sdev_attrs,
371 .shost_attrs = megaraid_shost_attrs, 372 .shost_attrs = megaraid_shost_attrs,
372}; 373};
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 9b60dc129a53..b3e5c1787876 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -2099,6 +2099,7 @@ static struct scsi_host_template megasas_template = {
2099 .bios_param = megasas_bios_param, 2099 .bios_param = megasas_bios_param,
2100 .use_clustering = ENABLE_CLUSTERING, 2100 .use_clustering = ENABLE_CLUSTERING,
2101 .change_queue_depth = megasas_change_queue_depth, 2101 .change_queue_depth = megasas_change_queue_depth,
2102 .no_write_same = 1,
2102}; 2103};
2103 2104
2104/** 2105/**
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 8e1b73775065..bfb72ec277c7 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -4314,6 +4314,7 @@ static struct scsi_host_template pmcraid_host_template = {
4314 .this_id = -1, 4314 .this_id = -1,
4315 .sg_tablesize = PMCRAID_MAX_IOADLS, 4315 .sg_tablesize = PMCRAID_MAX_IOADLS,
4316 .max_sectors = PMCRAID_IOA_MAX_SECTORS, 4316 .max_sectors = PMCRAID_IOA_MAX_SECTORS,
4317 .no_write_same = 1,
4317 .cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN, 4318 .cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN,
4318 .use_clustering = ENABLE_CLUSTERING, 4319 .use_clustering = ENABLE_CLUSTERING,
4319 .shost_attrs = pmcraid_host_attrs, 4320 .shost_attrs = pmcraid_host_attrs,
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 734a29a70f63..9bc913b92d13 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2627,6 +2627,12 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
2627{ 2627{
2628 struct scsi_device *sdev = sdkp->device; 2628 struct scsi_device *sdev = sdkp->device;
2629 2629
2630 if (sdev->host->no_write_same) {
2631 sdev->no_write_same = 1;
2632
2633 return;
2634 }
2635
2630 if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) { 2636 if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) {
2631 sdev->no_report_opcodes = 1; 2637 sdev->no_report_opcodes = 1;
2632 2638
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 16a3a0cc9672..fb7437dd5b7a 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1454,6 +1454,7 @@ static struct scsi_host_template scsi_driver = {
1454 .use_clustering = DISABLE_CLUSTERING, 1454 .use_clustering = DISABLE_CLUSTERING,
1455 /* Make sure we dont get a sg segment crosses a page boundary */ 1455 /* Make sure we dont get a sg segment crosses a page boundary */
1456 .dma_boundary = PAGE_SIZE-1, 1456 .dma_boundary = PAGE_SIZE-1,
1457 .no_write_same = 1,
1457}; 1458};
1458 1459
1459enum { 1460enum {
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 755243572219..50769a72166b 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -475,6 +475,9 @@ struct scsi_host_template {
475 */ 475 */
476 unsigned ordered_tag:1; 476 unsigned ordered_tag:1;
477 477
478 /* True if the controller does not support WRITE SAME */
479 unsigned no_write_same:1;
480
478 /* 481 /*
479 * Countdown for host blocking with no commands outstanding. 482 * Countdown for host blocking with no commands outstanding.
480 */ 483 */
@@ -674,6 +677,9 @@ struct Scsi_Host {
674 /* Don't resume host in EH */ 677 /* Don't resume host in EH */
675 unsigned eh_noresume:1; 678 unsigned eh_noresume:1;
676 679
680 /* The controller does not support WRITE SAME */
681 unsigned no_write_same:1;
682
677 /* 683 /*
678 * Optional work queue to be utilized by the transport 684 * Optional work queue to be utilized by the transport
679 */ 685 */