Commit c2356212 authored by Jeff Garzik's avatar Jeff Garzik

[libata] PCI IDE DMA code shuffling

PCI IDE DMA standard (or "bmdma") helper routines ata_bmdma_stop,
ata_bmdma_ack_irq, and ata_bmdma_status are added to linux/libata.h,
and used in libata-core.

There is a minor behavior change, such that, the Alt Status register
is read before acknowledging the bmdma interrupt.  This should be ok,
and furthermore there will be more significant behavior changes
in this area coming soon.
parent 77ca20f2
...@@ -2115,22 +2115,6 @@ static void ata_pio_task(void *_data) ...@@ -2115,22 +2115,6 @@ static void ata_pio_task(void *_data)
} }
} }
/**
* ata_check_bmdma - read PCI IDE BMDMA status
* @ap: struct ata_port
*/
static u8 ata_check_bmdma(struct ata_port *ap)
{
u8 host_stat;
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = (void *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
return host_stat;
}
/** /**
* ata_eng_timeout - Handle timeout of queued command * ata_eng_timeout - Handle timeout of queued command
* @ap: Port on which timed-out command is active * @ap: Port on which timed-out command is active
...@@ -2174,7 +2158,7 @@ void ata_eng_timeout(struct ata_port *ap) ...@@ -2174,7 +2158,7 @@ void ata_eng_timeout(struct ata_port *ap)
switch (qc->tf.protocol) { switch (qc->tf.protocol) {
case ATA_PROT_DMA: case ATA_PROT_DMA:
host_stat = ata_check_bmdma(ap); host_stat = ata_bmdma_status(ap);
printk(KERN_ERR "ata%u: DMA timeout, stat 0x%x\n", printk(KERN_ERR "ata%u: DMA timeout, stat 0x%x\n",
ap->id, host_stat); ap->id, host_stat);
...@@ -2546,29 +2530,8 @@ static void ata_dma_complete(struct ata_queued_cmd *qc, u8 host_stat) ...@@ -2546,29 +2530,8 @@ static void ata_dma_complete(struct ata_queued_cmd *qc, u8 host_stat)
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
VPRINTK("ENTER\n"); VPRINTK("ENTER\n");
if (ap->flags & ATA_FLAG_MMIO) { ata_bmdma_stop(ap);
void *mmio = (void *) ap->ioaddr.bmdma_addr; ata_bmdma_ack_irq(ap);
/* clear start/stop bit */
writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
mmio + ATA_DMA_CMD);
/* ack intr, err bits */
writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
mmio + ATA_DMA_STATUS);
} else {
/* clear start/stop bit */
outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* ack intr, err bits */
outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus(ap); /* dummy read */
DPRINTK("host %u, host_stat==0x%X, drv_stat==0x%X\n", DPRINTK("host %u, host_stat==0x%X, drv_stat==0x%X\n",
ap->id, (u32) host_stat, (u32) ata_chk_status(ap)); ap->id, (u32) host_stat, (u32) ata_chk_status(ap));
...@@ -2604,7 +2567,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ...@@ -2604,7 +2567,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
/* BMDMA completion */ /* BMDMA completion */
case ATA_PROT_DMA: case ATA_PROT_DMA:
case ATA_PROT_ATAPI_DMA: case ATA_PROT_ATAPI_DMA:
host_stat = ata_check_bmdma(ap); host_stat = ata_bmdma_status(ap);
VPRINTK("BUS_DMA (host_stat 0x%X)\n", host_stat); VPRINTK("BUS_DMA (host_stat 0x%X)\n", host_stat);
if (!(host_stat & ATA_DMA_INTR)) { if (!(host_stat & ATA_DMA_INTR)) {
......
...@@ -541,4 +541,44 @@ static inline unsigned int sata_dev_present(struct ata_port *ap) ...@@ -541,4 +541,44 @@ static inline unsigned int sata_dev_present(struct ata_port *ap)
return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
} }
static inline void ata_bmdma_stop(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = (void *) ap->ioaddr.bmdma_addr;
/* clear start/stop bit */
writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
mmio + ATA_DMA_CMD);
} else {
/* clear start/stop bit */
outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus(ap); /* dummy read */
}
static inline void ata_bmdma_ack_irq(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = ((void *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
writeb(readb(mmio), mmio);
} else {
unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
outb(inb(addr), addr);
}
}
static inline u8 ata_bmdma_status(struct ata_port *ap)
{
u8 host_stat;
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = (void *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
return host_stat;
}
#endif /* __LINUX_LIBATA_H__ */ #endif /* __LINUX_LIBATA_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment