aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorSaurav Kashyap <saurav.kashyap@qlogic.com>2011-07-14 15:00:12 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-27 06:12:25 -0400
commit3ce8866ceae87258cf66d1f7fd72abc918753cec (patch)
tree655dbace6c920da216275b9145f20a8515c808f9 /drivers/scsi
parent573e5913536a1393362265cfea9e708aa10fdf16 (diff)
[SCSI] qla2xxx: Basic infrastructure for dynamic logging.
This patch adds the dynamic logging framework to the qla2xxx driver. The user will be able to change the logging levels on the fly i.e. without load/unload of the driver. This also enables logging to be enabled for a particular section of the driver such as initialization, device discovery etc. Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c278
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h47
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c17
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
35static uint32_t ql_dbg_offset = 0x800;
36
11static inline void 37static inline void
12qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump) 38qla2xxx_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 */
1764void
1765ql_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 */
1810void
1811ql_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 */
1851void
1852ql_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 */
1909void
1910ql_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
1949void
1950ql_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 = &reg82->mailbox_in[0];
1963 else if (IS_FWI2_CAPABLE(ha))
1964 mbx_reg = &reg24->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
1976void
1977ql_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
385extern int ql_errlev;
386
387void
388ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, char *, ...);
389void
390ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, char *, ...);
391
392void
393ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, char *, ...);
394void
395ql_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);
439extern void qla2x00_dump_regs(scsi_qla_host_t *); 439extern void qla2x00_dump_regs(scsi_qla_host_t *);
440extern void qla2x00_dump_buffer(uint8_t *, uint32_t); 440extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
441extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); 441extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t);
442extern void ql_dump_regs(uint32_t, scsi_qla_host_t *, int32_t);
443extern 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 */
37static struct kmem_cache *ctx_cachep; 37static struct kmem_cache *ctx_cachep;
38/*
39 * error level for logging
40 */
41int ql_errlev = ql_log_all;
38 42
39int ql2xlogintimeout = 20; 43int ql2xlogintimeout = 20;
40module_param(ql2xlogintimeout, int, S_IRUGO); 44module_param(ql2xlogintimeout, int, S_IRUGO);
@@ -69,8 +73,17 @@ MODULE_PARM_DESC(ql2xallocfwdump,
69int ql2xextended_error_logging; 73int ql2xextended_error_logging;
70module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR); 74module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR);
71MODULE_PARM_DESC(ql2xextended_error_logging, 75MODULE_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
75int ql2xshiftctondsd = 6; 88int ql2xshiftctondsd = 6;
76module_param(ql2xshiftctondsd, int, S_IRUGO); 89module_param(ql2xshiftctondsd, int, S_IRUGO);