| .. | .. |
|---|
| 1 | | - /* |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 2 | +/* |
|---|
| 2 | 3 | * QLogic Fibre Channel HBA Driver |
|---|
| 3 | 4 | * Copyright (c) 2003-2014 QLogic Corporation |
|---|
| 4 | | - * |
|---|
| 5 | | - * See LICENSE.qla2xxx for copyright and licensing details. |
|---|
| 6 | 5 | */ |
|---|
| 7 | 6 | #include "qla_def.h" |
|---|
| 8 | 7 | |
|---|
| .. | .. |
|---|
| 11 | 10 | #include <linux/delay.h> |
|---|
| 12 | 11 | #include <linux/bsg-lib.h> |
|---|
| 13 | 12 | |
|---|
| 14 | | -/* BSG support for ELS/CT pass through */ |
|---|
| 15 | | -void |
|---|
| 16 | | -qla2x00_bsg_job_done(void *ptr, int res) |
|---|
| 13 | +static void qla2xxx_free_fcport_work(struct work_struct *work) |
|---|
| 17 | 14 | { |
|---|
| 18 | | - srb_t *sp = ptr; |
|---|
| 15 | + struct fc_port *fcport = container_of(work, typeof(*fcport), |
|---|
| 16 | + free_work); |
|---|
| 17 | + |
|---|
| 18 | + qla2x00_free_fcport(fcport); |
|---|
| 19 | +} |
|---|
| 20 | + |
|---|
| 21 | +/* BSG support for ELS/CT pass through */ |
|---|
| 22 | +void qla2x00_bsg_job_done(srb_t *sp, int res) |
|---|
| 23 | +{ |
|---|
| 19 | 24 | struct bsg_job *bsg_job = sp->u.bsg_job; |
|---|
| 20 | 25 | struct fc_bsg_reply *bsg_reply = bsg_job->reply; |
|---|
| 21 | 26 | |
|---|
| .. | .. |
|---|
| 26 | 31 | bsg_reply->reply_payload_rcv_len); |
|---|
| 27 | 32 | } |
|---|
| 28 | 33 | |
|---|
| 29 | | -void |
|---|
| 30 | | -qla2x00_bsg_sp_free(void *ptr) |
|---|
| 34 | +void qla2x00_bsg_sp_free(srb_t *sp) |
|---|
| 31 | 35 | { |
|---|
| 32 | | - srb_t *sp = ptr; |
|---|
| 33 | 36 | struct qla_hw_data *ha = sp->vha->hw; |
|---|
| 34 | 37 | struct bsg_job *bsg_job = sp->u.bsg_job; |
|---|
| 35 | 38 | struct fc_bsg_request *bsg_request = bsg_job->request; |
|---|
| .. | .. |
|---|
| 58 | 61 | |
|---|
| 59 | 62 | if (sp->type == SRB_CT_CMD || |
|---|
| 60 | 63 | sp->type == SRB_FXIOCB_BCMD || |
|---|
| 61 | | - sp->type == SRB_ELS_CMD_HST) |
|---|
| 62 | | - kfree(sp->fcport); |
|---|
| 64 | + sp->type == SRB_ELS_CMD_HST) { |
|---|
| 65 | + INIT_WORK(&sp->fcport->free_work, qla2xxx_free_fcport_work); |
|---|
| 66 | + queue_work(ha->wq, &sp->fcport->free_work); |
|---|
| 67 | + } |
|---|
| 68 | + |
|---|
| 63 | 69 | qla2x00_rel_sp(sp); |
|---|
| 64 | 70 | } |
|---|
| 65 | 71 | |
|---|
| .. | .. |
|---|
| 85 | 91 | return 0; |
|---|
| 86 | 92 | } |
|---|
| 87 | 93 | |
|---|
| 88 | | - if (bcode[0] != 'H' || bcode[1] != 'Q' || bcode[2] != 'O' || |
|---|
| 89 | | - bcode[3] != 'S') { |
|---|
| 94 | + if (memcmp(bcode, "HQOS", 4)) { |
|---|
| 90 | 95 | /* Invalid FCP priority data header*/ |
|---|
| 91 | 96 | ql_dbg(ql_dbg_user, vha, 0x7052, |
|---|
| 92 | 97 | "Invalid FCP Priority data header. bcode=0x%x.\n", |
|---|
| .. | .. |
|---|
| 218 | 223 | |
|---|
| 219 | 224 | /* validate fcp priority data */ |
|---|
| 220 | 225 | |
|---|
| 221 | | - if (!qla24xx_fcp_prio_cfg_valid(vha, |
|---|
| 222 | | - (struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) { |
|---|
| 226 | + if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 1)) { |
|---|
| 223 | 227 | bsg_reply->result = (DID_ERROR << 16); |
|---|
| 224 | 228 | ret = -EINVAL; |
|---|
| 225 | 229 | /* If buffer was invalidatic int |
|---|
| .. | .. |
|---|
| 410 | 414 | goto done_free_fcport; |
|---|
| 411 | 415 | |
|---|
| 412 | 416 | done_free_fcport: |
|---|
| 413 | | - if (bsg_request->msgcode == FC_BSG_RPT_ELS) |
|---|
| 414 | | - kfree(fcport); |
|---|
| 417 | + if (bsg_request->msgcode != FC_BSG_RPT_ELS) |
|---|
| 418 | + qla2x00_free_fcport(fcport); |
|---|
| 415 | 419 | done: |
|---|
| 416 | 420 | return rval; |
|---|
| 417 | 421 | } |
|---|
| .. | .. |
|---|
| 485 | 489 | >> 24; |
|---|
| 486 | 490 | switch (loop_id) { |
|---|
| 487 | 491 | case 0xFC: |
|---|
| 488 | | - loop_id = cpu_to_le16(NPH_SNS); |
|---|
| 492 | + loop_id = NPH_SNS; |
|---|
| 489 | 493 | break; |
|---|
| 490 | 494 | case 0xFA: |
|---|
| 491 | 495 | loop_id = vha->mgmt_svr_loop_id; |
|---|
| .. | .. |
|---|
| 551 | 555 | return rval; |
|---|
| 552 | 556 | |
|---|
| 553 | 557 | done_free_fcport: |
|---|
| 554 | | - kfree(fcport); |
|---|
| 558 | + qla2x00_free_fcport(fcport); |
|---|
| 555 | 559 | done_unmap_sg: |
|---|
| 556 | 560 | dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, |
|---|
| 557 | 561 | bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); |
|---|
| .. | .. |
|---|
| 686 | 690 | * dump and reset the chip. |
|---|
| 687 | 691 | */ |
|---|
| 688 | 692 | if (ret) { |
|---|
| 689 | | - ha->isp_ops->fw_dump(vha, 0); |
|---|
| 693 | + qla2xxx_dump_fw(vha); |
|---|
| 690 | 694 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
|---|
| 691 | 695 | } |
|---|
| 692 | 696 | rval = -EINVAL; |
|---|
| .. | .. |
|---|
| 723 | 727 | uint16_t response[MAILBOX_REGISTER_COUNT]; |
|---|
| 724 | 728 | uint16_t config[4], new_config[4]; |
|---|
| 725 | 729 | uint8_t *fw_sts_ptr; |
|---|
| 726 | | - uint8_t *req_data = NULL; |
|---|
| 730 | + void *req_data = NULL; |
|---|
| 727 | 731 | dma_addr_t req_data_dma; |
|---|
| 728 | 732 | uint32_t req_data_len; |
|---|
| 729 | 733 | uint8_t *rsp_data = NULL; |
|---|
| .. | .. |
|---|
| 801 | 805 | bsg_request->rqst_data.h_vendor.vendor_cmd[2]; |
|---|
| 802 | 806 | |
|---|
| 803 | 807 | if (atomic_read(&vha->loop_state) == LOOP_READY && |
|---|
| 804 | | - (ha->current_topology == ISP_CFG_F || |
|---|
| 805 | | - (le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE && |
|---|
| 806 | | - req_data_len == MAX_ELS_FRAME_PAYLOAD)) && |
|---|
| 807 | | - elreq.options == EXTERNAL_LOOPBACK) { |
|---|
| 808 | + ((ha->current_topology == ISP_CFG_F && (elreq.options & 7) >= 2) || |
|---|
| 809 | + ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) && |
|---|
| 810 | + get_unaligned_le32(req_data) == ELS_OPCODE_BYTE && |
|---|
| 811 | + req_data_len == MAX_ELS_FRAME_PAYLOAD && |
|---|
| 812 | + elreq.options == EXTERNAL_LOOPBACK))) { |
|---|
| 808 | 813 | type = "FC_BSG_HST_VENDOR_ECHO_DIAG"; |
|---|
| 809 | 814 | ql_dbg(ql_dbg_user, vha, 0x701e, |
|---|
| 810 | 815 | "BSG request type: %s.\n", type); |
|---|
| .. | .. |
|---|
| 890 | 895 | * doesn't work take FCoE dump and then |
|---|
| 891 | 896 | * reset the chip. |
|---|
| 892 | 897 | */ |
|---|
| 893 | | - ha->isp_ops->fw_dump(vha, 0); |
|---|
| 898 | + qla2xxx_dump_fw(vha); |
|---|
| 894 | 899 | set_bit(ISP_ABORT_NEEDED, |
|---|
| 895 | 900 | &vha->dpc_flags); |
|---|
| 896 | 901 | } |
|---|
| .. | .. |
|---|
| 1049 | 1054 | } |
|---|
| 1050 | 1055 | |
|---|
| 1051 | 1056 | flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; |
|---|
| 1052 | | - fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2))); |
|---|
| 1057 | + fw_ver = get_unaligned_le32((uint32_t *)fw_buf + 2); |
|---|
| 1053 | 1058 | |
|---|
| 1054 | 1059 | mn->entry_type = VERIFY_CHIP_IOCB_TYPE; |
|---|
| 1055 | 1060 | mn->entry_count = 1; |
|---|
| .. | .. |
|---|
| 1062 | 1067 | mn->fw_ver = cpu_to_le32(fw_ver); |
|---|
| 1063 | 1068 | mn->fw_size = cpu_to_le32(data_len); |
|---|
| 1064 | 1069 | mn->fw_seq_size = cpu_to_le32(data_len); |
|---|
| 1065 | | - mn->dseg_address[0] = cpu_to_le32(LSD(fw_dma)); |
|---|
| 1066 | | - mn->dseg_address[1] = cpu_to_le32(MSD(fw_dma)); |
|---|
| 1067 | | - mn->dseg_length = cpu_to_le32(data_len); |
|---|
| 1070 | + put_unaligned_le64(fw_dma, &mn->dsd.address); |
|---|
| 1071 | + mn->dsd.length = cpu_to_le32(data_len); |
|---|
| 1068 | 1072 | mn->data_seg_cnt = cpu_to_le16(1); |
|---|
| 1069 | 1073 | |
|---|
| 1070 | 1074 | rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); |
|---|
| .. | .. |
|---|
| 1243 | 1247 | if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) { |
|---|
| 1244 | 1248 | mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len); |
|---|
| 1245 | 1249 | mn->dseg_count = cpu_to_le16(1); |
|---|
| 1246 | | - mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma)); |
|---|
| 1247 | | - mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma)); |
|---|
| 1248 | | - mn->dseg_length = cpu_to_le32(ql84_mgmt->mgmt.len); |
|---|
| 1250 | + put_unaligned_le64(mgmt_dma, &mn->dsd.address); |
|---|
| 1251 | + mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len); |
|---|
| 1249 | 1252 | } |
|---|
| 1250 | 1253 | |
|---|
| 1251 | 1254 | rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0); |
|---|
| .. | .. |
|---|
| 1359 | 1362 | |
|---|
| 1360 | 1363 | if (rval) { |
|---|
| 1361 | 1364 | ql_log(ql_log_warn, vha, 0x704c, |
|---|
| 1362 | | - "iIDMA cmd failed for %8phN -- " |
|---|
| 1365 | + "iiDMA cmd failed for %8phN -- " |
|---|
| 1363 | 1366 | "%04x %x %04x %04x.\n", fcport->port_name, |
|---|
| 1364 | 1367 | rval, fcport->fp_speed, mb[0], mb[1]); |
|---|
| 1365 | 1368 | rval = (DID_ERROR << 16); |
|---|
| .. | .. |
|---|
| 1417 | 1420 | start == (ha->flt_region_fw * 4)) |
|---|
| 1418 | 1421 | valid = 1; |
|---|
| 1419 | 1422 | else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || |
|---|
| 1420 | | - IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) |
|---|
| 1423 | + IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
|---|
| 1424 | + IS_QLA28XX(ha)) |
|---|
| 1421 | 1425 | valid = 1; |
|---|
| 1422 | 1426 | if (!valid) { |
|---|
| 1423 | 1427 | ql_log(ql_log_warn, vha, 0x7058, |
|---|
| .. | .. |
|---|
| 1512 | 1516 | bsg_job->request_payload.sg_cnt, ha->optrom_buffer, |
|---|
| 1513 | 1517 | ha->optrom_region_size); |
|---|
| 1514 | 1518 | |
|---|
| 1515 | | - ha->isp_ops->write_optrom(vha, ha->optrom_buffer, |
|---|
| 1519 | + rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer, |
|---|
| 1516 | 1520 | ha->optrom_region_start, ha->optrom_region_size); |
|---|
| 1517 | 1521 | |
|---|
| 1518 | | - bsg_reply->result = DID_OK; |
|---|
| 1522 | + if (rval) { |
|---|
| 1523 | + bsg_reply->result = -EINVAL; |
|---|
| 1524 | + rval = -EINVAL; |
|---|
| 1525 | + } else { |
|---|
| 1526 | + bsg_reply->result = DID_OK; |
|---|
| 1527 | + } |
|---|
| 1519 | 1528 | vfree(ha->optrom_buffer); |
|---|
| 1520 | 1529 | ha->optrom_buffer = NULL; |
|---|
| 1521 | 1530 | ha->optrom_state = QLA_SWAITING; |
|---|
| .. | .. |
|---|
| 1539 | 1548 | uint32_t count; |
|---|
| 1540 | 1549 | dma_addr_t sfp_dma; |
|---|
| 1541 | 1550 | void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
|---|
| 1551 | + |
|---|
| 1542 | 1552 | if (!sfp) { |
|---|
| 1543 | 1553 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
|---|
| 1544 | 1554 | EXT_STATUS_NO_MEMORY; |
|---|
| .. | .. |
|---|
| 1589 | 1599 | struct qla_status_reg *sr = (void *)bsg; |
|---|
| 1590 | 1600 | dma_addr_t sfp_dma; |
|---|
| 1591 | 1601 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
|---|
| 1602 | + |
|---|
| 1592 | 1603 | if (!sfp) { |
|---|
| 1593 | 1604 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
|---|
| 1594 | 1605 | EXT_STATUS_NO_MEMORY; |
|---|
| .. | .. |
|---|
| 1639 | 1650 | struct qla_status_reg *sr = (void *)bsg; |
|---|
| 1640 | 1651 | dma_addr_t sfp_dma; |
|---|
| 1641 | 1652 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
|---|
| 1653 | + |
|---|
| 1642 | 1654 | if (!sfp) { |
|---|
| 1643 | 1655 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
|---|
| 1644 | 1656 | EXT_STATUS_NO_MEMORY; |
|---|
| .. | .. |
|---|
| 1685 | 1697 | struct qla_i2c_access *i2c = (void *)bsg; |
|---|
| 1686 | 1698 | dma_addr_t sfp_dma; |
|---|
| 1687 | 1699 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
|---|
| 1700 | + |
|---|
| 1688 | 1701 | if (!sfp) { |
|---|
| 1689 | 1702 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
|---|
| 1690 | 1703 | EXT_STATUS_NO_MEMORY; |
|---|
| .. | .. |
|---|
| 1730 | 1743 | struct qla_i2c_access *i2c = (void *)bsg; |
|---|
| 1731 | 1744 | dma_addr_t sfp_dma; |
|---|
| 1732 | 1745 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
|---|
| 1746 | + |
|---|
| 1733 | 1747 | if (!sfp) { |
|---|
| 1734 | 1748 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
|---|
| 1735 | 1749 | EXT_STATUS_NO_MEMORY; |
|---|
| .. | .. |
|---|
| 1965 | 1979 | |
|---|
| 1966 | 1980 | /* Dump the vendor information */ |
|---|
| 1967 | 1981 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf, |
|---|
| 1968 | | - (uint8_t *)piocb_rqst, sizeof(struct qla_mt_iocb_rqst_fx00)); |
|---|
| 1982 | + piocb_rqst, sizeof(*piocb_rqst)); |
|---|
| 1969 | 1983 | |
|---|
| 1970 | 1984 | if (!vha->flags.online) { |
|---|
| 1971 | 1985 | ql_log(ql_log_warn, vha, 0x70d0, |
|---|
| .. | .. |
|---|
| 2027 | 2041 | |
|---|
| 2028 | 2042 | /* Initialize all required fields of fcport */ |
|---|
| 2029 | 2043 | fcport->vha = vha; |
|---|
| 2030 | | - fcport->loop_id = piocb_rqst->dataword; |
|---|
| 2044 | + fcport->loop_id = le32_to_cpu(piocb_rqst->dataword); |
|---|
| 2031 | 2045 | |
|---|
| 2032 | 2046 | sp->type = SRB_FXIOCB_BCMD; |
|---|
| 2033 | 2047 | sp->name = "bsg_fx_mgmt"; |
|---|
| .. | .. |
|---|
| 2051 | 2065 | return rval; |
|---|
| 2052 | 2066 | |
|---|
| 2053 | 2067 | done_free_fcport: |
|---|
| 2054 | | - kfree(fcport); |
|---|
| 2068 | + qla2x00_free_fcport(fcport); |
|---|
| 2055 | 2069 | |
|---|
| 2056 | 2070 | done_unmap_rsp_sg: |
|---|
| 2057 | 2071 | if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) |
|---|
| .. | .. |
|---|
| 2161 | 2175 | struct qla_hw_data *ha = vha->hw; |
|---|
| 2162 | 2176 | struct qla_flash_update_caps cap; |
|---|
| 2163 | 2177 | |
|---|
| 2164 | | - if (!(IS_QLA27XX(ha))) |
|---|
| 2178 | + if (!(IS_QLA27XX(ha)) && !IS_QLA28XX(ha)) |
|---|
| 2165 | 2179 | return -EPERM; |
|---|
| 2166 | 2180 | |
|---|
| 2167 | 2181 | memset(&cap, 0, sizeof(cap)); |
|---|
| .. | .. |
|---|
| 2194 | 2208 | uint64_t online_fw_attr = 0; |
|---|
| 2195 | 2209 | struct qla_flash_update_caps cap; |
|---|
| 2196 | 2210 | |
|---|
| 2197 | | - if (!(IS_QLA27XX(ha))) |
|---|
| 2211 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 2198 | 2212 | return -EPERM; |
|---|
| 2199 | 2213 | |
|---|
| 2200 | 2214 | memset(&cap, 0, sizeof(cap)); |
|---|
| .. | .. |
|---|
| 2242 | 2256 | uint8_t domain, area, al_pa, state; |
|---|
| 2243 | 2257 | int rval; |
|---|
| 2244 | 2258 | |
|---|
| 2245 | | - if (!(IS_QLA27XX(ha))) |
|---|
| 2259 | + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
|---|
| 2246 | 2260 | return -EPERM; |
|---|
| 2247 | 2261 | |
|---|
| 2248 | 2262 | memset(&bbcr, 0, sizeof(bbcr)); |
|---|
| .. | .. |
|---|
| 2316 | 2330 | if (!IS_FWI2_CAPABLE(ha)) |
|---|
| 2317 | 2331 | return -EPERM; |
|---|
| 2318 | 2332 | |
|---|
| 2319 | | - stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats), |
|---|
| 2320 | | - &stats_dma, GFP_KERNEL); |
|---|
| 2333 | + stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma, |
|---|
| 2334 | + GFP_KERNEL); |
|---|
| 2321 | 2335 | if (!stats) { |
|---|
| 2322 | 2336 | ql_log(ql_log_warn, vha, 0x70e2, |
|---|
| 2323 | 2337 | "Failed to allocate memory for stats.\n"); |
|---|
| .. | .. |
|---|
| 2327 | 2341 | rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options); |
|---|
| 2328 | 2342 | |
|---|
| 2329 | 2343 | if (rval == QLA_SUCCESS) { |
|---|
| 2330 | | - ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e3, |
|---|
| 2331 | | - (uint8_t *)stats, sizeof(*stats)); |
|---|
| 2344 | + ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e5, |
|---|
| 2345 | + stats, sizeof(*stats)); |
|---|
| 2332 | 2346 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, |
|---|
| 2333 | 2347 | bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats)); |
|---|
| 2334 | 2348 | } |
|---|
| .. | .. |
|---|
| 2357 | 2371 | int rval; |
|---|
| 2358 | 2372 | struct qla_dport_diag *dd; |
|---|
| 2359 | 2373 | |
|---|
| 2360 | | - if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw)) |
|---|
| 2374 | + if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && |
|---|
| 2375 | + !IS_QLA28XX(vha->hw)) |
|---|
| 2361 | 2376 | return -EPERM; |
|---|
| 2362 | 2377 | |
|---|
| 2363 | 2378 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 2387 | 2402 | bsg_reply->reply_payload_rcv_len); |
|---|
| 2388 | 2403 | |
|---|
| 2389 | 2404 | kfree(dd); |
|---|
| 2405 | + |
|---|
| 2406 | + return 0; |
|---|
| 2407 | +} |
|---|
| 2408 | + |
|---|
| 2409 | +static int |
|---|
| 2410 | +qla2x00_get_flash_image_status(struct bsg_job *bsg_job) |
|---|
| 2411 | +{ |
|---|
| 2412 | + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); |
|---|
| 2413 | + struct fc_bsg_reply *bsg_reply = bsg_job->reply; |
|---|
| 2414 | + struct qla_hw_data *ha = vha->hw; |
|---|
| 2415 | + struct qla_active_regions regions = { }; |
|---|
| 2416 | + struct active_regions active_regions = { }; |
|---|
| 2417 | + |
|---|
| 2418 | + qla27xx_get_active_image(vha, &active_regions); |
|---|
| 2419 | + regions.global_image = active_regions.global; |
|---|
| 2420 | + |
|---|
| 2421 | + if (IS_QLA28XX(ha)) { |
|---|
| 2422 | + qla28xx_get_aux_images(vha, &active_regions); |
|---|
| 2423 | + regions.board_config = active_regions.aux.board_config; |
|---|
| 2424 | + regions.vpd_nvram = active_regions.aux.vpd_nvram; |
|---|
| 2425 | + regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1; |
|---|
| 2426 | + regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3; |
|---|
| 2427 | + } |
|---|
| 2428 | + |
|---|
| 2429 | + ql_dbg(ql_dbg_user, vha, 0x70e1, |
|---|
| 2430 | + "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n", |
|---|
| 2431 | + __func__, vha->host_no, regions.global_image, |
|---|
| 2432 | + regions.board_config, regions.vpd_nvram, |
|---|
| 2433 | + regions.npiv_config_0_1, regions.npiv_config_2_3); |
|---|
| 2434 | + |
|---|
| 2435 | + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, |
|---|
| 2436 | + bsg_job->reply_payload.sg_cnt, ®ions, sizeof(regions)); |
|---|
| 2437 | + |
|---|
| 2438 | + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK; |
|---|
| 2439 | + bsg_reply->reply_payload_rcv_len = sizeof(regions); |
|---|
| 2440 | + bsg_reply->result = DID_OK << 16; |
|---|
| 2441 | + bsg_job->reply_len = sizeof(struct fc_bsg_reply); |
|---|
| 2442 | + bsg_job_done(bsg_job, bsg_reply->result, |
|---|
| 2443 | + bsg_reply->reply_payload_rcv_len); |
|---|
| 2390 | 2444 | |
|---|
| 2391 | 2445 | return 0; |
|---|
| 2392 | 2446 | } |
|---|
| .. | .. |
|---|
| 2464 | 2518 | case QL_VND_DPORT_DIAGNOSTICS: |
|---|
| 2465 | 2519 | return qla2x00_do_dport_diagnostics(bsg_job); |
|---|
| 2466 | 2520 | |
|---|
| 2521 | + case QL_VND_SS_GET_FLASH_IMAGE_STATUS: |
|---|
| 2522 | + return qla2x00_get_flash_image_status(bsg_job); |
|---|
| 2523 | + |
|---|
| 2467 | 2524 | default: |
|---|
| 2468 | 2525 | return -ENOSYS; |
|---|
| 2469 | 2526 | } |
|---|