1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /* Copyright 2010 QLogic Corporation */
23 
24 /*
25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #pragma ident	"Copyright 2010 QLogic Corporation; ql_mbx.c"
30 
31 /*
32  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33  *
34  * ***********************************************************************
35  * *									**
36  * *				NOTICE					**
37  * *		COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION		**
38  * *			ALL RIGHTS RESERVED				**
39  * *									**
40  * ***********************************************************************
41  *
42  */
43 
44 #include <ql_apps.h>
45 #include <ql_api.h>
46 #include <ql_debug.h>
47 #include <ql_iocb.h>
48 #include <ql_isr.h>
49 #include <ql_mbx.h>
50 #include <ql_xioctl.h>
51 
52 /*
53  * Local data
54  */
55 
56 /*
57  * Local prototypes
58  */
59 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *);
60 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint16_t,
61     uint32_t, uint16_t);
62 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *);
63 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *,
64     caddr_t, uint32_t);
65 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *,
66     uint32_t);
67 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t);
68 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t);
69 
70 /*
71  * ql_mailbox_command
72  *	Issue mailbox command and waits for completion.
73  *
74  * Input:
75  *	ha = adapter state pointer.
76  *	mcp = mailbox command parameter structure pointer.
77  *
78  * Returns:
79  *	ql local function return status code.
80  *
81  * Context:
82  *	Kernel context.
83  */
84 static int
85 ql_mailbox_command(ql_adapter_state_t *vha, mbx_cmd_t *mcp)
86 {
87 	uint16_t		cnt;
88 	uint32_t		data;
89 	clock_t			timer, cv_stat;
90 	int			rval;
91 	uint32_t		set_flags = 0;
92 	uint32_t		reset_flags = 0;
93 	ql_adapter_state_t	*ha = vha->pha;
94 	int			mbx_cmd = mcp->mb[0];
95 
96 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
97 
98 	/* Acquire mailbox register lock. */
99 	MBX_REGISTER_LOCK(ha);
100 
101 	/* Check for mailbox available, if not wait for signal. */
102 	while (ha->mailbox_flags & MBX_BUSY_FLG ||
103 	    (CFG_IST(ha, CFG_CTRL_8021) &&
104 	    RD32_IO_REG(ha, nx_host_int) & NX_MBX_CMD)) {
105 		ha->mailbox_flags = (uint8_t)
106 		    (ha->mailbox_flags | MBX_WANT_FLG);
107 
108 		if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
109 			EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
110 			MBX_REGISTER_UNLOCK(ha);
111 			return (QL_LOCK_TIMEOUT);
112 		}
113 
114 		/* Set timeout after command that is running. */
115 		timer = (mcp->timeout + 20) * drv_usectohz(1000000);
116 		cv_stat = cv_reltimedwait_sig(&ha->cv_mbx_wait,
117 		    &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK);
118 		if (cv_stat == -1 || cv_stat == 0) {
119 			/*
120 			 * The timeout time 'timer' was
121 			 * reached without the condition
122 			 * being signaled.
123 			 */
124 			ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
125 			    ~MBX_WANT_FLG);
126 			cv_broadcast(&ha->cv_mbx_wait);
127 
128 			/* Release mailbox register lock. */
129 			MBX_REGISTER_UNLOCK(ha);
130 
131 			if (cv_stat == 0) {
132 				EL(vha, "waiting for availability aborted, "
133 				    "cmd=%xh\n", mcp->mb[0]);
134 				return (QL_ABORTED);
135 			}
136 			EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
137 			return (QL_LOCK_TIMEOUT);
138 		}
139 	}
140 
141 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
142 
143 	/* Structure pointer for return mailbox registers. */
144 	ha->mcp = mcp;
145 
146 	/* Load mailbox registers. */
147 	data = mcp->out_mb;
148 	for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
149 		if (data & MBX_0) {
150 			WRT16_IO_REG(ha, mailbox_in[cnt], mcp->mb[cnt]);
151 		}
152 		data >>= 1;
153 	}
154 
155 	/* Issue set host interrupt command. */
156 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT);
157 	if (CFG_IST(ha, CFG_CTRL_8021)) {
158 		WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
159 	} else if (CFG_IST(ha, CFG_CTRL_242581)) {
160 		WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
161 	} else {
162 		WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
163 	}
164 
165 	/* Wait for command to complete. */
166 	if (ha->flags & INTERRUPTS_ENABLED &&
167 	    !(ha->task_daemon_flags & (TASK_THREAD_CALLED |
168 	    TASK_DAEMON_POWERING_DOWN)) &&
169 	    !ddi_in_panic()) {
170 		timer = mcp->timeout * drv_usectohz(1000000);
171 		while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) &&
172 		    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
173 
174 			if (cv_reltimedwait(&ha->cv_mbx_intr,
175 			    &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK) == -1) {
176 				/*
177 				 * The timeout time 'timer' was
178 				 * reached without the condition
179 				 * being signaled.
180 				 */
181 				break;
182 			}
183 		}
184 	} else {
185 		/* Release mailbox register lock. */
186 		MBX_REGISTER_UNLOCK(ha);
187 
188 		/* Acquire interrupt lock. */
189 		for (timer = mcp->timeout * 100; timer; timer--) {
190 			/* Check for pending interrupts. */
191 			while (INTERRUPT_PENDING(ha)) {
192 				(void) ql_isr((caddr_t)ha);
193 				INTR_LOCK(ha);
194 				ha->intr_claimed = B_TRUE;
195 				INTR_UNLOCK(ha);
196 				if (ha->mailbox_flags &
197 				    (MBX_INTERRUPT | MBX_ABORT) ||
198 				    ha->task_daemon_flags & ISP_ABORT_NEEDED) {
199 					break;
200 				}
201 			}
202 			if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) ||
203 			    ha->task_daemon_flags & ISP_ABORT_NEEDED) {
204 				break;
205 			} else if (!ddi_in_panic() && timer % 101 == 0) {
206 				delay(drv_usectohz(10000));
207 			} else {
208 				drv_usecwait(10000);
209 			}
210 		}
211 
212 		/* Acquire mailbox register lock. */
213 		MBX_REGISTER_LOCK(ha);
214 	}
215 
216 	/* Mailbox command timeout? */
217 	if (ha->task_daemon_flags & ISP_ABORT_NEEDED ||
218 	    ha->mailbox_flags & MBX_ABORT) {
219 		rval = QL_ABORTED;
220 	} else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) {
221 		if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) {
222 			(void) ql_binary_fw_dump(ha, FALSE);
223 		}
224 		EL(vha, "command timeout, isp_abort_needed\n");
225 		set_flags |= ISP_ABORT_NEEDED;
226 		rval = QL_FUNCTION_TIMEOUT;
227 	} else {
228 		ha->mailbox_flags = (uint8_t)
229 		    (ha->mailbox_flags & ~MBX_INTERRUPT);
230 		/*
231 		 * This is the expected completion path so
232 		 * return the actual mbx cmd completion status.
233 		 */
234 		rval = mcp->mb[0];
235 	}
236 
237 	/*
238 	 * Clear outbound to risc mailbox registers per spec. The exception
239 	 * is on 2200 mailbox 4 and 5 affect the req and resp que indexes
240 	 * so avoid writing them.
241 	 */
242 	if (ha->cfg_flags & CFG_CTRL_2200) {
243 		data = ((mcp->out_mb & ~(MBX_4 | MBX_5)) >> 1);
244 	} else {
245 		data = (mcp->out_mb >> 1);
246 	}
247 	for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
248 		if (data & MBX_0) {
249 			WRT16_IO_REG(ha, mailbox_in[cnt], (uint16_t)0);
250 		}
251 		data >>= 1;
252 	}
253 
254 	/* Reset busy status. */
255 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
256 	    ~(MBX_BUSY_FLG | MBX_ABORT));
257 	ha->mcp = NULL;
258 
259 	/* If thread is waiting for mailbox go signal it to start. */
260 	if (ha->mailbox_flags & MBX_WANT_FLG) {
261 		ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
262 		    ~MBX_WANT_FLG);
263 		cv_broadcast(&ha->cv_mbx_wait);
264 	}
265 
266 	/* Release mailbox register lock. */
267 	MBX_REGISTER_UNLOCK(ha);
268 
269 	if (set_flags != 0 || reset_flags != 0) {
270 		ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags);
271 	}
272 
273 	if (rval != QL_SUCCESS) {
274 		EL(vha, "%s failed, rval=%xh, mcp->mb[0]=%xh\n",
275 		    mbx_cmd_text(mbx_cmd), rval, mcp->mb[0]);
276 	} else {
277 		/*EMPTY*/
278 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
279 	}
280 
281 	return (rval);
282 }
283 
284 /*
285  * ql_setup_mbox_dma_resources
286  *	Prepare the data for a mailbox dma transfer.
287  *
288  * Input:
289  *	ha = adapter state pointer.
290  *	mem_desc = descriptor to contain the dma resource information.
291  *	data = pointer to the data.
292  *	size = size of the data in bytes.
293  *
294  * Returns:
295  *	ql local function return status code.
296  *
297  * Context:
298  *	Kernel context.
299  */
300 static int
301 ql_setup_mbox_dma_transfer(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
302     caddr_t data, uint32_t size)
303 {
304 	int rval = QL_SUCCESS;
305 
306 	if ((rval = ql_setup_mbox_dma_resources(ha, mem_desc, size)) ==
307 	    QL_SUCCESS) {
308 		ql_setup_mbox_dma_data(mem_desc, data);
309 	} else {
310 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
311 	}
312 
313 	return (rval);
314 }
315 
316 /*
317  * ql_setup_mbox_dma_resources
318  *	Prepare a dma buffer.
319  *
320  * Input:
321  *	ha = adapter state pointer.
322  *	mem_desc = descriptor to contain the dma resource information.
323  *	data = pointer to the data.
324  *	size = size of the data in bytes.
325  *
326  * Returns:
327  *	ql local function return status code.
328  *
329  * Context:
330  *	Kernel context.
331  */
332 static int
333 ql_setup_mbox_dma_resources(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
334     uint32_t size)
335 {
336 	int	rval = QL_SUCCESS;
337 
338 	if ((rval = ql_get_dma_mem(ha, mem_desc, size, LITTLE_ENDIAN_DMA,
339 	    QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
340 		EL(ha, "failed, ql_get_dma_mem FC_NOMEM\n");
341 		rval = QL_MEMORY_ALLOC_FAILED;
342 	}
343 
344 	return (rval);
345 }
346 
347 /*
348  * ql_setup_mbox_dma_data
349  *	Move data to the dma buffer.
350  *
351  * Input:
352  *	mem_desc = descriptor to contain the dma resource information.
353  *	data = pointer to the data.
354  *
355  * Returns:
356  *
357  * Context:
358  *	Kernel context.
359  */
360 static void
361 ql_setup_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
362 {
363 	/* Copy out going data to DMA buffer. */
364 	ddi_rep_put8(mem_desc->acc_handle, (uint8_t *)data,
365 	    (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
366 
367 	/* Sync DMA buffer. */
368 	(void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
369 	    DDI_DMA_SYNC_FORDEV);
370 }
371 
372 /*
373  * ql_get_mbox_dma_data
374  *	Recover data from the dma buffer.
375  *
376  * Input:
377  *	mem_desc = descriptor to contain the dma resource information.
378  *	data = pointer to the data.
379  *
380  * Returns:
381  *
382  * Context:
383  *	Kernel context.
384  */
385 static void
386 ql_get_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
387 {
388 	/* Sync in coming DMA buffer. */
389 	(void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
390 	    DDI_DMA_SYNC_FORKERNEL);
391 	/* Copy in coming DMA data. */
392 	ddi_rep_get8(mem_desc->acc_handle, (uint8_t *)data,
393 	    (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
394 }
395 
396 /*
397  * ql_initialize_ip
398  *	Initialize IP receive buffer queue.
399  *
400  * Input:
401  *	ha = adapter state pointer.
402  *	ha->ip_init_ctrl_blk = setup for transmit.
403  *
404  * Returns:
405  *	ql local function return status code.
406  *
407  * Context:
408  *	Kernel context.
409  */
410 int
411 ql_initialize_ip(ql_adapter_state_t *ha)
412 {
413 	ql_link_t	*link;
414 	ql_tgt_t	*tq;
415 	uint16_t	index;
416 	int		rval;
417 	dma_mem_t	mem_desc;
418 	mbx_cmd_t	mc = {0};
419 	mbx_cmd_t	*mcp = &mc;
420 
421 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
422 
423 	if (CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_258081)) ||
424 	    ha->vp_index != 0) {
425 		ha->flags &= ~IP_INITIALIZED;
426 		EL(ha, "HBA does not support IP\n");
427 		return (QL_FUNCTION_FAILED);
428 	}
429 
430 	ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp;
431 	ha->rcvbuf_ring_index = 0;
432 
433 	/* Reset all sequence counts. */
434 	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
435 		for (link = ha->dev[index].first; link != NULL;
436 		    link = link->next) {
437 			tq = link->base_address;
438 			tq->ub_total_seg_cnt = 0;
439 		}
440 	}
441 
442 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
443 	    (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t));
444 	if (rval != QL_SUCCESS) {
445 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
446 		return (rval);
447 	}
448 
449 	mcp->mb[0] = MBC_INITIALIZE_IP;
450 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
451 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
452 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
453 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
454 	mcp->mb[8] = 0;
455 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
456 	mcp->in_mb = MBX_8|MBX_0;
457 	mcp->timeout = MAILBOX_TOV;
458 	rval = ql_mailbox_command(ha, mcp);
459 
460 	ql_free_dma_resource(ha, &mem_desc);
461 
462 	if (rval == QL_SUCCESS) {
463 		ADAPTER_STATE_LOCK(ha);
464 		ha->flags |= IP_INITIALIZED;
465 		ADAPTER_STATE_UNLOCK(ha);
466 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
467 	} else {
468 		ha->flags &= ~IP_INITIALIZED;
469 		EL(ha, "failed, rval = %xh\n", rval);
470 	}
471 	return (rval);
472 }
473 
474 /*
475  * ql_shutdown_ip
476  *	Disconnects firmware IP from system buffers.
477  *
478  * Input:
479  *	ha = adapter state pointer.
480  *
481  * Returns:
482  *	ql local function return status code.
483  *
484  * Context:
485  *	Kernel context.
486  */
487 int
488 ql_shutdown_ip(ql_adapter_state_t *ha)
489 {
490 	int		rval;
491 	mbx_cmd_t	mc = {0};
492 	mbx_cmd_t	*mcp = &mc;
493 	fc_unsol_buf_t	*ubp;
494 	ql_srb_t	*sp;
495 	uint16_t	index;
496 
497 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
498 
499 	mcp->mb[0] = MBC_UNLOAD_IP;
500 	mcp->out_mb = MBX_0;
501 	mcp->in_mb = MBX_0;
502 	mcp->timeout = MAILBOX_TOV;
503 	rval = ql_mailbox_command(ha, mcp);
504 
505 	ADAPTER_STATE_LOCK(ha);
506 	QL_UB_LOCK(ha);
507 	/* Return all unsolicited buffers that ISP-IP has. */
508 	for (index = 0; index < QL_UB_LIMIT; index++) {
509 		ubp = ha->ub_array[index];
510 		if (ubp != NULL) {
511 			sp = ubp->ub_fca_private;
512 			sp->flags &= ~SRB_UB_IN_ISP;
513 		}
514 	}
515 
516 	ha->ub_outcnt = 0;
517 	QL_UB_UNLOCK(ha);
518 	ha->flags &= ~IP_INITIALIZED;
519 	ADAPTER_STATE_UNLOCK(ha);
520 
521 	if (rval == QL_SUCCESS) {
522 		/* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */
523 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
524 	} else {
525 		EL(ha, "failed, rval = %xh\n", rval);
526 	}
527 	return (rval);
528 }
529 
530 /*
531  * ql_online_selftest
532  *	Issue online self test mailbox command.
533  *
534  * Input:
535  *	ha = adapter state pointer.
536  *
537  * Returns:
538  *	ql local function return status code.
539  *
540  * Context:
541  *	Kernel context.
542  */
543 int
544 ql_online_selftest(ql_adapter_state_t *ha)
545 {
546 	int		rval;
547 	mbx_cmd_t	mc = {0};
548 	mbx_cmd_t	*mcp = &mc;
549 
550 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
551 
552 	mcp->mb[0] = MBC_ONLINE_SELF_TEST;
553 	mcp->out_mb = MBX_0;
554 	mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3;
555 	mcp->timeout = MAILBOX_TOV;
556 	rval = ql_mailbox_command(ha, mcp);
557 
558 	if (rval != QL_SUCCESS) {
559 		EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
560 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
561 	} else {
562 		/*EMPTY*/
563 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
564 	}
565 	return (rval);
566 }
567 
568 /*
569  * ql_loop_back
570  *	Issue diagnostic loop back frame mailbox command.
571  *
572  * Input:
573  *	ha:	adapter state pointer.
574  *	findex:	FCF index.
575  *	lb:	loop back parameter structure pointer.
576  *
577  * Returns:
578  *	ql local function return status code.
579  *
580  * Context:
581  *	Kernel context.
582  */
583 #ifndef apps_64bit
584 int
585 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb,
586     uint32_t h_xmit, uint32_t h_rcv)
587 {
588 	int		rval;
589 	mbx_cmd_t	mc = {0};
590 	mbx_cmd_t	*mcp = &mc;
591 	ql_mbx_data_t	mr = {0};
592 	ql_mbx_data_t	*mrp = &mr;
593 
594 	uint16_t	int_loopback_bit_mask = BIT_2;
595 	int		wait;
596 
597 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
598 
599 	if (CFG_IST(ha, CFG_CTRL_81XX) && (lb->options &
600 	    MBC_LOOPBACK_POINT_MASK) == MBC_LOOPBACK_POINT_INTERNAL) {
601 		/* save current port config */
602 		rval = ql_get_port_config(ha, mrp);
603 		if (rval != QL_SUCCESS) {
604 			EL(ha, "ql_get_port_config failed, rval = %xh\n", rval);
605 			return (rval);
606 		}
607 
608 		/* set config to internal loopback */
609 		mr.mb[1] |= int_loopback_bit_mask;
610 		ha->async_event_wait &= ~(BIT_1 | BIT_0);
611 
612 		rval = ql_set_port_config(ha, mrp);
613 
614 		if (rval != QL_SUCCESS) {
615 			EL(ha, "ql_set_port_config failed, rval = %xh\n", rval);
616 			return (rval);
617 		}
618 		wait = MBC_ASYNC_EVENT_WAIT;
619 		while (wait) {
620 			if ((ha->async_event_wait & BIT_0) == 0) {
621 				ql_delay(ha, 1000000);
622 				wait--;
623 			} else {
624 				ha->async_event_wait &= ~BIT_0;
625 				break;
626 			}
627 		}
628 		EL(ha, "waited %d seconds for 8100 async event.\n",
629 		    MBC_ASYNC_EVENT_WAIT - wait);
630 
631 		wait = MBC_ASYNC_EVENT_WAIT;
632 		while (wait) {
633 			if ((ha->async_event_wait & BIT_1) == 0) {
634 				ql_delay(ha, 1000000);
635 				wait--;
636 			} else {
637 				ha->async_event_wait &= ~(BIT_1);
638 				break;
639 			}
640 		}
641 		EL(ha, "waited %d seconds for 8030 async event.\n",
642 		    MBC_ASYNC_EVENT_WAIT - wait);
643 	}
644 
645 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
646 	mcp->mb[1] = lb->options;
647 	mcp->mb[2] = findex;
648 	mcp->mb[6] = LSW(h_rcv);
649 	mcp->mb[7] = MSW(h_rcv);
650 	mcp->mb[10] = LSW(lb->transfer_count);
651 	mcp->mb[11] = MSW(lb->transfer_count);
652 	mcp->mb[12] = lb->transfer_segment_count;
653 	mcp->mb[13] = lb->receive_segment_count;
654 	mcp->mb[14] = LSW(lb->transfer_data_address);
655 	mcp->mb[15] = MSW(lb->transfer_data_address);
656 	mcp->mb[16] = LSW(lb->receive_data_address);
657 	mcp->mb[17] = MSW(lb->receive_data_address);
658 	mcp->mb[18] = LSW(lb->iteration_count);
659 	mcp->mb[19] = MSW(lb->iteration_count);
660 	mcp->mb[20] = LSW(h_xmit);
661 	mcp->mb[21] = MSW(h_xmit);
662 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
663 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
664 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
665 	mcp->timeout = lb->iteration_count / 300;
666 
667 	if (mcp->timeout < MAILBOX_TOV) {
668 		mcp->timeout = MAILBOX_TOV;
669 	}
670 
671 	rval = ql_mailbox_command(ha, mcp);
672 
673 	if (rval != QL_SUCCESS) {
674 		EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
675 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
676 	} else {
677 		/*EMPTY*/
678 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
679 	}
680 
681 	if (CFG_IST(ha, CFG_CTRL_81XX) && (lb->options &
682 	    MBC_LOOPBACK_POINT_MASK) == MBC_LOOPBACK_POINT_INTERNAL) {
683 		int		rval1;
684 		uint32_t	mb1;
685 
686 		/* restore original port config */
687 		mb1 = mrp->mb[1];
688 		mrp->mb[1] = (uint16_t)(mb1 &= ~int_loopback_bit_mask);
689 		ha->async_event_wait &= ~(BIT_1 | BIT_0);
690 
691 		rval1 = ql_set_port_config(ha, &mr);
692 
693 		if (rval1 != QL_SUCCESS) {
694 			EL(ha, "ql_set_port_config(2) failed, rval = %xh\n",
695 			    rval1);
696 			return (rval1);
697 		}
698 
699 		wait = MBC_ASYNC_EVENT_WAIT;
700 		while (wait) {
701 			if ((ha->async_event_wait & BIT_0) == 0) {
702 				ql_delay(ha, 1000000);
703 				wait--;
704 			} else {
705 				ha->async_event_wait &= ~BIT_0;
706 				break;
707 			}
708 		}
709 		EL(ha, "waited %d seconds for 8100 async event.\n",
710 		    MBC_ASYNC_EVENT_WAIT - wait);
711 
712 		wait = MBC_ASYNC_EVENT_WAIT;
713 		while (wait) {
714 			if ((ha->async_event_wait & BIT_1) == 0) {
715 				ql_delay(ha, 1000000);
716 				wait--;
717 			} else {
718 				ha->async_event_wait &= ~BIT_1;
719 				break;
720 			}
721 		}
722 		EL(ha, "waited %d seconds for 8030 async event.\n",
723 		    MBC_ASYNC_EVENT_WAIT - wait);
724 	}
725 	return (rval);
726 }
727 #else
728 int
729 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb)
730 {
731 	int		rval;
732 	mbx_cmd_t	mc = {0};
733 	mbx_cmd_t	*mcp = &mc;
734 
735 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
736 
737 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
738 	mcp->mb[1] = lb->options;
739 	mcp->mb[2] = findex;
740 	mcp->mb[6] = LSW(h_rcv);
741 	mcp->mb[7] = MSW(h_rcv);
742 	mcp->mb[6] = LSW(MSD(lb->receive_data_address));
743 	mcp->mb[7] = MSW(MSD(lb->receive_data_address));
744 	mcp->mb[10] = LSW(lb->transfer_count);
745 	mcp->mb[11] = MSW(lb->transfer_count);
746 	mcp->mb[12] = lb->transfer_segment_count;
747 	mcp->mb[13] = lb->receive_segment_count;
748 	mcp->mb[14] = LSW(lb->transfer_data_address);
749 	mcp->mb[15] = MSW(lb->transfer_data_address);
750 	mcp->mb[14] = LSW(LSD(lb->transfer_data_address));
751 	mcp->mb[15] = MSW(LSD(lb->transfer_data_address));
752 	mcp->mb[16] = LSW(lb->receive_data_address);
753 	mcp->mb[17] = MSW(lb->receive_data_address);
754 	mcp->mb[16] = LSW(LSD(lb->receive_data_address));
755 	mcp->mb[17] = MSW(LSD(lb->receive_data_address));
756 	mcp->mb[18] = LSW(lb->iteration_count);
757 	mcp->mb[19] = MSW(lb->iteration_count);
758 	mcp->mb[20] = LSW(h_xmit);
759 	mcp->mb[21] = MSW(h_xmit);
760 	mcp->mb[20] = LSW(MSD(lb->transfer_data_address));
761 	mcp->mb[21] = MSW(MSD(lb->transfer_data_address));
762 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
763 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
764 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
765 	mcp->timeout = lb->iteration_count / 300;
766 
767 	if (mcp->timeout < MAILBOX_TOV) {
768 		mcp->timeout = MAILBOX_TOV;
769 	}
770 
771 	rval = ql_mailbox_command(ha, mcp);
772 
773 	if (rval != QL_SUCCESS) {
774 		EL(ha, "failed, rval = %xh\n", rval);
775 	} else {
776 		/*EMPTY*/
777 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
778 	}
779 	return (rval);
780 }
781 #endif
782 
783 /*
784  * ql_echo
785  *	Issue an ELS echo using the user specified data to a user specified
786  *	destination
787  *
788  * Input:
789  *	ha:		adapter state pointer.
790  *	findex:		FCF index.
791  *	echo_pt:	echo parameter structure pointer.
792  *
793  * Returns:
794  *	ql local function return status code.
795  *
796  * Context:
797  *	Kernel context.
798  */
799 int
800 ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt)
801 {
802 	int		rval;
803 	mbx_cmd_t	mc = {0};
804 	mbx_cmd_t	*mcp = &mc;
805 
806 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
807 
808 	mcp->mb[0] = MBC_ECHO;			/* ECHO command */
809 	mcp->mb[1] = echo_pt->options;		/* command options; 64 bit */
810 						/* addressing (bit 6) and */
811 						/* real echo (bit 15 */
812 	mcp->mb[2] = findex;
813 
814 	/*
815 	 * I know this looks strange, using a field labled "not used"
816 	 * The way the ddi_dma_cookie_t structure/union is defined
817 	 * is a union of one 64 bit entity with an array of two 32
818 	 * bit enititys.  Since we have routines to convert 32 bit
819 	 * entities into 16 bit entities it is easier to use
820 	 * both 32 bit union members then the one 64 bit union
821 	 * member
822 	 */
823 	if (echo_pt->options & BIT_6) {
824 		/* 64 bit addressing */
825 		/* Receive data dest add in system memory bits 47-32 */
826 		mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused);
827 
828 		/* Receive data dest add in system memory bits 63-48 */
829 		mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused);
830 
831 		/* Transmit data source address in system memory bits 47-32 */
832 		mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused);
833 
834 		/* Transmit data source address in system memory bits 63-48 */
835 		mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused);
836 	}
837 
838 	/* transfer count bits 15-0 */
839 	mcp->mb[10] = LSW(echo_pt->transfer_count);
840 
841 	/* Transmit data source address in system memory bits 15-0 */
842 	mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address);
843 
844 	/*  Transmit data source address in system memory bits 31-16 */
845 	mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address);
846 
847 	/* Receive data destination address in system memory bits 15-0 */
848 	mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address);
849 
850 	/*  Receive data destination address in system memory bits 31-16 */
851 	mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address);
852 
853 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10|
854 	    MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
855 	mcp->in_mb = MBX_3|MBX_1|MBX_0;
856 	mcp->timeout = MAILBOX_TOV;
857 
858 	rval = ql_mailbox_command(ha, mcp);
859 
860 	if (rval != QL_SUCCESS) {
861 		EL(ha, "failed, rval = %xh\n", rval);
862 	} else {
863 		/*EMPTY*/
864 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
865 	}
866 	return (rval);
867 }
868 
869 /*
870  * ql_send_change_request
871  *	Issue send change request mailbox command.
872  *
873  * Input:
874  *	ha:	adapter state pointer.
875  *	fmt:	Registration format.
876  *
877  * Returns:
878  *	ql local function return status code.
879  *
880  * Context:
881  *	Kernel context.
882  */
883 int
884 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt)
885 {
886 	int		rval;
887 	mbx_cmd_t	mc = {0};
888 	mbx_cmd_t	*mcp = &mc;
889 
890 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
891 
892 	mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
893 	mcp->mb[1] = fmt;
894 	mcp->out_mb = MBX_1|MBX_0;
895 	if (ha->flags & VP_ENABLED) {
896 		mcp->mb[9] = ha->vp_index;
897 		mcp->out_mb |= MBX_9;
898 	}
899 	mcp->in_mb = MBX_0;
900 	mcp->timeout = MAILBOX_TOV;
901 	rval = ql_mailbox_command(ha, mcp);
902 
903 	if (rval != QL_SUCCESS) {
904 		EL(ha, "failed=%xh\n", rval);
905 	} else {
906 		/*EMPTY*/
907 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
908 	}
909 	return (rval);
910 }
911 
912 /*
913  * ql_send_lfa
914  *	Send a Loop Fabric Address mailbox command.
915  *
916  * Input:
917  *	ha:	adapter state pointer.
918  *	lfa:	LFA command structure pointer.
919  *
920  * Returns:
921  *	ql local function return status code.
922  *
923  * Context:
924  *	Kernel context.
925  */
926 int
927 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa)
928 {
929 	int		rval;
930 	uint16_t	size;
931 	dma_mem_t	mem_desc;
932 	mbx_cmd_t	mc = {0};
933 	mbx_cmd_t	*mcp = &mc;
934 
935 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
936 
937 	/* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */
938 	size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1);
939 
940 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size);
941 	if (rval != QL_SUCCESS) {
942 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
943 		return (rval);
944 	}
945 
946 	mcp->mb[0] = MBC_SEND_LFA_COMMAND;
947 	mcp->mb[1] = (uint16_t)(size >> 1);
948 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
949 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
950 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
951 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
952 	mcp->in_mb = MBX_0;
953 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
954 	if (ha->flags & VP_ENABLED) {
955 		mcp->mb[9] = ha->vp_index;
956 		mcp->out_mb |= MBX_9;
957 	}
958 	mcp->timeout = MAILBOX_TOV;
959 	rval = ql_mailbox_command(ha, mcp);
960 
961 	ql_free_dma_resource(ha, &mem_desc);
962 
963 	if (rval != QL_SUCCESS) {
964 		EL(ha, "failed, rval = %xh\n", rval);
965 	} else {
966 		/*EMPTY*/
967 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
968 	}
969 
970 	return (rval);
971 }
972 
973 /*
974  * ql_clear_aca
975  *	Issue clear ACA mailbox command.
976  *
977  * Input:
978  *	ha:	adapter state pointer.
979  *	tq:	target queue pointer.
980  *	lun:	LUN.
981  *
982  * Returns:
983  *	ql local function return status code.
984  *
985  * Context:
986  *	Kernel context.
987  */
988 int
989 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
990 {
991 	int		rval;
992 	mbx_cmd_t	mc = {0};
993 	mbx_cmd_t	*mcp = &mc;
994 
995 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
996 
997 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
998 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_ACA, 0);
999 	} else {
1000 		mcp->mb[0] = MBC_CLEAR_ACA;
1001 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1002 			mcp->mb[1] = tq->loop_id;
1003 		} else {
1004 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1005 		}
1006 		mcp->mb[2] = lun;
1007 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1008 		mcp->in_mb = MBX_0;
1009 		mcp->timeout = MAILBOX_TOV;
1010 		rval = ql_mailbox_command(ha, mcp);
1011 	}
1012 
1013 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1014 
1015 	if (rval != QL_SUCCESS) {
1016 		EL(ha, "failed, rval = %xh\n", rval);
1017 	} else {
1018 		/*EMPTY*/
1019 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1020 	}
1021 
1022 	return (rval);
1023 }
1024 
1025 /*
1026  * ql_target_reset
1027  *	Issue target reset mailbox command.
1028  *
1029  * Input:
1030  *	ha:	adapter state pointer.
1031  *	tq:	target queue pointer.
1032  *	delay:	seconds.
1033  *
1034  * Returns:
1035  *	ql local function return status code.
1036  *
1037  * Context:
1038  *	Kernel context.
1039  */
1040 int
1041 ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1042 {
1043 	ql_link_t	*link;
1044 	uint16_t	index;
1045 	int		rval;
1046 	mbx_cmd_t	mc = {0};
1047 	mbx_cmd_t	*mcp = &mc;
1048 
1049 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1050 
1051 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1052 		/* queue = NULL, all targets. */
1053 		if (tq == NULL) {
1054 			for (index = 0; index < DEVICE_HEAD_LIST_SIZE;
1055 			    index++) {
1056 				for (link = ha->dev[index].first; link !=
1057 				    NULL; link = link->next) {
1058 					tq = link->base_address;
1059 					if (!VALID_DEVICE_ID(ha,
1060 					    tq->loop_id)) {
1061 						continue;
1062 					}
1063 
1064 					if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
1065 						rval = ql_task_mgmt_iocb(ha,
1066 						    tq, 0, CF_DO_NOT_SEND |
1067 						    CF_TARGET_RESET, delay);
1068 					} else {
1069 						rval = ql_task_mgmt_iocb(ha,
1070 						    tq, 0, CF_TARGET_RESET,
1071 						    delay);
1072 					}
1073 
1074 					if (rval != QL_SUCCESS) {
1075 						break;
1076 					}
1077 				}
1078 
1079 				if (link != NULL) {
1080 					break;
1081 				}
1082 			}
1083 			tq = NULL;
1084 		} else {
1085 
1086 			if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
1087 				rval = ql_task_mgmt_iocb(ha, tq, 0,
1088 				    CF_TARGET_RESET | CF_DO_NOT_SEND, delay);
1089 			} else {
1090 				rval = ql_task_mgmt_iocb(ha, tq, 0,
1091 				    CF_TARGET_RESET, delay);
1092 			}
1093 		}
1094 	} else {
1095 		/* queue = NULL, all targets. */
1096 		if (tq == NULL) {
1097 			mcp->mb[0] = MBC_RESET;
1098 			mcp->mb[1] = delay;
1099 			mcp->out_mb = MBX_1|MBX_0;
1100 		} else {
1101 			mcp->mb[0] = MBC_TARGET_RESET;
1102 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1103 				mcp->mb[1] = tq->loop_id;
1104 			} else {
1105 				mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1106 			}
1107 			mcp->mb[2] = delay;
1108 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1109 		}
1110 		mcp->in_mb = MBX_0;
1111 		mcp->timeout = MAILBOX_TOV;
1112 		rval = ql_mailbox_command(ha, mcp);
1113 	}
1114 
1115 	tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1116 	    (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1117 
1118 	if (rval != QL_SUCCESS) {
1119 		EL(ha, "failed, rval = %xh\n", rval);
1120 	} else {
1121 		/*EMPTY*/
1122 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1123 	}
1124 
1125 	return (rval);
1126 }
1127 
1128 /*
1129  * ql_abort_target
1130  *	Issue abort target mailbox command.
1131  *
1132  * Input:
1133  *	ha:	adapter state pointer.
1134  *	tq:	target queue pointer.
1135  *	delay:	in seconds.
1136  *
1137  * Returns:
1138  *	ql local function return status code.
1139  *
1140  * Context:
1141  *	Kernel context.
1142  */
1143 int
1144 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1145 {
1146 	int		rval;
1147 	mbx_cmd_t	mc = {0};
1148 	mbx_cmd_t	*mcp = &mc;
1149 
1150 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1151 
1152 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1153 		rval = ql_task_mgmt_iocb(ha, tq, 0,
1154 		    CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1155 	} else {
1156 		mcp->mb[0] = MBC_ABORT_TARGET;
1157 		/* Don't send Task Mgt */
1158 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1159 			mcp->mb[1] = tq->loop_id;
1160 			mcp->mb[10] = BIT_0;
1161 			mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1162 		} else {
1163 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1164 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1165 		}
1166 		mcp->mb[2] = delay;
1167 		mcp->in_mb = MBX_0;
1168 		mcp->timeout = MAILBOX_TOV;
1169 		rval = ql_mailbox_command(ha, mcp);
1170 	}
1171 
1172 	(void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1173 
1174 	if (rval != QL_SUCCESS) {
1175 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1176 	} else {
1177 		/*EMPTY*/
1178 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1179 	}
1180 	return (rval);
1181 }
1182 
1183 /*
1184  * ql_lun_reset
1185  *	Issue LUN reset task management mailbox command.
1186  *
1187  * Input:
1188  *	ha:	adapter state pointer.
1189  *	tq:	target queue pointer.
1190  *	lun:	LUN.
1191  *
1192  * Returns:
1193  *	ql local function return status code.
1194  *
1195  * Context:
1196  *	Kernel context.
1197  */
1198 int
1199 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1200 {
1201 	int		rval;
1202 	mbx_cmd_t	mc = {0};
1203 	mbx_cmd_t	*mcp = &mc;
1204 
1205 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1206 
1207 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1208 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_LUN_RESET, 0);
1209 	} else {
1210 		mcp->mb[0] = MBC_LUN_RESET;
1211 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1212 			mcp->mb[1] = tq->loop_id;
1213 		} else {
1214 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1215 		}
1216 		mcp->mb[2] = lun;
1217 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1218 		mcp->in_mb = MBX_0;
1219 		mcp->timeout = MAILBOX_TOV;
1220 		rval = ql_mailbox_command(ha, mcp);
1221 	}
1222 
1223 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1224 
1225 	if (rval != QL_SUCCESS) {
1226 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1227 	} else {
1228 		/*EMPTY*/
1229 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1230 	}
1231 	return (rval);
1232 }
1233 
1234 /*
1235  * ql_clear_task_set
1236  *	Issue clear task set mailbox command.
1237  *
1238  * Input:
1239  *	ha:	adapter state pointer.
1240  *	tq:	target queue pointer.
1241  *	lun:	LUN.
1242  *
1243  * Returns:
1244  *	ql local function return status code.
1245  *
1246  * Context:
1247  *	Kernel context.
1248  */
1249 int
1250 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1251 {
1252 	int		rval;
1253 	mbx_cmd_t	mc = {0};
1254 	mbx_cmd_t	*mcp = &mc;
1255 
1256 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1257 
1258 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1259 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0);
1260 	} else {
1261 		mcp->mb[0] = MBC_CLEAR_TASK_SET;
1262 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1263 			mcp->mb[1] = tq->loop_id;
1264 		} else {
1265 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1266 		}
1267 		mcp->mb[2] = lun;
1268 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1269 		mcp->in_mb = MBX_0;
1270 		mcp->timeout = MAILBOX_TOV;
1271 		rval = ql_mailbox_command(ha, mcp);
1272 	}
1273 
1274 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1275 
1276 	if (rval != QL_SUCCESS) {
1277 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1278 	} else {
1279 		/*EMPTY*/
1280 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1281 	}
1282 
1283 	return (rval);
1284 }
1285 
1286 /*
1287  * ql_abort_task_set
1288  *	Issue abort task set mailbox command.
1289  *
1290  * Input:
1291  *	ha:	adapter state pointer.
1292  *	tq:	target queue pointer.
1293  *	lun:	LUN.
1294  *
1295  * Returns:
1296  *	ql local function return status code.
1297  *
1298  * Context:
1299  *	Kernel context.
1300  */
1301 int
1302 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1303 {
1304 	int		rval;
1305 	mbx_cmd_t	mc = {0};
1306 	mbx_cmd_t	*mcp = &mc;
1307 
1308 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1309 
1310 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1311 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0);
1312 	} else {
1313 		mcp->mb[0] = MBC_ABORT_TASK_SET;
1314 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1315 			mcp->mb[1] = tq->loop_id;
1316 		} else {
1317 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1318 		}
1319 		mcp->mb[2] = lun;
1320 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1321 		mcp->in_mb = MBX_0;
1322 		mcp->timeout = MAILBOX_TOV;
1323 		rval = ql_mailbox_command(ha, mcp);
1324 	}
1325 
1326 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1327 
1328 	if (rval != QL_SUCCESS) {
1329 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1330 	} else {
1331 		/*EMPTY*/
1332 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1333 	}
1334 
1335 	return (rval);
1336 }
1337 
1338 /*
1339  * ql_task_mgmt_iocb
1340  *	Function issues task management IOCB.
1341  *
1342  * Input:
1343  *	ha:	adapter state pointer.
1344  *	tq:	target queue pointer.
1345  *	lun:	LUN.
1346  *	flags:	control flags.
1347  *	delay:	seconds.
1348  *
1349  * Returns:
1350  *	ql local function return status code.
1351  *
1352  * Context:
1353  *	Kernel context
1354  */
1355 static int
1356 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun,
1357     uint32_t flags, uint16_t delay)
1358 {
1359 	ql_mbx_iocb_t	*pkt;
1360 	int		rval;
1361 	uint32_t	pkt_size;
1362 
1363 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1364 
1365 	pkt_size = sizeof (ql_mbx_iocb_t);
1366 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1367 	if (pkt == NULL) {
1368 		EL(ha, "failed, kmem_zalloc\n");
1369 		return (QL_MEMORY_ALLOC_FAILED);
1370 	}
1371 
1372 	pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1373 	pkt->mgmt.entry_count = 1;
1374 
1375 	pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1376 	pkt->mgmt.delay = (uint16_t)LE_16(delay);
1377 	pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1378 	pkt->mgmt.fcp_lun[2] = LSB(lun);
1379 	pkt->mgmt.fcp_lun[3] = MSB(lun);
1380 	pkt->mgmt.control_flags = LE_32(flags);
1381 	pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1382 	pkt->mgmt.target_id[1] = tq->d_id.b.area;
1383 	pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1384 	pkt->mgmt.vp_index = ha->vp_index;
1385 
1386 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1387 	if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1388 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1389 		    pkt->sts24.entry_status, tq->d_id.b24);
1390 		rval = QL_FUNCTION_PARAMETER_ERROR;
1391 	}
1392 
1393 	LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1394 
1395 	if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1396 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1397 		    pkt->sts24.comp_status, tq->d_id.b24);
1398 		rval = QL_FUNCTION_FAILED;
1399 	}
1400 
1401 	kmem_free(pkt, pkt_size);
1402 
1403 	if (rval != QL_SUCCESS) {
1404 		EL(ha, "failed, rval = %xh\n", rval);
1405 	} else {
1406 		/*EMPTY*/
1407 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1408 	}
1409 
1410 	return (rval);
1411 }
1412 
1413 /*
1414  * ql_loop_port_bypass
1415  *	Issue loop port bypass mailbox command.
1416  *
1417  * Input:
1418  *	ha:	adapter state pointer.
1419  *	tq:	target queue pointer.
1420  *
1421  * Returns:
1422  *	ql local function return status code.
1423  *
1424  * Context:
1425  *	Kernel context.
1426  */
1427 int
1428 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1429 {
1430 	int		rval;
1431 	mbx_cmd_t	mc = {0};
1432 	mbx_cmd_t	*mcp = &mc;
1433 
1434 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1435 
1436 	mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1437 
1438 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1439 		mcp->mb[1] = tq->d_id.b.al_pa;
1440 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1441 		mcp->mb[1] = tq->loop_id;
1442 	} else {
1443 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1444 	}
1445 
1446 	mcp->out_mb = MBX_1|MBX_0;
1447 	mcp->in_mb = MBX_0;
1448 	mcp->timeout = MAILBOX_TOV;
1449 	rval = ql_mailbox_command(ha, mcp);
1450 
1451 	if (rval != QL_SUCCESS) {
1452 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1453 	} else {
1454 		/*EMPTY*/
1455 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1456 	}
1457 
1458 	return (rval);
1459 }
1460 
1461 /*
1462  * ql_loop_port_enable
1463  *	Issue loop port enable mailbox command.
1464  *
1465  * Input:
1466  *	ha:	adapter state pointer.
1467  *	tq:	target queue pointer.
1468  *
1469  * Returns:
1470  *	ql local function return status code.
1471  *
1472  * Context:
1473  *	Kernel context.
1474  */
1475 int
1476 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1477 {
1478 	int		rval;
1479 	mbx_cmd_t	mc = {0};
1480 	mbx_cmd_t	*mcp = &mc;
1481 
1482 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1483 
1484 	mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1485 
1486 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1487 		mcp->mb[1] = tq->d_id.b.al_pa;
1488 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1489 		mcp->mb[1] = tq->loop_id;
1490 	} else {
1491 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1492 	}
1493 	mcp->out_mb = MBX_1|MBX_0;
1494 	mcp->in_mb = MBX_0;
1495 	mcp->timeout = MAILBOX_TOV;
1496 	rval = ql_mailbox_command(ha, mcp);
1497 
1498 	if (rval != QL_SUCCESS) {
1499 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1500 	} else {
1501 		/*EMPTY*/
1502 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1503 	}
1504 
1505 	return (rval);
1506 }
1507 
1508 /*
1509  * ql_login_lport
1510  *	Issue login loop port mailbox command.
1511  *
1512  * Input:
1513  *	ha:		adapter state pointer.
1514  *	tq:		target queue pointer.
1515  *	loop_id:	FC loop id.
1516  *	opt:		options.
1517  *			LLF_NONE, LLF_PLOGI
1518  *
1519  * Returns:
1520  *	ql local function return status code.
1521  *
1522  * Context:
1523  *	Kernel context.
1524  */
1525 int
1526 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1527     uint16_t opt)
1528 {
1529 	int		rval;
1530 	uint16_t	flags;
1531 	ql_mbx_data_t	mr;
1532 	mbx_cmd_t	mc = {0};
1533 	mbx_cmd_t	*mcp = &mc;
1534 
1535 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1536 	    ha->instance, tq->d_id.b24, loop_id);
1537 
1538 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1539 		flags = CF_CMD_PLOGI;
1540 		if ((opt & LLF_PLOGI) == 0) {
1541 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1542 		}
1543 		rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1544 	} else {
1545 		mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1546 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1547 			mcp->mb[1] = loop_id;
1548 		} else {
1549 			mcp->mb[1] = (uint16_t)(loop_id << 8);
1550 		}
1551 		mcp->mb[2] = opt;
1552 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1553 		mcp->in_mb = MBX_0;
1554 		mcp->timeout = MAILBOX_TOV;
1555 		rval = ql_mailbox_command(ha, mcp);
1556 	}
1557 
1558 	if (rval != QL_SUCCESS) {
1559 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1560 		    loop_id, rval);
1561 	} else {
1562 		/*EMPTY*/
1563 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1564 	}
1565 
1566 	return (rval);
1567 }
1568 
1569 /*
1570  * ql_login_fport
1571  *	Issue login fabric port mailbox command.
1572  *
1573  * Input:
1574  *	ha:		adapter state pointer.
1575  *	tq:		target queue pointer.
1576  *	loop_id:	FC loop id.
1577  *	opt:		options.
1578  *			LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1579  *	mr:		pointer for mailbox data.
1580  *
1581  * Returns:
1582  *	ql local function return status code.
1583  *
1584  * Context:
1585  *	Kernel context.
1586  */
1587 int
1588 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1589     uint16_t opt, ql_mbx_data_t *mr)
1590 {
1591 	int		rval;
1592 	uint16_t	flags;
1593 	mbx_cmd_t	mc = {0};
1594 	mbx_cmd_t	*mcp = &mc;
1595 
1596 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1597 	    ha->instance, tq->d_id.b24, loop_id);
1598 
1599 	if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) {
1600 		opt = (uint16_t)(opt | LFF_NO_PRLI);
1601 	}
1602 
1603 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1604 		flags = CF_CMD_PLOGI;
1605 		if (opt & LFF_NO_PLOGI) {
1606 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1607 		}
1608 		if (opt & LFF_NO_PRLI) {
1609 			flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1610 		}
1611 		rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1612 	} else {
1613 		mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1614 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1615 			mcp->mb[1] = loop_id;
1616 			mcp->mb[10] = opt;
1617 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1618 		} else {
1619 			mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1620 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1621 		}
1622 		mcp->mb[2] = MSW(tq->d_id.b24);
1623 		mcp->mb[3] = LSW(tq->d_id.b24);
1624 		mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1625 		mcp->timeout = MAILBOX_TOV;
1626 		rval = ql_mailbox_command(ha, mcp);
1627 
1628 		/* Return mailbox data. */
1629 		if (mr != NULL) {
1630 			mr->mb[0] = mcp->mb[0];
1631 			mr->mb[1] = mcp->mb[1];
1632 			mr->mb[2] = mcp->mb[2];
1633 			mr->mb[6] = mcp->mb[6];
1634 			mr->mb[7] = mcp->mb[7];
1635 		}
1636 	}
1637 
1638 	if (rval != QL_SUCCESS) {
1639 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1640 		    "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1],
1641 		    mr->mb[2]);
1642 	} else {
1643 		/*EMPTY*/
1644 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1645 	}
1646 
1647 	return (rval);
1648 }
1649 
1650 /*
1651  * ql_logout_fabric_port
1652  *	Issue logout fabric port mailbox command.
1653  *
1654  * Input:
1655  *	ha:	adapter state pointer.
1656  *	tq:	target queue pointer.
1657  *
1658  * Returns:
1659  *	ql local function return status code.
1660  *
1661  * Context:
1662  *	Kernel context.
1663  */
1664 int
1665 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1666 {
1667 	int		rval;
1668 	uint16_t	flag;
1669 	ql_mbx_data_t	mr;
1670 	mbx_cmd_t	mc = {0};
1671 	mbx_cmd_t	*mcp = &mc;
1672 
1673 	QL_PRINT_3(CE_CONT, "(%d): started, loop_id=%xh d_id=%xh\n",
1674 	    ha->instance, tq->loop_id, tq->d_id.b24);
1675 
1676 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1677 		flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1678 		    CFO_EXPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE :
1679 		    CFO_IMPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1680 		rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1681 	} else {
1682 		flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?  1 : 0);
1683 		mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1684 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1685 			mcp->mb[1] = tq->loop_id;
1686 			mcp->mb[10] = flag;
1687 			mcp->out_mb = MBX_10|MBX_1|MBX_0;
1688 		} else {
1689 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1690 			mcp->out_mb = MBX_1|MBX_0;
1691 		}
1692 		mcp->in_mb = MBX_0;
1693 		mcp->timeout = MAILBOX_TOV;
1694 		rval = ql_mailbox_command(ha, mcp);
1695 	}
1696 
1697 	if (rval != QL_SUCCESS) {
1698 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval,
1699 		    tq->d_id.b24, tq->loop_id);
1700 	} else {
1701 		/*EMPTY*/
1702 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1703 	}
1704 
1705 	return (rval);
1706 }
1707 
1708 /*
1709  * ql_log_iocb
1710  *	Function issues login/logout IOCB.
1711  *
1712  * Input:
1713  *	ha:		adapter state pointer.
1714  *	tq:		target queue pointer.
1715  *	loop_id:	FC Loop ID.
1716  *	flags:		control flags.
1717  *	mr:		pointer for mailbox data.
1718  *
1719  * Returns:
1720  *	ql local function return status code.
1721  *
1722  * Context:
1723  *	Kernel context.
1724  */
1725 int
1726 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1727     uint16_t flags, ql_mbx_data_t *mr)
1728 {
1729 	ql_mbx_iocb_t	*pkt;
1730 	int		rval;
1731 	uint32_t	pkt_size;
1732 
1733 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1734 
1735 	pkt_size = sizeof (ql_mbx_iocb_t);
1736 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1737 	if (pkt == NULL) {
1738 		EL(ha, "failed, kmem_zalloc\n");
1739 		return (QL_MEMORY_ALLOC_FAILED);
1740 	}
1741 
1742 	pkt->log.entry_type = LOG_TYPE;
1743 	pkt->log.entry_count = 1;
1744 	pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1745 	pkt->log.control_flags = (uint16_t)LE_16(flags);
1746 	pkt->log.port_id[0] = tq->d_id.b.al_pa;
1747 	pkt->log.port_id[1] = tq->d_id.b.area;
1748 	pkt->log.port_id[2] = tq->d_id.b.domain;
1749 	pkt->log.vp_index = ha->vp_index;
1750 
1751 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1752 	if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1753 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1754 		    pkt->log.entry_status, tq->d_id.b24);
1755 		rval = QL_FUNCTION_PARAMETER_ERROR;
1756 	}
1757 
1758 	if (rval == QL_SUCCESS) {
1759 		if (pkt->log.rsp_size == 0xB) {
1760 			LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1761 			tq->cmn_features = MSW(pkt->log.io_param[5]);
1762 			LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1763 			tq->conc_sequences = MSW(pkt->log.io_param[6]);
1764 			tq->relative_offset = LSW(pkt->log.io_param[6]);
1765 			LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1766 			tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1767 			tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1768 			LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1769 			tq->class3_open_sequences_per_exch =
1770 			    MSW(pkt->log.io_param[10]);
1771 			tq->prli_payload_length = 0x14;
1772 		}
1773 		if (mr != NULL) {
1774 			LITTLE_ENDIAN_16(&pkt->log.status);
1775 			LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1776 			LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1777 
1778 			if (pkt->log.status != CS_COMPLETE) {
1779 				EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1780 				    "%xh\n", pkt->log.status,
1781 				    pkt->log.io_param[0],
1782 				    pkt->log.io_param[1]);
1783 
1784 				switch (pkt->log.io_param[0]) {
1785 				case CS0_NO_LINK:
1786 				case CS0_FIRMWARE_NOT_READY:
1787 					mr->mb[0] = MBS_COMMAND_ERROR;
1788 					mr->mb[1] = 1;
1789 					break;
1790 				case CS0_NO_IOCB:
1791 				case CS0_NO_PCB_ALLOCATED:
1792 					mr->mb[0] = MBS_COMMAND_ERROR;
1793 					mr->mb[1] = 2;
1794 					break;
1795 				case CS0_NO_EXCH_CTRL_BLK:
1796 					mr->mb[0] = MBS_COMMAND_ERROR;
1797 					mr->mb[1] = 3;
1798 					break;
1799 				case CS0_COMMAND_FAILED:
1800 					mr->mb[0] = MBS_COMMAND_ERROR;
1801 					mr->mb[1] = 4;
1802 					switch (LSB(pkt->log.io_param[1])) {
1803 					case CS1_PLOGI_RESPONSE_FAILED:
1804 						mr->mb[2] = 3;
1805 						break;
1806 					case CS1_PRLI_FAILED:
1807 						mr->mb[2] = 4;
1808 						break;
1809 					case CS1_PRLI_RESPONSE_FAILED:
1810 						mr->mb[2] = 5;
1811 						break;
1812 					case CS1_COMMAND_LOGGED_OUT:
1813 						mr->mb[2] = 7;
1814 						break;
1815 					case CS1_PLOGI_FAILED:
1816 					default:
1817 						EL(ha, "log iop1 = %xh\n",
1818 						    LSB(pkt->log.io_param[1]))
1819 						mr->mb[2] = 2;
1820 						break;
1821 					}
1822 					break;
1823 				case CS0_PORT_NOT_LOGGED_IN:
1824 					mr->mb[0] = MBS_COMMAND_ERROR;
1825 					mr->mb[1] = 4;
1826 					mr->mb[2] = 7;
1827 					break;
1828 				case CS0_NO_FLOGI_ACC:
1829 				case CS0_NO_FABRIC_PRESENT:
1830 					mr->mb[0] = MBS_COMMAND_ERROR;
1831 					mr->mb[1] = 5;
1832 					break;
1833 				case CS0_ELS_REJECT_RECEIVED:
1834 					mr->mb[0] = MBS_COMMAND_ERROR;
1835 					mr->mb[1] = 0xd;
1836 					break;
1837 				case CS0_PORT_ID_USED:
1838 					mr->mb[0] = MBS_PORT_ID_USED;
1839 					mr->mb[1] = LSW(pkt->log.io_param[1]);
1840 					break;
1841 				case CS0_N_PORT_HANDLE_USED:
1842 					mr->mb[0] = MBS_LOOP_ID_USED;
1843 					mr->mb[1] = MSW(pkt->log.io_param[1]);
1844 					mr->mb[2] = LSW(pkt->log.io_param[1]);
1845 					break;
1846 				case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1847 					mr->mb[0] = MBS_ALL_IDS_IN_USE;
1848 					break;
1849 				case CS0_CMD_PARAMETER_ERROR:
1850 				default:
1851 					EL(ha, "pkt->log iop[0]=%xh\n",
1852 					    pkt->log.io_param[0]);
1853 					mr->mb[0] =
1854 					    MBS_COMMAND_PARAMETER_ERROR;
1855 					break;
1856 				}
1857 			} else {
1858 				QL_PRINT_3(CE_CONT, "(%d): status=%xh\n",
1859 				    ha->instance, pkt->log.status);
1860 
1861 				mr->mb[0] = MBS_COMMAND_COMPLETE;
1862 				mr->mb[1] = (uint16_t)
1863 				    (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1864 				if (pkt->log.io_param[0] & BIT_8) {
1865 					mr->mb[1] = (uint16_t)
1866 					    (mr->mb[1] | BIT_1);
1867 				}
1868 			}
1869 			rval = mr->mb[0];
1870 		}
1871 
1872 	}
1873 
1874 	kmem_free(pkt, pkt_size);
1875 
1876 	if (rval != QL_SUCCESS) {
1877 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1878 	} else {
1879 		/*EMPTY*/
1880 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1881 	}
1882 
1883 	return (rval);
1884 }
1885 
1886 /*
1887  * ql_get_port_database
1888  *	Issue get port database mailbox command
1889  *	and copy context to device queue.
1890  *
1891  * Input:
1892  *	ha:	adapter state pointer.
1893  *	tq:	target queue pointer.
1894  *	opt:	options.
1895  *		PDF_NONE, PDF_PLOGI, PDF_ADISC
1896  * Returns:
1897  *	ql local function return status code.
1898  *
1899  * Context:
1900  *	Kernel context.
1901  */
1902 int
1903 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1904 {
1905 	int			rval;
1906 	dma_mem_t		mem_desc;
1907 	mbx_cmd_t		mc = {0};
1908 	mbx_cmd_t		*mcp = &mc;
1909 	port_database_23_t	*pd23;
1910 
1911 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1912 
1913 	pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1914 	if (pd23 == NULL) {
1915 		rval = QL_MEMORY_ALLOC_FAILED;
1916 		EL(ha, "failed, rval = %xh\n", rval);
1917 		return (rval);
1918 	}
1919 
1920 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1921 	    PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1922 		return (QL_MEMORY_ALLOC_FAILED);
1923 	}
1924 
1925 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1926 		mcp->mb[0] = MBC_GET_PORT_DATABASE;
1927 		mcp->mb[1] = tq->loop_id;
1928 		mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1929 		mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1930 		mcp->mb[9] = ha->vp_index;
1931 		mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1932 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1933 		    MBX_2|MBX_1|MBX_0;
1934 	} else {
1935 		mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1936 		    MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1937 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1938 			mcp->mb[1] = tq->loop_id;
1939 			mcp->mb[10] = opt;
1940 			mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1941 			    MBX_2|MBX_1|MBX_0;
1942 		} else {
1943 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1944 			mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1945 		}
1946 	}
1947 
1948 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1949 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1950 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1951 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1952 	mcp->in_mb = MBX_0;
1953 	mcp->timeout = MAILBOX_TOV;
1954 	rval = ql_mailbox_command(ha, mcp);
1955 
1956 	if (rval == QL_SUCCESS) {
1957 		ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1958 	}
1959 
1960 	ql_free_dma_resource(ha, &mem_desc);
1961 
1962 	if (rval == QL_SUCCESS) {
1963 		if (CFG_IST(ha, CFG_CTRL_24258081)) {
1964 			port_database_24_t *pd24 = (port_database_24_t *)pd23;
1965 
1966 			tq->master_state = pd24->current_login_state;
1967 			tq->slave_state = pd24->last_stable_login_state;
1968 			if (PD_PORT_LOGIN(tq)) {
1969 				/* Names are big endian. */
1970 				bcopy((void *)&pd24->port_name[0],
1971 				    (void *)&tq->port_name[0], 8);
1972 				bcopy((void *)&pd24->node_name[0],
1973 				    (void *)&tq->node_name[0], 8);
1974 				tq->hard_addr.b.al_pa = pd24->hard_address[2];
1975 				tq->hard_addr.b.area = pd24->hard_address[1];
1976 				tq->hard_addr.b.domain = pd24->hard_address[0];
1977 				tq->class3_rcv_data_size =
1978 				    pd24->receive_data_size;
1979 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1980 				tq->prli_svc_param_word_0 =
1981 				    pd24->PRLI_service_parameter_word_0;
1982 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1983 				tq->prli_svc_param_word_3 =
1984 				    pd24->PRLI_service_parameter_word_3;
1985 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1986 			}
1987 		} else {
1988 			tq->master_state = pd23->master_state;
1989 			tq->slave_state = pd23->slave_state;
1990 			if (PD_PORT_LOGIN(tq)) {
1991 				/* Names are big endian. */
1992 				bcopy((void *)&pd23->port_name[0],
1993 				    (void *)&tq->port_name[0], 8);
1994 				bcopy((void *)&pd23->node_name[0],
1995 				    (void *)&tq->node_name[0], 8);
1996 				tq->hard_addr.b.al_pa = pd23->hard_address[2];
1997 				tq->hard_addr.b.area = pd23->hard_address[1];
1998 				tq->hard_addr.b.domain = pd23->hard_address[0];
1999 				tq->cmn_features = pd23->common_features;
2000 				LITTLE_ENDIAN_16(&tq->cmn_features);
2001 				tq->conc_sequences =
2002 				    pd23->total_concurrent_sequences;
2003 				LITTLE_ENDIAN_16(&tq->conc_sequences);
2004 				tq->relative_offset =
2005 				    pd23->RO_by_information_category;
2006 				LITTLE_ENDIAN_16(&tq->relative_offset);
2007 				tq->class3_recipient_ctl = pd23->recipient;
2008 				LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
2009 				tq->class3_rcv_data_size =
2010 				    pd23->receive_data_size;
2011 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
2012 				tq->class3_conc_sequences =
2013 				    pd23->concurrent_sequences;
2014 				LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
2015 				tq->class3_open_sequences_per_exch =
2016 				    pd23->open_sequences_per_exchange;
2017 				LITTLE_ENDIAN_16(
2018 				    &tq->class3_open_sequences_per_exch);
2019 				tq->prli_payload_length =
2020 				    pd23->PRLI_payload_length;
2021 				LITTLE_ENDIAN_16(&tq->prli_payload_length);
2022 				tq->prli_svc_param_word_0 =
2023 				    pd23->PRLI_service_parameter_word_0;
2024 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
2025 				tq->prli_svc_param_word_3 =
2026 				    pd23->PRLI_service_parameter_word_3;
2027 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
2028 			}
2029 		}
2030 
2031 		if (!PD_PORT_LOGIN(tq)) {
2032 			EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
2033 			    "master=%xh, slave=%xh\n", tq->d_id.b24,
2034 			    tq->loop_id, tq->master_state, tq->slave_state);
2035 			rval = QL_NOT_LOGGED_IN;
2036 		} else {
2037 			tq->flags = tq->prli_svc_param_word_3 &
2038 			    PRLI_W3_TARGET_FUNCTION ?
2039 			    tq->flags & ~TQF_INITIATOR_DEVICE :
2040 			    tq->flags | TQF_INITIATOR_DEVICE;
2041 
2042 			if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
2043 				tq->flags = tq->prli_svc_param_word_3 &
2044 				    PRLI_W3_RETRY ?
2045 				    tq->flags | TQF_TAPE_DEVICE :
2046 				    tq->flags & ~TQF_TAPE_DEVICE;
2047 			} else {
2048 				tq->flags &= ~TQF_TAPE_DEVICE;
2049 			}
2050 		}
2051 	}
2052 
2053 	kmem_free(pd23, PORT_DATABASE_SIZE);
2054 
2055 	if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) {
2056 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
2057 		    tq->loop_id, rval);
2058 	} else {
2059 		/*EMPTY*/
2060 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2061 	}
2062 
2063 	return (rval);
2064 }
2065 
2066 /*
2067  * ql_get_loop_position_map
2068  *	Issue get loop position map mailbox command.
2069  *
2070  * Input:
2071  *	ha:	adapter state pointer.
2072  *	size:	size of data buffer.
2073  *	bufp:	data pointer for DMA data.
2074  *
2075  * Returns:
2076  *	ql local function return status code.
2077  *
2078  * Context:
2079  *	Kernel context.
2080  */
2081 int
2082 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2083 {
2084 	int		rval;
2085 	dma_mem_t	mem_desc;
2086 	mbx_cmd_t	mc = {0};
2087 	mbx_cmd_t	*mcp = &mc;
2088 
2089 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2090 
2091 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2092 	    (uint32_t)size)) != QL_SUCCESS) {
2093 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2094 		return (QL_MEMORY_ALLOC_FAILED);
2095 	}
2096 
2097 	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2098 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2099 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2100 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2101 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2102 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2103 	mcp->in_mb = MBX_1|MBX_0;
2104 	mcp->timeout = MAILBOX_TOV;
2105 	rval = ql_mailbox_command(ha, mcp);
2106 
2107 	if (rval == QL_SUCCESS) {
2108 		ql_get_mbox_dma_data(&mem_desc, bufp);
2109 	}
2110 
2111 	ql_free_dma_resource(ha, &mem_desc);
2112 
2113 	if (rval != QL_SUCCESS) {
2114 		EL(ha, "failed=%xh\n", rval);
2115 	} else {
2116 		/*EMPTY*/
2117 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2118 	}
2119 
2120 	return (rval);
2121 }
2122 
2123 /*
2124  * ql_set_rnid_params
2125  *	Issue set RNID parameters mailbox command.
2126  *
2127  * Input:
2128  *	ha:		adapter state pointer.
2129  *	size:		size of data buffer.
2130  *	bufp:		data pointer for DMA data.
2131  *
2132  * Returns:
2133  *	ql local function return status code.
2134  *
2135  * Context:
2136  *	Kernel context.
2137  */
2138 int
2139 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2140 {
2141 	int		rval;
2142 	dma_mem_t	mem_desc;
2143 	mbx_cmd_t	mc = {0};
2144 	mbx_cmd_t	*mcp = &mc;
2145 
2146 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2147 
2148 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2149 	    (uint32_t)size)) != QL_SUCCESS) {
2150 		EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2151 		return (rval);
2152 	}
2153 
2154 	mcp->mb[0] = MBC_SET_PARAMETERS;
2155 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2156 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2157 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2158 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2159 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2160 	mcp->in_mb = MBX_0;
2161 	mcp->timeout = MAILBOX_TOV;
2162 	rval = ql_mailbox_command(ha, mcp);
2163 
2164 	ql_free_dma_resource(ha, &mem_desc);
2165 
2166 	if (rval != QL_SUCCESS) {
2167 		EL(ha, "failed, rval = %xh\n", rval);
2168 	} else {
2169 		/*EMPTY*/
2170 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2171 	}
2172 
2173 	return (rval);
2174 }
2175 
2176 /*
2177  * ql_send_rnid_els
2178  *	Issue a send node identfication data mailbox command.
2179  *
2180  * Input:
2181  *	ha:		adapter state pointer.
2182  *	loop_id:	FC loop id.
2183  *	opt:		options.
2184  *	size:		size of data buffer.
2185  *	bufp:		data pointer for DMA data.
2186  *
2187  * Returns:
2188  *	ql local function return status code.
2189  *
2190  * Context:
2191  *	Kernel context.
2192  */
2193 int
2194 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2195     size_t size, caddr_t bufp)
2196 {
2197 	int		rval;
2198 	dma_mem_t	mem_desc;
2199 	mbx_cmd_t	mc = {0};
2200 	mbx_cmd_t	*mcp = &mc;
2201 
2202 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2203 
2204 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2205 	    (uint32_t)size)) != QL_SUCCESS) {
2206 		return (QL_MEMORY_ALLOC_FAILED);
2207 	}
2208 
2209 	mcp->mb[0] = MBC_SEND_RNID_ELS;
2210 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2211 		mcp->mb[1] = loop_id;
2212 		mcp->mb[9] = ha->vp_index;
2213 		mcp->mb[10] = opt;
2214 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2215 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2216 		mcp->mb[1] = loop_id;
2217 		mcp->mb[10] = opt;
2218 		mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2219 	} else {
2220 		mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2221 		mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2222 	}
2223 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2224 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2225 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2226 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2227 	mcp->in_mb = MBX_0;
2228 	mcp->timeout = MAILBOX_TOV;
2229 	rval = ql_mailbox_command(ha, mcp);
2230 
2231 	if (rval == QL_SUCCESS) {
2232 		ql_get_mbox_dma_data(&mem_desc, bufp);
2233 	}
2234 
2235 	ql_free_dma_resource(ha, &mem_desc);
2236 
2237 	if (rval != QL_SUCCESS) {
2238 		EL(ha, "failed, rval = %xh\n", rval);
2239 	} else {
2240 		/*EMPTY*/
2241 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2242 	}
2243 
2244 	return (rval);
2245 }
2246 
2247 /*
2248  * ql_get_rnid_params
2249  *	Issue get RNID parameters mailbox command.
2250  *
2251  * Input:
2252  *	ha:	adapter state pointer.
2253  *	size:	size of data buffer.
2254  *	bufp:	data pointer for DMA data.
2255  *
2256  * Returns:
2257  *	ql local function return status code.
2258  *
2259  * Context:
2260  *	Kernel context.
2261  */
2262 int
2263 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2264 {
2265 	int		rval;
2266 	dma_mem_t	mem_desc;
2267 	mbx_cmd_t	mc = {0};
2268 	mbx_cmd_t	*mcp = &mc;
2269 
2270 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2271 
2272 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2273 	    (uint32_t)size)) != QL_SUCCESS) {
2274 		return (QL_MEMORY_ALLOC_FAILED);
2275 	}
2276 
2277 	mcp->mb[0] = MBC_GET_PARAMETERS;
2278 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2279 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2280 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2281 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2282 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2283 	mcp->in_mb = MBX_0;
2284 	mcp->timeout = MAILBOX_TOV;
2285 	rval = ql_mailbox_command(ha, mcp);
2286 
2287 	if (rval == QL_SUCCESS) {
2288 		ql_get_mbox_dma_data(&mem_desc, bufp);
2289 	}
2290 
2291 	ql_free_dma_resource(ha, &mem_desc);
2292 
2293 	if (rval != QL_SUCCESS) {
2294 		EL(ha, "failed=%xh\n", rval);
2295 	} else {
2296 		/*EMPTY*/
2297 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2298 	}
2299 
2300 	return (rval);
2301 }
2302 
2303 /*
2304  * ql_get_link_status
2305  *	Issue get link status mailbox command.
2306  *
2307  * Input:
2308  *	ha:		adapter state pointer.
2309  *	loop_id:	FC loop id or n_port_hdl.
2310  *	size:		size of data buffer.
2311  *	bufp:		data pointer for DMA data.
2312  *	port_no:	port number to query.
2313  *
2314  * Returns:
2315  *	ql local function return status code.
2316  *
2317  * Context:
2318  *	Kernel context.
2319  */
2320 int
2321 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2322     caddr_t bufp, uint8_t port_no)
2323 {
2324 	dma_mem_t	mem_desc;
2325 	mbx_cmd_t	mc = {0};
2326 	mbx_cmd_t	*mcp = &mc;
2327 	int		rval = QL_SUCCESS;
2328 	int		retry = 0;
2329 
2330 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2331 
2332 	do {
2333 		if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2334 		    (uint32_t)size)) != QL_SUCCESS) {
2335 			EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2336 			return (QL_MEMORY_ALLOC_FAILED);
2337 		}
2338 
2339 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2340 		if (CFG_IST(ha, CFG_CTRL_24258081)) {
2341 			if (loop_id == ha->loop_id) {
2342 				mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2343 				mcp->mb[8] = (uint16_t)(size >> 2);
2344 				mcp->out_mb = MBX_10|MBX_8;
2345 			} else {
2346 				mcp->mb[1] = loop_id;
2347 				mcp->mb[4] = port_no;
2348 				mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2349 				mcp->out_mb = MBX_10|MBX_4;
2350 			}
2351 		} else {
2352 			if (retry) {
2353 				port_no = (uint8_t)(port_no | BIT_3);
2354 			}
2355 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2356 				mcp->mb[1] = loop_id;
2357 				mcp->mb[10] = port_no;
2358 				mcp->out_mb = MBX_10;
2359 			} else {
2360 				mcp->mb[1] = (uint16_t)((loop_id << 8) |
2361 				    port_no);
2362 				mcp->out_mb = 0;
2363 			}
2364 		}
2365 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2366 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2367 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2368 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2369 		mcp->in_mb = MBX_1|MBX_0;
2370 		mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2371 		mcp->timeout = MAILBOX_TOV;
2372 
2373 		rval = ql_mailbox_command(ha, mcp);
2374 
2375 		if (rval == QL_SUCCESS) {
2376 			ql_get_mbox_dma_data(&mem_desc, bufp);
2377 		}
2378 
2379 		ql_free_dma_resource(ha, &mem_desc);
2380 
2381 		if (rval != QL_SUCCESS) {
2382 			EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2383 		}
2384 
2385 		/*
2386 		 * Some of the devices want d_id in the payload,
2387 		 * strictly as per standard. Let's retry.
2388 		 */
2389 
2390 	} while (rval == QL_COMMAND_ERROR && !retry++);
2391 
2392 	if (rval != QL_SUCCESS) {
2393 		EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2394 	} else {
2395 		/*EMPTY*/
2396 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2397 	}
2398 
2399 	return (rval);
2400 }
2401 
2402 /*
2403  * ql_get_status_counts
2404  *	Issue get adapter link status counts mailbox command.
2405  *
2406  * Input:
2407  *	ha:		adapter state pointer.
2408  *	loop_id:	FC loop id or n_port_hdl.
2409  *	size:		size of data buffer.
2410  *	bufp:		data pointer for DMA data.
2411  *	port_no:	port number to query.
2412  *
2413  * Returns:
2414  *	ql local function return status code.
2415  *
2416  * Context:
2417  *	Kernel context.
2418  */
2419 int
2420 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2421     caddr_t bufp, uint8_t port_no)
2422 {
2423 	dma_mem_t	mem_desc;
2424 	mbx_cmd_t	mc = {0};
2425 	mbx_cmd_t	*mcp = &mc;
2426 	int		rval = QL_SUCCESS;
2427 
2428 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2429 
2430 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2431 	    (uint32_t)size)) != QL_SUCCESS) {
2432 		EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2433 		return (QL_MEMORY_ALLOC_FAILED);
2434 	}
2435 
2436 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2437 		mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2438 		mcp->mb[8] = (uint16_t)(size / 4);
2439 		mcp->out_mb = MBX_10|MBX_8;
2440 	} else {
2441 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2442 
2443 		/* allows reporting when link is down */
2444 		if (CFG_IST(ha, CFG_CTRL_2200) == 0) {
2445 			port_no = (uint8_t)(port_no | BIT_6);
2446 		}
2447 
2448 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2449 			mcp->mb[1] = loop_id;
2450 			mcp->mb[10] = port_no;
2451 			mcp->out_mb = MBX_10|MBX_1;
2452 		} else {
2453 			mcp->mb[1] = (uint16_t)((loop_id << 8) |
2454 			    port_no);
2455 			mcp->out_mb = MBX_1;
2456 		}
2457 	}
2458 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2459 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2460 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2461 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2462 	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2463 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2464 	mcp->timeout = MAILBOX_TOV;
2465 	rval = ql_mailbox_command(ha, mcp);
2466 
2467 	if (rval == QL_SUCCESS) {
2468 		ql_get_mbox_dma_data(&mem_desc, bufp);
2469 	}
2470 
2471 	ql_free_dma_resource(ha, &mem_desc);
2472 
2473 	if (rval != QL_SUCCESS) {
2474 		EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2475 		    mcp->mb[1], mcp->mb[2]);
2476 	} else {
2477 		/*EMPTY*/
2478 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2479 	}
2480 
2481 	return (rval);
2482 }
2483 
2484 /*
2485  * ql_reset_link_status
2486  *	Issue Reset Link Error Status mailbox command
2487  *
2488  * Input:
2489  *	ha:	adapter state pointer.
2490  *
2491  * Returns:
2492  *	ql local function return status code.
2493  *
2494  * Context:
2495  *	Kernel context.
2496  */
2497 int
2498 ql_reset_link_status(ql_adapter_state_t *ha)
2499 {
2500 	int		rval;
2501 	mbx_cmd_t	mc = {0};
2502 	mbx_cmd_t	*mcp = &mc;
2503 
2504 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2505 
2506 	mcp->mb[0] = MBC_RESET_LINK_STATUS;
2507 	mcp->out_mb = MBX_0;
2508 	mcp->in_mb = MBX_0;
2509 	mcp->timeout = MAILBOX_TOV;
2510 	rval = ql_mailbox_command(ha, mcp);
2511 
2512 	if (rval != QL_SUCCESS) {
2513 		EL(ha, "failed=%xh\n", rval);
2514 	} else {
2515 		/*EMPTY*/
2516 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2517 	}
2518 
2519 	return (rval);
2520 }
2521 
2522 /*
2523  * ql_loop_reset
2524  *	Issue loop reset.
2525  *
2526  * Input:
2527  *	ha:	adapter state pointer.
2528  *
2529  * Returns:
2530  *	ql local function return status code.
2531  *
2532  * Context:
2533  *	Kernel context.
2534  */
2535 int
2536 ql_loop_reset(ql_adapter_state_t *ha)
2537 {
2538 	int	rval;
2539 
2540 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2541 
2542 	if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2543 		rval = ql_lip_reset(ha, 0xff);
2544 	} else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2545 		rval = ql_full_login_lip(ha);
2546 	} else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2547 		rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2548 	} else {
2549 		rval = ql_initiate_lip(ha);
2550 	}
2551 
2552 	if (rval != QL_SUCCESS) {
2553 		EL(ha, "failed, rval = %xh\n", rval);
2554 	} else {
2555 		/*EMPTY*/
2556 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2557 	}
2558 
2559 	return (rval);
2560 }
2561 
2562 /*
2563  * ql_initiate_lip
2564  *	Initiate LIP mailbox command.
2565  *
2566  * Input:
2567  *	ha:	adapter state pointer.
2568  *
2569  * Returns:
2570  *	ql local function return status code.
2571  *
2572  * Context:
2573  *	Kernel context.
2574  */
2575 int
2576 ql_initiate_lip(ql_adapter_state_t *ha)
2577 {
2578 	int		rval;
2579 	mbx_cmd_t	mc = {0};
2580 	mbx_cmd_t	*mcp = &mc;
2581 
2582 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2583 
2584 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2585 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2586 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2587 		    BIT_1 : BIT_4);
2588 		mcp->mb[3] = ha->loop_reset_delay;
2589 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2590 	} else {
2591 		mcp->mb[0] = MBC_INITIATE_LIP;
2592 		mcp->out_mb = MBX_0;
2593 	}
2594 	mcp->in_mb = MBX_0;
2595 	mcp->timeout = MAILBOX_TOV;
2596 	rval = ql_mailbox_command(ha, mcp);
2597 
2598 	if (rval != QL_SUCCESS) {
2599 		EL(ha, "failed, rval = %xh\n", rval);
2600 	} else {
2601 		/*EMPTY*/
2602 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2603 	}
2604 
2605 	return (rval);
2606 }
2607 
2608 /*
2609  * ql_full_login_lip
2610  *	Issue full login LIP mailbox command.
2611  *
2612  * Input:
2613  *	ha:	adapter state pointer.
2614  *
2615  * Returns:
2616  *	ql local function return status code.
2617  *
2618  * Context:
2619  *	Kernel context.
2620  */
2621 int
2622 ql_full_login_lip(ql_adapter_state_t *ha)
2623 {
2624 	int		rval;
2625 	mbx_cmd_t	mc = {0};
2626 	mbx_cmd_t	*mcp = &mc;
2627 
2628 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2629 
2630 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2631 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2632 		mcp->mb[1] = BIT_3;
2633 	} else if (CFG_IST(ha, CFG_CTRL_8081)) {
2634 		mcp->mb[1] = BIT_1;
2635 	}
2636 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2637 	mcp->in_mb = MBX_0;
2638 	mcp->timeout = MAILBOX_TOV;
2639 	rval = ql_mailbox_command(ha, mcp);
2640 
2641 	if (rval != QL_SUCCESS) {
2642 		EL(ha, "failed, rval = %xh\n", rval);
2643 	} else {
2644 		/*EMPTY*/
2645 		QL_PRINT_3(CE_CONT, "(%d): done", ha->instance);
2646 	}
2647 
2648 	return (rval);
2649 }
2650 
2651 /*
2652  * ql_lip_reset
2653  *	Issue lip reset to a port.
2654  *
2655  * Input:
2656  *	ha:		adapter state pointer.
2657  *	loop_id:	FC loop id.
2658  *
2659  * Returns:
2660  *	ql local function return status code.
2661  *
2662  * Context:
2663  *	Kernel context.
2664  */
2665 int
2666 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2667 {
2668 	int		rval;
2669 	mbx_cmd_t	mc = {0};
2670 	mbx_cmd_t	*mcp = &mc;
2671 
2672 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2673 
2674 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2675 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2676 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2677 		    BIT_1 : BIT_6);
2678 		mcp->mb[3] = ha->loop_reset_delay;
2679 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2680 	} else {
2681 		mcp->mb[0] = MBC_LIP_RESET;
2682 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2683 			mcp->mb[1] = loop_id;
2684 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2685 		} else {
2686 			mcp->mb[1] = (uint16_t)(loop_id << 8);
2687 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2688 		}
2689 		mcp->mb[2] = ha->loop_reset_delay;
2690 	}
2691 	mcp->in_mb = MBX_0;
2692 	mcp->timeout = MAILBOX_TOV;
2693 	rval = ql_mailbox_command(ha, mcp);
2694 
2695 	if (rval != QL_SUCCESS) {
2696 		EL(ha, "failed, rval = %xh\n", rval);
2697 	} else {
2698 		/*EMPTY*/
2699 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2700 	}
2701 
2702 	return (rval);
2703 }
2704 
2705 /*
2706  * ql_abort_command
2707  *	Abort command aborts a specified IOCB.
2708  *
2709  * Input:
2710  *	ha:	adapter state pointer.
2711  *	sp:	SRB structure pointer.
2712  *
2713  * Returns:
2714  *	ql local function return status code.
2715  *
2716  * Context:
2717  *	Kernel context.
2718  */
2719 int
2720 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2721 {
2722 	int		rval;
2723 	mbx_cmd_t	mc = {0};
2724 	mbx_cmd_t	*mcp = &mc;
2725 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2726 
2727 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2728 
2729 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2730 		rval = ql_abort_cmd_iocb(ha, sp);
2731 	} else {
2732 		mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2733 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2734 			mcp->mb[1] = tq->loop_id;
2735 		} else {
2736 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2737 		}
2738 		mcp->mb[2] = LSW(sp->handle);
2739 		mcp->mb[3] = MSW(sp->handle);
2740 		mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2741 		    sp->lun_queue->lun_no : 0);
2742 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2743 		mcp->in_mb = MBX_0;
2744 		mcp->timeout = MAILBOX_TOV;
2745 		rval = ql_mailbox_command(ha, mcp);
2746 	}
2747 
2748 	if (rval != QL_SUCCESS) {
2749 		EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2750 		    tq->d_id.b24, sp->handle);
2751 	} else {
2752 		/*EMPTY*/
2753 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2754 	}
2755 
2756 	return (rval);
2757 }
2758 
2759 /*
2760  * ql_abort_cmd_iocb
2761  *	Function issues abort command IOCB.
2762  *
2763  * Input:
2764  *	ha:	adapter state pointer.
2765  *	sp:	SRB structure pointer.
2766  *
2767  * Returns:
2768  *	ql local function return status code.
2769  *
2770  * Context:
2771  *	Interrupt or Kernel context, no mailbox commands allowed.
2772  */
2773 static int
2774 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2775 {
2776 	ql_mbx_iocb_t	*pkt;
2777 	int		rval;
2778 	uint32_t	pkt_size;
2779 	uint16_t	comp_status;
2780 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2781 
2782 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2783 
2784 	pkt_size = sizeof (ql_mbx_iocb_t);
2785 	if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2786 		EL(ha, "failed, kmem_zalloc\n");
2787 		return (QL_MEMORY_ALLOC_FAILED);
2788 	}
2789 
2790 	pkt->abo.entry_type = ABORT_CMD_TYPE;
2791 	pkt->abo.entry_count = 1;
2792 	pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2793 	pkt->abo.options = AF_NO_ABTS;
2794 	pkt->abo.cmd_handle = LE_32(sp->handle);
2795 	pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2796 	pkt->abo.target_id[1] = tq->d_id.b.area;
2797 	pkt->abo.target_id[2] = tq->d_id.b.domain;
2798 	pkt->abo.vp_index = ha->vp_index;
2799 
2800 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2801 
2802 	if (rval == QL_SUCCESS && (pkt->abo.entry_status  & 0x3c) != 0) {
2803 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2804 		    pkt->abo.entry_status, tq->d_id.b24);
2805 		rval = QL_FUNCTION_PARAMETER_ERROR;
2806 	}
2807 
2808 	comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2809 	if (rval == QL_SUCCESS && comp_status != CS_COMPLETE) {
2810 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2811 		    comp_status, tq->d_id.b24);
2812 		rval = QL_FUNCTION_FAILED;
2813 	}
2814 
2815 	kmem_free(pkt, pkt_size);
2816 
2817 	if (rval != QL_SUCCESS) {
2818 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2819 	} else {
2820 		/*EMPTY*/
2821 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2822 	}
2823 
2824 	return (rval);
2825 }
2826 
2827 /*
2828  * ql_verify_checksum
2829  *	Verify loaded RISC firmware.
2830  *
2831  * Input:
2832  *	ha = adapter state pointer.
2833  *
2834  * Returns:
2835  *	ql local function return status code.
2836  *
2837  * Context:
2838  *	Kernel context.
2839  */
2840 int
2841 ql_verify_checksum(ql_adapter_state_t *ha)
2842 {
2843 	int		rval;
2844 	mbx_cmd_t	mc = {0};
2845 	mbx_cmd_t	*mcp = &mc;
2846 
2847 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2848 
2849 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2850 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2851 		mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2852 		mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2853 	} else {
2854 		mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2855 	}
2856 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
2857 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2858 	mcp->timeout = MAILBOX_TOV;
2859 	rval = ql_mailbox_command(ha, mcp);
2860 
2861 	if (rval != QL_SUCCESS) {
2862 		EL(ha, "failed, rval = %xh\n", rval);
2863 	} else {
2864 		/*EMPTY*/
2865 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2866 	}
2867 
2868 	return (rval);
2869 }
2870 
2871 /*
2872  * ql_get_id_list
2873  *	Get d_id and loop ID list.
2874  *
2875  * Input:
2876  *	ha:	adapter state pointer.
2877  *	bp:	data pointer for DMA data.
2878  *	size:	size of data buffer.
2879  *	mr:	pointer for mailbox data.
2880  *
2881  * Returns:
2882  *	ql local function return status code.
2883  *
2884  * Context:
2885  *	Kernel context.
2886  */
2887 int
2888 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2889     ql_mbx_data_t *mr)
2890 {
2891 	int		rval;
2892 	dma_mem_t	mem_desc;
2893 	mbx_cmd_t	mc = {0};
2894 	mbx_cmd_t	*mcp = &mc;
2895 
2896 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2897 
2898 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2899 	    (uint32_t)size)) != QL_SUCCESS) {
2900 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2901 		return (QL_MEMORY_ALLOC_FAILED);
2902 	}
2903 
2904 	mcp->mb[0] = MBC_GET_ID_LIST;
2905 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2906 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2907 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2908 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2909 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2910 		mcp->mb[8] = (uint16_t)size;
2911 		mcp->mb[9] = ha->vp_index;
2912 		mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2913 	} else {
2914 		mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2915 		mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2916 		mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2917 		mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2918 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2919 	}
2920 	mcp->in_mb = MBX_1|MBX_0;
2921 	mcp->timeout = MAILBOX_TOV;
2922 	rval = ql_mailbox_command(ha, mcp);
2923 
2924 	if (rval == QL_SUCCESS) {
2925 		ql_get_mbox_dma_data(&mem_desc, bp);
2926 	}
2927 
2928 	ql_free_dma_resource(ha, &mem_desc);
2929 
2930 	/* Return mailbox data. */
2931 	if (mr != NULL) {
2932 		mr->mb[0] = mcp->mb[0];
2933 		mr->mb[1] = mcp->mb[1];
2934 	}
2935 
2936 	if (rval != QL_SUCCESS) {
2937 		EL(ha, "failed, rval = %xh\n", rval);
2938 	} else {
2939 		/*EMPTY*/
2940 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2941 	}
2942 
2943 	return (rval);
2944 }
2945 
2946 /*
2947  * ql_wrt_risc_ram
2948  *	Load RISC RAM.
2949  *
2950  * Input:
2951  *	ha:		adapter state pointer.
2952  *	risc_address:	risc ram word address.
2953  *	bp:		DMA pointer.
2954  *	word_count:	16/32bit word count.
2955  *
2956  * Returns:
2957  *	ql local function return status code.
2958  *
2959  * Context:
2960  *	Kernel context.
2961  */
2962 int
2963 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2964     uint32_t word_count)
2965 {
2966 	int		rval;
2967 	mbx_cmd_t	mc = {0};
2968 	mbx_cmd_t	*mcp = &mc;
2969 
2970 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2971 
2972 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2973 		mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
2974 		mcp->mb[4] = MSW(word_count);
2975 		mcp->mb[5] = LSW(word_count);
2976 		mcp->mb[6] = MSW(MSD(bp));
2977 		mcp->mb[7] = LSW(MSD(bp));
2978 		mcp->mb[8] = MSW(risc_address);
2979 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2980 		    MBX_0;
2981 	} else {
2982 		mcp->mb[0] = MBC_LOAD_RAM;
2983 		mcp->mb[4] = LSW(word_count);
2984 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2985 	}
2986 	mcp->mb[1] = LSW(risc_address);
2987 	mcp->mb[2] = MSW(LSD(bp));
2988 	mcp->mb[3] = LSW(LSD(bp));
2989 	mcp->in_mb = MBX_0;
2990 	mcp->timeout = MAILBOX_TOV;
2991 
2992 	rval = ql_mailbox_command(ha, mcp);
2993 
2994 	if (rval != QL_SUCCESS) {
2995 		EL(ha, "failed, rval = %xh\n", rval);
2996 	} else {
2997 		/*EMPTY*/
2998 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2999 	}
3000 
3001 	return (rval);
3002 }
3003 
3004 /*
3005  * ql_rd_risc_ram
3006  *	Get RISC RAM.
3007  *
3008  * Input:
3009  *	ha:		adapter state pointer.
3010  *	risc_address:	risc ram word address.
3011  *	bp:		direct data pointer.
3012  *	word_count:	16/32bit word count.
3013  *
3014  * Returns:
3015  *	ql local function return status code.
3016  *
3017  * Context:
3018  *	Kernel context.
3019  */
3020 int
3021 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
3022     uint32_t word_count)
3023 {
3024 	int		rval;
3025 	mbx_cmd_t	mc = {0};
3026 	mbx_cmd_t	*mcp = &mc;
3027 
3028 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3029 
3030 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
3031 		mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
3032 		mcp->mb[1] = LSW(risc_address);
3033 		mcp->mb[2] = MSW(LSD(bp));
3034 		mcp->mb[3] = LSW(LSD(bp));
3035 		mcp->mb[4] = MSW(word_count);
3036 		mcp->mb[5] = LSW(word_count);
3037 		mcp->mb[6] = MSW(MSD(bp));
3038 		mcp->mb[7] = LSW(MSD(bp));
3039 		mcp->mb[8] = MSW(risc_address);
3040 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
3041 		    MBX_0;
3042 	} else {
3043 		mcp->mb[0] = MBC_DUMP_RAM;	/* doesn't support 64bit addr */
3044 		mcp->mb[1] = LSW(risc_address);
3045 		mcp->mb[2] = MSW(LSD(bp));
3046 		mcp->mb[3] = LSW(LSD(bp));
3047 		mcp->mb[4] = LSW(word_count);
3048 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3049 	}
3050 	mcp->in_mb = MBX_0;
3051 	mcp->timeout = MAILBOX_TOV;
3052 	rval = ql_mailbox_command(ha, mcp);
3053 
3054 	if (rval != QL_SUCCESS) {
3055 		EL(ha, "failed, rval = %xh\n", rval);
3056 	} else {
3057 		/*EMPTY*/
3058 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3059 	}
3060 
3061 	return (rval);
3062 }
3063 
3064 /*
3065  * ql_wrt_risc_ram_word
3066  *	Write RISC RAM word.
3067  *
3068  * Input:
3069  *	ha:		adapter state pointer.
3070  *	risc_address:	risc ram word address.
3071  *	data:		data.
3072  *
3073  * Returns:
3074  *	ql local function return status code.
3075  *
3076  * Context:
3077  *	Kernel context.
3078  */
3079 int
3080 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3081     uint32_t data)
3082 {
3083