diff options
| -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) |
