aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/ahci.c6
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/libata-eh.c69
-rw-r--r--drivers/ata/sata_mv.c8
-rw-r--r--drivers/ata/sata_nv.c22
-rw-r--r--drivers/ata/sata_sil24.c12
-rw-r--r--include/linux/libata.h13
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);
6945EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); 6945EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
6946#endif /* CONFIG_PCI */ 6946#endif /* CONFIG_PCI */
6947 6947
6948EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
6949EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
6950EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
6948EXPORT_SYMBOL_GPL(ata_eng_timeout); 6951EXPORT_SYMBOL_GPL(ata_eng_timeout);
6949EXPORT_SYMBOL_GPL(ata_port_schedule_eh); 6952EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
6950EXPORT_SYMBOL_GPL(ata_port_abort); 6953EXPORT_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
88static 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 */
106void __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 */
126void 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 */
147void ata_ehi_clear_desc(struct ata_eh_info *ehi)
148{
149 ehi->desc[0] = '\0';
150 ehi->desc_len = 0;
151}
152
88static void ata_ering_record(struct ata_ering *ering, int is_io, 153static 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 { \ 913extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...);
914 (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \ 914extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...);
915 ATA_EH_DESC_LEN - (ehi)->desc_len, \ 915extern 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
924static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi) 917static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi)
925{ 918{