diff options
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 278 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 47 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 17 |
5 files changed, 349 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index c53719a9a747..dba9eedc3ded 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -4,10 +4,36 @@ | |||
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | |||
8 | /* | ||
9 | * Table for showing the current message id in use for particular level | ||
10 | * Change this table for addition of log/debug messages. | ||
11 | * ----------------------------------------------------- | ||
12 | * | Level | Last Value Used | | ||
13 | * ----------------------------------------------------- | ||
14 | * | Module Init and Probe | 0x0109 | | ||
15 | * | Mailbox commands | 0x1120 | | ||
16 | * | Device Discovery | 0x207d | | ||
17 | * | Queue Command and IO tracing | 0x304f | | ||
18 | * | DPC Thread | 0x401c | | ||
19 | * | Async Events | 0x5058 | | ||
20 | * | Timer Routines | 0x600d | | ||
21 | * | User Space Interactions | 0x70a1 | | ||
22 | * | Task Management | 0x8032 | | ||
23 | * | AER/EEH | 0x9010 | | ||
24 | * | Virtual Port | 0xa007 | | ||
25 | * | ISP82XX Specific | 0xb028 | | ||
26 | * | MultiQ | 0xc00b | | ||
27 | * | Misc | 0xd00b | | ||
28 | * ----------------------------------------------------- | ||
29 | */ | ||
30 | |||
7 | #include "qla_def.h" | 31 | #include "qla_def.h" |
8 | 32 | ||
9 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
10 | 34 | ||
35 | static uint32_t ql_dbg_offset = 0x800; | ||
36 | |||
11 | static inline void | 37 | static inline void |
12 | qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump) | 38 | qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump) |
13 | { | 39 | { |
@@ -1722,3 +1748,255 @@ qla2x00_dump_buffer_zipped(uint8_t *b, uint32_t size) | |||
1722 | printk(KERN_DEBUG "\n"); | 1748 | printk(KERN_DEBUG "\n"); |
1723 | } | 1749 | } |
1724 | } | 1750 | } |
1751 | /* | ||
1752 | * This function is for formatting and logging debug information. | ||
1753 | * It is to be used when vha is available. It formats the message | ||
1754 | * and logs it to the messages file. | ||
1755 | * parameters: | ||
1756 | * level: The level of the debug messages to be printed. | ||
1757 | * If ql2xextended_error_logging value is correctly set, | ||
1758 | * this message will appear in the messages file. | ||
1759 | * vha: Pointer to the scsi_qla_host_t. | ||
1760 | * id: This is a unique identifier for the level. It identifies the | ||
1761 | * part of the code from where the message originated. | ||
1762 | * msg: The message to be displayed. | ||
1763 | */ | ||
1764 | void | ||
1765 | ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, char *msg, ...) { | ||
1766 | |||
1767 | char pbuf[QL_DBG_BUF_LEN]; | ||
1768 | va_list ap; | ||
1769 | uint32_t len; | ||
1770 | struct pci_dev *pdev = NULL; | ||
1771 | |||
1772 | memset(pbuf, 0, QL_DBG_BUF_LEN); | ||
1773 | |||
1774 | va_start(ap, msg); | ||
1775 | |||
1776 | if ((level & ql2xextended_error_logging) == level) { | ||
1777 | if (vha != NULL) { | ||
1778 | pdev = vha->hw->pdev; | ||
1779 | /* <module-name> <pci-name> <msg-id>:<host> Message */ | ||
1780 | sprintf(pbuf, "%s [%s]-%04x:%ld: ", QL_MSGHDR, | ||
1781 | dev_name(&(pdev->dev)), id + ql_dbg_offset, | ||
1782 | vha->host_no); | ||
1783 | } else | ||
1784 | sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR, | ||
1785 | "0000:00:00.0", id + ql_dbg_offset); | ||
1786 | |||
1787 | len = strlen(pbuf); | ||
1788 | vsprintf(pbuf+len, msg, ap); | ||
1789 | pr_warning("%s", pbuf); | ||
1790 | } | ||
1791 | |||
1792 | va_end(ap); | ||
1793 | |||
1794 | } | ||
1795 | |||
1796 | /* | ||
1797 | * This function is for formatting and logging debug information. | ||
1798 | * It is to be used when vha is not available and pci is availble, | ||
1799 | * i.e., before host allocation. It formats the message and logs it | ||
1800 | * to the messages file. | ||
1801 | * parameters: | ||
1802 | * level: The level of the debug messages to be printed. | ||
1803 | * If ql2xextended_error_logging value is correctly set, | ||
1804 | * this message will appear in the messages file. | ||
1805 | * pdev: Pointer to the struct pci_dev. | ||
1806 | * id: This is a unique id for the level. It identifies the part | ||
1807 | * of the code from where the message originated. | ||
1808 | * msg: The message to be displayed. | ||
1809 | */ | ||
1810 | void | ||
1811 | ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id, char *msg, ...) { | ||
1812 | |||
1813 | char pbuf[QL_DBG_BUF_LEN]; | ||
1814 | va_list ap; | ||
1815 | uint32_t len; | ||
1816 | |||
1817 | if (pdev == NULL) | ||
1818 | return; | ||
1819 | |||
1820 | memset(pbuf, 0, QL_DBG_BUF_LEN); | ||
1821 | |||
1822 | va_start(ap, msg); | ||
1823 | |||
1824 | if ((level & ql2xextended_error_logging) == level) { | ||
1825 | /* <module-name> <dev-name>:<msg-id> Message */ | ||
1826 | sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR, | ||
1827 | dev_name(&(pdev->dev)), id + ql_dbg_offset); | ||
1828 | |||
1829 | len = strlen(pbuf); | ||
1830 | vsprintf(pbuf+len, msg, ap); | ||
1831 | pr_warning("%s", pbuf); | ||
1832 | } | ||
1833 | |||
1834 | va_end(ap); | ||
1835 | |||
1836 | } | ||
1837 | |||
1838 | /* | ||
1839 | * This function is for formatting and logging log messages. | ||
1840 | * It is to be used when vha is available. It formats the message | ||
1841 | * and logs it to the messages file. All the messages will be logged | ||
1842 | * irrespective of value of ql2xextended_error_logging. | ||
1843 | * parameters: | ||
1844 | * level: The level of the log messages to be printed in the | ||
1845 | * messages file. | ||
1846 | * vha: Pointer to the scsi_qla_host_t | ||
1847 | * id: This is a unique id for the level. It identifies the | ||
1848 | * part of the code from where the message originated. | ||
1849 | * msg: The message to be displayed. | ||
1850 | */ | ||
1851 | void | ||
1852 | ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, char *msg, ...) { | ||
1853 | |||
1854 | char pbuf[QL_DBG_BUF_LEN]; | ||
1855 | va_list ap; | ||
1856 | uint32_t len; | ||
1857 | struct pci_dev *pdev = NULL; | ||
1858 | |||
1859 | memset(pbuf, 0, QL_DBG_BUF_LEN); | ||
1860 | |||
1861 | va_start(ap, msg); | ||
1862 | |||
1863 | if (level <= ql_errlev) { | ||
1864 | if (vha != NULL) { | ||
1865 | pdev = vha->hw->pdev; | ||
1866 | /* <module-name> <msg-id>:<host> Message */ | ||
1867 | sprintf(pbuf, "%s [%s]-%04x:%ld: ", QL_MSGHDR, | ||
1868 | dev_name(&(pdev->dev)), id, vha->host_no); | ||
1869 | } else | ||
1870 | sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR, | ||
1871 | "0000:00:00.0", id); | ||
1872 | |||
1873 | len = strlen(pbuf); | ||
1874 | vsprintf(pbuf+len, msg, ap); | ||
1875 | |||
1876 | switch (level) { | ||
1877 | case 0: /* FATAL LOG */ | ||
1878 | pr_crit("%s", pbuf); | ||
1879 | break; | ||
1880 | case 1: | ||
1881 | pr_err("%s", pbuf); | ||
1882 | break; | ||
1883 | case 2: | ||
1884 | pr_warn("%s", pbuf); | ||
1885 | break; | ||
1886 | default: | ||
1887 | pr_info("%s", pbuf); | ||
1888 | break; | ||
1889 | } | ||
1890 | } | ||
1891 | |||
1892 | va_end(ap); | ||
1893 | } | ||
1894 | |||
1895 | /* | ||
1896 | * This function is for formatting and logging log messages. | ||
1897 | * It is to be used when vha is not available and pci is availble, | ||
1898 | * i.e., before host allocation. It formats the message and logs | ||
1899 | * it to the messages file. All the messages are logged irrespective | ||
1900 | * of the value of ql2xextended_error_logging. | ||
1901 | * parameters: | ||
1902 | * level: The level of the log messages to be printed in the | ||
1903 | * messages file. | ||
1904 | * pdev: Pointer to the struct pci_dev. | ||
1905 | * id: This is a unique id for the level. It identifies the | ||
1906 | * part of the code from where the message originated. | ||
1907 | * msg: The message to be displayed. | ||
1908 | */ | ||
1909 | void | ||
1910 | ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id, char *msg, ...) { | ||
1911 | |||
1912 | char pbuf[QL_DBG_BUF_LEN]; | ||
1913 | va_list ap; | ||
1914 | uint32_t len; | ||
1915 | |||
1916 | if (pdev == NULL) | ||
1917 | return; | ||
1918 | |||
1919 | memset(pbuf, 0, QL_DBG_BUF_LEN); | ||
1920 | |||
1921 | va_start(ap, msg); | ||
1922 | |||
1923 | if (level <= ql_errlev) { | ||
1924 | /* <module-name> <dev-name>:<msg-id> Message */ | ||
1925 | sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR, | ||
1926 | dev_name(&(pdev->dev)), id); | ||
1927 | |||
1928 | len = strlen(pbuf); | ||
1929 | vsprintf(pbuf+len, msg, ap); | ||
1930 | switch (level) { | ||
1931 | case 0: /* FATAL LOG */ | ||
1932 | pr_crit("%s", pbuf); | ||
1933 | break; | ||
1934 | case 1: | ||
1935 | pr_err("%s", pbuf); | ||
1936 | break; | ||
1937 | case 2: | ||
1938 | pr_warn("%s", pbuf); | ||
1939 | break; | ||
1940 | default: | ||
1941 | pr_info("%s", pbuf); | ||
1942 | break; | ||
1943 | } | ||
1944 | } | ||
1945 | |||
1946 | va_end(ap); | ||
1947 | } | ||
1948 | |||
1949 | void | ||
1950 | ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id) | ||
1951 | { | ||
1952 | int i; | ||
1953 | struct qla_hw_data *ha = vha->hw; | ||
1954 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
1955 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; | ||
1956 | struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; | ||
1957 | uint16_t __iomem *mbx_reg; | ||
1958 | |||
1959 | if ((level & ql2xextended_error_logging) == level) { | ||
1960 | |||
1961 | if (IS_QLA82XX(ha)) | ||
1962 | mbx_reg = ®82->mailbox_in[0]; | ||
1963 | else if (IS_FWI2_CAPABLE(ha)) | ||
1964 | mbx_reg = ®24->mailbox0; | ||
1965 | else | ||
1966 | mbx_reg = MAILBOX_REG(ha, reg, 0); | ||
1967 | |||
1968 | ql_dbg(level, vha, id, "Mailbox registers:\n"); | ||
1969 | for (i = 0; i < 6; i++) | ||
1970 | ql_dbg(level, vha, id, | ||
1971 | "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++)); | ||
1972 | } | ||
1973 | } | ||
1974 | |||
1975 | |||
1976 | void | ||
1977 | ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id, | ||
1978 | uint8_t *b, uint32_t size) | ||
1979 | { | ||
1980 | uint32_t cnt; | ||
1981 | uint8_t c; | ||
1982 | if ((level & ql2xextended_error_logging) == level) { | ||
1983 | |||
1984 | ql_dbg(level, vha, id, " 0 1 2 3 4 5 6 7 8 " | ||
1985 | "9 Ah Bh Ch Dh Eh Fh\n"); | ||
1986 | ql_dbg(level, vha, id, "----------------------------------" | ||
1987 | "----------------------------\n"); | ||
1988 | |||
1989 | ql_dbg(level, vha, id, ""); | ||
1990 | for (cnt = 0; cnt < size;) { | ||
1991 | c = *b++; | ||
1992 | printk("%02x", (uint32_t) c); | ||
1993 | cnt++; | ||
1994 | if (!(cnt % 16)) | ||
1995 | printk("\n"); | ||
1996 | else | ||
1997 | printk(" "); | ||
1998 | } | ||
1999 | if (cnt % 16) | ||
2000 | ql_dbg(level, vha, id, "\n"); | ||
2001 | } | ||
2002 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 930414541ec6..f955094fd5d8 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -370,3 +370,50 @@ struct qla2xxx_fw_dump { | |||
370 | struct qla81xx_fw_dump isp81; | 370 | struct qla81xx_fw_dump isp81; |
371 | } isp; | 371 | } isp; |
372 | }; | 372 | }; |
373 | |||
374 | #define QL_MSGHDR "qla2xxx" | ||
375 | |||
376 | #define ql_log_fatal 0 /* display fatal errors */ | ||
377 | #define ql_log_warn 1 /* display critical errors */ | ||
378 | #define ql_log_info 2 /* display all recovered errors */ | ||
379 | #define ql_log_all 3 /* This value is only used by ql_errlev. | ||
380 | * No messages will use this value. | ||
381 | * This should be always highest value | ||
382 | * as compared to other log levels. | ||
383 | */ | ||
384 | |||
385 | extern int ql_errlev; | ||
386 | |||
387 | void | ||
388 | ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, char *, ...); | ||
389 | void | ||
390 | ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, char *, ...); | ||
391 | |||
392 | void | ||
393 | ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, char *, ...); | ||
394 | void | ||
395 | ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, char *, ...); | ||
396 | |||
397 | /* Debug Levels */ | ||
398 | /* The 0x40000000 is the max value any debug level can have | ||
399 | * as ql2xextended_error_logging is of type signed int | ||
400 | */ | ||
401 | #define ql_dbg_init 0x40000000 /* Init Debug */ | ||
402 | #define ql_dbg_mbx 0x20000000 /* MBX Debug */ | ||
403 | #define ql_dbg_disc 0x10000000 /* Device Discovery Debug */ | ||
404 | #define ql_dbg_io 0x08000000 /* IO Tracing Debug */ | ||
405 | #define ql_dbg_dpc 0x04000000 /* DPC Thead Debug */ | ||
406 | #define ql_dbg_async 0x02000000 /* Async events Debug */ | ||
407 | #define ql_dbg_timer 0x01000000 /* Timer Debug */ | ||
408 | #define ql_dbg_user 0x00800000 /* User Space Interations Debug */ | ||
409 | #define ql_dbg_taskm 0x00400000 /* Task Management Debug */ | ||
410 | #define ql_dbg_aer 0x00200000 /* AER/EEH Debug */ | ||
411 | #define ql_dbg_multiq 0x00100000 /* MultiQ Debug */ | ||
412 | #define ql_dbg_p3p 0x00080000 /* P3P specific Debug */ | ||
413 | #define ql_dbg_vport 0x00040000 /* Virtual Port Debug */ | ||
414 | #define ql_dbg_buffer 0x00020000 /* For dumping the buffer/regs */ | ||
415 | #define ql_dbg_misc 0x00010000 /* For dumping everything that is not | ||
416 | * not covered by upper categories | ||
417 | */ | ||
418 | |||
419 | #define QL_DBG_BUF_LEN 512 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0b381224ae4b..38aef5d0515f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -439,6 +439,9 @@ extern void qla81xx_fw_dump(scsi_qla_host_t *, int); | |||
439 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 439 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
440 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 440 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
441 | extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); | 441 | extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); |
442 | extern void ql_dump_regs(uint32_t, scsi_qla_host_t *, int32_t); | ||
443 | extern void ql_dump_buffer(uint32_t, scsi_qla_host_t *, int32_t, | ||
444 | uint8_t *, uint32_t); | ||
442 | 445 | ||
443 | /* | 446 | /* |
444 | * Global Function Prototypes in qla_gs.c source file. | 447 | * Global Function Prototypes in qla_gs.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 920b76bfbb93..3d0384506929 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -2382,8 +2382,13 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) | |||
2382 | /* | 2382 | /* |
2383 | * Set host adapter parameters. | 2383 | * Set host adapter parameters. |
2384 | */ | 2384 | */ |
2385 | |||
2386 | /* | ||
2387 | * BIT_7 in the host-parameters section allows for modification to | ||
2388 | * internal driver logging. | ||
2389 | */ | ||
2385 | if (nv->host_p[0] & BIT_7) | 2390 | if (nv->host_p[0] & BIT_7) |
2386 | ql2xextended_error_logging = 1; | 2391 | ql2xextended_error_logging = 0x7fffffff; |
2387 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); | 2392 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); |
2388 | /* Always load RISC code on non ISP2[12]00 chips. */ | 2393 | /* Always load RISC code on non ISP2[12]00 chips. */ |
2389 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) | 2394 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index f461925a9dfc..8aa05c87b653 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -35,6 +35,10 @@ static struct kmem_cache *srb_cachep; | |||
35 | * CT6 CTX allocation cache | 35 | * CT6 CTX allocation cache |
36 | */ | 36 | */ |
37 | static struct kmem_cache *ctx_cachep; | 37 | static struct kmem_cache *ctx_cachep; |
38 | /* | ||
39 | * error level for logging | ||
40 | */ | ||
41 | int ql_errlev = ql_log_all; | ||
38 | 42 | ||
39 | int ql2xlogintimeout = 20; | 43 | int ql2xlogintimeout = 20; |
40 | module_param(ql2xlogintimeout, int, S_IRUGO); | 44 | module_param(ql2xlogintimeout, int, S_IRUGO); |
@@ -69,8 +73,17 @@ MODULE_PARM_DESC(ql2xallocfwdump, | |||
69 | int ql2xextended_error_logging; | 73 | int ql2xextended_error_logging; |
70 | module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR); | 74 | module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR); |
71 | MODULE_PARM_DESC(ql2xextended_error_logging, | 75 | MODULE_PARM_DESC(ql2xextended_error_logging, |
72 | "Option to enable extended error logging, " | 76 | "Option to enable extended error logging,\n" |
73 | "Default is 0 - no logging. 1 - log errors."); | 77 | "\t\tDefault is 0 - no logging. 0x40000000 - Module Init & Probe.\n" |
78 | "\t\t0x20000000 - Mailbox Cmnds. 0x10000000 - Device Discovery.\n" | ||
79 | "\t\t0x08000000 - IO tracing. 0x04000000 - DPC Thread.\n" | ||
80 | "\t\t0x02000000 - Async events. 0x01000000 - Timer routines.\n" | ||
81 | "\t\t0x00800000 - User space. 0x00400000 - Task Management.\n" | ||
82 | "\t\t0x00200000 - AER/EEH. 0x00100000 - Multi Q.\n" | ||
83 | "\t\t0x00080000 - P3P Specific. 0x00040000 - Virtual Port.\n" | ||
84 | "\t\t0x00020000 - Buffer Dump. 0x00010000 - Misc.\n" | ||
85 | "\t\t0x7fffffff - For enabling all logs, can be too many logs.\n" | ||
86 | "\t\tDo LOGICAL OR of the value to enable more than one level"); | ||
74 | 87 | ||
75 | int ql2xshiftctondsd = 6; | 88 | int ql2xshiftctondsd = 6; |
76 | module_param(ql2xshiftctondsd, int, S_IRUGO); | 89 | module_param(ql2xshiftctondsd, int, S_IRUGO); |