xref: /openbmc/linux/drivers/scsi/qla2xxx/qla_bsg.c (revision 7ce05074)
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 
14 static 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 */
23 void 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 	sp->free(sp);
29 
30 	bsg_reply->result = res;
31 	bsg_job_done(bsg_job, bsg_reply->result,
32 		       bsg_reply->reply_payload_rcv_len);
33 }
34 
35 void qla2x00_bsg_sp_free(srb_t *sp)
36 {
37 	struct qla_hw_data *ha = sp->vha->hw;
38 	struct bsg_job *bsg_job = sp->u.bsg_job;
39 	struct fc_bsg_request *bsg_request = bsg_job->request;
40 	struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
41 
42 	if (sp->type == SRB_FXIOCB_BCMD) {
43 		piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
44 		    &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
45 
46 		if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
47 			dma_unmap_sg(&ha->pdev->dev,
48 			    bsg_job->request_payload.sg_list,
49 			    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
50 
51 		if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
52 			dma_unmap_sg(&ha->pdev->dev,
53 			    bsg_job->reply_payload.sg_list,
54 			    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
55 	} else {
56 		dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
57 		    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
58 
59 		dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
60 		    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
61 	}
62 
63 	if (sp->type == SRB_CT_CMD ||
64 	    sp->type == SRB_FXIOCB_BCMD ||
65 	    sp->type == SRB_ELS_CMD_HST) {
66 		INIT_WORK(&sp->fcport->free_work, qla2xxx_free_fcport_work);
67 		queue_work(ha->wq, &sp->fcport->free_work);
68 	}
69 
70 	qla2x00_rel_sp(sp);
71 }
72 
73 int
74 qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
75 	struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
76 {
77 	int i, ret, num_valid;
78 	uint8_t *bcode;
79 	struct qla_fcp_prio_entry *pri_entry;
80 	uint32_t *bcode_val_ptr, bcode_val;
81 
82 	ret = 1;
83 	num_valid = 0;
84 	bcode = (uint8_t *)pri_cfg;
85 	bcode_val_ptr = (uint32_t *)pri_cfg;
86 	bcode_val = (uint32_t)(*bcode_val_ptr);
87 
88 	if (bcode_val == 0xFFFFFFFF) {
89 		/* No FCP Priority config data in flash */
90 		ql_dbg(ql_dbg_user, vha, 0x7051,
91 		    "No FCP Priority config data.\n");
92 		return 0;
93 	}
94 
95 	if (memcmp(bcode, "HQOS", 4)) {
96 		/* Invalid FCP priority data header*/
97 		ql_dbg(ql_dbg_user, vha, 0x7052,
98 		    "Invalid FCP Priority data header. bcode=0x%x.\n",
99 		    bcode_val);
100 		return 0;
101 	}
102 	if (flag != 1)
103 		return ret;
104 
105 	pri_entry = &pri_cfg->entry[0];
106 	for (i = 0; i < pri_cfg->num_entries; i++) {
107 		if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
108 			num_valid++;
109 		pri_entry++;
110 	}
111 
112 	if (num_valid == 0) {
113 		/* No valid FCP priority data entries */
114 		ql_dbg(ql_dbg_user, vha, 0x7053,
115 		    "No valid FCP Priority data entries.\n");
116 		ret = 0;
117 	} else {
118 		/* FCP priority data is valid */
119 		ql_dbg(ql_dbg_user, vha, 0x7054,
120 		    "Valid FCP priority data. num entries = %d.\n",
121 		    num_valid);
122 	}
123 
124 	return ret;
125 }
126 
127 static int
128 qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
129 {
130 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
131 	struct fc_bsg_request *bsg_request = bsg_job->request;
132 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
133 	scsi_qla_host_t *vha = shost_priv(host);
134 	struct qla_hw_data *ha = vha->hw;
135 	int ret = 0;
136 	uint32_t len;
137 	uint32_t oper;
138 
139 	if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_P3P_TYPE(ha))) {
140 		ret = -EINVAL;
141 		goto exit_fcp_prio_cfg;
142 	}
143 
144 	/* Get the sub command */
145 	oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
146 
147 	/* Only set config is allowed if config memory is not allocated */
148 	if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
149 		ret = -EINVAL;
150 		goto exit_fcp_prio_cfg;
151 	}
152 	switch (oper) {
153 	case QLFC_FCP_PRIO_DISABLE:
154 		if (ha->flags.fcp_prio_enabled) {
155 			ha->flags.fcp_prio_enabled = 0;
156 			ha->fcp_prio_cfg->attributes &=
157 				~FCP_PRIO_ATTR_ENABLE;
158 			qla24xx_update_all_fcp_prio(vha);
159 			bsg_reply->result = DID_OK;
160 		} else {
161 			ret = -EINVAL;
162 			bsg_reply->result = (DID_ERROR << 16);
163 			goto exit_fcp_prio_cfg;
164 		}
165 		break;
166 
167 	case QLFC_FCP_PRIO_ENABLE:
168 		if (!ha->flags.fcp_prio_enabled) {
169 			if (ha->fcp_prio_cfg) {
170 				ha->flags.fcp_prio_enabled = 1;
171 				ha->fcp_prio_cfg->attributes |=
172 				    FCP_PRIO_ATTR_ENABLE;
173 				qla24xx_update_all_fcp_prio(vha);
174 				bsg_reply->result = DID_OK;
175 			} else {
176 				ret = -EINVAL;
177 				bsg_reply->result = (DID_ERROR << 16);
178 				goto exit_fcp_prio_cfg;
179 			}
180 		}
181 		break;
182 
183 	case QLFC_FCP_PRIO_GET_CONFIG:
184 		len = bsg_job->reply_payload.payload_len;
185 		if (!len || len > FCP_PRIO_CFG_SIZE) {
186 			ret = -EINVAL;
187 			bsg_reply->result = (DID_ERROR << 16);
188 			goto exit_fcp_prio_cfg;
189 		}
190 
191 		bsg_reply->result = DID_OK;
192 		bsg_reply->reply_payload_rcv_len =
193 			sg_copy_from_buffer(
194 			bsg_job->reply_payload.sg_list,
195 			bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
196 			len);
197 
198 		break;
199 
200 	case QLFC_FCP_PRIO_SET_CONFIG:
201 		len = bsg_job->request_payload.payload_len;
202 		if (!len || len > FCP_PRIO_CFG_SIZE) {
203 			bsg_reply->result = (DID_ERROR << 16);
204 			ret = -EINVAL;
205 			goto exit_fcp_prio_cfg;
206 		}
207 
208 		if (!ha->fcp_prio_cfg) {
209 			ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE);
210 			if (!ha->fcp_prio_cfg) {
211 				ql_log(ql_log_warn, vha, 0x7050,
212 				    "Unable to allocate memory for fcp prio "
213 				    "config data (%x).\n", FCP_PRIO_CFG_SIZE);
214 				bsg_reply->result = (DID_ERROR << 16);
215 				ret = -ENOMEM;
216 				goto exit_fcp_prio_cfg;
217 			}
218 		}
219 
220 		memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE);
221 		sg_copy_to_buffer(bsg_job->request_payload.sg_list,
222 		bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg,
223 			FCP_PRIO_CFG_SIZE);
224 
225 		/* validate fcp priority data */
226 
227 		if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 1)) {
228 			bsg_reply->result = (DID_ERROR << 16);
229 			ret = -EINVAL;
230 			/* If buffer was invalidatic int
231 			 * fcp_prio_cfg is of no use
232 			 */
233 			vfree(ha->fcp_prio_cfg);
234 			ha->fcp_prio_cfg = NULL;
235 			goto exit_fcp_prio_cfg;
236 		}
237 
238 		ha->flags.fcp_prio_enabled = 0;
239 		if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
240 			ha->flags.fcp_prio_enabled = 1;
241 		qla24xx_update_all_fcp_prio(vha);
242 		bsg_reply->result = DID_OK;
243 		break;
244 	default:
245 		ret = -EINVAL;
246 		break;
247 	}
248 exit_fcp_prio_cfg:
249 	if (!ret)
250 		bsg_job_done(bsg_job, bsg_reply->result,
251 			       bsg_reply->reply_payload_rcv_len);
252 	return ret;
253 }
254 
255 static int
256 qla2x00_process_els(struct bsg_job *bsg_job)
257 {
258 	struct fc_bsg_request *bsg_request = bsg_job->request;
259 	struct fc_rport *rport;
260 	fc_port_t *fcport = NULL;
261 	struct Scsi_Host *host;
262 	scsi_qla_host_t *vha;
263 	struct qla_hw_data *ha;
264 	srb_t *sp;
265 	const char *type;
266 	int req_sg_cnt, rsp_sg_cnt;
267 	int rval =  (DID_ERROR << 16);
268 	uint16_t nextlid = 0;
269 
270 	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
271 		rport = fc_bsg_to_rport(bsg_job);
272 		fcport = *(fc_port_t **) rport->dd_data;
273 		host = rport_to_shost(rport);
274 		vha = shost_priv(host);
275 		ha = vha->hw;
276 		type = "FC_BSG_RPT_ELS";
277 	} else {
278 		host = fc_bsg_to_shost(bsg_job);
279 		vha = shost_priv(host);
280 		ha = vha->hw;
281 		type = "FC_BSG_HST_ELS_NOLOGIN";
282 	}
283 
284 	if (!vha->flags.online) {
285 		ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
286 		rval = -EIO;
287 		goto done;
288 	}
289 
290 	/* pass through is supported only for ISP 4Gb or higher */
291 	if (!IS_FWI2_CAPABLE(ha)) {
292 		ql_dbg(ql_dbg_user, vha, 0x7001,
293 		    "ELS passthru not supported for ISP23xx based adapters.\n");
294 		rval = -EPERM;
295 		goto done;
296 	}
297 
298 	/*  Multiple SG's are not supported for ELS requests */
299 	if (bsg_job->request_payload.sg_cnt > 1 ||
300 		bsg_job->reply_payload.sg_cnt > 1) {
301 		ql_dbg(ql_dbg_user, vha, 0x7002,
302 		    "Multiple SG's are not supported for ELS requests, "
303 		    "request_sg_cnt=%x reply_sg_cnt=%x.\n",
304 		    bsg_job->request_payload.sg_cnt,
305 		    bsg_job->reply_payload.sg_cnt);
306 		rval = -EPERM;
307 		goto done;
308 	}
309 
310 	/* ELS request for rport */
311 	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
312 		/* make sure the rport is logged in,
313 		 * if not perform fabric login
314 		 */
315 		if (qla2x00_fabric_login(vha, fcport, &nextlid)) {
316 			ql_dbg(ql_dbg_user, vha, 0x7003,
317 			    "Failed to login port %06X for ELS passthru.\n",
318 			    fcport->d_id.b24);
319 			rval = -EIO;
320 			goto done;
321 		}
322 	} else {
323 		/* Allocate a dummy fcport structure, since functions
324 		 * preparing the IOCB and mailbox command retrieves port
325 		 * specific information from fcport structure. For Host based
326 		 * ELS commands there will be no fcport structure allocated
327 		 */
328 		fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
329 		if (!fcport) {
330 			rval = -ENOMEM;
331 			goto done;
332 		}
333 
334 		/* Initialize all required  fields of fcport */
335 		fcport->vha = vha;
336 		fcport->d_id.b.al_pa =
337 			bsg_request->rqst_data.h_els.port_id[0];
338 		fcport->d_id.b.area =
339 			bsg_request->rqst_data.h_els.port_id[1];
340 		fcport->d_id.b.domain =
341 			bsg_request->rqst_data.h_els.port_id[2];
342 		fcport->loop_id =
343 			(fcport->d_id.b.al_pa == 0xFD) ?
344 			NPH_FABRIC_CONTROLLER : NPH_F_PORT;
345 	}
346 
347 	req_sg_cnt =
348 		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
349 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
350 	if (!req_sg_cnt) {
351 		dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
352 		    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
353 		rval = -ENOMEM;
354 		goto done_free_fcport;
355 	}
356 
357 	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
358 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
359         if (!rsp_sg_cnt) {
360 		dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
361 		    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
362 		rval = -ENOMEM;
363 		goto done_free_fcport;
364 	}
365 
366 	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
367 		(rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
368 		ql_log(ql_log_warn, vha, 0x7008,
369 		    "dma mapping resulted in different sg counts, "
370 		    "request_sg_cnt: %x dma_request_sg_cnt:%x reply_sg_cnt:%x "
371 		    "dma_reply_sg_cnt:%x.\n", bsg_job->request_payload.sg_cnt,
372 		    req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
373 		rval = -EAGAIN;
374 		goto done_unmap_sg;
375 	}
376 
377 	/* Alloc SRB structure */
378 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
379 	if (!sp) {
380 		rval = -ENOMEM;
381 		goto done_unmap_sg;
382 	}
383 
384 	sp->type =
385 		(bsg_request->msgcode == FC_BSG_RPT_ELS ?
386 		 SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
387 	sp->name =
388 		(bsg_request->msgcode == FC_BSG_RPT_ELS ?
389 		 "bsg_els_rpt" : "bsg_els_hst");
390 	sp->u.bsg_job = bsg_job;
391 	sp->free = qla2x00_bsg_sp_free;
392 	sp->done = qla2x00_bsg_job_done;
393 
394 	ql_dbg(ql_dbg_user, vha, 0x700a,
395 	    "bsg rqst type: %s els type: %x - loop-id=%x "
396 	    "portid=%-2x%02x%02x.\n", type,
397 	    bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
398 	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
399 
400 	rval = qla2x00_start_sp(sp);
401 	if (rval != QLA_SUCCESS) {
402 		ql_log(ql_log_warn, vha, 0x700e,
403 		    "qla2x00_start_sp failed = %d\n", rval);
404 		qla2x00_rel_sp(sp);
405 		rval = -EIO;
406 		goto done_unmap_sg;
407 	}
408 	return rval;
409 
410 done_unmap_sg:
411 	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
412 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
413 	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
414 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
415 	goto done_free_fcport;
416 
417 done_free_fcport:
418 	if (bsg_request->msgcode == FC_BSG_RPT_ELS)
419 		qla2x00_free_fcport(fcport);
420 done:
421 	return rval;
422 }
423 
424 static inline uint16_t
425 qla24xx_calc_ct_iocbs(uint16_t dsds)
426 {
427 	uint16_t iocbs;
428 
429 	iocbs = 1;
430 	if (dsds > 2) {
431 		iocbs += (dsds - 2) / 5;
432 		if ((dsds - 2) % 5)
433 			iocbs++;
434 	}
435 	return iocbs;
436 }
437 
438 static int
439 qla2x00_process_ct(struct bsg_job *bsg_job)
440 {
441 	srb_t *sp;
442 	struct fc_bsg_request *bsg_request = bsg_job->request;
443 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
444 	scsi_qla_host_t *vha = shost_priv(host);
445 	struct qla_hw_data *ha = vha->hw;
446 	int rval = (DID_ERROR << 16);
447 	int req_sg_cnt, rsp_sg_cnt;
448 	uint16_t loop_id;
449 	struct fc_port *fcport;
450 	char  *type = "FC_BSG_HST_CT";
451 
452 	req_sg_cnt =
453 		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
454 			bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
455 	if (!req_sg_cnt) {
456 		ql_log(ql_log_warn, vha, 0x700f,
457 		    "dma_map_sg return %d for request\n", req_sg_cnt);
458 		rval = -ENOMEM;
459 		goto done;
460 	}
461 
462 	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
463 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
464 	if (!rsp_sg_cnt) {
465 		ql_log(ql_log_warn, vha, 0x7010,
466 		    "dma_map_sg return %d for reply\n", rsp_sg_cnt);
467 		rval = -ENOMEM;
468 		goto done;
469 	}
470 
471 	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
472 	    (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
473 		ql_log(ql_log_warn, vha, 0x7011,
474 		    "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
475 		    "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
476 		    req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
477 		rval = -EAGAIN;
478 		goto done_unmap_sg;
479 	}
480 
481 	if (!vha->flags.online) {
482 		ql_log(ql_log_warn, vha, 0x7012,
483 		    "Host is not online.\n");
484 		rval = -EIO;
485 		goto done_unmap_sg;
486 	}
487 
488 	loop_id =
489 		(bsg_request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
490 			>> 24;
491 	switch (loop_id) {
492 	case 0xFC:
493 		loop_id = NPH_SNS;
494 		break;
495 	case 0xFA:
496 		loop_id = vha->mgmt_svr_loop_id;
497 		break;
498 	default:
499 		ql_dbg(ql_dbg_user, vha, 0x7013,
500 		    "Unknown loop id: %x.\n", loop_id);
501 		rval = -EINVAL;
502 		goto done_unmap_sg;
503 	}
504 
505 	/* Allocate a dummy fcport structure, since functions preparing the
506 	 * IOCB and mailbox command retrieves port specific information
507 	 * from fcport structure. For Host based ELS commands there will be
508 	 * no fcport structure allocated
509 	 */
510 	fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
511 	if (!fcport) {
512 		ql_log(ql_log_warn, vha, 0x7014,
513 		    "Failed to allocate fcport.\n");
514 		rval = -ENOMEM;
515 		goto done_unmap_sg;
516 	}
517 
518 	/* Initialize all required  fields of fcport */
519 	fcport->vha = vha;
520 	fcport->d_id.b.al_pa = bsg_request->rqst_data.h_ct.port_id[0];
521 	fcport->d_id.b.area = bsg_request->rqst_data.h_ct.port_id[1];
522 	fcport->d_id.b.domain = bsg_request->rqst_data.h_ct.port_id[2];
523 	fcport->loop_id = loop_id;
524 
525 	/* Alloc SRB structure */
526 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
527 	if (!sp) {
528 		ql_log(ql_log_warn, vha, 0x7015,
529 		    "qla2x00_get_sp failed.\n");
530 		rval = -ENOMEM;
531 		goto done_free_fcport;
532 	}
533 
534 	sp->type = SRB_CT_CMD;
535 	sp->name = "bsg_ct";
536 	sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
537 	sp->u.bsg_job = bsg_job;
538 	sp->free = qla2x00_bsg_sp_free;
539 	sp->done = qla2x00_bsg_job_done;
540 
541 	ql_dbg(ql_dbg_user, vha, 0x7016,
542 	    "bsg rqst type: %s else type: %x - "
543 	    "loop-id=%x portid=%02x%02x%02x.\n", type,
544 	    (bsg_request->rqst_data.h_ct.preamble_word2 >> 16),
545 	    fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
546 	    fcport->d_id.b.al_pa);
547 
548 	rval = qla2x00_start_sp(sp);
549 	if (rval != QLA_SUCCESS) {
550 		ql_log(ql_log_warn, vha, 0x7017,
551 		    "qla2x00_start_sp failed=%d.\n", rval);
552 		qla2x00_rel_sp(sp);
553 		rval = -EIO;
554 		goto done_free_fcport;
555 	}
556 	return rval;
557 
558 done_free_fcport:
559 	qla2x00_free_fcport(fcport);
560 done_unmap_sg:
561 	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
562 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
563 	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
564 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
565 done:
566 	return rval;
567 }
568 
569 /* Disable loopback mode */
570 static inline int
571 qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
572 			    int wait, int wait2)
573 {
574 	int ret = 0;
575 	int rval = 0;
576 	uint16_t new_config[4];
577 	struct qla_hw_data *ha = vha->hw;
578 
579 	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
580 		goto done_reset_internal;
581 
582 	memset(new_config, 0 , sizeof(new_config));
583 	if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
584 	    ENABLE_INTERNAL_LOOPBACK ||
585 	    (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
586 	    ENABLE_EXTERNAL_LOOPBACK) {
587 		new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
588 		ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
589 		    (new_config[0] & INTERNAL_LOOPBACK_MASK));
590 		memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
591 
592 		ha->notify_dcbx_comp = wait;
593 		ha->notify_lb_portup_comp = wait2;
594 
595 		ret = qla81xx_set_port_config(vha, new_config);
596 		if (ret != QLA_SUCCESS) {
597 			ql_log(ql_log_warn, vha, 0x7025,
598 			    "Set port config failed.\n");
599 			ha->notify_dcbx_comp = 0;
600 			ha->notify_lb_portup_comp = 0;
601 			rval = -EINVAL;
602 			goto done_reset_internal;
603 		}
604 
605 		/* Wait for DCBX complete event */
606 		if (wait && !wait_for_completion_timeout(&ha->dcbx_comp,
607 			(DCBX_COMP_TIMEOUT * HZ))) {
608 			ql_dbg(ql_dbg_user, vha, 0x7026,
609 			    "DCBX completion not received.\n");
610 			ha->notify_dcbx_comp = 0;
611 			ha->notify_lb_portup_comp = 0;
612 			rval = -EINVAL;
613 			goto done_reset_internal;
614 		} else
615 			ql_dbg(ql_dbg_user, vha, 0x7027,
616 			    "DCBX completion received.\n");
617 
618 		if (wait2 &&
619 		    !wait_for_completion_timeout(&ha->lb_portup_comp,
620 		    (LB_PORTUP_COMP_TIMEOUT * HZ))) {
621 			ql_dbg(ql_dbg_user, vha, 0x70c5,
622 			    "Port up completion not received.\n");
623 			ha->notify_lb_portup_comp = 0;
624 			rval = -EINVAL;
625 			goto done_reset_internal;
626 		} else
627 			ql_dbg(ql_dbg_user, vha, 0x70c6,
628 			    "Port up completion received.\n");
629 
630 		ha->notify_dcbx_comp = 0;
631 		ha->notify_lb_portup_comp = 0;
632 	}
633 done_reset_internal:
634 	return rval;
635 }
636 
637 /*
638  * Set the port configuration to enable the internal or external loopback
639  * depending on the loopback mode.
640  */
641 static inline int
642 qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
643 	uint16_t *new_config, uint16_t mode)
644 {
645 	int ret = 0;
646 	int rval = 0;
647 	unsigned long rem_tmo = 0, current_tmo = 0;
648 	struct qla_hw_data *ha = vha->hw;
649 
650 	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
651 		goto done_set_internal;
652 
653 	if (mode == INTERNAL_LOOPBACK)
654 		new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
655 	else if (mode == EXTERNAL_LOOPBACK)
656 		new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
657 	ql_dbg(ql_dbg_user, vha, 0x70be,
658 	     "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));
659 
660 	memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);
661 
662 	ha->notify_dcbx_comp = 1;
663 	ret = qla81xx_set_port_config(vha, new_config);
664 	if (ret != QLA_SUCCESS) {
665 		ql_log(ql_log_warn, vha, 0x7021,
666 		    "set port config failed.\n");
667 		ha->notify_dcbx_comp = 0;
668 		rval = -EINVAL;
669 		goto done_set_internal;
670 	}
671 
672 	/* Wait for DCBX complete event */
673 	current_tmo = DCBX_COMP_TIMEOUT * HZ;
674 	while (1) {
675 		rem_tmo = wait_for_completion_timeout(&ha->dcbx_comp,
676 		    current_tmo);
677 		if (!ha->idc_extend_tmo || rem_tmo) {
678 			ha->idc_extend_tmo = 0;
679 			break;
680 		}
681 		current_tmo = ha->idc_extend_tmo * HZ;
682 		ha->idc_extend_tmo = 0;
683 	}
684 
685 	if (!rem_tmo) {
686 		ql_dbg(ql_dbg_user, vha, 0x7022,
687 		    "DCBX completion not received.\n");
688 		ret = qla81xx_reset_loopback_mode(vha, new_config, 0, 0);
689 		/*
690 		 * If the reset of the loopback mode doesn't work take a FCoE
691 		 * dump and reset the chip.
692 		 */
693 		if (ret) {
694 			qla2xxx_dump_fw(vha);
695 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
696 		}
697 		rval = -EINVAL;
698 	} else {
699 		if (ha->flags.idc_compl_status) {
700 			ql_dbg(ql_dbg_user, vha, 0x70c3,
701 			    "Bad status in IDC Completion AEN\n");
702 			rval = -EINVAL;
703 			ha->flags.idc_compl_status = 0;
704 		} else
705 			ql_dbg(ql_dbg_user, vha, 0x7023,
706 			    "DCBX completion received.\n");
707 	}
708 
709 	ha->notify_dcbx_comp = 0;
710 	ha->idc_extend_tmo = 0;
711 
712 done_set_internal:
713 	return rval;
714 }
715 
716 static int
717 qla2x00_process_loopback(struct bsg_job *bsg_job)
718 {
719 	struct fc_bsg_request *bsg_request = bsg_job->request;
720 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
721 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
722 	scsi_qla_host_t *vha = shost_priv(host);
723 	struct qla_hw_data *ha = vha->hw;
724 	int rval;
725 	uint8_t command_sent;
726 	char *type;
727 	struct msg_echo_lb elreq;
728 	uint16_t response[MAILBOX_REGISTER_COUNT];
729 	uint16_t config[4], new_config[4];
730 	uint8_t *fw_sts_ptr;
731 	void *req_data = NULL;
732 	dma_addr_t req_data_dma;
733 	uint32_t req_data_len;
734 	uint8_t *rsp_data = NULL;
735 	dma_addr_t rsp_data_dma;
736 	uint32_t rsp_data_len;
737 
738 	if (!vha->flags.online) {
739 		ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
740 		return -EIO;
741 	}
742 
743 	memset(&elreq, 0, sizeof(elreq));
744 
745 	elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
746 		bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt,
747 		DMA_TO_DEVICE);
748 
749 	if (!elreq.req_sg_cnt) {
750 		ql_log(ql_log_warn, vha, 0x701a,
751 		    "dma_map_sg returned %d for request.\n", elreq.req_sg_cnt);
752 		return -ENOMEM;
753 	}
754 
755 	elreq.rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
756 		bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
757 		DMA_FROM_DEVICE);
758 
759 	if (!elreq.rsp_sg_cnt) {
760 		ql_log(ql_log_warn, vha, 0x701b,
761 		    "dma_map_sg returned %d for reply.\n", elreq.rsp_sg_cnt);
762 		rval = -ENOMEM;
763 		goto done_unmap_req_sg;
764 	}
765 
766 	if ((elreq.req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
767 		(elreq.rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
768 		ql_log(ql_log_warn, vha, 0x701c,
769 		    "dma mapping resulted in different sg counts, "
770 		    "request_sg_cnt: %x dma_request_sg_cnt: %x "
771 		    "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
772 		    bsg_job->request_payload.sg_cnt, elreq.req_sg_cnt,
773 		    bsg_job->reply_payload.sg_cnt, elreq.rsp_sg_cnt);
774 		rval = -EAGAIN;
775 		goto done_unmap_sg;
776 	}
777 	req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
778 	req_data = dma_alloc_coherent(&ha->pdev->dev, req_data_len,
779 		&req_data_dma, GFP_KERNEL);
780 	if (!req_data) {
781 		ql_log(ql_log_warn, vha, 0x701d,
782 		    "dma alloc failed for req_data.\n");
783 		rval = -ENOMEM;
784 		goto done_unmap_sg;
785 	}
786 
787 	rsp_data = dma_alloc_coherent(&ha->pdev->dev, rsp_data_len,
788 		&rsp_data_dma, GFP_KERNEL);
789 	if (!rsp_data) {
790 		ql_log(ql_log_warn, vha, 0x7004,
791 		    "dma alloc failed for rsp_data.\n");
792 		rval = -ENOMEM;
793 		goto done_free_dma_req;
794 	}
795 
796 	/* Copy the request buffer in req_data now */
797 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
798 		bsg_job->request_payload.sg_cnt, req_data, req_data_len);
799 
800 	elreq.send_dma = req_data_dma;
801 	elreq.rcv_dma = rsp_data_dma;
802 	elreq.transfer_size = req_data_len;
803 
804 	elreq.options = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
805 	elreq.iteration_count =
806 	    bsg_request->rqst_data.h_vendor.vendor_cmd[2];
807 
808 	if (atomic_read(&vha->loop_state) == LOOP_READY &&
809 	    ((ha->current_topology == ISP_CFG_F && (elreq.options & 7) >= 2) ||
810 	    ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
811 	    get_unaligned_le32(req_data) == ELS_OPCODE_BYTE &&
812 	    req_data_len == MAX_ELS_FRAME_PAYLOAD &&
813 	    elreq.options == EXTERNAL_LOOPBACK))) {
814 		type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
815 		ql_dbg(ql_dbg_user, vha, 0x701e,
816 		    "BSG request type: %s.\n", type);
817 		command_sent = INT_DEF_LB_ECHO_CMD;
818 		rval = qla2x00_echo_test(vha, &elreq, response);
819 	} else {
820 		if (IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) {
821 			memset(config, 0, sizeof(config));
822 			memset(new_config, 0, sizeof(new_config));
823 
824 			if (qla81xx_get_port_config(vha, config)) {
825 				ql_log(ql_log_warn, vha, 0x701f,
826 				    "Get port config failed.\n");
827 				rval = -EPERM;
828 				goto done_free_dma_rsp;
829 			}
830 
831 			if ((config[0] & INTERNAL_LOOPBACK_MASK) != 0) {
832 				ql_dbg(ql_dbg_user, vha, 0x70c4,
833 				    "Loopback operation already in "
834 				    "progress.\n");
835 				rval = -EAGAIN;
836 				goto done_free_dma_rsp;
837 			}
838 
839 			ql_dbg(ql_dbg_user, vha, 0x70c0,
840 			    "elreq.options=%04x\n", elreq.options);
841 
842 			if (elreq.options == EXTERNAL_LOOPBACK)
843 				if (IS_QLA8031(ha) || IS_QLA8044(ha))
844 					rval = qla81xx_set_loopback_mode(vha,
845 					    config, new_config, elreq.options);
846 				else
847 					rval = qla81xx_reset_loopback_mode(vha,
848 					    config, 1, 0);
849 			else
850 				rval = qla81xx_set_loopback_mode(vha, config,
851 				    new_config, elreq.options);
852 
853 			if (rval) {
854 				rval = -EPERM;
855 				goto done_free_dma_rsp;
856 			}
857 
858 			type = "FC_BSG_HST_VENDOR_LOOPBACK";
859 			ql_dbg(ql_dbg_user, vha, 0x7028,
860 			    "BSG request type: %s.\n", type);
861 
862 			command_sent = INT_DEF_LB_LOOPBACK_CMD;
863 			rval = qla2x00_loopback_test(vha, &elreq, response);
864 
865 			if (response[0] == MBS_COMMAND_ERROR &&
866 					response[1] == MBS_LB_RESET) {
867 				ql_log(ql_log_warn, vha, 0x7029,
868 				    "MBX command error, Aborting ISP.\n");
869 				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
870 				qla2xxx_wake_dpc(vha);
871 				qla2x00_wait_for_chip_reset(vha);
872 				/* Also reset the MPI */
873 				if (IS_QLA81XX(ha)) {
874 					if (qla81xx_restart_mpi_firmware(vha) !=
875 					    QLA_SUCCESS) {
876 						ql_log(ql_log_warn, vha, 0x702a,
877 						    "MPI reset failed.\n");
878 					}
879 				}
880 
881 				rval = -EIO;
882 				goto done_free_dma_rsp;
883 			}
884 
885 			if (new_config[0]) {
886 				int ret;
887 
888 				/* Revert back to original port config
889 				 * Also clear internal loopback
890 				 */
891 				ret = qla81xx_reset_loopback_mode(vha,
892 				    new_config, 0, 1);
893 				if (ret) {
894 					/*
895 					 * If the reset of the loopback mode
896 					 * doesn't work take FCoE dump and then
897 					 * reset the chip.
898 					 */
899 					qla2xxx_dump_fw(vha);
900 					set_bit(ISP_ABORT_NEEDED,
901 					    &vha->dpc_flags);
902 				}
903 
904 			}
905 
906 		} else {
907 			type = "FC_BSG_HST_VENDOR_LOOPBACK";
908 			ql_dbg(ql_dbg_user, vha, 0x702b,
909 			    "BSG request type: %s.\n", type);
910 			command_sent = INT_DEF_LB_LOOPBACK_CMD;
911 			rval = qla2x00_loopback_test(vha, &elreq, response);
912 		}
913 	}
914 
915 	if (rval) {
916 		ql_log(ql_log_warn, vha, 0x702c,
917 		    "Vendor request %s failed.\n", type);
918 
919 		rval = 0;
920 		bsg_reply->result = (DID_ERROR << 16);
921 		bsg_reply->reply_payload_rcv_len = 0;
922 	} else {
923 		ql_dbg(ql_dbg_user, vha, 0x702d,
924 		    "Vendor request %s completed.\n", type);
925 		bsg_reply->result = (DID_OK << 16);
926 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
927 			bsg_job->reply_payload.sg_cnt, rsp_data,
928 			rsp_data_len);
929 	}
930 
931 	bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
932 	    sizeof(response) + sizeof(uint8_t);
933 	fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply);
934 	memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), response,
935 			sizeof(response));
936 	fw_sts_ptr += sizeof(response);
937 	*fw_sts_ptr = command_sent;
938 
939 done_free_dma_rsp:
940 	dma_free_coherent(&ha->pdev->dev, rsp_data_len,
941 		rsp_data, rsp_data_dma);
942 done_free_dma_req:
943 	dma_free_coherent(&ha->pdev->dev, req_data_len,
944 		req_data, req_data_dma);
945 done_unmap_sg:
946 	dma_unmap_sg(&ha->pdev->dev,
947 	    bsg_job->reply_payload.sg_list,
948 	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
949 done_unmap_req_sg:
950 	dma_unmap_sg(&ha->pdev->dev,
951 	    bsg_job->request_payload.sg_list,
952 	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
953 	if (!rval)
954 		bsg_job_done(bsg_job, bsg_reply->result,
955 			       bsg_reply->reply_payload_rcv_len);
956 	return rval;
957 }
958 
959 static int
960 qla84xx_reset(struct bsg_job *bsg_job)
961 {
962 	struct fc_bsg_request *bsg_request = bsg_job->request;
963 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
964 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
965 	scsi_qla_host_t *vha = shost_priv(host);
966 	struct qla_hw_data *ha = vha->hw;
967 	int rval = 0;
968 	uint32_t flag;
969 
970 	if (!IS_QLA84XX(ha)) {
971 		ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
972 		return -EINVAL;
973 	}
974 
975 	flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
976 
977 	rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
978 
979 	if (rval) {
980 		ql_log(ql_log_warn, vha, 0x7030,
981 		    "Vendor request 84xx reset failed.\n");
982 		rval = (DID_ERROR << 16);
983 
984 	} else {
985 		ql_dbg(ql_dbg_user, vha, 0x7031,
986 		    "Vendor request 84xx reset completed.\n");
987 		bsg_reply->result = DID_OK;
988 		bsg_job_done(bsg_job, bsg_reply->result,
989 			       bsg_reply->reply_payload_rcv_len);
990 	}
991 
992 	return rval;
993 }
994 
995 static int
996 qla84xx_updatefw(struct bsg_job *bsg_job)
997 {
998 	struct fc_bsg_request *bsg_request = bsg_job->request;
999 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1000 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1001 	scsi_qla_host_t *vha = shost_priv(host);
1002 	struct qla_hw_data *ha = vha->hw;
1003 	struct verify_chip_entry_84xx *mn = NULL;
1004 	dma_addr_t mn_dma, fw_dma;
1005 	void *fw_buf = NULL;
1006 	int rval = 0;
1007 	uint32_t sg_cnt;
1008 	uint32_t data_len;
1009 	uint16_t options;
1010 	uint32_t flag;
1011 	uint32_t fw_ver;
1012 
1013 	if (!IS_QLA84XX(ha)) {
1014 		ql_dbg(ql_dbg_user, vha, 0x7032,
1015 		    "Not 84xx, exiting.\n");
1016 		return -EINVAL;
1017 	}
1018 
1019 	sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1020 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1021 	if (!sg_cnt) {
1022 		ql_log(ql_log_warn, vha, 0x7033,
1023 		    "dma_map_sg returned %d for request.\n", sg_cnt);
1024 		return -ENOMEM;
1025 	}
1026 
1027 	if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1028 		ql_log(ql_log_warn, vha, 0x7034,
1029 		    "DMA mapping resulted in different sg counts, "
1030 		    "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1031 		    bsg_job->request_payload.sg_cnt, sg_cnt);
1032 		rval = -EAGAIN;
1033 		goto done_unmap_sg;
1034 	}
1035 
1036 	data_len = bsg_job->request_payload.payload_len;
1037 	fw_buf = dma_alloc_coherent(&ha->pdev->dev, data_len,
1038 		&fw_dma, GFP_KERNEL);
1039 	if (!fw_buf) {
1040 		ql_log(ql_log_warn, vha, 0x7035,
1041 		    "DMA alloc failed for fw_buf.\n");
1042 		rval = -ENOMEM;
1043 		goto done_unmap_sg;
1044 	}
1045 
1046 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1047 		bsg_job->request_payload.sg_cnt, fw_buf, data_len);
1048 
1049 	mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1050 	if (!mn) {
1051 		ql_log(ql_log_warn, vha, 0x7036,
1052 		    "DMA alloc failed for fw buffer.\n");
1053 		rval = -ENOMEM;
1054 		goto done_free_fw_buf;
1055 	}
1056 
1057 	flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1058 	fw_ver = get_unaligned_le32((uint32_t *)fw_buf + 2);
1059 
1060 	mn->entry_type = VERIFY_CHIP_IOCB_TYPE;
1061 	mn->entry_count = 1;
1062 
1063 	options = VCO_FORCE_UPDATE | VCO_END_OF_DATA;
1064 	if (flag == A84_ISSUE_UPDATE_DIAGFW_CMD)
1065 		options |= VCO_DIAG_FW;
1066 
1067 	mn->options = cpu_to_le16(options);
1068 	mn->fw_ver =  cpu_to_le32(fw_ver);
1069 	mn->fw_size =  cpu_to_le32(data_len);
1070 	mn->fw_seq_size =  cpu_to_le32(data_len);
1071 	put_unaligned_le64(fw_dma, &mn->dsd.address);
1072 	mn->dsd.length = cpu_to_le32(data_len);
1073 	mn->data_seg_cnt = cpu_to_le16(1);
1074 
1075 	rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
1076 
1077 	if (rval) {
1078 		ql_log(ql_log_warn, vha, 0x7037,
1079 		    "Vendor request 84xx updatefw failed.\n");
1080 
1081 		rval = (DID_ERROR << 16);
1082 	} else {
1083 		ql_dbg(ql_dbg_user, vha, 0x7038,
1084 		    "Vendor request 84xx updatefw completed.\n");
1085 
1086 		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1087 		bsg_reply->result = DID_OK;
1088 	}
1089 
1090 	dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1091 
1092 done_free_fw_buf:
1093 	dma_free_coherent(&ha->pdev->dev, data_len, fw_buf, fw_dma);
1094 
1095 done_unmap_sg:
1096 	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1097 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1098 
1099 	if (!rval)
1100 		bsg_job_done(bsg_job, bsg_reply->result,
1101 			       bsg_reply->reply_payload_rcv_len);
1102 	return rval;
1103 }
1104 
1105 static int
1106 qla84xx_mgmt_cmd(struct bsg_job *bsg_job)
1107 {
1108 	struct fc_bsg_request *bsg_request = bsg_job->request;
1109 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1110 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1111 	scsi_qla_host_t *vha = shost_priv(host);
1112 	struct qla_hw_data *ha = vha->hw;
1113 	struct access_chip_84xx *mn = NULL;
1114 	dma_addr_t mn_dma, mgmt_dma;
1115 	void *mgmt_b = NULL;
1116 	int rval = 0;
1117 	struct qla_bsg_a84_mgmt *ql84_mgmt;
1118 	uint32_t sg_cnt;
1119 	uint32_t data_len = 0;
1120 	uint32_t dma_direction = DMA_NONE;
1121 
1122 	if (!IS_QLA84XX(ha)) {
1123 		ql_log(ql_log_warn, vha, 0x703a,
1124 		    "Not 84xx, exiting.\n");
1125 		return -EINVAL;
1126 	}
1127 
1128 	mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1129 	if (!mn) {
1130 		ql_log(ql_log_warn, vha, 0x703c,
1131 		    "DMA alloc failed for fw buffer.\n");
1132 		return -ENOMEM;
1133 	}
1134 
1135 	mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
1136 	mn->entry_count = 1;
1137 	ql84_mgmt = (void *)bsg_request + sizeof(struct fc_bsg_request);
1138 	switch (ql84_mgmt->mgmt.cmd) {
1139 	case QLA84_MGMT_READ_MEM:
1140 	case QLA84_MGMT_GET_INFO:
1141 		sg_cnt = dma_map_sg(&ha->pdev->dev,
1142 			bsg_job->reply_payload.sg_list,
1143 			bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1144 		if (!sg_cnt) {
1145 			ql_log(ql_log_warn, vha, 0x703d,
1146 			    "dma_map_sg returned %d for reply.\n", sg_cnt);
1147 			rval = -ENOMEM;
1148 			goto exit_mgmt;
1149 		}
1150 
1151 		dma_direction = DMA_FROM_DEVICE;
1152 
1153 		if (sg_cnt != bsg_job->reply_payload.sg_cnt) {
1154 			ql_log(ql_log_warn, vha, 0x703e,
1155 			    "DMA mapping resulted in different sg counts, "
1156 			    "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
1157 			    bsg_job->reply_payload.sg_cnt, sg_cnt);
1158 			rval = -EAGAIN;
1159 			goto done_unmap_sg;
1160 		}
1161 
1162 		data_len = bsg_job->reply_payload.payload_len;
1163 
1164 		mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1165 		    &mgmt_dma, GFP_KERNEL);
1166 		if (!mgmt_b) {
1167 			ql_log(ql_log_warn, vha, 0x703f,
1168 			    "DMA alloc failed for mgmt_b.\n");
1169 			rval = -ENOMEM;
1170 			goto done_unmap_sg;
1171 		}
1172 
1173 		if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) {
1174 			mn->options = cpu_to_le16(ACO_DUMP_MEMORY);
1175 			mn->parameter1 =
1176 				cpu_to_le32(
1177 				ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1178 
1179 		} else if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO) {
1180 			mn->options = cpu_to_le16(ACO_REQUEST_INFO);
1181 			mn->parameter1 =
1182 				cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.info.type);
1183 
1184 			mn->parameter2 =
1185 				cpu_to_le32(
1186 				ql84_mgmt->mgmt.mgmtp.u.info.context);
1187 		}
1188 		break;
1189 
1190 	case QLA84_MGMT_WRITE_MEM:
1191 		sg_cnt = dma_map_sg(&ha->pdev->dev,
1192 			bsg_job->request_payload.sg_list,
1193 			bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1194 
1195 		if (!sg_cnt) {
1196 			ql_log(ql_log_warn, vha, 0x7040,
1197 			    "dma_map_sg returned %d.\n", sg_cnt);
1198 			rval = -ENOMEM;
1199 			goto exit_mgmt;
1200 		}
1201 
1202 		dma_direction = DMA_TO_DEVICE;
1203 
1204 		if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1205 			ql_log(ql_log_warn, vha, 0x7041,
1206 			    "DMA mapping resulted in different sg counts, "
1207 			    "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1208 			    bsg_job->request_payload.sg_cnt, sg_cnt);
1209 			rval = -EAGAIN;
1210 			goto done_unmap_sg;
1211 		}
1212 
1213 		data_len = bsg_job->request_payload.payload_len;
1214 		mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1215 			&mgmt_dma, GFP_KERNEL);
1216 		if (!mgmt_b) {
1217 			ql_log(ql_log_warn, vha, 0x7042,
1218 			    "DMA alloc failed for mgmt_b.\n");
1219 			rval = -ENOMEM;
1220 			goto done_unmap_sg;
1221 		}
1222 
1223 		sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1224 			bsg_job->request_payload.sg_cnt, mgmt_b, data_len);
1225 
1226 		mn->options = cpu_to_le16(ACO_LOAD_MEMORY);
1227 		mn->parameter1 =
1228 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1229 		break;
1230 
1231 	case QLA84_MGMT_CHNG_CONFIG:
1232 		mn->options = cpu_to_le16(ACO_CHANGE_CONFIG_PARAM);
1233 		mn->parameter1 =
1234 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.id);
1235 
1236 		mn->parameter2 =
1237 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param0);
1238 
1239 		mn->parameter3 =
1240 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param1);
1241 		break;
1242 
1243 	default:
1244 		rval = -EIO;
1245 		goto exit_mgmt;
1246 	}
1247 
1248 	if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) {
1249 		mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len);
1250 		mn->dseg_count = cpu_to_le16(1);
1251 		put_unaligned_le64(mgmt_dma, &mn->dsd.address);
1252 		mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len);
1253 	}
1254 
1255 	rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0);
1256 
1257 	if (rval) {
1258 		ql_log(ql_log_warn, vha, 0x7043,
1259 		    "Vendor request 84xx mgmt failed.\n");
1260 
1261 		rval = (DID_ERROR << 16);
1262 
1263 	} else {
1264 		ql_dbg(ql_dbg_user, vha, 0x7044,
1265 		    "Vendor request 84xx mgmt completed.\n");
1266 
1267 		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1268 		bsg_reply->result = DID_OK;
1269 
1270 		if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) ||
1271 			(ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) {
1272 			bsg_reply->reply_payload_rcv_len =
1273 				bsg_job->reply_payload.payload_len;
1274 
1275 			sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1276 				bsg_job->reply_payload.sg_cnt, mgmt_b,
1277 				data_len);
1278 		}
1279 	}
1280 
1281 done_unmap_sg:
1282 	if (mgmt_b)
1283 		dma_free_coherent(&ha->pdev->dev, data_len, mgmt_b, mgmt_dma);
1284 
1285 	if (dma_direction == DMA_TO_DEVICE)
1286 		dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1287 			bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1288 	else if (dma_direction == DMA_FROM_DEVICE)
1289 		dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
1290 			bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1291 
1292 exit_mgmt:
1293 	dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1294 
1295 	if (!rval)
1296 		bsg_job_done(bsg_job, bsg_reply->result,
1297 			       bsg_reply->reply_payload_rcv_len);
1298 	return rval;
1299 }
1300 
1301 static int
1302 qla24xx_iidma(struct bsg_job *bsg_job)
1303 {
1304 	struct fc_bsg_request *bsg_request = bsg_job->request;
1305 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1306 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1307 	scsi_qla_host_t *vha = shost_priv(host);
1308 	int rval = 0;
1309 	struct qla_port_param *port_param = NULL;
1310 	fc_port_t *fcport = NULL;
1311 	int found = 0;
1312 	uint16_t mb[MAILBOX_REGISTER_COUNT];
1313 	uint8_t *rsp_ptr = NULL;
1314 
1315 	if (!IS_IIDMA_CAPABLE(vha->hw)) {
1316 		ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
1317 		return -EINVAL;
1318 	}
1319 
1320 	port_param = (void *)bsg_request + sizeof(struct fc_bsg_request);
1321 	if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
1322 		ql_log(ql_log_warn, vha, 0x7048,
1323 		    "Invalid destination type.\n");
1324 		return -EINVAL;
1325 	}
1326 
1327 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
1328 		if (fcport->port_type != FCT_TARGET)
1329 			continue;
1330 
1331 		if (memcmp(port_param->fc_scsi_addr.dest_addr.wwpn,
1332 			fcport->port_name, sizeof(fcport->port_name)))
1333 			continue;
1334 
1335 		found = 1;
1336 		break;
1337 	}
1338 
1339 	if (!found) {
1340 		ql_log(ql_log_warn, vha, 0x7049,
1341 		    "Failed to find port.\n");
1342 		return -EINVAL;
1343 	}
1344 
1345 	if (atomic_read(&fcport->state) != FCS_ONLINE) {
1346 		ql_log(ql_log_warn, vha, 0x704a,
1347 		    "Port is not online.\n");
1348 		return -EINVAL;
1349 	}
1350 
1351 	if (fcport->flags & FCF_LOGIN_NEEDED) {
1352 		ql_log(ql_log_warn, vha, 0x704b,
1353 		    "Remote port not logged in flags = 0x%x.\n", fcport->flags);
1354 		return -EINVAL;
1355 	}
1356 
1357 	if (port_param->mode)
1358 		rval = qla2x00_set_idma_speed(vha, fcport->loop_id,
1359 			port_param->speed, mb);
1360 	else
1361 		rval = qla2x00_get_idma_speed(vha, fcport->loop_id,
1362 			&port_param->speed, mb);
1363 
1364 	if (rval) {
1365 		ql_log(ql_log_warn, vha, 0x704c,
1366 		    "iiDMA cmd failed for %8phN -- "
1367 		    "%04x %x %04x %04x.\n", fcport->port_name,
1368 		    rval, fcport->fp_speed, mb[0], mb[1]);
1369 		rval = (DID_ERROR << 16);
1370 	} else {
1371 		if (!port_param->mode) {
1372 			bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
1373 				sizeof(struct qla_port_param);
1374 
1375 			rsp_ptr = ((uint8_t *)bsg_reply) +
1376 				sizeof(struct fc_bsg_reply);
1377 
1378 			memcpy(rsp_ptr, port_param,
1379 				sizeof(struct qla_port_param));
1380 		}
1381 
1382 		bsg_reply->result = DID_OK;
1383 		bsg_job_done(bsg_job, bsg_reply->result,
1384 			       bsg_reply->reply_payload_rcv_len);
1385 	}
1386 
1387 	return rval;
1388 }
1389 
1390 static int
1391 qla2x00_optrom_setup(struct bsg_job *bsg_job, scsi_qla_host_t *vha,
1392 	uint8_t is_update)
1393 {
1394 	struct fc_bsg_request *bsg_request = bsg_job->request;
1395 	uint32_t start = 0;
1396 	int valid = 0;
1397 	struct qla_hw_data *ha = vha->hw;
1398 
1399 	if (unlikely(pci_channel_offline(ha->pdev)))
1400 		return -EINVAL;
1401 
1402 	start = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1403 	if (start > ha->optrom_size) {
1404 		ql_log(ql_log_warn, vha, 0x7055,
1405 		    "start %d > optrom_size %d.\n", start, ha->optrom_size);
1406 		return -EINVAL;
1407 	}
1408 
1409 	if (ha->optrom_state != QLA_SWAITING) {
1410 		ql_log(ql_log_info, vha, 0x7056,
1411 		    "optrom_state %d.\n", ha->optrom_state);
1412 		return -EBUSY;
1413 	}
1414 
1415 	ha->optrom_region_start = start;
1416 	ql_dbg(ql_dbg_user, vha, 0x7057, "is_update=%d.\n", is_update);
1417 	if (is_update) {
1418 		if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
1419 			valid = 1;
1420 		else if (start == (ha->flt_region_boot * 4) ||
1421 		    start == (ha->flt_region_fw * 4))
1422 			valid = 1;
1423 		else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
1424 		    IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) ||
1425 		    IS_QLA28XX(ha))
1426 			valid = 1;
1427 		if (!valid) {
1428 			ql_log(ql_log_warn, vha, 0x7058,
1429 			    "Invalid start region 0x%x/0x%x.\n", start,
1430 			    bsg_job->request_payload.payload_len);
1431 			return -EINVAL;
1432 		}
1433 
1434 		ha->optrom_region_size = start +
1435 		    bsg_job->request_payload.payload_len > ha->optrom_size ?
1436 		    ha->optrom_size - start :
1437 		    bsg_job->request_payload.payload_len;
1438 		ha->optrom_state = QLA_SWRITING;
1439 	} else {
1440 		ha->optrom_region_size = start +
1441 		    bsg_job->reply_payload.payload_len > ha->optrom_size ?
1442 		    ha->optrom_size - start :
1443 		    bsg_job->reply_payload.payload_len;
1444 		ha->optrom_state = QLA_SREADING;
1445 	}
1446 
1447 	ha->optrom_buffer = vzalloc(ha->optrom_region_size);
1448 	if (!ha->optrom_buffer) {
1449 		ql_log(ql_log_warn, vha, 0x7059,
1450 		    "Read: Unable to allocate memory for optrom retrieval "
1451 		    "(%x)\n", ha->optrom_region_size);
1452 
1453 		ha->optrom_state = QLA_SWAITING;
1454 		return -ENOMEM;
1455 	}
1456 
1457 	return 0;
1458 }
1459 
1460 static int
1461 qla2x00_read_optrom(struct bsg_job *bsg_job)
1462 {
1463 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1464 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1465 	scsi_qla_host_t *vha = shost_priv(host);
1466 	struct qla_hw_data *ha = vha->hw;
1467 	int rval = 0;
1468 
1469 	if (ha->flags.nic_core_reset_hdlr_active)
1470 		return -EBUSY;
1471 
1472 	mutex_lock(&ha->optrom_mutex);
1473 	rval = qla2x00_optrom_setup(bsg_job, vha, 0);
1474 	if (rval) {
1475 		mutex_unlock(&ha->optrom_mutex);
1476 		return rval;
1477 	}
1478 
1479 	ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
1480 	    ha->optrom_region_start, ha->optrom_region_size);
1481 
1482 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1483 	    bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
1484 	    ha->optrom_region_size);
1485 
1486 	bsg_reply->reply_payload_rcv_len = ha->optrom_region_size;
1487 	bsg_reply->result = DID_OK;
1488 	vfree(ha->optrom_buffer);
1489 	ha->optrom_buffer = NULL;
1490 	ha->optrom_state = QLA_SWAITING;
1491 	mutex_unlock(&ha->optrom_mutex);
1492 	bsg_job_done(bsg_job, bsg_reply->result,
1493 		       bsg_reply->reply_payload_rcv_len);
1494 	return rval;
1495 }
1496 
1497 static int
1498 qla2x00_update_optrom(struct bsg_job *bsg_job)
1499 {
1500 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1501 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1502 	scsi_qla_host_t *vha = shost_priv(host);
1503 	struct qla_hw_data *ha = vha->hw;
1504 	int rval = 0;
1505 
1506 	mutex_lock(&ha->optrom_mutex);
1507 	rval = qla2x00_optrom_setup(bsg_job, vha, 1);
1508 	if (rval) {
1509 		mutex_unlock(&ha->optrom_mutex);
1510 		return rval;
1511 	}
1512 
1513 	/* Set the isp82xx_no_md_cap not to capture minidump */
1514 	ha->flags.isp82xx_no_md_cap = 1;
1515 
1516 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1517 	    bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
1518 	    ha->optrom_region_size);
1519 
1520 	rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
1521 	    ha->optrom_region_start, ha->optrom_region_size);
1522 
1523 	if (rval) {
1524 		bsg_reply->result = -EINVAL;
1525 		rval = -EINVAL;
1526 	} else {
1527 		bsg_reply->result = DID_OK;
1528 	}
1529 	vfree(ha->optrom_buffer);
1530 	ha->optrom_buffer = NULL;
1531 	ha->optrom_state = QLA_SWAITING;
1532 	mutex_unlock(&ha->optrom_mutex);
1533 	bsg_job_done(bsg_job, bsg_reply->result,
1534 		       bsg_reply->reply_payload_rcv_len);
1535 	return rval;
1536 }
1537 
1538 static int
1539 qla2x00_update_fru_versions(struct bsg_job *bsg_job)
1540 {
1541 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1542 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1543 	scsi_qla_host_t *vha = shost_priv(host);
1544 	struct qla_hw_data *ha = vha->hw;
1545 	int rval = 0;
1546 	uint8_t bsg[DMA_POOL_SIZE];
1547 	struct qla_image_version_list *list = (void *)bsg;
1548 	struct qla_image_version *image;
1549 	uint32_t count;
1550 	dma_addr_t sfp_dma;
1551 	void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1552 
1553 	if (!sfp) {
1554 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1555 		    EXT_STATUS_NO_MEMORY;
1556 		goto done;
1557 	}
1558 
1559 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1560 	    bsg_job->request_payload.sg_cnt, list, sizeof(bsg));
1561 
1562 	image = list->version;
1563 	count = list->count;
1564 	while (count--) {
1565 		memcpy(sfp, &image->field_info, sizeof(image->field_info));
1566 		rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1567 		    image->field_address.device, image->field_address.offset,
1568 		    sizeof(image->field_info), image->field_address.option);
1569 		if (rval) {
1570 			bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1571 			    EXT_STATUS_MAILBOX;
1572 			goto dealloc;
1573 		}
1574 		image++;
1575 	}
1576 
1577 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1578 
1579 dealloc:
1580 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1581 
1582 done:
1583 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1584 	bsg_reply->result = DID_OK << 16;
1585 	bsg_job_done(bsg_job, bsg_reply->result,
1586 		       bsg_reply->reply_payload_rcv_len);
1587 
1588 	return 0;
1589 }
1590 
1591 static int
1592 qla2x00_read_fru_status(struct bsg_job *bsg_job)
1593 {
1594 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1595 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1596 	scsi_qla_host_t *vha = shost_priv(host);
1597 	struct qla_hw_data *ha = vha->hw;
1598 	int rval = 0;
1599 	uint8_t bsg[DMA_POOL_SIZE];
1600 	struct qla_status_reg *sr = (void *)bsg;
1601 	dma_addr_t sfp_dma;
1602 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1603 
1604 	if (!sfp) {
1605 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1606 		    EXT_STATUS_NO_MEMORY;
1607 		goto done;
1608 	}
1609 
1610 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1611 	    bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1612 
1613 	rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1614 	    sr->field_address.device, sr->field_address.offset,
1615 	    sizeof(sr->status_reg), sr->field_address.option);
1616 	sr->status_reg = *sfp;
1617 
1618 	if (rval) {
1619 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1620 		    EXT_STATUS_MAILBOX;
1621 		goto dealloc;
1622 	}
1623 
1624 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1625 	    bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));
1626 
1627 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1628 
1629 dealloc:
1630 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1631 
1632 done:
1633 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1634 	bsg_reply->reply_payload_rcv_len = sizeof(*sr);
1635 	bsg_reply->result = DID_OK << 16;
1636 	bsg_job_done(bsg_job, bsg_reply->result,
1637 		       bsg_reply->reply_payload_rcv_len);
1638 
1639 	return 0;
1640 }
1641 
1642 static int
1643 qla2x00_write_fru_status(struct bsg_job *bsg_job)
1644 {
1645 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1646 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1647 	scsi_qla_host_t *vha = shost_priv(host);
1648 	struct qla_hw_data *ha = vha->hw;
1649 	int rval = 0;
1650 	uint8_t bsg[DMA_POOL_SIZE];
1651 	struct qla_status_reg *sr = (void *)bsg;
1652 	dma_addr_t sfp_dma;
1653 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1654 
1655 	if (!sfp) {
1656 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1657 		    EXT_STATUS_NO_MEMORY;
1658 		goto done;
1659 	}
1660 
1661 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1662 	    bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1663 
1664 	*sfp = sr->status_reg;
1665 	rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1666 	    sr->field_address.device, sr->field_address.offset,
1667 	    sizeof(sr->status_reg), sr->field_address.option);
1668 
1669 	if (rval) {
1670 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1671 		    EXT_STATUS_MAILBOX;
1672 		goto dealloc;
1673 	}
1674 
1675 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1676 
1677 dealloc:
1678 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1679 
1680 done:
1681 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1682 	bsg_reply->result = DID_OK << 16;
1683 	bsg_job_done(bsg_job, bsg_reply->result,
1684 		       bsg_reply->reply_payload_rcv_len);
1685 
1686 	return 0;
1687 }
1688 
1689 static int
1690 qla2x00_write_i2c(struct bsg_job *bsg_job)
1691 {
1692 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1693 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1694 	scsi_qla_host_t *vha = shost_priv(host);
1695 	struct qla_hw_data *ha = vha->hw;
1696 	int rval = 0;
1697 	uint8_t bsg[DMA_POOL_SIZE];
1698 	struct qla_i2c_access *i2c = (void *)bsg;
1699 	dma_addr_t sfp_dma;
1700 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1701 
1702 	if (!sfp) {
1703 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1704 		    EXT_STATUS_NO_MEMORY;
1705 		goto done;
1706 	}
1707 
1708 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1709 	    bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1710 
1711 	memcpy(sfp, i2c->buffer, i2c->length);
1712 	rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1713 	    i2c->device, i2c->offset, i2c->length, i2c->option);
1714 
1715 	if (rval) {
1716 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1717 		    EXT_STATUS_MAILBOX;
1718 		goto dealloc;
1719 	}
1720 
1721 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1722 
1723 dealloc:
1724 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1725 
1726 done:
1727 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1728 	bsg_reply->result = DID_OK << 16;
1729 	bsg_job_done(bsg_job, bsg_reply->result,
1730 		       bsg_reply->reply_payload_rcv_len);
1731 
1732 	return 0;
1733 }
1734 
1735 static int
1736 qla2x00_read_i2c(struct bsg_job *bsg_job)
1737 {
1738 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1739 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1740 	scsi_qla_host_t *vha = shost_priv(host);
1741 	struct qla_hw_data *ha = vha->hw;
1742 	int rval = 0;
1743 	uint8_t bsg[DMA_POOL_SIZE];
1744 	struct qla_i2c_access *i2c = (void *)bsg;
1745 	dma_addr_t sfp_dma;
1746 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1747 
1748 	if (!sfp) {
1749 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1750 		    EXT_STATUS_NO_MEMORY;
1751 		goto done;
1752 	}
1753 
1754 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1755 	    bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1756 
1757 	rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1758 		i2c->device, i2c->offset, i2c->length, i2c->option);
1759 
1760 	if (rval) {
1761 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1762 		    EXT_STATUS_MAILBOX;
1763 		goto dealloc;
1764 	}
1765 
1766 	memcpy(i2c->buffer, sfp, i2c->length);
1767 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1768 	    bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));
1769 
1770 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1771 
1772 dealloc:
1773 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1774 
1775 done:
1776 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1777 	bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
1778 	bsg_reply->result = DID_OK << 16;
1779 	bsg_job_done(bsg_job, bsg_reply->result,
1780 		       bsg_reply->reply_payload_rcv_len);
1781 
1782 	return 0;
1783 }
1784 
1785 static int
1786 qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
1787 {
1788 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1789 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1790 	scsi_qla_host_t *vha = shost_priv(host);
1791 	struct qla_hw_data *ha = vha->hw;
1792 	uint32_t rval = EXT_STATUS_OK;
1793 	uint16_t req_sg_cnt = 0;
1794 	uint16_t rsp_sg_cnt = 0;
1795 	uint16_t nextlid = 0;
1796 	uint32_t tot_dsds;
1797 	srb_t *sp = NULL;
1798 	uint32_t req_data_len;
1799 	uint32_t rsp_data_len;
1800 
1801 	/* Check the type of the adapter */
1802 	if (!IS_BIDI_CAPABLE(ha)) {
1803 		ql_log(ql_log_warn, vha, 0x70a0,
1804 			"This adapter is not supported\n");
1805 		rval = EXT_STATUS_NOT_SUPPORTED;
1806 		goto done;
1807 	}
1808 
1809 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1810 		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1811 		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1812 		rval =  EXT_STATUS_BUSY;
1813 		goto done;
1814 	}
1815 
1816 	/* Check if host is online */
1817 	if (!vha->flags.online) {
1818 		ql_log(ql_log_warn, vha, 0x70a1,
1819 			"Host is not online\n");
1820 		rval = EXT_STATUS_DEVICE_OFFLINE;
1821 		goto done;
1822 	}
1823 
1824 	/* Check if cable is plugged in or not */
1825 	if (vha->device_flags & DFLG_NO_CABLE) {
1826 		ql_log(ql_log_warn, vha, 0x70a2,
1827 			"Cable is unplugged...\n");
1828 		rval = EXT_STATUS_INVALID_CFG;
1829 		goto done;
1830 	}
1831 
1832 	/* Check if the switch is connected or not */
1833 	if (ha->current_topology != ISP_CFG_F) {
1834 		ql_log(ql_log_warn, vha, 0x70a3,
1835 			"Host is not connected to the switch\n");
1836 		rval = EXT_STATUS_INVALID_CFG;
1837 		goto done;
1838 	}
1839 
1840 	/* Check if operating mode is P2P */
1841 	if (ha->operating_mode != P2P) {
1842 		ql_log(ql_log_warn, vha, 0x70a4,
1843 		    "Host operating mode is not P2p\n");
1844 		rval = EXT_STATUS_INVALID_CFG;
1845 		goto done;
1846 	}
1847 
1848 	mutex_lock(&ha->selflogin_lock);
1849 	if (vha->self_login_loop_id == 0) {
1850 		/* Initialize all required  fields of fcport */
1851 		vha->bidir_fcport.vha = vha;
1852 		vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
1853 		vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
1854 		vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
1855 		vha->bidir_fcport.loop_id = vha->loop_id;
1856 
1857 		if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
1858 			ql_log(ql_log_warn, vha, 0x70a7,
1859 			    "Failed to login port %06X for bidirectional IOCB\n",
1860 			    vha->bidir_fcport.d_id.b24);
1861 			mutex_unlock(&ha->selflogin_lock);
1862 			rval = EXT_STATUS_MAILBOX;
1863 			goto done;
1864 		}
1865 		vha->self_login_loop_id = nextlid - 1;
1866 
1867 	}
1868 	/* Assign the self login loop id to fcport */
1869 	mutex_unlock(&ha->selflogin_lock);
1870 
1871 	vha->bidir_fcport.loop_id = vha->self_login_loop_id;
1872 
1873 	req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1874 		bsg_job->request_payload.sg_list,
1875 		bsg_job->request_payload.sg_cnt,
1876 		DMA_TO_DEVICE);
1877 
1878 	if (!req_sg_cnt) {
1879 		rval = EXT_STATUS_NO_MEMORY;
1880 		goto done;
1881 	}
1882 
1883 	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
1884 		bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
1885 		DMA_FROM_DEVICE);
1886 
1887 	if (!rsp_sg_cnt) {
1888 		rval = EXT_STATUS_NO_MEMORY;
1889 		goto done_unmap_req_sg;
1890 	}
1891 
1892 	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
1893 		(rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
1894 		ql_dbg(ql_dbg_user, vha, 0x70a9,
1895 		    "Dma mapping resulted in different sg counts "
1896 		    "[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
1897 		    "%x dma_reply_sg_cnt: %x]\n",
1898 		    bsg_job->request_payload.sg_cnt, req_sg_cnt,
1899 		    bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
1900 		rval = EXT_STATUS_NO_MEMORY;
1901 		goto done_unmap_sg;
1902 	}
1903 
1904 	req_data_len = bsg_job->request_payload.payload_len;
1905 	rsp_data_len = bsg_job->reply_payload.payload_len;
1906 
1907 	if (req_data_len != rsp_data_len) {
1908 		rval = EXT_STATUS_BUSY;
1909 		ql_log(ql_log_warn, vha, 0x70aa,
1910 		    "req_data_len != rsp_data_len\n");
1911 		goto done_unmap_sg;
1912 	}
1913 
1914 	/* Alloc SRB structure */
1915 	sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
1916 	if (!sp) {
1917 		ql_dbg(ql_dbg_user, vha, 0x70ac,
1918 		    "Alloc SRB structure failed\n");
1919 		rval = EXT_STATUS_NO_MEMORY;
1920 		goto done_unmap_sg;
1921 	}
1922 
1923 	/*Populate srb->ctx with bidir ctx*/
1924 	sp->u.bsg_job = bsg_job;
1925 	sp->free = qla2x00_bsg_sp_free;
1926 	sp->type = SRB_BIDI_CMD;
1927 	sp->done = qla2x00_bsg_job_done;
1928 
1929 	/* Add the read and write sg count */
1930 	tot_dsds = rsp_sg_cnt + req_sg_cnt;
1931 
1932 	rval = qla2x00_start_bidir(sp, vha, tot_dsds);
1933 	if (rval != EXT_STATUS_OK)
1934 		goto done_free_srb;
1935 	/* the bsg request  will be completed in the interrupt handler */
1936 	return rval;
1937 
1938 done_free_srb:
1939 	mempool_free(sp, ha->srb_mempool);
1940 done_unmap_sg:
1941 	dma_unmap_sg(&ha->pdev->dev,
1942 	    bsg_job->reply_payload.sg_list,
1943 	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1944 done_unmap_req_sg:
1945 	dma_unmap_sg(&ha->pdev->dev,
1946 	    bsg_job->request_payload.sg_list,
1947 	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1948 done:
1949 
1950 	/* Return an error vendor specific response
1951 	 * and complete the bsg request
1952 	 */
1953 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
1954 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1955 	bsg_reply->reply_payload_rcv_len = 0;
1956 	bsg_reply->result = (DID_OK) << 16;
1957 	bsg_job_done(bsg_job, bsg_reply->result,
1958 		       bsg_reply->reply_payload_rcv_len);
1959 	/* Always return success, vendor rsp carries correct status */
1960 	return 0;
1961 }
1962 
1963 static int
1964 qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
1965 {
1966 	struct fc_bsg_request *bsg_request = bsg_job->request;
1967 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1968 	scsi_qla_host_t *vha = shost_priv(host);
1969 	struct qla_hw_data *ha = vha->hw;
1970 	int rval = (DID_ERROR << 16);
1971 	struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
1972 	srb_t *sp;
1973 	int req_sg_cnt = 0, rsp_sg_cnt = 0;
1974 	struct fc_port *fcport;
1975 	char  *type = "FC_BSG_HST_FX_MGMT";
1976 
1977 	/* Copy the IOCB specific information */
1978 	piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
1979 	    &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1980 
1981 	/* Dump the vendor information */
1982 	ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf,
1983 	    piocb_rqst, sizeof(*piocb_rqst));
1984 
1985 	if (!vha->flags.online) {
1986 		ql_log(ql_log_warn, vha, 0x70d0,
1987 		    "Host is not online.\n");
1988 		rval = -EIO;
1989 		goto done;
1990 	}
1991 
1992 	if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID) {
1993 		req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1994 		    bsg_job->request_payload.sg_list,
1995 		    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1996 		if (!req_sg_cnt) {
1997 			ql_log(ql_log_warn, vha, 0x70c7,
1998 			    "dma_map_sg return %d for request\n", req_sg_cnt);
1999 			rval = -ENOMEM;
2000 			goto done;
2001 		}
2002 	}
2003 
2004 	if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) {
2005 		rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
2006 		    bsg_job->reply_payload.sg_list,
2007 		    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2008 		if (!rsp_sg_cnt) {
2009 			ql_log(ql_log_warn, vha, 0x70c8,
2010 			    "dma_map_sg return %d for reply\n", rsp_sg_cnt);
2011 			rval = -ENOMEM;
2012 			goto done_unmap_req_sg;
2013 		}
2014 	}
2015 
2016 	ql_dbg(ql_dbg_user, vha, 0x70c9,
2017 	    "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
2018 	    "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
2019 	    req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
2020 
2021 	/* Allocate a dummy fcport structure, since functions preparing the
2022 	 * IOCB and mailbox command retrieves port specific information
2023 	 * from fcport structure. For Host based ELS commands there will be
2024 	 * no fcport structure allocated
2025 	 */
2026 	fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
2027 	if (!fcport) {
2028 		ql_log(ql_log_warn, vha, 0x70ca,
2029 		    "Failed to allocate fcport.\n");
2030 		rval = -ENOMEM;
2031 		goto done_unmap_rsp_sg;
2032 	}
2033 
2034 	/* Alloc SRB structure */
2035 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
2036 	if (!sp) {
2037 		ql_log(ql_log_warn, vha, 0x70cb,
2038 		    "qla2x00_get_sp failed.\n");
2039 		rval = -ENOMEM;
2040 		goto done_free_fcport;
2041 	}
2042 
2043 	/* Initialize all required  fields of fcport */
2044 	fcport->vha = vha;
2045 	fcport->loop_id = le32_to_cpu(piocb_rqst->dataword);
2046 
2047 	sp->type = SRB_FXIOCB_BCMD;
2048 	sp->name = "bsg_fx_mgmt";
2049 	sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
2050 	sp->u.bsg_job = bsg_job;
2051 	sp->free = qla2x00_bsg_sp_free;
2052 	sp->done = qla2x00_bsg_job_done;
2053 
2054 	ql_dbg(ql_dbg_user, vha, 0x70cc,
2055 	    "bsg rqst type: %s fx_mgmt_type: %x id=%x\n",
2056 	    type, piocb_rqst->func_type, fcport->loop_id);
2057 
2058 	rval = qla2x00_start_sp(sp);
2059 	if (rval != QLA_SUCCESS) {
2060 		ql_log(ql_log_warn, vha, 0x70cd,
2061 		    "qla2x00_start_sp failed=%d.\n", rval);
2062 		mempool_free(sp, ha->srb_mempool);
2063 		rval = -EIO;
2064 		goto done_free_fcport;
2065 	}
2066 	return rval;
2067 
2068 done_free_fcport:
2069 	qla2x00_free_fcport(fcport);
2070 
2071 done_unmap_rsp_sg:
2072 	if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
2073 		dma_unmap_sg(&ha->pdev->dev,
2074 		    bsg_job->reply_payload.sg_list,
2075 		    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2076 done_unmap_req_sg:
2077 	if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
2078 		dma_unmap_sg(&ha->pdev->dev,
2079 		    bsg_job->request_payload.sg_list,
2080 		    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
2081 
2082 done:
2083 	return rval;
2084 }
2085 
2086 static int
2087 qla26xx_serdes_op(struct bsg_job *bsg_job)
2088 {
2089 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2090 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2091 	scsi_qla_host_t *vha = shost_priv(host);
2092 	int rval = 0;
2093 	struct qla_serdes_reg sr;
2094 
2095 	memset(&sr, 0, sizeof(sr));
2096 
2097 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2098 	    bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2099 
2100 	switch (sr.cmd) {
2101 	case INT_SC_SERDES_WRITE_REG:
2102 		rval = qla2x00_write_serdes_word(vha, sr.addr, sr.val);
2103 		bsg_reply->reply_payload_rcv_len = 0;
2104 		break;
2105 	case INT_SC_SERDES_READ_REG:
2106 		rval = qla2x00_read_serdes_word(vha, sr.addr, &sr.val);
2107 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2108 		    bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2109 		bsg_reply->reply_payload_rcv_len = sizeof(sr);
2110 		break;
2111 	default:
2112 		ql_dbg(ql_dbg_user, vha, 0x708c,
2113 		    "Unknown serdes cmd %x.\n", sr.cmd);
2114 		rval = -EINVAL;
2115 		break;
2116 	}
2117 
2118 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2119 	    rval ? EXT_STATUS_MAILBOX : 0;
2120 
2121 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2122 	bsg_reply->result = DID_OK << 16;
2123 	bsg_job_done(bsg_job, bsg_reply->result,
2124 		       bsg_reply->reply_payload_rcv_len);
2125 	return 0;
2126 }
2127 
2128 static int
2129 qla8044_serdes_op(struct bsg_job *bsg_job)
2130 {
2131 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2132 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2133 	scsi_qla_host_t *vha = shost_priv(host);
2134 	int rval = 0;
2135 	struct qla_serdes_reg_ex sr;
2136 
2137 	memset(&sr, 0, sizeof(sr));
2138 
2139 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2140 	    bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2141 
2142 	switch (sr.cmd) {
2143 	case INT_SC_SERDES_WRITE_REG:
2144 		rval = qla8044_write_serdes_word(vha, sr.addr, sr.val);
2145 		bsg_reply->reply_payload_rcv_len = 0;
2146 		break;
2147 	case INT_SC_SERDES_READ_REG:
2148 		rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val);
2149 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2150 		    bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2151 		bsg_reply->reply_payload_rcv_len = sizeof(sr);
2152 		break;
2153 	default:
2154 		ql_dbg(ql_dbg_user, vha, 0x7020,
2155 		    "Unknown serdes cmd %x.\n", sr.cmd);
2156 		rval = -EINVAL;
2157 		break;
2158 	}
2159 
2160 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2161 	    rval ? EXT_STATUS_MAILBOX : 0;
2162 
2163 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2164 	bsg_reply->result = DID_OK << 16;
2165 	bsg_job_done(bsg_job, bsg_reply->result,
2166 		       bsg_reply->reply_payload_rcv_len);
2167 	return 0;
2168 }
2169 
2170 static int
2171 qla27xx_get_flash_upd_cap(struct bsg_job *bsg_job)
2172 {
2173 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2174 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2175 	scsi_qla_host_t *vha = shost_priv(host);
2176 	struct qla_hw_data *ha = vha->hw;
2177 	struct qla_flash_update_caps cap;
2178 
2179 	if (!(IS_QLA27XX(ha)) && !IS_QLA28XX(ha))
2180 		return -EPERM;
2181 
2182 	memset(&cap, 0, sizeof(cap));
2183 	cap.capabilities = (uint64_t)ha->fw_attributes_ext[1] << 48 |
2184 			   (uint64_t)ha->fw_attributes_ext[0] << 32 |
2185 			   (uint64_t)ha->fw_attributes_h << 16 |
2186 			   (uint64_t)ha->fw_attributes;
2187 
2188 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2189 	    bsg_job->reply_payload.sg_cnt, &cap, sizeof(cap));
2190 	bsg_reply->reply_payload_rcv_len = sizeof(cap);
2191 
2192 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2193 	    EXT_STATUS_OK;
2194 
2195 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2196 	bsg_reply->result = DID_OK << 16;
2197 	bsg_job_done(bsg_job, bsg_reply->result,
2198 		       bsg_reply->reply_payload_rcv_len);
2199 	return 0;
2200 }
2201 
2202 static int
2203 qla27xx_set_flash_upd_cap(struct bsg_job *bsg_job)
2204 {
2205 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2206 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2207 	scsi_qla_host_t *vha = shost_priv(host);
2208 	struct qla_hw_data *ha = vha->hw;
2209 	uint64_t online_fw_attr = 0;
2210 	struct qla_flash_update_caps cap;
2211 
2212 	if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
2213 		return -EPERM;
2214 
2215 	memset(&cap, 0, sizeof(cap));
2216 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2217 	    bsg_job->request_payload.sg_cnt, &cap, sizeof(cap));
2218 
2219 	online_fw_attr = (uint64_t)ha->fw_attributes_ext[1] << 48 |
2220 			 (uint64_t)ha->fw_attributes_ext[0] << 32 |
2221 			 (uint64_t)ha->fw_attributes_h << 16 |
2222 			 (uint64_t)ha->fw_attributes;
2223 
2224 	if (online_fw_attr != cap.capabilities) {
2225 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2226 		    EXT_STATUS_INVALID_PARAM;
2227 		return -EINVAL;
2228 	}
2229 
2230 	if (cap.outage_duration < MAX_LOOP_TIMEOUT)  {
2231 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2232 		    EXT_STATUS_INVALID_PARAM;
2233 		return -EINVAL;
2234 	}
2235 
2236 	bsg_reply->reply_payload_rcv_len = 0;
2237 
2238 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2239 	    EXT_STATUS_OK;
2240 
2241 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2242 	bsg_reply->result = DID_OK << 16;
2243 	bsg_job_done(bsg_job, bsg_reply->result,
2244 		       bsg_reply->reply_payload_rcv_len);
2245 	return 0;
2246 }
2247 
2248 static int
2249 qla27xx_get_bbcr_data(struct bsg_job *bsg_job)
2250 {
2251 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2252 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2253 	scsi_qla_host_t *vha = shost_priv(host);
2254 	struct qla_hw_data *ha = vha->hw;
2255 	struct qla_bbcr_data bbcr;
2256 	uint16_t loop_id, topo, sw_cap;
2257 	uint8_t domain, area, al_pa, state;
2258 	int rval;
2259 
2260 	if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
2261 		return -EPERM;
2262 
2263 	memset(&bbcr, 0, sizeof(bbcr));
2264 
2265 	if (vha->flags.bbcr_enable)
2266 		bbcr.status = QLA_BBCR_STATUS_ENABLED;
2267 	else
2268 		bbcr.status = QLA_BBCR_STATUS_DISABLED;
2269 
2270 	if (bbcr.status == QLA_BBCR_STATUS_ENABLED) {
2271 		rval = qla2x00_get_adapter_id(vha, &loop_id, &al_pa,
2272 			&area, &domain, &topo, &sw_cap);
2273 		if (rval != QLA_SUCCESS) {
2274 			bbcr.status = QLA_BBCR_STATUS_UNKNOWN;
2275 			bbcr.state = QLA_BBCR_STATE_OFFLINE;
2276 			bbcr.mbx1 = loop_id;
2277 			goto done;
2278 		}
2279 
2280 		state = (vha->bbcr >> 12) & 0x1;
2281 
2282 		if (state) {
2283 			bbcr.state = QLA_BBCR_STATE_OFFLINE;
2284 			bbcr.offline_reason_code = QLA_BBCR_REASON_LOGIN_REJECT;
2285 		} else {
2286 			bbcr.state = QLA_BBCR_STATE_ONLINE;
2287 			bbcr.negotiated_bbscn = (vha->bbcr >> 8) & 0xf;
2288 		}
2289 
2290 		bbcr.configured_bbscn = vha->bbcr & 0xf;
2291 	}
2292 
2293 done:
2294 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2295 		bsg_job->reply_payload.sg_cnt, &bbcr, sizeof(bbcr));
2296 	bsg_reply->reply_payload_rcv_len = sizeof(bbcr);
2297 
2298 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2299 
2300 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2301 	bsg_reply->result = DID_OK << 16;
2302 	bsg_job_done(bsg_job, bsg_reply->result,
2303 		       bsg_reply->reply_payload_rcv_len);
2304 	return 0;
2305 }
2306 
2307 static int
2308 qla2x00_get_priv_stats(struct bsg_job *bsg_job)
2309 {
2310 	struct fc_bsg_request *bsg_request = bsg_job->request;
2311 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2312 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2313 	scsi_qla_host_t *vha = shost_priv(host);
2314 	struct qla_hw_data *ha = vha->hw;
2315 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
2316 	struct link_statistics *stats = NULL;
2317 	dma_addr_t stats_dma;
2318 	int rval;
2319 	uint32_t *cmd = bsg_request->rqst_data.h_vendor.vendor_cmd;
2320 	uint options = cmd[0] == QL_VND_GET_PRIV_STATS_EX ? cmd[1] : 0;
2321 
2322 	if (test_bit(UNLOADING, &vha->dpc_flags))
2323 		return -ENODEV;
2324 
2325 	if (unlikely(pci_channel_offline(ha->pdev)))
2326 		return -ENODEV;
2327 
2328 	if (qla2x00_reset_active(vha))
2329 		return -EBUSY;
2330 
2331 	if (!IS_FWI2_CAPABLE(ha))
2332 		return -EPERM;
2333 
2334 	stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma,
2335 				   GFP_KERNEL);
2336 	if (!stats) {
2337 		ql_log(ql_log_warn, vha, 0x70e2,
2338 		    "Failed to allocate memory for stats.\n");
2339 		return -ENOMEM;
2340 	}
2341 
2342 	rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options);
2343 
2344 	if (rval == QLA_SUCCESS) {
2345 		ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e5,
2346 			stats, sizeof(*stats));
2347 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2348 			bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats));
2349 	}
2350 
2351 	bsg_reply->reply_payload_rcv_len = sizeof(*stats);
2352 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2353 	    rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
2354 
2355 	bsg_job->reply_len = sizeof(*bsg_reply);
2356 	bsg_reply->result = DID_OK << 16;
2357 	bsg_job_done(bsg_job, bsg_reply->result,
2358 		       bsg_reply->reply_payload_rcv_len);
2359 
2360 	dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
2361 		stats, stats_dma);
2362 
2363 	return 0;
2364 }
2365 
2366 static int
2367 qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
2368 {
2369 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2370 	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2371 	scsi_qla_host_t *vha = shost_priv(host);
2372 	int rval;
2373 	struct qla_dport_diag *dd;
2374 
2375 	if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
2376 	    !IS_QLA28XX(vha->hw))
2377 		return -EPERM;
2378 
2379 	dd = kmalloc(sizeof(*dd), GFP_KERNEL);
2380 	if (!dd) {
2381 		ql_log(ql_log_warn, vha, 0x70db,
2382 		    "Failed to allocate memory for dport.\n");
2383 		return -ENOMEM;
2384 	}
2385 
2386 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2387 	    bsg_job->request_payload.sg_cnt, dd, sizeof(*dd));
2388 
2389 	rval = qla26xx_dport_diagnostics(
2390 	    vha, dd->buf, sizeof(dd->buf), dd->options);
2391 	if (rval == QLA_SUCCESS) {
2392 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2393 		    bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
2394 	}
2395 
2396 	bsg_reply->reply_payload_rcv_len = sizeof(*dd);
2397 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2398 	    rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
2399 
2400 	bsg_job->reply_len = sizeof(*bsg_reply);
2401 	bsg_reply->result = DID_OK << 16;
2402 	bsg_job_done(bsg_job, bsg_reply->result,
2403 		       bsg_reply->reply_payload_rcv_len);
2404 
2405 	kfree(dd);
2406 
2407 	return 0;
2408 }
2409 
2410 static int
2411 qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
2412 {
2413 	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2414 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2415 	struct qla_hw_data *ha = vha->hw;
2416 	struct qla_active_regions regions = { };
2417 	struct active_regions active_regions = { };
2418 
2419 	qla27xx_get_active_image(vha, &active_regions);
2420 	regions.global_image = active_regions.global;
2421 
2422 	if (IS_QLA28XX(ha)) {
2423 		qla28xx_get_aux_images(vha, &active_regions);
2424 		regions.board_config = active_regions.aux.board_config;
2425 		regions.vpd_nvram = active_regions.aux.vpd_nvram;
2426 		regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1;
2427 		regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3;
2428 	}
2429 
2430 	ql_dbg(ql_dbg_user, vha, 0x70e1,
2431 	    "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n",
2432 	    __func__, vha->host_no, regions.global_image,
2433 	    regions.board_config, regions.vpd_nvram,
2434 	    regions.npiv_config_0_1, regions.npiv_config_2_3);
2435 
2436 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2437 	    bsg_job->reply_payload.sg_cnt, &regions, sizeof(regions));
2438 
2439 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2440 	bsg_reply->reply_payload_rcv_len = sizeof(regions);
2441 	bsg_reply->result = DID_OK << 16;
2442 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2443 	bsg_job_done(bsg_job, bsg_reply->result,
2444 	    bsg_reply->reply_payload_rcv_len);
2445 
2446 	return 0;
2447 }
2448 
2449 static int
2450 qla2x00_manage_host_stats(struct bsg_job *bsg_job)
2451 {
2452 	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2453 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2454 	struct ql_vnd_mng_host_stats_param *req_data;
2455 	struct ql_vnd_mng_host_stats_resp rsp_data;
2456 	u32 req_data_len;
2457 	int ret = 0;
2458 
2459 	if (!vha->flags.online) {
2460 		ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
2461 		return -EIO;
2462 	}
2463 
2464 	req_data_len = bsg_job->request_payload.payload_len;
2465 
2466 	if (req_data_len != sizeof(struct ql_vnd_mng_host_stats_param)) {
2467 		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2468 		return -EIO;
2469 	}
2470 
2471 	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2472 	if (!req_data) {
2473 		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2474 		return -ENOMEM;
2475 	}
2476 
2477 	/* Copy the request buffer in req_data */
2478 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2479 			  bsg_job->request_payload.sg_cnt, req_data,
2480 			  req_data_len);
2481 
2482 	switch (req_data->action) {
2483 	case QLA_STOP:
2484 		ret = qla2xxx_stop_stats(vha->host, req_data->stat_type);
2485 		break;
2486 	case QLA_START:
2487 		ret = qla2xxx_start_stats(vha->host, req_data->stat_type);
2488 		break;
2489 	case QLA_CLEAR:
2490 		ret = qla2xxx_reset_stats(vha->host, req_data->stat_type);
2491 		break;
2492 	default:
2493 		ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
2494 		ret = -EIO;
2495 		break;
2496 	}
2497 
2498 	kfree(req_data);
2499 
2500 	/* Prepare response */
2501 	rsp_data.status = ret;
2502 	bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2503 
2504 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2505 	bsg_reply->reply_payload_rcv_len =
2506 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2507 				    bsg_job->reply_payload.sg_cnt,
2508 				    &rsp_data,
2509 				    sizeof(struct ql_vnd_mng_host_stats_resp));
2510 
2511 	bsg_reply->result = DID_OK;
2512 	bsg_job_done(bsg_job, bsg_reply->result,
2513 		     bsg_reply->reply_payload_rcv_len);
2514 
2515 	return ret;
2516 }
2517 
2518 static int
2519 qla2x00_get_host_stats(struct bsg_job *bsg_job)
2520 {
2521 	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2522 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2523 	struct ql_vnd_stats_param *req_data;
2524 	struct ql_vnd_host_stats_resp rsp_data;
2525 	u32 req_data_len;
2526 	int ret = 0;
2527 	u64 ini_entry_count = 0;
2528 	u64 entry_count = 0;
2529 	u64 tgt_num = 0;
2530 	u64 tmp_stat_type = 0;
2531 	u64 response_len = 0;
2532 	void *data;
2533 
2534 	req_data_len = bsg_job->request_payload.payload_len;
2535 
2536 	if (req_data_len != sizeof(struct ql_vnd_stats_param)) {
2537 		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2538 		return -EIO;
2539 	}
2540 
2541 	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2542 	if (!req_data) {
2543 		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2544 		return -ENOMEM;
2545 	}
2546 
2547 	/* Copy the request buffer in req_data */
2548 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2549 			  bsg_job->request_payload.sg_cnt, req_data, req_data_len);
2550 
2551 	/* Copy stat type to work on it */
2552 	tmp_stat_type = req_data->stat_type;
2553 
2554 	if (tmp_stat_type & QLA2XX_TGT_SHT_LNK_DOWN) {
2555 		/* Num of tgts connected to this host */
2556 		tgt_num = qla2x00_get_num_tgts(vha);
2557 		/* unset BIT_17 */
2558 		tmp_stat_type &= ~(1 << 17);
2559 	}
2560 
2561 	/* Total ini stats */
2562 	ini_entry_count = qla2x00_count_set_bits(tmp_stat_type);
2563 
2564 	/* Total number of entries */
2565 	entry_count = ini_entry_count + tgt_num;
2566 
2567 	response_len = sizeof(struct ql_vnd_host_stats_resp) +
2568 		(sizeof(struct ql_vnd_stat_entry) * entry_count);
2569 
2570 	if (response_len > bsg_job->reply_payload.payload_len) {
2571 		rsp_data.status = EXT_STATUS_BUFFER_TOO_SMALL;
2572 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
2573 		bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2574 
2575 		bsg_reply->reply_payload_rcv_len =
2576 			sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2577 					    bsg_job->reply_payload.sg_cnt, &rsp_data,
2578 					    sizeof(struct ql_vnd_mng_host_stats_resp));
2579 
2580 		bsg_reply->result = DID_OK;
2581 		bsg_job_done(bsg_job, bsg_reply->result,
2582 			     bsg_reply->reply_payload_rcv_len);
2583 		goto host_stat_out;
2584 	}
2585 
2586 	data = kzalloc(response_len, GFP_KERNEL);
2587 	if (!data) {
2588 		ret = -ENOMEM;
2589 		goto host_stat_out;
2590 	}
2591 
2592 	ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
2593 				    data, response_len);
2594 
2595 	rsp_data.status = EXT_STATUS_OK;
2596 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2597 
2598 	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2599 							       bsg_job->reply_payload.sg_cnt,
2600 							       data, response_len);
2601 	bsg_reply->result = DID_OK;
2602 	bsg_job_done(bsg_job, bsg_reply->result,
2603 		     bsg_reply->reply_payload_rcv_len);
2604 
2605 	kfree(data);
2606 host_stat_out:
2607 	kfree(req_data);
2608 	return ret;
2609 }
2610 
2611 static struct fc_rport *
2612 qla2xxx_find_rport(scsi_qla_host_t *vha, uint32_t tgt_num)
2613 {
2614 	fc_port_t *fcport = NULL;
2615 
2616 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
2617 		if (fcport->rport->number == tgt_num)
2618 			return fcport->rport;
2619 	}
2620 	return NULL;
2621 }
2622 
2623 static int
2624 qla2x00_get_tgt_stats(struct bsg_job *bsg_job)
2625 {
2626 	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2627 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2628 	struct ql_vnd_tgt_stats_param *req_data;
2629 	u32 req_data_len;
2630 	int ret = 0;
2631 	u64 response_len = 0;
2632 	struct ql_vnd_tgt_stats_resp *data = NULL;
2633 	struct fc_rport *rport = NULL;
2634 
2635 	if (!vha->flags.online) {
2636 		ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
2637 		return -EIO;
2638 	}
2639 
2640 	req_data_len = bsg_job->request_payload.payload_len;
2641 
2642 	if (req_data_len != sizeof(struct ql_vnd_stat_entry)) {
2643 		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2644 		return -EIO;
2645 	}
2646 
2647 	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2648 	if (!req_data) {
2649 		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2650 		return -ENOMEM;
2651 	}
2652 
2653 	/* Copy the request buffer in req_data */
2654 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2655 			  bsg_job->request_payload.sg_cnt,
2656 			  req_data, req_data_len);
2657 
2658 	response_len = sizeof(struct ql_vnd_tgt_stats_resp) +
2659 		sizeof(struct ql_vnd_stat_entry);
2660 
2661 	/* structure + size for one entry */
2662 	data = kzalloc(response_len, GFP_KERNEL);
2663 	if (!data) {
2664 		kfree(req_data);
2665 		return -ENOMEM;
2666 	}
2667 
2668 	if (response_len > bsg_job->reply_payload.payload_len) {
2669 		data->status = EXT_STATUS_BUFFER_TOO_SMALL;
2670 		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
2671 		bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2672 
2673 		bsg_reply->reply_payload_rcv_len =
2674 			sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2675 					    bsg_job->reply_payload.sg_cnt, data,
2676 					    sizeof(struct ql_vnd_tgt_stats_resp));
2677 
2678 		bsg_reply->result = DID_OK;
2679 		bsg_job_done(bsg_job, bsg_reply->result,
2680 			     bsg_reply->reply_payload_rcv_len);
2681 		goto tgt_stat_out;
2682 	}
2683 
2684 	rport = qla2xxx_find_rport(vha, req_data->tgt_id);
2685 	if (!rport) {
2686 		ql_log(ql_log_warn, vha, 0x0000, "target %d not found.\n", req_data->tgt_id);
2687 		ret = EXT_STATUS_INVALID_PARAM;
2688 		data->status = EXT_STATUS_INVALID_PARAM;
2689 		goto reply;
2690 	}
2691 
2692 	ret = qla2xxx_get_tgt_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
2693 				    rport, (void *)data, response_len);
2694 
2695 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2696 reply:
2697 	bsg_reply->reply_payload_rcv_len =
2698 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2699 				    bsg_job->reply_payload.sg_cnt, data,
2700 				    response_len);
2701 	bsg_reply->result = DID_OK;
2702 	bsg_job_done(bsg_job, bsg_reply->result,
2703 		     bsg_reply->reply_payload_rcv_len);
2704 
2705 tgt_stat_out:
2706 	kfree(data);
2707 	kfree(req_data);
2708 
2709 	return ret;
2710 }
2711 
2712 static int
2713 qla2x00_manage_host_port(struct bsg_job *bsg_job)
2714 {
2715 	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2716 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2717 	struct ql_vnd_mng_host_port_param *req_data;
2718 	struct ql_vnd_mng_host_port_resp rsp_data;
2719 	u32 req_data_len;
2720 	int ret = 0;
2721 
2722 	req_data_len = bsg_job->request_payload.payload_len;
2723 
2724 	if (req_data_len != sizeof(struct ql_vnd_mng_host_port_param)) {
2725 		ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2726 		return -EIO;
2727 	}
2728 
2729 	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2730 	if (!req_data) {
2731 		ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2732 		return -ENOMEM;
2733 	}
2734 
2735 	/* Copy the request buffer in req_data */
2736 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2737 			  bsg_job->request_payload.sg_cnt, req_data, req_data_len);
2738 
2739 	switch (req_data->action) {
2740 	case QLA_ENABLE:
2741 		ret = qla2xxx_enable_port(vha->host);
2742 		break;
2743 	case QLA_DISABLE:
2744 		ret = qla2xxx_disable_port(vha->host);
2745 		break;
2746 	default:
2747 		ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
2748 		ret = -EIO;
2749 		break;
2750 	}
2751 
2752 	kfree(req_data);
2753 
2754 	/* Prepare response */
2755 	rsp_data.status = ret;
2756 	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2757 	bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_port_resp);
2758 
2759 	bsg_reply->reply_payload_rcv_len =
2760 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2761 				    bsg_job->reply_payload.sg_cnt, &rsp_data,
2762 				    sizeof(struct ql_vnd_mng_host_port_resp));
2763 	bsg_reply->result = DID_OK;
2764 	bsg_job_done(bsg_job, bsg_reply->result,
2765 		     bsg_reply->reply_payload_rcv_len);
2766 
2767 	return ret;
2768 }
2769 
2770 static int
2771 qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
2772 {
2773 	struct fc_bsg_request *bsg_request = bsg_job->request;
2774 
2775 	switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
2776 	case QL_VND_LOOPBACK:
2777 		return qla2x00_process_loopback(bsg_job);
2778 
2779 	case QL_VND_A84_RESET:
2780 		return qla84xx_reset(bsg_job);
2781 
2782 	case QL_VND_A84_UPDATE_FW:
2783 		return qla84xx_updatefw(bsg_job);
2784 
2785 	case QL_VND_A84_MGMT_CMD:
2786 		return qla84xx_mgmt_cmd(bsg_job);
2787 
2788 	case QL_VND_IIDMA:
2789 		return qla24xx_iidma(bsg_job);
2790 
2791 	case QL_VND_FCP_PRIO_CFG_CMD:
2792 		return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);
2793 
2794 	case QL_VND_READ_FLASH:
2795 		return qla2x00_read_optrom(bsg_job);
2796 
2797 	case QL_VND_UPDATE_FLASH:
2798 		return qla2x00_update_optrom(bsg_job);
2799 
2800 	case QL_VND_SET_FRU_VERSION:
2801 		return qla2x00_update_fru_versions(bsg_job);
2802 
2803 	case QL_VND_READ_FRU_STATUS:
2804 		return qla2x00_read_fru_status(bsg_job);
2805 
2806 	case QL_VND_WRITE_FRU_STATUS:
2807 		return qla2x00_write_fru_status(bsg_job);
2808 
2809 	case QL_VND_WRITE_I2C:
2810 		return qla2x00_write_i2c(bsg_job);
2811 
2812 	case QL_VND_READ_I2C:
2813 		return qla2x00_read_i2c(bsg_job);
2814 
2815 	case QL_VND_DIAG_IO_CMD:
2816 		return qla24xx_process_bidir_cmd(bsg_job);
2817 
2818 	case QL_VND_FX00_MGMT_CMD:
2819 		return qlafx00_mgmt_cmd(bsg_job);
2820 
2821 	case QL_VND_SERDES_OP:
2822 		return qla26xx_serdes_op(bsg_job);
2823 
2824 	case QL_VND_SERDES_OP_EX:
2825 		return qla8044_serdes_op(bsg_job);
2826 
2827 	case QL_VND_GET_FLASH_UPDATE_CAPS:
2828 		return qla27xx_get_flash_upd_cap(bsg_job);
2829 
2830 	case QL_VND_SET_FLASH_UPDATE_CAPS:
2831 		return qla27xx_set_flash_upd_cap(bsg_job);
2832 
2833 	case QL_VND_GET_BBCR_DATA:
2834 		return qla27xx_get_bbcr_data(bsg_job);
2835 
2836 	case QL_VND_GET_PRIV_STATS:
2837 	case QL_VND_GET_PRIV_STATS_EX:
2838 		return qla2x00_get_priv_stats(bsg_job);
2839 
2840 	case QL_VND_DPORT_DIAGNOSTICS:
2841 		return qla2x00_do_dport_diagnostics(bsg_job);
2842 
2843 	case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
2844 		return qla2x00_get_flash_image_status(bsg_job);
2845 
2846 	case QL_VND_MANAGE_HOST_STATS:
2847 		return qla2x00_manage_host_stats(bsg_job);
2848 
2849 	case QL_VND_GET_HOST_STATS:
2850 		return qla2x00_get_host_stats(bsg_job);
2851 
2852 	case QL_VND_GET_TGT_STATS:
2853 		return qla2x00_get_tgt_stats(bsg_job);
2854 
2855 	case QL_VND_MANAGE_HOST_PORT:
2856 		return qla2x00_manage_host_port(bsg_job);
2857 
2858 	default:
2859 		return -ENOSYS;
2860 	}
2861 }
2862 
2863 int
2864 qla24xx_bsg_request(struct bsg_job *bsg_job)
2865 {
2866 	struct fc_bsg_request *bsg_request = bsg_job->request;
2867 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2868 	int ret = -EINVAL;
2869 	struct fc_rport *rport;
2870 	struct Scsi_Host *host;
2871 	scsi_qla_host_t *vha;
2872 
2873 	/* In case no data transferred. */
2874 	bsg_reply->reply_payload_rcv_len = 0;
2875 
2876 	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
2877 		rport = fc_bsg_to_rport(bsg_job);
2878 		host = rport_to_shost(rport);
2879 		vha = shost_priv(host);
2880 	} else {
2881 		host = fc_bsg_to_shost(bsg_job);
2882 		vha = shost_priv(host);
2883 	}
2884 
2885 	/* Disable port will bring down the chip, allow enable command */
2886 	if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
2887 	    bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
2888 		goto skip_chip_chk;
2889 
2890 	if (vha->hw->flags.port_isolated) {
2891 		bsg_reply->result = DID_ERROR;
2892 		/* operation not permitted */
2893 		return -EPERM;
2894 	}
2895 
2896 	if (qla2x00_chip_is_down(vha)) {
2897 		ql_dbg(ql_dbg_user, vha, 0x709f,
2898 		    "BSG: ISP abort active/needed -- cmd=%d.\n",
2899 		    bsg_request->msgcode);
2900 		return -EBUSY;
2901 	}
2902 
2903 skip_chip_chk:
2904 	ql_dbg(ql_dbg_user, vha, 0x7000,
2905 	    "Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);
2906 
2907 	switch (bsg_request->msgcode) {
2908 	case FC_BSG_RPT_ELS:
2909 	case FC_BSG_HST_ELS_NOLOGIN:
2910 		ret = qla2x00_process_els(bsg_job);
2911 		break;
2912 	case FC_BSG_HST_CT:
2913 		ret = qla2x00_process_ct(bsg_job);
2914 		break;
2915 	case FC_BSG_HST_VENDOR:
2916 		ret = qla2x00_process_vendor_specific(bsg_job);
2917 		break;
2918 	case FC_BSG_HST_ADD_RPORT:
2919 	case FC_BSG_HST_DEL_RPORT:
2920 	case FC_BSG_RPT_CT:
2921 	default:
2922 		ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
2923 		break;
2924 	}
2925 	return ret;
2926 }
2927 
2928 int
2929 qla24xx_bsg_timeout(struct bsg_job *bsg_job)
2930 {
2931 	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2932 	scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2933 	struct qla_hw_data *ha = vha->hw;
2934 	srb_t *sp;
2935 	int cnt, que;
2936 	unsigned long flags;
2937 	struct req_que *req;
2938 
2939 	/* find the bsg job from the active list of commands */
2940 	spin_lock_irqsave(&ha->hardware_lock, flags);
2941 	for (que = 0; que < ha->max_req_queues; que++) {
2942 		req = ha->req_q_map[que];
2943 		if (!req)
2944 			continue;
2945 
2946 		for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
2947 			sp = req->outstanding_cmds[cnt];
2948 			if (sp) {
2949 				if (((sp->type == SRB_CT_CMD) ||
2950 					(sp->type == SRB_ELS_CMD_HST) ||
2951 					(sp->type == SRB_FXIOCB_BCMD))
2952 					&& (sp->u.bsg_job == bsg_job)) {
2953 					req->outstanding_cmds[cnt] = NULL;
2954 					spin_unlock_irqrestore(&ha->hardware_lock, flags);
2955 					if (ha->isp_ops->abort_command(sp)) {
2956 						ql_log(ql_log_warn, vha, 0x7089,
2957 						    "mbx abort_command "
2958 						    "failed.\n");
2959 						bsg_reply->result = -EIO;
2960 					} else {
2961 						ql_dbg(ql_dbg_user, vha, 0x708a,
2962 						    "mbx abort_command "
2963 						    "success.\n");
2964 						bsg_reply->result = 0;
2965 					}
2966 					spin_lock_irqsave(&ha->hardware_lock, flags);
2967 					goto done;
2968 				}
2969 			}
2970 		}
2971 	}
2972 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
2973 	ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
2974 	bsg_reply->result = -ENXIO;
2975 	return 0;
2976 
2977 done:
2978 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
2979 	sp->free(sp);
2980 	return 0;
2981 }
2982