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