diff options
Diffstat (limited to 'drivers/scsi/mvsas')
| -rw-r--r-- | drivers/scsi/mvsas/mv_94xx.c | 10 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_94xx.h | 58 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_init.c | 18 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_sas.c | 42 | ||||
| -rw-r--r-- | drivers/scsi/mvsas/mv_sas.h | 6 |
5 files changed, 78 insertions, 56 deletions
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 1e4479f3331..9270d15ff1a 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c @@ -564,7 +564,7 @@ static void mvs_94xx_interrupt_enable(struct mvs_info *mvi) u32 tmp; tmp = mr32(MVS_GBL_CTL); - tmp |= (IRQ_SAS_A | IRQ_SAS_B); + tmp |= (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B); mw32(MVS_GBL_INT_STAT, tmp); writel(tmp, regs + 0x0C); writel(tmp, regs + 0x10); @@ -580,7 +580,7 @@ static void mvs_94xx_interrupt_disable(struct mvs_info *mvi) tmp = mr32(MVS_GBL_CTL); - tmp &= ~(IRQ_SAS_A | IRQ_SAS_B); + tmp &= ~(MVS_IRQ_SAS_A | MVS_IRQ_SAS_B); mw32(MVS_GBL_INT_STAT, tmp); writel(tmp, regs + 0x0C); writel(tmp, regs + 0x10); @@ -596,7 +596,7 @@ static u32 mvs_94xx_isr_status(struct mvs_info *mvi, int irq) if (!(mvi->flags & MVF_FLAG_SOC)) { stat = mr32(MVS_GBL_INT_STAT); - if (!(stat & (IRQ_SAS_A | IRQ_SAS_B))) + if (!(stat & (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B))) return 0; } return stat; @@ -606,8 +606,8 @@ static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat) { void __iomem *regs = mvi->regs; - if (((stat & IRQ_SAS_A) && mvi->id == 0) || - ((stat & IRQ_SAS_B) && mvi->id == 1)) { + if (((stat & MVS_IRQ_SAS_A) && mvi->id == 0) || + ((stat & MVS_IRQ_SAS_B) && mvi->id == 1)) { mw32_f(MVS_INT_STAT, CINT_DONE); spin_lock(&mvi->lock); diff --git a/drivers/scsi/mvsas/mv_94xx.h b/drivers/scsi/mvsas/mv_94xx.h index 487aa6f9741..14e197497b4 100644 --- a/drivers/scsi/mvsas/mv_94xx.h +++ b/drivers/scsi/mvsas/mv_94xx.h @@ -150,35 +150,35 @@ enum chip_register_bits { enum pci_interrupt_cause { /* MAIN_IRQ_CAUSE (R10200) Bits*/ - IRQ_COM_IN_I2O_IOP0 = (1 << 0), - IRQ_COM_IN_I2O_IOP1 = (1 << 1), - IRQ_COM_IN_I2O_IOP2 = (1 << 2), - IRQ_COM_IN_I2O_IOP3 = (1 << 3), - IRQ_COM_OUT_I2O_HOS0 = (1 << 4), - IRQ_COM_OUT_I2O_HOS1 = (1 << 5), - IRQ_COM_OUT_I2O_HOS2 = (1 << 6), - IRQ_COM_OUT_I2O_HOS3 = (1 << 7), - IRQ_PCIF_TO_CPU_DRBL0 = (1 << 8), - IRQ_PCIF_TO_CPU_DRBL1 = (1 << 9), - IRQ_PCIF_TO_CPU_DRBL2 = (1 << 10), - IRQ_PCIF_TO_CPU_DRBL3 = (1 << 11), - IRQ_PCIF_DRBL0 = (1 << 12), - IRQ_PCIF_DRBL1 = (1 << 13), - IRQ_PCIF_DRBL2 = (1 << 14), - IRQ_PCIF_DRBL3 = (1 << 15), - IRQ_XOR_A = (1 << 16), - IRQ_XOR_B = (1 << 17), - IRQ_SAS_A = (1 << 18), - IRQ_SAS_B = (1 << 19), - IRQ_CPU_CNTRL = (1 << 20), - IRQ_GPIO = (1 << 21), - IRQ_UART = (1 << 22), - IRQ_SPI = (1 << 23), - IRQ_I2C = (1 << 24), - IRQ_SGPIO = (1 << 25), - IRQ_COM_ERR = (1 << 29), - IRQ_I2O_ERR = (1 << 30), - IRQ_PCIE_ERR = (1 << 31), + MVS_IRQ_COM_IN_I2O_IOP0 = (1 << 0), + MVS_IRQ_COM_IN_I2O_IOP1 = (1 << 1), + MVS_IRQ_COM_IN_I2O_IOP2 = (1 << 2), + MVS_IRQ_COM_IN_I2O_IOP3 = (1 << 3), + MVS_IRQ_COM_OUT_I2O_HOS0 = (1 << 4), + MVS_IRQ_COM_OUT_I2O_HOS1 = (1 << 5), + MVS_IRQ_COM_OUT_I2O_HOS2 = (1 << 6), + MVS_IRQ_COM_OUT_I2O_HOS3 = (1 << 7), + MVS_IRQ_PCIF_TO_CPU_DRBL0 = (1 << 8), + MVS_IRQ_PCIF_TO_CPU_DRBL1 = (1 << 9), + MVS_IRQ_PCIF_TO_CPU_DRBL2 = (1 << 10), + MVS_IRQ_PCIF_TO_CPU_DRBL3 = (1 << 11), + MVS_IRQ_PCIF_DRBL0 = (1 << 12), + MVS_IRQ_PCIF_DRBL1 = (1 << 13), + MVS_IRQ_PCIF_DRBL2 = (1 << 14), + MVS_IRQ_PCIF_DRBL3 = (1 << 15), + MVS_IRQ_XOR_A = (1 << 16), + MVS_IRQ_XOR_B = (1 << 17), + MVS_IRQ_SAS_A = (1 << 18), + MVS_IRQ_SAS_B = (1 << 19), + MVS_IRQ_CPU_CNTRL = (1 << 20), + MVS_IRQ_GPIO = (1 << 21), + MVS_IRQ_UART = (1 << 22), + MVS_IRQ_SPI = (1 << 23), + MVS_IRQ_I2C = (1 << 24), + MVS_IRQ_SGPIO = (1 << 25), + MVS_IRQ_COM_ERR = (1 << 29), + MVS_IRQ_I2O_ERR = (1 << 30), + MVS_IRQ_PCIE_ERR = (1 << 31), }; union reg_phy_cfg { diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index ce90d0546cd..eacee48a955 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -254,7 +254,7 @@ static int mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) } for (i = 0; i < MVS_MAX_DEVICES; i++) { mvi->devices[i].taskfileset = MVS_ID_NOT_MAPPED; - mvi->devices[i].dev_type = NO_DEVICE; + mvi->devices[i].dev_type = SAS_PHY_UNUSED; mvi->devices[i].device_id = i; mvi->devices[i].dev_status = MVS_DEV_NORMAL; init_timer(&mvi->devices[i].timer); @@ -657,7 +657,6 @@ static void mvs_pci_remove(struct pci_dev *pdev) tasklet_kill(&((struct mvs_prv_info *)sha->lldd_ha)->mv_tasklet); #endif - pci_set_drvdata(pdev, NULL); sas_unregister_ha(sha); sas_remove_host(mvi->shost); scsi_remove_host(mvi->shost); @@ -703,7 +702,7 @@ static struct pci_device_id mvs_pci_table[] = { { PCI_VDEVICE(TTI, 0x2744), chip_9480 }, { PCI_VDEVICE(TTI, 0x2760), chip_9480 }, { - .vendor = 0x1b4b, + .vendor = PCI_VENDOR_ID_MARVELL_EXT, .device = 0x9480, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, @@ -712,7 +711,7 @@ static struct pci_device_id mvs_pci_table[] = { .driver_data = chip_9480, }, { - .vendor = 0x1b4b, + .vendor = PCI_VENDOR_ID_MARVELL_EXT, .device = 0x9445, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, @@ -721,7 +720,7 @@ static struct pci_device_id mvs_pci_table[] = { .driver_data = chip_9445, }, { - .vendor = 0x1b4b, + .vendor = PCI_VENDOR_ID_MARVELL_EXT, .device = 0x9485, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, @@ -729,6 +728,15 @@ static struct pci_device_id mvs_pci_table[] = { .class_mask = 0, .driver_data = chip_9485, }, + { + .vendor = PCI_VENDOR_ID_MARVELL_EXT, + .device = 0x9485, + .subvendor = PCI_ANY_ID, + .subdevice = 0x9485, + .class = 0, + .class_mask = 0, + .driver_data = chip_9485, + }, { PCI_VDEVICE(OCZ, 0x1021), chip_9485}, /* OCZ RevoDrive3 */ { PCI_VDEVICE(OCZ, 0x1022), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */ { PCI_VDEVICE(OCZ, 0x1040), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */ diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 078c63913b5..6c1f223a8e1 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -316,10 +316,13 @@ static int mvs_task_prep_smp(struct mvs_info *mvi, struct mvs_task_exec_info *tei) { int elem, rc, i; + struct sas_ha_struct *sha = mvi->sas; struct sas_task *task = tei->task; struct mvs_cmd_hdr *hdr = tei->hdr; struct domain_device *dev = task->dev; struct asd_sas_port *sas_port = dev->port; + struct sas_phy *sphy = dev->phy; + struct asd_sas_phy *sas_phy = sha->sas_phy[sphy->number]; struct scatterlist *sg_req, *sg_resp; u32 req_len, resp_len, tag = tei->tag; void *buf_tmp; @@ -392,7 +395,7 @@ static int mvs_task_prep_smp(struct mvs_info *mvi, slot->tx = mvi->tx_prod; mvi->tx[mvi->tx_prod] = cpu_to_le32((TXQ_CMD_SMP << TXQ_CMD_SHIFT) | TXQ_MODE_I | tag | - (sas_port->phy_mask << TXQ_PHY_SHIFT)); + (MVS_PHY_ID << TXQ_PHY_SHIFT)); hdr->flags |= flags; hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | ((req_len - 4) / 4)); @@ -438,11 +441,14 @@ static u32 mvs_get_ncq_tag(struct sas_task *task, u32 *tag) static int mvs_task_prep_ata(struct mvs_info *mvi, struct mvs_task_exec_info *tei) { + struct sas_ha_struct *sha = mvi->sas; struct sas_task *task = tei->task; struct domain_device *dev = task->dev; struct mvs_device *mvi_dev = dev->lldd_dev; struct mvs_cmd_hdr *hdr = tei->hdr; struct asd_sas_port *sas_port = dev->port; + struct sas_phy *sphy = dev->phy; + struct asd_sas_phy *sas_phy = sha->sas_phy[sphy->number]; struct mvs_slot_info *slot; void *buf_prd; u32 tag = tei->tag, hdr_tag; @@ -462,7 +468,7 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, slot->tx = mvi->tx_prod; del_q = TXQ_MODE_I | tag | (TXQ_CMD_STP << TXQ_CMD_SHIFT) | - (sas_port->phy_mask << TXQ_PHY_SHIFT) | + (MVS_PHY_ID << TXQ_PHY_SHIFT) | (mvi_dev->taskfileset << TXQ_SRS_SHIFT); mvi->tx[mvi->tx_prod] = cpu_to_le32(del_q); @@ -680,7 +686,8 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, if (ssp_hdr->frame_type != SSP_TASK) { buf_cmd[9] = fburst | task->ssp_task.task_attr | (task->ssp_task.task_prio << 3); - memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16); + memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); } else{ buf_cmd[10] = tmf->tmf; switch (tmf->tmf) { @@ -700,7 +707,7 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, return 0; } -#define DEV_IS_GONE(mvi_dev) ((!mvi_dev || (mvi_dev->dev_type == NO_DEVICE))) +#define DEV_IS_GONE(mvi_dev) ((!mvi_dev || (mvi_dev->dev_type == SAS_PHY_UNUSED))) static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf, struct mvs_tmf_task *tmf, int *pass) { @@ -720,7 +727,7 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf * libsas will use dev->port, should * not call task_done for sata */ - if (dev->dev_type != SATA_DEV) + if (dev->dev_type != SAS_SATA_DEV) task->task_done(task); return rc; } @@ -1153,10 +1160,10 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) phy->identify.device_type = phy->att_dev_info & PORT_DEV_TYPE_MASK; - if (phy->identify.device_type == SAS_END_DEV) + if (phy->identify.device_type == SAS_END_DEVICE) phy->identify.target_port_protocols = SAS_PROTOCOL_SSP; - else if (phy->identify.device_type != NO_DEVICE) + else if (phy->identify.device_type != SAS_PHY_UNUSED) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; if (oob_done) @@ -1254,7 +1261,7 @@ struct mvs_device *mvs_alloc_dev(struct mvs_info *mvi) { u32 dev; for (dev = 0; dev < MVS_MAX_DEVICES; dev++) { - if (mvi->devices[dev].dev_type == NO_DEVICE) { + if (mvi->devices[dev].dev_type == SAS_PHY_UNUSED) { mvi->devices[dev].device_id = dev; return &mvi->devices[dev]; } @@ -1272,7 +1279,7 @@ void mvs_free_dev(struct mvs_device *mvi_dev) u32 id = mvi_dev->device_id; memset(mvi_dev, 0, sizeof(*mvi_dev)); mvi_dev->device_id = id; - mvi_dev->dev_type = NO_DEVICE; + mvi_dev->dev_type = SAS_PHY_UNUSED; mvi_dev->dev_status = MVS_DEV_NORMAL; mvi_dev->taskfileset = MVS_ID_NOT_MAPPED; } @@ -1404,7 +1411,7 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev, if (res) { del_timer(&task->slow_task->timer); - mv_printk("executing internel task failed:%d\n", res); + mv_printk("executing internal task failed:%d\n", res); goto ex_err; } @@ -1474,7 +1481,7 @@ static int mvs_debug_I_T_nexus_reset(struct domain_device *dev) { int rc; struct sas_phy *phy = sas_get_local_phy(dev); - int reset_type = (dev->dev_type == SATA_DEV || + int reset_type = (dev->dev_type == SAS_SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1; rc = sas_phy_reset(phy, reset_type); sas_put_local_phy(phy); @@ -1623,7 +1630,7 @@ int mvs_abort_task(struct sas_task *task) } else if (task->task_proto & SAS_PROTOCOL_SATA || task->task_proto & SAS_PROTOCOL_STP) { - if (SATA_DEV == dev->dev_type) { + if (SAS_SATA_DEV == dev->dev_type) { struct mvs_slot_info *slot = task->lldd_task; u32 slot_idx = (u32)(slot - mvi->slot_info); mv_dprintk("mvs_abort_task() mvi=%p task=%p " @@ -1850,11 +1857,16 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) goto out; } - /* error info record present */ - if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) { + /* + * error info record present; slot->response is 32 bit aligned but may + * not be 64 bit aligned, so check for zero in two 32 bit reads + */ + if (unlikely((rx_desc & RXQ_ERR) + && (*((u32 *)slot->response) + || *(((u32 *)slot->response) + 1)))) { mv_dprintk("port %d slot %d rx_desc %X has error info" "%016llX.\n", slot->port->sas_port.id, slot_idx, - rx_desc, (u64)(*(u64 *)slot->response)); + rx_desc, get_unaligned_le64(slot->response)); tstat->stat = mvs_slot_err(mvi, task, slot_idx); tstat->resp = SAS_TASK_COMPLETE; goto out; diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 2ae77a0394b..d6b19dc80be 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -39,6 +39,7 @@ #include <linux/irq.h> #include <linux/slab.h> #include <linux/vmalloc.h> +#include <asm/unaligned.h> #include <scsi/libsas.h> #include <scsi/scsi.h> #include <scsi/scsi_tcq.h> @@ -67,7 +68,7 @@ extern const struct mvs_dispatch mvs_94xx_dispatch; extern struct kmem_cache *mvs_task_list_cache; #define DEV_IS_EXPANDER(type) \ - ((type == EDGE_DEV) || (type == FANOUT_DEV)) + ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE)) #define bit(n) ((u64)1 << n) @@ -76,6 +77,7 @@ extern struct kmem_cache *mvs_task_list_cache; (__mc) != 0 ; \ (++__lseq), (__mc) >>= 1) +#define MVS_PHY_ID (1U << sas_phy->id) #define MV_INIT_DELAYED_WORK(w, f, d) INIT_DELAYED_WORK(w, f) #define UNASSOC_D2H_FIS(id) \ ((void *) mvi->rx_fis + 0x100 * id) @@ -240,7 +242,7 @@ struct mvs_phy { struct mvs_device { struct list_head dev_entry; - enum sas_dev_type dev_type; + enum sas_device_type dev_type; struct mvs_info *mvi_info; struct domain_device *sas_device; struct timer_list timer; |
