diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index c9318bda46a3..6544226c1b28 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -480,6 +480,35 @@ static void sil24_eng_timeout(struct ata_port *ap) sil24_reset_controller(ap); } +static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) +{ + struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); + struct sil24_port_priv *pp = ap->private_data; + void *port = pp->port; + u32 irq_stat, cmd_err, sstatus, serror; + + irq_stat = readl(port + PORT_IRQ_STAT); + cmd_err = readl(port + PORT_CMD_ERR); + sstatus = readl(port + PORT_SSTATUS); + serror = readl(port + PORT_SERROR); + + /* Clear IRQ/errors */ + writel(irq_stat, port + PORT_IRQ_STAT); + if (cmd_err) + writel(cmd_err, port + PORT_CMD_ERR); + if (serror) + writel(serror, port + PORT_SERROR); + + printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n" + " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", + ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); + + if (qc) + ata_qc_complete(qc, ATA_ERR); + + sil24_reset_controller(ap); +} + static inline void sil24_host_intr(struct ata_port *ap) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); @@ -491,30 +520,8 @@ static inline void sil24_host_intr(struct ata_port *ap) if (!(slot_stat & HOST_SSTAT_ATTN)) { if (qc) ata_qc_complete(qc, 0); - } else { - u32 irq_stat, cmd_err, sstatus, serror; - - irq_stat = readl(port + PORT_IRQ_STAT); - cmd_err = readl(port + PORT_CMD_ERR); - sstatus = readl(port + PORT_SSTATUS); - serror = readl(port + PORT_SERROR); - - /* Clear IRQ/errors */ - writel(irq_stat, port + PORT_IRQ_STAT); - if (cmd_err) - writel(cmd_err, port + PORT_CMD_ERR); - if (serror) - writel(serror, port + PORT_SERROR); - - printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n" - " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", - ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); - - if (qc) - ata_qc_complete(qc, ATA_ERR); - - sil24_reset_controller(ap); - } + } else + sil24_error_intr(ap, slot_stat); } static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)