diff options
-rw-r--r-- | drivers/ata/ahci.c | 6 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 3 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 69 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 8 | ||||
-rw-r--r-- | drivers/ata/sata_nv.c | 22 | ||||
-rw-r--r-- | drivers/ata/sata_sil24.c | 12 | ||||
-rw-r--r-- | include/linux/libata.h | 13 |
7 files changed, 98 insertions, 35 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c5034d450c62..210292cd8ad1 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1289,12 +1289,12 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
1289 | if (irq_stat & PORT_IRQ_IF_ERR) { | 1289 | if (irq_stat & PORT_IRQ_IF_ERR) { |
1290 | err_mask |= AC_ERR_ATA_BUS; | 1290 | err_mask |= AC_ERR_ATA_BUS; |
1291 | action |= ATA_EH_SOFTRESET; | 1291 | action |= ATA_EH_SOFTRESET; |
1292 | ata_ehi_push_desc(ehi, ", interface fatal error"); | 1292 | ata_ehi_push_desc(ehi, "interface fatal error"); |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { | 1295 | if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { |
1296 | ata_ehi_hotplugged(ehi); | 1296 | ata_ehi_hotplugged(ehi); |
1297 | ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ? | 1297 | ata_ehi_push_desc(ehi, "%s", irq_stat & PORT_IRQ_CONNECT ? |
1298 | "connection status changed" : "PHY RDY changed"); | 1298 | "connection status changed" : "PHY RDY changed"); |
1299 | } | 1299 | } |
1300 | 1300 | ||
@@ -1303,7 +1303,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
1303 | 1303 | ||
1304 | err_mask |= AC_ERR_HSM; | 1304 | err_mask |= AC_ERR_HSM; |
1305 | action |= ATA_EH_SOFTRESET; | 1305 | action |= ATA_EH_SOFTRESET; |
1306 | ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x", | 1306 | ata_ehi_push_desc(ehi, "unknown FIS %08x %08x %08x %08x", |
1307 | unk[0], unk[1], unk[2], unk[3]); | 1307 | unk[0], unk[1], unk[2], unk[3]); |
1308 | } | 1308 | } |
1309 | 1309 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 39a8e986a4ea..ecbc3278238a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -6945,6 +6945,9 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter); | |||
6945 | EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); | 6945 | EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); |
6946 | #endif /* CONFIG_PCI */ | 6946 | #endif /* CONFIG_PCI */ |
6947 | 6947 | ||
6948 | EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); | ||
6949 | EXPORT_SYMBOL_GPL(ata_ehi_push_desc); | ||
6950 | EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); | ||
6948 | EXPORT_SYMBOL_GPL(ata_eng_timeout); | 6951 | EXPORT_SYMBOL_GPL(ata_eng_timeout); |
6949 | EXPORT_SYMBOL_GPL(ata_port_schedule_eh); | 6952 | EXPORT_SYMBOL_GPL(ata_port_schedule_eh); |
6950 | EXPORT_SYMBOL_GPL(ata_port_abort); | 6953 | EXPORT_SYMBOL_GPL(ata_port_abort); |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 9aa62a0754f6..96b184ebf708 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -85,6 +85,71 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) | |||
85 | { } | 85 | { } |
86 | #endif /* CONFIG_PM */ | 86 | #endif /* CONFIG_PM */ |
87 | 87 | ||
88 | static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt, | ||
89 | va_list args) | ||
90 | { | ||
91 | ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len, | ||
92 | ATA_EH_DESC_LEN - ehi->desc_len, | ||
93 | fmt, args); | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * __ata_ehi_push_desc - push error description without adding separator | ||
98 | * @ehi: target EHI | ||
99 | * @fmt: printf format string | ||
100 | * | ||
101 | * Format string according to @fmt and append it to @ehi->desc. | ||
102 | * | ||
103 | * LOCKING: | ||
104 | * spin_lock_irqsave(host lock) | ||
105 | */ | ||
106 | void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) | ||
107 | { | ||
108 | va_list args; | ||
109 | |||
110 | va_start(args, fmt); | ||
111 | __ata_ehi_pushv_desc(ehi, fmt, args); | ||
112 | va_end(args); | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * ata_ehi_push_desc - push error description with separator | ||
117 | * @ehi: target EHI | ||
118 | * @fmt: printf format string | ||
119 | * | ||
120 | * Format string according to @fmt and append it to @ehi->desc. | ||
121 | * If @ehi->desc is not empty, ", " is added in-between. | ||
122 | * | ||
123 | * LOCKING: | ||
124 | * spin_lock_irqsave(host lock) | ||
125 | */ | ||
126 | void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) | ||
127 | { | ||
128 | va_list args; | ||
129 | |||
130 | if (ehi->desc_len) | ||
131 | __ata_ehi_push_desc(ehi, ", "); | ||
132 | |||
133 | va_start(args, fmt); | ||
134 | __ata_ehi_pushv_desc(ehi, fmt, args); | ||
135 | va_end(args); | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * ata_ehi_clear_desc - clean error description | ||
140 | * @ehi: target EHI | ||
141 | * | ||
142 | * Clear @ehi->desc. | ||
143 | * | ||
144 | * LOCKING: | ||
145 | * spin_lock_irqsave(host lock) | ||
146 | */ | ||
147 | void ata_ehi_clear_desc(struct ata_eh_info *ehi) | ||
148 | { | ||
149 | ehi->desc[0] = '\0'; | ||
150 | ehi->desc_len = 0; | ||
151 | } | ||
152 | |||
88 | static void ata_ering_record(struct ata_ering *ering, int is_io, | 153 | static void ata_ering_record(struct ata_ering *ering, int is_io, |
89 | unsigned int err_mask) | 154 | unsigned int err_mask) |
90 | { | 155 | { |
@@ -1524,14 +1589,14 @@ static void ata_eh_report(struct ata_port *ap) | |||
1524 | ehc->i.err_mask, ap->sactive, ehc->i.serror, | 1589 | ehc->i.err_mask, ap->sactive, ehc->i.serror, |
1525 | ehc->i.action, frozen); | 1590 | ehc->i.action, frozen); |
1526 | if (desc) | 1591 | if (desc) |
1527 | ata_dev_printk(ehc->i.dev, KERN_ERR, "(%s)\n", desc); | 1592 | ata_dev_printk(ehc->i.dev, KERN_ERR, "%s\n", desc); |
1528 | } else { | 1593 | } else { |
1529 | ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x " | 1594 | ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x " |
1530 | "SAct 0x%x SErr 0x%x action 0x%x%s\n", | 1595 | "SAct 0x%x SErr 0x%x action 0x%x%s\n", |
1531 | ehc->i.err_mask, ap->sactive, ehc->i.serror, | 1596 | ehc->i.err_mask, ap->sactive, ehc->i.serror, |
1532 | ehc->i.action, frozen); | 1597 | ehc->i.action, frozen); |
1533 | if (desc) | 1598 | if (desc) |
1534 | ata_port_printk(ap, KERN_ERR, "(%s)\n", desc); | 1599 | ata_port_printk(ap, KERN_ERR, "%s\n", desc); |
1535 | } | 1600 | } |
1536 | 1601 | ||
1537 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { | 1602 | for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 80ade5b93b86..b4b737e081e8 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1411,12 +1411,12 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
1411 | EDMA_ERR_INTRL_PAR)) { | 1411 | EDMA_ERR_INTRL_PAR)) { |
1412 | err_mask |= AC_ERR_ATA_BUS; | 1412 | err_mask |= AC_ERR_ATA_BUS; |
1413 | action |= ATA_EH_HARDRESET; | 1413 | action |= ATA_EH_HARDRESET; |
1414 | ata_ehi_push_desc(ehi, ", parity error"); | 1414 | ata_ehi_push_desc(ehi, "parity error"); |
1415 | } | 1415 | } |
1416 | if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) { | 1416 | if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) { |
1417 | ata_ehi_hotplugged(ehi); | 1417 | ata_ehi_hotplugged(ehi); |
1418 | ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ? | 1418 | ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ? |
1419 | ", dev disconnect" : ", dev connect"); | 1419 | "dev disconnect" : "dev connect"); |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | if (IS_GEN_I(hpriv)) { | 1422 | if (IS_GEN_I(hpriv)) { |
@@ -1425,7 +1425,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
1425 | if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { | 1425 | if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { |
1426 | struct mv_port_priv *pp = ap->private_data; | 1426 | struct mv_port_priv *pp = ap->private_data; |
1427 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | 1427 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; |
1428 | ata_ehi_push_desc(ehi, ", EDMA self-disable"); | 1428 | ata_ehi_push_desc(ehi, "EDMA self-disable"); |
1429 | } | 1429 | } |
1430 | } else { | 1430 | } else { |
1431 | eh_freeze_mask = EDMA_EH_FREEZE; | 1431 | eh_freeze_mask = EDMA_EH_FREEZE; |
@@ -1433,7 +1433,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
1433 | if (edma_err_cause & EDMA_ERR_SELF_DIS) { | 1433 | if (edma_err_cause & EDMA_ERR_SELF_DIS) { |
1434 | struct mv_port_priv *pp = ap->private_data; | 1434 | struct mv_port_priv *pp = ap->private_data; |
1435 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | 1435 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; |
1436 | ata_ehi_push_desc(ehi, ", EDMA self-disable"); | 1436 | ata_ehi_push_desc(ehi, "EDMA self-disable"); |
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | if (edma_err_cause & EDMA_ERR_SERR) { | 1439 | if (edma_err_cause & EDMA_ERR_SERR) { |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index db81e3efa5ec..5d943da042f7 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -715,19 +715,20 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) | |||
715 | int freeze = 0; | 715 | int freeze = 0; |
716 | 716 | ||
717 | ata_ehi_clear_desc(ehi); | 717 | ata_ehi_clear_desc(ehi); |
718 | ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x", flags ); | 718 | __ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x: ", flags ); |
719 | if (flags & NV_CPB_RESP_ATA_ERR) { | 719 | if (flags & NV_CPB_RESP_ATA_ERR) { |
720 | ata_ehi_push_desc(ehi, ": ATA error"); | 720 | ata_ehi_push_desc(ehi, "ATA error"); |
721 | ehi->err_mask |= AC_ERR_DEV; | 721 | ehi->err_mask |= AC_ERR_DEV; |
722 | } else if (flags & NV_CPB_RESP_CMD_ERR) { | 722 | } else if (flags & NV_CPB_RESP_CMD_ERR) { |
723 | ata_ehi_push_desc(ehi, ": CMD error"); | 723 | ata_ehi_push_desc(ehi, "CMD error"); |
724 | ehi->err_mask |= AC_ERR_DEV; | 724 | ehi->err_mask |= AC_ERR_DEV; |
725 | } else if (flags & NV_CPB_RESP_CPB_ERR) { | 725 | } else if (flags & NV_CPB_RESP_CPB_ERR) { |
726 | ata_ehi_push_desc(ehi, ": CPB error"); | 726 | ata_ehi_push_desc(ehi, "CPB error"); |
727 | ehi->err_mask |= AC_ERR_SYSTEM; | 727 | ehi->err_mask |= AC_ERR_SYSTEM; |
728 | freeze = 1; | 728 | freeze = 1; |
729 | } else { | 729 | } else { |
730 | /* notifier error, but no error in CPB flags? */ | 730 | /* notifier error, but no error in CPB flags? */ |
731 | ata_ehi_push_desc(ehi, "unknown"); | ||
731 | ehi->err_mask |= AC_ERR_OTHER; | 732 | ehi->err_mask |= AC_ERR_OTHER; |
732 | freeze = 1; | 733 | freeze = 1; |
733 | } | 734 | } |
@@ -854,20 +855,21 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | |||
854 | struct ata_eh_info *ehi = &ap->eh_info; | 855 | struct ata_eh_info *ehi = &ap->eh_info; |
855 | 856 | ||
856 | ata_ehi_clear_desc(ehi); | 857 | ata_ehi_clear_desc(ehi); |
857 | ata_ehi_push_desc(ehi, "ADMA status 0x%08x", status ); | 858 | __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status ); |
858 | if (status & NV_ADMA_STAT_TIMEOUT) { | 859 | if (status & NV_ADMA_STAT_TIMEOUT) { |
859 | ehi->err_mask |= AC_ERR_SYSTEM; | 860 | ehi->err_mask |= AC_ERR_SYSTEM; |
860 | ata_ehi_push_desc(ehi, ": timeout"); | 861 | ata_ehi_push_desc(ehi, "timeout"); |
861 | } else if (status & NV_ADMA_STAT_HOTPLUG) { | 862 | } else if (status & NV_ADMA_STAT_HOTPLUG) { |
862 | ata_ehi_hotplugged(ehi); | 863 | ata_ehi_hotplugged(ehi); |
863 | ata_ehi_push_desc(ehi, ": hotplug"); | 864 | ata_ehi_push_desc(ehi, "hotplug"); |
864 | } else if (status & NV_ADMA_STAT_HOTUNPLUG) { | 865 | } else if (status & NV_ADMA_STAT_HOTUNPLUG) { |
865 | ata_ehi_hotplugged(ehi); | 866 | ata_ehi_hotplugged(ehi); |
866 | ata_ehi_push_desc(ehi, ": hot unplug"); | 867 | ata_ehi_push_desc(ehi, "hot unplug"); |
867 | } else if (status & NV_ADMA_STAT_SERROR) { | 868 | } else if (status & NV_ADMA_STAT_SERROR) { |
868 | /* let libata analyze SError and figure out the cause */ | 869 | /* let libata analyze SError and figure out the cause */ |
869 | ata_ehi_push_desc(ehi, ": SError"); | 870 | ata_ehi_push_desc(ehi, "SError"); |
870 | } | 871 | } else |
872 | ata_ehi_push_desc(ehi, "unknown"); | ||
871 | ata_port_freeze(ap); | 873 | ata_port_freeze(ap); |
872 | continue; | 874 | continue; |
873 | } | 875 | } |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index e538edc1b4ea..e201f1cab66d 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -814,16 +814,16 @@ static void sil24_error_intr(struct ata_port *ap) | |||
814 | 814 | ||
815 | if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { | 815 | if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { |
816 | ata_ehi_hotplugged(ehi); | 816 | ata_ehi_hotplugged(ehi); |
817 | ata_ehi_push_desc(ehi, ", %s", | 817 | ata_ehi_push_desc(ehi, "%s", |
818 | irq_stat & PORT_IRQ_PHYRDY_CHG ? | 818 | irq_stat & PORT_IRQ_PHYRDY_CHG ? |
819 | "PHY RDY changed" : "device exchanged"); | 819 | "PHY RDY changed" : "device exchanged"); |
820 | freeze = 1; | 820 | freeze = 1; |
821 | } | 821 | } |
822 | 822 | ||
823 | if (irq_stat & PORT_IRQ_UNK_FIS) { | 823 | if (irq_stat & PORT_IRQ_UNK_FIS) { |
824 | ehi->err_mask |= AC_ERR_HSM; | 824 | ehi->err_mask |= AC_ERR_HSM; |
825 | ehi->action |= ATA_EH_SOFTRESET; | 825 | ehi->action |= ATA_EH_SOFTRESET; |
826 | ata_ehi_push_desc(ehi , ", unknown FIS"); | 826 | ata_ehi_push_desc(ehi, "unknown FIS"); |
827 | freeze = 1; | 827 | freeze = 1; |
828 | } | 828 | } |
829 | 829 | ||
@@ -842,11 +842,11 @@ static void sil24_error_intr(struct ata_port *ap) | |||
842 | if (ci && ci->desc) { | 842 | if (ci && ci->desc) { |
843 | err_mask |= ci->err_mask; | 843 | err_mask |= ci->err_mask; |
844 | action |= ci->action; | 844 | action |= ci->action; |
845 | ata_ehi_push_desc(ehi, ", %s", ci->desc); | 845 | ata_ehi_push_desc(ehi, "%s", ci->desc); |
846 | } else { | 846 | } else { |
847 | err_mask |= AC_ERR_OTHER; | 847 | err_mask |= AC_ERR_OTHER; |
848 | action |= ATA_EH_SOFTRESET; | 848 | action |= ATA_EH_SOFTRESET; |
849 | ata_ehi_push_desc(ehi, ", unknown command error %d", | 849 | ata_ehi_push_desc(ehi, "unknown command error %d", |
850 | cerr); | 850 | cerr); |
851 | } | 851 | } |
852 | 852 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index 5d3df6cde272..94b37d180680 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -910,16 +910,9 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
910 | /* | 910 | /* |
911 | * ata_eh_info helpers | 911 | * ata_eh_info helpers |
912 | */ | 912 | */ |
913 | #define ata_ehi_push_desc(ehi, fmt, args...) do { \ | 913 | extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); |
914 | (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \ | 914 | extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); |
915 | ATA_EH_DESC_LEN - (ehi)->desc_len, \ | 915 | extern void ata_ehi_clear_desc(struct ata_eh_info *ehi); |
916 | fmt , ##args); \ | ||
917 | } while (0) | ||
918 | |||
919 | #define ata_ehi_clear_desc(ehi) do { \ | ||
920 | (ehi)->desc[0] = '\0'; \ | ||
921 | (ehi)->desc_len = 0; \ | ||
922 | } while (0) | ||
923 | 916 | ||
924 | static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi) | 917 | static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi) |
925 | { | 918 | { |