|
@@ -4,10 +4,36 @@
|
|
|
*
|
|
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
|
|
*/
|
|
|
+
|
|
|
+/*
|
|
|
+ * Table for showing the current message id in use for particular level
|
|
|
+ * Change this table for addition of log/debug messages.
|
|
|
+ * -----------------------------------------------------
|
|
|
+ * | Level | Last Value Used |
|
|
|
+ * -----------------------------------------------------
|
|
|
+ * | Module Init and Probe | 0x0109 |
|
|
|
+ * | Mailbox commands | 0x1120 |
|
|
|
+ * | Device Discovery | 0x207d |
|
|
|
+ * | Queue Command and IO tracing | 0x304f |
|
|
|
+ * | DPC Thread | 0x401c |
|
|
|
+ * | Async Events | 0x5058 |
|
|
|
+ * | Timer Routines | 0x600d |
|
|
|
+ * | User Space Interactions | 0x70a1 |
|
|
|
+ * | Task Management | 0x8032 |
|
|
|
+ * | AER/EEH | 0x9010 |
|
|
|
+ * | Virtual Port | 0xa007 |
|
|
|
+ * | ISP82XX Specific | 0xb028 |
|
|
|
+ * | MultiQ | 0xc00b |
|
|
|
+ * | Misc | 0xd00b |
|
|
|
+ * -----------------------------------------------------
|
|
|
+ */
|
|
|
+
|
|
|
#include "qla_def.h"
|
|
|
|
|
|
#include <linux/delay.h>
|
|
|
|
|
|
+static uint32_t ql_dbg_offset = 0x800;
|
|
|
+
|
|
|
static inline void
|
|
|
qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
|
|
|
{
|
|
@@ -1722,3 +1748,255 @@ qla2x00_dump_buffer_zipped(uint8_t *b, uint32_t size)
|
|
|
printk(KERN_DEBUG "\n");
|
|
|
}
|
|
|
}
|
|
|
+/*
|
|
|
+ * This function is for formatting and logging debug information.
|
|
|
+ * It is to be used when vha is available. It formats the message
|
|
|
+ * and logs it to the messages file.
|
|
|
+ * parameters:
|
|
|
+ * level: The level of the debug messages to be printed.
|
|
|
+ * If ql2xextended_error_logging value is correctly set,
|
|
|
+ * this message will appear in the messages file.
|
|
|
+ * vha: Pointer to the scsi_qla_host_t.
|
|
|
+ * id: This is a unique identifier for the level. It identifies the
|
|
|
+ * part of the code from where the message originated.
|
|
|
+ * msg: The message to be displayed.
|
|
|
+ */
|
|
|
+void
|
|
|
+ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, char *msg, ...) {
|
|
|
+
|
|
|
+ char pbuf[QL_DBG_BUF_LEN];
|
|
|
+ va_list ap;
|
|
|
+ uint32_t len;
|
|
|
+ struct pci_dev *pdev = NULL;
|
|
|
+
|
|
|
+ memset(pbuf, 0, QL_DBG_BUF_LEN);
|
|
|
+
|
|
|
+ va_start(ap, msg);
|
|
|
+
|
|
|
+ if ((level & ql2xextended_error_logging) == level) {
|
|
|
+ if (vha != NULL) {
|
|
|
+ pdev = vha->hw->pdev;
|
|
|
+ /* <module-name> <pci-name> <msg-id>:<host> Message */
|
|
|
+ sprintf(pbuf, "%s [%s]-%04x:%ld: ", QL_MSGHDR,
|
|
|
+ dev_name(&(pdev->dev)), id + ql_dbg_offset,
|
|
|
+ vha->host_no);
|
|
|
+ } else
|
|
|
+ sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR,
|
|
|
+ "0000:00:00.0", id + ql_dbg_offset);
|
|
|
+
|
|
|
+ len = strlen(pbuf);
|
|
|
+ vsprintf(pbuf+len, msg, ap);
|
|
|
+ pr_warning("%s", pbuf);
|
|
|
+ }
|
|
|
+
|
|
|
+ va_end(ap);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * This function is for formatting and logging debug information.
|
|
|
+ * It is to be used when vha is not available and pci is availble,
|
|
|
+ * i.e., before host allocation. It formats the message and logs it
|
|
|
+ * to the messages file.
|
|
|
+ * parameters:
|
|
|
+ * level: The level of the debug messages to be printed.
|
|
|
+ * If ql2xextended_error_logging value is correctly set,
|
|
|
+ * this message will appear in the messages file.
|
|
|
+ * pdev: Pointer to the struct pci_dev.
|
|
|
+ * id: This is a unique id for the level. It identifies the part
|
|
|
+ * of the code from where the message originated.
|
|
|
+ * msg: The message to be displayed.
|
|
|
+ */
|
|
|
+void
|
|
|
+ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id, char *msg, ...) {
|
|
|
+
|
|
|
+ char pbuf[QL_DBG_BUF_LEN];
|
|
|
+ va_list ap;
|
|
|
+ uint32_t len;
|
|
|
+
|
|
|
+ if (pdev == NULL)
|
|
|
+ return;
|
|
|
+
|
|
|
+ memset(pbuf, 0, QL_DBG_BUF_LEN);
|
|
|
+
|
|
|
+ va_start(ap, msg);
|
|
|
+
|
|
|
+ if ((level & ql2xextended_error_logging) == level) {
|
|
|
+ /* <module-name> <dev-name>:<msg-id> Message */
|
|
|
+ sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR,
|
|
|
+ dev_name(&(pdev->dev)), id + ql_dbg_offset);
|
|
|
+
|
|
|
+ len = strlen(pbuf);
|
|
|
+ vsprintf(pbuf+len, msg, ap);
|
|
|
+ pr_warning("%s", pbuf);
|
|
|
+ }
|
|
|
+
|
|
|
+ va_end(ap);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * This function is for formatting and logging log messages.
|
|
|
+ * It is to be used when vha is available. It formats the message
|
|
|
+ * and logs it to the messages file. All the messages will be logged
|
|
|
+ * irrespective of value of ql2xextended_error_logging.
|
|
|
+ * parameters:
|
|
|
+ * level: The level of the log messages to be printed in the
|
|
|
+ * messages file.
|
|
|
+ * vha: Pointer to the scsi_qla_host_t
|
|
|
+ * id: This is a unique id for the level. It identifies the
|
|
|
+ * part of the code from where the message originated.
|
|
|
+ * msg: The message to be displayed.
|
|
|
+ */
|
|
|
+void
|
|
|
+ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, char *msg, ...) {
|
|
|
+
|
|
|
+ char pbuf[QL_DBG_BUF_LEN];
|
|
|
+ va_list ap;
|
|
|
+ uint32_t len;
|
|
|
+ struct pci_dev *pdev = NULL;
|
|
|
+
|
|
|
+ memset(pbuf, 0, QL_DBG_BUF_LEN);
|
|
|
+
|
|
|
+ va_start(ap, msg);
|
|
|
+
|
|
|
+ if (level <= ql_errlev) {
|
|
|
+ if (vha != NULL) {
|
|
|
+ pdev = vha->hw->pdev;
|
|
|
+ /* <module-name> <msg-id>:<host> Message */
|
|
|
+ sprintf(pbuf, "%s [%s]-%04x:%ld: ", QL_MSGHDR,
|
|
|
+ dev_name(&(pdev->dev)), id, vha->host_no);
|
|
|
+ } else
|
|
|
+ sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR,
|
|
|
+ "0000:00:00.0", id);
|
|
|
+
|
|
|
+ len = strlen(pbuf);
|
|
|
+ vsprintf(pbuf+len, msg, ap);
|
|
|
+
|
|
|
+ switch (level) {
|
|
|
+ case 0: /* FATAL LOG */
|
|
|
+ pr_crit("%s", pbuf);
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ pr_err("%s", pbuf);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ pr_warn("%s", pbuf);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ pr_info("%s", pbuf);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ va_end(ap);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * This function is for formatting and logging log messages.
|
|
|
+ * It is to be used when vha is not available and pci is availble,
|
|
|
+ * i.e., before host allocation. It formats the message and logs
|
|
|
+ * it to the messages file. All the messages are logged irrespective
|
|
|
+ * of the value of ql2xextended_error_logging.
|
|
|
+ * parameters:
|
|
|
+ * level: The level of the log messages to be printed in the
|
|
|
+ * messages file.
|
|
|
+ * pdev: Pointer to the struct pci_dev.
|
|
|
+ * id: This is a unique id for the level. It identifies the
|
|
|
+ * part of the code from where the message originated.
|
|
|
+ * msg: The message to be displayed.
|
|
|
+ */
|
|
|
+void
|
|
|
+ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id, char *msg, ...) {
|
|
|
+
|
|
|
+ char pbuf[QL_DBG_BUF_LEN];
|
|
|
+ va_list ap;
|
|
|
+ uint32_t len;
|
|
|
+
|
|
|
+ if (pdev == NULL)
|
|
|
+ return;
|
|
|
+
|
|
|
+ memset(pbuf, 0, QL_DBG_BUF_LEN);
|
|
|
+
|
|
|
+ va_start(ap, msg);
|
|
|
+
|
|
|
+ if (level <= ql_errlev) {
|
|
|
+ /* <module-name> <dev-name>:<msg-id> Message */
|
|
|
+ sprintf(pbuf, "%s [%s]-%04x: : ", QL_MSGHDR,
|
|
|
+ dev_name(&(pdev->dev)), id);
|
|
|
+
|
|
|
+ len = strlen(pbuf);
|
|
|
+ vsprintf(pbuf+len, msg, ap);
|
|
|
+ switch (level) {
|
|
|
+ case 0: /* FATAL LOG */
|
|
|
+ pr_crit("%s", pbuf);
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ pr_err("%s", pbuf);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ pr_warn("%s", pbuf);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ pr_info("%s", pbuf);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ va_end(ap);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ struct qla_hw_data *ha = vha->hw;
|
|
|
+ struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
|
|
|
+ struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
|
|
|
+ struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
|
|
|
+ uint16_t __iomem *mbx_reg;
|
|
|
+
|
|
|
+ if ((level & ql2xextended_error_logging) == level) {
|
|
|
+
|
|
|
+ if (IS_QLA82XX(ha))
|
|
|
+ mbx_reg = ®82->mailbox_in[0];
|
|
|
+ else if (IS_FWI2_CAPABLE(ha))
|
|
|
+ mbx_reg = ®24->mailbox0;
|
|
|
+ else
|
|
|
+ mbx_reg = MAILBOX_REG(ha, reg, 0);
|
|
|
+
|
|
|
+ ql_dbg(level, vha, id, "Mailbox registers:\n");
|
|
|
+ for (i = 0; i < 6; i++)
|
|
|
+ ql_dbg(level, vha, id,
|
|
|
+ "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void
|
|
|
+ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id,
|
|
|
+ uint8_t *b, uint32_t size)
|
|
|
+{
|
|
|
+ uint32_t cnt;
|
|
|
+ uint8_t c;
|
|
|
+ if ((level & ql2xextended_error_logging) == level) {
|
|
|
+
|
|
|
+ ql_dbg(level, vha, id, " 0 1 2 3 4 5 6 7 8 "
|
|
|
+ "9 Ah Bh Ch Dh Eh Fh\n");
|
|
|
+ ql_dbg(level, vha, id, "----------------------------------"
|
|
|
+ "----------------------------\n");
|
|
|
+
|
|
|
+ ql_dbg(level, vha, id, "");
|
|
|
+ for (cnt = 0; cnt < size;) {
|
|
|
+ c = *b++;
|
|
|
+ printk("%02x", (uint32_t) c);
|
|
|
+ cnt++;
|
|
|
+ if (!(cnt % 16))
|
|
|
+ printk("\n");
|
|
|
+ else
|
|
|
+ printk(" ");
|
|
|
+ }
|
|
|
+ if (cnt % 16)
|
|
|
+ ql_dbg(level, vha, id, "\n");
|
|
|
+ }
|
|
|
+}
|