diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 10 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 20 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 310 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 19 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 95 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 641 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 253 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 510 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 363 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 5 |
14 files changed, 1121 insertions, 1117 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 6465dae5883a..a2f1b3043dfb 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -107,7 +107,7 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj, set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); break; } - return -EINVAL; + return count; } static struct bin_attribute sysfs_fw_dump_attr = { @@ -387,7 +387,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, break; case 3: if (ha->optrom_state != QLA_SWRITING) - return -ENOMEM; + return -EINVAL; if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x7068, @@ -667,7 +667,7 @@ qla2x00_sysfs_write_edc(struct file *filp, struct kobject *kobj, dev, adr, len, opt); if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x7074, - "Unable to write EDC (%x) %02x:%04x:%02x:%02hhx\n", + "Unable to write EDC (%x) %02x:%04x:%02x:%02x:%02hhx\n", rval, dev, adr, opt, len, buf[8]); return -EIO; } @@ -724,7 +724,7 @@ qla2x00_sysfs_write_edc_status(struct file *filp, struct kobject *kobj, dev, adr, len, opt); if (rval != QLA_SUCCESS) { ql_log(ql_log_info, vha, 0x7075, - "Unable to write EDC status (%x) %02x:%04x:%02x.\n", + "Unable to write EDC status (%x) %02x:%04x:%02x:%02x.\n", rval, dev, adr, opt, len); return -EIO; } @@ -1971,8 +1971,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) "Queue delete failed.\n"); } - scsi_host_put(vha->host); ql_log(ql_log_info, vha, 0x7088, "VP[%d] deleted.\n", id); + scsi_host_put(vha->host); return 0; } diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 8b641a8a0c74..b1d0f936bf2d 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -31,6 +31,7 @@ qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size) memset(sp, 0, sizeof(*sp)); sp->fcport = fcport; sp->ctx = ctx; + ctx->iocbs = 1; done: return sp; } @@ -102,7 +103,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) bsg_job->reply->reply_payload_rcv_len = 0; - if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))) { + if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA82XX(ha))) { ret = -EINVAL; goto exit_fcp_prio_cfg; } @@ -389,6 +390,20 @@ done: return rval; } +inline uint16_t +qla24xx_calc_ct_iocbs(uint16_t dsds) +{ + uint16_t iocbs; + + iocbs = 1; + if (dsds > 2) { + iocbs += (dsds - 2) / 5; + if ((dsds - 2) % 5) + iocbs++; + } + return iocbs; +} + static int qla2x00_process_ct(struct fc_bsg_job *bsg_job) { @@ -489,6 +504,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) ct = sp->ctx; ct->type = SRB_CT_CMD; ct->name = "bsg_ct"; + ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt); ct->u.bsg_job = bsg_job; ql_dbg(ql_dbg_user, vha, 0x7016, @@ -1653,7 +1669,7 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job) } ql_dbg(ql_dbg_user, vha, 0x7000, - "Entered %s msgcode=%d.\n", __func__, bsg_job->request->msgcode); + "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode); switch (bsg_job->request->msgcode) { case FC_BSG_RPT_ELS: diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index f3cddd5800c3..7c54624b5b13 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -11,15 +11,17 @@ * ---------------------------------------------------------------------- * | Level | Last Value Used | Holes | * ---------------------------------------------------------------------- - * | Module Init and Probe | 0x0116 | | + * | Module Init and Probe | 0x0116 | 0xfa | * | Mailbox commands | 0x112b | | - * | Device Discovery | 0x2083 | | - * | Queue Command and IO tracing | 0x302e | 0x3008 | + * | Device Discovery | 0x2084 | | + * | Queue Command and IO tracing | 0x302f | 0x3008,0x302d, | + * | | | 0x302e | * | DPC Thread | 0x401c | | - * | Async Events | 0x5059 | | - * | Timer Routines | 0x6010 | 0x600e,0x600f | - * | User Space Interactions | 0x709d | | - * | Task Management | 0x8041 | 0x800b | + * | Async Events | 0x5057 | 0x5052 | + * | Timer Routines | 0x6011 | 0x600e,0x600f | + * | User Space Interactions | 0x709e | | + * | Task Management | 0x803c | 0x8025-0x8026 | + * | | | 0x800b,0x8039 | * | AER/EEH | 0x900f | | * | Virtual Port | 0xa007 | | * | ISP82XX Specific | 0xb052 | | @@ -368,7 +370,7 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) memcpy(iter_reg, ha->fce, ntohl(fcec->size)); - return iter_reg; + return (char *)iter_reg + ntohl(fcec->size); } static inline void * @@ -1650,6 +1652,15 @@ qla81xx_fw_dump_failed: /****************************************************************************/ /* Driver Debug Functions. */ /****************************************************************************/ + +static inline int +ql_mask_match(uint32_t level) +{ + if (ql2xextended_error_logging == 1) + ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK; + return (level & ql2xextended_error_logging) == level; +} + /* * This function is for formatting and logging debug information. * It is to be used when vha is available. It formats the message @@ -1664,34 +1675,31 @@ qla81xx_fw_dump_failed: * 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); +ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) +{ + va_list va; + struct va_format vaf; + + if (!ql_mask_match(level)) + return; + + va_start(va, fmt); + + vaf.fmt = fmt; + vaf.va = &va; + + if (vha != NULL) { + const struct pci_dev *pdev = vha->hw->pdev; + /* <module-name> <pci-name> <msg-id>:<host> Message */ + pr_warn("%s [%s]-%04x:%ld: %pV", + QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, + vha->host_no, &vaf); + } else { + pr_warn("%s [%s]-%04x: : %pV", + QL_MSGHDR, "0000:00:00.0", id + ql_dbg_offset, &vaf); } - va_end(ap); + va_end(va); } @@ -1710,31 +1718,27 @@ ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, char *msg, ...) { * 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; +ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id, + const char *fmt, ...) +{ + va_list va; + struct va_format vaf; if (pdev == NULL) return; + if (!ql_mask_match(level)) + 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); + va_start(va, fmt); - len = strlen(pbuf); - vsprintf(pbuf+len, msg, ap); - pr_warning("%s", pbuf); - } + vaf.fmt = fmt; + vaf.va = &va; - va_end(ap); + /* <module-name> <dev-name>:<msg-id> Message */ + pr_warn("%s [%s]-%04x: : %pV", + QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, &vaf); + va_end(va); } /* @@ -1751,47 +1755,47 @@ ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id, char *msg, ...) { * 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); +ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) +{ + va_list va; + struct va_format vaf; + char pbuf[128]; - len = strlen(pbuf); - vsprintf(pbuf+len, msg, ap); + if (level > ql_errlev) + return; - 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; - } + if (vha != NULL) { + const struct pci_dev *pdev = vha->hw->pdev; + /* <module-name> <msg-id>:<host> Message */ + snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ", + QL_MSGHDR, dev_name(&(pdev->dev)), id, vha->host_no); + } else { + snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ", + QL_MSGHDR, "0000:00:00.0", id); + } + pbuf[sizeof(pbuf) - 1] = 0; + + va_start(va, fmt); + + vaf.fmt = fmt; + vaf.va = &va; + + switch (level) { + case 0: /* FATAL LOG */ + pr_crit("%s%pV", pbuf, &vaf); + break; + case 1: + pr_err("%s%pV", pbuf, &vaf); + break; + case 2: + pr_warn("%s%pV", pbuf, &vaf); + break; + default: + pr_info("%s%pV", pbuf, &vaf); + break; } - va_end(ap); + va_end(va); } /* @@ -1809,43 +1813,44 @@ ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, char *msg, ...) { * 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; +ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id, + const char *fmt, ...) +{ + va_list va; + struct va_format vaf; + char pbuf[128]; if (pdev == NULL) return; + if (level > ql_errlev) + 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; - } + /* <module-name> <dev-name>:<msg-id> Message */ + snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ", + QL_MSGHDR, dev_name(&(pdev->dev)), id); + pbuf[sizeof(pbuf) - 1] = 0; + + va_start(va, fmt); + + vaf.fmt = fmt; + vaf.va = &va; + + switch (level) { + case 0: /* FATAL LOG */ + pr_crit("%s%pV", pbuf, &vaf); + break; + case 1: + pr_err("%s%pV", pbuf, &vaf); + break; + case 2: + pr_warn("%s%pV", pbuf, &vaf); + break; + default: + pr_info("%s%pV", pbuf, &vaf); + break; } - va_end(ap); + va_end(va); } void @@ -1858,20 +1863,20 @@ ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id) 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); + if (!ql_mask_match(level)) + return; - 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++)); - } + 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++)); } @@ -1881,24 +1886,25 @@ ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id, { 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"); + + if (!ql_mask_match(level)) + return; + + 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"); } diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 98a377b99017..5f1b6d9c3dcb 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -232,6 +232,7 @@ struct qla2xxx_fw_dump { }; #define QL_MSGHDR "qla2xxx" +#define QL_DBG_DEFAULT1_MASK 0x1e400000 #define ql_log_fatal 0 /* display fatal errors */ #define ql_log_warn 1 /* display critical errors */ @@ -244,15 +245,15 @@ struct qla2xxx_fw_dump { extern int ql_errlev; -void -ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, char *, ...); -void -ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, char *, ...); +void __attribute__((format (printf, 4, 5))) +ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...); +void __attribute__((format (printf, 4, 5))) +ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); -void -ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, char *, ...); -void -ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, char *, ...); +void __attribute__((format (printf, 4, 5))) +ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...); +void __attribute__((format (printf, 4, 5))) +ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); /* Debug Levels */ /* The 0x40000000 is the max value any debug level can have @@ -275,5 +276,3 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, char *, ...); #define ql_dbg_misc 0x00010000 /* For dumping everything that is not * not covered by upper categories */ - -#define QL_DBG_BUF_LEN 512 diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index fcf052c50bf5..a6a4eebce4a8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -271,6 +271,7 @@ struct srb_iocb { struct srb_ctx { uint16_t type; char *name; + int iocbs; union { struct srb_iocb *iocb_cmd; struct fc_bsg_job *bsg_job; @@ -2244,6 +2245,7 @@ struct isp_operations { int (*get_flash_version) (struct scsi_qla_host *, void *); int (*start_scsi) (srb_t *); int (*abort_isp) (struct scsi_qla_host *); + int (*iospace_config)(struct qla_hw_data*); }; /* MSI-X Support *************************************************************/ @@ -2978,10 +2980,6 @@ typedef struct scsi_qla_host { atomic_dec(&__vha->vref_count); \ } while (0) - -#define qla_printk(level, ha, format, arg...) \ - dev_printk(level , &((ha)->pdev->dev) , format , ## arg) - /* * qla2x00 local function return status codes */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index c0c11afb685c..408679be8fdf 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -572,7 +572,7 @@ extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *, size_t, char *); extern int qla82xx_mbx_intr_enable(scsi_qla_host_t *); extern int qla82xx_mbx_intr_disable(scsi_qla_host_t *); -extern void qla82xx_start_iocbs(srb_t *); +extern void qla82xx_start_iocbs(scsi_qla_host_t *); extern int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *); extern int qla82xx_check_md_needed(scsi_qla_host_t *); extern void qla82xx_chip_reset_cleanup(scsi_qla_host_t *); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 37937aa3c3b8..4aea4ae23300 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -758,7 +758,7 @@ qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) "GA_NXT Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.gan_data[8] != 0x80 || sns_cmd->p.gan_data[9] != 0x02) { - ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207d, + ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084, "GA_NXT failed, rejected request ga_nxt_rsp:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074, sns_cmd->p.gan_data, 16); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 54ea68cec4c5..1fa067e053d2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -111,6 +111,7 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, memset(sp, 0, sizeof(*sp)); sp->fcport = fcport; sp->ctx = ctx; + ctx->iocbs = 1; ctx->u.iocb_cmd = iocb; iocb->free = qla2x00_ctx_sp_free; @@ -154,8 +155,8 @@ qla2x00_async_iocb_timeout(srb_t *sp) struct srb_ctx *ctx = sp->ctx; ql_dbg(ql_dbg_disc, fcport->vha, 0x2071, - "Async-%s timeout - portid=%02x%02x%02x.\n", - ctx->name, fcport->d_id.b.domain, fcport->d_id.b.area, + "Async-%s timeout - hdl=%x portid=%02x%02x%02x.\n", + ctx->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); fcport->flags &= ~FCF_ASYNC_SENT; @@ -211,9 +212,10 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, goto done_free_sp; ql_dbg(ql_dbg_disc, vha, 0x2072, - "Async-login - loopid=%x portid=%02x%02x%02x retries=%d.\n", - fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, fcport->login_retry); + "Async-login - hdl=%x, loopid=%x portid=%02x%02x%02x " + "retries=%d.\n", sp->handle, fcport->loop_id, + fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, + fcport->login_retry); return rval; done_free_sp: @@ -258,9 +260,9 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) goto done_free_sp; ql_dbg(ql_dbg_disc, vha, 0x2070, - "Async-logout - loop-id=%x portid=%02x%02x%02x.\n", - fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa); + "Async-logout - hdl=%x loop-id=%x portid=%02x%02x%02x.\n", + sp->handle, fcport->loop_id, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa); return rval; done_free_sp: @@ -308,9 +310,9 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, goto done_free_sp; ql_dbg(ql_dbg_disc, vha, 0x206f, - "Async-adisc - loopid=%x portid=%02x%02x%02x.\n", - fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa); + "Async-adisc - hdl=%x loopid=%x portid=%02x%02x%02x.\n", + sp->handle, fcport->loop_id, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa); return rval; done_free_sp: @@ -360,9 +362,9 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun, goto done_free_sp; ql_dbg(ql_dbg_taskm, vha, 0x802f, - "Async-tmf loop-id=%x portid=%02x%02x%02x.\n", - fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa); + "Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x.\n", + sp->handle, fcport->loop_id, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa); return rval; done_free_sp: @@ -514,7 +516,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) set_bit(0, ha->req_qid_map); set_bit(0, ha->rsp_qid_map); - ql_log(ql_log_info, vha, 0x0040, + ql_dbg(ql_dbg_init, vha, 0x0040, "Configuring PCI space...\n"); rval = ha->isp_ops->pci_config(vha); if (rval) { @@ -533,7 +535,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) } ha->isp_ops->get_flash_version(vha, req->ring); - ql_log(ql_log_info, vha, 0x0061, + ql_dbg(ql_dbg_init, vha, 0x0061, "Configure NVRAM parameters...\n"); ha->isp_ops->nvram_config(vha); @@ -550,7 +552,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) return QLA_FUNCTION_FAILED; } - ql_log(ql_log_info, vha, 0x0078, + ql_dbg(ql_dbg_init, vha, 0x0078, "Verifying loaded RISC code...\n"); if (qla2x00_isp_firmware(vha) != QLA_SUCCESS) { @@ -1294,7 +1296,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) ha->flags.fce_enabled = 0; goto try_eft; } - ql_log(ql_log_info, vha, 0x00c0, + ql_dbg(ql_dbg_init, vha, 0x00c0, "Allocate (%d KB) for FCE...\n", FCE_SIZE / 1024); fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; @@ -1321,7 +1323,7 @@ try_eft: tc_dma); goto cont_alloc; } - ql_log(ql_log_info, vha, 0x00c3, + ql_dbg(ql_dbg_init, vha, 0x00c3, "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); eft_size = EFT_SIZE; @@ -1358,7 +1360,7 @@ cont_alloc: } return; } - ql_log(ql_log_info, vha, 0x00c5, + ql_dbg(ql_dbg_init, vha, 0x00c5, "Allocated (%d KB) for firmware dump.\n", dump_size / 1024); ha->fw_dump_len = dump_size; @@ -1929,7 +1931,7 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) rval = qla84xx_init_chip(vha); if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, - vha, 0x8026, + vha, 0x8007, "Init chip failed.\n"); break; } @@ -1938,7 +1940,7 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) cs84xx_time = jiffies - cs84xx_time; wtime += cs84xx_time; mtime += cs84xx_time; - ql_dbg(ql_dbg_taskm, vha, 0x8025, + ql_dbg(ql_dbg_taskm, vha, 0x8008, "Increasing wait time by %ld. " "New time %ld.\n", cs84xx_time, wtime); @@ -1981,16 +1983,13 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) /* Delay for a while */ msleep(500); - - ql_dbg(ql_dbg_taskm, vha, 0x8039, - "fw_state=%x curr time=%lx.\n", state[0], jiffies); } while (1); ql_dbg(ql_dbg_taskm, vha, 0x803a, "fw_state=%x (%x, %x, %x, %x) " "curr time=%lx.\n", state[0], state[1], state[2], state[3], state[4], jiffies); - if (rval) { + if (rval && !(vha->device_flags & DFLG_NO_CABLE)) { ql_log(ql_log_warn, vha, 0x803b, "Firmware ready **** FAILED ****.\n"); } @@ -2386,7 +2385,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) * internal driver logging. */ if (nv->host_p[0] & BIT_7) - ql2xextended_error_logging = 0x7fffffff; + ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK; ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); /* Always load RISC code on non ISP2[12]00 chips. */ if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) @@ -4188,7 +4187,8 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) spin_unlock_irqrestore(&ha->vport_slock, flags); } else { - ql_log(ql_log_warn, vha, 0x8023, "%s **** FAILED ****.\n"); + ql_log(ql_log_warn, vha, 0x8023, "%s **** FAILED ****.\n", + __func__); } return(status); @@ -4638,7 +4638,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, struct req_que *req = ha->req_q_map[0]; ql_dbg(ql_dbg_init, vha, 0x008b, - "Loading firmware from flash (%x).\n", faddr); + "FW: Loading firmware from flash (%x).\n", faddr); rval = QLA_SUCCESS; @@ -4836,8 +4836,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) return QLA_FUNCTION_FAILED; } - ql_log(ql_log_info, vha, 0x0092, - "Loading via request-firmware.\n"); + ql_dbg(ql_dbg_init, vha, 0x0092, + "FW: Loading via request-firmware.\n"); rval = QLA_SUCCESS; @@ -5425,7 +5425,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) if ((vha->device_flags & DFLG_NO_CABLE)) status = 0; - ql_log(ql_log_info, vha, 0x803d, + ql_log(ql_log_info, vha, 0x8000, "Configure loop done, status = 0x%x.\n", status); } @@ -5458,7 +5458,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) ha->fce_dma, ha->fce_bufs, ha->fce_mb, &ha->fce_bufs); if (rval) { - ql_log(ql_log_warn, vha, 0x803e, + ql_log(ql_log_warn, vha, 0x8001, "Unable to reinitialize FCE (%d).\n", rval); ha->flags.fce_enabled = 0; @@ -5470,7 +5470,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) rval = qla2x00_enable_eft_trace(vha, ha->eft_dma, EFT_NUM_BUFFERS); if (rval) { - ql_log(ql_log_warn, vha, 0x803f, + ql_log(ql_log_warn, vha, 0x8010, "Unable to reinitialize EFT (%d).\n", rval); } @@ -5478,7 +5478,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) } if (!status) { - ql_dbg(ql_dbg_taskm, vha, 0x8040, + ql_dbg(ql_dbg_taskm, vha, 0x8011, "qla82xx_restart_isp succeeded.\n"); spin_lock_irqsave(&ha->vport_slock, flags); @@ -5496,7 +5496,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) spin_unlock_irqrestore(&ha->vport_slock, flags); } else { - ql_log(ql_log_warn, vha, 0x8041, + ql_log(ql_log_warn, vha, 0x8016, "qla82xx_restart_isp **** FAILED ****.\n"); } @@ -5643,13 +5643,26 @@ qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport) if (priority < 0) return QLA_FUNCTION_FAILED; + if (IS_QLA82XX(vha->hw)) { + fcport->fcp_prio = priority & 0xf; + return QLA_SUCCESS; + } + ret = qla24xx_set_fcp_prio(vha, fcport->loop_id, priority, mb); - if (ret == QLA_SUCCESS) - fcport->fcp_prio = priority; - else + if (ret == QLA_SUCCESS) { + if (fcport->fcp_prio != priority) + ql_dbg(ql_dbg_user, vha, 0x709e, + "Updated FCP_CMND priority - value=%d loop_id=%d " + "port_id=%02x%02x%02x.\n", priority, + fcport->loop_id, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa); + fcport->fcp_prio = priority & 0xf; + } else ql_dbg(ql_dbg_user, vha, 0x704f, - "Unable to activate fcp priority, ret=0x%x.\n", ret); - + "Unable to update FCP_CMND priority - ret=0x%x for " + "loop_id=%d port_id=%02x%02x%02x.\n", ret, fcport->loop_id, + fcport->d_id.b.domain, fcport->d_id.b.area, + fcport->d_id.b.al_pa); return ret; } diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index a4b267e60a35..55a96761b5a4 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -11,8 +11,6 @@ #include <scsi/scsi_tcq.h> -static void qla2x00_isp_cmd(struct scsi_qla_host *, struct req_que *); - static void qla25xx_set_que(srb_t *, struct rsp_que **); /** * qla2x00_get_cmd_direction() - Determine control_flag data direction. @@ -468,6 +466,42 @@ queuing_error: } /** + * qla2x00_start_iocbs() - Execute the IOCB command + */ +static void +qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) +{ + struct qla_hw_data *ha = vha->hw; + device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); + struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp; + + if (IS_QLA82XX(ha)) { + qla82xx_start_iocbs(vha); + } else { + /* Adjust ring index. */ + req->ring_index++; + if (req->ring_index == req->length) { + req->ring_index = 0; + req->ring_ptr = req->ring; + } else + req->ring_ptr++; + + /* Set chip new ring index. */ + if (ha->mqenable) { + WRT_REG_DWORD(®->isp25mq.req_q_in, req->ring_index); + RD_REG_DWORD(&ioreg->hccr); + } else if (IS_FWI2_CAPABLE(ha)) { + WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index); + RD_REG_DWORD_RELAXED(®->isp24.req_q_in); + } else { + WRT_REG_WORD(ISP_REQ_Q_IN(ha, ®->isp), + req->ring_index); + RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, ®->isp)); + } + } +} + +/** * qla2x00_marker() - Send a marker IOCB to the firmware. * @ha: HA context * @loop_id: loop ID @@ -489,6 +523,7 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); mrk24 = NULL; + req = ha->req_q_map[0]; mrk = (mrk_entry_t *)qla2x00_alloc_iocbs(vha, 0); if (mrk == NULL) { ql_log(ql_log_warn, base_vha, 0x3026, @@ -515,7 +550,7 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, } wmb(); - qla2x00_isp_cmd(vha, req); + qla2x00_start_iocbs(vha, req); return (QLA_SUCCESS); } @@ -536,89 +571,140 @@ qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req, } /** - * qla2x00_isp_cmd() - Modify the request ring pointer. - * @ha: HA context + * qla24xx_calc_iocbs() - Determine number of Command Type 3 and + * Continuation Type 1 IOCBs to allocate. + * + * @dsds: number of data segment decriptors needed * - * Note: The caller must hold the hardware lock before calling this routine. + * Returns the number of IOCB entries needed to store @dsds. */ -static void -qla2x00_isp_cmd(struct scsi_qla_host *vha, struct req_que *req) +inline uint16_t +qla24xx_calc_iocbs(scsi_qla_host_t *vha, uint16_t dsds) { - struct qla_hw_data *ha = vha->hw; - device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); - struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp; + uint16_t iocbs; - ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x302d, - "IOCB data:\n"); - ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302e, - (uint8_t *)req->ring_ptr, REQUEST_ENTRY_SIZE); + iocbs = 1; + if (dsds > 1) { + iocbs += (dsds - 1) / 5; + if ((dsds - 1) % 5) + iocbs++; + } + return iocbs; +} - /* Adjust ring index. */ - req->ring_index++; - if (req->ring_index == req->length) { - req->ring_index = 0; - req->ring_ptr = req->ring; - } else - req->ring_ptr++; +static inline int +qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, + uint16_t tot_dsds) +{ + uint32_t *cur_dsd = NULL; + scsi_qla_host_t *vha; + struct qla_hw_data *ha; + struct scsi_cmnd *cmd; + struct scatterlist *cur_seg; + uint32_t *dsd_seg; + void *next_dsd; + uint8_t avail_dsds; + uint8_t first_iocb = 1; + uint32_t dsd_list_len; + struct dsd_dma *dsd_ptr; + struct ct6_dsd *ctx; - /* Set chip new ring index. */ - if (IS_QLA82XX(ha)) { - uint32_t dbval = 0x04 | (ha->portnum << 5); + cmd = sp->cmd; - /* write, read and verify logic */ - dbval = dbval | (req->id << 8) | (req->ring_index << 16); - if (ql2xdbwr) - qla82xx_wr_32(ha, ha->nxdb_wr_ptr, dbval); - else { - WRT_REG_DWORD( - (unsigned long __iomem *)ha->nxdb_wr_ptr, - dbval); - wmb(); - while (RD_REG_DWORD(ha->nxdb_rd_ptr) != dbval) { - WRT_REG_DWORD((unsigned long __iomem *) - ha->nxdb_wr_ptr, dbval); - wmb(); - } - } - } else if (ha->mqenable) { - /* Set chip new ring index. */ - WRT_REG_DWORD(®->isp25mq.req_q_in, req->ring_index); - RD_REG_DWORD(&ioreg->hccr); - } else { - if (IS_FWI2_CAPABLE(ha)) { - WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index); - RD_REG_DWORD_RELAXED(®->isp24.req_q_in); + /* Update entry type to indicate Command Type 3 IOCB */ + *((uint32_t *)(&cmd_pkt->entry_type)) = + __constant_cpu_to_le32(COMMAND_TYPE_6); + + /* No data transfer */ + if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { + cmd_pkt->byte_count = __constant_cpu_to_le32(0); + return 0; + } + + vha = sp->fcport->vha; + ha = vha->hw; + + /* Set transfer direction */ + if (cmd->sc_data_direction == DMA_TO_DEVICE) { + cmd_pkt->control_flags = + __constant_cpu_to_le16(CF_WRITE_DATA); + ha->qla_stats.output_bytes += scsi_bufflen(cmd); + } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { + cmd_pkt->control_flags = + __constant_cpu_to_le16(CF_READ_DATA); + ha->qla_stats.input_bytes += scsi_bufflen(cmd); + } + + cur_seg = scsi_sglist(cmd); + ctx = sp->ctx; + + while (tot_dsds) { + avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ? + QLA_DSDS_PER_IOCB : tot_dsds; + tot_dsds -= avail_dsds; + dsd_list_len = (avail_dsds + 1) * QLA_DSD_SIZE; + + dsd_ptr = list_first_entry(&ha->gbl_dsd_list, + struct dsd_dma, list); + next_dsd = dsd_ptr->dsd_addr; + list_del(&dsd_ptr->list); + ha->gbl_dsd_avail--; + list_add_tail(&dsd_ptr->list, &ctx->dsd_list); + ctx->dsd_use_cnt++; + ha->gbl_dsd_inuse++; + + if (first_iocb) { + first_iocb = 0; + dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; + *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); + *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); + cmd_pkt->fcp_data_dseg_len = cpu_to_le32(dsd_list_len); } else { - WRT_REG_WORD(ISP_REQ_Q_IN(ha, ®->isp), - req->ring_index); - RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, ®->isp)); + *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); + *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); + *cur_dsd++ = cpu_to_le32(dsd_list_len); + } + cur_dsd = (uint32_t *)next_dsd; + while (avail_dsds) { + dma_addr_t sle_dma; + + sle_dma = sg_dma_address(cur_seg); + *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); + *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); + *cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg)); + cur_seg = sg_next(cur_seg); + avail_dsds--; } } + /* Null termination */ + *cur_dsd++ = 0; + *cur_dsd++ = 0; + *cur_dsd++ = 0; + cmd_pkt->control_flags |= CF_DATA_SEG_DESCR_ENABLE; + return 0; } -/** - * qla24xx_calc_iocbs() - Determine number of Command Type 3 and - * Continuation Type 1 IOCBs to allocate. +/* + * qla24xx_calc_dsd_lists() - Determine number of DSD list required + * for Command Type 6. * * @dsds: number of data segment decriptors needed * - * Returns the number of IOCB entries needed to store @dsds. + * Returns the number of dsd list needed to store @dsds. */ inline uint16_t -qla24xx_calc_iocbs(scsi_qla_host_t *vha, uint16_t dsds) +qla24xx_calc_dsd_lists(uint16_t dsds) { - uint16_t iocbs; + uint16_t dsd_lists = 0; - iocbs = 1; - if (dsds > 1) { - iocbs += (dsds - 1) / 5; - if ((dsds - 1) % 5) - iocbs++; - } - return iocbs; + dsd_lists = (dsds/QLA_DSDS_PER_IOCB); + if (dsds % QLA_DSDS_PER_IOCB) + dsd_lists++; + return dsd_lists; } + /** * qla24xx_build_scsi_iocbs() - Build IOCB command utilizing Command Type 7 * IOCB types. @@ -945,6 +1031,7 @@ alloc_and_fill: *cur_dsd++ = 0; return 0; } + static int qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, uint16_t tot_dsds) @@ -1004,7 +1091,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, sle_dma = sg_dma_address(sg); ql_dbg(ql_dbg_io, vha, 0x300a, "sg entry %d - addr=0x%x 0x%x, " "len=%d for cmd=%p.\n", - cur_dsd, i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg), + i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg), sp->cmd); *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); @@ -1731,6 +1818,7 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) uint32_t index, handle; request_t *pkt; uint16_t cnt, req_cnt; + struct srb_ctx *ctx; pkt = NULL; req_cnt = 1; @@ -1759,6 +1847,12 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp) req->outstanding_cmds[handle] = sp; sp->handle = handle; + /* Adjust entry-counts as needed. */ + if (sp->ctx) { + ctx = sp->ctx; + req_cnt = ctx->iocbs; + } + skip_cmd_array: /* Check for room on request queue. */ if (req->cnt < req_cnt) { @@ -1793,42 +1887,6 @@ queuing_error: } static void -qla2x00_start_iocbs(srb_t *sp) -{ - struct qla_hw_data *ha = sp->fcport->vha->hw; - struct req_que *req = ha->req_q_map[0]; - device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); - struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp; - - if (IS_QLA82XX(ha)) { - qla82xx_start_iocbs(sp); - } else { - /* Adjust ring index. */ - req->ring_index++; - if (req->ring_index == req->length) { - req->ring_index = 0; - req->ring_ptr = req->ring; - } else - req->ring_ptr++; - - /* Set chip new ring index. */ - if (ha->mqenable) { - WRT_REG_DWORD(®->isp25mq.req_q_in, req->ring_index); - RD_REG_DWORD(&ioreg->hccr); - } else if (IS_QLA82XX(ha)) { - qla82xx_start_iocbs(sp); - } else if (IS_FWI2_CAPABLE(ha)) { - WRT_REG_DWORD(®->isp24.req_q_in, req->ring_index); - RD_REG_DWORD_RELAXED(®->isp24.req_q_in); - } else { - WRT_REG_WORD(ISP_REQ_Q_IN(ha, ®->isp), - req->ring_index); - RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, ®->isp)); - } - } -} - -static void qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio) { struct srb_ctx *ctx = sp->ctx; @@ -2160,6 +2218,381 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) ct_iocb->entry_count = entry_count; } +/* + * qla82xx_start_scsi() - Send a SCSI command to the ISP + * @sp: command to send to the ISP + * + * Returns non-zero if a failure occurred, else zero. + */ +int +qla82xx_start_scsi(srb_t *sp) +{ + int ret, nseg; + unsigned long flags; + struct scsi_cmnd *cmd; + uint32_t *clr_ptr; + uint32_t index; + uint32_t handle; + uint16_t cnt; + uint16_t req_cnt; + uint16_t tot_dsds; + struct device_reg_82xx __iomem *reg; + uint32_t dbval; + uint32_t *fcp_dl; + uint8_t additional_cdb_len; + struct ct6_dsd *ctx; + struct scsi_qla_host *vha = sp->fcport->vha; + struct qla_hw_data *ha = vha->hw; + struct req_que *req = NULL; + struct rsp_que *rsp = NULL; + char tag[2]; + + /* Setup device pointers. */ + ret = 0; + reg = &ha->iobase->isp82; + cmd = sp->cmd; + req = vha->req; + rsp = ha->rsp_q_map[0]; + + /* So we know we haven't pci_map'ed anything yet */ + tot_dsds = 0; + + dbval = 0x04 | (ha->portnum << 5); + + /* Send marker if required */ + if (vha->marker_needed != 0) { + if (qla2x00_marker(vha, req, + rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x300c, + "qla2x00_marker failed for cmd=%p.\n", cmd); + return QLA_FUNCTION_FAILED; + } + vha->marker_needed = 0; + } + + /* Acquire ring specific lock */ + spin_lock_irqsave(&ha->hardware_lock, flags); + + /* Check for room in outstanding command list. */ + handle = req->current_outstanding_cmd; + for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) { + handle++; + if (handle == MAX_OUTSTANDING_COMMANDS) + handle = 1; + if (!req->outstanding_cmds[handle]) + break; + } + if (index == MAX_OUTSTANDING_COMMANDS) + goto queuing_error; + + /* Map the sg table so we have an accurate count of sg entries needed */ + if (scsi_sg_count(cmd)) { + nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd), + scsi_sg_count(cmd), cmd->sc_data_direction); + if (unlikely(!nseg)) + goto queuing_error; + } else + nseg = 0; + + tot_dsds = nseg; + + if (tot_dsds > ql2xshiftctondsd) { + struct cmd_type_6 *cmd_pkt; + uint16_t more_dsd_lists = 0; + struct dsd_dma *dsd_ptr; + uint16_t i; + + more_dsd_lists = qla24xx_calc_dsd_lists(tot_dsds); + if ((more_dsd_lists + ha->gbl_dsd_inuse) >= NUM_DSD_CHAIN) { + ql_dbg(ql_dbg_io, vha, 0x300d, + "Num of DSD list %d is than %d for cmd=%p.\n", + more_dsd_lists + ha->gbl_dsd_inuse, NUM_DSD_CHAIN, + cmd); + goto queuing_error; + } + + if (more_dsd_lists <= ha->gbl_dsd_avail) + goto sufficient_dsds; + else + more_dsd_lists -= ha->gbl_dsd_avail; + + for (i = 0; i < more_dsd_lists; i++) { + dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC); + if (!dsd_ptr) { + ql_log(ql_log_fatal, vha, 0x300e, + "Failed to allocate memory for dsd_dma " + "for cmd=%p.\n", cmd); + goto queuing_error; + } + + dsd_ptr->dsd_addr = dma_pool_alloc(ha->dl_dma_pool, + GFP_ATOMIC, &dsd_ptr->dsd_list_dma); + if (!dsd_ptr->dsd_addr) { + kfree(dsd_ptr); + ql_log(ql_log_fatal, vha, 0x300f, + "Failed to allocate memory for dsd_addr " + "for cmd=%p.\n", cmd); + goto queuing_error; + } + list_add_tail(&dsd_ptr->list, &ha->gbl_dsd_list); + ha->gbl_dsd_avail++; + } + +sufficient_dsds: + req_cnt = 1; + + if (req->cnt < (req_cnt + 2)) { + cnt = (uint16_t)RD_REG_DWORD_RELAXED( + ®->req_q_out[0]); + if (req->ring_index < cnt) + req->cnt = cnt - req->ring_index; + else + req->cnt = req->length - + (req->ring_index - cnt); + } + + if (req->cnt < (req_cnt + 2)) + goto queuing_error; + + ctx = sp->ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); + if (!sp->ctx) { + ql_log(ql_log_fatal, vha, 0x3010, + "Failed to allocate ctx for cmd=%p.\n", cmd); + goto queuing_error; + } + memset(ctx, 0, sizeof(struct ct6_dsd)); + ctx->fcp_cmnd = dma_pool_alloc(ha->fcp_cmnd_dma_pool, + GFP_ATOMIC, &ctx->fcp_cmnd_dma); + if (!ctx->fcp_cmnd) { + ql_log(ql_log_fatal, vha, 0x3011, + "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd); + goto queuing_error_fcp_cmnd; + } + + /* Initialize the DSD list and dma handle */ + INIT_LIST_HEAD(&ctx->dsd_list); + ctx->dsd_use_cnt = 0; + + if (cmd->cmd_len > 16) { + additional_cdb_len = cmd->cmd_len - 16; + if ((cmd->cmd_len % 4) != 0) { + /* SCSI command bigger than 16 bytes must be + * multiple of 4 + */ + ql_log(ql_log_warn, vha, 0x3012, + "scsi cmd len %d not multiple of 4 " + "for cmd=%p.\n", cmd->cmd_len, cmd); + goto queuing_error_fcp_cmnd; + } + ctx->fcp_cmnd_len = 12 + cmd->cmd_len + 4; + } else { + additional_cdb_len = 0; + ctx->fcp_cmnd_len = 12 + 16 + 4; + } + + cmd_pkt = (struct cmd_type_6 *)req->ring_ptr; + cmd_pkt->handle = MAKE_HANDLE(req->id, handle); + + /* Zero out remaining portion of packet. */ + /* tagged queuing modifier -- default is TSK_SIMPLE (0). */ + clr_ptr = (uint32_t *)cmd_pkt + 2; + memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8); + cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); + + /* Set NPORT-ID and LUN number*/ + cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id); + cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; + cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; + cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; + cmd_pkt->vp_index = sp->fcport->vp_idx; + + /* Build IOCB segments */ + if (qla24xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds)) + goto queuing_error_fcp_cmnd; + + int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); + host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); + + /* build FCP_CMND IU */ + memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); + int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); + ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; + + if (cmd->sc_data_direction == DMA_TO_DEVICE) + ctx->fcp_cmnd->additional_cdb_len |= 1; + else if (cmd->sc_data_direction == DMA_FROM_DEVICE) + ctx->fcp_cmnd->additional_cdb_len |= 2; + + /* + * Update tagged queuing modifier -- default is TSK_SIMPLE (0). + */ + if (scsi_populate_tag_msg(cmd, tag)) { + switch (tag[0]) { + case HEAD_OF_QUEUE_TAG: + ctx->fcp_cmnd->task_attribute = + TSK_HEAD_OF_QUEUE; + break; + case ORDERED_QUEUE_TAG: + ctx->fcp_cmnd->task_attribute = + TSK_ORDERED; + break; + } + } + + /* Populate the FCP_PRIO. */ + if (ha->flags.fcp_prio_enabled) + ctx->fcp_cmnd->task_attribute |= + sp->fcport->fcp_prio << 3; + + memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); + + fcp_dl = (uint32_t *)(ctx->fcp_cmnd->cdb + 16 + + additional_cdb_len); + *fcp_dl = htonl((uint32_t)scsi_bufflen(cmd)); + + cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len); + cmd_pkt->fcp_cmnd_dseg_address[0] = + cpu_to_le32(LSD(ctx->fcp_cmnd_dma)); + cmd_pkt->fcp_cmnd_dseg_address[1] = + cpu_to_le32(MSD(ctx->fcp_cmnd_dma)); + + sp->flags |= SRB_FCP_CMND_DMA_VALID; + cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); + /* Set total data segment count. */ + cmd_pkt->entry_count = (uint8_t)req_cnt; + /* Specify response queue number where + * completion should happen + */ + cmd_pkt->entry_status = (uint8_t) rsp->id; + } else { + struct cmd_type_7 *cmd_pkt; + req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); + if (req->cnt < (req_cnt + 2)) { + cnt = (uint16_t)RD_REG_DWORD_RELAXED( + ®->req_q_out[0]); + if (req->ring_index < cnt) + req->cnt = cnt - req->ring_index; + else + req->cnt = req->length - + (req->ring_index - cnt); + } + if (req->cnt < (req_cnt + 2)) + goto queuing_error; + + cmd_pkt = (struct cmd_type_7 *)req->ring_ptr; + cmd_pkt->handle = MAKE_HANDLE(req->id, handle); + + /* Zero out remaining portion of packet. */ + /* tagged queuing modifier -- default is TSK_SIMPLE (0).*/ + clr_ptr = (uint32_t *)cmd_pkt + 2; + memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8); + cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); + + /* Set NPORT-ID and LUN number*/ + cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id); + cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; + cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; + cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; + cmd_pkt->vp_index = sp->fcport->vp_idx; + + int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); + host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, + sizeof(cmd_pkt->lun)); + + /* + * Update tagged queuing modifier -- default is TSK_SIMPLE (0). + */ + if (scsi_populate_tag_msg(cmd, tag)) { + switch (tag[0]) { + case HEAD_OF_QUEUE_TAG: + cmd_pkt->task = TSK_HEAD_OF_QUEUE; + break; + case ORDERED_QUEUE_TAG: + cmd_pkt->task = TSK_ORDERED; + break; + } + } + + /* Populate the FCP_PRIO. */ + if (ha->flags.fcp_prio_enabled) + cmd_pkt->task |= sp->fcport->fcp_prio << 3; + + /* Load SCSI command packet. */ + memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); + host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); + + cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); + + /* Build IOCB segments */ + qla24xx_build_scsi_iocbs(sp, cmd_pkt, tot_dsds); + + /* Set total data segment count. */ + cmd_pkt->entry_count = (uint8_t)req_cnt; + /* Specify response queue number where + * completion should happen. + */ + cmd_pkt->entry_status = (uint8_t) rsp->id; + + } + /* Build command packet. */ + req->current_outstanding_cmd = handle; + req->outstanding_cmds[handle] = sp; + sp->handle = handle; + sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; + req->cnt -= req_cnt; + wmb(); + + /* Adjust ring index. */ + req->ring_index++; + if (req->ring_index == req->length) { + req->ring_index = 0; + req->ring_ptr = req->ring; + } else + req->ring_ptr++; + + sp->flags |= SRB_DMA_VALID; + + /* Set chip new ring index. */ + /* write, read and verify logic */ + dbval = dbval | (req->id << 8) | (req->ring_index << 16); + if (ql2xdbwr) + qla82xx_wr_32(ha, ha->nxdb_wr_ptr, dbval); + else { + WRT_REG_DWORD( + (unsigned long __iomem *)ha->nxdb_wr_ptr, + dbval); + wmb(); + while (RD_REG_DWORD(ha->nxdb_rd_ptr) != dbval) { + WRT_REG_DWORD( + (unsigned long __iomem *)ha->nxdb_wr_ptr, + dbval); + wmb(); + } + } + + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + + spin_unlock_irqrestore(&ha->hardware_lock, flags); + return QLA_SUCCESS; + +queuing_error_fcp_cmnd: + dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma); +queuing_error: + if (tot_dsds) + scsi_dma_unmap(cmd); + + if (sp->ctx) { + mempool_free(sp->ctx, ha->ctx_mempool); + sp->ctx = NULL; + } + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + return QLA_FUNCTION_FAILED; +} + int qla2x00_start_sp(srb_t *sp) { @@ -2196,8 +2629,8 @@ qla2x00_start_sp(srb_t *sp) break; case SRB_CT_CMD: IS_FWI2_CAPABLE(ha) ? - qla24xx_ct_iocb(sp, pkt) : - qla2x00_ct_iocb(sp, pkt); + qla24xx_ct_iocb(sp, pkt) : + qla2x00_ct_iocb(sp, pkt); break; case SRB_ADISC_CMD: IS_FWI2_CAPABLE(ha) ? @@ -2212,7 +2645,7 @@ qla2x00_start_sp(srb_t *sp) } wmb(); - qla2x00_start_iocbs(sp); + qla2x00_start_iocbs(sp->fcport->vha, ha->req_q_map[0]); done: spin_unlock_irqrestore(&ha->hardware_lock, flags); return rval; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 7b91b290ffd6..e804585cc59c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -242,32 +242,34 @@ static void qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) { uint16_t cnt; + uint32_t mboxes; uint16_t __iomem *wptr; struct qla_hw_data *ha = vha->hw; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + /* Read all mbox registers? */ + mboxes = (1 << ha->mbx_count) - 1; + if (!ha->mcp) + ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERRROR.\n"); + else + mboxes = ha->mcp->in_mb; + /* Load return mailbox registers. */ ha->flags.mbox_int = 1; ha->mailbox_out[0] = mb0; + mboxes >>= 1; wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1); for (cnt = 1; cnt < ha->mbx_count; cnt++) { if (IS_QLA2200(ha) && cnt == 8) wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8); - if (cnt == 4 || cnt == 5) + if ((cnt == 4 || cnt == 5) && (mboxes & BIT_0)) ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr); - else + else if (mboxes & BIT_0) ha->mailbox_out[cnt] = RD_REG_WORD(wptr); wptr++; - } - - if (ha->mcp) { - ql_dbg(ql_dbg_async, vha, 0x5000, - "Got mbx completion. cmd=%x.\n", ha->mcp->mb[0]); - } else { - ql_dbg(ql_dbg_async, vha, 0x5001, - "MBX pointer ERROR.\n"); + mboxes >>= 1; } } @@ -298,7 +300,7 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr) return; ql_dbg(ql_dbg_async, vha, 0x5022, - "Inter-Driver Commucation %s -- ACK timeout=%d.\n", + "%lu Inter-Driver Communication %s -- ACK timeout=%d.\n", vha->host_no, event[aen & 0xff], timeout); rval = qla2x00_post_idc_ack_work(vha, mb); @@ -453,7 +455,7 @@ skip_rio: break; case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ - ql_log(ql_log_info, vha, 0x5009, + ql_dbg(ql_dbg_async, vha, 0x5009, "LIP occurred (%x).\n", mb[1]); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { @@ -487,7 +489,7 @@ skip_rio: ha->link_data_rate = mb[1]; } - ql_log(ql_log_info, vha, 0x500a, + ql_dbg(ql_dbg_async, vha, 0x500a, "LOOP UP detected (%s Gbps).\n", link_speed); vha->flags.management_server_logged_in = 0; @@ -497,7 +499,7 @@ skip_rio: case MBA_LOOP_DOWN: /* Loop Down Event */ mbx = IS_QLA81XX(ha) ? RD_REG_WORD(®24->mailbox4) : 0; mbx = IS_QLA82XX(ha) ? RD_REG_WORD(®82->mailbox_out[4]) : mbx; - ql_log(ql_log_info, vha, 0x500b, + ql_dbg(ql_dbg_async, vha, 0x500b, "LOOP DOWN detected (%x %x %x %x).\n", mb[1], mb[2], mb[3], mbx); @@ -519,7 +521,7 @@ skip_rio: break; case MBA_LIP_RESET: /* LIP reset occurred */ - ql_log(ql_log_info, vha, 0x500c, + ql_dbg(ql_dbg_async, vha, 0x500c, "LIP reset occurred (%x).\n", mb[1]); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { @@ -587,7 +589,7 @@ skip_rio: if (IS_QLA2100(ha)) break; - ql_log(ql_log_info, vha, 0x500f, + ql_dbg(ql_dbg_async, vha, 0x500f, "Configuration change detected: value=%x.\n", mb[1]); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { @@ -920,15 +922,15 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, QLA_LOGIO_LOGIN_RETRIED : 0; if (mbx->entry_status) { ql_dbg(ql_dbg_async, vha, 0x5043, - "Async-%s error entry - portid=%02x%02x%02x " + "Async-%s error entry - hdl=%x portid=%02x%02x%02x " "entry-status=%x status=%x state-flag=%x " - "status-flags=%x.\n", - type, fcport->d_id.b.domain, fcport->d_id.b.area, + "status-flags=%x.\n", type, sp->handle, + fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, mbx->entry_status, le16_to_cpu(mbx->status), le16_to_cpu(mbx->state_flags), le16_to_cpu(mbx->status_flags)); - ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5057, + ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5029, (uint8_t *)mbx, sizeof(*mbx)); goto logio_done; @@ -940,9 +942,10 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, status = 0; if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) { ql_dbg(ql_dbg_async, vha, 0x5045, - "Async-%s complete - portid=%02x%02x%02x mbx1=%x.\n", - type, fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, le16_to_cpu(mbx->mb1)); + "Async-%s complete - hdl=%x portid=%02x%02x%02x mbx1=%x.\n", + type, sp->handle, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa, + le16_to_cpu(mbx->mb1)); data[0] = MBS_COMMAND_COMPLETE; if (ctx->type == SRB_LOGIN_CMD) { @@ -968,11 +971,10 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, } ql_log(ql_log_warn, vha, 0x5046, - "Async-%s failed - portid=%02x%02x%02x status=%x " - "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n", - type, fcport->d_id.b.domain, - fcport->d_id.b.area, fcport->d_id.b.al_pa, status, - le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1), + "Async-%s failed - hdl=%x portid=%02x%02x%02x status=%x " + "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n", type, sp->handle, + fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, + status, le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1), le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6), le16_to_cpu(mbx->mb7)); @@ -1036,7 +1038,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, bsg_job->reply->result = DID_ERROR << 16; bsg_job->reply->reply_payload_rcv_len = 0; } - ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5058, + ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, (uint8_t *)pkt, sizeof(*pkt)); } else { bsg_job->reply->result = DID_OK << 16; @@ -1111,9 +1113,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count); ql_log(ql_log_info, vha, 0x503f, - "ELS-CT pass-through-%s error comp_status-status=0x%x " + "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " "error subcode 1=0x%x error subcode 2=0x%x total_byte = 0x%x.\n", - type, comp_status, fw_status[1], fw_status[2], + type, sp->handle, comp_status, fw_status[1], fw_status[2], le16_to_cpu(((struct els_sts_entry_24xx *) pkt)->total_byte_count)); fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); @@ -1121,9 +1123,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, } else { ql_log(ql_log_info, vha, 0x5040, - "ELS-CT pass-through-%s error comp_status-status=0x%x " + "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " "error subcode 1=0x%x error subcode 2=0x%x.\n", - type, comp_status, + type, sp->handle, comp_status, le16_to_cpu(((struct els_sts_entry_24xx *) pkt)->error_subcode_1), le16_to_cpu(((struct els_sts_entry_24xx *) @@ -1184,11 +1186,12 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, QLA_LOGIO_LOGIN_RETRIED : 0; if (logio->entry_status) { ql_log(ql_log_warn, vha, 0x5034, - "Async-%s error entry - " + "Async-%s error entry - hdl=%x" "portid=%02x%02x%02x entry-status=%x.\n", - type, fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, logio->entry_status); - ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5059, + type, sp->handle, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa, + logio->entry_status); + ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, (uint8_t *)logio, sizeof(*logio)); goto logio_done; @@ -1196,10 +1199,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) { ql_dbg(ql_dbg_async, vha, 0x5036, - "Async-%s complete - portid=%02x%02x%02x " - "iop0=%x.\n", - type, fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, + "Async-%s complete - hdl=%x portid=%02x%02x%02x " + "iop0=%x.\n", type, sp->handle, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa, le32_to_cpu(logio->io_parameter[0])); data[0] = MBS_COMMAND_COMPLETE; @@ -1238,9 +1240,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, } ql_dbg(ql_dbg_async, vha, 0x5037, - "Async-%s failed - portid=%02x%02x%02x comp=%x " - "iop0=%x iop1=%x.\n", - type, fcport->d_id.b.domain, + "Async-%s failed - hdl=%x portid=%02x%02x%02x comp=%x " + "iop0=%x iop1=%x.\n", type, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, le16_to_cpu(logio->comp_status), le32_to_cpu(logio->io_parameter[0]), @@ -1274,25 +1275,25 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, if (sts->entry_status) { ql_log(ql_log_warn, vha, 0x5038, - "Async-%s error - entry-status(%x).\n", - type, sts->entry_status); + "Async-%s error - hdl=%x entry-status(%x).\n", + type, sp->handle, sts->entry_status); } else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { ql_log(ql_log_warn, vha, 0x5039, - "Async-%s error - completion status(%x).\n", - type, sts->comp_status); + "Async-%s error - hdl=%x completion status(%x).\n", + type, sp->handle, sts->comp_status); } else if (!(le16_to_cpu(sts->scsi_status) & SS_RESPONSE_INFO_LEN_VALID)) { ql_log(ql_log_warn, vha, 0x503a, - "Async-%s error - no response info(%x).\n", - type, sts->scsi_status); + "Async-%s error - hdl=%x no response info(%x).\n", + type, sp->handle, sts->scsi_status); } else if (le32_to_cpu(sts->rsp_data_len) < 4) { ql_log(ql_log_warn, vha, 0x503b, - "Async-%s error - not enough response(%d).\n", - type, sts->rsp_data_len); + "Async-%s error - hdl=%x not enough response(%d).\n", + type, sp->handle, sts->rsp_data_len); } else if (sts->data[3]) { ql_log(ql_log_warn, vha, 0x503c, - "Async-%s error - response(%x).\n", - type, sts->data[3]); + "Async-%s error - hdl=%x response(%x).\n", + type, sp->handle, sts->data[3]); } else { error = 0; } @@ -1337,9 +1338,6 @@ qla2x00_process_response_queue(struct rsp_que *rsp) } if (pkt->entry_status != 0) { - ql_log(ql_log_warn, vha, 0x5035, - "Process error entry.\n"); - qla2x00_error_entry(vha, rsp, pkt); ((response_t *)pkt)->signature = RESPONSE_PROCESSED; wmb(); @@ -1391,7 +1389,6 @@ qla2x00_process_response_queue(struct rsp_que *rsp) } static inline void - qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len, uint32_t sense_len, struct rsp_que *rsp) { @@ -1413,13 +1410,14 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len, if (sp->request_sense_length != 0) rsp->status_srb = sp; - ql_dbg(ql_dbg_io, vha, 0x301c, - "Check condition Sense data, scsi(%ld:%d:%d:%d) cmd=%p.\n", - sp->fcport->vha->host_no, cp->device->channel, cp->device->id, - cp->device->lun, cp); - if (sense_len) + if (sense_len) { + ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c, + "Check condition Sense data, nexus%ld:%d:%d cmd=%p.\n", + sp->fcport->vha->host_no, cp->device->id, cp->device->lun, + cp); ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302b, cp->sense_buffer, sense_len); + } } struct scsi_dif_tuple { @@ -1506,7 +1504,7 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) } if (k != blocks_done) { - qla_printk(KERN_WARNING, sp->fcport->vha->hw, + ql_log(ql_log_warn, vha, 0x302f, "unexpected tag values tag:lba=%x:%llx)\n", e_ref_tag, (unsigned long long)lba_s); return 1; @@ -1611,7 +1609,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) sp = NULL; if (sp == NULL) { - ql_log(ql_log_warn, vha, 0x3017, + ql_dbg(ql_dbg_io, vha, 0x3017, "Invalid status handle (0x%x).\n", sts->handle); if (IS_QLA82XX(ha)) @@ -1623,7 +1621,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) } cp = sp->cmd; if (cp == NULL) { - ql_log(ql_log_warn, vha, 0x3018, + ql_dbg(ql_dbg_io, vha, 0x3018, "Command already returned (0x%x/%p).\n", sts->handle, sp); @@ -1670,7 +1668,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) par_sense_len -= rsp_info_len; } if (rsp_info_len > 3 && rsp_info[3]) { - ql_log(ql_log_warn, vha, 0x3019, + ql_dbg(ql_dbg_io, vha, 0x3019, "FCP I/O protocol failure (0x%x/0x%x).\n", rsp_info_len, rsp_info[3]); @@ -1701,7 +1699,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) if (!lscsi_status && ((unsigned)(scsi_bufflen(cp) - resid) < cp->underflow)) { - ql_log(ql_log_warn, vha, 0x301a, + ql_dbg(ql_dbg_io, vha, 0x301a, "Mid-layer underflow " "detected (0x%x of 0x%x bytes).\n", resid, scsi_bufflen(cp)); @@ -1713,7 +1711,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) cp->result = DID_OK << 16 | lscsi_status; if (lscsi_status == SAM_STAT_TASK_SET_FULL) { - ql_log(ql_log_warn, vha, 0x301b, + ql_dbg(ql_dbg_io, vha, 0x301b, "QUEUE FULL detected.\n"); break; } @@ -1735,7 +1733,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) scsi_set_resid(cp, resid); if (scsi_status & SS_RESIDUAL_UNDER) { if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) { - ql_log(ql_log_warn, vha, 0x301d, + ql_dbg(ql_dbg_io, vha, 0x301d, "Dropped frame(s) detected " "(0x%x of 0x%x bytes).\n", resid, scsi_bufflen(cp)); @@ -1747,7 +1745,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) if (!lscsi_status && ((unsigned)(scsi_bufflen(cp) - resid) < cp->underflow)) { - ql_log(ql_log_warn, vha, 0x301e, + ql_dbg(ql_dbg_io, vha, 0x301e, "Mid-layer underflow " "detected (0x%x of 0x%x bytes).\n", resid, scsi_bufflen(cp)); @@ -1756,7 +1754,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) break; } } else { - ql_log(ql_log_warn, vha, 0x301f, + ql_dbg(ql_dbg_io, vha, 0x301f, "Dropped frame(s) detected (0x%x " "of 0x%x bytes).\n", resid, scsi_bufflen(cp)); @@ -1774,7 +1772,7 @@ check_scsi_status: */ if (lscsi_status != 0) { if (lscsi_status == SAM_STAT_TASK_SET_FULL) { - ql_log(ql_log_warn, vha, 0x3020, + ql_dbg(ql_dbg_io, vha, 0x3020, "QUEUE FULL detected.\n"); logit = 1; break; @@ -1838,10 +1836,15 @@ out: if (logit) ql_dbg(ql_dbg_io, vha, 0x3022, "FCP command status: 0x%x-0x%x (0x%x) " - "oxid=0x%x cdb=%02x%02x%02x len=0x%x " + "nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x " + "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x " "rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n", - comp_status, scsi_status, cp->result, ox_id, cp->cmnd[0], - cp->cmnd[1], cp->cmnd[2], scsi_bufflen(cp), rsp_info_len, + comp_status, scsi_status, cp->result, vha->host_no, + cp->device->id, cp->device->lun, fcport->d_id.b.domain, + fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id, + cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3], + cp->cmnd[4], cp->cmnd[5], cp->cmnd[6], cp->cmnd[7], + cp->cmnd[8], cp->cmnd[9], scsi_bufflen(cp), rsp_info_len, resid_len, fw_resid_len); if (rsp->status_srb == NULL) @@ -1899,6 +1902,45 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) } } +static int +qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp) +{ + struct qla_hw_data *ha = vha->hw; + struct srb_ctx *ctx; + + if (!sp->ctx) + return 1; + + ctx = sp->ctx; + + if (ctx->type == SRB_LOGIN_CMD || + ctx->type == SRB_LOGOUT_CMD || + ctx->type == SRB_TM_CMD) { + ctx->u.iocb_cmd->done(sp); + return 0; + } else if (ctx->type == SRB_ADISC_CMD) { + ctx->u.iocb_cmd->free(sp); + return 0; + } else { + struct fc_bsg_job *bsg_job; + + bsg_job = ctx->u.bsg_job; + if (ctx->type == SRB_ELS_CMD_HST || + ctx->type == SRB_CT_CMD) + kfree(sp->fcport); + + bsg_job->reply->reply_data.ctels_reply.status = + FC_CTELS_STATUS_OK; + bsg_job->reply->result = DID_ERROR << 16; + bsg_job->reply->reply_payload_rcv_len = 0; + kfree(sp->ctx); + mempool_free(sp, ha->srb_mempool); + bsg_job->job_done(bsg_job); + return 0; + } + return 1; +} + /** * qla2x00_error_entry() - Process an error entry. * @ha: SCSI driver HA context @@ -1909,7 +1951,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) { srb_t *sp; struct qla_hw_data *ha = vha->hw; - uint32_t handle = LSW(pkt->handle); + const char func[] = "ERROR-IOCB"; uint16_t que = MSW(pkt->handle); struct req_que *req = ha->req_q_map[que]; @@ -1932,28 +1974,20 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) ql_dbg(ql_dbg_async, vha, 0x502f, "UNKNOWN flag error.\n"); - /* Validate handle. */ - if (handle < MAX_OUTSTANDING_COMMANDS) - sp = req->outstanding_cmds[handle]; - else - sp = NULL; - + sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); if (sp) { - /* Free outstanding command slot. */ - req->outstanding_cmds[handle] = NULL; - - /* Bad payload or header */ - if (pkt->entry_status & - (RF_INV_E_ORDER | RF_INV_E_COUNT | - RF_INV_E_PARAM | RF_INV_E_TYPE)) { - sp->cmd->result = DID_ERROR << 16; - } else if (pkt->entry_status & RF_BUSY) { - sp->cmd->result = DID_BUS_BUSY << 16; - } else { - sp->cmd->result = DID_ERROR << 16; + if (qla2x00_free_sp_ctx(vha, sp)) { + if (pkt->entry_status & + (RF_INV_E_ORDER | RF_INV_E_COUNT | + RF_INV_E_PARAM | RF_INV_E_TYPE)) { + sp->cmd->result = DID_ERROR << 16; + } else if (pkt->entry_status & RF_BUSY) { + sp->cmd->result = DID_BUS_BUSY << 16; + } else { + sp->cmd->result = DID_ERROR << 16; + } + qla2x00_sp_compl(ha, sp); } - qla2x00_sp_compl(ha, sp); - } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type == COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7 || pkt->entry_type == COMMAND_TYPE_6) { @@ -1977,26 +2011,30 @@ static void qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) { uint16_t cnt; + uint32_t mboxes; uint16_t __iomem *wptr; struct qla_hw_data *ha = vha->hw; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + /* Read all mbox registers? */ + mboxes = (1 << ha->mbx_count) - 1; + if (!ha->mcp) + ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERRROR.\n"); + else + mboxes = ha->mcp->in_mb; + /* Load return mailbox registers. */ ha->flags.mbox_int = 1; ha->mailbox_out[0] = mb0; + mboxes >>= 1; wptr = (uint16_t __iomem *)®->mailbox1; for (cnt = 1; cnt < ha->mbx_count; cnt++) { - ha->mailbox_out[cnt] = RD_REG_WORD(wptr); - wptr++; - } + if (mboxes & BIT_0) + ha->mailbox_out[cnt] = RD_REG_WORD(wptr); - if (ha->mcp) { - ql_dbg(ql_dbg_async, vha, 0x504d, - "Got mailbox completion. cmd=%x.\n", ha->mcp->mb[0]); - } else { - ql_dbg(ql_dbg_async, vha, 0x504e, - "MBX pointer ERROR.\n"); + mboxes >>= 1; + wptr++; } } @@ -2025,9 +2063,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, } if (pkt->entry_status != 0) { - ql_dbg(ql_dbg_async, vha, 0x5029, - "Process error entry.\n"); - qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt); ((response_t *)pkt)->signature = RESPONSE_PROCESSED; wmb(); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 82a33533ed26..34344d3f8658 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -2887,7 +2887,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, if (vp_idx == 0 && (MSB(stat) != 1)) goto reg_needed; - if (MSB(stat) == 1) { + if (MSB(stat) != 0) { ql_dbg(ql_dbg_mbx, vha, 0x10ba, "Could not acquire ID for VP[%d].\n", vp_idx); return; diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 1873940a7ccb..1cd46cd7ff90 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -369,7 +369,7 @@ qla82xx_pci_set_crbwindow_2M(struct qla_hw_data *ha, ulong *off) ql_dbg(ql_dbg_p3p, vha, 0xb000, "%s: Written crbwin (0x%x) " "!= Read crbwin (0x%x), off=0x%lx.\n", - ha->crb_win, win_read, *off); + __func__, ha->crb_win, win_read, *off); } *off = (*off & MASK(16)) + CRB_INDIRECT_2M + ha->nx_pcibase; } @@ -409,7 +409,7 @@ qla82xx_pci_set_crbwindow(struct qla_hw_data *ha, u64 off) } /* strange address given */ ql_dbg(ql_dbg_p3p, vha, 0xb001, - "%x: Warning: unm_nic_pci_set_crbwindow " + "%s: Warning: unm_nic_pci_set_crbwindow " "called with an unknown address(%llx).\n", QLA2XXX_DRIVER_NAME, off); return off; @@ -1711,12 +1711,12 @@ qla82xx_iospace_config(struct qla_hw_data *ha) ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc006, "nx_pci_base=%p iobase=%p " "max_req_queues=%d msix_count=%d.\n", - ha->nx_pcibase, ha->iobase, + (void *)ha->nx_pcibase, ha->iobase, ha->max_req_queues, ha->msix_count); ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0010, "nx_pci_base=%p iobase=%p " "max_req_queues=%d msix_count=%d.\n", - ha->nx_pcibase, ha->iobase, + (void *)ha->nx_pcibase, ha->iobase, ha->max_req_queues, ha->msix_count); return 0; @@ -1744,7 +1744,7 @@ qla82xx_pci_config(scsi_qla_host_t *vha) ret = pci_set_mwi(ha->pdev); ha->chip_revision = ha->pdev->revision; ql_dbg(ql_dbg_init, vha, 0x0043, - "Chip revision:%ld.\n", + "Chip revision:%d.\n", ha->chip_revision); return 0; } @@ -2023,13 +2023,9 @@ qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) wptr++; } - if (ha->mcp) { - ql_dbg(ql_dbg_async, vha, 0x5052, - "Got mailbox completion. cmd=%x.\n", ha->mcp->mb[0]); - } else { + if (!ha->mcp) ql_dbg(ql_dbg_async, vha, 0x5053, "MBX pointer ERROR.\n"); - } } /* @@ -2543,484 +2539,6 @@ qla82xx_start_firmware(scsi_qla_host_t *vha) return qla82xx_check_rcvpeg_state(ha); } -static inline int -qla2xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, - uint16_t tot_dsds) -{ - uint32_t *cur_dsd = NULL; - scsi_qla_host_t *vha; - struct qla_hw_data *ha; - struct scsi_cmnd *cmd; - struct scatterlist *cur_seg; - uint32_t *dsd_seg; - void *next_dsd; - uint8_t avail_dsds; - uint8_t first_iocb = 1; - uint32_t dsd_list_len; - struct dsd_dma *dsd_ptr; - struct ct6_dsd *ctx; - - cmd = sp->cmd; - - /* Update entry type to indicate Command Type 3 IOCB */ - *((uint32_t *)(&cmd_pkt->entry_type)) = - __constant_cpu_to_le32(COMMAND_TYPE_6); - - /* No data transfer */ - if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { - cmd_pkt->byte_count = __constant_cpu_to_le32(0); - return 0; - } - - vha = sp->fcport->vha; - ha = vha->hw; - - /* Set transfer direction */ - if (cmd->sc_data_direction == DMA_TO_DEVICE) { - cmd_pkt->control_flags = - __constant_cpu_to_le16(CF_WRITE_DATA); - ha->qla_stats.output_bytes += scsi_bufflen(cmd); - } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { - cmd_pkt->control_flags = - __constant_cpu_to_le16(CF_READ_DATA); - ha->qla_stats.input_bytes += scsi_bufflen(cmd); - } - - cur_seg = scsi_sglist(cmd); - ctx = sp->ctx; - - while (tot_dsds) { - avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ? - QLA_DSDS_PER_IOCB : tot_dsds; - tot_dsds -= avail_dsds; - dsd_list_len = (avail_dsds + 1) * QLA_DSD_SIZE; - - dsd_ptr = list_first_entry(&ha->gbl_dsd_list, - struct dsd_dma, list); - next_dsd = dsd_ptr->dsd_addr; - list_del(&dsd_ptr->list); - ha->gbl_dsd_avail--; - list_add_tail(&dsd_ptr->list, &ctx->dsd_list); - ctx->dsd_use_cnt++; - ha->gbl_dsd_inuse++; - - if (first_iocb) { - first_iocb = 0; - dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; - *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); - *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); - cmd_pkt->fcp_data_dseg_len = cpu_to_le32(dsd_list_len); - } else { - *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); - *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); - *cur_dsd++ = cpu_to_le32(dsd_list_len); - } - cur_dsd = (uint32_t *)next_dsd; - while (avail_dsds) { - dma_addr_t sle_dma; - - sle_dma = sg_dma_address(cur_seg); - *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); - *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); - *cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg)); - cur_seg = sg_next(cur_seg); - avail_dsds--; - } - } - - /* Null termination */ - *cur_dsd++ = 0; - *cur_dsd++ = 0; - *cur_dsd++ = 0; - cmd_pkt->control_flags |= CF_DATA_SEG_DESCR_ENABLE; - return 0; -} - -/* - * qla82xx_calc_dsd_lists() - Determine number of DSD list required - * for Command Type 6. - * - * @dsds: number of data segment decriptors needed - * - * Returns the number of dsd list needed to store @dsds. - */ -inline uint16_t -qla82xx_calc_dsd_lists(uint16_t dsds) -{ - uint16_t dsd_lists = 0; - - dsd_lists = (dsds/QLA_DSDS_PER_IOCB); - if (dsds % QLA_DSDS_PER_IOCB) - dsd_lists++; - return dsd_lists; -} - -/* - * qla82xx_start_scsi() - Send a SCSI command to the ISP - * @sp: command to send to the ISP - * - * Returns non-zero if a failure occurred, else zero. - */ -int -qla82xx_start_scsi(srb_t *sp) -{ - int ret, nseg; - unsigned long flags; - struct scsi_cmnd *cmd; - uint32_t *clr_ptr; - uint32_t index; - uint32_t handle; - uint16_t cnt; - uint16_t req_cnt; - uint16_t tot_dsds; - struct device_reg_82xx __iomem *reg; - uint32_t dbval; - uint32_t *fcp_dl; - uint8_t additional_cdb_len; - struct ct6_dsd *ctx; - struct scsi_qla_host *vha = sp->fcport->vha; - struct qla_hw_data *ha = vha->hw; - struct req_que *req = NULL; - struct rsp_que *rsp = NULL; - char tag[2]; - - /* Setup device pointers. */ - ret = 0; - reg = &ha->iobase->isp82; - cmd = sp->cmd; - req = vha->req; - rsp = ha->rsp_q_map[0]; - - /* So we know we haven't pci_map'ed anything yet */ - tot_dsds = 0; - - dbval = 0x04 | (ha->portnum << 5); - - /* Send marker if required */ - if (vha->marker_needed != 0) { - if (qla2x00_marker(vha, req, - rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0x300c, - "qla2x00_marker failed for cmd=%p.\n", cmd); - return QLA_FUNCTION_FAILED; - } - vha->marker_needed = 0; - } - - /* Acquire ring specific lock */ - spin_lock_irqsave(&ha->hardware_lock, flags); - - /* Check for room in outstanding command list. */ - handle = req->current_outstanding_cmd; - for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) { - handle++; - if (handle == MAX_OUTSTANDING_COMMANDS) - handle = 1; - if (!req->outstanding_cmds[handle]) - break; - } - if (index == MAX_OUTSTANDING_COMMANDS) - goto queuing_error; - - /* Map the sg table so we have an accurate count of sg entries needed */ - if (scsi_sg_count(cmd)) { - nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd), - scsi_sg_count(cmd), cmd->sc_data_direction); - if (unlikely(!nseg)) - goto queuing_error; - } else - nseg = 0; - - tot_dsds = nseg; - - if (tot_dsds > ql2xshiftctondsd) { - struct cmd_type_6 *cmd_pkt; - uint16_t more_dsd_lists = 0; - struct dsd_dma *dsd_ptr; - uint16_t i; - - more_dsd_lists = qla82xx_calc_dsd_lists(tot_dsds); - if ((more_dsd_lists + ha->gbl_dsd_inuse) >= NUM_DSD_CHAIN) { - ql_dbg(ql_dbg_io, vha, 0x300d, - "Num of DSD list %d is than %d for cmd=%p.\n", - more_dsd_lists + ha->gbl_dsd_inuse, NUM_DSD_CHAIN, - cmd); - goto queuing_error; - } - - if (more_dsd_lists <= ha->gbl_dsd_avail) - goto sufficient_dsds; - else - more_dsd_lists -= ha->gbl_dsd_avail; - - for (i = 0; i < more_dsd_lists; i++) { - dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC); - if (!dsd_ptr) { - ql_log(ql_log_fatal, vha, 0x300e, - "Failed to allocate memory for dsd_dma " - "for cmd=%p.\n", cmd); - goto queuing_error; - } - - dsd_ptr->dsd_addr = dma_pool_alloc(ha->dl_dma_pool, - GFP_ATOMIC, &dsd_ptr->dsd_list_dma); - if (!dsd_ptr->dsd_addr) { - kfree(dsd_ptr); - ql_log(ql_log_fatal, vha, 0x300f, - "Failed to allocate memory for dsd_addr " - "for cmd=%p.\n", cmd); - goto queuing_error; - } - list_add_tail(&dsd_ptr->list, &ha->gbl_dsd_list); - ha->gbl_dsd_avail++; - } - -sufficient_dsds: - req_cnt = 1; - - if (req->cnt < (req_cnt + 2)) { - cnt = (uint16_t)RD_REG_DWORD_RELAXED( - ®->req_q_out[0]); - if (req->ring_index < cnt) - req->cnt = cnt - req->ring_index; - else - req->cnt = req->length - - (req->ring_index - cnt); - } - - if (req->cnt < (req_cnt + 2)) - goto queuing_error; - - ctx = sp->ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); - if (!sp->ctx) { - ql_log(ql_log_fatal, vha, 0x3010, - "Failed to allocate ctx for cmd=%p.\n", cmd); - goto queuing_error; - } - memset(ctx, 0, sizeof(struct ct6_dsd)); - ctx->fcp_cmnd = dma_pool_alloc(ha->fcp_cmnd_dma_pool, - GFP_ATOMIC, &ctx->fcp_cmnd_dma); - if (!ctx->fcp_cmnd) { - ql_log(ql_log_fatal, vha, 0x3011, - "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd); - goto queuing_error_fcp_cmnd; - } - - /* Initialize the DSD list and dma handle */ - INIT_LIST_HEAD(&ctx->dsd_list); - ctx->dsd_use_cnt = 0; - - if (cmd->cmd_len > 16) { - additional_cdb_len = cmd->cmd_len - 16; - if ((cmd->cmd_len % 4) != 0) { - /* SCSI command bigger than 16 bytes must be - * multiple of 4 - */ - ql_log(ql_log_warn, vha, 0x3012, - "scsi cmd len %d not multiple of 4 " - "for cmd=%p.\n", cmd->cmd_len, cmd); - goto queuing_error_fcp_cmnd; - } - ctx->fcp_cmnd_len = 12 + cmd->cmd_len + 4; - } else { - additional_cdb_len = 0; - ctx->fcp_cmnd_len = 12 + 16 + 4; - } - - cmd_pkt = (struct cmd_type_6 *)req->ring_ptr; - cmd_pkt->handle = MAKE_HANDLE(req->id, handle); - - /* Zero out remaining portion of packet. */ - /* tagged queuing modifier -- default is TSK_SIMPLE (0). */ - clr_ptr = (uint32_t *)cmd_pkt + 2; - memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8); - cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); - - /* Set NPORT-ID and LUN number*/ - cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id); - cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; - cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; - cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; - cmd_pkt->vp_index = sp->fcport->vp_idx; - - /* Build IOCB segments */ - if (qla2xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds)) - goto queuing_error_fcp_cmnd; - - int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); - host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); - - /* build FCP_CMND IU */ - memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); - int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); - ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; - - if (cmd->sc_data_direction == DMA_TO_DEVICE) - ctx->fcp_cmnd->additional_cdb_len |= 1; - else if (cmd->sc_data_direction == DMA_FROM_DEVICE) - ctx->fcp_cmnd->additional_cdb_len |= 2; - - /* - * Update tagged queuing modifier -- default is TSK_SIMPLE (0). - */ - if (scsi_populate_tag_msg(cmd, tag)) { - switch (tag[0]) { - case HEAD_OF_QUEUE_TAG: - ctx->fcp_cmnd->task_attribute = - TSK_HEAD_OF_QUEUE; - break; - case ORDERED_QUEUE_TAG: - ctx->fcp_cmnd->task_attribute = - TSK_ORDERED; - break; - } - } - - memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); - - fcp_dl = (uint32_t *)(ctx->fcp_cmnd->cdb + 16 + - additional_cdb_len); - *fcp_dl = htonl((uint32_t)scsi_bufflen(cmd)); - - cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len); - cmd_pkt->fcp_cmnd_dseg_address[0] = - cpu_to_le32(LSD(ctx->fcp_cmnd_dma)); - cmd_pkt->fcp_cmnd_dseg_address[1] = - cpu_to_le32(MSD(ctx->fcp_cmnd_dma)); - - sp->flags |= SRB_FCP_CMND_DMA_VALID; - cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); - /* Set total data segment count. */ - cmd_pkt->entry_count = (uint8_t)req_cnt; - /* Specify response queue number where - * completion should happen - */ - cmd_pkt->entry_status = (uint8_t) rsp->id; - } else { - struct cmd_type_7 *cmd_pkt; - req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); - if (req->cnt < (req_cnt + 2)) { - cnt = (uint16_t)RD_REG_DWORD_RELAXED( - ®->req_q_out[0]); - if (req->ring_index < cnt) - req->cnt = cnt - req->ring_index; - else - req->cnt = req->length - - (req->ring_index - cnt); - } - if (req->cnt < (req_cnt + 2)) - goto queuing_error; - - cmd_pkt = (struct cmd_type_7 *)req->ring_ptr; - cmd_pkt->handle = MAKE_HANDLE(req->id, handle); - - /* Zero out remaining portion of packet. */ - /* tagged queuing modifier -- default is TSK_SIMPLE (0).*/ - clr_ptr = (uint32_t *)cmd_pkt + 2; - memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8); - cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); - - /* Set NPORT-ID and LUN number*/ - cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id); - cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; - cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; - cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; - cmd_pkt->vp_index = sp->fcport->vp_idx; - - int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); - host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, - sizeof(cmd_pkt->lun)); - - /* - * Update tagged queuing modifier -- default is TSK_SIMPLE (0). - */ - if (scsi_populate_tag_msg(cmd, tag)) { - switch (tag[0]) { - case HEAD_OF_QUEUE_TAG: - cmd_pkt->task = TSK_HEAD_OF_QUEUE; - break; - case ORDERED_QUEUE_TAG: - cmd_pkt->task = TSK_ORDERED; - break; - } - } - - /* Load SCSI command packet. */ - memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); - host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); - - cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); - - /* Build IOCB segments */ - qla24xx_build_scsi_iocbs(sp, cmd_pkt, tot_dsds); - - /* Set total data segment count. */ - cmd_pkt->entry_count = (uint8_t)req_cnt; - /* Specify response queue number where - * completion should happen. - */ - cmd_pkt->entry_status = (uint8_t) rsp->id; - - } - /* Build command packet. */ - req->current_outstanding_cmd = handle; - req->outstanding_cmds[handle] = sp; - sp->handle = handle; - sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; - req->cnt -= req_cnt; - wmb(); - - /* Adjust ring index. */ - req->ring_index++; - if (req->ring_index == req->length) { - req->ring_index = 0; - req->ring_ptr = req->ring; - } else - req->ring_ptr++; - - sp->flags |= SRB_DMA_VALID; - - /* Set chip new ring index. */ - /* write, read and verify logic */ - dbval = dbval | (req->id << 8) | (req->ring_index << 16); - if (ql2xdbwr) - qla82xx_wr_32(ha, ha->nxdb_wr_ptr, dbval); - else { - WRT_REG_DWORD( - (unsigned long __iomem *)ha->nxdb_wr_ptr, - dbval); - wmb(); - while (RD_REG_DWORD(ha->nxdb_rd_ptr) != dbval) { - WRT_REG_DWORD( - (unsigned long __iomem *)ha->nxdb_wr_ptr, - dbval); - wmb(); - } - } - - /* Manage unprocessed RIO/ZIO commands in response queue. */ - if (vha->flags.process_response_queue && - rsp->ring_ptr->signature != RESPONSE_PROCESSED) - qla24xx_process_response_queue(vha, rsp); - - spin_unlock_irqrestore(&ha->hardware_lock, flags); - return QLA_SUCCESS; - -queuing_error_fcp_cmnd: - dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma); -queuing_error: - if (tot_dsds) - scsi_dma_unmap(cmd); - - if (sp->ctx) { - mempool_free(sp->ctx, ha->ctx_mempool); - sp->ctx = NULL; - } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - return QLA_FUNCTION_FAILED; -} - static uint32_t * qla82xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, uint32_t length) @@ -3272,9 +2790,9 @@ qla82xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, } void -qla82xx_start_iocbs(srb_t *sp) +qla82xx_start_iocbs(scsi_qla_host_t *vha) { - struct qla_hw_data *ha = sp->fcport->vha->hw; + struct qla_hw_data *ha = vha->hw; struct req_que *req = ha->req_q_map[0]; struct device_reg_82xx __iomem *reg; uint32_t dbval; @@ -3659,11 +3177,10 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha) qla82xx_md_free(vha); /* ALlocate MiniDump resources */ qla82xx_md_prep(vha); - } else - ql_log(ql_log_info, vha, 0xb02e, - "Firmware dump available to retrieve\n", - vha->host_no); - } + } + } else + ql_log(ql_log_info, vha, 0xb02e, + "Firmware dump available to retrieve\n"); } return rval; } @@ -3758,7 +3275,6 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha) switch (dev_state) { case QLA82XX_DEV_READY: - qla82xx_check_md_needed(vha); ha->flags.isp82xx_reset_owner = 0; goto exit; case QLA82XX_DEV_COLD: @@ -4067,7 +3583,7 @@ int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *vha) } } ql_dbg(ql_dbg_p3p, vha, 0xb027, - "%s status=%d.\n", status); + "%s: status=%d.\n", __func__, status); return status; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index f9e5b85e84d8..4ed1e4a96b95 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -83,6 +83,9 @@ MODULE_PARM_DESC(ql2xextended_error_logging, "\t\t0x00080000 - P3P Specific. 0x00040000 - Virtual Port.\n" "\t\t0x00020000 - Buffer Dump. 0x00010000 - Misc.\n" "\t\t0x7fffffff - For enabling all logs, can be too many logs.\n" + "\t\t0x1e400000 - Preferred value for capturing essential " + "debug information (equivalent to old " + "ql2xextended_error_logging=1).\n" "\t\tDo LOGICAL OR of the value to enable more than one level"); int ql2xshiftctondsd = 6; @@ -199,7 +202,7 @@ int ql2xmdcapmask = 0x1F; module_param(ql2xmdcapmask, int, S_IRUGO); MODULE_PARM_DESC(ql2xmdcapmask, "Set the Minidump driver capture mask level. " - "Default is 0x7F - Can be set to 0x3, 0x7, 0xF, 0x1F, 0x7F."); + "Default is 0x1F - Can be set to 0x3, 0x7, 0xF, 0x1F, 0x7F."); int ql2xmdenable = 1; module_param(ql2xmdenable, int, S_IRUGO); @@ -847,14 +850,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) int wait = 0; struct qla_hw_data *ha = vha->hw; - ql_dbg(ql_dbg_taskm, vha, 0x8000, - "Entered %s for cmd=%p.\n", __func__, cmd); if (!CMD_SP(cmd)) return SUCCESS; ret = fc_block_scsi_eh(cmd); - ql_dbg(ql_dbg_taskm, vha, 0x8001, - "Return value of fc_block_scsi_eh=%d.\n", ret); if (ret != 0) return ret; ret = SUCCESS; @@ -870,7 +869,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) } ql_dbg(ql_dbg_taskm, vha, 0x8002, - "Aborting sp=%p cmd=%p from RISC ", sp, cmd); + "Aborting from RISC nexus=%ld:%d:%d sp=%p cmd=%p\n", + vha->host_no, id, lun, sp, cmd); /* Get a reference to the sp and drop the lock.*/ sp_get(sp); @@ -878,10 +878,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) spin_unlock_irqrestore(&ha->hardware_lock, flags); if (ha->isp_ops->abort_command(sp)) { ql_dbg(ql_dbg_taskm, vha, 0x8003, - "Abort command mbx failed for cmd=%p.\n", cmd); + "Abort command mbx failed cmd=%p.\n", cmd); } else { ql_dbg(ql_dbg_taskm, vha, 0x8004, - "Abort command mbx success.\n"); + "Abort command mbx success cmd=%p.\n", cmd); wait = 1; } @@ -897,13 +897,14 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) if (wait) { if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x8006, - "Abort handler timed out for cmd=%p.\n", cmd); + "Abort handler timed out cmd=%p.\n", cmd); ret = FAILED; } } ql_log(ql_log_info, vha, 0x801c, - "Abort command issued -- %d %x.\n", wait, ret); + "Abort command issued nexus=%ld:%d:%d -- %d %x.\n", + vha->host_no, id, lun, wait, ret); return ret; } @@ -972,19 +973,15 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, int err; if (!fcport) { - ql_log(ql_log_warn, vha, 0x8007, - "fcport is NULL.\n"); return FAILED; } err = fc_block_scsi_eh(cmd); - ql_dbg(ql_dbg_taskm, vha, 0x8008, - "fc_block_scsi_eh ret=%d.\n", err); if (err != 0) return err; ql_log(ql_log_info, vha, 0x8009, - "%s RESET ISSUED for id %d lun %d cmd=%p.\n", name, + "%s RESET ISSUED nexus=%ld:%d:%d cmd=%p.\n", name, vha->host_no, cmd->device->id, cmd->device->lun, cmd); err = 0; @@ -1009,15 +1006,16 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, } ql_log(ql_log_info, vha, 0x800e, - "%s RESET SUCCEEDED for id %d lun %d cmd=%p.\n", name, - cmd->device->id, cmd->device->lun, cmd); + "%s RESET SUCCEEDED nexus:%ld:%d:%d cmd=%p.\n", name, + vha->host_no, cmd->device->id, cmd->device->lun, cmd); return SUCCESS; eh_reset_failed: ql_log(ql_log_info, vha, 0x800f, - "%s RESET FAILED: %s for id %d lun %d cmd=%p.\n", name, - reset_errors[err], cmd->device->id, cmd->device->lun); + "%s RESET FAILED: %s nexus=%ld:%d:%d cmd=%p.\n", name, + reset_errors[err], vha->host_no, cmd->device->id, cmd->device->lun, + cmd); return FAILED; } @@ -1068,20 +1066,16 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) lun = cmd->device->lun; if (!fcport) { - ql_log(ql_log_warn, vha, 0x8010, - "fcport is NULL.\n"); return ret; } ret = fc_block_scsi_eh(cmd); - ql_dbg(ql_dbg_taskm, vha, 0x8011, - "fc_block_scsi_eh ret=%d.\n", ret); if (ret != 0) return ret; ret = FAILED; ql_log(ql_log_info, vha, 0x8012, - "BUS RESET ISSUED for id %d lun %d.\n", id, lun); + "BUS RESET ISSUED nexus=%ld:%d%d.\n", vha->host_no, id, lun); if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) { ql_log(ql_log_fatal, vha, 0x8013, @@ -1105,7 +1099,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) eh_bus_reset_done: ql_log(ql_log_warn, vha, 0x802b, - "BUS RESET %s.\n", (ret == FAILED) ? "FAILED" : "SUCCEDED"); + "BUS RESET %s nexus=%ld:%d:%d.\n", + (ret == FAILED) ? "FAILED" : "SUCCEDED", vha->host_no, id, lun); return ret; } @@ -1139,20 +1134,16 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) lun = cmd->device->lun; if (!fcport) { - ql_log(ql_log_warn, vha, 0x8016, - "fcport is NULL.\n"); return ret; } ret = fc_block_scsi_eh(cmd); - ql_dbg(ql_dbg_taskm, vha, 0x8017, - "fc_block_scsi_eh ret=%d.\n", ret); if (ret != 0) return ret; ret = FAILED; ql_log(ql_log_info, vha, 0x8018, - "ADAPTER RESET ISSUED for id %d lun %d.\n", id, lun); + "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun); if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS) goto eh_host_reset_lock; @@ -1193,8 +1184,9 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) ret = SUCCESS; eh_host_reset_lock: - qla_printk(KERN_INFO, ha, "%s: reset %s.\n", __func__, - (ret == FAILED) ? "failed" : "succeeded"); + ql_log(ql_log_info, vha, 0x8017, + "ADAPTER RESET %s nexus=%ld:%d:%d.\n", + (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun); return ret; } @@ -1344,10 +1336,8 @@ static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth) return; ql_dbg(ql_dbg_io, fcport->vha, 0x3029, - "Queue depth adjusted-down " - "to %d for scsi(%ld:%d:%d:%d).\n", - sdev->queue_depth, fcport->vha->host_no, - sdev->channel, sdev->id, sdev->lun); + "Queue depth adjusted-down to %d for nexus=%ld:%d:%d.\n", + sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun); } static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth) @@ -1369,10 +1359,8 @@ static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth) scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, qdepth); ql_dbg(ql_dbg_io, vha, 0x302a, - "Queue depth adjusted-up to %d for " - "scsi(%ld:%d:%d:%d).\n", - sdev->queue_depth, fcport->vha->host_no, - sdev->channel, sdev->id, sdev->lun); + "Queue depth adjusted-up to %d for nexus=%ld:%d:%d.\n", + sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun); } static int @@ -1496,6 +1484,118 @@ qla24xx_disable_intrs(struct qla_hw_data *ha) spin_unlock_irqrestore(&ha->hardware_lock, flags); } +static int +qla2x00_iospace_config(struct qla_hw_data *ha) +{ + resource_size_t pio; + uint16_t msix; + int cpus; + + if (IS_QLA82XX(ha)) + return qla82xx_iospace_config(ha); + + if (pci_request_selected_regions(ha->pdev, ha->bars, + QLA2XXX_DRIVER_NAME)) { + ql_log_pci(ql_log_fatal, ha->pdev, 0x0011, + "Failed to reserve PIO/MMIO regions (%s), aborting.\n", + pci_name(ha->pdev)); + goto iospace_error_exit; + } + if (!(ha->bars & 1)) + goto skip_pio; + + /* We only need PIO for Flash operations on ISP2312 v2 chips. */ + pio = pci_resource_start(ha->pdev, 0); + if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) { + if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) { + ql_log_pci(ql_log_warn, ha->pdev, 0x0012, + "Invalid pci I/O region size (%s).\n", + pci_name(ha->pdev)); + pio = 0; + } + } else { + ql_log_pci(ql_log_warn, ha->pdev, 0x0013, + "Region #0 no a PIO resource (%s).\n", + pci_name(ha->pdev)); + pio = 0; + } + ha->pio_address = pio; + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014, + "PIO address=%llu.\n", + (unsigned long long)ha->pio_address); + +skip_pio: + /* Use MMIO operations for all accesses. */ + if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) { + ql_log_pci(ql_log_fatal, ha->pdev, 0x0015, + "Region #1 not an MMIO resource (%s), aborting.\n", + pci_name(ha->pdev)); + goto iospace_error_exit; + } + if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) { + ql_log_pci(ql_log_fatal, ha->pdev, 0x0016, + "Invalid PCI mem region size (%s), aborting.\n", + pci_name(ha->pdev)); + goto iospace_error_exit; + } + + ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN); + if (!ha->iobase) { + ql_log_pci(ql_log_fatal, ha->pdev, 0x0017, + "Cannot remap MMIO (%s), aborting.\n", + pci_name(ha->pdev)); + goto iospace_error_exit; + } + + /* Determine queue resources */ + ha->max_req_queues = ha->max_rsp_queues = 1; + if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) || + (ql2xmaxqueues > 1 && ql2xmultique_tag) || + (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))) + goto mqiobase_exit; + + ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), + pci_resource_len(ha->pdev, 3)); + if (ha->mqiobase) { + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0018, + "MQIO Base=%p.\n", ha->mqiobase); + /* Read MSIX vector size of the board */ + pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix); + ha->msix_count = msix; + /* Max queues are bounded by available msix vectors */ + /* queue 0 uses two msix vectors */ + if (ql2xmultique_tag) { + cpus = num_online_cpus(); + ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ? + (cpus + 1) : (ha->msix_count - 1); + ha->max_req_queues = 2; + } else if (ql2xmaxqueues > 1) { + ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ? + QLA_MQ_SIZE : ql2xmaxqueues; + ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc008, + "QoS mode set, max no of request queues:%d.\n", + ha->max_req_queues); + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0019, + "QoS mode set, max no of request queues:%d.\n", + ha->max_req_queues); + } + ql_log_pci(ql_log_info, ha->pdev, 0x001a, + "MSI-X vector count: %d.\n", msix); + } else + ql_log_pci(ql_log_info, ha->pdev, 0x001b, + "BAR 3 not enabled.\n"); + +mqiobase_exit: + ha->msix_count = ha->max_rsp_queues + 1; + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x001c, + "MSIX Count:%d.\n", ha->msix_count); + return (0); + +iospace_error_exit: + return (-ENOMEM); +} + + static struct isp_operations qla2100_isp_ops = { .pci_config = qla2100_pci_config, .reset_chip = qla2x00_reset_chip, @@ -1530,6 +1630,7 @@ static struct isp_operations qla2100_isp_ops = { .get_flash_version = qla2x00_get_flash_version, .start_scsi = qla2x00_start_scsi, .abort_isp = qla2x00_abort_isp, + .iospace_config = qla2x00_iospace_config, }; static struct isp_operations qla2300_isp_ops = { @@ -1566,6 +1667,7 @@ static struct isp_operations qla2300_isp_ops = { .get_flash_version = qla2x00_get_flash_version, .start_scsi = qla2x00_start_scsi, .abort_isp = qla2x00_abort_isp, + .iospace_config = qla2x00_iospace_config, }; static struct isp_operations qla24xx_isp_ops = { @@ -1602,6 +1704,7 @@ static struct isp_operations qla24xx_isp_ops = { .get_flash_version = qla24xx_get_flash_version, .start_scsi = qla24xx_start_scsi, .abort_isp = qla2x00_abort_isp, + .iospace_config = qla2x00_iospace_config, }; static struct isp_operations qla25xx_isp_ops = { @@ -1638,6 +1741,7 @@ static struct isp_operations qla25xx_isp_ops = { .get_flash_version = qla24xx_get_flash_version, .start_scsi = qla24xx_dif_start_scsi, .abort_isp = qla2x00_abort_isp, + .iospace_config = qla2x00_iospace_config, }; static struct isp_operations qla81xx_isp_ops = { @@ -1674,6 +1778,7 @@ static struct isp_operations qla81xx_isp_ops = { .get_flash_version = qla24xx_get_flash_version, .start_scsi = qla24xx_dif_start_scsi, .abort_isp = qla2x00_abort_isp, + .iospace_config = qla2x00_iospace_config, }; static struct isp_operations qla82xx_isp_ops = { @@ -1710,6 +1815,7 @@ static struct isp_operations qla82xx_isp_ops = { .get_flash_version = qla24xx_get_flash_version, .start_scsi = qla82xx_start_scsi, .abort_isp = qla82xx_abort_isp, + .iospace_config = qla82xx_iospace_config, }; static inline void @@ -1819,121 +1925,10 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha) else ha->flags.port0 = 0; ql_dbg_pci(ql_dbg_init, ha->pdev, 0x000b, - "device_type=0x%x port=%d fw_srisc_address=%p.\n", + "device_type=0x%x port=%d fw_srisc_address=0x%x.\n", ha->device_type, ha->flags.port0, ha->fw_srisc_address); } -static int -qla2x00_iospace_config(struct qla_hw_data *ha) -{ - resource_size_t pio; - uint16_t msix; - int cpus; - - if (IS_QLA82XX(ha)) - return qla82xx_iospace_config(ha); - - if (pci_request_selected_regions(ha->pdev, ha->bars, - QLA2XXX_DRIVER_NAME)) { - ql_log_pci(ql_log_fatal, ha->pdev, 0x0011, - "Failed to reserve PIO/MMIO regions (%s), aborting.\n", - pci_name(ha->pdev)); - goto iospace_error_exit; - } - if (!(ha->bars & 1)) - goto skip_pio; - - /* We only need PIO for Flash operations on ISP2312 v2 chips. */ - pio = pci_resource_start(ha->pdev, 0); - if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) { - if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) { - ql_log_pci(ql_log_warn, ha->pdev, 0x0012, - "Invalid pci I/O region size (%s).\n", - pci_name(ha->pdev)); - pio = 0; - } - } else { - ql_log_pci(ql_log_warn, ha->pdev, 0x0013, - "Region #0 no a PIO resource (%s).\n", - pci_name(ha->pdev)); - pio = 0; - } - ha->pio_address = pio; - ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014, - "PIO address=%p.\n", - ha->pio_address); - -skip_pio: - /* Use MMIO operations for all accesses. */ - if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) { - ql_log_pci(ql_log_fatal, ha->pdev, 0x0015, - "Region #1 not an MMIO resource (%s), aborting.\n", - pci_name(ha->pdev)); - goto iospace_error_exit; - } - if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) { - ql_log_pci(ql_log_fatal, ha->pdev, 0x0016, - "Invalid PCI mem region size (%s), aborting.\n", - pci_name(ha->pdev)); - goto iospace_error_exit; - } - - ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN); - if (!ha->iobase) { - ql_log_pci(ql_log_fatal, ha->pdev, 0x0017, - "Cannot remap MMIO (%s), aborting.\n", - pci_name(ha->pdev)); - goto iospace_error_exit; - } - - /* Determine queue resources */ - ha->max_req_queues = ha->max_rsp_queues = 1; - if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) || - (ql2xmaxqueues > 1 && ql2xmultique_tag) || - (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))) - goto mqiobase_exit; - - ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), - pci_resource_len(ha->pdev, 3)); - if (ha->mqiobase) { - ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0018, - "MQIO Base=%p.\n", ha->mqiobase); - /* Read MSIX vector size of the board */ - pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix); - ha->msix_count = msix; - /* Max queues are bounded by available msix vectors */ - /* queue 0 uses two msix vectors */ - if (ql2xmultique_tag) { - cpus = num_online_cpus(); - ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ? - (cpus + 1) : (ha->msix_count - 1); - ha->max_req_queues = 2; - } else if (ql2xmaxqueues > 1) { - ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ? - QLA_MQ_SIZE : ql2xmaxqueues; - ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc008, - "QoS mode set, max no of request queues:%d.\n", - ha->max_req_queues); - ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0019, - "QoS mode set, max no of request queues:%d.\n", - ha->max_req_queues); - } - ql_log_pci(ql_log_info, ha->pdev, 0x001a, - "MSI-X vector count: %d.\n", msix); - } else - ql_log_pci(ql_log_info, ha->pdev, 0x001b, - "BAR 3 not enabled.\n"); - -mqiobase_exit: - ha->msix_count = ha->max_rsp_queues + 1; - ql_dbg_pci(ql_dbg_init, ha->pdev, 0x001c, - "MSIX Count:%d.\n", ha->msix_count); - return (0); - -iospace_error_exit: - return (-ENOMEM); -} - static void qla2xxx_scan_start(struct Scsi_Host *shost) { @@ -2032,14 +2027,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) pdev->needs_freset = 1; } - /* Configure PCI I/O space */ - ret = qla2x00_iospace_config(ha); - if (ret) - goto probe_hw_failed; - - ql_log_pci(ql_log_info, pdev, 0x001d, - "Found an ISP%04X irq %d iobase 0x%p.\n", - pdev->device, pdev->irq, ha->iobase); ha->prev_topology = 0; ha->init_cb_size = sizeof(init_cb_t); ha->link_data_rate = PORT_SPEED_UNKNOWN; @@ -2152,6 +2139,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) "flash_data_off=%d, nvram_conf_off=%d, nvram_data_off=%d.\n", ha->isp_ops, ha->flash_conf_off, ha->flash_data_off, ha->nvram_conf_off, ha->nvram_data_off); + + /* Configure PCI I/O space */ + ret = ha->isp_ops->iospace_config(ha); + if (ret) + goto probe_hw_failed; + + ql_log_pci(ql_log_info, pdev, 0x001d, + "Found an ISP%04X irq %d iobase 0x%p.\n", + pdev->device, pdev->irq, ha->iobase); mutex_init(&ha->vport_lock); init_completion(&ha->mbx_cmd_comp); complete(&ha->mbx_cmd_comp); @@ -2227,7 +2223,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql_dbg(ql_dbg_init, base_vha, 0x0033, "max_id=%d this_id=%d " "cmd_per_len=%d unique_id=%d max_cmd_len=%d max_channel=%d " - "max_lun=%d transportt=%p, vendor_id=%d.\n", host->max_id, + "max_lun=%d transportt=%p, vendor_id=%llu.\n", host->max_id, host->this_id, host->cmd_per_lun, host->unique_id, host->max_cmd_len, host->max_channel, host->max_lun, host->transportt, sht->vendor_id); @@ -2382,9 +2378,6 @@ skip_dpc: qla2x00_dfs_setup(base_vha); - ql_log(ql_log_info, base_vha, 0x00fa, - "QLogic Fibre Channed HBA Driver: %s.\n", - qla2x00_version_str); ql_log(ql_log_info, base_vha, 0x00fb, "QLogic %s - %s.\n", ha->model_number, ha->model_desc ? ha->model_desc : ""); @@ -2833,7 +2826,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, if (!ha->sns_cmd) goto fail_dma_pool; ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0026, - "sns_cmd.\n", ha->sns_cmd); + "sns_cmd: %p.\n", ha->sns_cmd); } else { /* Get consistent memory allocated for MS IOCB */ ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, @@ -3460,27 +3453,21 @@ qla2x00_do_dpc(void *data) schedule(); __set_current_state(TASK_RUNNING); - ql_dbg(ql_dbg_dpc, base_vha, 0x4001, - "DPC handler waking up.\n"); - ql_dbg(ql_dbg_dpc, base_vha, 0x4002, - "dpc_flags=0x%lx.\n", base_vha->dpc_flags); - - /* Initialization not yet finished. Don't do anything yet. */ - if (!base_vha->flags.init_done) - continue; + if (!base_vha->flags.init_done || ha->flags.mbox_busy) + goto end_loop; if (ha->flags.eeh_busy) { ql_dbg(ql_dbg_dpc, base_vha, 0x4003, "eeh_busy=%d.\n", ha->flags.eeh_busy); - continue; + goto end_loop; } ha->dpc_active = 1; - if (ha->flags.mbox_busy) { - ha->dpc_active = 0; - continue; - } + ql_dbg(ql_dbg_dpc, base_vha, 0x4001, + "DPC handler waking up.\n"); + ql_dbg(ql_dbg_dpc, base_vha, 0x4002, + "dpc_flags=0x%lx.\n", base_vha->dpc_flags); qla2x00_do_work(base_vha); @@ -3622,6 +3609,7 @@ qla2x00_do_dpc(void *data) qla2x00_do_dpc_all_vps(base_vha); ha->dpc_active = 0; +end_loop: set_current_state(TASK_INTERRUPTIBLE); } /* End of while(1) */ __set_current_state(TASK_RUNNING); @@ -3705,16 +3693,6 @@ qla2x00_sp_free_dma(srb_t *sp) sp->flags &= ~SRB_CRC_CTX_DMA_VALID; } - CMD_SP(cmd) = NULL; -} - -static void -qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp) -{ - struct scsi_cmnd *cmd = sp->cmd; - - qla2x00_sp_free_dma(sp); - if (sp->flags & SRB_FCP_CMND_DMA_VALID) { struct ct6_dsd *ctx = sp->ctx; dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, @@ -3726,6 +3704,15 @@ qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp) sp->ctx = NULL; } + CMD_SP(cmd) = NULL; +} + +static void +qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp) +{ + struct scsi_cmnd *cmd = sp->cmd; + + qla2x00_sp_free_dma(sp); mempool_free(sp, ha->srb_mempool); cmd->scsi_done(cmd); } diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index eff13563c82d..16bc72844a97 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -904,8 +904,9 @@ no_flash_data: } done: ql_dbg(ql_dbg_init, vha, 0x004d, - "FDT[%x]: (0x%x/0x%x) erase=0x%x " - "pr=%x upro=%x wrtd=0x%x blk=0x%x.\n", loc, mid, fid, + "FDT[%s]: (0x%x/0x%x) erase=0x%x " + "pr=%x wrtd=0x%x blk=0x%x.\n", + loc, mid, fid, ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, ha->fdt_wrt_disable, ha->fdt_block_size); |