From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/scsi/qla2xxx/qla_bsg.c | 161 +++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 112 insertions(+), 49 deletions(-) diff --git a/kernel/drivers/scsi/qla2xxx/qla_bsg.c b/kernel/drivers/scsi/qla2xxx/qla_bsg.c index eae1665..804cac4 100644 --- a/kernel/drivers/scsi/qla2xxx/qla_bsg.c +++ b/kernel/drivers/scsi/qla2xxx/qla_bsg.c @@ -1,8 +1,7 @@ - /* +// SPDX-License-Identifier: GPL-2.0-only +/* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" @@ -11,11 +10,17 @@ #include <linux/delay.h> #include <linux/bsg-lib.h> -/* BSG support for ELS/CT pass through */ -void -qla2x00_bsg_job_done(void *ptr, int res) +static void qla2xxx_free_fcport_work(struct work_struct *work) { - srb_t *sp = ptr; + struct fc_port *fcport = container_of(work, typeof(*fcport), + free_work); + + qla2x00_free_fcport(fcport); +} + +/* BSG support for ELS/CT pass through */ +void qla2x00_bsg_job_done(srb_t *sp, int res) +{ struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_reply *bsg_reply = bsg_job->reply; @@ -26,10 +31,8 @@ bsg_reply->reply_payload_rcv_len); } -void -qla2x00_bsg_sp_free(void *ptr) +void qla2x00_bsg_sp_free(srb_t *sp) { - srb_t *sp = ptr; struct qla_hw_data *ha = sp->vha->hw; struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_request *bsg_request = bsg_job->request; @@ -58,8 +61,11 @@ if (sp->type == SRB_CT_CMD || sp->type == SRB_FXIOCB_BCMD || - sp->type == SRB_ELS_CMD_HST) - kfree(sp->fcport); + sp->type == SRB_ELS_CMD_HST) { + INIT_WORK(&sp->fcport->free_work, qla2xxx_free_fcport_work); + queue_work(ha->wq, &sp->fcport->free_work); + } + qla2x00_rel_sp(sp); } @@ -85,8 +91,7 @@ return 0; } - if (bcode[0] != 'H' || bcode[1] != 'Q' || bcode[2] != 'O' || - bcode[3] != 'S') { + if (memcmp(bcode, "HQOS", 4)) { /* Invalid FCP priority data header*/ ql_dbg(ql_dbg_user, vha, 0x7052, "Invalid FCP Priority data header. bcode=0x%x.\n", @@ -218,8 +223,7 @@ /* validate fcp priority data */ - if (!qla24xx_fcp_prio_cfg_valid(vha, - (struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) { + if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 1)) { bsg_reply->result = (DID_ERROR << 16); ret = -EINVAL; /* If buffer was invalidatic int @@ -264,6 +268,10 @@ if (bsg_request->msgcode == FC_BSG_RPT_ELS) { rport = fc_bsg_to_rport(bsg_job); + if (!rport) { + rval = -ENOMEM; + goto done; + } fcport = *(fc_port_t **) rport->dd_data; host = rport_to_shost(rport); vha = shost_priv(host); @@ -410,8 +418,8 @@ goto done_free_fcport; done_free_fcport: - if (bsg_request->msgcode == FC_BSG_RPT_ELS) - kfree(fcport); + if (bsg_request->msgcode != FC_BSG_RPT_ELS) + qla2x00_free_fcport(fcport); done: return rval; } @@ -485,7 +493,7 @@ >> 24; switch (loop_id) { case 0xFC: - loop_id = cpu_to_le16(NPH_SNS); + loop_id = NPH_SNS; break; case 0xFA: loop_id = vha->mgmt_svr_loop_id; @@ -551,7 +559,7 @@ return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_sg: dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); @@ -686,7 +694,7 @@ * dump and reset the chip. */ if (ret) { - ha->isp_ops->fw_dump(vha, 0); + qla2xxx_dump_fw(vha); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); } rval = -EINVAL; @@ -723,7 +731,7 @@ uint16_t response[MAILBOX_REGISTER_COUNT]; uint16_t config[4], new_config[4]; uint8_t *fw_sts_ptr; - uint8_t *req_data = NULL; + void *req_data = NULL; dma_addr_t req_data_dma; uint32_t req_data_len; uint8_t *rsp_data = NULL; @@ -801,10 +809,11 @@ bsg_request->rqst_data.h_vendor.vendor_cmd[2]; if (atomic_read(&vha->loop_state) == LOOP_READY && - (ha->current_topology == ISP_CFG_F || - (le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE && - req_data_len == MAX_ELS_FRAME_PAYLOAD)) && - elreq.options == EXTERNAL_LOOPBACK) { + ((ha->current_topology == ISP_CFG_F && (elreq.options & 7) >= 2) || + ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) && + get_unaligned_le32(req_data) == ELS_OPCODE_BYTE && + req_data_len == MAX_ELS_FRAME_PAYLOAD && + elreq.options == EXTERNAL_LOOPBACK))) { type = "FC_BSG_HST_VENDOR_ECHO_DIAG"; ql_dbg(ql_dbg_user, vha, 0x701e, "BSG request type: %s.\n", type); @@ -890,7 +899,7 @@ * doesn't work take FCoE dump and then * reset the chip. */ - ha->isp_ops->fw_dump(vha, 0); + qla2xxx_dump_fw(vha); set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); } @@ -1049,7 +1058,7 @@ } flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; - fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2))); + fw_ver = get_unaligned_le32((uint32_t *)fw_buf + 2); mn->entry_type = VERIFY_CHIP_IOCB_TYPE; mn->entry_count = 1; @@ -1062,9 +1071,8 @@ mn->fw_ver = cpu_to_le32(fw_ver); mn->fw_size = cpu_to_le32(data_len); mn->fw_seq_size = cpu_to_le32(data_len); - mn->dseg_address[0] = cpu_to_le32(LSD(fw_dma)); - mn->dseg_address[1] = cpu_to_le32(MSD(fw_dma)); - mn->dseg_length = cpu_to_le32(data_len); + put_unaligned_le64(fw_dma, &mn->dsd.address); + mn->dsd.length = cpu_to_le32(data_len); mn->data_seg_cnt = cpu_to_le16(1); rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); @@ -1243,9 +1251,8 @@ if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) { mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len); mn->dseg_count = cpu_to_le16(1); - mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma)); - mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma)); - mn->dseg_length = cpu_to_le32(ql84_mgmt->mgmt.len); + put_unaligned_le64(mgmt_dma, &mn->dsd.address); + mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len); } rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0); @@ -1359,7 +1366,7 @@ if (rval) { ql_log(ql_log_warn, vha, 0x704c, - "iIDMA cmd failed for %8phN -- " + "iiDMA cmd failed for %8phN -- " "%04x %x %04x %04x.\n", fcport->port_name, rval, fcport->fp_speed, mb[0], mb[1]); rval = (DID_ERROR << 16); @@ -1417,7 +1424,8 @@ start == (ha->flt_region_fw * 4)) valid = 1; else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || - IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) + IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || + IS_QLA28XX(ha)) valid = 1; if (!valid) { ql_log(ql_log_warn, vha, 0x7058, @@ -1512,10 +1520,15 @@ bsg_job->request_payload.sg_cnt, ha->optrom_buffer, ha->optrom_region_size); - ha->isp_ops->write_optrom(vha, ha->optrom_buffer, + rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer, ha->optrom_region_start, ha->optrom_region_size); - bsg_reply->result = DID_OK; + if (rval) { + bsg_reply->result = -EINVAL; + rval = -EINVAL; + } else { + bsg_reply->result = DID_OK; + } vfree(ha->optrom_buffer); ha->optrom_buffer = NULL; ha->optrom_state = QLA_SWAITING; @@ -1539,6 +1552,7 @@ uint32_t count; dma_addr_t sfp_dma; void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); + if (!sfp) { bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_NO_MEMORY; @@ -1589,6 +1603,7 @@ struct qla_status_reg *sr = (void *)bsg; dma_addr_t sfp_dma; uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); + if (!sfp) { bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_NO_MEMORY; @@ -1639,6 +1654,7 @@ struct qla_status_reg *sr = (void *)bsg; dma_addr_t sfp_dma; uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); + if (!sfp) { bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_NO_MEMORY; @@ -1685,6 +1701,7 @@ struct qla_i2c_access *i2c = (void *)bsg; dma_addr_t sfp_dma; uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); + if (!sfp) { bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_NO_MEMORY; @@ -1730,6 +1747,7 @@ struct qla_i2c_access *i2c = (void *)bsg; dma_addr_t sfp_dma; uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); + if (!sfp) { bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_NO_MEMORY; @@ -1965,7 +1983,7 @@ /* Dump the vendor information */ ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf, - (uint8_t *)piocb_rqst, sizeof(struct qla_mt_iocb_rqst_fx00)); + piocb_rqst, sizeof(*piocb_rqst)); if (!vha->flags.online) { ql_log(ql_log_warn, vha, 0x70d0, @@ -2027,7 +2045,7 @@ /* Initialize all required fields of fcport */ fcport->vha = vha; - fcport->loop_id = piocb_rqst->dataword; + fcport->loop_id = le32_to_cpu(piocb_rqst->dataword); sp->type = SRB_FXIOCB_BCMD; sp->name = "bsg_fx_mgmt"; @@ -2051,7 +2069,7 @@ return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_rsp_sg: if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) @@ -2161,7 +2179,7 @@ struct qla_hw_data *ha = vha->hw; struct qla_flash_update_caps cap; - if (!(IS_QLA27XX(ha))) + if (!(IS_QLA27XX(ha)) && !IS_QLA28XX(ha)) return -EPERM; memset(&cap, 0, sizeof(cap)); @@ -2194,7 +2212,7 @@ uint64_t online_fw_attr = 0; struct qla_flash_update_caps cap; - if (!(IS_QLA27XX(ha))) + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) return -EPERM; memset(&cap, 0, sizeof(cap)); @@ -2242,7 +2260,7 @@ uint8_t domain, area, al_pa, state; int rval; - if (!(IS_QLA27XX(ha))) + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) return -EPERM; memset(&bbcr, 0, sizeof(bbcr)); @@ -2316,8 +2334,8 @@ if (!IS_FWI2_CAPABLE(ha)) return -EPERM; - stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats), - &stats_dma, GFP_KERNEL); + stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma, + GFP_KERNEL); if (!stats) { ql_log(ql_log_warn, vha, 0x70e2, "Failed to allocate memory for stats.\n"); @@ -2327,8 +2345,8 @@ rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options); if (rval == QLA_SUCCESS) { - ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e3, - (uint8_t *)stats, sizeof(*stats)); + ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e5, + stats, sizeof(*stats)); sg_copy_from_buffer(bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats)); } @@ -2357,7 +2375,8 @@ int rval; struct qla_dport_diag *dd; - if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw)) + if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && + !IS_QLA28XX(vha->hw)) return -EPERM; dd = kmalloc(sizeof(*dd), GFP_KERNEL); @@ -2387,6 +2406,45 @@ bsg_reply->reply_payload_rcv_len); kfree(dd); + + return 0; +} + +static int +qla2x00_get_flash_image_status(struct bsg_job *bsg_job) +{ + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct qla_hw_data *ha = vha->hw; + struct qla_active_regions regions = { }; + struct active_regions active_regions = { }; + + qla27xx_get_active_image(vha, &active_regions); + regions.global_image = active_regions.global; + + if (IS_QLA28XX(ha)) { + qla28xx_get_aux_images(vha, &active_regions); + regions.board_config = active_regions.aux.board_config; + regions.vpd_nvram = active_regions.aux.vpd_nvram; + regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1; + regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3; + } + + ql_dbg(ql_dbg_user, vha, 0x70e1, + "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n", + __func__, vha->host_no, regions.global_image, + regions.board_config, regions.vpd_nvram, + regions.npiv_config_0_1, regions.npiv_config_2_3); + + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, ®ions, sizeof(regions)); + + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK; + bsg_reply->reply_payload_rcv_len = sizeof(regions); + bsg_reply->result = DID_OK << 16; + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return 0; } @@ -2464,6 +2522,9 @@ case QL_VND_DPORT_DIAGNOSTICS: return qla2x00_do_dport_diagnostics(bsg_job); + case QL_VND_SS_GET_FLASH_IMAGE_STATUS: + return qla2x00_get_flash_image_status(bsg_job); + default: return -ENOSYS; } @@ -2484,6 +2545,8 @@ if (bsg_request->msgcode == FC_BSG_RPT_ELS) { rport = fc_bsg_to_rport(bsg_job); + if (!rport) + return ret; host = rport_to_shost(rport); vha = shost_priv(host); } else { -- Gitblit v1.6.2