aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_dbg.c
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/qla2xxx/qla_dbg.c
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/qla2xxx/qla_dbg.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c278
1 files changed, 278 insertions, 0 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}