xref: /linux/drivers/scsi/qla2xxx/qla_bsg.c (revision b43ab901d671e3e3cad425ea5e9a3c74e266dcdd)
1 /*
2  * QLogic Fibre Channel HBA Driver
3  * Copyright (c)  2003-2011 QLogic Corporation
4  *
5  * See LICENSE.qla2xxx for copyright and licensing details.
6  */
7 #include "qla_def.h"
8 
9 #include <linux/kthread.h>
10 #include <linux/vmalloc.h>
11 #include <linux/delay.h>
12 
13 /* BSG support for ELS/CT pass through */
14 inline srb_t *
15 qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size)
16 {
17 	srb_t *sp;
18 	struct qla_hw_data *ha = vha->hw;
19 	struct srb_ctx *ctx;
20 
21 	sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
22 	if (!sp)
23 		goto done;
24 	ctx = kzalloc(size, GFP_KERNEL);
25 	if (!ctx) {
26 		mempool_free(sp, ha->srb_mempool);
27 		sp = NULL;
28 		goto done;
29 	}
30 
31 	memset(sp, 0, sizeof(*sp));
32 	sp->fcport = fcport;
33 	sp->ctx = ctx;
34 	ctx->iocbs = 1;
35 done:
36 	return sp;
37 }
38 
39 int
40 qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
41 	struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
42 {
43 	int i, ret, num_valid;
44 	uint8_t *bcode;
45 	struct qla_fcp_prio_entry *pri_entry;
46 	uint32_t *bcode_val_ptr, bcode_val;
47 
48 	ret = 1;
49 	num_valid = 0;
50 	bcode = (uint8_t *)pri_cfg;
51 	bcode_val_ptr = (uint32_t *)pri_cfg;
52 	bcode_val = (uint32_t)(*bcode_val_ptr);
53 
54 	if (bcode_val == 0xFFFFFFFF) {
55 		/* No FCP Priority config data in flash */
56 		ql_dbg(ql_dbg_user, vha, 0x7051,
57 		    "No FCP Priority config data.\n");
58 		return 0;
59 	}
60 
61 	if (bcode[0] != 'H' || bcode[1] != 'Q' || bcode[2] != 'O' ||
62 			bcode[3] != 'S') {
63 		/* Invalid FCP priority data header*/
64 		ql_dbg(ql_dbg_user, vha, 0x7052,
65 		    "Invalid FCP Priority data header. bcode=0x%x.\n",
66 		    bcode_val);
67 		return 0;
68 	}
69 	if (flag != 1)
70 		return ret;
71 
72 	pri_entry = &pri_cfg->entry[0];
73 	for (i = 0; i < pri_cfg->num_entries; i++) {
74 		if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
75 			num_valid++;
76 		pri_entry++;
77 	}
78 
79 	if (num_valid == 0) {
80 		/* No valid FCP priority data entries */
81 		ql_dbg(ql_dbg_user, vha, 0x7053,
82 		    "No valid FCP Priority data entries.\n");
83 		ret = 0;
84 	} else {
85 		/* FCP priority data is valid */
86 		ql_dbg(ql_dbg_user, vha, 0x7054,
87 		    "Valid FCP priority data. num entries = %d.\n",
88 		    num_valid);
89 	}
90 
91 	return ret;
92 }
93 
94 static int
95 qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
96 {
97 	struct Scsi_Host *host = bsg_job->shost;
98 	scsi_qla_host_t *vha = shost_priv(host);
99 	struct qla_hw_data *ha = vha->hw;
100 	int ret = 0;
101 	uint32_t len;
102 	uint32_t oper;
103 
104 	bsg_job->reply->reply_payload_rcv_len = 0;
105 
106 	if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA82XX(ha))) {
107 		ret = -EINVAL;
108 		goto exit_fcp_prio_cfg;
109 	}
110 
111 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
112 		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
113 		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
114 		ret = -EBUSY;
115 		goto exit_fcp_prio_cfg;
116 	}
117 
118 	/* Get the sub command */
119 	oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
120 
121 	/* Only set config is allowed if config memory is not allocated */
122 	if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
123 		ret = -EINVAL;
124 		goto exit_fcp_prio_cfg;
125 	}
126 	switch (oper) {
127 	case QLFC_FCP_PRIO_DISABLE:
128 		if (ha->flags.fcp_prio_enabled) {
129 			ha->flags.fcp_prio_enabled = 0;
130 			ha->fcp_prio_cfg->attributes &=
131 				~FCP_PRIO_ATTR_ENABLE;
132 			qla24xx_update_all_fcp_prio(vha);
133 			bsg_job->reply->result = DID_OK;
134 		} else {
135 			ret = -EINVAL;
136 			bsg_job->reply->result = (DID_ERROR << 16);
137 			goto exit_fcp_prio_cfg;
138 		}
139 		break;
140 
141 	case QLFC_FCP_PRIO_ENABLE:
142 		if (!ha->flags.fcp_prio_enabled) {
143 			if (ha->fcp_prio_cfg) {
144 				ha->flags.fcp_prio_enabled = 1;
145 				ha->fcp_prio_cfg->attributes |=
146 				    FCP_PRIO_ATTR_ENABLE;
147 				qla24xx_update_all_fcp_prio(vha);
148 				bsg_job->reply->result = DID_OK;
149 			} else {
150 				ret = -EINVAL;
151 				bsg_job->reply->result = (DID_ERROR << 16);
152 				goto exit_fcp_prio_cfg;
153 			}
154 		}
155 		break;
156 
157 	case QLFC_FCP_PRIO_GET_CONFIG:
158 		len = bsg_job->reply_payload.payload_len;
159 		if (!len || len > FCP_PRIO_CFG_SIZE) {
160 			ret = -EINVAL;
161 			bsg_job->reply->result = (DID_ERROR << 16);
162 			goto exit_fcp_prio_cfg;
163 		}
164 
165 		bsg_job->reply->result = DID_OK;
166 		bsg_job->reply->reply_payload_rcv_len =
167 			sg_copy_from_buffer(
168 			bsg_job->reply_payload.sg_list,
169 			bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
170 			len);
171 
172 		break;
173 
174 	case QLFC_FCP_PRIO_SET_CONFIG:
175 		len = bsg_job->request_payload.payload_len;
176 		if (!len || len > FCP_PRIO_CFG_SIZE) {
177 			bsg_job->reply->result = (DID_ERROR << 16);
178 			ret = -EINVAL;
179 			goto exit_fcp_prio_cfg;
180 		}
181 
182 		if (!ha->fcp_prio_cfg) {
183 			ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE);
184 			if (!ha->fcp_prio_cfg) {
185 				ql_log(ql_log_warn, vha, 0x7050,
186 				    "Unable to allocate memory for fcp prio "
187 				    "config data (%x).\n", FCP_PRIO_CFG_SIZE);
188 				bsg_job->reply->result = (DID_ERROR << 16);
189 				ret = -ENOMEM;
190 				goto exit_fcp_prio_cfg;
191 			}
192 		}
193 
194 		memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE);
195 		sg_copy_to_buffer(bsg_job->request_payload.sg_list,
196 		bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg,
197 			FCP_PRIO_CFG_SIZE);
198 
199 		/* validate fcp priority data */
200 
201 		if (!qla24xx_fcp_prio_cfg_valid(vha,
202 		    (struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) {
203 			bsg_job->reply->result = (DID_ERROR << 16);
204 			ret = -EINVAL;
205 			/* If buffer was invalidatic int
206 			 * fcp_prio_cfg is of no use
207 			 */
208 			vfree(ha->fcp_prio_cfg);
209 			ha->fcp_prio_cfg = NULL;
210 			goto exit_fcp_prio_cfg;
211 		}
212 
213 		ha->flags.fcp_prio_enabled = 0;
214 		if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
215 			ha->flags.fcp_prio_enabled = 1;
216 		qla24xx_update_all_fcp_prio(vha);
217 		bsg_job->reply->result = DID_OK;
218 		break;
219 	default:
220 		ret = -EINVAL;
221 		break;
222 	}
223 exit_fcp_prio_cfg:
224 	bsg_job->job_done(bsg_job);
225 	return ret;
226 }
227 static int
228 qla2x00_process_els(struct fc_bsg_job *bsg_job)
229 {
230 	struct fc_rport *rport;
231 	fc_port_t *fcport = NULL;
232 	struct Scsi_Host *host;
233 	scsi_qla_host_t *vha;
234 	struct qla_hw_data *ha;
235 	srb_t *sp;
236 	const char *type;
237 	int req_sg_cnt, rsp_sg_cnt;
238 	int rval =  (DRIVER_ERROR << 16);
239 	uint16_t nextlid = 0;
240 	struct srb_ctx *els;
241 
242 	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
243 		rport = bsg_job->rport;
244 		fcport = *(fc_port_t **) rport->dd_data;
245 		host = rport_to_shost(rport);
246 		vha = shost_priv(host);
247 		ha = vha->hw;
248 		type = "FC_BSG_RPT_ELS";
249 	} else {
250 		host = bsg_job->shost;
251 		vha = shost_priv(host);
252 		ha = vha->hw;
253 		type = "FC_BSG_HST_ELS_NOLOGIN";
254 	}
255 
256 	/* pass through is supported only for ISP 4Gb or higher */
257 	if (!IS_FWI2_CAPABLE(ha)) {
258 		ql_dbg(ql_dbg_user, vha, 0x7001,
259 		    "ELS passthru not supported for ISP23xx based adapters.\n");
260 		rval = -EPERM;
261 		goto done;
262 	}
263 
264 	/*  Multiple SG's are not supported for ELS requests */
265 	if (bsg_job->request_payload.sg_cnt > 1 ||
266 		bsg_job->reply_payload.sg_cnt > 1) {
267 		ql_dbg(ql_dbg_user, vha, 0x7002,
268 		    "Multiple SG's are not suppored for ELS requests, "
269 		    "request_sg_cnt=%x reply_sg_cnt=%x.\n",
270 		    bsg_job->request_payload.sg_cnt,
271 		    bsg_job->reply_payload.sg_cnt);
272 		rval = -EPERM;
273 		goto done;
274 	}
275 
276 	/* ELS request for rport */
277 	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
278 		/* make sure the rport is logged in,
279 		 * if not perform fabric login
280 		 */
281 		if (qla2x00_fabric_login(vha, fcport, &nextlid)) {
282 			ql_dbg(ql_dbg_user, vha, 0x7003,
283 			    "Failed to login port %06X for ELS passthru.\n",
284 			    fcport->d_id.b24);
285 			rval = -EIO;
286 			goto done;
287 		}
288 	} else {
289 		/* Allocate a dummy fcport structure, since functions
290 		 * preparing the IOCB and mailbox command retrieves port
291 		 * specific information from fcport structure. For Host based
292 		 * ELS commands there will be no fcport structure allocated
293 		 */
294 		fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
295 		if (!fcport) {
296 			rval = -ENOMEM;
297 			goto done;
298 		}
299 
300 		/* Initialize all required  fields of fcport */
301 		fcport->vha = vha;
302 		fcport->vp_idx = vha->vp_idx;
303 		fcport->d_id.b.al_pa =
304 			bsg_job->request->rqst_data.h_els.port_id[0];
305 		fcport->d_id.b.area =
306 			bsg_job->request->rqst_data.h_els.port_id[1];
307 		fcport->d_id.b.domain =
308 			bsg_job->request->rqst_data.h_els.port_id[2];
309 		fcport->loop_id =
310 			(fcport->d_id.b.al_pa == 0xFD) ?
311 			NPH_FABRIC_CONTROLLER : NPH_F_PORT;
312 	}
313 
314 	if (!vha->flags.online) {
315 		ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
316 		rval = -EIO;
317 		goto done;
318 	}
319 
320 	req_sg_cnt =
321 		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
322 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
323 	if (!req_sg_cnt) {
324 		rval = -ENOMEM;
325 		goto done_free_fcport;
326 	}
327 
328 	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
329 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
330         if (!rsp_sg_cnt) {
331 		rval = -ENOMEM;
332 		goto done_free_fcport;
333 	}
334 
335 	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
336 		(rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
337 		ql_log(ql_log_warn, vha, 0x7008,
338 		    "dma mapping resulted in different sg counts, "
339 		    "request_sg_cnt: %x dma_request_sg_cnt:%x reply_sg_cnt:%x "
340 		    "dma_reply_sg_cnt:%x.\n", bsg_job->request_payload.sg_cnt,
341 		    req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
342 		rval = -EAGAIN;
343 		goto done_unmap_sg;
344 	}
345 
346 	/* Alloc SRB structure */
347 	sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx));
348 	if (!sp) {
349 		rval = -ENOMEM;
350 		goto done_unmap_sg;
351 	}
352 
353 	els = sp->ctx;
354 	els->type =
355 		(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
356 		SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
357 	els->name =
358 		(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
359 		"bsg_els_rpt" : "bsg_els_hst");
360 	els->u.bsg_job = bsg_job;
361 
362 	ql_dbg(ql_dbg_user, vha, 0x700a,
363 	    "bsg rqst type: %s els type: %x - loop-id=%x "
364 	    "portid=%-2x%02x%02x.\n", type,
365 	    bsg_job->request->rqst_data.h_els.command_code, fcport->loop_id,
366 	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
367 
368 	rval = qla2x00_start_sp(sp);
369 	if (rval != QLA_SUCCESS) {
370 		ql_log(ql_log_warn, vha, 0x700e,
371 		    "qla2x00_start_sp failed = %d\n", rval);
372 		kfree(sp->ctx);
373 		mempool_free(sp, ha->srb_mempool);
374 		rval = -EIO;
375 		goto done_unmap_sg;
376 	}
377 	return rval;
378 
379 done_unmap_sg:
380 	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
381 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
382 	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
383 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
384 	goto done_free_fcport;
385 
386 done_free_fcport:
387 	if (bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN)
388 		kfree(fcport);
389 done:
390 	return rval;
391 }
392 
393 inline uint16_t
394 qla24xx_calc_ct_iocbs(uint16_t dsds)
395 {
396 	uint16_t iocbs;
397 
398 	iocbs = 1;
399 	if (dsds > 2) {
400 		iocbs += (dsds - 2) / 5;
401 		if ((dsds - 2) % 5)
402 			iocbs++;
403 	}
404 	return iocbs;
405 }
406 
407 static int
408 qla2x00_process_ct(struct fc_bsg_job *bsg_job)
409 {
410 	srb_t *sp;
411 	struct Scsi_Host *host = bsg_job->shost;
412 	scsi_qla_host_t *vha = shost_priv(host);
413 	struct qla_hw_data *ha = vha->hw;
414 	int rval = (DRIVER_ERROR << 16);
415 	int req_sg_cnt, rsp_sg_cnt;
416 	uint16_t loop_id;
417 	struct fc_port *fcport;
418 	char  *type = "FC_BSG_HST_CT";
419 	struct srb_ctx *ct;
420 
421 	req_sg_cnt =
422 		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
423 			bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
424 	if (!req_sg_cnt) {
425 		ql_log(ql_log_warn, vha, 0x700f,
426 		    "dma_map_sg return %d for request\n", req_sg_cnt);
427 		rval = -ENOMEM;
428 		goto done;
429 	}
430 
431 	rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
432 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
433 	if (!rsp_sg_cnt) {
434 		ql_log(ql_log_warn, vha, 0x7010,
435 		    "dma_map_sg return %d for reply\n", rsp_sg_cnt);
436 		rval = -ENOMEM;
437 		goto done;
438 	}
439 
440 	if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
441 	    (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
442 		ql_log(ql_log_warn, vha, 0x7011,
443 		    "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
444 		    "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
445 		    req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
446 		rval = -EAGAIN;
447 		goto done_unmap_sg;
448 	}
449 
450 	if (!vha->flags.online) {
451 		ql_log(ql_log_warn, vha, 0x7012,
452 		    "Host is not online.\n");
453 		rval = -EIO;
454 		goto done_unmap_sg;
455 	}
456 
457 	loop_id =
458 		(bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
459 			>> 24;
460 	switch (loop_id) {
461 	case 0xFC:
462 		loop_id = cpu_to_le16(NPH_SNS);
463 		break;
464 	case 0xFA:
465 		loop_id = vha->mgmt_svr_loop_id;
466 		break;
467 	default:
468 		ql_dbg(ql_dbg_user, vha, 0x7013,
469 		    "Unknown loop id: %x.\n", loop_id);
470 		rval = -EINVAL;
471 		goto done_unmap_sg;
472 	}
473 
474 	/* Allocate a dummy fcport structure, since functions preparing the
475 	 * IOCB and mailbox command retrieves port specific information
476 	 * from fcport structure. For Host based ELS commands there will be
477 	 * no fcport structure allocated
478 	 */
479 	fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
480 	if (!fcport) {
481 		ql_log(ql_log_warn, vha, 0x7014,
482 		    "Failed to allocate fcport.\n");
483 		rval = -ENOMEM;
484 		goto done_unmap_sg;
485 	}
486 
487 	/* Initialize all required  fields of fcport */
488 	fcport->vha = vha;
489 	fcport->vp_idx = vha->vp_idx;
490 	fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0];
491 	fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1];
492 	fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2];
493 	fcport->loop_id = loop_id;
494 
495 	/* Alloc SRB structure */
496 	sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx));
497 	if (!sp) {
498 		ql_log(ql_log_warn, vha, 0x7015,
499 		    "qla2x00_get_ctx_bsg_sp failed.\n");
500 		rval = -ENOMEM;
501 		goto done_free_fcport;
502 	}
503 
504 	ct = sp->ctx;
505 	ct->type = SRB_CT_CMD;
506 	ct->name = "bsg_ct";
507 	ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
508 	ct->u.bsg_job = bsg_job;
509 
510 	ql_dbg(ql_dbg_user, vha, 0x7016,
511 	    "bsg rqst type: %s else type: %x - "
512 	    "loop-id=%x portid=%02x%02x%02x.\n", type,
513 	    (bsg_job->request->rqst_data.h_ct.preamble_word2 >> 16),
514 	    fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
515 	    fcport->d_id.b.al_pa);
516 
517 	rval = qla2x00_start_sp(sp);
518 	if (rval != QLA_SUCCESS) {
519 		ql_log(ql_log_warn, vha, 0x7017,
520 		    "qla2x00_start_sp failed=%d.\n", rval);
521 		kfree(sp->ctx);
522 		mempool_free(sp, ha->srb_mempool);
523 		rval = -EIO;
524 		goto done_free_fcport;
525 	}
526 	return rval;
527 
528 done_free_fcport:
529 	kfree(fcport);
530 done_unmap_sg:
531 	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
532 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
533 	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
534 		bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
535 done:
536 	return rval;
537 }
538 
539 /* Set the port configuration to enable the
540  * internal loopback on ISP81XX
541  */
542 static inline int
543 qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
544     uint16_t *new_config)
545 {
546 	int ret = 0;
547 	int rval = 0;
548 	struct qla_hw_data *ha = vha->hw;
549 
550 	if (!IS_QLA81XX(ha))
551 		goto done_set_internal;
552 
553 	new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
554 	memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
555 
556 	ha->notify_dcbx_comp = 1;
557 	ret = qla81xx_set_port_config(vha, new_config);
558 	if (ret != QLA_SUCCESS) {
559 		ql_log(ql_log_warn, vha, 0x7021,
560 		    "set port config failed.\n");
561 		ha->notify_dcbx_comp = 0;
562 		rval = -EINVAL;
563 		goto done_set_internal;
564 	}
565 
566 	/* Wait for DCBX complete event */
567 	if (!wait_for_completion_timeout(&ha->dcbx_comp, (20 * HZ))) {
568 		ql_dbg(ql_dbg_user, vha, 0x7022,
569 		    "State change notification not received.\n");
570 	} else
571 		ql_dbg(ql_dbg_user, vha, 0x7023,
572 		    "State change received.\n");
573 
574 	ha->notify_dcbx_comp = 0;
575 
576 done_set_internal:
577 	return rval;
578 }
579 
580 /* Set the port configuration to disable the
581  * internal loopback on ISP81XX
582  */
583 static inline int
584 qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
585     int wait)
586 {
587 	int ret = 0;
588 	int rval = 0;
589 	uint16_t new_config[4];
590 	struct qla_hw_data *ha = vha->hw;
591 
592 	if (!IS_QLA81XX(ha))
593 		goto done_reset_internal;
594 
595 	memset(new_config, 0 , sizeof(new_config));
596 	if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
597 			ENABLE_INTERNAL_LOOPBACK) {
598 		new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
599 		memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
600 
601 		ha->notify_dcbx_comp = wait;
602 		ret = qla81xx_set_port_config(vha, new_config);
603 		if (ret != QLA_SUCCESS) {
604 			ql_log(ql_log_warn, vha, 0x7025,
605 			    "Set port config failed.\n");
606 			ha->notify_dcbx_comp = 0;
607 			rval = -EINVAL;
608 			goto done_reset_internal;
609 		}
610 
611 		/* Wait for DCBX complete event */
612 		if (wait && !wait_for_completion_timeout(&ha->dcbx_comp,
613 			(20 * HZ))) {
614 			ql_dbg(ql_dbg_user, vha, 0x7026,
615 			    "State change notification not received.\n");
616 			ha->notify_dcbx_comp = 0;
617 			rval = -EINVAL;
618 			goto done_reset_internal;
619 		} else
620 			ql_dbg(ql_dbg_user, vha, 0x7027,
621 			    "State change received.\n");
622 
623 		ha->notify_dcbx_comp = 0;
624 	}
625 done_reset_internal:
626 	return rval;
627 }
628 
629 static int
630 qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
631 {
632 	struct Scsi_Host *host = bsg_job->shost;
633 	scsi_qla_host_t *vha = shost_priv(host);
634 	struct qla_hw_data *ha = vha->hw;
635 	int rval;
636 	uint8_t command_sent;
637 	char *type;
638 	struct msg_echo_lb elreq;
639 	uint16_t response[MAILBOX_REGISTER_COUNT];
640 	uint16_t config[4], new_config[4];
641 	uint8_t *fw_sts_ptr;
642 	uint8_t *req_data = NULL;
643 	dma_addr_t req_data_dma;
644 	uint32_t req_data_len;
645 	uint8_t *rsp_data = NULL;
646 	dma_addr_t rsp_data_dma;
647 	uint32_t rsp_data_len;
648 
649 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
650 		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
651 		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
652 		ql_log(ql_log_warn, vha, 0x7018, "Abort active or needed.\n");
653 		return -EBUSY;
654 	}
655 
656 	if (!vha->flags.online) {
657 		ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
658 		return -EIO;
659 	}
660 
661 	elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
662 		bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt,
663 		DMA_TO_DEVICE);
664 
665 	if (!elreq.req_sg_cnt) {
666 		ql_log(ql_log_warn, vha, 0x701a,
667 		    "dma_map_sg returned %d for request.\n", elreq.req_sg_cnt);
668 		return -ENOMEM;
669 	}
670 
671 	elreq.rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
672 		bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
673 		DMA_FROM_DEVICE);
674 
675 	if (!elreq.rsp_sg_cnt) {
676 		ql_log(ql_log_warn, vha, 0x701b,
677 		    "dma_map_sg returned %d for reply.\n", elreq.rsp_sg_cnt);
678 		rval = -ENOMEM;
679 		goto done_unmap_req_sg;
680 	}
681 
682 	if ((elreq.req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
683 		(elreq.rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
684 		ql_log(ql_log_warn, vha, 0x701c,
685 		    "dma mapping resulted in different sg counts, "
686 		    "request_sg_cnt: %x dma_request_sg_cnt: %x "
687 		    "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
688 		    bsg_job->request_payload.sg_cnt, elreq.req_sg_cnt,
689 		    bsg_job->reply_payload.sg_cnt, elreq.rsp_sg_cnt);
690 		rval = -EAGAIN;
691 		goto done_unmap_sg;
692 	}
693 	req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
694 	req_data = dma_alloc_coherent(&ha->pdev->dev, req_data_len,
695 		&req_data_dma, GFP_KERNEL);
696 	if (!req_data) {
697 		ql_log(ql_log_warn, vha, 0x701d,
698 		    "dma alloc failed for req_data.\n");
699 		rval = -ENOMEM;
700 		goto done_unmap_sg;
701 	}
702 
703 	rsp_data = dma_alloc_coherent(&ha->pdev->dev, rsp_data_len,
704 		&rsp_data_dma, GFP_KERNEL);
705 	if (!rsp_data) {
706 		ql_log(ql_log_warn, vha, 0x7004,
707 		    "dma alloc failed for rsp_data.\n");
708 		rval = -ENOMEM;
709 		goto done_free_dma_req;
710 	}
711 
712 	/* Copy the request buffer in req_data now */
713 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
714 		bsg_job->request_payload.sg_cnt, req_data, req_data_len);
715 
716 	elreq.send_dma = req_data_dma;
717 	elreq.rcv_dma = rsp_data_dma;
718 	elreq.transfer_size = req_data_len;
719 
720 	elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
721 
722 	if ((ha->current_topology == ISP_CFG_F ||
723 	    (atomic_read(&vha->loop_state) == LOOP_DOWN) ||
724 	    (IS_QLA81XX(ha) &&
725 	    le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
726 	    && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
727 		elreq.options == EXTERNAL_LOOPBACK) {
728 		type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
729 		ql_dbg(ql_dbg_user, vha, 0x701e,
730 		    "BSG request type: %s.\n", type);
731 		command_sent = INT_DEF_LB_ECHO_CMD;
732 		rval = qla2x00_echo_test(vha, &elreq, response);
733 	} else {
734 		if (IS_QLA81XX(ha)) {
735 			memset(config, 0, sizeof(config));
736 			memset(new_config, 0, sizeof(new_config));
737 			if (qla81xx_get_port_config(vha, config)) {
738 				ql_log(ql_log_warn, vha, 0x701f,
739 				    "Get port config failed.\n");
740 				bsg_job->reply->reply_payload_rcv_len = 0;
741 				bsg_job->reply->result = (DID_ERROR << 16);
742 				rval = -EPERM;
743 				goto done_free_dma_req;
744 			}
745 
746 			if (elreq.options != EXTERNAL_LOOPBACK) {
747 				ql_dbg(ql_dbg_user, vha, 0x7020,
748 				    "Internal: curent port config = %x\n",
749 				    config[0]);
750 				if (qla81xx_set_internal_loopback(vha, config,
751 					new_config)) {
752 					ql_log(ql_log_warn, vha, 0x7024,
753 					    "Internal loopback failed.\n");
754 					bsg_job->reply->reply_payload_rcv_len =
755 						0;
756 					bsg_job->reply->result =
757 						(DID_ERROR << 16);
758 					rval = -EPERM;
759 					goto done_free_dma_req;
760 				}
761 			} else {
762 				/* For external loopback to work
763 				 * ensure internal loopback is disabled
764 				 */
765 				if (qla81xx_reset_internal_loopback(vha,
766 					config, 1)) {
767 					bsg_job->reply->reply_payload_rcv_len =
768 						0;
769 					bsg_job->reply->result =
770 						(DID_ERROR << 16);
771 					rval = -EPERM;
772 					goto done_free_dma_req;
773 				}
774 			}
775 
776 			type = "FC_BSG_HST_VENDOR_LOOPBACK";
777 			ql_dbg(ql_dbg_user, vha, 0x7028,
778 			    "BSG request type: %s.\n", type);
779 
780 			command_sent = INT_DEF_LB_LOOPBACK_CMD;
781 			rval = qla2x00_loopback_test(vha, &elreq, response);
782 
783 			if (new_config[0]) {
784 				/* Revert back to original port config
785 				 * Also clear internal loopback
786 				 */
787 				qla81xx_reset_internal_loopback(vha,
788 				    new_config, 0);
789 			}
790 
791 			if (response[0] == MBS_COMMAND_ERROR &&
792 					response[1] == MBS_LB_RESET) {
793 				ql_log(ql_log_warn, vha, 0x7029,
794 				    "MBX command error, Aborting ISP.\n");
795 				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
796 				qla2xxx_wake_dpc(vha);
797 				qla2x00_wait_for_chip_reset(vha);
798 				/* Also reset the MPI */
799 				if (qla81xx_restart_mpi_firmware(vha) !=
800 				    QLA_SUCCESS) {
801 					ql_log(ql_log_warn, vha, 0x702a,
802 					    "MPI reset failed.\n");
803 				}
804 
805 				bsg_job->reply->reply_payload_rcv_len = 0;
806 				bsg_job->reply->result = (DID_ERROR << 16);
807 				rval = -EIO;
808 				goto done_free_dma_req;
809 			}
810 		} else {
811 			type = "FC_BSG_HST_VENDOR_LOOPBACK";
812 			ql_dbg(ql_dbg_user, vha, 0x702b,
813 			    "BSG request type: %s.\n", type);
814 			command_sent = INT_DEF_LB_LOOPBACK_CMD;
815 			rval = qla2x00_loopback_test(vha, &elreq, response);
816 		}
817 	}
818 
819 	if (rval) {
820 		ql_log(ql_log_warn, vha, 0x702c,
821 		    "Vendor request %s failed.\n", type);
822 
823 		fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
824 		    sizeof(struct fc_bsg_reply);
825 
826 		memcpy(fw_sts_ptr, response, sizeof(response));
827 		fw_sts_ptr += sizeof(response);
828 		*fw_sts_ptr = command_sent;
829 		rval = 0;
830 		bsg_job->reply->reply_payload_rcv_len = 0;
831 		bsg_job->reply->result = (DID_ERROR << 16);
832 	} else {
833 		ql_dbg(ql_dbg_user, vha, 0x702d,
834 		    "Vendor request %s completed.\n", type);
835 
836 		bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
837 			sizeof(response) + sizeof(uint8_t);
838 		bsg_job->reply->reply_payload_rcv_len =
839 			bsg_job->reply_payload.payload_len;
840 		fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
841 			sizeof(struct fc_bsg_reply);
842 		memcpy(fw_sts_ptr, response, sizeof(response));
843 		fw_sts_ptr += sizeof(response);
844 		*fw_sts_ptr = command_sent;
845 		bsg_job->reply->result = DID_OK;
846 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
847 			bsg_job->reply_payload.sg_cnt, rsp_data,
848 			rsp_data_len);
849 	}
850 	bsg_job->job_done(bsg_job);
851 
852 	dma_free_coherent(&ha->pdev->dev, rsp_data_len,
853 		rsp_data, rsp_data_dma);
854 done_free_dma_req:
855 	dma_free_coherent(&ha->pdev->dev, req_data_len,
856 		req_data, req_data_dma);
857 done_unmap_sg:
858 	dma_unmap_sg(&ha->pdev->dev,
859 	    bsg_job->reply_payload.sg_list,
860 	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
861 done_unmap_req_sg:
862 	dma_unmap_sg(&ha->pdev->dev,
863 	    bsg_job->request_payload.sg_list,
864 	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
865 	return rval;
866 }
867 
868 static int
869 qla84xx_reset(struct fc_bsg_job *bsg_job)
870 {
871 	struct Scsi_Host *host = bsg_job->shost;
872 	scsi_qla_host_t *vha = shost_priv(host);
873 	struct qla_hw_data *ha = vha->hw;
874 	int rval = 0;
875 	uint32_t flag;
876 
877 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
878 	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
879 	    test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
880 		ql_log(ql_log_warn, vha, 0x702e, "Abort active or needed.\n");
881 		return -EBUSY;
882 	}
883 
884 	if (!IS_QLA84XX(ha)) {
885 		ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
886 		return -EINVAL;
887 	}
888 
889 	flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
890 
891 	rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
892 
893 	if (rval) {
894 		ql_log(ql_log_warn, vha, 0x7030,
895 		    "Vendor request 84xx reset failed.\n");
896 		rval = bsg_job->reply->reply_payload_rcv_len = 0;
897 		bsg_job->reply->result = (DID_ERROR << 16);
898 
899 	} else {
900 		ql_dbg(ql_dbg_user, vha, 0x7031,
901 		    "Vendor request 84xx reset completed.\n");
902 		bsg_job->reply->result = DID_OK;
903 	}
904 
905 	bsg_job->job_done(bsg_job);
906 	return rval;
907 }
908 
909 static int
910 qla84xx_updatefw(struct fc_bsg_job *bsg_job)
911 {
912 	struct Scsi_Host *host = bsg_job->shost;
913 	scsi_qla_host_t *vha = shost_priv(host);
914 	struct qla_hw_data *ha = vha->hw;
915 	struct verify_chip_entry_84xx *mn = NULL;
916 	dma_addr_t mn_dma, fw_dma;
917 	void *fw_buf = NULL;
918 	int rval = 0;
919 	uint32_t sg_cnt;
920 	uint32_t data_len;
921 	uint16_t options;
922 	uint32_t flag;
923 	uint32_t fw_ver;
924 
925 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
926 		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
927 		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags))
928 		return -EBUSY;
929 
930 	if (!IS_QLA84XX(ha)) {
931 		ql_dbg(ql_dbg_user, vha, 0x7032,
932 		    "Not 84xx, exiting.\n");
933 		return -EINVAL;
934 	}
935 
936 	sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
937 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
938 	if (!sg_cnt) {
939 		ql_log(ql_log_warn, vha, 0x7033,
940 		    "dma_map_sg returned %d for request.\n", sg_cnt);
941 		return -ENOMEM;
942 	}
943 
944 	if (sg_cnt != bsg_job->request_payload.sg_cnt) {
945 		ql_log(ql_log_warn, vha, 0x7034,
946 		    "DMA mapping resulted in different sg counts, "
947 		    "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
948 		    bsg_job->request_payload.sg_cnt, sg_cnt);
949 		rval = -EAGAIN;
950 		goto done_unmap_sg;
951 	}
952 
953 	data_len = bsg_job->request_payload.payload_len;
954 	fw_buf = dma_alloc_coherent(&ha->pdev->dev, data_len,
955 		&fw_dma, GFP_KERNEL);
956 	if (!fw_buf) {
957 		ql_log(ql_log_warn, vha, 0x7035,
958 		    "DMA alloc failed for fw_buf.\n");
959 		rval = -ENOMEM;
960 		goto done_unmap_sg;
961 	}
962 
963 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
964 		bsg_job->request_payload.sg_cnt, fw_buf, data_len);
965 
966 	mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
967 	if (!mn) {
968 		ql_log(ql_log_warn, vha, 0x7036,
969 		    "DMA alloc failed for fw buffer.\n");
970 		rval = -ENOMEM;
971 		goto done_free_fw_buf;
972 	}
973 
974 	flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
975 	fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2)));
976 
977 	memset(mn, 0, sizeof(struct access_chip_84xx));
978 	mn->entry_type = VERIFY_CHIP_IOCB_TYPE;
979 	mn->entry_count = 1;
980 
981 	options = VCO_FORCE_UPDATE | VCO_END_OF_DATA;
982 	if (flag == A84_ISSUE_UPDATE_DIAGFW_CMD)
983 		options |= VCO_DIAG_FW;
984 
985 	mn->options = cpu_to_le16(options);
986 	mn->fw_ver =  cpu_to_le32(fw_ver);
987 	mn->fw_size =  cpu_to_le32(data_len);
988 	mn->fw_seq_size =  cpu_to_le32(data_len);
989 	mn->dseg_address[0] = cpu_to_le32(LSD(fw_dma));
990 	mn->dseg_address[1] = cpu_to_le32(MSD(fw_dma));
991 	mn->dseg_length = cpu_to_le32(data_len);
992 	mn->data_seg_cnt = cpu_to_le16(1);
993 
994 	rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
995 
996 	if (rval) {
997 		ql_log(ql_log_warn, vha, 0x7037,
998 		    "Vendor request 84xx updatefw failed.\n");
999 
1000 		rval = bsg_job->reply->reply_payload_rcv_len = 0;
1001 		bsg_job->reply->result = (DID_ERROR << 16);
1002 
1003 	} else {
1004 		ql_dbg(ql_dbg_user, vha, 0x7038,
1005 		    "Vendor request 84xx updatefw completed.\n");
1006 
1007 		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1008 		bsg_job->reply->result = DID_OK;
1009 	}
1010 
1011 	bsg_job->job_done(bsg_job);
1012 	dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1013 
1014 done_free_fw_buf:
1015 	dma_free_coherent(&ha->pdev->dev, data_len, fw_buf, fw_dma);
1016 
1017 done_unmap_sg:
1018 	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1019 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1020 
1021 	return rval;
1022 }
1023 
1024 static int
1025 qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
1026 {
1027 	struct Scsi_Host *host = bsg_job->shost;
1028 	scsi_qla_host_t *vha = shost_priv(host);
1029 	struct qla_hw_data *ha = vha->hw;
1030 	struct access_chip_84xx *mn = NULL;
1031 	dma_addr_t mn_dma, mgmt_dma;
1032 	void *mgmt_b = NULL;
1033 	int rval = 0;
1034 	struct qla_bsg_a84_mgmt *ql84_mgmt;
1035 	uint32_t sg_cnt;
1036 	uint32_t data_len = 0;
1037 	uint32_t dma_direction = DMA_NONE;
1038 
1039 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1040 		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1041 		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1042 		ql_log(ql_log_warn, vha, 0x7039,
1043 		    "Abort active or needed.\n");
1044 		return -EBUSY;
1045 	}
1046 
1047 	if (!IS_QLA84XX(ha)) {
1048 		ql_log(ql_log_warn, vha, 0x703a,
1049 		    "Not 84xx, exiting.\n");
1050 		return -EINVAL;
1051 	}
1052 
1053 	ql84_mgmt = (struct qla_bsg_a84_mgmt *)((char *)bsg_job->request +
1054 		sizeof(struct fc_bsg_request));
1055 	if (!ql84_mgmt) {
1056 		ql_log(ql_log_warn, vha, 0x703b,
1057 		    "MGMT header not provided, exiting.\n");
1058 		return -EINVAL;
1059 	}
1060 
1061 	mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1062 	if (!mn) {
1063 		ql_log(ql_log_warn, vha, 0x703c,
1064 		    "DMA alloc failed for fw buffer.\n");
1065 		return -ENOMEM;
1066 	}
1067 
1068 	memset(mn, 0, sizeof(struct access_chip_84xx));
1069 	mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
1070 	mn->entry_count = 1;
1071 
1072 	switch (ql84_mgmt->mgmt.cmd) {
1073 	case QLA84_MGMT_READ_MEM:
1074 	case QLA84_MGMT_GET_INFO:
1075 		sg_cnt = dma_map_sg(&ha->pdev->dev,
1076 			bsg_job->reply_payload.sg_list,
1077 			bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1078 		if (!sg_cnt) {
1079 			ql_log(ql_log_warn, vha, 0x703d,
1080 			    "dma_map_sg returned %d for reply.\n", sg_cnt);
1081 			rval = -ENOMEM;
1082 			goto exit_mgmt;
1083 		}
1084 
1085 		dma_direction = DMA_FROM_DEVICE;
1086 
1087 		if (sg_cnt != bsg_job->reply_payload.sg_cnt) {
1088 			ql_log(ql_log_warn, vha, 0x703e,
1089 			    "DMA mapping resulted in different sg counts, "
1090 			    "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
1091 			    bsg_job->reply_payload.sg_cnt, sg_cnt);
1092 			rval = -EAGAIN;
1093 			goto done_unmap_sg;
1094 		}
1095 
1096 		data_len = bsg_job->reply_payload.payload_len;
1097 
1098 		mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1099 		    &mgmt_dma, GFP_KERNEL);
1100 		if (!mgmt_b) {
1101 			ql_log(ql_log_warn, vha, 0x703f,
1102 			    "DMA alloc failed for mgmt_b.\n");
1103 			rval = -ENOMEM;
1104 			goto done_unmap_sg;
1105 		}
1106 
1107 		if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) {
1108 			mn->options = cpu_to_le16(ACO_DUMP_MEMORY);
1109 			mn->parameter1 =
1110 				cpu_to_le32(
1111 				ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1112 
1113 		} else if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO) {
1114 			mn->options = cpu_to_le16(ACO_REQUEST_INFO);
1115 			mn->parameter1 =
1116 				cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.info.type);
1117 
1118 			mn->parameter2 =
1119 				cpu_to_le32(
1120 				ql84_mgmt->mgmt.mgmtp.u.info.context);
1121 		}
1122 		break;
1123 
1124 	case QLA84_MGMT_WRITE_MEM:
1125 		sg_cnt = dma_map_sg(&ha->pdev->dev,
1126 			bsg_job->request_payload.sg_list,
1127 			bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1128 
1129 		if (!sg_cnt) {
1130 			ql_log(ql_log_warn, vha, 0x7040,
1131 			    "dma_map_sg returned %d.\n", sg_cnt);
1132 			rval = -ENOMEM;
1133 			goto exit_mgmt;
1134 		}
1135 
1136 		dma_direction = DMA_TO_DEVICE;
1137 
1138 		if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1139 			ql_log(ql_log_warn, vha, 0x7041,
1140 			    "DMA mapping resulted in different sg counts, "
1141 			    "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1142 			    bsg_job->request_payload.sg_cnt, sg_cnt);
1143 			rval = -EAGAIN;
1144 			goto done_unmap_sg;
1145 		}
1146 
1147 		data_len = bsg_job->request_payload.payload_len;
1148 		mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1149 			&mgmt_dma, GFP_KERNEL);
1150 		if (!mgmt_b) {
1151 			ql_log(ql_log_warn, vha, 0x7042,
1152 			    "DMA alloc failed for mgmt_b.\n");
1153 			rval = -ENOMEM;
1154 			goto done_unmap_sg;
1155 		}
1156 
1157 		sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1158 			bsg_job->request_payload.sg_cnt, mgmt_b, data_len);
1159 
1160 		mn->options = cpu_to_le16(ACO_LOAD_MEMORY);
1161 		mn->parameter1 =
1162 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1163 		break;
1164 
1165 	case QLA84_MGMT_CHNG_CONFIG:
1166 		mn->options = cpu_to_le16(ACO_CHANGE_CONFIG_PARAM);
1167 		mn->parameter1 =
1168 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.id);
1169 
1170 		mn->parameter2 =
1171 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param0);
1172 
1173 		mn->parameter3 =
1174 			cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param1);
1175 		break;
1176 
1177 	default:
1178 		rval = -EIO;
1179 		goto exit_mgmt;
1180 	}
1181 
1182 	if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) {
1183 		mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len);
1184 		mn->dseg_count = cpu_to_le16(1);
1185 		mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma));
1186 		mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma));
1187 		mn->dseg_length = cpu_to_le32(ql84_mgmt->mgmt.len);
1188 	}
1189 
1190 	rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0);
1191 
1192 	if (rval) {
1193 		ql_log(ql_log_warn, vha, 0x7043,
1194 		    "Vendor request 84xx mgmt failed.\n");
1195 
1196 		rval = bsg_job->reply->reply_payload_rcv_len = 0;
1197 		bsg_job->reply->result = (DID_ERROR << 16);
1198 
1199 	} else {
1200 		ql_dbg(ql_dbg_user, vha, 0x7044,
1201 		    "Vendor request 84xx mgmt completed.\n");
1202 
1203 		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1204 		bsg_job->reply->result = DID_OK;
1205 
1206 		if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) ||
1207 			(ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) {
1208 			bsg_job->reply->reply_payload_rcv_len =
1209 				bsg_job->reply_payload.payload_len;
1210 
1211 			sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1212 				bsg_job->reply_payload.sg_cnt, mgmt_b,
1213 				data_len);
1214 		}
1215 	}
1216 
1217 	bsg_job->job_done(bsg_job);
1218 
1219 done_unmap_sg:
1220 	if (mgmt_b)
1221 		dma_free_coherent(&ha->pdev->dev, data_len, mgmt_b, mgmt_dma);
1222 
1223 	if (dma_direction == DMA_TO_DEVICE)
1224 		dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1225 			bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1226 	else if (dma_direction == DMA_FROM_DEVICE)
1227 		dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
1228 			bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1229 
1230 exit_mgmt:
1231 	dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1232 
1233 	return rval;
1234 }
1235 
1236 static int
1237 qla24xx_iidma(struct fc_bsg_job *bsg_job)
1238 {
1239 	struct Scsi_Host *host = bsg_job->shost;
1240 	scsi_qla_host_t *vha = shost_priv(host);
1241 	int rval = 0;
1242 	struct qla_port_param *port_param = NULL;
1243 	fc_port_t *fcport = NULL;
1244 	uint16_t mb[MAILBOX_REGISTER_COUNT];
1245 	uint8_t *rsp_ptr = NULL;
1246 
1247 	bsg_job->reply->reply_payload_rcv_len = 0;
1248 
1249 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1250 		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1251 		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1252 		ql_log(ql_log_warn, vha, 0x7045, "abort active or needed.\n");
1253 		return -EBUSY;
1254 	}
1255 
1256 	if (!IS_IIDMA_CAPABLE(vha->hw)) {
1257 		ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
1258 		return -EINVAL;
1259 	}
1260 
1261 	port_param = (struct qla_port_param *)((char *)bsg_job->request +
1262 		sizeof(struct fc_bsg_request));
1263 	if (!port_param) {
1264 		ql_log(ql_log_warn, vha, 0x7047,
1265 		    "port_param header not provided.\n");
1266 		return -EINVAL;
1267 	}
1268 
1269 	if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
1270 		ql_log(ql_log_warn, vha, 0x7048,
1271 		    "Invalid destination type.\n");
1272 		return -EINVAL;
1273 	}
1274 
1275 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
1276 		if (fcport->port_type != FCT_TARGET)
1277 			continue;
1278 
1279 		if (memcmp(port_param->fc_scsi_addr.dest_addr.wwpn,
1280 			fcport->port_name, sizeof(fcport->port_name)))
1281 			continue;
1282 		break;
1283 	}
1284 
1285 	if (!fcport) {
1286 		ql_log(ql_log_warn, vha, 0x7049,
1287 		    "Failed to find port.\n");
1288 		return -EINVAL;
1289 	}
1290 
1291 	if (atomic_read(&fcport->state) != FCS_ONLINE) {
1292 		ql_log(ql_log_warn, vha, 0x704a,
1293 		    "Port is not online.\n");
1294 		return -EINVAL;
1295 	}
1296 
1297 	if (fcport->flags & FCF_LOGIN_NEEDED) {
1298 		ql_log(ql_log_warn, vha, 0x704b,
1299 		    "Remote port not logged in flags = 0x%x.\n", fcport->flags);
1300 		return -EINVAL;
1301 	}
1302 
1303 	if (port_param->mode)
1304 		rval = qla2x00_set_idma_speed(vha, fcport->loop_id,
1305 			port_param->speed, mb);
1306 	else
1307 		rval = qla2x00_get_idma_speed(vha, fcport->loop_id,
1308 			&port_param->speed, mb);
1309 
1310 	if (rval) {
1311 		ql_log(ql_log_warn, vha, 0x704c,
1312 		    "iIDMA cmd failed for %02x%02x%02x%02x%02x%02x%02x%02x -- "
1313 		    "%04x %x %04x %04x.\n", fcport->port_name[0],
1314 		    fcport->port_name[1], fcport->port_name[2],
1315 		    fcport->port_name[3], fcport->port_name[4],
1316 		    fcport->port_name[5], fcport->port_name[6],
1317 		    fcport->port_name[7], rval, fcport->fp_speed, mb[0], mb[1]);
1318 		rval = 0;
1319 		bsg_job->reply->result = (DID_ERROR << 16);
1320 
1321 	} else {
1322 		if (!port_param->mode) {
1323 			bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
1324 				sizeof(struct qla_port_param);
1325 
1326 			rsp_ptr = ((uint8_t *)bsg_job->reply) +
1327 				sizeof(struct fc_bsg_reply);
1328 
1329 			memcpy(rsp_ptr, port_param,
1330 				sizeof(struct qla_port_param));
1331 		}
1332 
1333 		bsg_job->reply->result = DID_OK;
1334 	}
1335 
1336 	bsg_job->job_done(bsg_job);
1337 	return rval;
1338 }
1339 
1340 static int
1341 qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
1342 	uint8_t is_update)
1343 {
1344 	uint32_t start = 0;
1345 	int valid = 0;
1346 	struct qla_hw_data *ha = vha->hw;
1347 
1348 	bsg_job->reply->reply_payload_rcv_len = 0;
1349 
1350 	if (unlikely(pci_channel_offline(ha->pdev)))
1351 		return -EINVAL;
1352 
1353 	start = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
1354 	if (start > ha->optrom_size) {
1355 		ql_log(ql_log_warn, vha, 0x7055,
1356 		    "start %d > optrom_size %d.\n", start, ha->optrom_size);
1357 		return -EINVAL;
1358 	}
1359 
1360 	if (ha->optrom_state != QLA_SWAITING) {
1361 		ql_log(ql_log_info, vha, 0x7056,
1362 		    "optrom_state %d.\n", ha->optrom_state);
1363 		return -EBUSY;
1364 	}
1365 
1366 	ha->optrom_region_start = start;
1367 	ql_dbg(ql_dbg_user, vha, 0x7057, "is_update=%d.\n", is_update);
1368 	if (is_update) {
1369 		if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
1370 			valid = 1;
1371 		else if (start == (ha->flt_region_boot * 4) ||
1372 		    start == (ha->flt_region_fw * 4))
1373 			valid = 1;
1374 		else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
1375 		    IS_QLA8XXX_TYPE(ha))
1376 			valid = 1;
1377 		if (!valid) {
1378 			ql_log(ql_log_warn, vha, 0x7058,
1379 			    "Invalid start region 0x%x/0x%x.\n", start,
1380 			    bsg_job->request_payload.payload_len);
1381 			return -EINVAL;
1382 		}
1383 
1384 		ha->optrom_region_size = start +
1385 		    bsg_job->request_payload.payload_len > ha->optrom_size ?
1386 		    ha->optrom_size - start :
1387 		    bsg_job->request_payload.payload_len;
1388 		ha->optrom_state = QLA_SWRITING;
1389 	} else {
1390 		ha->optrom_region_size = start +
1391 		    bsg_job->reply_payload.payload_len > ha->optrom_size ?
1392 		    ha->optrom_size - start :
1393 		    bsg_job->reply_payload.payload_len;
1394 		ha->optrom_state = QLA_SREADING;
1395 	}
1396 
1397 	ha->optrom_buffer = vmalloc(ha->optrom_region_size);
1398 	if (!ha->optrom_buffer) {
1399 		ql_log(ql_log_warn, vha, 0x7059,
1400 		    "Read: Unable to allocate memory for optrom retrieval "
1401 		    "(%x)\n", ha->optrom_region_size);
1402 
1403 		ha->optrom_state = QLA_SWAITING;
1404 		return -ENOMEM;
1405 	}
1406 
1407 	memset(ha->optrom_buffer, 0, ha->optrom_region_size);
1408 	return 0;
1409 }
1410 
1411 static int
1412 qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
1413 {
1414 	struct Scsi_Host *host = bsg_job->shost;
1415 	scsi_qla_host_t *vha = shost_priv(host);
1416 	struct qla_hw_data *ha = vha->hw;
1417 	int rval = 0;
1418 
1419 	rval = qla2x00_optrom_setup(bsg_job, vha, 0);
1420 	if (rval)
1421 		return rval;
1422 
1423 	ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
1424 	    ha->optrom_region_start, ha->optrom_region_size);
1425 
1426 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1427 	    bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
1428 	    ha->optrom_region_size);
1429 
1430 	bsg_job->reply->reply_payload_rcv_len = ha->optrom_region_size;
1431 	bsg_job->reply->result = DID_OK;
1432 	vfree(ha->optrom_buffer);
1433 	ha->optrom_buffer = NULL;
1434 	ha->optrom_state = QLA_SWAITING;
1435 	bsg_job->job_done(bsg_job);
1436 	return rval;
1437 }
1438 
1439 static int
1440 qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
1441 {
1442 	struct Scsi_Host *host = bsg_job->shost;
1443 	scsi_qla_host_t *vha = shost_priv(host);
1444 	struct qla_hw_data *ha = vha->hw;
1445 	int rval = 0;
1446 
1447 	rval = qla2x00_optrom_setup(bsg_job, vha, 1);
1448 	if (rval)
1449 		return rval;
1450 
1451 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1452 	    bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
1453 	    ha->optrom_region_size);
1454 
1455 	ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
1456 	    ha->optrom_region_start, ha->optrom_region_size);
1457 
1458 	bsg_job->reply->result = DID_OK;
1459 	vfree(ha->optrom_buffer);
1460 	ha->optrom_buffer = NULL;
1461 	ha->optrom_state = QLA_SWAITING;
1462 	bsg_job->job_done(bsg_job);
1463 	return rval;
1464 }
1465 
1466 static int
1467 qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
1468 {
1469 	struct Scsi_Host *host = bsg_job->shost;
1470 	scsi_qla_host_t *vha = shost_priv(host);
1471 	struct qla_hw_data *ha = vha->hw;
1472 	int rval = 0;
1473 	uint8_t bsg[DMA_POOL_SIZE];
1474 	struct qla_image_version_list *list = (void *)bsg;
1475 	struct qla_image_version *image;
1476 	uint32_t count;
1477 	dma_addr_t sfp_dma;
1478 	void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1479 	if (!sfp) {
1480 		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1481 		    EXT_STATUS_NO_MEMORY;
1482 		goto done;
1483 	}
1484 
1485 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1486 	    bsg_job->request_payload.sg_cnt, list, sizeof(bsg));
1487 
1488 	image = list->version;
1489 	count = list->count;
1490 	while (count--) {
1491 		memcpy(sfp, &image->field_info, sizeof(image->field_info));
1492 		rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1493 		    image->field_address.device, image->field_address.offset,
1494 		    sizeof(image->field_info), image->field_address.option);
1495 		if (rval) {
1496 			bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1497 			    EXT_STATUS_MAILBOX;
1498 			goto dealloc;
1499 		}
1500 		image++;
1501 	}
1502 
1503 	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1504 
1505 dealloc:
1506 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1507 
1508 done:
1509 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1510 	bsg_job->reply->result = DID_OK << 16;
1511 	bsg_job->job_done(bsg_job);
1512 
1513 	return 0;
1514 }
1515 
1516 static int
1517 qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
1518 {
1519 	struct Scsi_Host *host = bsg_job->shost;
1520 	scsi_qla_host_t *vha = shost_priv(host);
1521 	struct qla_hw_data *ha = vha->hw;
1522 	int rval = 0;
1523 	uint8_t bsg[DMA_POOL_SIZE];
1524 	struct qla_status_reg *sr = (void *)bsg;
1525 	dma_addr_t sfp_dma;
1526 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1527 	if (!sfp) {
1528 		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1529 		    EXT_STATUS_NO_MEMORY;
1530 		goto done;
1531 	}
1532 
1533 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1534 	    bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1535 
1536 	rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1537 	    sr->field_address.device, sr->field_address.offset,
1538 	    sizeof(sr->status_reg), sr->field_address.option);
1539 	sr->status_reg = *sfp;
1540 
1541 	if (rval) {
1542 		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1543 		    EXT_STATUS_MAILBOX;
1544 		goto dealloc;
1545 	}
1546 
1547 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1548 	    bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));
1549 
1550 	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1551 
1552 dealloc:
1553 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1554 
1555 done:
1556 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1557 	bsg_job->reply->reply_payload_rcv_len = sizeof(*sr);
1558 	bsg_job->reply->result = DID_OK << 16;
1559 	bsg_job->job_done(bsg_job);
1560 
1561 	return 0;
1562 }
1563 
1564 static int
1565 qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
1566 {
1567 	struct Scsi_Host *host = bsg_job->shost;
1568 	scsi_qla_host_t *vha = shost_priv(host);
1569 	struct qla_hw_data *ha = vha->hw;
1570 	int rval = 0;
1571 	uint8_t bsg[DMA_POOL_SIZE];
1572 	struct qla_status_reg *sr = (void *)bsg;
1573 	dma_addr_t sfp_dma;
1574 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1575 	if (!sfp) {
1576 		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1577 		    EXT_STATUS_NO_MEMORY;
1578 		goto done;
1579 	}
1580 
1581 	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1582 	    bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1583 
1584 	*sfp = sr->status_reg;
1585 	rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1586 	    sr->field_address.device, sr->field_address.offset,
1587 	    sizeof(sr->status_reg), sr->field_address.option);
1588 
1589 	if (rval) {
1590 		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1591 		    EXT_STATUS_MAILBOX;
1592 		goto dealloc;
1593 	}
1594 
1595 	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1596 
1597 dealloc:
1598 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1599 
1600 done:
1601 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1602 	bsg_job->reply->result = DID_OK << 16;
1603 	bsg_job->job_done(bsg_job);
1604 
1605 	return 0;
1606 }
1607 
1608 static int
1609 qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
1610 {
1611 	switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
1612 	case QL_VND_LOOPBACK:
1613 		return qla2x00_process_loopback(bsg_job);
1614 
1615 	case QL_VND_A84_RESET:
1616 		return qla84xx_reset(bsg_job);
1617 
1618 	case QL_VND_A84_UPDATE_FW:
1619 		return qla84xx_updatefw(bsg_job);
1620 
1621 	case QL_VND_A84_MGMT_CMD:
1622 		return qla84xx_mgmt_cmd(bsg_job);
1623 
1624 	case QL_VND_IIDMA:
1625 		return qla24xx_iidma(bsg_job);
1626 
1627 	case QL_VND_FCP_PRIO_CFG_CMD:
1628 		return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);
1629 
1630 	case QL_VND_READ_FLASH:
1631 		return qla2x00_read_optrom(bsg_job);
1632 
1633 	case QL_VND_UPDATE_FLASH:
1634 		return qla2x00_update_optrom(bsg_job);
1635 
1636 	case QL_VND_SET_FRU_VERSION:
1637 		return qla2x00_update_fru_versions(bsg_job);
1638 
1639 	case QL_VND_READ_FRU_STATUS:
1640 		return qla2x00_read_fru_status(bsg_job);
1641 
1642 	case QL_VND_WRITE_FRU_STATUS:
1643 		return qla2x00_write_fru_status(bsg_job);
1644 
1645 	default:
1646 		bsg_job->reply->result = (DID_ERROR << 16);
1647 		bsg_job->job_done(bsg_job);
1648 		return -ENOSYS;
1649 	}
1650 }
1651 
1652 int
1653 qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
1654 {
1655 	int ret = -EINVAL;
1656 	struct fc_rport *rport;
1657 	fc_port_t *fcport = NULL;
1658 	struct Scsi_Host *host;
1659 	scsi_qla_host_t *vha;
1660 
1661 	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
1662 		rport = bsg_job->rport;
1663 		fcport = *(fc_port_t **) rport->dd_data;
1664 		host = rport_to_shost(rport);
1665 		vha = shost_priv(host);
1666 	} else {
1667 		host = bsg_job->shost;
1668 		vha = shost_priv(host);
1669 	}
1670 
1671 	ql_dbg(ql_dbg_user, vha, 0x7000,
1672 	    "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode);
1673 
1674 	switch (bsg_job->request->msgcode) {
1675 	case FC_BSG_RPT_ELS:
1676 	case FC_BSG_HST_ELS_NOLOGIN:
1677 		ret = qla2x00_process_els(bsg_job);
1678 		break;
1679 	case FC_BSG_HST_CT:
1680 		ret = qla2x00_process_ct(bsg_job);
1681 		break;
1682 	case FC_BSG_HST_VENDOR:
1683 		ret = qla2x00_process_vendor_specific(bsg_job);
1684 		break;
1685 	case FC_BSG_HST_ADD_RPORT:
1686 	case FC_BSG_HST_DEL_RPORT:
1687 	case FC_BSG_RPT_CT:
1688 	default:
1689 		ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
1690 		break;
1691 	}
1692 	return ret;
1693 }
1694 
1695 int
1696 qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
1697 {
1698 	scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
1699 	struct qla_hw_data *ha = vha->hw;
1700 	srb_t *sp;
1701 	int cnt, que;
1702 	unsigned long flags;
1703 	struct req_que *req;
1704 	struct srb_ctx *sp_bsg;
1705 
1706 	/* find the bsg job from the active list of commands */
1707 	spin_lock_irqsave(&ha->hardware_lock, flags);
1708 	for (que = 0; que < ha->max_req_queues; que++) {
1709 		req = ha->req_q_map[que];
1710 		if (!req)
1711 			continue;
1712 
1713 		for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
1714 			sp = req->outstanding_cmds[cnt];
1715 			if (sp) {
1716 				sp_bsg = sp->ctx;
1717 
1718 				if (((sp_bsg->type == SRB_CT_CMD) ||
1719 					(sp_bsg->type == SRB_ELS_CMD_HST))
1720 					&& (sp_bsg->u.bsg_job == bsg_job)) {
1721 					spin_unlock_irqrestore(&ha->hardware_lock, flags);
1722 					if (ha->isp_ops->abort_command(sp)) {
1723 						ql_log(ql_log_warn, vha, 0x7089,
1724 						    "mbx abort_command "
1725 						    "failed.\n");
1726 						bsg_job->req->errors =
1727 						bsg_job->reply->result = -EIO;
1728 					} else {
1729 						ql_dbg(ql_dbg_user, vha, 0x708a,
1730 						    "mbx abort_command "
1731 						    "success.\n");
1732 						bsg_job->req->errors =
1733 						bsg_job->reply->result = 0;
1734 					}
1735 					spin_lock_irqsave(&ha->hardware_lock, flags);
1736 					goto done;
1737 				}
1738 			}
1739 		}
1740 	}
1741 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
1742 	ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
1743 	bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
1744 	return 0;
1745 
1746 done:
1747 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
1748 	if (bsg_job->request->msgcode == FC_BSG_HST_CT)
1749 		kfree(sp->fcport);
1750 	kfree(sp->ctx);
1751 	mempool_free(sp, ha->srb_mempool);
1752 	return 0;
1753 }
1754