u32 tmp;
int work;
+ printk(KERN_WARNING "ata%u: port reset, "
+ "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n",
+ ap->id,
+ irq_stat,
+ readl(mmio + HOST_IRQ_STAT),
+ readl(port_mmio + PORT_IRQ_STAT),
+ readl(port_mmio + PORT_CMD),
+ readl(port_mmio + PORT_TFDATA),
+ readl(port_mmio + PORT_SCR_STAT),
+ readl(port_mmio + PORT_SCR_ERR));
+
/* stop DMA */
tmp = readl(port_mmio + PORT_CMD);
tmp &= ~PORT_CMD_START;
tmp |= PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
readl(port_mmio + PORT_CMD); /* flush */
-
- printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id);
}
static void ahci_eng_timeout(struct ata_port *ap)
struct ata_queued_cmd *qc;
unsigned long flags;
- DPRINTK("ENTER\n");
+ printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id);
spin_lock_irqsave(&host_set->lock, flags);
- ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
-
qc = ata_qc_from_tag(ap, ap->active_tag);
if (!qc) {
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
ap->id);
} else {
+ ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
+
/* hack alert! We cannot use the supplied completion
* function from inside the ->eh_strategy_handler() thread.
* libata is the only user of ->eh_strategy_handler() in
}
if (status & PORT_IRQ_FATAL) {
+ unsigned int err_mask;
+ if (status & PORT_IRQ_TF_ERR)
+ err_mask = AC_ERR_DEV;
+ else if (status & PORT_IRQ_IF_ERR)
+ err_mask = AC_ERR_ATA_BUS;
+ else
+ err_mask = AC_ERR_HOST_BUS;
+
+ /* command processing has stopped due to error; restart */
ahci_intr_error(ap, status);
+
if (qc)
- ata_qc_complete(qc, AC_ERR_OTHER);
+ ata_qc_complete(qc, err_mask);
}
return 1;