summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@redhat.com>2003-11-10 00:41:12 -0500
committerJeff Garzik <jgarzik@redhat.com>2003-11-10 00:41:12 -0500
commitef38b911ed30878476f97f5d3cb87ae375366d99 (patch)
tree1328779b73566d83351e34c21bc9ebdd397ff30f /drivers
parent84a76754657b5c119d2fabcb153c2c4158d4e61b (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.c37
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;