static void sata_dwc_error_intr(struct ata_port *ap, struct sata_dwc_device *hsdev, uint intpr) { struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); struct ata_eh_info *ehi = &ap->link.eh_info; unsigned int err_mask = 0, action = 0; struct ata_queued_cmd *qc; u32 serror; u8 status, tag; u32 err_reg; ata_ehi_clear_desc(ehi); serror = core_scr_read(SCR_ERROR); status = ap->ops->sff_check_status(ap); err_reg = in_le32(&(host_pvt.sata_dma_regs->interrupt_status.error.\ low)); tag = ap->link.active_tag; dev_err(ap->dev, "%s SCR_ERROR=0x%08x intpr=0x%08x status=0x%08x " "dma_intp=%d pending=%d issued=%d dma_err_status=0x%08x\n", __func__, serror, intpr, status, host_pvt.dma_interrupt_count, hsdevp->dma_pending[tag], hsdevp->cmd_issued[tag], err_reg); clear_serror(); clear_interrupt_bit(hsdev, SATA_DWC_INTPR_ERR); err_mask |= AC_ERR_HOST_BUS; action |= ATA_EH_RESET; ehi->serror |= serror; ehi->action |= action; qc = ata_qc_from_tag(ap, tag); if (qc) qc->err_mask |= err_mask; else ehi->err_mask |= err_mask; ata_port_abort(ap); }
static void inic_host_intr(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); struct ata_eh_info *ehi = &ap->link.eh_info; u8 irq_stat; /* fetch and clear irq */ irq_stat = readb(port_base + PORT_IRQ_STAT); writeb(irq_stat, port_base + PORT_IRQ_STAT); if (likely(!(irq_stat & PIRQ_ERR))) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { ata_chk_status(ap); /* clear ATA interrupt */ return; } if (likely(ata_host_intr(ap, qc))) return; ata_chk_status(ap); /* clear ATA interrupt */ ata_port_printk(ap, KERN_WARNING, "unhandled " "interrupt, irq_stat=%x\n", irq_stat); return; } /* error */ ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat); if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) { ata_ehi_hotplugged(ehi); ata_port_freeze(ap); } else ata_port_abort(ap); }