From 5f16b331d83757ad5154af07b449c722fef45d5e Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Wed, 22 Aug 2012 14:21:00 -0400 Subject: [SCSI] qla2xxx: Use bitmap to store loop_id's for fcports. Store used fcport loop_id's in a bitmap so that as opposed to looping through all fcports to find the next free loop_id, new loop_id lookup can be just be done via bitops. [jejb: plus fix for incorrect LOOPID_MAP_SIZE from Andrew Vasquez] Signed-off-by: Giridhar Malavali Signed-off-by: Andrew Vasquez Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 81 +++++++++++------------------------------ 1 file changed, 21 insertions(+), 60 deletions(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a44653b42161..290052352619 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -3285,7 +3285,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, */ if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) { fcport->d_id.b24 = new_fcport->d_id.b24; - fcport->loop_id = FC_NO_LOOP_ID; + qla2x00_clear_loop_id(fcport); fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED); break; @@ -3306,7 +3306,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, ha->isp_ops->fabric_logout(vha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - fcport->loop_id = FC_NO_LOOP_ID; + qla2x00_clear_loop_id(fcport); } break; @@ -3352,71 +3352,32 @@ int qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) { int rval; - int found; - fc_port_t *fcport; - uint16_t first_loop_id; struct qla_hw_data *ha = vha->hw; - struct scsi_qla_host *vp; - struct scsi_qla_host *tvp; unsigned long flags = 0; rval = QLA_SUCCESS; - /* Save starting loop ID. */ - first_loop_id = dev->loop_id; - - for (;;) { - /* Skip loop ID if already used by adapter. */ - if (dev->loop_id == vha->loop_id) - dev->loop_id++; - - /* Skip reserved loop IDs. */ - while (qla2x00_is_reserved_id(vha, dev->loop_id)) - dev->loop_id++; - - /* Reset loop ID if passed the end. */ - if (dev->loop_id > ha->max_loop_id) { - /* first loop ID. */ - dev->loop_id = ha->min_external_loopid; - } - - /* Check for loop ID being already in use. */ - found = 0; - fcport = NULL; - - spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { - list_for_each_entry(fcport, &vp->vp_fcports, list) { - if (fcport->loop_id == dev->loop_id && - fcport != dev) { - /* ID possibly in use */ - found++; - break; - } - } - if (found) - break; - } - spin_unlock_irqrestore(&ha->vport_slock, flags); + spin_lock_irqsave(&ha->vport_slock, flags); - /* If not in use then it is free to use. */ - if (!found) { - ql_dbg(ql_dbg_disc, dev->vha, 0x2086, - "Assigning new loopid=%x, portid=%x.\n", - dev->loop_id, dev->d_id.b24); - break; - } + dev->loop_id = find_first_zero_bit(ha->loop_id_map, + LOOPID_MAP_SIZE); + if (dev->loop_id >= LOOPID_MAP_SIZE || + qla2x00_is_reserved_id(vha, dev->loop_id)) { + dev->loop_id = FC_NO_LOOP_ID; + rval = QLA_FUNCTION_FAILED; + } else + set_bit(dev->loop_id, ha->loop_id_map); - /* ID in use. Try next value. */ - dev->loop_id++; + spin_unlock_irqrestore(&ha->vport_slock, flags); - /* If wrap around. No free ID to use. */ - if (dev->loop_id == first_loop_id) { - dev->loop_id = FC_NO_LOOP_ID; - rval = QLA_FUNCTION_FAILED; - break; - } - } + if (rval == QLA_SUCCESS) + ql_dbg(ql_dbg_disc, dev->vha, 0x2086, + "Assigning new loopid=%x, portid=%x.\n", + dev->loop_id, dev->d_id.b24); + else + ql_log(ql_log_warn, dev->vha, 0x2087, + "No loop_id's available, portid=%x.\n", + dev->d_id.b24); return (rval); } @@ -3616,7 +3577,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport, ha->isp_ops->fabric_logout(vha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - fcport->loop_id = FC_NO_LOOP_ID; + qla2x00_clear_loop_id(fcport); fcport->login_retry = 0; rval = 3; -- cgit v1.2.1 From a9b6f722f62d0a302b980a4fdcdf9c9933955772 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 22 Aug 2012 14:21:01 -0400 Subject: [SCSI] qla2xxx: Implementation of bidirectional. [jejb: merge fix for introduced warning] Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 290052352619..fa39411597f9 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -77,7 +77,7 @@ qla2x00_sp_free(void *data, void *ptr) /* Asynchronous Login/Logout Routines -------------------------------------- */ -static inline unsigned long +unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *vha) { unsigned long tmo; -- cgit v1.2.1 From 7d613ac6acec8c29e7aa3f80e28e8e982977a151 Mon Sep 17 00:00:00 2001 From: Santosh Vernekar Date: Wed, 22 Aug 2012 14:21:03 -0400 Subject: [SCSI] qla2xxx: IDC implementation for ISP83xx. Signed-off-by: Santosh Vernekar Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 389 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index fa39411597f9..590238d878f6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -429,6 +429,71 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, /* QLogic ISP2x00 Hardware Support Functions. */ /****************************************************************************/ +int +qla83xx_nic_core_fw_load(scsi_qla_host_t *vha) +{ + int rval = QLA_SUCCESS; + struct qla_hw_data *ha = vha->hw; + uint32_t idc_major_ver, idc_minor_ver; + + qla83xx_idc_lock(vha, 0); + + /* SV: TODO: Assign initialization timeout from + * flash-info / other param + */ + ha->fcoe_dev_init_timeout = QLA83XX_IDC_INITIALIZATION_TIMEOUT; + ha->fcoe_reset_timeout = QLA83XX_IDC_RESET_ACK_TIMEOUT; + + /* Set our fcoe function presence */ + if (__qla83xx_set_drv_presence(vha) != QLA_SUCCESS) { + ql_dbg(ql_dbg_p3p, vha, 0xb077, + "Error while setting DRV-Presence.\n"); + rval = QLA_FUNCTION_FAILED; + goto exit; + } + + /* Decide the reset ownership */ + qla83xx_reset_ownership(vha); + + /* + * On first protocol driver load: + * Init-Owner: Set IDC-Major-Version and Clear IDC-Lock-Recovery + * register. + * Others: Check compatibility with current IDC Major version. + */ + qla83xx_rd_reg(vha, QLA83XX_IDC_MAJOR_VERSION, &idc_major_ver); + if (ha->flags.nic_core_reset_owner) { + /* Set IDC Major version */ + idc_major_ver = QLA83XX_SUPP_IDC_MAJOR_VERSION; + qla83xx_wr_reg(vha, QLA83XX_IDC_MAJOR_VERSION, idc_major_ver); + + /* Clearing IDC-Lock-Recovery register */ + qla83xx_wr_reg(vha, QLA83XX_IDC_LOCK_RECOVERY, 0); + } else if (idc_major_ver != QLA83XX_SUPP_IDC_MAJOR_VERSION) { + /* + * Clear further IDC participation if we are not compatible with + * the current IDC Major Version. + */ + ql_log(ql_log_warn, vha, 0xb07d, + "Failing load, idc_major_ver=%d, expected_major_ver=%d.\n", + idc_major_ver, QLA83XX_SUPP_IDC_MAJOR_VERSION); + __qla83xx_clear_drv_presence(vha); + rval = QLA_FUNCTION_FAILED; + goto exit; + } + /* Each function sets its supported Minor version. */ + qla83xx_rd_reg(vha, QLA83XX_IDC_MINOR_VERSION, &idc_minor_ver); + idc_minor_ver |= (QLA83XX_SUPP_IDC_MINOR_VERSION << (ha->portnum * 2)); + qla83xx_wr_reg(vha, QLA83XX_IDC_MINOR_VERSION, idc_minor_ver); + + rval = qla83xx_idc_state_handler(vha); + +exit: + qla83xx_idc_unlock(vha, 0); + + return rval; +} + /* * qla2x00_initialize_adapter * Initialize board. @@ -537,6 +602,14 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) } } + /* Load the NIC Core f/w if we are the first protocol driver. */ + if (IS_QLA8031(ha)) { + rval = qla83xx_nic_core_fw_load(vha); + if (rval) + ql_log(ql_log_warn, vha, 0x0124, + "Error in initializing NIC Core f/w.\n"); + } + if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) qla24xx_read_fcp_prio_cfg(vha); @@ -3736,6 +3809,307 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) spin_unlock_irqrestore(&ha->vport_slock, flags); } +/* Assumes idc_lock always held on entry */ +void +qla83xx_reset_ownership(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + uint32_t drv_presence, drv_presence_mask; + uint32_t dev_part_info1, dev_part_info2, class_type; + uint32_t class_type_mask = 0x3; + uint16_t fcoe_other_function = 0xffff, i; + + qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence); + + qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1); + qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2); + for (i = 0; i < 8; i++) { + class_type = ((dev_part_info1 >> (i * 4)) & class_type_mask); + if ((class_type == QLA83XX_CLASS_TYPE_FCOE) && + (i != ha->portnum)) { + fcoe_other_function = i; + break; + } + } + if (fcoe_other_function == 0xffff) { + for (i = 0; i < 8; i++) { + class_type = ((dev_part_info2 >> (i * 4)) & + class_type_mask); + if ((class_type == QLA83XX_CLASS_TYPE_FCOE) && + ((i + 8) != ha->portnum)) { + fcoe_other_function = i + 8; + break; + } + } + } + /* + * Prepare drv-presence mask based on fcoe functions present. + * However consider only valid physical fcoe function numbers (0-15). + */ + drv_presence_mask = ~((1 << (ha->portnum)) | + ((fcoe_other_function == 0xffff) ? + 0 : (1 << (fcoe_other_function)))); + + /* We are the reset owner iff: + * - No other protocol drivers present. + * - This is the lowest among fcoe functions. */ + if (!(drv_presence & drv_presence_mask) && + (ha->portnum < fcoe_other_function)) { + ql_dbg(ql_dbg_p3p, vha, 0xb07f, + "This host is Reset owner.\n"); + ha->flags.nic_core_reset_owner = 1; + } +} + +int +__qla83xx_set_drv_ack(scsi_qla_host_t *vha) +{ + int rval = QLA_SUCCESS; + struct qla_hw_data *ha = vha->hw; + uint32_t drv_ack; + + rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack); + if (rval == QLA_SUCCESS) { + drv_ack |= (1 << ha->portnum); + rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack); + } + + return rval; +} + +int +qla83xx_set_drv_ack(scsi_qla_host_t *vha) +{ + int rval = QLA_SUCCESS; + + qla83xx_idc_lock(vha, 0); + rval = __qla83xx_set_drv_ack(vha); + qla83xx_idc_unlock(vha, 0); + + return rval; +} + +int +__qla83xx_clear_drv_ack(scsi_qla_host_t *vha) +{ + int rval = QLA_SUCCESS; + struct qla_hw_data *ha = vha->hw; + uint32_t drv_ack; + + rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack); + if (rval == QLA_SUCCESS) { + drv_ack &= ~(1 << ha->portnum); + rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack); + } + + return rval; +} + +int +qla83xx_clear_drv_ack(scsi_qla_host_t *vha) +{ + int rval = QLA_SUCCESS; + + qla83xx_idc_lock(vha, 0); + rval = __qla83xx_clear_drv_ack(vha); + qla83xx_idc_unlock(vha, 0); + + return rval; +} + +const char * +qla83xx_dev_state_to_string(uint32_t dev_state) +{ + switch (dev_state) { + case QLA8XXX_DEV_COLD: + return "COLD/RE-INIT"; + case QLA8XXX_DEV_INITIALIZING: + return "INITIALIZING"; + case QLA8XXX_DEV_READY: + return "READY"; + case QLA8XXX_DEV_NEED_RESET: + return "NEED RESET"; + case QLA8XXX_DEV_NEED_QUIESCENT: + return "NEED QUIESCENT"; + case QLA8XXX_DEV_FAILED: + return "FAILED"; + case QLA8XXX_DEV_QUIESCENT: + return "QUIESCENT"; + default: + return "Unknown"; + } +} + +/* Assumes idc-lock always held on entry */ +void +qla83xx_idc_audit(scsi_qla_host_t *vha, int audit_type) +{ + struct qla_hw_data *ha = vha->hw; + uint32_t idc_audit_reg = 0, duration_secs = 0; + + switch (audit_type) { + case IDC_AUDIT_TIMESTAMP: + ha->idc_audit_ts = (jiffies_to_msecs(jiffies) / 1000); + idc_audit_reg = (ha->portnum) | + (IDC_AUDIT_TIMESTAMP << 7) | (ha->idc_audit_ts << 8); + qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg); + break; + + case IDC_AUDIT_COMPLETION: + duration_secs = ((jiffies_to_msecs(jiffies) - + jiffies_to_msecs(ha->idc_audit_ts)) / 1000); + idc_audit_reg = (ha->portnum) | + (IDC_AUDIT_COMPLETION << 7) | (duration_secs << 8); + qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg); + break; + + default: + ql_log(ql_log_warn, vha, 0xb078, + "Invalid audit type specified.\n"); + break; + } +} + +/* Assumes idc_lock always held on entry */ +int +qla83xx_initiating_reset(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + uint32_t idc_control, dev_state; + + __qla83xx_get_idc_control(vha, &idc_control); + if ((idc_control & QLA83XX_IDC_RESET_DISABLED)) { + ql_log(ql_log_info, vha, 0xb080, + "NIC Core reset has been disabled. idc-control=0x%x\n", + idc_control); + return QLA_FUNCTION_FAILED; + } + + /* Set NEED-RESET iff in READY state and we are the reset-owner */ + qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state); + if (ha->flags.nic_core_reset_owner && dev_state == QLA8XXX_DEV_READY) { + qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, + QLA8XXX_DEV_NEED_RESET); + ql_log(ql_log_info, vha, 0xb056, "HW State: NEED RESET.\n"); + qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP); + } else { + const char *state = qla83xx_dev_state_to_string(dev_state); + ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state); + + /* SV: XXX: Is timeout required here? */ + /* Wait for IDC state change READY -> NEED_RESET */ + while (dev_state == QLA8XXX_DEV_READY) { + qla83xx_idc_unlock(vha, 0); + msleep(200); + qla83xx_idc_lock(vha, 0); + qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state); + } + } + + /* Send IDC ack by writing to drv-ack register */ + __qla83xx_set_drv_ack(vha); + + return QLA_SUCCESS; +} + +int +__qla83xx_set_idc_control(scsi_qla_host_t *vha, uint32_t idc_control) +{ + return qla83xx_wr_reg(vha, QLA83XX_IDC_CONTROL, idc_control); +} + +int +qla83xx_set_idc_control(scsi_qla_host_t *vha, uint32_t idc_control) +{ + int rval = QLA_SUCCESS; + + qla83xx_idc_lock(vha, 0); + rval = __qla83xx_set_idc_control(vha, idc_control); + qla83xx_idc_unlock(vha, 0); + + return rval; +} + +int +__qla83xx_get_idc_control(scsi_qla_host_t *vha, uint32_t *idc_control) +{ + return qla83xx_rd_reg(vha, QLA83XX_IDC_CONTROL, idc_control); +} + +int +qla83xx_get_idc_control(scsi_qla_host_t *vha, uint32_t *idc_control) +{ + int rval = QLA_SUCCESS; + + qla83xx_idc_lock(vha, 0); + rval = __qla83xx_get_idc_control(vha, idc_control); + qla83xx_idc_unlock(vha, 0); + + return rval; +} + +int +qla83xx_check_driver_presence(scsi_qla_host_t *vha) +{ + uint32_t drv_presence = 0; + struct qla_hw_data *ha = vha->hw; + + qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence); + if (drv_presence & (1 << ha->portnum)) + return QLA_SUCCESS; + else + return QLA_TEST_FAILED; +} + +int +qla83xx_nic_core_reset(scsi_qla_host_t *vha) +{ + int rval = QLA_SUCCESS; + struct qla_hw_data *ha = vha->hw; + + ql_dbg(ql_dbg_p3p, vha, 0xb058, + "Entered %s().\n", __func__); + + if (vha->device_flags & DFLG_DEV_FAILED) { + ql_log(ql_log_warn, vha, 0xb059, + "Device in unrecoverable FAILED state.\n"); + return QLA_FUNCTION_FAILED; + } + + qla83xx_idc_lock(vha, 0); + + if (qla83xx_check_driver_presence(vha) != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0xb05a, + "Function=0x%x has been removed from IDC participation.\n", + ha->portnum); + rval = QLA_FUNCTION_FAILED; + goto exit; + } + + qla83xx_reset_ownership(vha); + + rval = qla83xx_initiating_reset(vha); + + /* + * Perform reset if we are the reset-owner, + * else wait till IDC state changes to READY/FAILED. + */ + if (rval == QLA_SUCCESS) { + rval = qla83xx_idc_state_handler(vha); + + if (rval == QLA_SUCCESS) + ha->flags.nic_core_hung = 0; + __qla83xx_clear_drv_ack(vha); + } + +exit: + qla83xx_idc_unlock(vha, 0); + + ql_dbg(ql_dbg_p3p, vha, 0xb05b, "Exiting %s.\n", __func__); + + return rval; +} + /* * qla82xx_quiescent_state_cleanup * Description: This function will block the new I/Os @@ -3871,6 +4245,14 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) struct req_que *req = ha->req_q_map[0]; unsigned long flags; + if (IS_QLA8031(ha)) { + ql_dbg(ql_dbg_p3p, vha, 0xb05c, + "Clearing fcoe driver presence.\n"); + if (qla83xx_clear_drv_presence(vha) != QLA_SUCCESS) + ql_dbg(ql_dbg_p3p, vha, 0xb073, + "Erro while clearing DRV-Presence.\n"); + } + if (vha->flags.online) { qla2x00_abort_isp_cleanup(vha); @@ -3982,6 +4364,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) } spin_unlock_irqrestore(&ha->vport_slock, flags); + if (IS_QLA8031(ha)) { + ql_dbg(ql_dbg_p3p, vha, 0xb05d, + "Setting back fcoe driver presence.\n"); + if (qla83xx_set_drv_presence(vha) != QLA_SUCCESS) + ql_dbg(ql_dbg_p3p, vha, 0xb074, + "Error while setting DRV-Presence.\n"); + } } else { ql_log(ql_log_warn, vha, 0x8023, "%s **** FAILED ****.\n", __func__); -- cgit v1.2.1 From 81178772b636a0effe65c98f85a50dc32427b436 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 22 Aug 2012 14:21:04 -0400 Subject: [SCSI] qla2xxx: Implemetation of mctp. [jejb: fix up checkpatch errors] Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 590238d878f6..0ea15b781adf 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4110,6 +4110,60 @@ exit: return rval; } +int +qla2xxx_mctp_dump(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + int rval = QLA_FUNCTION_FAILED; + + if (!IS_MCTP_CAPABLE(ha)) { + /* This message can be removed from the final version */ + ql_log(ql_log_info, vha, 0x506d, + "This board is not MCTP capable\n"); + return rval; + } + + if (!ha->mctp_dump) { + ha->mctp_dump = dma_alloc_coherent(&ha->pdev->dev, + MCTP_DUMP_SIZE, &ha->mctp_dump_dma, GFP_KERNEL); + + if (!ha->mctp_dump) { + ql_log(ql_log_warn, vha, 0x506e, + "Failed to allocate memory for mctp dump\n"); + return rval; + } + } + +#define MCTP_DUMP_STR_ADDR 0x00000000 + rval = qla2x00_dump_mctp_data(vha, ha->mctp_dump_dma, + MCTP_DUMP_STR_ADDR, MCTP_DUMP_SIZE/4); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x506f, + "Failed to capture mctp dump\n"); + } else { + ql_log(ql_log_info, vha, 0x5070, + "Mctp dump capture for host (%ld/%p).\n", + vha->host_no, ha->mctp_dump); + ha->mctp_dumped = 1; + } + + if (!ha->flags.nic_core_reset_hdlr_active) { + ha->flags.nic_core_reset_hdlr_active = 1; + rval = qla83xx_restart_nic_firmware(vha); + if (rval) + /* NIC Core reset failed. */ + ql_log(ql_log_warn, vha, 0x5071, + "Failed to restart nic firmware\n"); + else + ql_dbg(ql_dbg_p3p, vha, 0xb084, + "Restarted NIC firmware successfully.\n"); + ha->flags.nic_core_reset_hdlr_active = 0; + } + + return rval; + +} + /* * qla82xx_quiescent_state_cleanup * Description: This function will block the new I/Os -- cgit v1.2.1 From 8fcd6b8b0fbc61fb1af2960dcec8b23bd2211372 Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Wed, 22 Aug 2012 14:21:06 -0400 Subject: [SCSI] qla2xxx: Changes for ISP83xx loopback support. Minor changes to support loopback functionality with ISP83xx CNAs. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 0ea15b781adf..37eeaa84e62a 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4165,7 +4165,7 @@ qla2xxx_mctp_dump(scsi_qla_host_t *vha) } /* -* qla82xx_quiescent_state_cleanup +* qla2x00_quiesce_io * Description: This function will block the new I/Os * Its not aborting any I/Os as context * is not destroyed during quiescence @@ -4173,20 +4173,20 @@ qla2xxx_mctp_dump(scsi_qla_host_t *vha) * return : void */ void -qla82xx_quiescent_state_cleanup(scsi_qla_host_t *vha) +qla2x00_quiesce_io(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; struct scsi_qla_host *vp; - ql_dbg(ql_dbg_p3p, vha, 0xb002, - "Performing ISP error recovery - ha=%p.\n", ha); + ql_dbg(ql_dbg_dpc, vha, 0x401d, + "Quiescing I/O - ha=%p.\n", ha); atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); qla2x00_mark_all_devices_lost(vha, 0); list_for_each_entry(vp, &ha->vp_list, list) - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vp, 0); } else { if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, -- cgit v1.2.1 From 46152ceb7c9d3bc39715a9994122a6e403cd3db8 Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Wed, 22 Aug 2012 14:21:08 -0400 Subject: [SCSI] qla2xxx: Update the driver copyright. Update the driver copyright from 2003-2011 to 2003-2012. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 37eeaa84e62a..6619b56c06f6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1,6 +1,6 @@ /* * QLogic Fibre Channel HBA Driver - * Copyright (c) 2003-2011 QLogic Corporation + * Copyright (c) 2003-2012 QLogic Corporation * * See LICENSE.qla2xxx for copyright and licensing details. */ -- cgit v1.2.1 From 370d550ea4eda6889ae2fb8a5e9845d2276f1567 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Wed, 22 Aug 2012 14:21:10 -0400 Subject: [SCSI] qla2xxx: Fix for continuous rescan attempts in arbitrated loop topology. Stale information in the temporary fcport created in qla2x00_configure_local_loop() causes qla2x00_get_port_database() call to fail. This reschedules scan, which gets stuck continuously in the rescheduling-of-scan loop due to the failure. Signed-off-by: Arun Easi Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 6619b56c06f6..414f810726f0 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2826,6 +2826,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) if (loop_id > LAST_LOCAL_LOOP_ID) continue; + memset(new_fcport, 0, sizeof(fc_port_t)); + /* Fill in member data. */ new_fcport->d_id.b.domain = domain; new_fcport->d_id.b.area = area; -- cgit v1.2.1 From a6171297c2dc5964570ca6a2036bddff9530004e Mon Sep 17 00:00:00 2001 From: Santosh Vernekar Date: Wed, 22 Aug 2012 14:21:13 -0400 Subject: [SCSI] qla2xxx: Perform ROM mbx cmd access only after ISP soft-reset during f/w recovery. Signed-off-by: Santosh Vernekar Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 414f810726f0..117338da6053 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4301,17 +4301,17 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) struct req_que *req = ha->req_q_map[0]; unsigned long flags; - if (IS_QLA8031(ha)) { - ql_dbg(ql_dbg_p3p, vha, 0xb05c, - "Clearing fcoe driver presence.\n"); - if (qla83xx_clear_drv_presence(vha) != QLA_SUCCESS) - ql_dbg(ql_dbg_p3p, vha, 0xb073, - "Erro while clearing DRV-Presence.\n"); - } - if (vha->flags.online) { qla2x00_abort_isp_cleanup(vha); + if (IS_QLA8031(ha)) { + ql_dbg(ql_dbg_p3p, vha, 0xb05c, + "Clearing fcoe driver presence.\n"); + if (qla83xx_clear_drv_presence(vha) != QLA_SUCCESS) + ql_dbg(ql_dbg_p3p, vha, 0xb073, + "Error while clearing DRV-Presence.\n"); + } + if (unlikely(pci_channel_offline(ha->pdev) && ha->flags.pci_channel_io_perm_failure)) { clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); -- cgit v1.2.1 From 711aa7f722821405125b2a3c6a3e6a3f275952bd Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 22 Aug 2012 14:21:15 -0400 Subject: [SCSI] qla2xxx: Dont call nic restart firmware if it is already active and running. Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 117338da6053..9b5e392a1e82 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -435,6 +435,7 @@ qla83xx_nic_core_fw_load(scsi_qla_host_t *vha) int rval = QLA_SUCCESS; struct qla_hw_data *ha = vha->hw; uint32_t idc_major_ver, idc_minor_ver; + uint16_t config[4]; qla83xx_idc_lock(vha, 0); @@ -486,6 +487,13 @@ qla83xx_nic_core_fw_load(scsi_qla_host_t *vha) idc_minor_ver |= (QLA83XX_SUPP_IDC_MINOR_VERSION << (ha->portnum * 2)); qla83xx_wr_reg(vha, QLA83XX_IDC_MINOR_VERSION, idc_minor_ver); + if (ha->flags.nic_core_reset_owner) { + memset(config, 0, sizeof(config)); + if (!qla81xx_get_port_config(vha, config)) + qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, + QLA8XXX_DEV_READY); + } + rval = qla83xx_idc_state_handler(vha); exit: -- cgit v1.2.1 From c74d88a46865a9c4f14a40ec1ae88e34f38da7a7 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Wed, 22 Aug 2012 14:21:19 -0400 Subject: [SCSI] qla2xxx: Fail initialization if unable to load RISC code. Signed-off-by: Andrew Vasquez Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9b5e392a1e82..f4bbf1cee6b7 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1561,7 +1561,8 @@ enable_82xx_npiv: "ISP Firmware failed checksum.\n"); goto failed; } - } + } else + goto failed; if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) { /* Enable proper parity. */ -- cgit v1.2.1 From 45980cc22edc324d145978340bd3fc6dd8417f81 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 22 Aug 2012 14:21:21 -0400 Subject: [SCSI] qla2xxx: Do not restrict the number of NPIV ports for ISP83xx. Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f4bbf1cee6b7..075059de60f3 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1907,7 +1907,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha) ql_dbg(ql_dbg_init, vha, 0x00d1, "Issue init firmware.\n"); if (ha->flags.npiv_supported) { - if (ha->operating_mode == LOOP) + if (ha->operating_mode == LOOP && !IS_CNA_CAPABLE(ha)) ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1; mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports); } -- cgit v1.2.1 From 5ffd3a52bf5afd69012d253665c65a49002883cc Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Wed, 22 Aug 2012 14:21:26 -0400 Subject: [SCSI] qla2xxx: Set Maximum Read Request Size to 4K. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 075059de60f3..327e0fc686ad 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -767,7 +767,7 @@ qla24xx_pci_config(scsi_qla_host_t *vha) /* PCIe -- adjust Maximum Read Request Size (2048). */ if (pci_is_pcie(ha->pdev)) - pcie_set_readrq(ha->pdev, 2048); + pcie_set_readrq(ha->pdev, 4096); pci_disable_rom(ha->pdev); @@ -803,7 +803,7 @@ qla25xx_pci_config(scsi_qla_host_t *vha) /* PCIe -- adjust Maximum Read Request Size (2048). */ if (pci_is_pcie(ha->pdev)) - pcie_set_readrq(ha->pdev, 2048); + pcie_set_readrq(ha->pdev, 4096); pci_disable_rom(ha->pdev); -- cgit v1.2.1 From 2a8593f80d576425de5332bc2d1319eb2683b9d5 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 22 Aug 2012 14:21:27 -0400 Subject: [SCSI] qla2xxx: Get fcal position map should not be called for p2p topology. Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 327e0fc686ad..ef4aeb792135 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2764,11 +2764,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) new_fcport = NULL; entries = MAX_FIBRE_DEVICES_LOOP; - ql_dbg(ql_dbg_disc, vha, 0x2016, - "Getting FCAL position map.\n"); - if (ql2xextended_error_logging & ql_dbg_disc) - qla2x00_get_fcal_position_map(vha, NULL); - /* Get list of logged in devices. */ memset(ha->gid_list, 0, qla2x00_gid_list_size(ha)); rval = qla2x00_get_id_list(vha, ha->gid_list, ha->gid_list_dma, -- cgit v1.2.1 From 409ee0fe14b113cbb7ec6ef4a6e0982e2e5c1e8f Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 22 Aug 2012 14:21:29 -0400 Subject: [SCSI] qla2xxx: Restrict nic core reset to one function for mctp. Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index ef4aeb792135..62081cf4d824 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4153,7 +4153,7 @@ qla2xxx_mctp_dump(scsi_qla_host_t *vha) ha->mctp_dumped = 1; } - if (!ha->flags.nic_core_reset_hdlr_active) { + if (!ha->flags.nic_core_reset_hdlr_active && !ha->portnum) { ha->flags.nic_core_reset_hdlr_active = 1; rval = qla83xx_restart_nic_firmware(vha); if (rval) -- cgit v1.2.1 From 9e522cd8f3dd7d19b644fc9cfc372bebde9f0053 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Wed, 22 Aug 2012 14:21:31 -0400 Subject: [SCSI] qla2xxx: T10 DIF - ISP83xx changes. Signed-off-by: Arun Easi Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/scsi/qla2xxx/qla_init.c') diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 62081cf4d824..799a58bb9859 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5498,6 +5498,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) rval = 1; } + if (IS_T10_PI_CAPABLE(ha)) + nv->frame_payload_size &= ~7; + /* Reset Initialization control block */ memset(icb, 0, ha->init_cb_size); -- cgit v1.2.1