diff options
Diffstat (limited to 'drivers/scsi/sata_sil24.c')
-rw-r--r-- | drivers/scsi/sata_sil24.c | 55 |
1 files changed, 31 insertions, 24 deletions
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) | |||
480 | sil24_reset_controller(ap); | 480 | sil24_reset_controller(ap); |
481 | } | 481 | } |
482 | 482 | ||
483 | static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) | ||
484 | { | ||
485 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); | ||
486 | struct sil24_port_priv *pp = ap->private_data; | ||
487 | void *port = pp->port; | ||
488 | u32 irq_stat, cmd_err, sstatus, serror; | ||
489 | |||
490 | irq_stat = readl(port + PORT_IRQ_STAT); | ||
491 | cmd_err = readl(port + PORT_CMD_ERR); | ||
492 | sstatus = readl(port + PORT_SSTATUS); | ||
493 | serror = readl(port + PORT_SERROR); | ||
494 | |||
495 | /* Clear IRQ/errors */ | ||
496 | writel(irq_stat, port + PORT_IRQ_STAT); | ||
497 | if (cmd_err) | ||
498 | writel(cmd_err, port + PORT_CMD_ERR); | ||
499 | if (serror) | ||
500 | writel(serror, port + PORT_SERROR); | ||
501 | |||
502 | printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n" | ||
503 | " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", | ||
504 | ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); | ||
505 | |||
506 | if (qc) | ||
507 | ata_qc_complete(qc, ATA_ERR); | ||
508 | |||
509 | sil24_reset_controller(ap); | ||
510 | } | ||
511 | |||
483 | static inline void sil24_host_intr(struct ata_port *ap) | 512 | static inline void sil24_host_intr(struct ata_port *ap) |
484 | { | 513 | { |
485 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); | 514 | 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) | |||
491 | if (!(slot_stat & HOST_SSTAT_ATTN)) { | 520 | if (!(slot_stat & HOST_SSTAT_ATTN)) { |
492 | if (qc) | 521 | if (qc) |
493 | ata_qc_complete(qc, 0); | 522 | ata_qc_complete(qc, 0); |
494 | } else { | 523 | } else |
495 | u32 irq_stat, cmd_err, sstatus, serror; | 524 | sil24_error_intr(ap, slot_stat); |
496 | |||
497 | irq_stat = readl(port + PORT_IRQ_STAT); | ||
498 | cmd_err = readl(port + PORT_CMD_ERR); | ||
499 | sstatus = readl(port + PORT_SSTATUS); | ||
500 | serror = readl(port + PORT_SERROR); | ||
501 | |||
502 | /* Clear IRQ/errors */ | ||
503 | writel(irq_stat, port + PORT_IRQ_STAT); | ||
504 | if (cmd_err) | ||
505 | writel(cmd_err, port + PORT_CMD_ERR); | ||
506 | if (serror) | ||
507 | writel(serror, port + PORT_SERROR); | ||
508 | |||
509 | printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n" | ||
510 | " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", | ||
511 | ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); | ||
512 | |||
513 | if (qc) | ||
514 | ata_qc_complete(qc, ATA_ERR); | ||
515 | |||
516 | sil24_reset_controller(ap); | ||
517 | } | ||
518 | } | 525 | } |
519 | 526 | ||
520 | static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs) | 527 | static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs) |