diff options
author | Mikael Pettersson <mikpe@it.uu.se> | 2007-03-14 04:51:35 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 14:15:59 -0400 |
commit | 176efb054422bffe6b5a34194ffad134366c7f7e (patch) | |
tree | bd7d8445b57555dc813ba890a2f8d031170285a7 /drivers/ata/sata_promise.c | |
parent | 724114a5738131997af9272f3c716dbe457c1690 (diff) |
sata_promise: decode and report error reasons
This patch adds much needed error reason decoding and
reporting to sata_promise. It's simplistic but should
log all relevant error info the controller provides.
Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r-- | drivers/ata/sata_promise.c | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index acc9913dd6dc..baa836881b03 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include "sata_promise.h" | 45 | #include "sata_promise.h" |
46 | 46 | ||
47 | #define DRV_NAME "sata_promise" | 47 | #define DRV_NAME "sata_promise" |
48 | #define DRV_VERSION "2.03" | 48 | #define DRV_VERSION "2.04" |
49 | 49 | ||
50 | 50 | ||
51 | enum { | 51 | enum { |
@@ -70,8 +70,23 @@ enum { | |||
70 | PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ | 70 | PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ |
71 | PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */ | 71 | PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */ |
72 | 72 | ||
73 | PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) | | 73 | /* PDC_GLOBAL_CTL bit definitions */ |
74 | (1<<8) | (1<<9) | (1<<10), | 74 | PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */ |
75 | PDC_SH_ERR = (1 << 9), /* PCI error while loading S/G table */ | ||
76 | PDC_DH_ERR = (1 << 10), /* PCI error while loading data */ | ||
77 | PDC2_HTO_ERR = (1 << 12), /* host bus timeout */ | ||
78 | PDC2_ATA_HBA_ERR = (1 << 13), /* error during SATA DATA FIS transmission */ | ||
79 | PDC2_ATA_DMA_CNT_ERR = (1 << 14), /* DMA DATA FIS size differs from S/G count */ | ||
80 | PDC_OVERRUN_ERR = (1 << 19), /* S/G byte count larger than HD requires */ | ||
81 | PDC_UNDERRUN_ERR = (1 << 20), /* S/G byte count less than HD requires */ | ||
82 | PDC_DRIVE_ERR = (1 << 21), /* drive error */ | ||
83 | PDC_PCI_SYS_ERR = (1 << 22), /* PCI system error */ | ||
84 | PDC1_PCI_PARITY_ERR = (1 << 23), /* PCI parity error (from SATA150 driver) */ | ||
85 | PDC1_ERR_MASK = PDC1_PCI_PARITY_ERR, | ||
86 | PDC2_ERR_MASK = PDC2_HTO_ERR | PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR, | ||
87 | PDC_ERR_MASK = (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC_OVERRUN_ERR | ||
88 | | PDC_UNDERRUN_ERR | PDC_DRIVE_ERR | PDC_PCI_SYS_ERR | ||
89 | | PDC1_ERR_MASK | PDC2_ERR_MASK), | ||
75 | 90 | ||
76 | board_2037x = 0, /* FastTrak S150 TX2plus */ | 91 | board_2037x = 0, /* FastTrak S150 TX2plus */ |
77 | board_20319 = 1, /* FastTrak S150 TX4 */ | 92 | board_20319 = 1, /* FastTrak S150 TX4 */ |
@@ -615,17 +630,48 @@ static void pdc_post_internal_cmd(struct ata_queued_cmd *qc) | |||
615 | pdc_reset_port(ap); | 630 | pdc_reset_port(ap); |
616 | } | 631 | } |
617 | 632 | ||
633 | static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | ||
634 | u32 port_status, u32 err_mask) | ||
635 | { | ||
636 | struct ata_eh_info *ehi = &ap->eh_info; | ||
637 | unsigned int ac_err_mask = 0; | ||
638 | |||
639 | ata_ehi_clear_desc(ehi); | ||
640 | ata_ehi_push_desc(ehi, "port_status 0x%08x", port_status); | ||
641 | port_status &= err_mask; | ||
642 | |||
643 | if (port_status & PDC_DRIVE_ERR) | ||
644 | ac_err_mask |= AC_ERR_DEV; | ||
645 | if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR)) | ||
646 | ac_err_mask |= AC_ERR_HSM; | ||
647 | if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR)) | ||
648 | ac_err_mask |= AC_ERR_ATA_BUS; | ||
649 | if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR | ||
650 | | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) | ||
651 | ac_err_mask |= AC_ERR_HOST_BUS; | ||
652 | |||
653 | ehi->action |= ATA_EH_SOFTRESET; | ||
654 | qc->err_mask |= ac_err_mask; | ||
655 | ata_port_freeze(ap); | ||
656 | } | ||
657 | |||
618 | static inline unsigned int pdc_host_intr( struct ata_port *ap, | 658 | static inline unsigned int pdc_host_intr( struct ata_port *ap, |
619 | struct ata_queued_cmd *qc) | 659 | struct ata_queued_cmd *qc) |
620 | { | 660 | { |
621 | unsigned int handled = 0; | 661 | unsigned int handled = 0; |
622 | u32 tmp; | 662 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; |
623 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL; | 663 | struct pdc_host_priv *hp = ap->host->private_data; |
664 | u32 port_status, err_mask; | ||
624 | 665 | ||
625 | tmp = readl(mmio); | 666 | err_mask = PDC_ERR_MASK; |
626 | if (tmp & PDC_ERR_MASK) { | 667 | if (hp->flags & PDC_FLAG_GEN_II) |
627 | qc->err_mask |= AC_ERR_DEV; | 668 | err_mask &= ~PDC1_ERR_MASK; |
628 | pdc_reset_port(ap); | 669 | else |
670 | err_mask &= ~PDC2_ERR_MASK; | ||
671 | port_status = readl(port_mmio + PDC_GLOBAL_CTL); | ||
672 | if (unlikely(port_status & err_mask)) { | ||
673 | pdc_error_intr(ap, qc, port_status, err_mask); | ||
674 | return 1; | ||
629 | } | 675 | } |
630 | 676 | ||
631 | switch (qc->tf.protocol) { | 677 | switch (qc->tf.protocol) { |