static inline void rb500_pata_finish_io(struct ata_port *ap) { struct ata_host *ah = ap->host; struct rb500_cf_info *info = ah->private_data; ata_altstatus(ap); ndelay(RB500_CF_IO_DELAY); set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); }
static u8 scc_bmdma_status (struct ata_port *ap) { u8 host_stat; void __iomem *mmio = ap->ioaddr.bmdma_addr; host_stat = in_be32(mmio + SCC_DMA_STATUS); /* Workaround for PTERADD: emulate DMA_INTR when * - IDE_STATUS[ERR] = 1 * - INT_STATUS[INTRQ] = 1 * - DMA_STATUS[IORACTA] = 1 */ if (!(host_stat & ATA_DMA_INTR)) { u32 int_status = in_be32(mmio + SCC_DMA_INTST); if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ && host_stat & ATA_DMA_ACTIVE) host_stat |= ATA_DMA_INTR; } return host_stat; }
static void scc_bmdma_stop (struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR]; void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR]; u32 reg; while (1) { reg = in_be32(bmid_base + SCC_DMA_INTST); if (reg & INTSTS_SERROR) { printk(KERN_WARNING "%s: SERROR\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT); out_be32(bmid_base + SCC_DMA_CMD, in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); continue; } if (reg & INTSTS_PRERR) { u32 maea0, maec0; maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0); maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0); printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT); out_be32(bmid_base + SCC_DMA_CMD, in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); continue; } if (reg & INTSTS_RERR) { printk(KERN_WARNING "%s: Response Error\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT); out_be32(bmid_base + SCC_DMA_CMD, in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); continue; } if (reg & INTSTS_ICERR) { out_be32(bmid_base + SCC_DMA_CMD, in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT); continue; } if (reg & INTSTS_BMSINT) { unsigned int classes; printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME); out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT); /* TBD: SW reset */ scc_std_softreset(ap, &classes); continue; } if (reg & INTSTS_BMHE) { out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE); continue; } if (reg & INTSTS_ACTEINT) { out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT); continue; } if (reg & INTSTS_IOIRQS) { out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS); continue; } break; } /* clear start/stop bit */ out_be32(bmid_base + SCC_DMA_CMD, in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ ata_altstatus(ap); /* dummy read */ }