Commit 54b2b50c authored by Martin K. Petersen's avatar Martin K. Petersen Committed by James Bottomley

[SCSI] Disable WRITE SAME for RAID and virtual host adapter drivers

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: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Cc: stable@kernel.org
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent ae5fbae0
...@@ -3625,6 +3625,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) ...@@ -3625,6 +3625,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
shost->max_lun = 1; shost->max_lun = 1;
shost->max_channel = 1; shost->max_channel = 1;
shost->max_cmd_len = 16; shost->max_cmd_len = 16;
shost->no_write_same = 1;
/* Schedule policy is determined by ->qc_defer() /* Schedule policy is determined by ->qc_defer()
* callback and it needs to see every deferred qc. * callback and it needs to see every deferred qc.
......
...@@ -1623,6 +1623,7 @@ static struct scsi_host_template scsi_driver_template = { ...@@ -1623,6 +1623,7 @@ static struct scsi_host_template scsi_driver_template = {
.cmd_per_lun = 1, .cmd_per_lun = 1,
.can_queue = 1, .can_queue = 1,
.sdev_attrs = sbp2_scsi_sysfs_attrs, .sdev_attrs = sbp2_scsi_sysfs_attrs,
.no_write_same = 1,
}; };
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>"); MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
......
...@@ -2025,7 +2025,8 @@ static struct scsi_host_template driver_template = { ...@@ -2025,7 +2025,8 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = TW_MAX_CMDS_PER_LUN, .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.shost_attrs = twa_host_attrs, .shost_attrs = twa_host_attrs,
.emulated = 1 .emulated = 1,
.no_write_same = 1,
}; };
/* This function will probe and initialize a card */ /* This function will probe and initialize a card */
......
...@@ -1600,7 +1600,8 @@ static struct scsi_host_template driver_template = { ...@@ -1600,7 +1600,8 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = TW_MAX_CMDS_PER_LUN, .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.shost_attrs = twl_host_attrs, .shost_attrs = twl_host_attrs,
.emulated = 1 .emulated = 1,
.no_write_same = 1,
}; };
/* This function will probe and initialize a card */ /* This function will probe and initialize a card */
......
...@@ -2279,7 +2279,8 @@ static struct scsi_host_template driver_template = { ...@@ -2279,7 +2279,8 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = TW_MAX_CMDS_PER_LUN, .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.shost_attrs = tw_host_attrs, .shost_attrs = tw_host_attrs,
.emulated = 1 .emulated = 1,
.no_write_same = 1,
}; };
/* This function will probe and initialize a card */ /* This function will probe and initialize a card */
......
...@@ -1081,6 +1081,7 @@ static struct scsi_host_template aac_driver_template = { ...@@ -1081,6 +1081,7 @@ static struct scsi_host_template aac_driver_template = {
#endif #endif
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.emulated = 1, .emulated = 1,
.no_write_same = 1,
}; };
static void __aac_shutdown(struct aac_dev * aac) static void __aac_shutdown(struct aac_dev * aac)
......
...@@ -137,6 +137,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { ...@@ -137,6 +137,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
.cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.shost_attrs = arcmsr_host_attrs, .shost_attrs = arcmsr_host_attrs,
.no_write_same = 1,
}; };
static struct pci_device_id arcmsr_device_id_table[] = { static struct pci_device_id arcmsr_device_id_table[] = {
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)},
......
...@@ -4684,6 +4684,7 @@ static struct scsi_host_template gdth_template = { ...@@ -4684,6 +4684,7 @@ static struct scsi_host_template gdth_template = {
.cmd_per_lun = GDTH_MAXC_P_L, .cmd_per_lun = GDTH_MAXC_P_L,
.unchecked_isa_dma = 1, .unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.no_write_same = 1,
}; };
#ifdef CONFIG_ISA #ifdef CONFIG_ISA
......
...@@ -395,6 +395,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) ...@@ -395,6 +395,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->use_clustering = sht->use_clustering; shost->use_clustering = sht->use_clustering;
shost->ordered_tag = sht->ordered_tag; shost->ordered_tag = sht->ordered_tag;
shost->eh_deadline = shost_eh_deadline * HZ; shost->eh_deadline = shost_eh_deadline * HZ;
shost->no_write_same = sht->no_write_same;
if (sht->supported_mode == MODE_UNKNOWN) if (sht->supported_mode == MODE_UNKNOWN)
/* means we didn't set it ... default to INITIATOR */ /* means we didn't set it ... default to INITIATOR */
......
...@@ -561,6 +561,7 @@ static struct scsi_host_template hpsa_driver_template = { ...@@ -561,6 +561,7 @@ static struct scsi_host_template hpsa_driver_template = {
.sdev_attrs = hpsa_sdev_attrs, .sdev_attrs = hpsa_sdev_attrs,
.shost_attrs = hpsa_shost_attrs, .shost_attrs = hpsa_shost_attrs,
.max_sectors = 8192, .max_sectors = 8192,
.no_write_same = 1,
}; };
......
...@@ -6305,7 +6305,8 @@ static struct scsi_host_template driver_template = { ...@@ -6305,7 +6305,8 @@ static struct scsi_host_template driver_template = {
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.shost_attrs = ipr_ioa_attrs, .shost_attrs = ipr_ioa_attrs,
.sdev_attrs = ipr_dev_attrs, .sdev_attrs = ipr_dev_attrs,
.proc_name = IPR_NAME .proc_name = IPR_NAME,
.no_write_same = 1,
}; };
/** /**
......
...@@ -374,6 +374,7 @@ static struct scsi_host_template ips_driver_template = { ...@@ -374,6 +374,7 @@ static struct scsi_host_template ips_driver_template = {
.sg_tablesize = IPS_MAX_SG, .sg_tablesize = IPS_MAX_SG,
.cmd_per_lun = 3, .cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.no_write_same = 1,
}; };
......
...@@ -4244,6 +4244,7 @@ static struct scsi_host_template megaraid_template = { ...@@ -4244,6 +4244,7 @@ static struct scsi_host_template megaraid_template = {
.eh_device_reset_handler = megaraid_reset, .eh_device_reset_handler = megaraid_reset,
.eh_bus_reset_handler = megaraid_reset, .eh_bus_reset_handler = megaraid_reset,
.eh_host_reset_handler = megaraid_reset, .eh_host_reset_handler = megaraid_reset,
.no_write_same = 1,
}; };
static int static int
......
...@@ -367,6 +367,7 @@ static struct scsi_host_template megaraid_template_g = { ...@@ -367,6 +367,7 @@ static struct scsi_host_template megaraid_template_g = {
.eh_host_reset_handler = megaraid_reset_handler, .eh_host_reset_handler = megaraid_reset_handler,
.change_queue_depth = megaraid_change_queue_depth, .change_queue_depth = megaraid_change_queue_depth,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.no_write_same = 1,
.sdev_attrs = megaraid_sdev_attrs, .sdev_attrs = megaraid_sdev_attrs,
.shost_attrs = megaraid_shost_attrs, .shost_attrs = megaraid_shost_attrs,
}; };
......
...@@ -2148,6 +2148,7 @@ static struct scsi_host_template megasas_template = { ...@@ -2148,6 +2148,7 @@ static struct scsi_host_template megasas_template = {
.bios_param = megasas_bios_param, .bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.change_queue_depth = megasas_change_queue_depth, .change_queue_depth = megasas_change_queue_depth,
.no_write_same = 1,
}; };
/** /**
......
...@@ -4315,6 +4315,7 @@ static struct scsi_host_template pmcraid_host_template = { ...@@ -4315,6 +4315,7 @@ static struct scsi_host_template pmcraid_host_template = {
.this_id = -1, .this_id = -1,
.sg_tablesize = PMCRAID_MAX_IOADLS, .sg_tablesize = PMCRAID_MAX_IOADLS,
.max_sectors = PMCRAID_IOA_MAX_SECTORS, .max_sectors = PMCRAID_IOA_MAX_SECTORS,
.no_write_same = 1,
.cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN, .cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.shost_attrs = pmcraid_host_attrs, .shost_attrs = pmcraid_host_attrs,
......
...@@ -2659,6 +2659,12 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) ...@@ -2659,6 +2659,12 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
{ {
struct scsi_device *sdev = sdkp->device; struct scsi_device *sdev = sdkp->device;
if (sdev->host->no_write_same) {
sdev->no_write_same = 1;
return;
}
if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) { if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) {
/* too large values might cause issues with arcmsr */ /* too large values might cause issues with arcmsr */
int vpd_buf_len = 64; int vpd_buf_len = 64;
......
...@@ -1697,6 +1697,7 @@ static struct scsi_host_template scsi_driver = { ...@@ -1697,6 +1697,7 @@ static struct scsi_host_template scsi_driver = {
.use_clustering = DISABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
/* Make sure we dont get a sg segment crosses a page boundary */ /* Make sure we dont get a sg segment crosses a page boundary */
.dma_boundary = PAGE_SIZE-1, .dma_boundary = PAGE_SIZE-1,
.no_write_same = 1,
}; };
enum { enum {
......
...@@ -475,6 +475,9 @@ struct scsi_host_template { ...@@ -475,6 +475,9 @@ struct scsi_host_template {
*/ */
unsigned ordered_tag:1; unsigned ordered_tag:1;
/* True if the controller does not support WRITE SAME */
unsigned no_write_same:1;
/* /*
* Countdown for host blocking with no commands outstanding. * Countdown for host blocking with no commands outstanding.
*/ */
...@@ -677,6 +680,9 @@ struct Scsi_Host { ...@@ -677,6 +680,9 @@ struct Scsi_Host {
/* Don't resume host in EH */ /* Don't resume host in EH */
unsigned eh_noresume:1; unsigned eh_noresume:1;
/* The controller does not support WRITE SAME */
unsigned no_write_same:1;
/* /*
* Optional work queue to be utilized by the transport * Optional work queue to be utilized by the transport
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment