aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Hancock <hancockr@shaw.ca>2007-10-02 11:22:02 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-12 14:55:45 -0400
commit1333e19434da116bc832e1b8925359d1565fedc9 (patch)
tree581785c8864f55347e1de0eb10850cc374b79b6e
parent6949b9148d3656afc13a2ccc06d13c071ec71bdc (diff)
libata: add human-readable error value decoding
This adds human-readable decoding of the ATA status and error registers (similar to what drivers/ide does) as well as the SATA Serror register to libata error handling output. This prevents the need to pore through standards documents to figure out the meaning of the bits in these registers when looking at error reports. Some bits that drivers/ide decoded are not decoded here, since the bits are either command-dependent or obsolete, and properly parsing them would add too much complexity. Signed-off-by: Robert Hancock <hancockr@shaw.ca> [edited slightly to make output a bit more symmetric] Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/libata-eh.c45
-rw-r--r--include/linux/ata.h9
2 files changed, 54 insertions, 0 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 5f2c0f376f74..0bd3898793a7 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1911,6 +1911,27 @@ static void ata_eh_link_report(struct ata_link *link)
1911 ata_link_printk(link, KERN_ERR, "%s\n", desc); 1911 ata_link_printk(link, KERN_ERR, "%s\n", desc);
1912 } 1912 }
1913 1913
1914 if (ehc->i.serror)
1915 ata_port_printk(ap, KERN_ERR,
1916 "SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
1917 ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
1918 ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
1919 ehc->i.serror & SERR_DATA ? "UnrecovData " : "",
1920 ehc->i.serror & SERR_PERSISTENT ? "Persist " : "",
1921 ehc->i.serror & SERR_PROTOCOL ? "Proto " : "",
1922 ehc->i.serror & SERR_INTERNAL ? "HostInt " : "",
1923 ehc->i.serror & SERR_PHYRDY_CHG ? "PHYRdyChg " : "",
1924 ehc->i.serror & SERR_PHY_INT_ERR ? "PHYInt " : "",
1925 ehc->i.serror & SERR_COMM_WAKE ? "CommWake " : "",
1926 ehc->i.serror & SERR_10B_8B_ERR ? "10B8B " : "",
1927 ehc->i.serror & SERR_DISPARITY ? "Dispar " : "",
1928 ehc->i.serror & SERR_CRC ? "BadCRC " : "",
1929 ehc->i.serror & SERR_HANDSHAKE ? "Handshk " : "",
1930 ehc->i.serror & SERR_LINK_SEQ_ERR ? "LinkSeq " : "",
1931 ehc->i.serror & SERR_TRANS_ST_ERROR ? "TrStaTrns " : "",
1932 ehc->i.serror & SERR_UNRECOG_FIS ? "UnrecFIS " : "",
1933 ehc->i.serror & SERR_DEV_XCHG ? "DevExch " : "" );
1934
1914 for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { 1935 for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
1915 static const char *dma_str[] = { 1936 static const char *dma_str[] = {
1916 [DMA_BIDIRECTIONAL] = "bidi", 1937 [DMA_BIDIRECTIONAL] = "bidi",
@@ -1942,6 +1963,30 @@ static void ata_eh_link_report(struct ata_link *link)
1942 res->hob_lbal, res->hob_lbam, res->hob_lbah, 1963 res->hob_lbal, res->hob_lbam, res->hob_lbah,
1943 res->device, qc->err_mask, ata_err_string(qc->err_mask), 1964 res->device, qc->err_mask, ata_err_string(qc->err_mask),
1944 qc->err_mask & AC_ERR_NCQ ? " <F>" : ""); 1965 qc->err_mask & AC_ERR_NCQ ? " <F>" : "");
1966
1967 if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
1968 ATA_ERR) ) {
1969 if (res->command & ATA_BUSY)
1970 ata_dev_printk(qc->dev, KERN_ERR,
1971 "status: { Busy }\n" );
1972 else
1973 ata_dev_printk(qc->dev, KERN_ERR,
1974 "status: { %s%s%s%s}\n",
1975 res->command & ATA_DRDY ? "DRDY " : "",
1976 res->command & ATA_DF ? "DF " : "",
1977 res->command & ATA_DRQ ? "DRQ " : "",
1978 res->command & ATA_ERR ? "ERR " : "" );
1979 }
1980
1981 if (cmd->command != ATA_CMD_PACKET &&
1982 (res->feature & (ATA_ICRC | ATA_UNC | ATA_IDNF |
1983 ATA_ABORTED)))
1984 ata_dev_printk(qc->dev, KERN_ERR,
1985 "error: { %s%s%s%s}\n",
1986 res->feature & ATA_ICRC ? "ICRC " : "",
1987 res->feature & ATA_UNC ? "UNC " : "",
1988 res->feature & ATA_IDNF ? "IDNF " : "",
1989 res->feature & ATA_ABORTED ? "ABRT " : "" );
1945 } 1990 }
1946} 1991}
1947 1992
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 21f00a0646d8..a4f373f8b798 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -287,6 +287,15 @@ enum {
287 SERR_PROTOCOL = (1 << 10), /* protocol violation */ 287 SERR_PROTOCOL = (1 << 10), /* protocol violation */
288 SERR_INTERNAL = (1 << 11), /* host internal error */ 288 SERR_INTERNAL = (1 << 11), /* host internal error */
289 SERR_PHYRDY_CHG = (1 << 16), /* PHY RDY changed */ 289 SERR_PHYRDY_CHG = (1 << 16), /* PHY RDY changed */
290 SERR_PHY_INT_ERR = (1 << 17), /* PHY internal error */
291 SERR_COMM_WAKE = (1 << 18), /* Comm wake */
292 SERR_10B_8B_ERR = (1 << 19), /* 10b to 8b decode error */
293 SERR_DISPARITY = (1 << 20), /* Disparity */
294 SERR_CRC = (1 << 21), /* CRC error */
295 SERR_HANDSHAKE = (1 << 22), /* Handshake error */
296 SERR_LINK_SEQ_ERR = (1 << 23), /* Link sequence error */
297 SERR_TRANS_ST_ERROR = (1 << 24), /* Transport state trans. error */
298 SERR_UNRECOG_FIS = (1 << 25), /* Unrecognized FIS */
290 SERR_DEV_XCHG = (1 << 26), /* device exchanged */ 299 SERR_DEV_XCHG = (1 << 26), /* device exchanged */
291 300
292 /* struct ata_taskfile flags */ 301 /* struct ata_taskfile flags */