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