Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * QLogic Fibre Channel HBA Driver
0004  * Copyright (c)  2003-2014 QLogic Corporation
0005  */
0006 #include "qla_def.h"
0007 #include "qla_gbl.h"
0008 
0009 #include <linux/kthread.h>
0010 #include <linux/vmalloc.h>
0011 #include <linux/delay.h>
0012 #include <linux/bsg-lib.h>
0013 
0014 static void qla2xxx_free_fcport_work(struct work_struct *work)
0015 {
0016     struct fc_port *fcport = container_of(work, typeof(*fcport),
0017         free_work);
0018 
0019     qla2x00_free_fcport(fcport);
0020 }
0021 
0022 /* BSG support for ELS/CT pass through */
0023 void qla2x00_bsg_job_done(srb_t *sp, int res)
0024 {
0025     struct bsg_job *bsg_job = sp->u.bsg_job;
0026     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
0027 
0028     ql_dbg(ql_dbg_user, sp->vha, 0x7009,
0029         "%s: sp hdl %x, result=%x bsg ptr %p\n",
0030         __func__, sp->handle, res, bsg_job);
0031 
0032     /* ref: INIT */
0033     kref_put(&sp->cmd_kref, qla2x00_sp_release);
0034 
0035     bsg_reply->result = res;
0036     bsg_job_done(bsg_job, bsg_reply->result,
0037                bsg_reply->reply_payload_rcv_len);
0038 }
0039 
0040 void qla2x00_bsg_sp_free(srb_t *sp)
0041 {
0042     struct qla_hw_data *ha = sp->vha->hw;
0043     struct bsg_job *bsg_job = sp->u.bsg_job;
0044     struct fc_bsg_request *bsg_request = bsg_job->request;
0045     struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
0046 
0047     if (sp->type == SRB_FXIOCB_BCMD) {
0048         piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
0049             &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
0050 
0051         if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
0052             dma_unmap_sg(&ha->pdev->dev,
0053                 bsg_job->request_payload.sg_list,
0054                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0055 
0056         if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
0057             dma_unmap_sg(&ha->pdev->dev,
0058                 bsg_job->reply_payload.sg_list,
0059                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0060     } else {
0061 
0062         if (sp->remap.remapped) {
0063             dma_pool_free(ha->purex_dma_pool, sp->remap.rsp.buf,
0064                 sp->remap.rsp.dma);
0065             dma_pool_free(ha->purex_dma_pool, sp->remap.req.buf,
0066                 sp->remap.req.dma);
0067         } else {
0068             dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
0069                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0070 
0071             dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
0072                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0073         }
0074     }
0075 
0076     if (sp->type == SRB_CT_CMD ||
0077         sp->type == SRB_FXIOCB_BCMD ||
0078         sp->type == SRB_ELS_CMD_HST) {
0079         INIT_WORK(&sp->fcport->free_work, qla2xxx_free_fcport_work);
0080         queue_work(ha->wq, &sp->fcport->free_work);
0081     }
0082 
0083     qla2x00_rel_sp(sp);
0084 }
0085 
0086 int
0087 qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
0088     struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
0089 {
0090     int i, ret, num_valid;
0091     uint8_t *bcode;
0092     struct qla_fcp_prio_entry *pri_entry;
0093     uint32_t *bcode_val_ptr, bcode_val;
0094 
0095     ret = 1;
0096     num_valid = 0;
0097     bcode = (uint8_t *)pri_cfg;
0098     bcode_val_ptr = (uint32_t *)pri_cfg;
0099     bcode_val = (uint32_t)(*bcode_val_ptr);
0100 
0101     if (bcode_val == 0xFFFFFFFF) {
0102         /* No FCP Priority config data in flash */
0103         ql_dbg(ql_dbg_user, vha, 0x7051,
0104             "No FCP Priority config data.\n");
0105         return 0;
0106     }
0107 
0108     if (memcmp(bcode, "HQOS", 4)) {
0109         /* Invalid FCP priority data header*/
0110         ql_dbg(ql_dbg_user, vha, 0x7052,
0111             "Invalid FCP Priority data header. bcode=0x%x.\n",
0112             bcode_val);
0113         return 0;
0114     }
0115     if (flag != 1)
0116         return ret;
0117 
0118     pri_entry = &pri_cfg->entry[0];
0119     for (i = 0; i < pri_cfg->num_entries; i++) {
0120         if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
0121             num_valid++;
0122         pri_entry++;
0123     }
0124 
0125     if (num_valid == 0) {
0126         /* No valid FCP priority data entries */
0127         ql_dbg(ql_dbg_user, vha, 0x7053,
0128             "No valid FCP Priority data entries.\n");
0129         ret = 0;
0130     } else {
0131         /* FCP priority data is valid */
0132         ql_dbg(ql_dbg_user, vha, 0x7054,
0133             "Valid FCP priority data. num entries = %d.\n",
0134             num_valid);
0135     }
0136 
0137     return ret;
0138 }
0139 
0140 static int
0141 qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
0142 {
0143     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
0144     struct fc_bsg_request *bsg_request = bsg_job->request;
0145     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
0146     scsi_qla_host_t *vha = shost_priv(host);
0147     struct qla_hw_data *ha = vha->hw;
0148     int ret = 0;
0149     uint32_t len;
0150     uint32_t oper;
0151 
0152     if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_P3P_TYPE(ha))) {
0153         ret = -EINVAL;
0154         goto exit_fcp_prio_cfg;
0155     }
0156 
0157     /* Get the sub command */
0158     oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
0159 
0160     /* Only set config is allowed if config memory is not allocated */
0161     if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
0162         ret = -EINVAL;
0163         goto exit_fcp_prio_cfg;
0164     }
0165     switch (oper) {
0166     case QLFC_FCP_PRIO_DISABLE:
0167         if (ha->flags.fcp_prio_enabled) {
0168             ha->flags.fcp_prio_enabled = 0;
0169             ha->fcp_prio_cfg->attributes &=
0170                 ~FCP_PRIO_ATTR_ENABLE;
0171             qla24xx_update_all_fcp_prio(vha);
0172             bsg_reply->result = DID_OK;
0173         } else {
0174             ret = -EINVAL;
0175             bsg_reply->result = (DID_ERROR << 16);
0176             goto exit_fcp_prio_cfg;
0177         }
0178         break;
0179 
0180     case QLFC_FCP_PRIO_ENABLE:
0181         if (!ha->flags.fcp_prio_enabled) {
0182             if (ha->fcp_prio_cfg) {
0183                 ha->flags.fcp_prio_enabled = 1;
0184                 ha->fcp_prio_cfg->attributes |=
0185                     FCP_PRIO_ATTR_ENABLE;
0186                 qla24xx_update_all_fcp_prio(vha);
0187                 bsg_reply->result = DID_OK;
0188             } else {
0189                 ret = -EINVAL;
0190                 bsg_reply->result = (DID_ERROR << 16);
0191                 goto exit_fcp_prio_cfg;
0192             }
0193         }
0194         break;
0195 
0196     case QLFC_FCP_PRIO_GET_CONFIG:
0197         len = bsg_job->reply_payload.payload_len;
0198         if (!len || len > FCP_PRIO_CFG_SIZE) {
0199             ret = -EINVAL;
0200             bsg_reply->result = (DID_ERROR << 16);
0201             goto exit_fcp_prio_cfg;
0202         }
0203 
0204         bsg_reply->result = DID_OK;
0205         bsg_reply->reply_payload_rcv_len =
0206             sg_copy_from_buffer(
0207             bsg_job->reply_payload.sg_list,
0208             bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
0209             len);
0210 
0211         break;
0212 
0213     case QLFC_FCP_PRIO_SET_CONFIG:
0214         len = bsg_job->request_payload.payload_len;
0215         if (!len || len > FCP_PRIO_CFG_SIZE) {
0216             bsg_reply->result = (DID_ERROR << 16);
0217             ret = -EINVAL;
0218             goto exit_fcp_prio_cfg;
0219         }
0220 
0221         if (!ha->fcp_prio_cfg) {
0222             ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE);
0223             if (!ha->fcp_prio_cfg) {
0224                 ql_log(ql_log_warn, vha, 0x7050,
0225                     "Unable to allocate memory for fcp prio "
0226                     "config data (%x).\n", FCP_PRIO_CFG_SIZE);
0227                 bsg_reply->result = (DID_ERROR << 16);
0228                 ret = -ENOMEM;
0229                 goto exit_fcp_prio_cfg;
0230             }
0231         }
0232 
0233         memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE);
0234         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
0235         bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg,
0236             FCP_PRIO_CFG_SIZE);
0237 
0238         /* validate fcp priority data */
0239 
0240         if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 1)) {
0241             bsg_reply->result = (DID_ERROR << 16);
0242             ret = -EINVAL;
0243             /* If buffer was invalidatic int
0244              * fcp_prio_cfg is of no use
0245              */
0246             vfree(ha->fcp_prio_cfg);
0247             ha->fcp_prio_cfg = NULL;
0248             goto exit_fcp_prio_cfg;
0249         }
0250 
0251         ha->flags.fcp_prio_enabled = 0;
0252         if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
0253             ha->flags.fcp_prio_enabled = 1;
0254         qla24xx_update_all_fcp_prio(vha);
0255         bsg_reply->result = DID_OK;
0256         break;
0257     default:
0258         ret = -EINVAL;
0259         break;
0260     }
0261 exit_fcp_prio_cfg:
0262     if (!ret)
0263         bsg_job_done(bsg_job, bsg_reply->result,
0264                    bsg_reply->reply_payload_rcv_len);
0265     return ret;
0266 }
0267 
0268 static int
0269 qla2x00_process_els(struct bsg_job *bsg_job)
0270 {
0271     struct fc_bsg_request *bsg_request = bsg_job->request;
0272     struct fc_rport *rport;
0273     fc_port_t *fcport = NULL;
0274     struct Scsi_Host *host;
0275     scsi_qla_host_t *vha;
0276     struct qla_hw_data *ha;
0277     srb_t *sp;
0278     const char *type;
0279     int req_sg_cnt, rsp_sg_cnt;
0280     int rval =  (DID_ERROR << 16);
0281     uint16_t nextlid = 0;
0282     uint32_t els_cmd = 0;
0283 
0284     if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
0285         rport = fc_bsg_to_rport(bsg_job);
0286         fcport = *(fc_port_t **) rport->dd_data;
0287         host = rport_to_shost(rport);
0288         vha = shost_priv(host);
0289         ha = vha->hw;
0290         type = "FC_BSG_RPT_ELS";
0291     } else {
0292         host = fc_bsg_to_shost(bsg_job);
0293         vha = shost_priv(host);
0294         ha = vha->hw;
0295         type = "FC_BSG_HST_ELS_NOLOGIN";
0296         els_cmd = bsg_request->rqst_data.h_els.command_code;
0297         if (els_cmd == ELS_AUTH_ELS)
0298             return qla_edif_process_els(vha, bsg_job);
0299     }
0300 
0301     if (!vha->flags.online) {
0302         ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
0303         rval = -EIO;
0304         goto done;
0305     }
0306 
0307     /* pass through is supported only for ISP 4Gb or higher */
0308     if (!IS_FWI2_CAPABLE(ha)) {
0309         ql_dbg(ql_dbg_user, vha, 0x7001,
0310             "ELS passthru not supported for ISP23xx based adapters.\n");
0311         rval = -EPERM;
0312         goto done;
0313     }
0314 
0315     /*  Multiple SG's are not supported for ELS requests */
0316     if (bsg_job->request_payload.sg_cnt > 1 ||
0317         bsg_job->reply_payload.sg_cnt > 1) {
0318         ql_dbg(ql_dbg_user, vha, 0x7002,
0319             "Multiple SG's are not supported for ELS requests, "
0320             "request_sg_cnt=%x reply_sg_cnt=%x.\n",
0321             bsg_job->request_payload.sg_cnt,
0322             bsg_job->reply_payload.sg_cnt);
0323         rval = -EPERM;
0324         goto done;
0325     }
0326 
0327     /* ELS request for rport */
0328     if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
0329         /* make sure the rport is logged in,
0330          * if not perform fabric login
0331          */
0332         if (qla2x00_fabric_login(vha, fcport, &nextlid)) {
0333             ql_dbg(ql_dbg_user, vha, 0x7003,
0334                 "Failed to login port %06X for ELS passthru.\n",
0335                 fcport->d_id.b24);
0336             rval = -EIO;
0337             goto done;
0338         }
0339     } else {
0340         /* Allocate a dummy fcport structure, since functions
0341          * preparing the IOCB and mailbox command retrieves port
0342          * specific information from fcport structure. For Host based
0343          * ELS commands there will be no fcport structure allocated
0344          */
0345         fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
0346         if (!fcport) {
0347             rval = -ENOMEM;
0348             goto done;
0349         }
0350 
0351         /* Initialize all required  fields of fcport */
0352         fcport->vha = vha;
0353         fcport->d_id.b.al_pa =
0354             bsg_request->rqst_data.h_els.port_id[0];
0355         fcport->d_id.b.area =
0356             bsg_request->rqst_data.h_els.port_id[1];
0357         fcport->d_id.b.domain =
0358             bsg_request->rqst_data.h_els.port_id[2];
0359         fcport->loop_id =
0360             (fcport->d_id.b.al_pa == 0xFD) ?
0361             NPH_FABRIC_CONTROLLER : NPH_F_PORT;
0362     }
0363 
0364     req_sg_cnt =
0365         dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
0366         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0367     if (!req_sg_cnt) {
0368         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
0369             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0370         rval = -ENOMEM;
0371         goto done_free_fcport;
0372     }
0373 
0374     rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
0375         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0376         if (!rsp_sg_cnt) {
0377         dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
0378             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0379         rval = -ENOMEM;
0380         goto done_free_fcport;
0381     }
0382 
0383     if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
0384         (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
0385         ql_log(ql_log_warn, vha, 0x7008,
0386             "dma mapping resulted in different sg counts, "
0387             "request_sg_cnt: %x dma_request_sg_cnt:%x reply_sg_cnt:%x "
0388             "dma_reply_sg_cnt:%x.\n", bsg_job->request_payload.sg_cnt,
0389             req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
0390         rval = -EAGAIN;
0391         goto done_unmap_sg;
0392     }
0393 
0394     /* Alloc SRB structure */
0395     sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
0396     if (!sp) {
0397         rval = -ENOMEM;
0398         goto done_unmap_sg;
0399     }
0400 
0401     sp->type =
0402         (bsg_request->msgcode == FC_BSG_RPT_ELS ?
0403          SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
0404     sp->name =
0405         (bsg_request->msgcode == FC_BSG_RPT_ELS ?
0406          "bsg_els_rpt" : "bsg_els_hst");
0407     sp->u.bsg_job = bsg_job;
0408     sp->free = qla2x00_bsg_sp_free;
0409     sp->done = qla2x00_bsg_job_done;
0410 
0411     ql_dbg(ql_dbg_user, vha, 0x700a,
0412         "bsg rqst type: %s els type: %x - loop-id=%x "
0413         "portid=%-2x%02x%02x.\n", type,
0414         bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
0415         fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
0416 
0417     rval = qla2x00_start_sp(sp);
0418     if (rval != QLA_SUCCESS) {
0419         ql_log(ql_log_warn, vha, 0x700e,
0420             "qla2x00_start_sp failed = %d\n", rval);
0421         qla2x00_rel_sp(sp);
0422         rval = -EIO;
0423         goto done_unmap_sg;
0424     }
0425     return rval;
0426 
0427 done_unmap_sg:
0428     dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
0429         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0430     dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
0431         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0432     goto done_free_fcport;
0433 
0434 done_free_fcport:
0435     if (bsg_request->msgcode != FC_BSG_RPT_ELS)
0436         qla2x00_free_fcport(fcport);
0437 done:
0438     return rval;
0439 }
0440 
0441 static inline uint16_t
0442 qla24xx_calc_ct_iocbs(uint16_t dsds)
0443 {
0444     uint16_t iocbs;
0445 
0446     iocbs = 1;
0447     if (dsds > 2) {
0448         iocbs += (dsds - 2) / 5;
0449         if ((dsds - 2) % 5)
0450             iocbs++;
0451     }
0452     return iocbs;
0453 }
0454 
0455 static int
0456 qla2x00_process_ct(struct bsg_job *bsg_job)
0457 {
0458     srb_t *sp;
0459     struct fc_bsg_request *bsg_request = bsg_job->request;
0460     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
0461     scsi_qla_host_t *vha = shost_priv(host);
0462     struct qla_hw_data *ha = vha->hw;
0463     int rval = (DID_ERROR << 16);
0464     int req_sg_cnt, rsp_sg_cnt;
0465     uint16_t loop_id;
0466     struct fc_port *fcport;
0467     char  *type = "FC_BSG_HST_CT";
0468 
0469     req_sg_cnt =
0470         dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
0471             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0472     if (!req_sg_cnt) {
0473         ql_log(ql_log_warn, vha, 0x700f,
0474             "dma_map_sg return %d for request\n", req_sg_cnt);
0475         rval = -ENOMEM;
0476         goto done;
0477     }
0478 
0479     rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
0480         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0481     if (!rsp_sg_cnt) {
0482         ql_log(ql_log_warn, vha, 0x7010,
0483             "dma_map_sg return %d for reply\n", rsp_sg_cnt);
0484         rval = -ENOMEM;
0485         goto done;
0486     }
0487 
0488     if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
0489         (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
0490         ql_log(ql_log_warn, vha, 0x7011,
0491             "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
0492             "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
0493             req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
0494         rval = -EAGAIN;
0495         goto done_unmap_sg;
0496     }
0497 
0498     if (!vha->flags.online) {
0499         ql_log(ql_log_warn, vha, 0x7012,
0500             "Host is not online.\n");
0501         rval = -EIO;
0502         goto done_unmap_sg;
0503     }
0504 
0505     loop_id =
0506         (bsg_request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
0507             >> 24;
0508     switch (loop_id) {
0509     case 0xFC:
0510         loop_id = NPH_SNS;
0511         break;
0512     case 0xFA:
0513         loop_id = vha->mgmt_svr_loop_id;
0514         break;
0515     default:
0516         ql_dbg(ql_dbg_user, vha, 0x7013,
0517             "Unknown loop id: %x.\n", loop_id);
0518         rval = -EINVAL;
0519         goto done_unmap_sg;
0520     }
0521 
0522     /* Allocate a dummy fcport structure, since functions preparing the
0523      * IOCB and mailbox command retrieves port specific information
0524      * from fcport structure. For Host based ELS commands there will be
0525      * no fcport structure allocated
0526      */
0527     fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
0528     if (!fcport) {
0529         ql_log(ql_log_warn, vha, 0x7014,
0530             "Failed to allocate fcport.\n");
0531         rval = -ENOMEM;
0532         goto done_unmap_sg;
0533     }
0534 
0535     /* Initialize all required  fields of fcport */
0536     fcport->vha = vha;
0537     fcport->d_id.b.al_pa = bsg_request->rqst_data.h_ct.port_id[0];
0538     fcport->d_id.b.area = bsg_request->rqst_data.h_ct.port_id[1];
0539     fcport->d_id.b.domain = bsg_request->rqst_data.h_ct.port_id[2];
0540     fcport->loop_id = loop_id;
0541 
0542     /* Alloc SRB structure */
0543     sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
0544     if (!sp) {
0545         ql_log(ql_log_warn, vha, 0x7015,
0546             "qla2x00_get_sp failed.\n");
0547         rval = -ENOMEM;
0548         goto done_free_fcport;
0549     }
0550 
0551     sp->type = SRB_CT_CMD;
0552     sp->name = "bsg_ct";
0553     sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
0554     sp->u.bsg_job = bsg_job;
0555     sp->free = qla2x00_bsg_sp_free;
0556     sp->done = qla2x00_bsg_job_done;
0557 
0558     ql_dbg(ql_dbg_user, vha, 0x7016,
0559         "bsg rqst type: %s else type: %x - "
0560         "loop-id=%x portid=%02x%02x%02x.\n", type,
0561         (bsg_request->rqst_data.h_ct.preamble_word2 >> 16),
0562         fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
0563         fcport->d_id.b.al_pa);
0564 
0565     rval = qla2x00_start_sp(sp);
0566     if (rval != QLA_SUCCESS) {
0567         ql_log(ql_log_warn, vha, 0x7017,
0568             "qla2x00_start_sp failed=%d.\n", rval);
0569         qla2x00_rel_sp(sp);
0570         rval = -EIO;
0571         goto done_free_fcport;
0572     }
0573     return rval;
0574 
0575 done_free_fcport:
0576     qla2x00_free_fcport(fcport);
0577 done_unmap_sg:
0578     dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
0579         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0580     dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
0581         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0582 done:
0583     return rval;
0584 }
0585 
0586 /* Disable loopback mode */
0587 static inline int
0588 qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
0589                 int wait, int wait2)
0590 {
0591     int ret = 0;
0592     int rval = 0;
0593     uint16_t new_config[4];
0594     struct qla_hw_data *ha = vha->hw;
0595 
0596     if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
0597         goto done_reset_internal;
0598 
0599     memset(new_config, 0 , sizeof(new_config));
0600     if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
0601         ENABLE_INTERNAL_LOOPBACK ||
0602         (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
0603         ENABLE_EXTERNAL_LOOPBACK) {
0604         new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
0605         ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
0606             (new_config[0] & INTERNAL_LOOPBACK_MASK));
0607         memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
0608 
0609         ha->notify_dcbx_comp = wait;
0610         ha->notify_lb_portup_comp = wait2;
0611 
0612         ret = qla81xx_set_port_config(vha, new_config);
0613         if (ret != QLA_SUCCESS) {
0614             ql_log(ql_log_warn, vha, 0x7025,
0615                 "Set port config failed.\n");
0616             ha->notify_dcbx_comp = 0;
0617             ha->notify_lb_portup_comp = 0;
0618             rval = -EINVAL;
0619             goto done_reset_internal;
0620         }
0621 
0622         /* Wait for DCBX complete event */
0623         if (wait && !wait_for_completion_timeout(&ha->dcbx_comp,
0624             (DCBX_COMP_TIMEOUT * HZ))) {
0625             ql_dbg(ql_dbg_user, vha, 0x7026,
0626                 "DCBX completion not received.\n");
0627             ha->notify_dcbx_comp = 0;
0628             ha->notify_lb_portup_comp = 0;
0629             rval = -EINVAL;
0630             goto done_reset_internal;
0631         } else
0632             ql_dbg(ql_dbg_user, vha, 0x7027,
0633                 "DCBX completion received.\n");
0634 
0635         if (wait2 &&
0636             !wait_for_completion_timeout(&ha->lb_portup_comp,
0637             (LB_PORTUP_COMP_TIMEOUT * HZ))) {
0638             ql_dbg(ql_dbg_user, vha, 0x70c5,
0639                 "Port up completion not received.\n");
0640             ha->notify_lb_portup_comp = 0;
0641             rval = -EINVAL;
0642             goto done_reset_internal;
0643         } else
0644             ql_dbg(ql_dbg_user, vha, 0x70c6,
0645                 "Port up completion received.\n");
0646 
0647         ha->notify_dcbx_comp = 0;
0648         ha->notify_lb_portup_comp = 0;
0649     }
0650 done_reset_internal:
0651     return rval;
0652 }
0653 
0654 /*
0655  * Set the port configuration to enable the internal or external loopback
0656  * depending on the loopback mode.
0657  */
0658 static inline int
0659 qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
0660     uint16_t *new_config, uint16_t mode)
0661 {
0662     int ret = 0;
0663     int rval = 0;
0664     unsigned long rem_tmo = 0, current_tmo = 0;
0665     struct qla_hw_data *ha = vha->hw;
0666 
0667     if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
0668         goto done_set_internal;
0669 
0670     if (mode == INTERNAL_LOOPBACK)
0671         new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
0672     else if (mode == EXTERNAL_LOOPBACK)
0673         new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
0674     ql_dbg(ql_dbg_user, vha, 0x70be,
0675          "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));
0676 
0677     memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);
0678 
0679     ha->notify_dcbx_comp = 1;
0680     ret = qla81xx_set_port_config(vha, new_config);
0681     if (ret != QLA_SUCCESS) {
0682         ql_log(ql_log_warn, vha, 0x7021,
0683             "set port config failed.\n");
0684         ha->notify_dcbx_comp = 0;
0685         rval = -EINVAL;
0686         goto done_set_internal;
0687     }
0688 
0689     /* Wait for DCBX complete event */
0690     current_tmo = DCBX_COMP_TIMEOUT * HZ;
0691     while (1) {
0692         rem_tmo = wait_for_completion_timeout(&ha->dcbx_comp,
0693             current_tmo);
0694         if (!ha->idc_extend_tmo || rem_tmo) {
0695             ha->idc_extend_tmo = 0;
0696             break;
0697         }
0698         current_tmo = ha->idc_extend_tmo * HZ;
0699         ha->idc_extend_tmo = 0;
0700     }
0701 
0702     if (!rem_tmo) {
0703         ql_dbg(ql_dbg_user, vha, 0x7022,
0704             "DCBX completion not received.\n");
0705         ret = qla81xx_reset_loopback_mode(vha, new_config, 0, 0);
0706         /*
0707          * If the reset of the loopback mode doesn't work take a FCoE
0708          * dump and reset the chip.
0709          */
0710         if (ret) {
0711             qla2xxx_dump_fw(vha);
0712             set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
0713         }
0714         rval = -EINVAL;
0715     } else {
0716         if (ha->flags.idc_compl_status) {
0717             ql_dbg(ql_dbg_user, vha, 0x70c3,
0718                 "Bad status in IDC Completion AEN\n");
0719             rval = -EINVAL;
0720             ha->flags.idc_compl_status = 0;
0721         } else
0722             ql_dbg(ql_dbg_user, vha, 0x7023,
0723                 "DCBX completion received.\n");
0724     }
0725 
0726     ha->notify_dcbx_comp = 0;
0727     ha->idc_extend_tmo = 0;
0728 
0729 done_set_internal:
0730     return rval;
0731 }
0732 
0733 static int
0734 qla2x00_process_loopback(struct bsg_job *bsg_job)
0735 {
0736     struct fc_bsg_request *bsg_request = bsg_job->request;
0737     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
0738     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
0739     scsi_qla_host_t *vha = shost_priv(host);
0740     struct qla_hw_data *ha = vha->hw;
0741     int rval;
0742     uint8_t command_sent;
0743     char *type;
0744     struct msg_echo_lb elreq;
0745     uint16_t response[MAILBOX_REGISTER_COUNT];
0746     uint16_t config[4], new_config[4];
0747     uint8_t *fw_sts_ptr;
0748     void *req_data = NULL;
0749     dma_addr_t req_data_dma;
0750     uint32_t req_data_len;
0751     uint8_t *rsp_data = NULL;
0752     dma_addr_t rsp_data_dma;
0753     uint32_t rsp_data_len;
0754 
0755     if (!vha->flags.online) {
0756         ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
0757         return -EIO;
0758     }
0759 
0760     memset(&elreq, 0, sizeof(elreq));
0761 
0762     elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
0763         bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt,
0764         DMA_TO_DEVICE);
0765 
0766     if (!elreq.req_sg_cnt) {
0767         ql_log(ql_log_warn, vha, 0x701a,
0768             "dma_map_sg returned %d for request.\n", elreq.req_sg_cnt);
0769         return -ENOMEM;
0770     }
0771 
0772     elreq.rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
0773         bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
0774         DMA_FROM_DEVICE);
0775 
0776     if (!elreq.rsp_sg_cnt) {
0777         ql_log(ql_log_warn, vha, 0x701b,
0778             "dma_map_sg returned %d for reply.\n", elreq.rsp_sg_cnt);
0779         rval = -ENOMEM;
0780         goto done_unmap_req_sg;
0781     }
0782 
0783     if ((elreq.req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
0784         (elreq.rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
0785         ql_log(ql_log_warn, vha, 0x701c,
0786             "dma mapping resulted in different sg counts, "
0787             "request_sg_cnt: %x dma_request_sg_cnt: %x "
0788             "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
0789             bsg_job->request_payload.sg_cnt, elreq.req_sg_cnt,
0790             bsg_job->reply_payload.sg_cnt, elreq.rsp_sg_cnt);
0791         rval = -EAGAIN;
0792         goto done_unmap_sg;
0793     }
0794     req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
0795     req_data = dma_alloc_coherent(&ha->pdev->dev, req_data_len,
0796         &req_data_dma, GFP_KERNEL);
0797     if (!req_data) {
0798         ql_log(ql_log_warn, vha, 0x701d,
0799             "dma alloc failed for req_data.\n");
0800         rval = -ENOMEM;
0801         goto done_unmap_sg;
0802     }
0803 
0804     rsp_data = dma_alloc_coherent(&ha->pdev->dev, rsp_data_len,
0805         &rsp_data_dma, GFP_KERNEL);
0806     if (!rsp_data) {
0807         ql_log(ql_log_warn, vha, 0x7004,
0808             "dma alloc failed for rsp_data.\n");
0809         rval = -ENOMEM;
0810         goto done_free_dma_req;
0811     }
0812 
0813     /* Copy the request buffer in req_data now */
0814     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
0815         bsg_job->request_payload.sg_cnt, req_data, req_data_len);
0816 
0817     elreq.send_dma = req_data_dma;
0818     elreq.rcv_dma = rsp_data_dma;
0819     elreq.transfer_size = req_data_len;
0820 
0821     elreq.options = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
0822     elreq.iteration_count =
0823         bsg_request->rqst_data.h_vendor.vendor_cmd[2];
0824 
0825     if (atomic_read(&vha->loop_state) == LOOP_READY &&
0826         ((ha->current_topology == ISP_CFG_F && (elreq.options & 7) >= 2) ||
0827         ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
0828         get_unaligned_le32(req_data) == ELS_OPCODE_BYTE &&
0829         req_data_len == MAX_ELS_FRAME_PAYLOAD &&
0830         elreq.options == EXTERNAL_LOOPBACK))) {
0831         type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
0832         ql_dbg(ql_dbg_user, vha, 0x701e,
0833             "BSG request type: %s.\n", type);
0834         command_sent = INT_DEF_LB_ECHO_CMD;
0835         rval = qla2x00_echo_test(vha, &elreq, response);
0836     } else {
0837         if (IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) {
0838             memset(config, 0, sizeof(config));
0839             memset(new_config, 0, sizeof(new_config));
0840 
0841             if (qla81xx_get_port_config(vha, config)) {
0842                 ql_log(ql_log_warn, vha, 0x701f,
0843                     "Get port config failed.\n");
0844                 rval = -EPERM;
0845                 goto done_free_dma_rsp;
0846             }
0847 
0848             if ((config[0] & INTERNAL_LOOPBACK_MASK) != 0) {
0849                 ql_dbg(ql_dbg_user, vha, 0x70c4,
0850                     "Loopback operation already in "
0851                     "progress.\n");
0852                 rval = -EAGAIN;
0853                 goto done_free_dma_rsp;
0854             }
0855 
0856             ql_dbg(ql_dbg_user, vha, 0x70c0,
0857                 "elreq.options=%04x\n", elreq.options);
0858 
0859             if (elreq.options == EXTERNAL_LOOPBACK)
0860                 if (IS_QLA8031(ha) || IS_QLA8044(ha))
0861                     rval = qla81xx_set_loopback_mode(vha,
0862                         config, new_config, elreq.options);
0863                 else
0864                     rval = qla81xx_reset_loopback_mode(vha,
0865                         config, 1, 0);
0866             else
0867                 rval = qla81xx_set_loopback_mode(vha, config,
0868                     new_config, elreq.options);
0869 
0870             if (rval) {
0871                 rval = -EPERM;
0872                 goto done_free_dma_rsp;
0873             }
0874 
0875             type = "FC_BSG_HST_VENDOR_LOOPBACK";
0876             ql_dbg(ql_dbg_user, vha, 0x7028,
0877                 "BSG request type: %s.\n", type);
0878 
0879             command_sent = INT_DEF_LB_LOOPBACK_CMD;
0880             rval = qla2x00_loopback_test(vha, &elreq, response);
0881 
0882             if (response[0] == MBS_COMMAND_ERROR &&
0883                     response[1] == MBS_LB_RESET) {
0884                 ql_log(ql_log_warn, vha, 0x7029,
0885                     "MBX command error, Aborting ISP.\n");
0886                 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
0887                 qla2xxx_wake_dpc(vha);
0888                 qla2x00_wait_for_chip_reset(vha);
0889                 /* Also reset the MPI */
0890                 if (IS_QLA81XX(ha)) {
0891                     if (qla81xx_restart_mpi_firmware(vha) !=
0892                         QLA_SUCCESS) {
0893                         ql_log(ql_log_warn, vha, 0x702a,
0894                             "MPI reset failed.\n");
0895                     }
0896                 }
0897 
0898                 rval = -EIO;
0899                 goto done_free_dma_rsp;
0900             }
0901 
0902             if (new_config[0]) {
0903                 int ret;
0904 
0905                 /* Revert back to original port config
0906                  * Also clear internal loopback
0907                  */
0908                 ret = qla81xx_reset_loopback_mode(vha,
0909                     new_config, 0, 1);
0910                 if (ret) {
0911                     /*
0912                      * If the reset of the loopback mode
0913                      * doesn't work take FCoE dump and then
0914                      * reset the chip.
0915                      */
0916                     qla2xxx_dump_fw(vha);
0917                     set_bit(ISP_ABORT_NEEDED,
0918                         &vha->dpc_flags);
0919                 }
0920 
0921             }
0922 
0923         } else {
0924             type = "FC_BSG_HST_VENDOR_LOOPBACK";
0925             ql_dbg(ql_dbg_user, vha, 0x702b,
0926                 "BSG request type: %s.\n", type);
0927             command_sent = INT_DEF_LB_LOOPBACK_CMD;
0928             rval = qla2x00_loopback_test(vha, &elreq, response);
0929         }
0930     }
0931 
0932     if (rval) {
0933         ql_log(ql_log_warn, vha, 0x702c,
0934             "Vendor request %s failed.\n", type);
0935 
0936         rval = 0;
0937         bsg_reply->result = (DID_ERROR << 16);
0938         bsg_reply->reply_payload_rcv_len = 0;
0939     } else {
0940         ql_dbg(ql_dbg_user, vha, 0x702d,
0941             "Vendor request %s completed.\n", type);
0942         bsg_reply->result = (DID_OK << 16);
0943         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
0944             bsg_job->reply_payload.sg_cnt, rsp_data,
0945             rsp_data_len);
0946     }
0947 
0948     bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
0949         sizeof(response) + sizeof(uint8_t);
0950     fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply);
0951     memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), response,
0952             sizeof(response));
0953     fw_sts_ptr += sizeof(response);
0954     *fw_sts_ptr = command_sent;
0955 
0956 done_free_dma_rsp:
0957     dma_free_coherent(&ha->pdev->dev, rsp_data_len,
0958         rsp_data, rsp_data_dma);
0959 done_free_dma_req:
0960     dma_free_coherent(&ha->pdev->dev, req_data_len,
0961         req_data, req_data_dma);
0962 done_unmap_sg:
0963     dma_unmap_sg(&ha->pdev->dev,
0964         bsg_job->reply_payload.sg_list,
0965         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
0966 done_unmap_req_sg:
0967     dma_unmap_sg(&ha->pdev->dev,
0968         bsg_job->request_payload.sg_list,
0969         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
0970     if (!rval)
0971         bsg_job_done(bsg_job, bsg_reply->result,
0972                    bsg_reply->reply_payload_rcv_len);
0973     return rval;
0974 }
0975 
0976 static int
0977 qla84xx_reset(struct bsg_job *bsg_job)
0978 {
0979     struct fc_bsg_request *bsg_request = bsg_job->request;
0980     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
0981     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
0982     scsi_qla_host_t *vha = shost_priv(host);
0983     struct qla_hw_data *ha = vha->hw;
0984     int rval = 0;
0985     uint32_t flag;
0986 
0987     if (!IS_QLA84XX(ha)) {
0988         ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
0989         return -EINVAL;
0990     }
0991 
0992     flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
0993 
0994     rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
0995 
0996     if (rval) {
0997         ql_log(ql_log_warn, vha, 0x7030,
0998             "Vendor request 84xx reset failed.\n");
0999         rval = (DID_ERROR << 16);
1000 
1001     } else {
1002         ql_dbg(ql_dbg_user, vha, 0x7031,
1003             "Vendor request 84xx reset completed.\n");
1004         bsg_reply->result = DID_OK;
1005         bsg_job_done(bsg_job, bsg_reply->result,
1006                    bsg_reply->reply_payload_rcv_len);
1007     }
1008 
1009     return rval;
1010 }
1011 
1012 static int
1013 qla84xx_updatefw(struct bsg_job *bsg_job)
1014 {
1015     struct fc_bsg_request *bsg_request = bsg_job->request;
1016     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1017     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1018     scsi_qla_host_t *vha = shost_priv(host);
1019     struct qla_hw_data *ha = vha->hw;
1020     struct verify_chip_entry_84xx *mn = NULL;
1021     dma_addr_t mn_dma, fw_dma;
1022     void *fw_buf = NULL;
1023     int rval = 0;
1024     uint32_t sg_cnt;
1025     uint32_t data_len;
1026     uint16_t options;
1027     uint32_t flag;
1028     uint32_t fw_ver;
1029 
1030     if (!IS_QLA84XX(ha)) {
1031         ql_dbg(ql_dbg_user, vha, 0x7032,
1032             "Not 84xx, exiting.\n");
1033         return -EINVAL;
1034     }
1035 
1036     sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1037         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1038     if (!sg_cnt) {
1039         ql_log(ql_log_warn, vha, 0x7033,
1040             "dma_map_sg returned %d for request.\n", sg_cnt);
1041         return -ENOMEM;
1042     }
1043 
1044     if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1045         ql_log(ql_log_warn, vha, 0x7034,
1046             "DMA mapping resulted in different sg counts, "
1047             "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1048             bsg_job->request_payload.sg_cnt, sg_cnt);
1049         rval = -EAGAIN;
1050         goto done_unmap_sg;
1051     }
1052 
1053     data_len = bsg_job->request_payload.payload_len;
1054     fw_buf = dma_alloc_coherent(&ha->pdev->dev, data_len,
1055         &fw_dma, GFP_KERNEL);
1056     if (!fw_buf) {
1057         ql_log(ql_log_warn, vha, 0x7035,
1058             "DMA alloc failed for fw_buf.\n");
1059         rval = -ENOMEM;
1060         goto done_unmap_sg;
1061     }
1062 
1063     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1064         bsg_job->request_payload.sg_cnt, fw_buf, data_len);
1065 
1066     mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1067     if (!mn) {
1068         ql_log(ql_log_warn, vha, 0x7036,
1069             "DMA alloc failed for fw buffer.\n");
1070         rval = -ENOMEM;
1071         goto done_free_fw_buf;
1072     }
1073 
1074     flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1075     fw_ver = get_unaligned_le32((uint32_t *)fw_buf + 2);
1076 
1077     mn->entry_type = VERIFY_CHIP_IOCB_TYPE;
1078     mn->entry_count = 1;
1079 
1080     options = VCO_FORCE_UPDATE | VCO_END_OF_DATA;
1081     if (flag == A84_ISSUE_UPDATE_DIAGFW_CMD)
1082         options |= VCO_DIAG_FW;
1083 
1084     mn->options = cpu_to_le16(options);
1085     mn->fw_ver =  cpu_to_le32(fw_ver);
1086     mn->fw_size =  cpu_to_le32(data_len);
1087     mn->fw_seq_size =  cpu_to_le32(data_len);
1088     put_unaligned_le64(fw_dma, &mn->dsd.address);
1089     mn->dsd.length = cpu_to_le32(data_len);
1090     mn->data_seg_cnt = cpu_to_le16(1);
1091 
1092     rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
1093 
1094     if (rval) {
1095         ql_log(ql_log_warn, vha, 0x7037,
1096             "Vendor request 84xx updatefw failed.\n");
1097 
1098         rval = (DID_ERROR << 16);
1099     } else {
1100         ql_dbg(ql_dbg_user, vha, 0x7038,
1101             "Vendor request 84xx updatefw completed.\n");
1102 
1103         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1104         bsg_reply->result = DID_OK;
1105     }
1106 
1107     dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1108 
1109 done_free_fw_buf:
1110     dma_free_coherent(&ha->pdev->dev, data_len, fw_buf, fw_dma);
1111 
1112 done_unmap_sg:
1113     dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1114         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1115 
1116     if (!rval)
1117         bsg_job_done(bsg_job, bsg_reply->result,
1118                    bsg_reply->reply_payload_rcv_len);
1119     return rval;
1120 }
1121 
1122 static int
1123 qla84xx_mgmt_cmd(struct bsg_job *bsg_job)
1124 {
1125     struct fc_bsg_request *bsg_request = bsg_job->request;
1126     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1127     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1128     scsi_qla_host_t *vha = shost_priv(host);
1129     struct qla_hw_data *ha = vha->hw;
1130     struct access_chip_84xx *mn = NULL;
1131     dma_addr_t mn_dma, mgmt_dma;
1132     void *mgmt_b = NULL;
1133     int rval = 0;
1134     struct qla_bsg_a84_mgmt *ql84_mgmt;
1135     uint32_t sg_cnt;
1136     uint32_t data_len = 0;
1137     uint32_t dma_direction = DMA_NONE;
1138 
1139     if (!IS_QLA84XX(ha)) {
1140         ql_log(ql_log_warn, vha, 0x703a,
1141             "Not 84xx, exiting.\n");
1142         return -EINVAL;
1143     }
1144 
1145     mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1146     if (!mn) {
1147         ql_log(ql_log_warn, vha, 0x703c,
1148             "DMA alloc failed for fw buffer.\n");
1149         return -ENOMEM;
1150     }
1151 
1152     mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
1153     mn->entry_count = 1;
1154     ql84_mgmt = (void *)bsg_request + sizeof(struct fc_bsg_request);
1155     switch (ql84_mgmt->mgmt.cmd) {
1156     case QLA84_MGMT_READ_MEM:
1157     case QLA84_MGMT_GET_INFO:
1158         sg_cnt = dma_map_sg(&ha->pdev->dev,
1159             bsg_job->reply_payload.sg_list,
1160             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1161         if (!sg_cnt) {
1162             ql_log(ql_log_warn, vha, 0x703d,
1163                 "dma_map_sg returned %d for reply.\n", sg_cnt);
1164             rval = -ENOMEM;
1165             goto exit_mgmt;
1166         }
1167 
1168         dma_direction = DMA_FROM_DEVICE;
1169 
1170         if (sg_cnt != bsg_job->reply_payload.sg_cnt) {
1171             ql_log(ql_log_warn, vha, 0x703e,
1172                 "DMA mapping resulted in different sg counts, "
1173                 "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
1174                 bsg_job->reply_payload.sg_cnt, sg_cnt);
1175             rval = -EAGAIN;
1176             goto done_unmap_sg;
1177         }
1178 
1179         data_len = bsg_job->reply_payload.payload_len;
1180 
1181         mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1182             &mgmt_dma, GFP_KERNEL);
1183         if (!mgmt_b) {
1184             ql_log(ql_log_warn, vha, 0x703f,
1185                 "DMA alloc failed for mgmt_b.\n");
1186             rval = -ENOMEM;
1187             goto done_unmap_sg;
1188         }
1189 
1190         if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) {
1191             mn->options = cpu_to_le16(ACO_DUMP_MEMORY);
1192             mn->parameter1 =
1193                 cpu_to_le32(
1194                 ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1195 
1196         } else if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO) {
1197             mn->options = cpu_to_le16(ACO_REQUEST_INFO);
1198             mn->parameter1 =
1199                 cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.info.type);
1200 
1201             mn->parameter2 =
1202                 cpu_to_le32(
1203                 ql84_mgmt->mgmt.mgmtp.u.info.context);
1204         }
1205         break;
1206 
1207     case QLA84_MGMT_WRITE_MEM:
1208         sg_cnt = dma_map_sg(&ha->pdev->dev,
1209             bsg_job->request_payload.sg_list,
1210             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1211 
1212         if (!sg_cnt) {
1213             ql_log(ql_log_warn, vha, 0x7040,
1214                 "dma_map_sg returned %d.\n", sg_cnt);
1215             rval = -ENOMEM;
1216             goto exit_mgmt;
1217         }
1218 
1219         dma_direction = DMA_TO_DEVICE;
1220 
1221         if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1222             ql_log(ql_log_warn, vha, 0x7041,
1223                 "DMA mapping resulted in different sg counts, "
1224                 "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1225                 bsg_job->request_payload.sg_cnt, sg_cnt);
1226             rval = -EAGAIN;
1227             goto done_unmap_sg;
1228         }
1229 
1230         data_len = bsg_job->request_payload.payload_len;
1231         mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1232             &mgmt_dma, GFP_KERNEL);
1233         if (!mgmt_b) {
1234             ql_log(ql_log_warn, vha, 0x7042,
1235                 "DMA alloc failed for mgmt_b.\n");
1236             rval = -ENOMEM;
1237             goto done_unmap_sg;
1238         }
1239 
1240         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1241             bsg_job->request_payload.sg_cnt, mgmt_b, data_len);
1242 
1243         mn->options = cpu_to_le16(ACO_LOAD_MEMORY);
1244         mn->parameter1 =
1245             cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1246         break;
1247 
1248     case QLA84_MGMT_CHNG_CONFIG:
1249         mn->options = cpu_to_le16(ACO_CHANGE_CONFIG_PARAM);
1250         mn->parameter1 =
1251             cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.id);
1252 
1253         mn->parameter2 =
1254             cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param0);
1255 
1256         mn->parameter3 =
1257             cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param1);
1258         break;
1259 
1260     default:
1261         rval = -EIO;
1262         goto exit_mgmt;
1263     }
1264 
1265     if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) {
1266         mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len);
1267         mn->dseg_count = cpu_to_le16(1);
1268         put_unaligned_le64(mgmt_dma, &mn->dsd.address);
1269         mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len);
1270     }
1271 
1272     rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0);
1273 
1274     if (rval) {
1275         ql_log(ql_log_warn, vha, 0x7043,
1276             "Vendor request 84xx mgmt failed.\n");
1277 
1278         rval = (DID_ERROR << 16);
1279 
1280     } else {
1281         ql_dbg(ql_dbg_user, vha, 0x7044,
1282             "Vendor request 84xx mgmt completed.\n");
1283 
1284         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1285         bsg_reply->result = DID_OK;
1286 
1287         if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) ||
1288             (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) {
1289             bsg_reply->reply_payload_rcv_len =
1290                 bsg_job->reply_payload.payload_len;
1291 
1292             sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1293                 bsg_job->reply_payload.sg_cnt, mgmt_b,
1294                 data_len);
1295         }
1296     }
1297 
1298 done_unmap_sg:
1299     if (mgmt_b)
1300         dma_free_coherent(&ha->pdev->dev, data_len, mgmt_b, mgmt_dma);
1301 
1302     if (dma_direction == DMA_TO_DEVICE)
1303         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1304             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1305     else if (dma_direction == DMA_FROM_DEVICE)
1306         dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
1307             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1308 
1309 exit_mgmt:
1310     dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1311 
1312     if (!rval)
1313         bsg_job_done(bsg_job, bsg_reply->result,
1314                    bsg_reply->reply_payload_rcv_len);
1315     return rval;
1316 }
1317 
1318 static int
1319 qla24xx_iidma(struct bsg_job *bsg_job)
1320 {
1321     struct fc_bsg_request *bsg_request = bsg_job->request;
1322     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1323     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1324     scsi_qla_host_t *vha = shost_priv(host);
1325     int rval = 0;
1326     struct qla_port_param *port_param = NULL;
1327     fc_port_t *fcport = NULL;
1328     int found = 0;
1329     uint16_t mb[MAILBOX_REGISTER_COUNT];
1330     uint8_t *rsp_ptr = NULL;
1331 
1332     if (!IS_IIDMA_CAPABLE(vha->hw)) {
1333         ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
1334         return -EINVAL;
1335     }
1336 
1337     port_param = (void *)bsg_request + sizeof(struct fc_bsg_request);
1338     if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
1339         ql_log(ql_log_warn, vha, 0x7048,
1340             "Invalid destination type.\n");
1341         return -EINVAL;
1342     }
1343 
1344     list_for_each_entry(fcport, &vha->vp_fcports, list) {
1345         if (fcport->port_type != FCT_TARGET)
1346             continue;
1347 
1348         if (memcmp(port_param->fc_scsi_addr.dest_addr.wwpn,
1349             fcport->port_name, sizeof(fcport->port_name)))
1350             continue;
1351 
1352         found = 1;
1353         break;
1354     }
1355 
1356     if (!found) {
1357         ql_log(ql_log_warn, vha, 0x7049,
1358             "Failed to find port.\n");
1359         return -EINVAL;
1360     }
1361 
1362     if (atomic_read(&fcport->state) != FCS_ONLINE) {
1363         ql_log(ql_log_warn, vha, 0x704a,
1364             "Port is not online.\n");
1365         return -EINVAL;
1366     }
1367 
1368     if (fcport->flags & FCF_LOGIN_NEEDED) {
1369         ql_log(ql_log_warn, vha, 0x704b,
1370             "Remote port not logged in flags = 0x%x.\n", fcport->flags);
1371         return -EINVAL;
1372     }
1373 
1374     if (port_param->mode)
1375         rval = qla2x00_set_idma_speed(vha, fcport->loop_id,
1376             port_param->speed, mb);
1377     else
1378         rval = qla2x00_get_idma_speed(vha, fcport->loop_id,
1379             &port_param->speed, mb);
1380 
1381     if (rval) {
1382         ql_log(ql_log_warn, vha, 0x704c,
1383             "iiDMA cmd failed for %8phN -- "
1384             "%04x %x %04x %04x.\n", fcport->port_name,
1385             rval, fcport->fp_speed, mb[0], mb[1]);
1386         rval = (DID_ERROR << 16);
1387     } else {
1388         if (!port_param->mode) {
1389             bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
1390                 sizeof(struct qla_port_param);
1391 
1392             rsp_ptr = ((uint8_t *)bsg_reply) +
1393                 sizeof(struct fc_bsg_reply);
1394 
1395             memcpy(rsp_ptr, port_param,
1396                 sizeof(struct qla_port_param));
1397         }
1398 
1399         bsg_reply->result = DID_OK;
1400         bsg_job_done(bsg_job, bsg_reply->result,
1401                    bsg_reply->reply_payload_rcv_len);
1402     }
1403 
1404     return rval;
1405 }
1406 
1407 static int
1408 qla2x00_optrom_setup(struct bsg_job *bsg_job, scsi_qla_host_t *vha,
1409     uint8_t is_update)
1410 {
1411     struct fc_bsg_request *bsg_request = bsg_job->request;
1412     uint32_t start = 0;
1413     int valid = 0;
1414     struct qla_hw_data *ha = vha->hw;
1415 
1416     if (unlikely(pci_channel_offline(ha->pdev)))
1417         return -EINVAL;
1418 
1419     start = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1420     if (start > ha->optrom_size) {
1421         ql_log(ql_log_warn, vha, 0x7055,
1422             "start %d > optrom_size %d.\n", start, ha->optrom_size);
1423         return -EINVAL;
1424     }
1425 
1426     if (ha->optrom_state != QLA_SWAITING) {
1427         ql_log(ql_log_info, vha, 0x7056,
1428             "optrom_state %d.\n", ha->optrom_state);
1429         return -EBUSY;
1430     }
1431 
1432     ha->optrom_region_start = start;
1433     ql_dbg(ql_dbg_user, vha, 0x7057, "is_update=%d.\n", is_update);
1434     if (is_update) {
1435         if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
1436             valid = 1;
1437         else if (start == (ha->flt_region_boot * 4) ||
1438             start == (ha->flt_region_fw * 4))
1439             valid = 1;
1440         else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
1441             IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) ||
1442             IS_QLA28XX(ha))
1443             valid = 1;
1444         if (!valid) {
1445             ql_log(ql_log_warn, vha, 0x7058,
1446                 "Invalid start region 0x%x/0x%x.\n", start,
1447                 bsg_job->request_payload.payload_len);
1448             return -EINVAL;
1449         }
1450 
1451         ha->optrom_region_size = start +
1452             bsg_job->request_payload.payload_len > ha->optrom_size ?
1453             ha->optrom_size - start :
1454             bsg_job->request_payload.payload_len;
1455         ha->optrom_state = QLA_SWRITING;
1456     } else {
1457         ha->optrom_region_size = start +
1458             bsg_job->reply_payload.payload_len > ha->optrom_size ?
1459             ha->optrom_size - start :
1460             bsg_job->reply_payload.payload_len;
1461         ha->optrom_state = QLA_SREADING;
1462     }
1463 
1464     ha->optrom_buffer = vzalloc(ha->optrom_region_size);
1465     if (!ha->optrom_buffer) {
1466         ql_log(ql_log_warn, vha, 0x7059,
1467             "Read: Unable to allocate memory for optrom retrieval "
1468             "(%x)\n", ha->optrom_region_size);
1469 
1470         ha->optrom_state = QLA_SWAITING;
1471         return -ENOMEM;
1472     }
1473 
1474     return 0;
1475 }
1476 
1477 static int
1478 qla2x00_read_optrom(struct bsg_job *bsg_job)
1479 {
1480     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1481     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1482     scsi_qla_host_t *vha = shost_priv(host);
1483     struct qla_hw_data *ha = vha->hw;
1484     int rval = 0;
1485 
1486     if (ha->flags.nic_core_reset_hdlr_active)
1487         return -EBUSY;
1488 
1489     mutex_lock(&ha->optrom_mutex);
1490     rval = qla2x00_optrom_setup(bsg_job, vha, 0);
1491     if (rval) {
1492         mutex_unlock(&ha->optrom_mutex);
1493         return rval;
1494     }
1495 
1496     ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
1497         ha->optrom_region_start, ha->optrom_region_size);
1498 
1499     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1500         bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
1501         ha->optrom_region_size);
1502 
1503     bsg_reply->reply_payload_rcv_len = ha->optrom_region_size;
1504     bsg_reply->result = DID_OK;
1505     vfree(ha->optrom_buffer);
1506     ha->optrom_buffer = NULL;
1507     ha->optrom_state = QLA_SWAITING;
1508     mutex_unlock(&ha->optrom_mutex);
1509     bsg_job_done(bsg_job, bsg_reply->result,
1510                bsg_reply->reply_payload_rcv_len);
1511     return rval;
1512 }
1513 
1514 static int
1515 qla2x00_update_optrom(struct bsg_job *bsg_job)
1516 {
1517     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1518     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1519     scsi_qla_host_t *vha = shost_priv(host);
1520     struct qla_hw_data *ha = vha->hw;
1521     int rval = 0;
1522 
1523     mutex_lock(&ha->optrom_mutex);
1524     rval = qla2x00_optrom_setup(bsg_job, vha, 1);
1525     if (rval) {
1526         mutex_unlock(&ha->optrom_mutex);
1527         return rval;
1528     }
1529 
1530     /* Set the isp82xx_no_md_cap not to capture minidump */
1531     ha->flags.isp82xx_no_md_cap = 1;
1532 
1533     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1534         bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
1535         ha->optrom_region_size);
1536 
1537     rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
1538         ha->optrom_region_start, ha->optrom_region_size);
1539 
1540     if (rval) {
1541         bsg_reply->result = -EINVAL;
1542         rval = -EINVAL;
1543     } else {
1544         bsg_reply->result = DID_OK;
1545     }
1546     vfree(ha->optrom_buffer);
1547     ha->optrom_buffer = NULL;
1548     ha->optrom_state = QLA_SWAITING;
1549     mutex_unlock(&ha->optrom_mutex);
1550     bsg_job_done(bsg_job, bsg_reply->result,
1551                bsg_reply->reply_payload_rcv_len);
1552     return rval;
1553 }
1554 
1555 static int
1556 qla2x00_update_fru_versions(struct bsg_job *bsg_job)
1557 {
1558     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1559     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1560     scsi_qla_host_t *vha = shost_priv(host);
1561     struct qla_hw_data *ha = vha->hw;
1562     int rval = 0;
1563     uint8_t bsg[DMA_POOL_SIZE];
1564     struct qla_image_version_list *list = (void *)bsg;
1565     struct qla_image_version *image;
1566     uint32_t count;
1567     dma_addr_t sfp_dma;
1568     void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1569 
1570     if (!sfp) {
1571         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1572             EXT_STATUS_NO_MEMORY;
1573         goto done;
1574     }
1575 
1576     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1577         bsg_job->request_payload.sg_cnt, list, sizeof(bsg));
1578 
1579     image = list->version;
1580     count = list->count;
1581     while (count--) {
1582         memcpy(sfp, &image->field_info, sizeof(image->field_info));
1583         rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1584             image->field_address.device, image->field_address.offset,
1585             sizeof(image->field_info), image->field_address.option);
1586         if (rval) {
1587             bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1588                 EXT_STATUS_MAILBOX;
1589             goto dealloc;
1590         }
1591         image++;
1592     }
1593 
1594     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1595 
1596 dealloc:
1597     dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1598 
1599 done:
1600     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1601     bsg_reply->result = DID_OK << 16;
1602     bsg_job_done(bsg_job, bsg_reply->result,
1603                bsg_reply->reply_payload_rcv_len);
1604 
1605     return 0;
1606 }
1607 
1608 static int
1609 qla2x00_read_fru_status(struct bsg_job *bsg_job)
1610 {
1611     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1612     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1613     scsi_qla_host_t *vha = shost_priv(host);
1614     struct qla_hw_data *ha = vha->hw;
1615     int rval = 0;
1616     uint8_t bsg[DMA_POOL_SIZE];
1617     struct qla_status_reg *sr = (void *)bsg;
1618     dma_addr_t sfp_dma;
1619     uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1620 
1621     if (!sfp) {
1622         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1623             EXT_STATUS_NO_MEMORY;
1624         goto done;
1625     }
1626 
1627     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1628         bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1629 
1630     rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1631         sr->field_address.device, sr->field_address.offset,
1632         sizeof(sr->status_reg), sr->field_address.option);
1633     sr->status_reg = *sfp;
1634 
1635     if (rval) {
1636         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1637             EXT_STATUS_MAILBOX;
1638         goto dealloc;
1639     }
1640 
1641     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1642         bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));
1643 
1644     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1645 
1646 dealloc:
1647     dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1648 
1649 done:
1650     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1651     bsg_reply->reply_payload_rcv_len = sizeof(*sr);
1652     bsg_reply->result = DID_OK << 16;
1653     bsg_job_done(bsg_job, bsg_reply->result,
1654                bsg_reply->reply_payload_rcv_len);
1655 
1656     return 0;
1657 }
1658 
1659 static int
1660 qla2x00_write_fru_status(struct bsg_job *bsg_job)
1661 {
1662     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1663     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1664     scsi_qla_host_t *vha = shost_priv(host);
1665     struct qla_hw_data *ha = vha->hw;
1666     int rval = 0;
1667     uint8_t bsg[DMA_POOL_SIZE];
1668     struct qla_status_reg *sr = (void *)bsg;
1669     dma_addr_t sfp_dma;
1670     uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1671 
1672     if (!sfp) {
1673         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1674             EXT_STATUS_NO_MEMORY;
1675         goto done;
1676     }
1677 
1678     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1679         bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1680 
1681     *sfp = sr->status_reg;
1682     rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1683         sr->field_address.device, sr->field_address.offset,
1684         sizeof(sr->status_reg), sr->field_address.option);
1685 
1686     if (rval) {
1687         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1688             EXT_STATUS_MAILBOX;
1689         goto dealloc;
1690     }
1691 
1692     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1693 
1694 dealloc:
1695     dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1696 
1697 done:
1698     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1699     bsg_reply->result = DID_OK << 16;
1700     bsg_job_done(bsg_job, bsg_reply->result,
1701                bsg_reply->reply_payload_rcv_len);
1702 
1703     return 0;
1704 }
1705 
1706 static int
1707 qla2x00_write_i2c(struct bsg_job *bsg_job)
1708 {
1709     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1710     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1711     scsi_qla_host_t *vha = shost_priv(host);
1712     struct qla_hw_data *ha = vha->hw;
1713     int rval = 0;
1714     uint8_t bsg[DMA_POOL_SIZE];
1715     struct qla_i2c_access *i2c = (void *)bsg;
1716     dma_addr_t sfp_dma;
1717     uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1718 
1719     if (!sfp) {
1720         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1721             EXT_STATUS_NO_MEMORY;
1722         goto done;
1723     }
1724 
1725     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1726         bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1727 
1728     memcpy(sfp, i2c->buffer, i2c->length);
1729     rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1730         i2c->device, i2c->offset, i2c->length, i2c->option);
1731 
1732     if (rval) {
1733         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1734             EXT_STATUS_MAILBOX;
1735         goto dealloc;
1736     }
1737 
1738     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1739 
1740 dealloc:
1741     dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1742 
1743 done:
1744     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1745     bsg_reply->result = DID_OK << 16;
1746     bsg_job_done(bsg_job, bsg_reply->result,
1747                bsg_reply->reply_payload_rcv_len);
1748 
1749     return 0;
1750 }
1751 
1752 static int
1753 qla2x00_read_i2c(struct bsg_job *bsg_job)
1754 {
1755     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1756     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1757     scsi_qla_host_t *vha = shost_priv(host);
1758     struct qla_hw_data *ha = vha->hw;
1759     int rval = 0;
1760     uint8_t bsg[DMA_POOL_SIZE];
1761     struct qla_i2c_access *i2c = (void *)bsg;
1762     dma_addr_t sfp_dma;
1763     uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1764 
1765     if (!sfp) {
1766         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1767             EXT_STATUS_NO_MEMORY;
1768         goto done;
1769     }
1770 
1771     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1772         bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1773 
1774     rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1775         i2c->device, i2c->offset, i2c->length, i2c->option);
1776 
1777     if (rval) {
1778         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1779             EXT_STATUS_MAILBOX;
1780         goto dealloc;
1781     }
1782 
1783     memcpy(i2c->buffer, sfp, i2c->length);
1784     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1785         bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));
1786 
1787     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1788 
1789 dealloc:
1790     dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1791 
1792 done:
1793     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1794     bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
1795     bsg_reply->result = DID_OK << 16;
1796     bsg_job_done(bsg_job, bsg_reply->result,
1797                bsg_reply->reply_payload_rcv_len);
1798 
1799     return 0;
1800 }
1801 
1802 static int
1803 qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
1804 {
1805     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1806     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1807     scsi_qla_host_t *vha = shost_priv(host);
1808     struct qla_hw_data *ha = vha->hw;
1809     uint32_t rval = EXT_STATUS_OK;
1810     uint16_t req_sg_cnt = 0;
1811     uint16_t rsp_sg_cnt = 0;
1812     uint16_t nextlid = 0;
1813     uint32_t tot_dsds;
1814     srb_t *sp = NULL;
1815     uint32_t req_data_len;
1816     uint32_t rsp_data_len;
1817 
1818     /* Check the type of the adapter */
1819     if (!IS_BIDI_CAPABLE(ha)) {
1820         ql_log(ql_log_warn, vha, 0x70a0,
1821             "This adapter is not supported\n");
1822         rval = EXT_STATUS_NOT_SUPPORTED;
1823         goto done;
1824     }
1825 
1826     if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1827         test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1828         test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1829         rval =  EXT_STATUS_BUSY;
1830         goto done;
1831     }
1832 
1833     /* Check if host is online */
1834     if (!vha->flags.online) {
1835         ql_log(ql_log_warn, vha, 0x70a1,
1836             "Host is not online\n");
1837         rval = EXT_STATUS_DEVICE_OFFLINE;
1838         goto done;
1839     }
1840 
1841     /* Check if cable is plugged in or not */
1842     if (vha->device_flags & DFLG_NO_CABLE) {
1843         ql_log(ql_log_warn, vha, 0x70a2,
1844             "Cable is unplugged...\n");
1845         rval = EXT_STATUS_INVALID_CFG;
1846         goto done;
1847     }
1848 
1849     /* Check if the switch is connected or not */
1850     if (ha->current_topology != ISP_CFG_F) {
1851         ql_log(ql_log_warn, vha, 0x70a3,
1852             "Host is not connected to the switch\n");
1853         rval = EXT_STATUS_INVALID_CFG;
1854         goto done;
1855     }
1856 
1857     /* Check if operating mode is P2P */
1858     if (ha->operating_mode != P2P) {
1859         ql_log(ql_log_warn, vha, 0x70a4,
1860             "Host operating mode is not P2p\n");
1861         rval = EXT_STATUS_INVALID_CFG;
1862         goto done;
1863     }
1864 
1865     mutex_lock(&ha->selflogin_lock);
1866     if (vha->self_login_loop_id == 0) {
1867         /* Initialize all required  fields of fcport */
1868         vha->bidir_fcport.vha = vha;
1869         vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
1870         vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
1871         vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
1872         vha->bidir_fcport.loop_id = vha->loop_id;
1873 
1874         if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
1875             ql_log(ql_log_warn, vha, 0x70a7,
1876                 "Failed to login port %06X for bidirectional IOCB\n",
1877                 vha->bidir_fcport.d_id.b24);
1878             mutex_unlock(&ha->selflogin_lock);
1879             rval = EXT_STATUS_MAILBOX;
1880             goto done;
1881         }
1882         vha->self_login_loop_id = nextlid - 1;
1883 
1884     }
1885     /* Assign the self login loop id to fcport */
1886     mutex_unlock(&ha->selflogin_lock);
1887 
1888     vha->bidir_fcport.loop_id = vha->self_login_loop_id;
1889 
1890     req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1891         bsg_job->request_payload.sg_list,
1892         bsg_job->request_payload.sg_cnt,
1893         DMA_TO_DEVICE);
1894 
1895     if (!req_sg_cnt) {
1896         rval = EXT_STATUS_NO_MEMORY;
1897         goto done;
1898     }
1899 
1900     rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
1901         bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
1902         DMA_FROM_DEVICE);
1903 
1904     if (!rsp_sg_cnt) {
1905         rval = EXT_STATUS_NO_MEMORY;
1906         goto done_unmap_req_sg;
1907     }
1908 
1909     if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
1910         (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
1911         ql_dbg(ql_dbg_user, vha, 0x70a9,
1912             "Dma mapping resulted in different sg counts "
1913             "[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
1914             "%x dma_reply_sg_cnt: %x]\n",
1915             bsg_job->request_payload.sg_cnt, req_sg_cnt,
1916             bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
1917         rval = EXT_STATUS_NO_MEMORY;
1918         goto done_unmap_sg;
1919     }
1920 
1921     req_data_len = bsg_job->request_payload.payload_len;
1922     rsp_data_len = bsg_job->reply_payload.payload_len;
1923 
1924     if (req_data_len != rsp_data_len) {
1925         rval = EXT_STATUS_BUSY;
1926         ql_log(ql_log_warn, vha, 0x70aa,
1927             "req_data_len != rsp_data_len\n");
1928         goto done_unmap_sg;
1929     }
1930 
1931     /* Alloc SRB structure */
1932     sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
1933     if (!sp) {
1934         ql_dbg(ql_dbg_user, vha, 0x70ac,
1935             "Alloc SRB structure failed\n");
1936         rval = EXT_STATUS_NO_MEMORY;
1937         goto done_unmap_sg;
1938     }
1939 
1940     /*Populate srb->ctx with bidir ctx*/
1941     sp->u.bsg_job = bsg_job;
1942     sp->free = qla2x00_bsg_sp_free;
1943     sp->type = SRB_BIDI_CMD;
1944     sp->done = qla2x00_bsg_job_done;
1945 
1946     /* Add the read and write sg count */
1947     tot_dsds = rsp_sg_cnt + req_sg_cnt;
1948 
1949     rval = qla2x00_start_bidir(sp, vha, tot_dsds);
1950     if (rval != EXT_STATUS_OK)
1951         goto done_free_srb;
1952     /* the bsg request  will be completed in the interrupt handler */
1953     return rval;
1954 
1955 done_free_srb:
1956     mempool_free(sp, ha->srb_mempool);
1957 done_unmap_sg:
1958     dma_unmap_sg(&ha->pdev->dev,
1959         bsg_job->reply_payload.sg_list,
1960         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1961 done_unmap_req_sg:
1962     dma_unmap_sg(&ha->pdev->dev,
1963         bsg_job->request_payload.sg_list,
1964         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1965 done:
1966 
1967     /* Return an error vendor specific response
1968      * and complete the bsg request
1969      */
1970     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
1971     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1972     bsg_reply->reply_payload_rcv_len = 0;
1973     bsg_reply->result = (DID_OK) << 16;
1974     bsg_job_done(bsg_job, bsg_reply->result,
1975                bsg_reply->reply_payload_rcv_len);
1976     /* Always return success, vendor rsp carries correct status */
1977     return 0;
1978 }
1979 
1980 static int
1981 qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
1982 {
1983     struct fc_bsg_request *bsg_request = bsg_job->request;
1984     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1985     scsi_qla_host_t *vha = shost_priv(host);
1986     struct qla_hw_data *ha = vha->hw;
1987     int rval = (DID_ERROR << 16);
1988     struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
1989     srb_t *sp;
1990     int req_sg_cnt = 0, rsp_sg_cnt = 0;
1991     struct fc_port *fcport;
1992     char  *type = "FC_BSG_HST_FX_MGMT";
1993 
1994     /* Copy the IOCB specific information */
1995     piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
1996         &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1997 
1998     /* Dump the vendor information */
1999     ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf,
2000         piocb_rqst, sizeof(*piocb_rqst));
2001 
2002     if (!vha->flags.online) {
2003         ql_log(ql_log_warn, vha, 0x70d0,
2004             "Host is not online.\n");
2005         rval = -EIO;
2006         goto done;
2007     }
2008 
2009     if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID) {
2010         req_sg_cnt = dma_map_sg(&ha->pdev->dev,
2011             bsg_job->request_payload.sg_list,
2012             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
2013         if (!req_sg_cnt) {
2014             ql_log(ql_log_warn, vha, 0x70c7,
2015                 "dma_map_sg return %d for request\n", req_sg_cnt);
2016             rval = -ENOMEM;
2017             goto done;
2018         }
2019     }
2020 
2021     if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) {
2022         rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
2023             bsg_job->reply_payload.sg_list,
2024             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2025         if (!rsp_sg_cnt) {
2026             ql_log(ql_log_warn, vha, 0x70c8,
2027                 "dma_map_sg return %d for reply\n", rsp_sg_cnt);
2028             rval = -ENOMEM;
2029             goto done_unmap_req_sg;
2030         }
2031     }
2032 
2033     ql_dbg(ql_dbg_user, vha, 0x70c9,
2034         "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
2035         "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
2036         req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
2037 
2038     /* Allocate a dummy fcport structure, since functions preparing the
2039      * IOCB and mailbox command retrieves port specific information
2040      * from fcport structure. For Host based ELS commands there will be
2041      * no fcport structure allocated
2042      */
2043     fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
2044     if (!fcport) {
2045         ql_log(ql_log_warn, vha, 0x70ca,
2046             "Failed to allocate fcport.\n");
2047         rval = -ENOMEM;
2048         goto done_unmap_rsp_sg;
2049     }
2050 
2051     /* Alloc SRB structure */
2052     sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
2053     if (!sp) {
2054         ql_log(ql_log_warn, vha, 0x70cb,
2055             "qla2x00_get_sp failed.\n");
2056         rval = -ENOMEM;
2057         goto done_free_fcport;
2058     }
2059 
2060     /* Initialize all required  fields of fcport */
2061     fcport->vha = vha;
2062     fcport->loop_id = le32_to_cpu(piocb_rqst->dataword);
2063 
2064     sp->type = SRB_FXIOCB_BCMD;
2065     sp->name = "bsg_fx_mgmt";
2066     sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
2067     sp->u.bsg_job = bsg_job;
2068     sp->free = qla2x00_bsg_sp_free;
2069     sp->done = qla2x00_bsg_job_done;
2070 
2071     ql_dbg(ql_dbg_user, vha, 0x70cc,
2072         "bsg rqst type: %s fx_mgmt_type: %x id=%x\n",
2073         type, piocb_rqst->func_type, fcport->loop_id);
2074 
2075     rval = qla2x00_start_sp(sp);
2076     if (rval != QLA_SUCCESS) {
2077         ql_log(ql_log_warn, vha, 0x70cd,
2078             "qla2x00_start_sp failed=%d.\n", rval);
2079         mempool_free(sp, ha->srb_mempool);
2080         rval = -EIO;
2081         goto done_free_fcport;
2082     }
2083     return rval;
2084 
2085 done_free_fcport:
2086     qla2x00_free_fcport(fcport);
2087 
2088 done_unmap_rsp_sg:
2089     if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
2090         dma_unmap_sg(&ha->pdev->dev,
2091             bsg_job->reply_payload.sg_list,
2092             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2093 done_unmap_req_sg:
2094     if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
2095         dma_unmap_sg(&ha->pdev->dev,
2096             bsg_job->request_payload.sg_list,
2097             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
2098 
2099 done:
2100     return rval;
2101 }
2102 
2103 static int
2104 qla26xx_serdes_op(struct bsg_job *bsg_job)
2105 {
2106     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2107     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2108     scsi_qla_host_t *vha = shost_priv(host);
2109     int rval = 0;
2110     struct qla_serdes_reg sr;
2111 
2112     memset(&sr, 0, sizeof(sr));
2113 
2114     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2115         bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2116 
2117     switch (sr.cmd) {
2118     case INT_SC_SERDES_WRITE_REG:
2119         rval = qla2x00_write_serdes_word(vha, sr.addr, sr.val);
2120         bsg_reply->reply_payload_rcv_len = 0;
2121         break;
2122     case INT_SC_SERDES_READ_REG:
2123         rval = qla2x00_read_serdes_word(vha, sr.addr, &sr.val);
2124         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2125             bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2126         bsg_reply->reply_payload_rcv_len = sizeof(sr);
2127         break;
2128     default:
2129         ql_dbg(ql_dbg_user, vha, 0x708c,
2130             "Unknown serdes cmd %x.\n", sr.cmd);
2131         rval = -EINVAL;
2132         break;
2133     }
2134 
2135     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2136         rval ? EXT_STATUS_MAILBOX : 0;
2137 
2138     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2139     bsg_reply->result = DID_OK << 16;
2140     bsg_job_done(bsg_job, bsg_reply->result,
2141                bsg_reply->reply_payload_rcv_len);
2142     return 0;
2143 }
2144 
2145 static int
2146 qla8044_serdes_op(struct bsg_job *bsg_job)
2147 {
2148     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2149     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2150     scsi_qla_host_t *vha = shost_priv(host);
2151     int rval = 0;
2152     struct qla_serdes_reg_ex sr;
2153 
2154     memset(&sr, 0, sizeof(sr));
2155 
2156     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2157         bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2158 
2159     switch (sr.cmd) {
2160     case INT_SC_SERDES_WRITE_REG:
2161         rval = qla8044_write_serdes_word(vha, sr.addr, sr.val);
2162         bsg_reply->reply_payload_rcv_len = 0;
2163         break;
2164     case INT_SC_SERDES_READ_REG:
2165         rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val);
2166         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2167             bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2168         bsg_reply->reply_payload_rcv_len = sizeof(sr);
2169         break;
2170     default:
2171         ql_dbg(ql_dbg_user, vha, 0x7020,
2172             "Unknown serdes cmd %x.\n", sr.cmd);
2173         rval = -EINVAL;
2174         break;
2175     }
2176 
2177     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2178         rval ? EXT_STATUS_MAILBOX : 0;
2179 
2180     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2181     bsg_reply->result = DID_OK << 16;
2182     bsg_job_done(bsg_job, bsg_reply->result,
2183                bsg_reply->reply_payload_rcv_len);
2184     return 0;
2185 }
2186 
2187 static int
2188 qla27xx_get_flash_upd_cap(struct bsg_job *bsg_job)
2189 {
2190     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2191     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2192     scsi_qla_host_t *vha = shost_priv(host);
2193     struct qla_hw_data *ha = vha->hw;
2194     struct qla_flash_update_caps cap;
2195 
2196     if (!(IS_QLA27XX(ha)) && !IS_QLA28XX(ha))
2197         return -EPERM;
2198 
2199     memset(&cap, 0, sizeof(cap));
2200     cap.capabilities = (uint64_t)ha->fw_attributes_ext[1] << 48 |
2201                (uint64_t)ha->fw_attributes_ext[0] << 32 |
2202                (uint64_t)ha->fw_attributes_h << 16 |
2203                (uint64_t)ha->fw_attributes;
2204 
2205     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2206         bsg_job->reply_payload.sg_cnt, &cap, sizeof(cap));
2207     bsg_reply->reply_payload_rcv_len = sizeof(cap);
2208 
2209     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2210         EXT_STATUS_OK;
2211 
2212     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2213     bsg_reply->result = DID_OK << 16;
2214     bsg_job_done(bsg_job, bsg_reply->result,
2215                bsg_reply->reply_payload_rcv_len);
2216     return 0;
2217 }
2218 
2219 static int
2220 qla27xx_set_flash_upd_cap(struct bsg_job *bsg_job)
2221 {
2222     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2223     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2224     scsi_qla_host_t *vha = shost_priv(host);
2225     struct qla_hw_data *ha = vha->hw;
2226     uint64_t online_fw_attr = 0;
2227     struct qla_flash_update_caps cap;
2228 
2229     if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
2230         return -EPERM;
2231 
2232     memset(&cap, 0, sizeof(cap));
2233     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2234         bsg_job->request_payload.sg_cnt, &cap, sizeof(cap));
2235 
2236     online_fw_attr = (uint64_t)ha->fw_attributes_ext[1] << 48 |
2237              (uint64_t)ha->fw_attributes_ext[0] << 32 |
2238              (uint64_t)ha->fw_attributes_h << 16 |
2239              (uint64_t)ha->fw_attributes;
2240 
2241     if (online_fw_attr != cap.capabilities) {
2242         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2243             EXT_STATUS_INVALID_PARAM;
2244         return -EINVAL;
2245     }
2246 
2247     if (cap.outage_duration < MAX_LOOP_TIMEOUT)  {
2248         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2249             EXT_STATUS_INVALID_PARAM;
2250         return -EINVAL;
2251     }
2252 
2253     bsg_reply->reply_payload_rcv_len = 0;
2254 
2255     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2256         EXT_STATUS_OK;
2257 
2258     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2259     bsg_reply->result = DID_OK << 16;
2260     bsg_job_done(bsg_job, bsg_reply->result,
2261                bsg_reply->reply_payload_rcv_len);
2262     return 0;
2263 }
2264 
2265 static int
2266 qla27xx_get_bbcr_data(struct bsg_job *bsg_job)
2267 {
2268     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2269     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2270     scsi_qla_host_t *vha = shost_priv(host);
2271     struct qla_hw_data *ha = vha->hw;
2272     struct qla_bbcr_data bbcr;
2273     uint16_t loop_id, topo, sw_cap;
2274     uint8_t domain, area, al_pa, state;
2275     int rval;
2276 
2277     if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
2278         return -EPERM;
2279 
2280     memset(&bbcr, 0, sizeof(bbcr));
2281 
2282     if (vha->flags.bbcr_enable)
2283         bbcr.status = QLA_BBCR_STATUS_ENABLED;
2284     else
2285         bbcr.status = QLA_BBCR_STATUS_DISABLED;
2286 
2287     if (bbcr.status == QLA_BBCR_STATUS_ENABLED) {
2288         rval = qla2x00_get_adapter_id(vha, &loop_id, &al_pa,
2289             &area, &domain, &topo, &sw_cap);
2290         if (rval != QLA_SUCCESS) {
2291             bbcr.status = QLA_BBCR_STATUS_UNKNOWN;
2292             bbcr.state = QLA_BBCR_STATE_OFFLINE;
2293             bbcr.mbx1 = loop_id;
2294             goto done;
2295         }
2296 
2297         state = (vha->bbcr >> 12) & 0x1;
2298 
2299         if (state) {
2300             bbcr.state = QLA_BBCR_STATE_OFFLINE;
2301             bbcr.offline_reason_code = QLA_BBCR_REASON_LOGIN_REJECT;
2302         } else {
2303             bbcr.state = QLA_BBCR_STATE_ONLINE;
2304             bbcr.negotiated_bbscn = (vha->bbcr >> 8) & 0xf;
2305         }
2306 
2307         bbcr.configured_bbscn = vha->bbcr & 0xf;
2308     }
2309 
2310 done:
2311     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2312         bsg_job->reply_payload.sg_cnt, &bbcr, sizeof(bbcr));
2313     bsg_reply->reply_payload_rcv_len = sizeof(bbcr);
2314 
2315     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2316 
2317     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2318     bsg_reply->result = DID_OK << 16;
2319     bsg_job_done(bsg_job, bsg_reply->result,
2320                bsg_reply->reply_payload_rcv_len);
2321     return 0;
2322 }
2323 
2324 static int
2325 qla2x00_get_priv_stats(struct bsg_job *bsg_job)
2326 {
2327     struct fc_bsg_request *bsg_request = bsg_job->request;
2328     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2329     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2330     scsi_qla_host_t *vha = shost_priv(host);
2331     struct qla_hw_data *ha = vha->hw;
2332     struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
2333     struct link_statistics *stats = NULL;
2334     dma_addr_t stats_dma;
2335     int rval;
2336     uint32_t *cmd = bsg_request->rqst_data.h_vendor.vendor_cmd;
2337     uint options = cmd[0] == QL_VND_GET_PRIV_STATS_EX ? cmd[1] : 0;
2338 
2339     if (test_bit(UNLOADING, &vha->dpc_flags))
2340         return -ENODEV;
2341 
2342     if (unlikely(pci_channel_offline(ha->pdev)))
2343         return -ENODEV;
2344 
2345     if (qla2x00_reset_active(vha))
2346         return -EBUSY;
2347 
2348     if (!IS_FWI2_CAPABLE(ha))
2349         return -EPERM;
2350 
2351     stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma,
2352                    GFP_KERNEL);
2353     if (!stats) {
2354         ql_log(ql_log_warn, vha, 0x70e2,
2355             "Failed to allocate memory for stats.\n");
2356         return -ENOMEM;
2357     }
2358 
2359     rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options);
2360 
2361     if (rval == QLA_SUCCESS) {
2362         ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e5,
2363             stats, sizeof(*stats));
2364         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2365             bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats));
2366     }
2367 
2368     bsg_reply->reply_payload_rcv_len = sizeof(*stats);
2369     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2370         rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
2371 
2372     bsg_job->reply_len = sizeof(*bsg_reply);
2373     bsg_reply->result = DID_OK << 16;
2374     bsg_job_done(bsg_job, bsg_reply->result,
2375                bsg_reply->reply_payload_rcv_len);
2376 
2377     dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
2378         stats, stats_dma);
2379 
2380     return 0;
2381 }
2382 
2383 static int
2384 qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
2385 {
2386     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2387     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2388     scsi_qla_host_t *vha = shost_priv(host);
2389     int rval;
2390     struct qla_dport_diag *dd;
2391 
2392     if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
2393         !IS_QLA28XX(vha->hw))
2394         return -EPERM;
2395 
2396     dd = kmalloc(sizeof(*dd), GFP_KERNEL);
2397     if (!dd) {
2398         ql_log(ql_log_warn, vha, 0x70db,
2399             "Failed to allocate memory for dport.\n");
2400         return -ENOMEM;
2401     }
2402 
2403     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2404         bsg_job->request_payload.sg_cnt, dd, sizeof(*dd));
2405 
2406     rval = qla26xx_dport_diagnostics(
2407         vha, dd->buf, sizeof(dd->buf), dd->options);
2408     if (rval == QLA_SUCCESS) {
2409         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2410             bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
2411     }
2412 
2413     bsg_reply->reply_payload_rcv_len = sizeof(*dd);
2414     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2415         rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
2416 
2417     bsg_job->reply_len = sizeof(*bsg_reply);
2418     bsg_reply->result = DID_OK << 16;
2419     bsg_job_done(bsg_job, bsg_reply->result,
2420                bsg_reply->reply_payload_rcv_len);
2421 
2422     kfree(dd);
2423 
2424     return 0;
2425 }
2426 
2427 static int
2428 qla2x00_do_dport_diagnostics_v2(struct bsg_job *bsg_job)
2429 {
2430     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2431     struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2432     scsi_qla_host_t *vha = shost_priv(host);
2433     int rval;
2434     struct qla_dport_diag_v2 *dd;
2435     mbx_cmd_t mc;
2436     mbx_cmd_t *mcp = &mc;
2437     uint16_t options;
2438 
2439     if (!IS_DPORT_CAPABLE(vha->hw))
2440         return -EPERM;
2441 
2442     dd = kzalloc(sizeof(*dd), GFP_KERNEL);
2443     if (!dd)
2444         return -ENOMEM;
2445 
2446     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2447             bsg_job->request_payload.sg_cnt, dd, sizeof(*dd));
2448 
2449     options  = dd->options;
2450 
2451     /*  Check dport Test in progress */
2452     if (options == QLA_GET_DPORT_RESULT_V2 &&
2453         vha->dport_status & DPORT_DIAG_IN_PROGRESS) {
2454         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2455                     EXT_STATUS_DPORT_DIAG_IN_PROCESS;
2456         goto dportcomplete;
2457     }
2458 
2459     /*  Check chip reset in progress and start/restart requests arrive */
2460     if (vha->dport_status & DPORT_DIAG_CHIP_RESET_IN_PROGRESS &&
2461         (options == QLA_START_DPORT_TEST_V2 ||
2462          options == QLA_RESTART_DPORT_TEST_V2)) {
2463         vha->dport_status &= ~DPORT_DIAG_CHIP_RESET_IN_PROGRESS;
2464     }
2465 
2466     /*  Check chip reset in progress and get result request arrive */
2467     if (vha->dport_status & DPORT_DIAG_CHIP_RESET_IN_PROGRESS &&
2468         options == QLA_GET_DPORT_RESULT_V2) {
2469         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2470                     EXT_STATUS_DPORT_DIAG_NOT_RUNNING;
2471         goto dportcomplete;
2472     }
2473 
2474     rval = qla26xx_dport_diagnostics_v2(vha, dd, mcp);
2475 
2476     if (rval == QLA_SUCCESS) {
2477         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2478                     EXT_STATUS_OK;
2479         if (options == QLA_START_DPORT_TEST_V2 ||
2480             options == QLA_RESTART_DPORT_TEST_V2) {
2481             dd->mbx1 = mcp->mb[0];
2482             dd->mbx2 = mcp->mb[1];
2483             vha->dport_status |=  DPORT_DIAG_IN_PROGRESS;
2484         } else if (options == QLA_GET_DPORT_RESULT_V2) {
2485             dd->mbx1 = le16_to_cpu(vha->dport_data[1]);
2486             dd->mbx2 = le16_to_cpu(vha->dport_data[2]);
2487         }
2488     } else {
2489         dd->mbx1 = mcp->mb[0];
2490         dd->mbx2 = mcp->mb[1];
2491         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2492                 EXT_STATUS_DPORT_DIAG_ERR;
2493     }
2494 
2495 dportcomplete:
2496     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2497                 bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
2498 
2499     bsg_reply->reply_payload_rcv_len = sizeof(*dd);
2500     bsg_job->reply_len = sizeof(*bsg_reply);
2501     bsg_reply->result = DID_OK << 16;
2502     bsg_job_done(bsg_job, bsg_reply->result,
2503              bsg_reply->reply_payload_rcv_len);
2504 
2505     kfree(dd);
2506 
2507     return 0;
2508 }
2509 
2510 static int
2511 qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
2512 {
2513     scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2514     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2515     struct qla_hw_data *ha = vha->hw;
2516     struct qla_active_regions regions = { };
2517     struct active_regions active_regions = { };
2518 
2519     qla27xx_get_active_image(vha, &active_regions);
2520     regions.global_image = active_regions.global;
2521 
2522     if (IS_QLA28XX(ha)) {
2523         qla28xx_get_aux_images(vha, &active_regions);
2524         regions.board_config = active_regions.aux.board_config;
2525         regions.vpd_nvram = active_regions.aux.vpd_nvram;
2526         regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1;
2527         regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3;
2528     }
2529 
2530     ql_dbg(ql_dbg_user, vha, 0x70e1,
2531         "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n",
2532         __func__, vha->host_no, regions.global_image,
2533         regions.board_config, regions.vpd_nvram,
2534         regions.npiv_config_0_1, regions.npiv_config_2_3);
2535 
2536     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2537         bsg_job->reply_payload.sg_cnt, &regions, sizeof(regions));
2538 
2539     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2540     bsg_reply->reply_payload_rcv_len = sizeof(regions);
2541     bsg_reply->result = DID_OK << 16;
2542     bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2543     bsg_job_done(bsg_job, bsg_reply->result,
2544         bsg_reply->reply_payload_rcv_len);
2545 
2546     return 0;
2547 }
2548 
2549 static int
2550 qla2x00_manage_host_stats(struct bsg_job *bsg_job)
2551 {
2552     scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2553     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2554     struct ql_vnd_mng_host_stats_param *req_data;
2555     struct ql_vnd_mng_host_stats_resp rsp_data;
2556     u32 req_data_len;
2557     int ret = 0;
2558 
2559     if (!vha->flags.online) {
2560         ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
2561         return -EIO;
2562     }
2563 
2564     req_data_len = bsg_job->request_payload.payload_len;
2565 
2566     if (req_data_len != sizeof(struct ql_vnd_mng_host_stats_param)) {
2567         ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2568         return -EIO;
2569     }
2570 
2571     req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2572     if (!req_data) {
2573         ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2574         return -ENOMEM;
2575     }
2576 
2577     /* Copy the request buffer in req_data */
2578     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2579               bsg_job->request_payload.sg_cnt, req_data,
2580               req_data_len);
2581 
2582     switch (req_data->action) {
2583     case QLA_STOP:
2584         ret = qla2xxx_stop_stats(vha->host, req_data->stat_type);
2585         break;
2586     case QLA_START:
2587         ret = qla2xxx_start_stats(vha->host, req_data->stat_type);
2588         break;
2589     case QLA_CLEAR:
2590         ret = qla2xxx_reset_stats(vha->host, req_data->stat_type);
2591         break;
2592     default:
2593         ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
2594         ret = -EIO;
2595         break;
2596     }
2597 
2598     kfree(req_data);
2599 
2600     /* Prepare response */
2601     rsp_data.status = ret;
2602     bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2603 
2604     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2605     bsg_reply->reply_payload_rcv_len =
2606         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2607                     bsg_job->reply_payload.sg_cnt,
2608                     &rsp_data,
2609                     sizeof(struct ql_vnd_mng_host_stats_resp));
2610 
2611     bsg_reply->result = DID_OK;
2612     bsg_job_done(bsg_job, bsg_reply->result,
2613              bsg_reply->reply_payload_rcv_len);
2614 
2615     return ret;
2616 }
2617 
2618 static int
2619 qla2x00_get_host_stats(struct bsg_job *bsg_job)
2620 {
2621     scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2622     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2623     struct ql_vnd_stats_param *req_data;
2624     struct ql_vnd_host_stats_resp rsp_data;
2625     u32 req_data_len;
2626     int ret = 0;
2627     u64 ini_entry_count = 0;
2628     u64 entry_count = 0;
2629     u64 tgt_num = 0;
2630     u64 tmp_stat_type = 0;
2631     u64 response_len = 0;
2632     void *data;
2633 
2634     req_data_len = bsg_job->request_payload.payload_len;
2635 
2636     if (req_data_len != sizeof(struct ql_vnd_stats_param)) {
2637         ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2638         return -EIO;
2639     }
2640 
2641     req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2642     if (!req_data) {
2643         ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2644         return -ENOMEM;
2645     }
2646 
2647     /* Copy the request buffer in req_data */
2648     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2649               bsg_job->request_payload.sg_cnt, req_data, req_data_len);
2650 
2651     /* Copy stat type to work on it */
2652     tmp_stat_type = req_data->stat_type;
2653 
2654     if (tmp_stat_type & QLA2XX_TGT_SHT_LNK_DOWN) {
2655         /* Num of tgts connected to this host */
2656         tgt_num = qla2x00_get_num_tgts(vha);
2657         /* unset BIT_17 */
2658         tmp_stat_type &= ~(1 << 17);
2659     }
2660 
2661     /* Total ini stats */
2662     ini_entry_count = qla2x00_count_set_bits(tmp_stat_type);
2663 
2664     /* Total number of entries */
2665     entry_count = ini_entry_count + tgt_num;
2666 
2667     response_len = sizeof(struct ql_vnd_host_stats_resp) +
2668         (sizeof(struct ql_vnd_stat_entry) * entry_count);
2669 
2670     if (response_len > bsg_job->reply_payload.payload_len) {
2671         rsp_data.status = EXT_STATUS_BUFFER_TOO_SMALL;
2672         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
2673         bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2674 
2675         bsg_reply->reply_payload_rcv_len =
2676             sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2677                         bsg_job->reply_payload.sg_cnt, &rsp_data,
2678                         sizeof(struct ql_vnd_mng_host_stats_resp));
2679 
2680         bsg_reply->result = DID_OK;
2681         bsg_job_done(bsg_job, bsg_reply->result,
2682                  bsg_reply->reply_payload_rcv_len);
2683         goto host_stat_out;
2684     }
2685 
2686     data = kzalloc(response_len, GFP_KERNEL);
2687     if (!data) {
2688         ret = -ENOMEM;
2689         goto host_stat_out;
2690     }
2691 
2692     ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
2693                     data, response_len);
2694 
2695     rsp_data.status = EXT_STATUS_OK;
2696     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2697 
2698     bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2699                                    bsg_job->reply_payload.sg_cnt,
2700                                    data, response_len);
2701     bsg_reply->result = DID_OK;
2702     bsg_job_done(bsg_job, bsg_reply->result,
2703              bsg_reply->reply_payload_rcv_len);
2704 
2705     kfree(data);
2706 host_stat_out:
2707     kfree(req_data);
2708     return ret;
2709 }
2710 
2711 static struct fc_rport *
2712 qla2xxx_find_rport(scsi_qla_host_t *vha, uint32_t tgt_num)
2713 {
2714     fc_port_t *fcport = NULL;
2715 
2716     list_for_each_entry(fcport, &vha->vp_fcports, list) {
2717         if (fcport->rport->number == tgt_num)
2718             return fcport->rport;
2719     }
2720     return NULL;
2721 }
2722 
2723 static int
2724 qla2x00_get_tgt_stats(struct bsg_job *bsg_job)
2725 {
2726     scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2727     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2728     struct ql_vnd_tgt_stats_param *req_data;
2729     u32 req_data_len;
2730     int ret = 0;
2731     u64 response_len = 0;
2732     struct ql_vnd_tgt_stats_resp *data = NULL;
2733     struct fc_rport *rport = NULL;
2734 
2735     if (!vha->flags.online) {
2736         ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
2737         return -EIO;
2738     }
2739 
2740     req_data_len = bsg_job->request_payload.payload_len;
2741 
2742     if (req_data_len != sizeof(struct ql_vnd_stat_entry)) {
2743         ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2744         return -EIO;
2745     }
2746 
2747     req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2748     if (!req_data) {
2749         ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2750         return -ENOMEM;
2751     }
2752 
2753     /* Copy the request buffer in req_data */
2754     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2755               bsg_job->request_payload.sg_cnt,
2756               req_data, req_data_len);
2757 
2758     response_len = sizeof(struct ql_vnd_tgt_stats_resp) +
2759         sizeof(struct ql_vnd_stat_entry);
2760 
2761     /* structure + size for one entry */
2762     data = kzalloc(response_len, GFP_KERNEL);
2763     if (!data) {
2764         kfree(req_data);
2765         return -ENOMEM;
2766     }
2767 
2768     if (response_len > bsg_job->reply_payload.payload_len) {
2769         data->status = EXT_STATUS_BUFFER_TOO_SMALL;
2770         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
2771         bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2772 
2773         bsg_reply->reply_payload_rcv_len =
2774             sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2775                         bsg_job->reply_payload.sg_cnt, data,
2776                         sizeof(struct ql_vnd_tgt_stats_resp));
2777 
2778         bsg_reply->result = DID_OK;
2779         bsg_job_done(bsg_job, bsg_reply->result,
2780                  bsg_reply->reply_payload_rcv_len);
2781         goto tgt_stat_out;
2782     }
2783 
2784     rport = qla2xxx_find_rport(vha, req_data->tgt_id);
2785     if (!rport) {
2786         ql_log(ql_log_warn, vha, 0x0000, "target %d not found.\n", req_data->tgt_id);
2787         ret = EXT_STATUS_INVALID_PARAM;
2788         data->status = EXT_STATUS_INVALID_PARAM;
2789         goto reply;
2790     }
2791 
2792     ret = qla2xxx_get_tgt_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
2793                     rport, (void *)data, response_len);
2794 
2795     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2796 reply:
2797     bsg_reply->reply_payload_rcv_len =
2798         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2799                     bsg_job->reply_payload.sg_cnt, data,
2800                     response_len);
2801     bsg_reply->result = DID_OK;
2802     bsg_job_done(bsg_job, bsg_reply->result,
2803              bsg_reply->reply_payload_rcv_len);
2804 
2805 tgt_stat_out:
2806     kfree(data);
2807     kfree(req_data);
2808 
2809     return ret;
2810 }
2811 
2812 static int
2813 qla2x00_manage_host_port(struct bsg_job *bsg_job)
2814 {
2815     scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2816     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2817     struct ql_vnd_mng_host_port_param *req_data;
2818     struct ql_vnd_mng_host_port_resp rsp_data;
2819     u32 req_data_len;
2820     int ret = 0;
2821 
2822     req_data_len = bsg_job->request_payload.payload_len;
2823 
2824     if (req_data_len != sizeof(struct ql_vnd_mng_host_port_param)) {
2825         ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2826         return -EIO;
2827     }
2828 
2829     req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2830     if (!req_data) {
2831         ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2832         return -ENOMEM;
2833     }
2834 
2835     /* Copy the request buffer in req_data */
2836     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2837               bsg_job->request_payload.sg_cnt, req_data, req_data_len);
2838 
2839     switch (req_data->action) {
2840     case QLA_ENABLE:
2841         ret = qla2xxx_enable_port(vha->host);
2842         break;
2843     case QLA_DISABLE:
2844         ret = qla2xxx_disable_port(vha->host);
2845         break;
2846     default:
2847         ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
2848         ret = -EIO;
2849         break;
2850     }
2851 
2852     kfree(req_data);
2853 
2854     /* Prepare response */
2855     rsp_data.status = ret;
2856     bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2857     bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_port_resp);
2858 
2859     bsg_reply->reply_payload_rcv_len =
2860         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2861                     bsg_job->reply_payload.sg_cnt, &rsp_data,
2862                     sizeof(struct ql_vnd_mng_host_port_resp));
2863     bsg_reply->result = DID_OK;
2864     bsg_job_done(bsg_job, bsg_reply->result,
2865              bsg_reply->reply_payload_rcv_len);
2866 
2867     return ret;
2868 }
2869 
2870 static int
2871 qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_job)
2872 {
2873     struct fc_bsg_request *bsg_request = bsg_job->request;
2874 
2875     ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n",
2876         __func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]);
2877 
2878     switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
2879     case QL_VND_LOOPBACK:
2880         return qla2x00_process_loopback(bsg_job);
2881 
2882     case QL_VND_A84_RESET:
2883         return qla84xx_reset(bsg_job);
2884 
2885     case QL_VND_A84_UPDATE_FW:
2886         return qla84xx_updatefw(bsg_job);
2887 
2888     case QL_VND_A84_MGMT_CMD:
2889         return qla84xx_mgmt_cmd(bsg_job);
2890 
2891     case QL_VND_IIDMA:
2892         return qla24xx_iidma(bsg_job);
2893 
2894     case QL_VND_FCP_PRIO_CFG_CMD:
2895         return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);
2896 
2897     case QL_VND_READ_FLASH:
2898         return qla2x00_read_optrom(bsg_job);
2899 
2900     case QL_VND_UPDATE_FLASH:
2901         return qla2x00_update_optrom(bsg_job);
2902 
2903     case QL_VND_SET_FRU_VERSION:
2904         return qla2x00_update_fru_versions(bsg_job);
2905 
2906     case QL_VND_READ_FRU_STATUS:
2907         return qla2x00_read_fru_status(bsg_job);
2908 
2909     case QL_VND_WRITE_FRU_STATUS:
2910         return qla2x00_write_fru_status(bsg_job);
2911 
2912     case QL_VND_WRITE_I2C:
2913         return qla2x00_write_i2c(bsg_job);
2914 
2915     case QL_VND_READ_I2C:
2916         return qla2x00_read_i2c(bsg_job);
2917 
2918     case QL_VND_DIAG_IO_CMD:
2919         return qla24xx_process_bidir_cmd(bsg_job);
2920 
2921     case QL_VND_FX00_MGMT_CMD:
2922         return qlafx00_mgmt_cmd(bsg_job);
2923 
2924     case QL_VND_SERDES_OP:
2925         return qla26xx_serdes_op(bsg_job);
2926 
2927     case QL_VND_SERDES_OP_EX:
2928         return qla8044_serdes_op(bsg_job);
2929 
2930     case QL_VND_GET_FLASH_UPDATE_CAPS:
2931         return qla27xx_get_flash_upd_cap(bsg_job);
2932 
2933     case QL_VND_SET_FLASH_UPDATE_CAPS:
2934         return qla27xx_set_flash_upd_cap(bsg_job);
2935 
2936     case QL_VND_GET_BBCR_DATA:
2937         return qla27xx_get_bbcr_data(bsg_job);
2938 
2939     case QL_VND_GET_PRIV_STATS:
2940     case QL_VND_GET_PRIV_STATS_EX:
2941         return qla2x00_get_priv_stats(bsg_job);
2942 
2943     case QL_VND_DPORT_DIAGNOSTICS:
2944         return qla2x00_do_dport_diagnostics(bsg_job);
2945 
2946     case QL_VND_DPORT_DIAGNOSTICS_V2:
2947         return qla2x00_do_dport_diagnostics_v2(bsg_job);
2948 
2949     case QL_VND_EDIF_MGMT:
2950         return qla_edif_app_mgmt(bsg_job);
2951 
2952     case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
2953         return qla2x00_get_flash_image_status(bsg_job);
2954 
2955     case QL_VND_MANAGE_HOST_STATS:
2956         return qla2x00_manage_host_stats(bsg_job);
2957 
2958     case QL_VND_GET_HOST_STATS:
2959         return qla2x00_get_host_stats(bsg_job);
2960 
2961     case QL_VND_GET_TGT_STATS:
2962         return qla2x00_get_tgt_stats(bsg_job);
2963 
2964     case QL_VND_MANAGE_HOST_PORT:
2965         return qla2x00_manage_host_port(bsg_job);
2966 
2967     case QL_VND_MBX_PASSTHRU:
2968         return qla2x00_mailbox_passthru(bsg_job);
2969 
2970     default:
2971         return -ENOSYS;
2972     }
2973 }
2974 
2975 int
2976 qla24xx_bsg_request(struct bsg_job *bsg_job)
2977 {
2978     struct fc_bsg_request *bsg_request = bsg_job->request;
2979     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2980     int ret = -EINVAL;
2981     struct fc_rport *rport;
2982     struct Scsi_Host *host;
2983     scsi_qla_host_t *vha;
2984 
2985     /* In case no data transferred. */
2986     bsg_reply->reply_payload_rcv_len = 0;
2987 
2988     if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
2989         rport = fc_bsg_to_rport(bsg_job);
2990         host = rport_to_shost(rport);
2991         vha = shost_priv(host);
2992     } else {
2993         host = fc_bsg_to_shost(bsg_job);
2994         vha = shost_priv(host);
2995     }
2996 
2997     /* Disable port will bring down the chip, allow enable command */
2998     if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
2999         bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
3000         goto skip_chip_chk;
3001 
3002     if (vha->hw->flags.port_isolated) {
3003         bsg_reply->result = DID_ERROR;
3004         /* operation not permitted */
3005         return -EPERM;
3006     }
3007 
3008     if (qla2x00_chip_is_down(vha)) {
3009         ql_dbg(ql_dbg_user, vha, 0x709f,
3010             "BSG: ISP abort active/needed -- cmd=%d.\n",
3011             bsg_request->msgcode);
3012         SET_DID_STATUS(bsg_reply->result, DID_ERROR);
3013         return -EBUSY;
3014     }
3015 
3016     if (test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags)) {
3017         SET_DID_STATUS(bsg_reply->result, DID_ERROR);
3018         return -EIO;
3019     }
3020 
3021 skip_chip_chk:
3022     ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
3023         "Entered %s msgcode=0x%x. bsg ptr %px\n",
3024         __func__, bsg_request->msgcode, bsg_job);
3025 
3026     switch (bsg_request->msgcode) {
3027     case FC_BSG_RPT_ELS:
3028     case FC_BSG_HST_ELS_NOLOGIN:
3029         ret = qla2x00_process_els(bsg_job);
3030         break;
3031     case FC_BSG_HST_CT:
3032         ret = qla2x00_process_ct(bsg_job);
3033         break;
3034     case FC_BSG_HST_VENDOR:
3035         ret = qla2x00_process_vendor_specific(vha, bsg_job);
3036         break;
3037     case FC_BSG_HST_ADD_RPORT:
3038     case FC_BSG_HST_DEL_RPORT:
3039     case FC_BSG_RPT_CT:
3040     default:
3041         ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
3042         break;
3043     }
3044 
3045     ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
3046         "%s done with return %x\n", __func__, ret);
3047 
3048     return ret;
3049 }
3050 
3051 int
3052 qla24xx_bsg_timeout(struct bsg_job *bsg_job)
3053 {
3054     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
3055     scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
3056     struct qla_hw_data *ha = vha->hw;
3057     srb_t *sp;
3058     int cnt, que;
3059     unsigned long flags;
3060     struct req_que *req;
3061 
3062     ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n",
3063         __func__, bsg_job);
3064 
3065     if (qla2x00_isp_reg_stat(ha)) {
3066         ql_log(ql_log_info, vha, 0x9007,
3067             "PCI/Register disconnect.\n");
3068         qla_pci_set_eeh_busy(vha);
3069     }
3070 
3071     /* find the bsg job from the active list of commands */
3072     spin_lock_irqsave(&ha->hardware_lock, flags);
3073     for (que = 0; que < ha->max_req_queues; que++) {
3074         req = ha->req_q_map[que];
3075         if (!req)
3076             continue;
3077 
3078         for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
3079             sp = req->outstanding_cmds[cnt];
3080             if (sp &&
3081                 (sp->type == SRB_CT_CMD ||
3082                  sp->type == SRB_ELS_CMD_HST ||
3083                  sp->type == SRB_ELS_CMD_HST_NOLOGIN ||
3084                  sp->type == SRB_FXIOCB_BCMD) &&
3085                 sp->u.bsg_job == bsg_job) {
3086                 req->outstanding_cmds[cnt] = NULL;
3087                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3088 
3089                 if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) {
3090                     ql_log(ql_log_warn, vha, 0x7089,
3091                         "mbx abort_command failed.\n");
3092                     bsg_reply->result = -EIO;
3093                 } else {
3094                     ql_dbg(ql_dbg_user, vha, 0x708a,
3095                         "mbx abort_command success.\n");
3096                     bsg_reply->result = 0;
3097                 }
3098                 spin_lock_irqsave(&ha->hardware_lock, flags);
3099                 goto done;
3100 
3101             }
3102         }
3103     }
3104     spin_unlock_irqrestore(&ha->hardware_lock, flags);
3105     ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
3106     bsg_reply->result = -ENXIO;
3107     return 0;
3108 
3109 done:
3110     spin_unlock_irqrestore(&ha->hardware_lock, flags);
3111     /* ref: INIT */
3112     kref_put(&sp->cmd_kref, qla2x00_sp_release);
3113     return 0;
3114 }
3115 
3116 int qla2x00_mailbox_passthru(struct bsg_job *bsg_job)
3117 {
3118     struct fc_bsg_reply *bsg_reply = bsg_job->reply;
3119     scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
3120     int ret = -EINVAL;
3121     int ptsize = sizeof(struct qla_mbx_passthru);
3122     struct qla_mbx_passthru *req_data = NULL;
3123     uint32_t req_data_len;
3124 
3125     req_data_len = bsg_job->request_payload.payload_len;
3126     if (req_data_len != ptsize) {
3127         ql_log(ql_log_warn, vha, 0xf0a3, "req_data_len invalid.\n");
3128         return -EIO;
3129     }
3130     req_data = kzalloc(ptsize, GFP_KERNEL);
3131     if (!req_data) {
3132         ql_log(ql_log_warn, vha, 0xf0a4,
3133                "req_data memory allocation failure.\n");
3134         return -ENOMEM;
3135     }
3136 
3137     /* Copy the request buffer in req_data */
3138     sg_copy_to_buffer(bsg_job->request_payload.sg_list,
3139               bsg_job->request_payload.sg_cnt, req_data, ptsize);
3140     ret = qla_mailbox_passthru(vha, req_data->mbx_in, req_data->mbx_out);
3141 
3142     /* Copy the req_data in  request buffer */
3143     sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
3144                 bsg_job->reply_payload.sg_cnt, req_data, ptsize);
3145 
3146     bsg_reply->reply_payload_rcv_len = ptsize;
3147     if (ret == QLA_SUCCESS)
3148         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
3149     else
3150         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_ERR;
3151 
3152     bsg_job->reply_len = sizeof(*bsg_job->reply);
3153     bsg_reply->result = DID_OK << 16;
3154     bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
3155 
3156     kfree(req_data);
3157 
3158     return ret;
3159 }