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