mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-05 03:44:03 +08:00
SCSI fixes on 20131206
This is a set of nine fixes (and one author update). The libsas one should fix discovery in eSATA devices, the WRITE_SAME one is the largest, but it should fix a lot of problems we've been getting with the emulated RAID devices (they've been effectively lying about support and then firmware has been choking on the commands). The rest are various crash, hang or warn driver fixes. Signed-off-by: James Bottomley <JBottomley@Parallels.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQEcBAABAgAGBQJSoeU/AAoJEDeqqVYsXL0McPkH/0PdSofj8emMfravBWM5knWk YPc+JnEYF+LaOmBYE7X4mEBGq4utbRll5IuFPxuw19X7cWS3A0uOE5cBvzOWKOIw 5xjGx5ik6rd04SRl/8wdERTtXJWUcTQFICjS+2IKogUyBuWgPOr+Ked2aDt2UXCQ zz1QkpLvE9ogKvVo8uuRynFDu7yCVCQB6QFAEiVxKSe+8IphfORQ3co3tczhWwPY Tp030xHEQFV6fKAO1ZnrtImih3tj5gp4Sp73x54FyjCYajWj95XkSplhAvGE/mXI xEGbtpuxHkVuS/+u1ziRuL3cVrgZvXRPyZAj3GSB4lOkrqA8danTStb+oRYbGCc= =nIqW -----END PGP SIGNATURE----- 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 nine fixes (and one author update). The libsas one should fix discovery in eSATA devices, the WRITE_SAME one is the largest, but it should fix a lot of problems we've been getting with the emulated RAID devices (they've been effectively lying about support and then firmware has been choking on the commands). The rest are various crash, hang or warn driver fixes" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: [SCSI] bfa: Fix crash when symb name set for offline vport [SCSI] enclosure: fix WARN_ON in dual path device removing [SCSI] pm80xx: Tasklets synchronization fix. [SCSI] pm80xx: Resetting the phy state. [SCSI] pm80xx: Fix for direct attached device. [SCSI] pm80xx: Module author addition [SCSI] hpsa: return 0 from driver probe function on success, not 1 [SCSI] hpsa: do not discard scsi status on aborted commands [SCSI] Disable WRITE SAME for RAID and virtual host adapter drivers [SCSI] libsas: fix usage of ata_tf_to_fis
This commit is contained in:
commit
7adfff587b
@ -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 = {
|
|||||||
.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>");
|
||||||
|
@ -198,6 +198,13 @@ static void enclosure_remove_links(struct enclosure_component *cdev)
|
|||||||
{
|
{
|
||||||
char name[ENCLOSURE_NAME_SIZE];
|
char name[ENCLOSURE_NAME_SIZE];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In odd circumstances, like multipath devices, something else may
|
||||||
|
* already have removed the links, so check for this condition first.
|
||||||
|
*/
|
||||||
|
if (!cdev->dev->kobj.sd)
|
||||||
|
return;
|
||||||
|
|
||||||
enclosure_link_name(cdev, name);
|
enclosure_link_name(cdev, name);
|
||||||
sysfs_remove_link(&cdev->dev->kobj, name);
|
sysfs_remove_link(&cdev->dev->kobj, name);
|
||||||
sysfs_remove_link(&cdev->cdev.kobj, "device");
|
sysfs_remove_link(&cdev->cdev.kobj, "device");
|
||||||
|
@ -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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
#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 = {
|
|||||||
.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)},
|
||||||
|
@ -296,6 +296,7 @@ wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn,
|
|||||||
struct bfa_fcs_lport_s *bfa_fcs_lookup_port(struct bfa_fcs_s *fcs,
|
struct bfa_fcs_lport_s *bfa_fcs_lookup_port(struct bfa_fcs_s *fcs,
|
||||||
u16 vf_id, wwn_t lpwwn);
|
u16 vf_id, wwn_t lpwwn);
|
||||||
|
|
||||||
|
void bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port, char *symname);
|
||||||
void bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
|
void bfa_fcs_lport_get_info(struct bfa_fcs_lport_s *port,
|
||||||
struct bfa_lport_info_s *port_info);
|
struct bfa_lport_info_s *port_info);
|
||||||
void bfa_fcs_lport_get_attr(struct bfa_fcs_lport_s *port,
|
void bfa_fcs_lport_get_attr(struct bfa_fcs_lport_s *port,
|
||||||
|
@ -1097,6 +1097,17 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
|
|||||||
bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
|
bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bfa_fcs_lport_set_symname(struct bfa_fcs_lport_s *port,
|
||||||
|
char *symname)
|
||||||
|
{
|
||||||
|
strcpy(port->port_cfg.sym_name.symname, symname);
|
||||||
|
|
||||||
|
if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
|
||||||
|
bfa_fcs_lport_ns_util_send_rspn_id(
|
||||||
|
BFA_FCS_GET_NS_FROM_PORT(port), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fcs_lport_api
|
* fcs_lport_api
|
||||||
*/
|
*/
|
||||||
@ -5140,9 +5151,6 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
|
|||||||
u8 *psymbl = &symbl[0];
|
u8 *psymbl = &symbl[0];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Avoid sending RSPN in the following states. */
|
/* Avoid sending RSPN in the following states. */
|
||||||
if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
|
if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
|
||||||
bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
|
bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
|
||||||
|
@ -593,11 +593,8 @@ bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
spin_lock_irqsave(&bfad->bfad_lock, flags);
|
||||||
if (strlen(sym_name) > 0) {
|
if (strlen(sym_name) > 0)
|
||||||
strcpy(fcs_vport->lport.port_cfg.sym_name.symname, sym_name);
|
bfa_fcs_lport_set_symname(&fcs_vport->lport, sym_name);
|
||||||
bfa_fcs_lport_ns_util_send_rspn_id(
|
|
||||||
BFA_FCS_GET_NS_FROM_PORT((&fcs_vport->lport)), NULL);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
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 = {
|
|||||||
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1288,7 +1289,7 @@ static void complete_scsi_command(struct CommandList *cp)
|
|||||||
"has check condition: aborted command: "
|
"has check condition: aborted command: "
|
||||||
"ASC: 0x%x, ASCQ: 0x%x\n",
|
"ASC: 0x%x, ASCQ: 0x%x\n",
|
||||||
cp, asc, ascq);
|
cp, asc, ascq);
|
||||||
cmd->result = DID_SOFT_ERROR << 16;
|
cmd->result |= DID_SOFT_ERROR << 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Must be some other type of check condition */
|
/* Must be some other type of check condition */
|
||||||
@ -4925,7 +4926,7 @@ reinit_after_soft_reset:
|
|||||||
hpsa_hba_inquiry(h);
|
hpsa_hba_inquiry(h);
|
||||||
hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
|
hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
|
||||||
start_controller_lockup_detector(h);
|
start_controller_lockup_detector(h);
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
clean4:
|
clean4:
|
||||||
hpsa_free_sg_chain_blocks(h);
|
hpsa_free_sg_chain_blocks(h);
|
||||||
|
@ -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 = {
|
|||||||
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
|
|||||||
qc->tf.nsect = 0;
|
qc->tf.nsect = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis);
|
ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *)&task->ata_task.fis);
|
||||||
task->uldd_task = qc;
|
task->uldd_task = qc;
|
||||||
if (ata_is_atapi(qc->tf.protocol)) {
|
if (ata_is_atapi(qc->tf.protocol)) {
|
||||||
memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
|
memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
|
||||||
|
@ -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 = {
|
|||||||
.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 = {
|
|||||||
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3403,6 +3403,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u8 deviceType = pPayload->sas_identify.dev_type;
|
u8 deviceType = pPayload->sas_identify.dev_type;
|
||||||
port->port_state = portstate;
|
port->port_state = portstate;
|
||||||
|
phy->phy_state = PHY_STATE_LINK_UP_SPC;
|
||||||
PM8001_MSG_DBG(pm8001_ha,
|
PM8001_MSG_DBG(pm8001_ha,
|
||||||
pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n",
|
pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n",
|
||||||
port_id, phy_id));
|
port_id, phy_id));
|
||||||
@ -3483,6 +3484,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|||||||
pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d,"
|
pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d,"
|
||||||
" phy id = %d\n", port_id, phy_id));
|
" phy id = %d\n", port_id, phy_id));
|
||||||
port->port_state = portstate;
|
port->port_state = portstate;
|
||||||
|
phy->phy_state = PHY_STATE_LINK_UP_SPC;
|
||||||
port->port_attached = 1;
|
port->port_attached = 1;
|
||||||
pm8001_get_lrate_mode(phy, link_rate);
|
pm8001_get_lrate_mode(phy, link_rate);
|
||||||
phy->phy_type |= PORT_TYPE_SATA;
|
phy->phy_type |= PORT_TYPE_SATA;
|
||||||
|
@ -131,6 +131,10 @@
|
|||||||
#define LINKRATE_30 (0x02 << 8)
|
#define LINKRATE_30 (0x02 << 8)
|
||||||
#define LINKRATE_60 (0x04 << 8)
|
#define LINKRATE_60 (0x04 << 8)
|
||||||
|
|
||||||
|
/* for phy state */
|
||||||
|
|
||||||
|
#define PHY_STATE_LINK_UP_SPC 0x1
|
||||||
|
|
||||||
/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */
|
/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */
|
||||||
#define GSM_SM_BASE 0x4F0000
|
#define GSM_SM_BASE 0x4F0000
|
||||||
struct mpi_msg_hdr{
|
struct mpi_msg_hdr{
|
||||||
|
@ -175,20 +175,16 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
|
|||||||
static void pm8001_tasklet(unsigned long opaque)
|
static void pm8001_tasklet(unsigned long opaque)
|
||||||
{
|
{
|
||||||
struct pm8001_hba_info *pm8001_ha;
|
struct pm8001_hba_info *pm8001_ha;
|
||||||
u32 vec;
|
struct isr_param *irq_vector;
|
||||||
pm8001_ha = (struct pm8001_hba_info *)opaque;
|
|
||||||
|
irq_vector = (struct isr_param *)opaque;
|
||||||
|
pm8001_ha = irq_vector->drv_inst;
|
||||||
if (unlikely(!pm8001_ha))
|
if (unlikely(!pm8001_ha))
|
||||||
BUG_ON(1);
|
BUG_ON(1);
|
||||||
vec = pm8001_ha->int_vector;
|
PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id);
|
||||||
PM8001_CHIP_DISP->isr(pm8001_ha, vec);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct pm8001_hba_info *outq_to_hba(u8 *outq)
|
|
||||||
{
|
|
||||||
return container_of((outq - *outq), struct pm8001_hba_info, outq[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pm8001_interrupt_handler_msix - main MSIX interrupt handler.
|
* pm8001_interrupt_handler_msix - main MSIX interrupt handler.
|
||||||
* It obtains the vector number and calls the equivalent bottom
|
* It obtains the vector number and calls the equivalent bottom
|
||||||
@ -198,18 +194,20 @@ static struct pm8001_hba_info *outq_to_hba(u8 *outq)
|
|||||||
*/
|
*/
|
||||||
static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque)
|
static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque)
|
||||||
{
|
{
|
||||||
struct pm8001_hba_info *pm8001_ha = outq_to_hba(opaque);
|
struct isr_param *irq_vector;
|
||||||
u8 outq = *(u8 *)opaque;
|
struct pm8001_hba_info *pm8001_ha;
|
||||||
irqreturn_t ret = IRQ_HANDLED;
|
irqreturn_t ret = IRQ_HANDLED;
|
||||||
|
irq_vector = (struct isr_param *)opaque;
|
||||||
|
pm8001_ha = irq_vector->drv_inst;
|
||||||
|
|
||||||
if (unlikely(!pm8001_ha))
|
if (unlikely(!pm8001_ha))
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
|
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
pm8001_ha->int_vector = outq;
|
|
||||||
#ifdef PM8001_USE_TASKLET
|
#ifdef PM8001_USE_TASKLET
|
||||||
tasklet_schedule(&pm8001_ha->tasklet);
|
tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id]);
|
||||||
#else
|
#else
|
||||||
ret = PM8001_CHIP_DISP->isr(pm8001_ha, outq);
|
ret = PM8001_CHIP_DISP->isr(pm8001_ha, irq_vector->irq_id);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -230,9 +228,8 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id)
|
|||||||
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
|
if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha))
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
pm8001_ha->int_vector = 0;
|
|
||||||
#ifdef PM8001_USE_TASKLET
|
#ifdef PM8001_USE_TASKLET
|
||||||
tasklet_schedule(&pm8001_ha->tasklet);
|
tasklet_schedule(&pm8001_ha->tasklet[0]);
|
||||||
#else
|
#else
|
||||||
ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0);
|
ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -457,7 +454,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
|
|||||||
{
|
{
|
||||||
struct pm8001_hba_info *pm8001_ha;
|
struct pm8001_hba_info *pm8001_ha;
|
||||||
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
|
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
|
||||||
|
int j;
|
||||||
|
|
||||||
pm8001_ha = sha->lldd_ha;
|
pm8001_ha = sha->lldd_ha;
|
||||||
if (!pm8001_ha)
|
if (!pm8001_ha)
|
||||||
@ -480,12 +477,14 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
|
|||||||
pm8001_ha->iomb_size = IOMB_SIZE_SPC;
|
pm8001_ha->iomb_size = IOMB_SIZE_SPC;
|
||||||
|
|
||||||
#ifdef PM8001_USE_TASKLET
|
#ifdef PM8001_USE_TASKLET
|
||||||
/**
|
/* Tasklet for non msi-x interrupt handler */
|
||||||
* default tasklet for non msi-x interrupt handler/first msi-x
|
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||||
* interrupt handler
|
tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
|
||||||
**/
|
(unsigned long)&(pm8001_ha->irq_vector[0]));
|
||||||
tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet,
|
else
|
||||||
(unsigned long)pm8001_ha);
|
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
|
||||||
|
tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
|
||||||
|
(unsigned long)&(pm8001_ha->irq_vector[j]));
|
||||||
#endif
|
#endif
|
||||||
pm8001_ioremap(pm8001_ha);
|
pm8001_ioremap(pm8001_ha);
|
||||||
if (!pm8001_alloc(pm8001_ha, ent))
|
if (!pm8001_alloc(pm8001_ha, ent))
|
||||||
@ -733,19 +732,20 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
|
|||||||
"pci_enable_msix request ret:%d no of intr %d\n",
|
"pci_enable_msix request ret:%d no of intr %d\n",
|
||||||
rc, pm8001_ha->number_of_intr));
|
rc, pm8001_ha->number_of_intr));
|
||||||
|
|
||||||
for (i = 0; i < number_of_intr; i++)
|
|
||||||
pm8001_ha->outq[i] = i;
|
|
||||||
|
|
||||||
for (i = 0; i < number_of_intr; i++) {
|
for (i = 0; i < number_of_intr; i++) {
|
||||||
snprintf(intr_drvname[i], sizeof(intr_drvname[0]),
|
snprintf(intr_drvname[i], sizeof(intr_drvname[0]),
|
||||||
DRV_NAME"%d", i);
|
DRV_NAME"%d", i);
|
||||||
|
pm8001_ha->irq_vector[i].irq_id = i;
|
||||||
|
pm8001_ha->irq_vector[i].drv_inst = pm8001_ha;
|
||||||
|
|
||||||
if (request_irq(pm8001_ha->msix_entries[i].vector,
|
if (request_irq(pm8001_ha->msix_entries[i].vector,
|
||||||
pm8001_interrupt_handler_msix, flag,
|
pm8001_interrupt_handler_msix, flag,
|
||||||
intr_drvname[i], &pm8001_ha->outq[i])) {
|
intr_drvname[i], &(pm8001_ha->irq_vector[i]))) {
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
free_irq(
|
free_irq(
|
||||||
pm8001_ha->msix_entries[j].vector,
|
pm8001_ha->msix_entries[j].vector,
|
||||||
&pm8001_ha->outq[j]);
|
&(pm8001_ha->irq_vector[i]));
|
||||||
pci_disable_msix(pm8001_ha->pdev);
|
pci_disable_msix(pm8001_ha->pdev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -907,7 +907,7 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
|
|||||||
{
|
{
|
||||||
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
|
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
|
||||||
struct pm8001_hba_info *pm8001_ha;
|
struct pm8001_hba_info *pm8001_ha;
|
||||||
int i;
|
int i, j;
|
||||||
pm8001_ha = sha->lldd_ha;
|
pm8001_ha = sha->lldd_ha;
|
||||||
sas_unregister_ha(sha);
|
sas_unregister_ha(sha);
|
||||||
sas_remove_host(pm8001_ha->shost);
|
sas_remove_host(pm8001_ha->shost);
|
||||||
@ -921,13 +921,18 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
|
|||||||
synchronize_irq(pm8001_ha->msix_entries[i].vector);
|
synchronize_irq(pm8001_ha->msix_entries[i].vector);
|
||||||
for (i = 0; i < pm8001_ha->number_of_intr; i++)
|
for (i = 0; i < pm8001_ha->number_of_intr; i++)
|
||||||
free_irq(pm8001_ha->msix_entries[i].vector,
|
free_irq(pm8001_ha->msix_entries[i].vector,
|
||||||
&pm8001_ha->outq[i]);
|
&(pm8001_ha->irq_vector[i]));
|
||||||
pci_disable_msix(pdev);
|
pci_disable_msix(pdev);
|
||||||
#else
|
#else
|
||||||
free_irq(pm8001_ha->irq, sha);
|
free_irq(pm8001_ha->irq, sha);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PM8001_USE_TASKLET
|
#ifdef PM8001_USE_TASKLET
|
||||||
tasklet_kill(&pm8001_ha->tasklet);
|
/* For non-msix and msix interrupts */
|
||||||
|
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||||
|
tasklet_kill(&pm8001_ha->tasklet[0]);
|
||||||
|
else
|
||||||
|
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
|
||||||
|
tasklet_kill(&pm8001_ha->tasklet[j]);
|
||||||
#endif
|
#endif
|
||||||
pm8001_free(pm8001_ha);
|
pm8001_free(pm8001_ha);
|
||||||
kfree(sha->sas_phy);
|
kfree(sha->sas_phy);
|
||||||
@ -948,7 +953,7 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||||||
{
|
{
|
||||||
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
|
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
|
||||||
struct pm8001_hba_info *pm8001_ha;
|
struct pm8001_hba_info *pm8001_ha;
|
||||||
int i;
|
int i, j;
|
||||||
u32 device_state;
|
u32 device_state;
|
||||||
pm8001_ha = sha->lldd_ha;
|
pm8001_ha = sha->lldd_ha;
|
||||||
flush_workqueue(pm8001_wq);
|
flush_workqueue(pm8001_wq);
|
||||||
@ -964,13 +969,18 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||||||
synchronize_irq(pm8001_ha->msix_entries[i].vector);
|
synchronize_irq(pm8001_ha->msix_entries[i].vector);
|
||||||
for (i = 0; i < pm8001_ha->number_of_intr; i++)
|
for (i = 0; i < pm8001_ha->number_of_intr; i++)
|
||||||
free_irq(pm8001_ha->msix_entries[i].vector,
|
free_irq(pm8001_ha->msix_entries[i].vector,
|
||||||
&pm8001_ha->outq[i]);
|
&(pm8001_ha->irq_vector[i]));
|
||||||
pci_disable_msix(pdev);
|
pci_disable_msix(pdev);
|
||||||
#else
|
#else
|
||||||
free_irq(pm8001_ha->irq, sha);
|
free_irq(pm8001_ha->irq, sha);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PM8001_USE_TASKLET
|
#ifdef PM8001_USE_TASKLET
|
||||||
tasklet_kill(&pm8001_ha->tasklet);
|
/* For non-msix and msix interrupts */
|
||||||
|
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||||
|
tasklet_kill(&pm8001_ha->tasklet[0]);
|
||||||
|
else
|
||||||
|
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
|
||||||
|
tasklet_kill(&pm8001_ha->tasklet[j]);
|
||||||
#endif
|
#endif
|
||||||
device_state = pci_choose_state(pdev, state);
|
device_state = pci_choose_state(pdev, state);
|
||||||
pm8001_printk("pdev=0x%p, slot=%s, entering "
|
pm8001_printk("pdev=0x%p, slot=%s, entering "
|
||||||
@ -993,7 +1003,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
|
|||||||
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
|
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
|
||||||
struct pm8001_hba_info *pm8001_ha;
|
struct pm8001_hba_info *pm8001_ha;
|
||||||
int rc;
|
int rc;
|
||||||
u8 i = 0;
|
u8 i = 0, j;
|
||||||
u32 device_state;
|
u32 device_state;
|
||||||
pm8001_ha = sha->lldd_ha;
|
pm8001_ha = sha->lldd_ha;
|
||||||
device_state = pdev->current_state;
|
device_state = pdev->current_state;
|
||||||
@ -1033,10 +1043,14 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto err_out_disable;
|
goto err_out_disable;
|
||||||
#ifdef PM8001_USE_TASKLET
|
#ifdef PM8001_USE_TASKLET
|
||||||
/* default tasklet for non msi-x interrupt handler/first msi-x
|
/* Tasklet for non msi-x interrupt handler */
|
||||||
* interrupt handler */
|
if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001))
|
||||||
tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet,
|
tasklet_init(&pm8001_ha->tasklet[0], pm8001_tasklet,
|
||||||
(unsigned long)pm8001_ha);
|
(unsigned long)&(pm8001_ha->irq_vector[0]));
|
||||||
|
else
|
||||||
|
for (j = 0; j < PM8001_MAX_MSIX_VEC; j++)
|
||||||
|
tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
|
||||||
|
(unsigned long)&(pm8001_ha->irq_vector[j]));
|
||||||
#endif
|
#endif
|
||||||
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0);
|
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0);
|
||||||
if (pm8001_ha->chip_id != chip_8001) {
|
if (pm8001_ha->chip_id != chip_8001) {
|
||||||
@ -1169,6 +1183,7 @@ module_exit(pm8001_exit);
|
|||||||
MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>");
|
MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>");
|
||||||
MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>");
|
MODULE_AUTHOR("Anand Kumar Santhanam <AnandKumar.Santhanam@pmcs.com>");
|
||||||
MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>");
|
MODULE_AUTHOR("Sangeetha Gnanasekaran <Sangeetha.Gnanasekaran@pmcs.com>");
|
||||||
|
MODULE_AUTHOR("Nikith Ganigarakoppal <Nikith.Ganigarakoppal@pmcs.com>");
|
||||||
MODULE_DESCRIPTION(
|
MODULE_DESCRIPTION(
|
||||||
"PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 "
|
"PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 "
|
||||||
"SAS/SATA controller driver");
|
"SAS/SATA controller driver");
|
||||||
|
@ -1098,15 +1098,17 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun)
|
|||||||
struct pm8001_tmf_task tmf_task;
|
struct pm8001_tmf_task tmf_task;
|
||||||
struct pm8001_device *pm8001_dev = dev->lldd_dev;
|
struct pm8001_device *pm8001_dev = dev->lldd_dev;
|
||||||
struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev);
|
struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev);
|
||||||
|
DECLARE_COMPLETION_ONSTACK(completion_setstate);
|
||||||
if (dev_is_sata(dev)) {
|
if (dev_is_sata(dev)) {
|
||||||
struct sas_phy *phy = sas_get_local_phy(dev);
|
struct sas_phy *phy = sas_get_local_phy(dev);
|
||||||
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
|
rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
|
||||||
dev, 1, 0);
|
dev, 1, 0);
|
||||||
rc = sas_phy_reset(phy, 1);
|
rc = sas_phy_reset(phy, 1);
|
||||||
sas_put_local_phy(phy);
|
sas_put_local_phy(phy);
|
||||||
|
pm8001_dev->setds_completion = &completion_setstate;
|
||||||
rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
|
rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
|
||||||
pm8001_dev, 0x01);
|
pm8001_dev, 0x01);
|
||||||
msleep(2000);
|
wait_for_completion(&completion_setstate);
|
||||||
} else {
|
} else {
|
||||||
tmf_task.tmf = TMF_LU_RESET;
|
tmf_task.tmf = TMF_LU_RESET;
|
||||||
rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
|
rc = pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
|
||||||
|
@ -466,6 +466,10 @@ struct pm8001_hba_memspace {
|
|||||||
u64 membase;
|
u64 membase;
|
||||||
u32 memsize;
|
u32 memsize;
|
||||||
};
|
};
|
||||||
|
struct isr_param {
|
||||||
|
struct pm8001_hba_info *drv_inst;
|
||||||
|
u32 irq_id;
|
||||||
|
};
|
||||||
struct pm8001_hba_info {
|
struct pm8001_hba_info {
|
||||||
char name[PM8001_NAME_LENGTH];
|
char name[PM8001_NAME_LENGTH];
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
@ -519,14 +523,13 @@ struct pm8001_hba_info {
|
|||||||
int number_of_intr;/*will be used in remove()*/
|
int number_of_intr;/*will be used in remove()*/
|
||||||
#endif
|
#endif
|
||||||
#ifdef PM8001_USE_TASKLET
|
#ifdef PM8001_USE_TASKLET
|
||||||
struct tasklet_struct tasklet;
|
struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC];
|
||||||
#endif
|
#endif
|
||||||
u32 logging_level;
|
u32 logging_level;
|
||||||
u32 fw_status;
|
u32 fw_status;
|
||||||
u32 smp_exp_mode;
|
u32 smp_exp_mode;
|
||||||
u32 int_vector;
|
|
||||||
const struct firmware *fw_image;
|
const struct firmware *fw_image;
|
||||||
u8 outq[PM8001_MAX_MSIX_VEC];
|
struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pm8001_work {
|
struct pm8001_work {
|
||||||
|
@ -2894,6 +2894,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u8 deviceType = pPayload->sas_identify.dev_type;
|
u8 deviceType = pPayload->sas_identify.dev_type;
|
||||||
port->port_state = portstate;
|
port->port_state = portstate;
|
||||||
|
phy->phy_state = PHY_STATE_LINK_UP_SPCV;
|
||||||
PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
|
PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
|
||||||
"portid:%d; phyid:%d; linkrate:%d; "
|
"portid:%d; phyid:%d; linkrate:%d; "
|
||||||
"portstate:%x; devicetype:%x\n",
|
"portstate:%x; devicetype:%x\n",
|
||||||
@ -2978,6 +2979,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|||||||
port_id, phy_id, link_rate, portstate));
|
port_id, phy_id, link_rate, portstate));
|
||||||
|
|
||||||
port->port_state = portstate;
|
port->port_state = portstate;
|
||||||
|
phy->phy_state = PHY_STATE_LINK_UP_SPCV;
|
||||||
port->port_attached = 1;
|
port->port_attached = 1;
|
||||||
pm8001_get_lrate_mode(phy, link_rate);
|
pm8001_get_lrate_mode(phy, link_rate);
|
||||||
phy->phy_type |= PORT_TYPE_SATA;
|
phy->phy_type |= PORT_TYPE_SATA;
|
||||||
|
@ -215,6 +215,8 @@
|
|||||||
#define SAS_DOPNRJT_RTRY_TMO 128
|
#define SAS_DOPNRJT_RTRY_TMO 128
|
||||||
#define SAS_COPNRJT_RTRY_TMO 128
|
#define SAS_COPNRJT_RTRY_TMO 128
|
||||||
|
|
||||||
|
/* for phy state */
|
||||||
|
#define PHY_STATE_LINK_UP_SPCV 0x2
|
||||||
/*
|
/*
|
||||||
Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
|
Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
|
||||||
Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128
|
Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128
|
||||||
|
@ -4325,6 +4325,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)
|
|||||||
{
|
{
|
||||||
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 = {
|
|||||||
.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 {
|
|||||||
*/
|
*/
|
||||||
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 {
|
|||||||
/* 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
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user