diff options
author | Jeff Garzik <jeff@garzik.org> | 2007-07-12 14:30:19 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-07-12 14:30:19 -0400 |
commit | 4537deb5e90b717a725b3d74b58b4bb1d28443d0 (patch) | |
tree | 7bb086d58f52e5271903cd934ae13f82e74b7aae /drivers/ata/sata_mv.c | |
parent | c5d3e45a2200a0905dc45b72714726b7aac3aaf1 (diff) |
[libata] sata_mv: minor bug fixes, enhancements, and cleanups (prep for new EH)
* Continue replacing "CONSTANT & var" tests with "var & CONSTANT"
* Don't clear EDMA_CFG_NCQ_GO_ON_ERR on Gen-IIE, where that bit does
not exist
* Set I/O Id field in descriptor, where present. Appears to work
fine on all versions, even though queueing is still disabled.
* call pci_set_mwi(), to (a) make sure cacheline size is set properly,
and (b) enable MWI transactions
* Remove never-used handling of coalescing interrupt bits (these events
are always masked)
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 23 |
1 files changed, 8 insertions, 15 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 8c554f2e69b0..7fa42c36c417 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -807,7 +807,7 @@ static int mv_stop_dma(struct ata_port *ap) | |||
807 | u32 reg; | 807 | u32 reg; |
808 | int i, err = 0; | 808 | int i, err = 0; |
809 | 809 | ||
810 | if (MV_PP_FLAG_EDMA_EN & pp->pp_flags) { | 810 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { |
811 | /* Disable EDMA if active. The disable bit auto clears. | 811 | /* Disable EDMA if active. The disable bit auto clears. |
812 | */ | 812 | */ |
813 | writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); | 813 | writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); |
@@ -819,9 +819,9 @@ static int mv_stop_dma(struct ata_port *ap) | |||
819 | /* now properly wait for the eDMA to stop */ | 819 | /* now properly wait for the eDMA to stop */ |
820 | for (i = 1000; i > 0; i--) { | 820 | for (i = 1000; i > 0; i--) { |
821 | reg = readl(port_mmio + EDMA_CMD_OFS); | 821 | reg = readl(port_mmio + EDMA_CMD_OFS); |
822 | if (!(EDMA_EN & reg)) { | 822 | if (!(reg & EDMA_EN)) |
823 | break; | 823 | break; |
824 | } | 824 | |
825 | udelay(100); | 825 | udelay(100); |
826 | } | 826 | } |
827 | 827 | ||
@@ -974,7 +974,7 @@ static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv, | |||
974 | cfg |= (1 << 18); /* enab early completion */ | 974 | cfg |= (1 << 18); /* enab early completion */ |
975 | cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */ | 975 | cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */ |
976 | cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */ | 976 | cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */ |
977 | cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */ | 977 | cfg &= ~(EDMA_CFG_NCQ); /* clear NCQ */ |
978 | } | 978 | } |
979 | 979 | ||
980 | writelfl(cfg, port_mmio + EDMA_CFG_OFS); | 980 | writelfl(cfg, port_mmio + EDMA_CFG_OFS); |
@@ -1143,6 +1143,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1143 | flags |= CRQB_FLAG_READ; | 1143 | flags |= CRQB_FLAG_READ; |
1144 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); | 1144 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); |
1145 | flags |= qc->tag << CRQB_TAG_SHIFT; | 1145 | flags |= qc->tag << CRQB_TAG_SHIFT; |
1146 | flags |= qc->tag << CRQB_IOID_SHIFT; /* 50xx appears to ignore this*/ | ||
1146 | 1147 | ||
1147 | /* get current queue index from hardware */ | 1148 | /* get current queue index from hardware */ |
1148 | in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) | 1149 | in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) |
@@ -1236,6 +1237,8 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
1236 | 1237 | ||
1237 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); | 1238 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); |
1238 | flags |= qc->tag << CRQB_TAG_SHIFT; | 1239 | flags |= qc->tag << CRQB_TAG_SHIFT; |
1240 | flags |= qc->tag << CRQB_IOID_SHIFT; /* "I/O Id" is -really- | ||
1241 | what we use as our tag */ | ||
1239 | 1242 | ||
1240 | /* get current queue index from hardware */ | 1243 | /* get current queue index from hardware */ |
1241 | in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) | 1244 | in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS) |
@@ -1525,7 +1528,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
1525 | struct ata_host *host = dev_instance; | 1528 | struct ata_host *host = dev_instance; |
1526 | unsigned int hc, handled = 0, n_hcs; | 1529 | unsigned int hc, handled = 0, n_hcs; |
1527 | void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; | 1530 | void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; |
1528 | struct mv_host_priv *hpriv; | ||
1529 | u32 irq_stat; | 1531 | u32 irq_stat; |
1530 | 1532 | ||
1531 | irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); | 1533 | irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); |
@@ -1547,16 +1549,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
1547 | } | 1549 | } |
1548 | } | 1550 | } |
1549 | 1551 | ||
1550 | hpriv = host->private_data; | ||
1551 | if (IS_60XX(hpriv)) { | ||
1552 | /* deal with the interrupt coalescing bits */ | ||
1553 | if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) { | ||
1554 | writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO); | ||
1555 | writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI); | ||
1556 | writelfl(0, mmio + MV_IRQ_COAL_CAUSE); | ||
1557 | } | ||
1558 | } | ||
1559 | |||
1560 | if (PCI_ERR & irq_stat) { | 1552 | if (PCI_ERR & irq_stat) { |
1561 | printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n", | 1553 | printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n", |
1562 | readl(mmio + PCI_IRQ_CAUSE_OFS)); | 1554 | readl(mmio + PCI_IRQ_CAUSE_OFS)); |
@@ -2474,6 +2466,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2474 | mv_print_info(host); | 2466 | mv_print_info(host); |
2475 | 2467 | ||
2476 | pci_set_master(pdev); | 2468 | pci_set_master(pdev); |
2469 | pci_set_mwi(pdev); | ||
2477 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, | 2470 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, |
2478 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); | 2471 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); |
2479 | } | 2472 | } |