cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qla_bsg.c (84816B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * QLogic Fibre Channel HBA Driver
      4 * Copyright (c)  2003-2014 QLogic Corporation
      5 */
      6#include "qla_def.h"
      7#include "qla_gbl.h"
      8
      9#include <linux/kthread.h>
     10#include <linux/vmalloc.h>
     11#include <linux/delay.h>
     12#include <linux/bsg-lib.h>
     13
     14static void qla2xxx_free_fcport_work(struct work_struct *work)
     15{
     16	struct fc_port *fcport = container_of(work, typeof(*fcport),
     17	    free_work);
     18
     19	qla2x00_free_fcport(fcport);
     20}
     21
     22/* BSG support for ELS/CT pass through */
     23void qla2x00_bsg_job_done(srb_t *sp, int res)
     24{
     25	struct bsg_job *bsg_job = sp->u.bsg_job;
     26	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
     27
     28	ql_dbg(ql_dbg_user, sp->vha, 0x7009,
     29	    "%s: sp hdl %x, result=%x bsg ptr %p\n",
     30	    __func__, sp->handle, res, bsg_job);
     31
     32	/* ref: INIT */
     33	kref_put(&sp->cmd_kref, qla2x00_sp_release);
     34
     35	bsg_reply->result = res;
     36	bsg_job_done(bsg_job, bsg_reply->result,
     37		       bsg_reply->reply_payload_rcv_len);
     38}
     39
     40void qla2x00_bsg_sp_free(srb_t *sp)
     41{
     42	struct qla_hw_data *ha = sp->vha->hw;
     43	struct bsg_job *bsg_job = sp->u.bsg_job;
     44	struct fc_bsg_request *bsg_request = bsg_job->request;
     45	struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
     46
     47	if (sp->type == SRB_FXIOCB_BCMD) {
     48		piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
     49		    &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
     50
     51		if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
     52			dma_unmap_sg(&ha->pdev->dev,
     53			    bsg_job->request_payload.sg_list,
     54			    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
     55
     56		if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
     57			dma_unmap_sg(&ha->pdev->dev,
     58			    bsg_job->reply_payload.sg_list,
     59			    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
     60	} else {
     61
     62		if (sp->remap.remapped) {
     63			dma_pool_free(ha->purex_dma_pool, sp->remap.rsp.buf,
     64			    sp->remap.rsp.dma);
     65			dma_pool_free(ha->purex_dma_pool, sp->remap.req.buf,
     66			    sp->remap.req.dma);
     67		} else {
     68			dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
     69				bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
     70
     71			dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
     72				bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
     73		}
     74	}
     75
     76	if (sp->type == SRB_CT_CMD ||
     77	    sp->type == SRB_FXIOCB_BCMD ||
     78	    sp->type == SRB_ELS_CMD_HST) {
     79		INIT_WORK(&sp->fcport->free_work, qla2xxx_free_fcport_work);
     80		queue_work(ha->wq, &sp->fcport->free_work);
     81	}
     82
     83	qla2x00_rel_sp(sp);
     84}
     85
     86int
     87qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
     88	struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
     89{
     90	int i, ret, num_valid;
     91	uint8_t *bcode;
     92	struct qla_fcp_prio_entry *pri_entry;
     93	uint32_t *bcode_val_ptr, bcode_val;
     94
     95	ret = 1;
     96	num_valid = 0;
     97	bcode = (uint8_t *)pri_cfg;
     98	bcode_val_ptr = (uint32_t *)pri_cfg;
     99	bcode_val = (uint32_t)(*bcode_val_ptr);
    100
    101	if (bcode_val == 0xFFFFFFFF) {
    102		/* No FCP Priority config data in flash */
    103		ql_dbg(ql_dbg_user, vha, 0x7051,
    104		    "No FCP Priority config data.\n");
    105		return 0;
    106	}
    107
    108	if (memcmp(bcode, "HQOS", 4)) {
    109		/* Invalid FCP priority data header*/
    110		ql_dbg(ql_dbg_user, vha, 0x7052,
    111		    "Invalid FCP Priority data header. bcode=0x%x.\n",
    112		    bcode_val);
    113		return 0;
    114	}
    115	if (flag != 1)
    116		return ret;
    117
    118	pri_entry = &pri_cfg->entry[0];
    119	for (i = 0; i < pri_cfg->num_entries; i++) {
    120		if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
    121			num_valid++;
    122		pri_entry++;
    123	}
    124
    125	if (num_valid == 0) {
    126		/* No valid FCP priority data entries */
    127		ql_dbg(ql_dbg_user, vha, 0x7053,
    128		    "No valid FCP Priority data entries.\n");
    129		ret = 0;
    130	} else {
    131		/* FCP priority data is valid */
    132		ql_dbg(ql_dbg_user, vha, 0x7054,
    133		    "Valid FCP priority data. num entries = %d.\n",
    134		    num_valid);
    135	}
    136
    137	return ret;
    138}
    139
    140static int
    141qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
    142{
    143	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
    144	struct fc_bsg_request *bsg_request = bsg_job->request;
    145	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
    146	scsi_qla_host_t *vha = shost_priv(host);
    147	struct qla_hw_data *ha = vha->hw;
    148	int ret = 0;
    149	uint32_t len;
    150	uint32_t oper;
    151
    152	if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_P3P_TYPE(ha))) {
    153		ret = -EINVAL;
    154		goto exit_fcp_prio_cfg;
    155	}
    156
    157	/* Get the sub command */
    158	oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
    159
    160	/* Only set config is allowed if config memory is not allocated */
    161	if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
    162		ret = -EINVAL;
    163		goto exit_fcp_prio_cfg;
    164	}
    165	switch (oper) {
    166	case QLFC_FCP_PRIO_DISABLE:
    167		if (ha->flags.fcp_prio_enabled) {
    168			ha->flags.fcp_prio_enabled = 0;
    169			ha->fcp_prio_cfg->attributes &=
    170				~FCP_PRIO_ATTR_ENABLE;
    171			qla24xx_update_all_fcp_prio(vha);
    172			bsg_reply->result = DID_OK;
    173		} else {
    174			ret = -EINVAL;
    175			bsg_reply->result = (DID_ERROR << 16);
    176			goto exit_fcp_prio_cfg;
    177		}
    178		break;
    179
    180	case QLFC_FCP_PRIO_ENABLE:
    181		if (!ha->flags.fcp_prio_enabled) {
    182			if (ha->fcp_prio_cfg) {
    183				ha->flags.fcp_prio_enabled = 1;
    184				ha->fcp_prio_cfg->attributes |=
    185				    FCP_PRIO_ATTR_ENABLE;
    186				qla24xx_update_all_fcp_prio(vha);
    187				bsg_reply->result = DID_OK;
    188			} else {
    189				ret = -EINVAL;
    190				bsg_reply->result = (DID_ERROR << 16);
    191				goto exit_fcp_prio_cfg;
    192			}
    193		}
    194		break;
    195
    196	case QLFC_FCP_PRIO_GET_CONFIG:
    197		len = bsg_job->reply_payload.payload_len;
    198		if (!len || len > FCP_PRIO_CFG_SIZE) {
    199			ret = -EINVAL;
    200			bsg_reply->result = (DID_ERROR << 16);
    201			goto exit_fcp_prio_cfg;
    202		}
    203
    204		bsg_reply->result = DID_OK;
    205		bsg_reply->reply_payload_rcv_len =
    206			sg_copy_from_buffer(
    207			bsg_job->reply_payload.sg_list,
    208			bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
    209			len);
    210
    211		break;
    212
    213	case QLFC_FCP_PRIO_SET_CONFIG:
    214		len = bsg_job->request_payload.payload_len;
    215		if (!len || len > FCP_PRIO_CFG_SIZE) {
    216			bsg_reply->result = (DID_ERROR << 16);
    217			ret = -EINVAL;
    218			goto exit_fcp_prio_cfg;
    219		}
    220
    221		if (!ha->fcp_prio_cfg) {
    222			ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE);
    223			if (!ha->fcp_prio_cfg) {
    224				ql_log(ql_log_warn, vha, 0x7050,
    225				    "Unable to allocate memory for fcp prio "
    226				    "config data (%x).\n", FCP_PRIO_CFG_SIZE);
    227				bsg_reply->result = (DID_ERROR << 16);
    228				ret = -ENOMEM;
    229				goto exit_fcp_prio_cfg;
    230			}
    231		}
    232
    233		memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE);
    234		sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    235		bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg,
    236			FCP_PRIO_CFG_SIZE);
    237
    238		/* validate fcp priority data */
    239
    240		if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 1)) {
    241			bsg_reply->result = (DID_ERROR << 16);
    242			ret = -EINVAL;
    243			/* If buffer was invalidatic int
    244			 * fcp_prio_cfg is of no use
    245			 */
    246			vfree(ha->fcp_prio_cfg);
    247			ha->fcp_prio_cfg = NULL;
    248			goto exit_fcp_prio_cfg;
    249		}
    250
    251		ha->flags.fcp_prio_enabled = 0;
    252		if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
    253			ha->flags.fcp_prio_enabled = 1;
    254		qla24xx_update_all_fcp_prio(vha);
    255		bsg_reply->result = DID_OK;
    256		break;
    257	default:
    258		ret = -EINVAL;
    259		break;
    260	}
    261exit_fcp_prio_cfg:
    262	if (!ret)
    263		bsg_job_done(bsg_job, bsg_reply->result,
    264			       bsg_reply->reply_payload_rcv_len);
    265	return ret;
    266}
    267
    268static int
    269qla2x00_process_els(struct bsg_job *bsg_job)
    270{
    271	struct fc_bsg_request *bsg_request = bsg_job->request;
    272	struct fc_rport *rport;
    273	fc_port_t *fcport = NULL;
    274	struct Scsi_Host *host;
    275	scsi_qla_host_t *vha;
    276	struct qla_hw_data *ha;
    277	srb_t *sp;
    278	const char *type;
    279	int req_sg_cnt, rsp_sg_cnt;
    280	int rval =  (DID_ERROR << 16);
    281	uint16_t nextlid = 0;
    282	uint32_t els_cmd = 0;
    283
    284	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
    285		rport = fc_bsg_to_rport(bsg_job);
    286		fcport = *(fc_port_t **) rport->dd_data;
    287		host = rport_to_shost(rport);
    288		vha = shost_priv(host);
    289		ha = vha->hw;
    290		type = "FC_BSG_RPT_ELS";
    291	} else {
    292		host = fc_bsg_to_shost(bsg_job);
    293		vha = shost_priv(host);
    294		ha = vha->hw;
    295		type = "FC_BSG_HST_ELS_NOLOGIN";
    296		els_cmd = bsg_request->rqst_data.h_els.command_code;
    297		if (els_cmd == ELS_AUTH_ELS)
    298			return qla_edif_process_els(vha, bsg_job);
    299	}
    300
    301	if (!vha->flags.online) {
    302		ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
    303		rval = -EIO;
    304		goto done;
    305	}
    306
    307	/* pass through is supported only for ISP 4Gb or higher */
    308	if (!IS_FWI2_CAPABLE(ha)) {
    309		ql_dbg(ql_dbg_user, vha, 0x7001,
    310		    "ELS passthru not supported for ISP23xx based adapters.\n");
    311		rval = -EPERM;
    312		goto done;
    313	}
    314
    315	/*  Multiple SG's are not supported for ELS requests */
    316	if (bsg_job->request_payload.sg_cnt > 1 ||
    317		bsg_job->reply_payload.sg_cnt > 1) {
    318		ql_dbg(ql_dbg_user, vha, 0x7002,
    319		    "Multiple SG's are not supported for ELS requests, "
    320		    "request_sg_cnt=%x reply_sg_cnt=%x.\n",
    321		    bsg_job->request_payload.sg_cnt,
    322		    bsg_job->reply_payload.sg_cnt);
    323		rval = -EPERM;
    324		goto done;
    325	}
    326
    327	/* ELS request for rport */
    328	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
    329		/* make sure the rport is logged in,
    330		 * if not perform fabric login
    331		 */
    332		if (qla2x00_fabric_login(vha, fcport, &nextlid)) {
    333			ql_dbg(ql_dbg_user, vha, 0x7003,
    334			    "Failed to login port %06X for ELS passthru.\n",
    335			    fcport->d_id.b24);
    336			rval = -EIO;
    337			goto done;
    338		}
    339	} else {
    340		/* Allocate a dummy fcport structure, since functions
    341		 * preparing the IOCB and mailbox command retrieves port
    342		 * specific information from fcport structure. For Host based
    343		 * ELS commands there will be no fcport structure allocated
    344		 */
    345		fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
    346		if (!fcport) {
    347			rval = -ENOMEM;
    348			goto done;
    349		}
    350
    351		/* Initialize all required  fields of fcport */
    352		fcport->vha = vha;
    353		fcport->d_id.b.al_pa =
    354			bsg_request->rqst_data.h_els.port_id[0];
    355		fcport->d_id.b.area =
    356			bsg_request->rqst_data.h_els.port_id[1];
    357		fcport->d_id.b.domain =
    358			bsg_request->rqst_data.h_els.port_id[2];
    359		fcport->loop_id =
    360			(fcport->d_id.b.al_pa == 0xFD) ?
    361			NPH_FABRIC_CONTROLLER : NPH_F_PORT;
    362	}
    363
    364	req_sg_cnt =
    365		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
    366		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
    367	if (!req_sg_cnt) {
    368		dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
    369		    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
    370		rval = -ENOMEM;
    371		goto done_free_fcport;
    372	}
    373
    374	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
    375		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
    376        if (!rsp_sg_cnt) {
    377		dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
    378		    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
    379		rval = -ENOMEM;
    380		goto done_free_fcport;
    381	}
    382
    383	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
    384		(rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
    385		ql_log(ql_log_warn, vha, 0x7008,
    386		    "dma mapping resulted in different sg counts, "
    387		    "request_sg_cnt: %x dma_request_sg_cnt:%x reply_sg_cnt:%x "
    388		    "dma_reply_sg_cnt:%x.\n", bsg_job->request_payload.sg_cnt,
    389		    req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
    390		rval = -EAGAIN;
    391		goto done_unmap_sg;
    392	}
    393
    394	/* Alloc SRB structure */
    395	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
    396	if (!sp) {
    397		rval = -ENOMEM;
    398		goto done_unmap_sg;
    399	}
    400
    401	sp->type =
    402		(bsg_request->msgcode == FC_BSG_RPT_ELS ?
    403		 SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
    404	sp->name =
    405		(bsg_request->msgcode == FC_BSG_RPT_ELS ?
    406		 "bsg_els_rpt" : "bsg_els_hst");
    407	sp->u.bsg_job = bsg_job;
    408	sp->free = qla2x00_bsg_sp_free;
    409	sp->done = qla2x00_bsg_job_done;
    410
    411	ql_dbg(ql_dbg_user, vha, 0x700a,
    412	    "bsg rqst type: %s els type: %x - loop-id=%x "
    413	    "portid=%-2x%02x%02x.\n", type,
    414	    bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
    415	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
    416
    417	rval = qla2x00_start_sp(sp);
    418	if (rval != QLA_SUCCESS) {
    419		ql_log(ql_log_warn, vha, 0x700e,
    420		    "qla2x00_start_sp failed = %d\n", rval);
    421		qla2x00_rel_sp(sp);
    422		rval = -EIO;
    423		goto done_unmap_sg;
    424	}
    425	return rval;
    426
    427done_unmap_sg:
    428	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
    429		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
    430	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
    431		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
    432	goto done_free_fcport;
    433
    434done_free_fcport:
    435	if (bsg_request->msgcode != FC_BSG_RPT_ELS)
    436		qla2x00_free_fcport(fcport);
    437done:
    438	return rval;
    439}
    440
    441static inline uint16_t
    442qla24xx_calc_ct_iocbs(uint16_t dsds)
    443{
    444	uint16_t iocbs;
    445
    446	iocbs = 1;
    447	if (dsds > 2) {
    448		iocbs += (dsds - 2) / 5;
    449		if ((dsds - 2) % 5)
    450			iocbs++;
    451	}
    452	return iocbs;
    453}
    454
    455static int
    456qla2x00_process_ct(struct bsg_job *bsg_job)
    457{
    458	srb_t *sp;
    459	struct fc_bsg_request *bsg_request = bsg_job->request;
    460	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
    461	scsi_qla_host_t *vha = shost_priv(host);
    462	struct qla_hw_data *ha = vha->hw;
    463	int rval = (DID_ERROR << 16);
    464	int req_sg_cnt, rsp_sg_cnt;
    465	uint16_t loop_id;
    466	struct fc_port *fcport;
    467	char  *type = "FC_BSG_HST_CT";
    468
    469	req_sg_cnt =
    470		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
    471			bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
    472	if (!req_sg_cnt) {
    473		ql_log(ql_log_warn, vha, 0x700f,
    474		    "dma_map_sg return %d for request\n", req_sg_cnt);
    475		rval = -ENOMEM;
    476		goto done;
    477	}
    478
    479	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
    480		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
    481	if (!rsp_sg_cnt) {
    482		ql_log(ql_log_warn, vha, 0x7010,
    483		    "dma_map_sg return %d for reply\n", rsp_sg_cnt);
    484		rval = -ENOMEM;
    485		goto done;
    486	}
    487
    488	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
    489	    (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
    490		ql_log(ql_log_warn, vha, 0x7011,
    491		    "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
    492		    "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
    493		    req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
    494		rval = -EAGAIN;
    495		goto done_unmap_sg;
    496	}
    497
    498	if (!vha->flags.online) {
    499		ql_log(ql_log_warn, vha, 0x7012,
    500		    "Host is not online.\n");
    501		rval = -EIO;
    502		goto done_unmap_sg;
    503	}
    504
    505	loop_id =
    506		(bsg_request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
    507			>> 24;
    508	switch (loop_id) {
    509	case 0xFC:
    510		loop_id = NPH_SNS;
    511		break;
    512	case 0xFA:
    513		loop_id = vha->mgmt_svr_loop_id;
    514		break;
    515	default:
    516		ql_dbg(ql_dbg_user, vha, 0x7013,
    517		    "Unknown loop id: %x.\n", loop_id);
    518		rval = -EINVAL;
    519		goto done_unmap_sg;
    520	}
    521
    522	/* Allocate a dummy fcport structure, since functions preparing the
    523	 * IOCB and mailbox command retrieves port specific information
    524	 * from fcport structure. For Host based ELS commands there will be
    525	 * no fcport structure allocated
    526	 */
    527	fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
    528	if (!fcport) {
    529		ql_log(ql_log_warn, vha, 0x7014,
    530		    "Failed to allocate fcport.\n");
    531		rval = -ENOMEM;
    532		goto done_unmap_sg;
    533	}
    534
    535	/* Initialize all required  fields of fcport */
    536	fcport->vha = vha;
    537	fcport->d_id.b.al_pa = bsg_request->rqst_data.h_ct.port_id[0];
    538	fcport->d_id.b.area = bsg_request->rqst_data.h_ct.port_id[1];
    539	fcport->d_id.b.domain = bsg_request->rqst_data.h_ct.port_id[2];
    540	fcport->loop_id = loop_id;
    541
    542	/* Alloc SRB structure */
    543	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
    544	if (!sp) {
    545		ql_log(ql_log_warn, vha, 0x7015,
    546		    "qla2x00_get_sp failed.\n");
    547		rval = -ENOMEM;
    548		goto done_free_fcport;
    549	}
    550
    551	sp->type = SRB_CT_CMD;
    552	sp->name = "bsg_ct";
    553	sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
    554	sp->u.bsg_job = bsg_job;
    555	sp->free = qla2x00_bsg_sp_free;
    556	sp->done = qla2x00_bsg_job_done;
    557
    558	ql_dbg(ql_dbg_user, vha, 0x7016,
    559	    "bsg rqst type: %s else type: %x - "
    560	    "loop-id=%x portid=%02x%02x%02x.\n", type,
    561	    (bsg_request->rqst_data.h_ct.preamble_word2 >> 16),
    562	    fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
    563	    fcport->d_id.b.al_pa);
    564
    565	rval = qla2x00_start_sp(sp);
    566	if (rval != QLA_SUCCESS) {
    567		ql_log(ql_log_warn, vha, 0x7017,
    568		    "qla2x00_start_sp failed=%d.\n", rval);
    569		qla2x00_rel_sp(sp);
    570		rval = -EIO;
    571		goto done_free_fcport;
    572	}
    573	return rval;
    574
    575done_free_fcport:
    576	qla2x00_free_fcport(fcport);
    577done_unmap_sg:
    578	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
    579		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
    580	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
    581		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
    582done:
    583	return rval;
    584}
    585
    586/* Disable loopback mode */
    587static inline int
    588qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
    589			    int wait, int wait2)
    590{
    591	int ret = 0;
    592	int rval = 0;
    593	uint16_t new_config[4];
    594	struct qla_hw_data *ha = vha->hw;
    595
    596	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
    597		goto done_reset_internal;
    598
    599	memset(new_config, 0 , sizeof(new_config));
    600	if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
    601	    ENABLE_INTERNAL_LOOPBACK ||
    602	    (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
    603	    ENABLE_EXTERNAL_LOOPBACK) {
    604		new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
    605		ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
    606		    (new_config[0] & INTERNAL_LOOPBACK_MASK));
    607		memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
    608
    609		ha->notify_dcbx_comp = wait;
    610		ha->notify_lb_portup_comp = wait2;
    611
    612		ret = qla81xx_set_port_config(vha, new_config);
    613		if (ret != QLA_SUCCESS) {
    614			ql_log(ql_log_warn, vha, 0x7025,
    615			    "Set port config failed.\n");
    616			ha->notify_dcbx_comp = 0;
    617			ha->notify_lb_portup_comp = 0;
    618			rval = -EINVAL;
    619			goto done_reset_internal;
    620		}
    621
    622		/* Wait for DCBX complete event */
    623		if (wait && !wait_for_completion_timeout(&ha->dcbx_comp,
    624			(DCBX_COMP_TIMEOUT * HZ))) {
    625			ql_dbg(ql_dbg_user, vha, 0x7026,
    626			    "DCBX completion not received.\n");
    627			ha->notify_dcbx_comp = 0;
    628			ha->notify_lb_portup_comp = 0;
    629			rval = -EINVAL;
    630			goto done_reset_internal;
    631		} else
    632			ql_dbg(ql_dbg_user, vha, 0x7027,
    633			    "DCBX completion received.\n");
    634
    635		if (wait2 &&
    636		    !wait_for_completion_timeout(&ha->lb_portup_comp,
    637		    (LB_PORTUP_COMP_TIMEOUT * HZ))) {
    638			ql_dbg(ql_dbg_user, vha, 0x70c5,
    639			    "Port up completion not received.\n");
    640			ha->notify_lb_portup_comp = 0;
    641			rval = -EINVAL;
    642			goto done_reset_internal;
    643		} else
    644			ql_dbg(ql_dbg_user, vha, 0x70c6,
    645			    "Port up completion received.\n");
    646
    647		ha->notify_dcbx_comp = 0;
    648		ha->notify_lb_portup_comp = 0;
    649	}
    650done_reset_internal:
    651	return rval;
    652}
    653
    654/*
    655 * Set the port configuration to enable the internal or external loopback
    656 * depending on the loopback mode.
    657 */
    658static inline int
    659qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
    660	uint16_t *new_config, uint16_t mode)
    661{
    662	int ret = 0;
    663	int rval = 0;
    664	unsigned long rem_tmo = 0, current_tmo = 0;
    665	struct qla_hw_data *ha = vha->hw;
    666
    667	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
    668		goto done_set_internal;
    669
    670	if (mode == INTERNAL_LOOPBACK)
    671		new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
    672	else if (mode == EXTERNAL_LOOPBACK)
    673		new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
    674	ql_dbg(ql_dbg_user, vha, 0x70be,
    675	     "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));
    676
    677	memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);
    678
    679	ha->notify_dcbx_comp = 1;
    680	ret = qla81xx_set_port_config(vha, new_config);
    681	if (ret != QLA_SUCCESS) {
    682		ql_log(ql_log_warn, vha, 0x7021,
    683		    "set port config failed.\n");
    684		ha->notify_dcbx_comp = 0;
    685		rval = -EINVAL;
    686		goto done_set_internal;
    687	}
    688
    689	/* Wait for DCBX complete event */
    690	current_tmo = DCBX_COMP_TIMEOUT * HZ;
    691	while (1) {
    692		rem_tmo = wait_for_completion_timeout(&ha->dcbx_comp,
    693		    current_tmo);
    694		if (!ha->idc_extend_tmo || rem_tmo) {
    695			ha->idc_extend_tmo = 0;
    696			break;
    697		}
    698		current_tmo = ha->idc_extend_tmo * HZ;
    699		ha->idc_extend_tmo = 0;
    700	}
    701
    702	if (!rem_tmo) {
    703		ql_dbg(ql_dbg_user, vha, 0x7022,
    704		    "DCBX completion not received.\n");
    705		ret = qla81xx_reset_loopback_mode(vha, new_config, 0, 0);
    706		/*
    707		 * If the reset of the loopback mode doesn't work take a FCoE
    708		 * dump and reset the chip.
    709		 */
    710		if (ret) {
    711			qla2xxx_dump_fw(vha);
    712			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
    713		}
    714		rval = -EINVAL;
    715	} else {
    716		if (ha->flags.idc_compl_status) {
    717			ql_dbg(ql_dbg_user, vha, 0x70c3,
    718			    "Bad status in IDC Completion AEN\n");
    719			rval = -EINVAL;
    720			ha->flags.idc_compl_status = 0;
    721		} else
    722			ql_dbg(ql_dbg_user, vha, 0x7023,
    723			    "DCBX completion received.\n");
    724	}
    725
    726	ha->notify_dcbx_comp = 0;
    727	ha->idc_extend_tmo = 0;
    728
    729done_set_internal:
    730	return rval;
    731}
    732
    733static int
    734qla2x00_process_loopback(struct bsg_job *bsg_job)
    735{
    736	struct fc_bsg_request *bsg_request = bsg_job->request;
    737	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
    738	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
    739	scsi_qla_host_t *vha = shost_priv(host);
    740	struct qla_hw_data *ha = vha->hw;
    741	int rval;
    742	uint8_t command_sent;
    743	char *type;
    744	struct msg_echo_lb elreq;
    745	uint16_t response[MAILBOX_REGISTER_COUNT];
    746	uint16_t config[4], new_config[4];
    747	uint8_t *fw_sts_ptr;
    748	void *req_data = NULL;
    749	dma_addr_t req_data_dma;
    750	uint32_t req_data_len;
    751	uint8_t *rsp_data = NULL;
    752	dma_addr_t rsp_data_dma;
    753	uint32_t rsp_data_len;
    754
    755	if (!vha->flags.online) {
    756		ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
    757		return -EIO;
    758	}
    759
    760	memset(&elreq, 0, sizeof(elreq));
    761
    762	elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
    763		bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt,
    764		DMA_TO_DEVICE);
    765
    766	if (!elreq.req_sg_cnt) {
    767		ql_log(ql_log_warn, vha, 0x701a,
    768		    "dma_map_sg returned %d for request.\n", elreq.req_sg_cnt);
    769		return -ENOMEM;
    770	}
    771
    772	elreq.rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
    773		bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
    774		DMA_FROM_DEVICE);
    775
    776	if (!elreq.rsp_sg_cnt) {
    777		ql_log(ql_log_warn, vha, 0x701b,
    778		    "dma_map_sg returned %d for reply.\n", elreq.rsp_sg_cnt);
    779		rval = -ENOMEM;
    780		goto done_unmap_req_sg;
    781	}
    782
    783	if ((elreq.req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
    784		(elreq.rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
    785		ql_log(ql_log_warn, vha, 0x701c,
    786		    "dma mapping resulted in different sg counts, "
    787		    "request_sg_cnt: %x dma_request_sg_cnt: %x "
    788		    "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
    789		    bsg_job->request_payload.sg_cnt, elreq.req_sg_cnt,
    790		    bsg_job->reply_payload.sg_cnt, elreq.rsp_sg_cnt);
    791		rval = -EAGAIN;
    792		goto done_unmap_sg;
    793	}
    794	req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
    795	req_data = dma_alloc_coherent(&ha->pdev->dev, req_data_len,
    796		&req_data_dma, GFP_KERNEL);
    797	if (!req_data) {
    798		ql_log(ql_log_warn, vha, 0x701d,
    799		    "dma alloc failed for req_data.\n");
    800		rval = -ENOMEM;
    801		goto done_unmap_sg;
    802	}
    803
    804	rsp_data = dma_alloc_coherent(&ha->pdev->dev, rsp_data_len,
    805		&rsp_data_dma, GFP_KERNEL);
    806	if (!rsp_data) {
    807		ql_log(ql_log_warn, vha, 0x7004,
    808		    "dma alloc failed for rsp_data.\n");
    809		rval = -ENOMEM;
    810		goto done_free_dma_req;
    811	}
    812
    813	/* Copy the request buffer in req_data now */
    814	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    815		bsg_job->request_payload.sg_cnt, req_data, req_data_len);
    816
    817	elreq.send_dma = req_data_dma;
    818	elreq.rcv_dma = rsp_data_dma;
    819	elreq.transfer_size = req_data_len;
    820
    821	elreq.options = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
    822	elreq.iteration_count =
    823	    bsg_request->rqst_data.h_vendor.vendor_cmd[2];
    824
    825	if (atomic_read(&vha->loop_state) == LOOP_READY &&
    826	    ((ha->current_topology == ISP_CFG_F && (elreq.options & 7) >= 2) ||
    827	    ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
    828	    get_unaligned_le32(req_data) == ELS_OPCODE_BYTE &&
    829	    req_data_len == MAX_ELS_FRAME_PAYLOAD &&
    830	    elreq.options == EXTERNAL_LOOPBACK))) {
    831		type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
    832		ql_dbg(ql_dbg_user, vha, 0x701e,
    833		    "BSG request type: %s.\n", type);
    834		command_sent = INT_DEF_LB_ECHO_CMD;
    835		rval = qla2x00_echo_test(vha, &elreq, response);
    836	} else {
    837		if (IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) {
    838			memset(config, 0, sizeof(config));
    839			memset(new_config, 0, sizeof(new_config));
    840
    841			if (qla81xx_get_port_config(vha, config)) {
    842				ql_log(ql_log_warn, vha, 0x701f,
    843				    "Get port config failed.\n");
    844				rval = -EPERM;
    845				goto done_free_dma_rsp;
    846			}
    847
    848			if ((config[0] & INTERNAL_LOOPBACK_MASK) != 0) {
    849				ql_dbg(ql_dbg_user, vha, 0x70c4,
    850				    "Loopback operation already in "
    851				    "progress.\n");
    852				rval = -EAGAIN;
    853				goto done_free_dma_rsp;
    854			}
    855
    856			ql_dbg(ql_dbg_user, vha, 0x70c0,
    857			    "elreq.options=%04x\n", elreq.options);
    858
    859			if (elreq.options == EXTERNAL_LOOPBACK)
    860				if (IS_QLA8031(ha) || IS_QLA8044(ha))
    861					rval = qla81xx_set_loopback_mode(vha,
    862					    config, new_config, elreq.options);
    863				else
    864					rval = qla81xx_reset_loopback_mode(vha,
    865					    config, 1, 0);
    866			else
    867				rval = qla81xx_set_loopback_mode(vha, config,
    868				    new_config, elreq.options);
    869
    870			if (rval) {
    871				rval = -EPERM;
    872				goto done_free_dma_rsp;
    873			}
    874
    875			type = "FC_BSG_HST_VENDOR_LOOPBACK";
    876			ql_dbg(ql_dbg_user, vha, 0x7028,
    877			    "BSG request type: %s.\n", type);
    878
    879			command_sent = INT_DEF_LB_LOOPBACK_CMD;
    880			rval = qla2x00_loopback_test(vha, &elreq, response);
    881
    882			if (response[0] == MBS_COMMAND_ERROR &&
    883					response[1] == MBS_LB_RESET) {
    884				ql_log(ql_log_warn, vha, 0x7029,
    885				    "MBX command error, Aborting ISP.\n");
    886				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
    887				qla2xxx_wake_dpc(vha);
    888				qla2x00_wait_for_chip_reset(vha);
    889				/* Also reset the MPI */
    890				if (IS_QLA81XX(ha)) {
    891					if (qla81xx_restart_mpi_firmware(vha) !=
    892					    QLA_SUCCESS) {
    893						ql_log(ql_log_warn, vha, 0x702a,
    894						    "MPI reset failed.\n");
    895					}
    896				}
    897
    898				rval = -EIO;
    899				goto done_free_dma_rsp;
    900			}
    901
    902			if (new_config[0]) {
    903				int ret;
    904
    905				/* Revert back to original port config
    906				 * Also clear internal loopback
    907				 */
    908				ret = qla81xx_reset_loopback_mode(vha,
    909				    new_config, 0, 1);
    910				if (ret) {
    911					/*
    912					 * If the reset of the loopback mode
    913					 * doesn't work take FCoE dump and then
    914					 * reset the chip.
    915					 */
    916					qla2xxx_dump_fw(vha);
    917					set_bit(ISP_ABORT_NEEDED,
    918					    &vha->dpc_flags);
    919				}
    920
    921			}
    922
    923		} else {
    924			type = "FC_BSG_HST_VENDOR_LOOPBACK";
    925			ql_dbg(ql_dbg_user, vha, 0x702b,
    926			    "BSG request type: %s.\n", type);
    927			command_sent = INT_DEF_LB_LOOPBACK_CMD;
    928			rval = qla2x00_loopback_test(vha, &elreq, response);
    929		}
    930	}
    931
    932	if (rval) {
    933		ql_log(ql_log_warn, vha, 0x702c,
    934		    "Vendor request %s failed.\n", type);
    935
    936		rval = 0;
    937		bsg_reply->result = (DID_ERROR << 16);
    938		bsg_reply->reply_payload_rcv_len = 0;
    939	} else {
    940		ql_dbg(ql_dbg_user, vha, 0x702d,
    941		    "Vendor request %s completed.\n", type);
    942		bsg_reply->result = (DID_OK << 16);
    943		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
    944			bsg_job->reply_payload.sg_cnt, rsp_data,
    945			rsp_data_len);
    946	}
    947
    948	bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
    949	    sizeof(response) + sizeof(uint8_t);
    950	fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply);
    951	memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), response,
    952			sizeof(response));
    953	fw_sts_ptr += sizeof(response);
    954	*fw_sts_ptr = command_sent;
    955
    956done_free_dma_rsp:
    957	dma_free_coherent(&ha->pdev->dev, rsp_data_len,
    958		rsp_data, rsp_data_dma);
    959done_free_dma_req:
    960	dma_free_coherent(&ha->pdev->dev, req_data_len,
    961		req_data, req_data_dma);
    962done_unmap_sg:
    963	dma_unmap_sg(&ha->pdev->dev,
    964	    bsg_job->reply_payload.sg_list,
    965	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
    966done_unmap_req_sg:
    967	dma_unmap_sg(&ha->pdev->dev,
    968	    bsg_job->request_payload.sg_list,
    969	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
    970	if (!rval)
    971		bsg_job_done(bsg_job, bsg_reply->result,
    972			       bsg_reply->reply_payload_rcv_len);
    973	return rval;
    974}
    975
    976static int
    977qla84xx_reset(struct bsg_job *bsg_job)
    978{
    979	struct fc_bsg_request *bsg_request = bsg_job->request;
    980	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
    981	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
    982	scsi_qla_host_t *vha = shost_priv(host);
    983	struct qla_hw_data *ha = vha->hw;
    984	int rval = 0;
    985	uint32_t flag;
    986
    987	if (!IS_QLA84XX(ha)) {
    988		ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
    989		return -EINVAL;
    990	}
    991
    992	flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
    993
    994	rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
    995
    996	if (rval) {
    997		ql_log(ql_log_warn, vha, 0x7030,
    998		    "Vendor request 84xx reset failed.\n");
    999		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
   1012static int
   1013qla84xx_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
   1109done_free_fw_buf:
   1110	dma_free_coherent(&ha->pdev->dev, data_len, fw_buf, fw_dma);
   1111
   1112done_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
   1122static int
   1123qla84xx_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
   1298done_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
   1309exit_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
   1318static int
   1319qla24xx_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
   1407static int
   1408qla2x00_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
   1477static int
   1478qla2x00_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
   1514static int
   1515qla2x00_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
   1555static int
   1556qla2x00_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
   1596dealloc:
   1597	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
   1598
   1599done:
   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
   1608static int
   1609qla2x00_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
   1646dealloc:
   1647	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
   1648
   1649done:
   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
   1659static int
   1660qla2x00_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
   1694dealloc:
   1695	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
   1696
   1697done:
   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
   1706static int
   1707qla2x00_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
   1740dealloc:
   1741	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
   1742
   1743done:
   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
   1752static int
   1753qla2x00_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
   1789dealloc:
   1790	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
   1791
   1792done:
   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
   1802static int
   1803qla24xx_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
   1955done_free_srb:
   1956	mempool_free(sp, ha->srb_mempool);
   1957done_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);
   1961done_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);
   1965done:
   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
   1980static int
   1981qlafx00_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
   2085done_free_fcport:
   2086	qla2x00_free_fcport(fcport);
   2087
   2088done_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);
   2093done_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
   2099done:
   2100	return rval;
   2101}
   2102
   2103static int
   2104qla26xx_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
   2145static int
   2146qla8044_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
   2187static int
   2188qla27xx_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
   2219static int
   2220qla27xx_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
   2265static int
   2266qla27xx_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
   2310done:
   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
   2324static int
   2325qla2x00_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
   2383static int
   2384qla2x00_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
   2427static int
   2428qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
   2429{
   2430	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
   2431	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   2432	struct qla_hw_data *ha = vha->hw;
   2433	struct qla_active_regions regions = { };
   2434	struct active_regions active_regions = { };
   2435
   2436	qla27xx_get_active_image(vha, &active_regions);
   2437	regions.global_image = active_regions.global;
   2438
   2439	if (IS_QLA28XX(ha)) {
   2440		qla28xx_get_aux_images(vha, &active_regions);
   2441		regions.board_config = active_regions.aux.board_config;
   2442		regions.vpd_nvram = active_regions.aux.vpd_nvram;
   2443		regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1;
   2444		regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3;
   2445	}
   2446
   2447	ql_dbg(ql_dbg_user, vha, 0x70e1,
   2448	    "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n",
   2449	    __func__, vha->host_no, regions.global_image,
   2450	    regions.board_config, regions.vpd_nvram,
   2451	    regions.npiv_config_0_1, regions.npiv_config_2_3);
   2452
   2453	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   2454	    bsg_job->reply_payload.sg_cnt, &regions, sizeof(regions));
   2455
   2456	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
   2457	bsg_reply->reply_payload_rcv_len = sizeof(regions);
   2458	bsg_reply->result = DID_OK << 16;
   2459	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
   2460	bsg_job_done(bsg_job, bsg_reply->result,
   2461	    bsg_reply->reply_payload_rcv_len);
   2462
   2463	return 0;
   2464}
   2465
   2466static int
   2467qla2x00_manage_host_stats(struct bsg_job *bsg_job)
   2468{
   2469	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
   2470	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   2471	struct ql_vnd_mng_host_stats_param *req_data;
   2472	struct ql_vnd_mng_host_stats_resp rsp_data;
   2473	u32 req_data_len;
   2474	int ret = 0;
   2475
   2476	if (!vha->flags.online) {
   2477		ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
   2478		return -EIO;
   2479	}
   2480
   2481	req_data_len = bsg_job->request_payload.payload_len;
   2482
   2483	if (req_data_len != sizeof(struct ql_vnd_mng_host_stats_param)) {
   2484		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
   2485		return -EIO;
   2486	}
   2487
   2488	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
   2489	if (!req_data) {
   2490		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
   2491		return -ENOMEM;
   2492	}
   2493
   2494	/* Copy the request buffer in req_data */
   2495	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   2496			  bsg_job->request_payload.sg_cnt, req_data,
   2497			  req_data_len);
   2498
   2499	switch (req_data->action) {
   2500	case QLA_STOP:
   2501		ret = qla2xxx_stop_stats(vha->host, req_data->stat_type);
   2502		break;
   2503	case QLA_START:
   2504		ret = qla2xxx_start_stats(vha->host, req_data->stat_type);
   2505		break;
   2506	case QLA_CLEAR:
   2507		ret = qla2xxx_reset_stats(vha->host, req_data->stat_type);
   2508		break;
   2509	default:
   2510		ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
   2511		ret = -EIO;
   2512		break;
   2513	}
   2514
   2515	kfree(req_data);
   2516
   2517	/* Prepare response */
   2518	rsp_data.status = ret;
   2519	bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
   2520
   2521	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
   2522	bsg_reply->reply_payload_rcv_len =
   2523		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   2524				    bsg_job->reply_payload.sg_cnt,
   2525				    &rsp_data,
   2526				    sizeof(struct ql_vnd_mng_host_stats_resp));
   2527
   2528	bsg_reply->result = DID_OK;
   2529	bsg_job_done(bsg_job, bsg_reply->result,
   2530		     bsg_reply->reply_payload_rcv_len);
   2531
   2532	return ret;
   2533}
   2534
   2535static int
   2536qla2x00_get_host_stats(struct bsg_job *bsg_job)
   2537{
   2538	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
   2539	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   2540	struct ql_vnd_stats_param *req_data;
   2541	struct ql_vnd_host_stats_resp rsp_data;
   2542	u32 req_data_len;
   2543	int ret = 0;
   2544	u64 ini_entry_count = 0;
   2545	u64 entry_count = 0;
   2546	u64 tgt_num = 0;
   2547	u64 tmp_stat_type = 0;
   2548	u64 response_len = 0;
   2549	void *data;
   2550
   2551	req_data_len = bsg_job->request_payload.payload_len;
   2552
   2553	if (req_data_len != sizeof(struct ql_vnd_stats_param)) {
   2554		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
   2555		return -EIO;
   2556	}
   2557
   2558	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
   2559	if (!req_data) {
   2560		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
   2561		return -ENOMEM;
   2562	}
   2563
   2564	/* Copy the request buffer in req_data */
   2565	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   2566			  bsg_job->request_payload.sg_cnt, req_data, req_data_len);
   2567
   2568	/* Copy stat type to work on it */
   2569	tmp_stat_type = req_data->stat_type;
   2570
   2571	if (tmp_stat_type & QLA2XX_TGT_SHT_LNK_DOWN) {
   2572		/* Num of tgts connected to this host */
   2573		tgt_num = qla2x00_get_num_tgts(vha);
   2574		/* unset BIT_17 */
   2575		tmp_stat_type &= ~(1 << 17);
   2576	}
   2577
   2578	/* Total ini stats */
   2579	ini_entry_count = qla2x00_count_set_bits(tmp_stat_type);
   2580
   2581	/* Total number of entries */
   2582	entry_count = ini_entry_count + tgt_num;
   2583
   2584	response_len = sizeof(struct ql_vnd_host_stats_resp) +
   2585		(sizeof(struct ql_vnd_stat_entry) * entry_count);
   2586
   2587	if (response_len > bsg_job->reply_payload.payload_len) {
   2588		rsp_data.status = EXT_STATUS_BUFFER_TOO_SMALL;
   2589		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
   2590		bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
   2591
   2592		bsg_reply->reply_payload_rcv_len =
   2593			sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   2594					    bsg_job->reply_payload.sg_cnt, &rsp_data,
   2595					    sizeof(struct ql_vnd_mng_host_stats_resp));
   2596
   2597		bsg_reply->result = DID_OK;
   2598		bsg_job_done(bsg_job, bsg_reply->result,
   2599			     bsg_reply->reply_payload_rcv_len);
   2600		goto host_stat_out;
   2601	}
   2602
   2603	data = kzalloc(response_len, GFP_KERNEL);
   2604	if (!data) {
   2605		ret = -ENOMEM;
   2606		goto host_stat_out;
   2607	}
   2608
   2609	ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
   2610				    data, response_len);
   2611
   2612	rsp_data.status = EXT_STATUS_OK;
   2613	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
   2614
   2615	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   2616							       bsg_job->reply_payload.sg_cnt,
   2617							       data, response_len);
   2618	bsg_reply->result = DID_OK;
   2619	bsg_job_done(bsg_job, bsg_reply->result,
   2620		     bsg_reply->reply_payload_rcv_len);
   2621
   2622	kfree(data);
   2623host_stat_out:
   2624	kfree(req_data);
   2625	return ret;
   2626}
   2627
   2628static struct fc_rport *
   2629qla2xxx_find_rport(scsi_qla_host_t *vha, uint32_t tgt_num)
   2630{
   2631	fc_port_t *fcport = NULL;
   2632
   2633	list_for_each_entry(fcport, &vha->vp_fcports, list) {
   2634		if (fcport->rport->number == tgt_num)
   2635			return fcport->rport;
   2636	}
   2637	return NULL;
   2638}
   2639
   2640static int
   2641qla2x00_get_tgt_stats(struct bsg_job *bsg_job)
   2642{
   2643	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
   2644	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   2645	struct ql_vnd_tgt_stats_param *req_data;
   2646	u32 req_data_len;
   2647	int ret = 0;
   2648	u64 response_len = 0;
   2649	struct ql_vnd_tgt_stats_resp *data = NULL;
   2650	struct fc_rport *rport = NULL;
   2651
   2652	if (!vha->flags.online) {
   2653		ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
   2654		return -EIO;
   2655	}
   2656
   2657	req_data_len = bsg_job->request_payload.payload_len;
   2658
   2659	if (req_data_len != sizeof(struct ql_vnd_stat_entry)) {
   2660		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
   2661		return -EIO;
   2662	}
   2663
   2664	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
   2665	if (!req_data) {
   2666		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
   2667		return -ENOMEM;
   2668	}
   2669
   2670	/* Copy the request buffer in req_data */
   2671	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   2672			  bsg_job->request_payload.sg_cnt,
   2673			  req_data, req_data_len);
   2674
   2675	response_len = sizeof(struct ql_vnd_tgt_stats_resp) +
   2676		sizeof(struct ql_vnd_stat_entry);
   2677
   2678	/* structure + size for one entry */
   2679	data = kzalloc(response_len, GFP_KERNEL);
   2680	if (!data) {
   2681		kfree(req_data);
   2682		return -ENOMEM;
   2683	}
   2684
   2685	if (response_len > bsg_job->reply_payload.payload_len) {
   2686		data->status = EXT_STATUS_BUFFER_TOO_SMALL;
   2687		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
   2688		bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
   2689
   2690		bsg_reply->reply_payload_rcv_len =
   2691			sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   2692					    bsg_job->reply_payload.sg_cnt, data,
   2693					    sizeof(struct ql_vnd_tgt_stats_resp));
   2694
   2695		bsg_reply->result = DID_OK;
   2696		bsg_job_done(bsg_job, bsg_reply->result,
   2697			     bsg_reply->reply_payload_rcv_len);
   2698		goto tgt_stat_out;
   2699	}
   2700
   2701	rport = qla2xxx_find_rport(vha, req_data->tgt_id);
   2702	if (!rport) {
   2703		ql_log(ql_log_warn, vha, 0x0000, "target %d not found.\n", req_data->tgt_id);
   2704		ret = EXT_STATUS_INVALID_PARAM;
   2705		data->status = EXT_STATUS_INVALID_PARAM;
   2706		goto reply;
   2707	}
   2708
   2709	ret = qla2xxx_get_tgt_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
   2710				    rport, (void *)data, response_len);
   2711
   2712	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
   2713reply:
   2714	bsg_reply->reply_payload_rcv_len =
   2715		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   2716				    bsg_job->reply_payload.sg_cnt, data,
   2717				    response_len);
   2718	bsg_reply->result = DID_OK;
   2719	bsg_job_done(bsg_job, bsg_reply->result,
   2720		     bsg_reply->reply_payload_rcv_len);
   2721
   2722tgt_stat_out:
   2723	kfree(data);
   2724	kfree(req_data);
   2725
   2726	return ret;
   2727}
   2728
   2729static int
   2730qla2x00_manage_host_port(struct bsg_job *bsg_job)
   2731{
   2732	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
   2733	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   2734	struct ql_vnd_mng_host_port_param *req_data;
   2735	struct ql_vnd_mng_host_port_resp rsp_data;
   2736	u32 req_data_len;
   2737	int ret = 0;
   2738
   2739	req_data_len = bsg_job->request_payload.payload_len;
   2740
   2741	if (req_data_len != sizeof(struct ql_vnd_mng_host_port_param)) {
   2742		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
   2743		return -EIO;
   2744	}
   2745
   2746	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
   2747	if (!req_data) {
   2748		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
   2749		return -ENOMEM;
   2750	}
   2751
   2752	/* Copy the request buffer in req_data */
   2753	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   2754			  bsg_job->request_payload.sg_cnt, req_data, req_data_len);
   2755
   2756	switch (req_data->action) {
   2757	case QLA_ENABLE:
   2758		ret = qla2xxx_enable_port(vha->host);
   2759		break;
   2760	case QLA_DISABLE:
   2761		ret = qla2xxx_disable_port(vha->host);
   2762		break;
   2763	default:
   2764		ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
   2765		ret = -EIO;
   2766		break;
   2767	}
   2768
   2769	kfree(req_data);
   2770
   2771	/* Prepare response */
   2772	rsp_data.status = ret;
   2773	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
   2774	bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_port_resp);
   2775
   2776	bsg_reply->reply_payload_rcv_len =
   2777		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   2778				    bsg_job->reply_payload.sg_cnt, &rsp_data,
   2779				    sizeof(struct ql_vnd_mng_host_port_resp));
   2780	bsg_reply->result = DID_OK;
   2781	bsg_job_done(bsg_job, bsg_reply->result,
   2782		     bsg_reply->reply_payload_rcv_len);
   2783
   2784	return ret;
   2785}
   2786
   2787static int
   2788qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_job)
   2789{
   2790	struct fc_bsg_request *bsg_request = bsg_job->request;
   2791
   2792	ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n",
   2793	    __func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]);
   2794
   2795	switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
   2796	case QL_VND_LOOPBACK:
   2797		return qla2x00_process_loopback(bsg_job);
   2798
   2799	case QL_VND_A84_RESET:
   2800		return qla84xx_reset(bsg_job);
   2801
   2802	case QL_VND_A84_UPDATE_FW:
   2803		return qla84xx_updatefw(bsg_job);
   2804
   2805	case QL_VND_A84_MGMT_CMD:
   2806		return qla84xx_mgmt_cmd(bsg_job);
   2807
   2808	case QL_VND_IIDMA:
   2809		return qla24xx_iidma(bsg_job);
   2810
   2811	case QL_VND_FCP_PRIO_CFG_CMD:
   2812		return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);
   2813
   2814	case QL_VND_READ_FLASH:
   2815		return qla2x00_read_optrom(bsg_job);
   2816
   2817	case QL_VND_UPDATE_FLASH:
   2818		return qla2x00_update_optrom(bsg_job);
   2819
   2820	case QL_VND_SET_FRU_VERSION:
   2821		return qla2x00_update_fru_versions(bsg_job);
   2822
   2823	case QL_VND_READ_FRU_STATUS:
   2824		return qla2x00_read_fru_status(bsg_job);
   2825
   2826	case QL_VND_WRITE_FRU_STATUS:
   2827		return qla2x00_write_fru_status(bsg_job);
   2828
   2829	case QL_VND_WRITE_I2C:
   2830		return qla2x00_write_i2c(bsg_job);
   2831
   2832	case QL_VND_READ_I2C:
   2833		return qla2x00_read_i2c(bsg_job);
   2834
   2835	case QL_VND_DIAG_IO_CMD:
   2836		return qla24xx_process_bidir_cmd(bsg_job);
   2837
   2838	case QL_VND_FX00_MGMT_CMD:
   2839		return qlafx00_mgmt_cmd(bsg_job);
   2840
   2841	case QL_VND_SERDES_OP:
   2842		return qla26xx_serdes_op(bsg_job);
   2843
   2844	case QL_VND_SERDES_OP_EX:
   2845		return qla8044_serdes_op(bsg_job);
   2846
   2847	case QL_VND_GET_FLASH_UPDATE_CAPS:
   2848		return qla27xx_get_flash_upd_cap(bsg_job);
   2849
   2850	case QL_VND_SET_FLASH_UPDATE_CAPS:
   2851		return qla27xx_set_flash_upd_cap(bsg_job);
   2852
   2853	case QL_VND_GET_BBCR_DATA:
   2854		return qla27xx_get_bbcr_data(bsg_job);
   2855
   2856	case QL_VND_GET_PRIV_STATS:
   2857	case QL_VND_GET_PRIV_STATS_EX:
   2858		return qla2x00_get_priv_stats(bsg_job);
   2859
   2860	case QL_VND_DPORT_DIAGNOSTICS:
   2861		return qla2x00_do_dport_diagnostics(bsg_job);
   2862
   2863	case QL_VND_EDIF_MGMT:
   2864		return qla_edif_app_mgmt(bsg_job);
   2865
   2866	case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
   2867		return qla2x00_get_flash_image_status(bsg_job);
   2868
   2869	case QL_VND_MANAGE_HOST_STATS:
   2870		return qla2x00_manage_host_stats(bsg_job);
   2871
   2872	case QL_VND_GET_HOST_STATS:
   2873		return qla2x00_get_host_stats(bsg_job);
   2874
   2875	case QL_VND_GET_TGT_STATS:
   2876		return qla2x00_get_tgt_stats(bsg_job);
   2877
   2878	case QL_VND_MANAGE_HOST_PORT:
   2879		return qla2x00_manage_host_port(bsg_job);
   2880
   2881	case QL_VND_MBX_PASSTHRU:
   2882		return qla2x00_mailbox_passthru(bsg_job);
   2883
   2884	default:
   2885		return -ENOSYS;
   2886	}
   2887}
   2888
   2889int
   2890qla24xx_bsg_request(struct bsg_job *bsg_job)
   2891{
   2892	struct fc_bsg_request *bsg_request = bsg_job->request;
   2893	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   2894	int ret = -EINVAL;
   2895	struct fc_rport *rport;
   2896	struct Scsi_Host *host;
   2897	scsi_qla_host_t *vha;
   2898
   2899	/* In case no data transferred. */
   2900	bsg_reply->reply_payload_rcv_len = 0;
   2901
   2902	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
   2903		rport = fc_bsg_to_rport(bsg_job);
   2904		host = rport_to_shost(rport);
   2905		vha = shost_priv(host);
   2906	} else {
   2907		host = fc_bsg_to_shost(bsg_job);
   2908		vha = shost_priv(host);
   2909	}
   2910
   2911	/* Disable port will bring down the chip, allow enable command */
   2912	if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
   2913	    bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
   2914		goto skip_chip_chk;
   2915
   2916	if (vha->hw->flags.port_isolated) {
   2917		bsg_reply->result = DID_ERROR;
   2918		/* operation not permitted */
   2919		return -EPERM;
   2920	}
   2921
   2922	if (qla2x00_chip_is_down(vha)) {
   2923		ql_dbg(ql_dbg_user, vha, 0x709f,
   2924		    "BSG: ISP abort active/needed -- cmd=%d.\n",
   2925		    bsg_request->msgcode);
   2926		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   2927		return -EBUSY;
   2928	}
   2929
   2930	if (test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags)) {
   2931		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   2932		return -EIO;
   2933	}
   2934
   2935skip_chip_chk:
   2936	ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
   2937	    "Entered %s msgcode=0x%x. bsg ptr %px\n",
   2938	    __func__, bsg_request->msgcode, bsg_job);
   2939
   2940	switch (bsg_request->msgcode) {
   2941	case FC_BSG_RPT_ELS:
   2942	case FC_BSG_HST_ELS_NOLOGIN:
   2943		ret = qla2x00_process_els(bsg_job);
   2944		break;
   2945	case FC_BSG_HST_CT:
   2946		ret = qla2x00_process_ct(bsg_job);
   2947		break;
   2948	case FC_BSG_HST_VENDOR:
   2949		ret = qla2x00_process_vendor_specific(vha, bsg_job);
   2950		break;
   2951	case FC_BSG_HST_ADD_RPORT:
   2952	case FC_BSG_HST_DEL_RPORT:
   2953	case FC_BSG_RPT_CT:
   2954	default:
   2955		ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
   2956		break;
   2957	}
   2958
   2959	ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
   2960	    "%s done with return %x\n", __func__, ret);
   2961
   2962	return ret;
   2963}
   2964
   2965int
   2966qla24xx_bsg_timeout(struct bsg_job *bsg_job)
   2967{
   2968	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   2969	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
   2970	struct qla_hw_data *ha = vha->hw;
   2971	srb_t *sp;
   2972	int cnt, que;
   2973	unsigned long flags;
   2974	struct req_que *req;
   2975
   2976	ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n",
   2977	    __func__, bsg_job);
   2978	/* find the bsg job from the active list of commands */
   2979	spin_lock_irqsave(&ha->hardware_lock, flags);
   2980	for (que = 0; que < ha->max_req_queues; que++) {
   2981		req = ha->req_q_map[que];
   2982		if (!req)
   2983			continue;
   2984
   2985		for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
   2986			sp = req->outstanding_cmds[cnt];
   2987			if (sp &&
   2988			    (sp->type == SRB_CT_CMD ||
   2989			     sp->type == SRB_ELS_CMD_HST ||
   2990			     sp->type == SRB_ELS_CMD_HST_NOLOGIN ||
   2991			     sp->type == SRB_FXIOCB_BCMD) &&
   2992			    sp->u.bsg_job == bsg_job) {
   2993				req->outstanding_cmds[cnt] = NULL;
   2994				spin_unlock_irqrestore(&ha->hardware_lock, flags);
   2995				if (ha->isp_ops->abort_command(sp)) {
   2996					ql_log(ql_log_warn, vha, 0x7089,
   2997					    "mbx abort_command failed.\n");
   2998					bsg_reply->result = -EIO;
   2999				} else {
   3000					ql_dbg(ql_dbg_user, vha, 0x708a,
   3001					    "mbx abort_command success.\n");
   3002					bsg_reply->result = 0;
   3003				}
   3004				spin_lock_irqsave(&ha->hardware_lock, flags);
   3005				goto done;
   3006
   3007			}
   3008		}
   3009	}
   3010	spin_unlock_irqrestore(&ha->hardware_lock, flags);
   3011	ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
   3012	bsg_reply->result = -ENXIO;
   3013	return 0;
   3014
   3015done:
   3016	spin_unlock_irqrestore(&ha->hardware_lock, flags);
   3017	/* ref: INIT */
   3018	kref_put(&sp->cmd_kref, qla2x00_sp_release);
   3019	return 0;
   3020}
   3021
   3022int qla2x00_mailbox_passthru(struct bsg_job *bsg_job)
   3023{
   3024	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   3025	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
   3026	int ret = -EINVAL;
   3027	int ptsize = sizeof(struct qla_mbx_passthru);
   3028	struct qla_mbx_passthru *req_data = NULL;
   3029	uint32_t req_data_len;
   3030
   3031	req_data_len = bsg_job->request_payload.payload_len;
   3032	if (req_data_len != ptsize) {
   3033		ql_log(ql_log_warn, vha, 0xf0a3, "req_data_len invalid.\n");
   3034		return -EIO;
   3035	}
   3036	req_data = kzalloc(ptsize, GFP_KERNEL);
   3037	if (!req_data) {
   3038		ql_log(ql_log_warn, vha, 0xf0a4,
   3039		       "req_data memory allocation failure.\n");
   3040		return -ENOMEM;
   3041	}
   3042
   3043	/* Copy the request buffer in req_data */
   3044	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   3045			  bsg_job->request_payload.sg_cnt, req_data, ptsize);
   3046	ret = qla_mailbox_passthru(vha, req_data->mbx_in, req_data->mbx_out);
   3047
   3048	/* Copy the req_data in  request buffer */
   3049	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   3050			    bsg_job->reply_payload.sg_cnt, req_data, ptsize);
   3051
   3052	bsg_reply->reply_payload_rcv_len = ptsize;
   3053	if (ret == QLA_SUCCESS)
   3054		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
   3055	else
   3056		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_ERR;
   3057
   3058	bsg_job->reply_len = sizeof(*bsg_job->reply);
   3059	bsg_reply->result = DID_OK << 16;
   3060	bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
   3061
   3062	kfree(req_data);
   3063
   3064	return ret;
   3065}