diff options
| author | Jeff Garzik <jgarzik@redhat.com> | 2003-11-10 00:41:12 -0500 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2003-11-10 00:41:12 -0500 |
| commit | ef38b911ed30878476f97f5d3cb87ae375366d99 (patch) | |
| tree | 1328779b73566d83351e34c21bc9ebdd397ff30f /drivers | |
| parent | 84a76754657b5c119d2fabcb153c2c4158d4e61b (diff) | |
[libata promise] fixes suggested by Promise
* flush host FIFO after sending data to DIMM window
* don't set SCR addresses, as the hardware doesn't have SCRs
(cosmetic)
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/scsi/sata_promise.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index edad0bf95576..2bad4c62b269 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -54,6 +54,7 @@ enum { PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */ PDC_20621_SEQCTL = 0x400, PDC_20621_SEQMASK = 0x480, + PDC_20621_GENERAL_CTL = 0x484, PDC_20621_PAGE_SIZE = (32 * 1024), /* chosen, not constant, values; we design our own DIMM mem map */ @@ -247,7 +248,7 @@ static int pdc_port_start(struct ata_port *ap) rc = ata_port_start(ap); if (rc) return rc; - + pp = kmalloc(sizeof(*pp), GFP_KERNEL); if (!pp) { rc = -ENOMEM; @@ -490,7 +491,7 @@ static inline void pdc20621_host_sg(struct ata_taskfile *tf, u8 *buf, buf32[dw], buf32[dw + 1]); } -static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf, +static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf, unsigned int devno, u8 *buf, unsigned int portno) { @@ -585,12 +586,17 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc) struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; struct pdc_port_priv *pp = ap->private_data; + void *mmio = ap->host_set->mmio_base; void *dimm_mmio = ap->host_set->private_data; unsigned int portno = ap->port_no; unsigned int i, last, idx, total_len = 0, sgt_len; u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; VPRINTK("ata%u: ENTER\n", ap->id); + + /* hard-code chip #0 */ + mmio += PDC_CHIP0_OFS; + /* * Build S/G table */ @@ -626,7 +632,12 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc) memcpy_toio(dimm_mmio + (portno * PDC_DIMM_WINDOW_STEP) + PDC_DIMM_HOST_PRD, &pp->dimm_buf[PDC_DIMM_HEADER_SZ], sgt_len); - readl(dimm_mmio); /* flush */ + + /* force host FIFO dump */ + writel(0x00000001, mmio + PDC_20621_GENERAL_CTL); + + readl(dimm_mmio); /* MMIO PCI posting flush */ + VPRINTK("ata pkt buf ofs %u, prd size %u, mmio copied\n", i, sgt_len); } @@ -731,7 +742,7 @@ static void pdc20621_dma_start(struct ata_queued_cmd *qc) writel(port_ofs + PDC_DIMM_ATA_PKT, (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); - VPRINTK("submitted ofs 0x%x (%u), seq %u\n", + VPRINTK("submitted ofs 0x%x (%u), seq %u\n", port_ofs + PDC_DIMM_ATA_PKT, port_ofs + PDC_DIMM_ATA_PKT, seq); @@ -795,7 +806,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); } - + /* step two - execute ATA command */ else { VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, @@ -1223,10 +1234,12 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * } pdc_sata_setup_port(&probe_ent->port[0], base + 0x200); - probe_ent->port[0].scr_addr = base + 0x400; - pdc_sata_setup_port(&probe_ent->port[1], base + 0x280); - probe_ent->port[1].scr_addr = base + 0x500; + + if (!have_20621) { + probe_ent->port[0].scr_addr = base + 0x400; + probe_ent->port[1].scr_addr = base + 0x500; + } /* notice 4-port boards */ switch (board_idx) { @@ -1235,10 +1248,12 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * probe_ent->n_ports = 4; pdc_sata_setup_port(&probe_ent->port[2], base + 0x300); - probe_ent->port[2].scr_addr = base + 0x600; - pdc_sata_setup_port(&probe_ent->port[3], base + 0x380); - probe_ent->port[3].scr_addr = base + 0x700; + + if (!have_20621) { + probe_ent->port[2].scr_addr = base + 0x600; + probe_ent->port[3].scr_addr = base + 0x700; + } break; case board_2037x: probe_ent->n_ports = 2; |
