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 		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 
962 					if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
963 						rval = ql_task_mgmt_iocb(ha,
964 						    tq, 0, CF_DO_NOT_SEND |
965 						    CF_TARGET_RESET, delay);
966 					} else {
967 						rval = ql_task_mgmt_iocb(ha,
968 						    tq, 0, CF_TARGET_RESET,
969 						    delay);
970 					}
971 
972 					if (rval != QL_SUCCESS) {
973 						break;
974 					}
975 				}
976 
977 				if (link != NULL) {
978 					break;
979 				}
980 			}
981 			tq = NULL;
982 		} else {
983 
984 			if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
985 				rval = ql_task_mgmt_iocb(ha, tq, 0,
986 				    CF_TARGET_RESET | CF_DO_NOT_SEND, delay);
987 			} else {
988 				rval = ql_task_mgmt_iocb(ha, tq, 0,
989 				    CF_TARGET_RESET, delay);
990 			}
991 		}
992 	} else {
993 		/* queue = NULL, all targets. */
994 		if (tq == NULL) {
995 			mcp->mb[0] = MBC_RESET;
996 			mcp->mb[1] = delay;
997 			mcp->out_mb = MBX_1|MBX_0;
998 		} else {
999 			mcp->mb[0] = MBC_TARGET_RESET;
1000 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1001 				mcp->mb[1] = tq->loop_id;
1002 			} else {
1003 				mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1004 			}
1005 			mcp->mb[2] = delay;
1006 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1007 		}
1008 		mcp->in_mb = MBX_0;
1009 		mcp->timeout = MAILBOX_TOV;
1010 		rval = ql_mailbox_command(ha, mcp);
1011 	}
1012 
1013 	tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1014 	    (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1015 
1016 	if (rval != QL_SUCCESS) {
1017 		EL(ha, "failed, rval = %xh\n", rval);
1018 	} else {
1019 		/*EMPTY*/
1020 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1021 	}
1022 
1023 	return (rval);
1024 }
1025 
1026 /*
1027  * ql_abort_target
1028  *	Issue abort target mailbox command.
1029  *
1030  * Input:
1031  *	ha:	adapter state pointer.
1032  *	tq:	target queue pointer.
1033  *	delay:	in seconds.
1034  *
1035  * Returns:
1036  *	ql local function return status code.
1037  *
1038  * Context:
1039  *	Kernel context.
1040  */
1041 int
1042 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1043 {
1044 	int		rval;
1045 	mbx_cmd_t	mc = {0};
1046 	mbx_cmd_t	*mcp = &mc;
1047 
1048 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1049 
1050 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1051 		rval = ql_task_mgmt_iocb(ha, tq, 0,
1052 		    CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1053 	} else {
1054 		mcp->mb[0] = MBC_ABORT_TARGET;
1055 		/* Don't send Task Mgt */
1056 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1057 			mcp->mb[1] = tq->loop_id;
1058 			mcp->mb[10] = BIT_0;
1059 			mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1060 		} else {
1061 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1062 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1063 		}
1064 		mcp->mb[2] = delay;
1065 		mcp->in_mb = MBX_0;
1066 		mcp->timeout = MAILBOX_TOV;
1067 		rval = ql_mailbox_command(ha, mcp);
1068 	}
1069 
1070 	(void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1071 
1072 	if (rval != QL_SUCCESS) {
1073 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1074 	} else {
1075 		/*EMPTY*/
1076 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1077 	}
1078 	return (rval);
1079 }
1080 
1081 /*
1082  * ql_lun_reset
1083  *	Issue LUN reset task management mailbox command.
1084  *
1085  * Input:
1086  *	ha:	adapter state pointer.
1087  *	tq:	target queue pointer.
1088  *	lun:	LUN.
1089  *
1090  * Returns:
1091  *	ql local function return status code.
1092  *
1093  * Context:
1094  *	Kernel context.
1095  */
1096 int
1097 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1098 {
1099 	int		rval;
1100 	mbx_cmd_t	mc = {0};
1101 	mbx_cmd_t	*mcp = &mc;
1102 
1103 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1104 
1105 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1106 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_LUN_RESET, 0);
1107 	} else {
1108 		mcp->mb[0] = MBC_LUN_RESET;
1109 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1110 			mcp->mb[1] = tq->loop_id;
1111 		} else {
1112 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1113 		}
1114 		mcp->mb[2] = lun;
1115 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1116 		mcp->in_mb = MBX_0;
1117 		mcp->timeout = MAILBOX_TOV;
1118 		rval = ql_mailbox_command(ha, mcp);
1119 	}
1120 
1121 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1122 
1123 	if (rval != QL_SUCCESS) {
1124 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1125 	} else {
1126 		/*EMPTY*/
1127 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1128 	}
1129 	return (rval);
1130 }
1131 
1132 /*
1133  * ql_clear_task_set
1134  *	Issue clear task set mailbox command.
1135  *
1136  * Input:
1137  *	ha:	adapter state pointer.
1138  *	tq:	target queue pointer.
1139  *	lun:	LUN.
1140  *
1141  * Returns:
1142  *	ql local function return status code.
1143  *
1144  * Context:
1145  *	Kernel context.
1146  */
1147 int
1148 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1149 {
1150 	int		rval;
1151 	mbx_cmd_t	mc = {0};
1152 	mbx_cmd_t	*mcp = &mc;
1153 
1154 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1155 
1156 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1157 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0);
1158 	} else {
1159 		mcp->mb[0] = MBC_CLEAR_TASK_SET;
1160 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1161 			mcp->mb[1] = tq->loop_id;
1162 		} else {
1163 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1164 		}
1165 		mcp->mb[2] = lun;
1166 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
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, lun, 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 
1181 	return (rval);
1182 }
1183 
1184 /*
1185  * ql_abort_task_set
1186  *	Issue abort task set mailbox command.
1187  *
1188  * Input:
1189  *	ha:	adapter state pointer.
1190  *	tq:	target queue pointer.
1191  *	lun:	LUN.
1192  *
1193  * Returns:
1194  *	ql local function return status code.
1195  *
1196  * Context:
1197  *	Kernel context.
1198  */
1199 int
1200 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1201 {
1202 	int		rval;
1203 	mbx_cmd_t	mc = {0};
1204 	mbx_cmd_t	*mcp = &mc;
1205 
1206 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1207 
1208 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1209 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0);
1210 	} else {
1211 		mcp->mb[0] = MBC_ABORT_TASK_SET;
1212 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1213 			mcp->mb[1] = tq->loop_id;
1214 		} else {
1215 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1216 		}
1217 		mcp->mb[2] = lun;
1218 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1219 		mcp->in_mb = MBX_0;
1220 		mcp->timeout = MAILBOX_TOV;
1221 		rval = ql_mailbox_command(ha, mcp);
1222 	}
1223 
1224 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1225 
1226 	if (rval != QL_SUCCESS) {
1227 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1228 	} else {
1229 		/*EMPTY*/
1230 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1231 	}
1232 
1233 	return (rval);
1234 }
1235 
1236 /*
1237  * ql_task_mgmt_iocb
1238  *	Function issues task management IOCB.
1239  *
1240  * Input:
1241  *	ha:	adapter state pointer.
1242  *	tq:	target queue pointer.
1243  *	lun:	LUN.
1244  *	flags:	control flags.
1245  *	delay:	seconds.
1246  *
1247  * Returns:
1248  *	ql local function return status code.
1249  *
1250  * Context:
1251  *	Kernel context
1252  */
1253 static int
1254 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun,
1255     uint32_t flags, uint16_t delay)
1256 {
1257 	ql_mbx_iocb_t	*pkt;
1258 	int		rval;
1259 	uint32_t	pkt_size;
1260 
1261 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1262 
1263 	pkt_size = sizeof (ql_mbx_iocb_t);
1264 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1265 	if (pkt == NULL) {
1266 		EL(ha, "failed, kmem_zalloc\n");
1267 		return (QL_MEMORY_ALLOC_FAILED);
1268 	}
1269 
1270 	pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1271 	pkt->mgmt.entry_count = 1;
1272 
1273 	pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1274 	pkt->mgmt.delay = (uint16_t)LE_16(delay);
1275 	pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1276 	pkt->mgmt.fcp_lun[2] = LSB(lun);
1277 	pkt->mgmt.fcp_lun[3] = MSB(lun);
1278 	pkt->mgmt.control_flags = LE_32(flags);
1279 	pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1280 	pkt->mgmt.target_id[1] = tq->d_id.b.area;
1281 	pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1282 	pkt->mgmt.vp_index = ha->vp_index;
1283 
1284 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1285 	if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1286 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1287 		    pkt->sts24.entry_status, tq->d_id.b24);
1288 		rval = QL_FUNCTION_PARAMETER_ERROR;
1289 	}
1290 
1291 	LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1292 
1293 	if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1294 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1295 		    pkt->sts24.comp_status, tq->d_id.b24);
1296 		rval = QL_FUNCTION_FAILED;
1297 	}
1298 
1299 	kmem_free(pkt, pkt_size);
1300 
1301 	if (rval != QL_SUCCESS) {
1302 		EL(ha, "failed, rval = %xh\n", rval);
1303 	} else {
1304 		/*EMPTY*/
1305 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1306 	}
1307 
1308 	return (rval);
1309 }
1310 
1311 /*
1312  * ql_loop_port_bypass
1313  *	Issue loop port bypass mailbox command.
1314  *
1315  * Input:
1316  *	ha:	adapter state pointer.
1317  *	tq:	target queue pointer.
1318  *
1319  * Returns:
1320  *	ql local function return status code.
1321  *
1322  * Context:
1323  *	Kernel context.
1324  */
1325 int
1326 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1327 {
1328 	int		rval;
1329 	mbx_cmd_t	mc = {0};
1330 	mbx_cmd_t	*mcp = &mc;
1331 
1332 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1333 
1334 	mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1335 
1336 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1337 		mcp->mb[1] = tq->d_id.b.al_pa;
1338 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1339 		mcp->mb[1] = tq->loop_id;
1340 	} else {
1341 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1342 	}
1343 
1344 	mcp->out_mb = MBX_1|MBX_0;
1345 	mcp->in_mb = MBX_0;
1346 	mcp->timeout = MAILBOX_TOV;
1347 	rval = ql_mailbox_command(ha, mcp);
1348 
1349 	if (rval != QL_SUCCESS) {
1350 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1351 	} else {
1352 		/*EMPTY*/
1353 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1354 	}
1355 
1356 	return (rval);
1357 }
1358 
1359 /*
1360  * ql_loop_port_enable
1361  *	Issue loop port enable mailbox command.
1362  *
1363  * Input:
1364  *	ha:	adapter state pointer.
1365  *	tq:	target queue pointer.
1366  *
1367  * Returns:
1368  *	ql local function return status code.
1369  *
1370  * Context:
1371  *	Kernel context.
1372  */
1373 int
1374 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1375 {
1376 	int		rval;
1377 	mbx_cmd_t	mc = {0};
1378 	mbx_cmd_t	*mcp = &mc;
1379 
1380 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1381 
1382 	mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1383 
1384 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1385 		mcp->mb[1] = tq->d_id.b.al_pa;
1386 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1387 		mcp->mb[1] = tq->loop_id;
1388 	} else {
1389 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1390 	}
1391 	mcp->out_mb = MBX_1|MBX_0;
1392 	mcp->in_mb = MBX_0;
1393 	mcp->timeout = MAILBOX_TOV;
1394 	rval = ql_mailbox_command(ha, mcp);
1395 
1396 	if (rval != QL_SUCCESS) {
1397 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1398 	} else {
1399 		/*EMPTY*/
1400 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1401 	}
1402 
1403 	return (rval);
1404 }
1405 
1406 /*
1407  * ql_login_lport
1408  *	Issue login loop port mailbox command.
1409  *
1410  * Input:
1411  *	ha:		adapter state pointer.
1412  *	tq:		target queue pointer.
1413  *	loop_id:	FC loop id.
1414  *	opt:		options.
1415  *			LLF_NONE, LLF_PLOGI
1416  *
1417  * Returns:
1418  *	ql local function return status code.
1419  *
1420  * Context:
1421  *	Kernel context.
1422  */
1423 int
1424 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1425     uint16_t opt)
1426 {
1427 	int		rval;
1428 	uint16_t	flags;
1429 	ql_mbx_data_t	mr;
1430 	mbx_cmd_t	mc = {0};
1431 	mbx_cmd_t	*mcp = &mc;
1432 
1433 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1434 	    ha->instance, tq->d_id.b24, loop_id);
1435 
1436 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1437 		flags = CF_CMD_PLOGI;
1438 		if ((opt & LLF_PLOGI) == 0) {
1439 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1440 		}
1441 		rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1442 	} else {
1443 		mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1444 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1445 			mcp->mb[1] = loop_id;
1446 		} else {
1447 			mcp->mb[1] = (uint16_t)(loop_id << 8);
1448 		}
1449 		mcp->mb[2] = opt;
1450 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1451 		mcp->in_mb = MBX_0;
1452 		mcp->timeout = MAILBOX_TOV;
1453 		rval = ql_mailbox_command(ha, mcp);
1454 	}
1455 
1456 	if (rval != QL_SUCCESS) {
1457 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1458 		    loop_id, rval);
1459 	} else {
1460 		/*EMPTY*/
1461 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1462 	}
1463 
1464 	return (rval);
1465 }
1466 
1467 /*
1468  * ql_login_fport
1469  *	Issue login fabric port mailbox command.
1470  *
1471  * Input:
1472  *	ha:		adapter state pointer.
1473  *	tq:		target queue pointer.
1474  *	loop_id:	FC loop id.
1475  *	opt:		options.
1476  *			LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1477  *	mr:		pointer for mailbox data.
1478  *
1479  * Returns:
1480  *	ql local function return status code.
1481  *
1482  * Context:
1483  *	Kernel context.
1484  */
1485 int
1486 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1487     uint16_t opt, ql_mbx_data_t *mr)
1488 {
1489 	int		rval;
1490 	uint16_t	flags;
1491 	mbx_cmd_t	mc = {0};
1492 	mbx_cmd_t	*mcp = &mc;
1493 
1494 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1495 	    ha->instance, tq->d_id.b24, loop_id);
1496 
1497 	if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) {
1498 		opt = (uint16_t)(opt | LFF_NO_PRLI);
1499 	}
1500 
1501 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1502 		flags = CF_CMD_PLOGI;
1503 		if (opt & LFF_NO_PLOGI) {
1504 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1505 		}
1506 		if (opt & LFF_NO_PRLI) {
1507 			flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1508 		}
1509 		rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1510 	} else {
1511 		mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1512 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1513 			mcp->mb[1] = loop_id;
1514 			mcp->mb[10] = opt;
1515 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1516 		} else {
1517 			mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1518 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1519 		}
1520 		mcp->mb[2] = MSW(tq->d_id.b24);
1521 		mcp->mb[3] = LSW(tq->d_id.b24);
1522 		mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1523 		mcp->timeout = MAILBOX_TOV;
1524 		rval = ql_mailbox_command(ha, mcp);
1525 
1526 		/* Return mailbox data. */
1527 		if (mr != NULL) {
1528 			mr->mb[0] = mcp->mb[0];
1529 			mr->mb[1] = mcp->mb[1];
1530 			mr->mb[2] = mcp->mb[2];
1531 			mr->mb[6] = mcp->mb[6];
1532 			mr->mb[7] = mcp->mb[7];
1533 		}
1534 	}
1535 
1536 	if (rval != QL_SUCCESS) {
1537 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1538 		    "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1],
1539 		    mr->mb[2]);
1540 	} else {
1541 		/*EMPTY*/
1542 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1543 	}
1544 
1545 	return (rval);
1546 }
1547 
1548 /*
1549  * ql_logout_fabric_port
1550  *	Issue logout fabric port mailbox command.
1551  *
1552  * Input:
1553  *	ha:	adapter state pointer.
1554  *	tq:	target queue pointer.
1555  *
1556  * Returns:
1557  *	ql local function return status code.
1558  *
1559  * Context:
1560  *	Kernel context.
1561  */
1562 int
1563 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1564 {
1565 	int		rval;
1566 	uint16_t	flag;
1567 	ql_mbx_data_t	mr;
1568 	mbx_cmd_t	mc = {0};
1569 	mbx_cmd_t	*mcp = &mc;
1570 
1571 	QL_PRINT_3(CE_CONT, "(%d): started, loop_id=%xh d_id=%xh\n",
1572 	    ha->instance, tq->loop_id, tq->d_id.b24);
1573 
1574 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1575 		flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1576 		    CFO_EXPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE :
1577 		    CFO_IMPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1578 		rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1579 	} else {
1580 		flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?  1 : 0);
1581 		mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1582 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1583 			mcp->mb[1] = tq->loop_id;
1584 			mcp->mb[10] = flag;
1585 			mcp->out_mb = MBX_10|MBX_1|MBX_0;
1586 		} else {
1587 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1588 			mcp->out_mb = MBX_1|MBX_0;
1589 		}
1590 		mcp->in_mb = MBX_0;
1591 		mcp->timeout = MAILBOX_TOV;
1592 		rval = ql_mailbox_command(ha, mcp);
1593 	}
1594 
1595 	if (rval != QL_SUCCESS) {
1596 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval,
1597 		    tq->d_id.b24, tq->loop_id);
1598 	} else {
1599 		/*EMPTY*/
1600 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1601 	}
1602 
1603 	return (rval);
1604 }
1605 
1606 /*
1607  * ql_log_iocb
1608  *	Function issues login/logout IOCB.
1609  *
1610  * Input:
1611  *	ha:		adapter state pointer.
1612  *	tq:		target queue pointer.
1613  *	loop_id:	FC Loop ID.
1614  *	flags:		control flags.
1615  *	mr:		pointer for mailbox data.
1616  *
1617  * Returns:
1618  *	ql local function return status code.
1619  *
1620  * Context:
1621  *	Kernel context.
1622  */
1623 int
1624 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1625     uint16_t flags, ql_mbx_data_t *mr)
1626 {
1627 	ql_mbx_iocb_t	*pkt;
1628 	int		rval;
1629 	uint32_t	pkt_size;
1630 
1631 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1632 
1633 	pkt_size = sizeof (ql_mbx_iocb_t);
1634 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1635 	if (pkt == NULL) {
1636 		EL(ha, "failed, kmem_zalloc\n");
1637 		return (QL_MEMORY_ALLOC_FAILED);
1638 	}
1639 
1640 	pkt->log.entry_type = LOG_TYPE;
1641 	pkt->log.entry_count = 1;
1642 	pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1643 	pkt->log.control_flags = (uint16_t)LE_16(flags);
1644 	pkt->log.port_id[0] = tq->d_id.b.al_pa;
1645 	pkt->log.port_id[1] = tq->d_id.b.area;
1646 	pkt->log.port_id[2] = tq->d_id.b.domain;
1647 	pkt->log.vp_index = ha->vp_index;
1648 
1649 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1650 	if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1651 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1652 		    pkt->log.entry_status, tq->d_id.b24);
1653 		rval = QL_FUNCTION_PARAMETER_ERROR;
1654 	}
1655 
1656 	if (rval == QL_SUCCESS) {
1657 		if (pkt->log.rsp_size == 0xB) {
1658 			LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1659 			tq->cmn_features = MSW(pkt->log.io_param[5]);
1660 			LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1661 			tq->conc_sequences = MSW(pkt->log.io_param[6]);
1662 			tq->relative_offset = LSW(pkt->log.io_param[6]);
1663 			LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1664 			tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1665 			tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1666 			LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1667 			tq->class3_open_sequences_per_exch =
1668 			    MSW(pkt->log.io_param[10]);
1669 			tq->prli_payload_length = 0x14;
1670 		}
1671 		if (mr != NULL) {
1672 			LITTLE_ENDIAN_16(&pkt->log.status);
1673 			LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1674 			LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1675 
1676 			if (pkt->log.status != CS_COMPLETE) {
1677 				EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1678 				    "%xh\n", pkt->log.status,
1679 				    pkt->log.io_param[0],
1680 				    pkt->log.io_param[1]);
1681 
1682 				switch (pkt->log.io_param[0]) {
1683 				case CS0_NO_LINK:
1684 				case CS0_FIRMWARE_NOT_READY:
1685 					mr->mb[0] = MBS_COMMAND_ERROR;
1686 					mr->mb[1] = 1;
1687 					break;
1688 				case CS0_NO_IOCB:
1689 				case CS0_NO_PCB_ALLOCATED:
1690 					mr->mb[0] = MBS_COMMAND_ERROR;
1691 					mr->mb[1] = 2;
1692 					break;
1693 				case CS0_NO_EXCH_CTRL_BLK:
1694 					mr->mb[0] = MBS_COMMAND_ERROR;
1695 					mr->mb[1] = 3;
1696 					break;
1697 				case CS0_COMMAND_FAILED:
1698 					mr->mb[0] = MBS_COMMAND_ERROR;
1699 					mr->mb[1] = 4;
1700 					switch (LSB(pkt->log.io_param[1])) {
1701 					case CS1_PLOGI_RESPONSE_FAILED:
1702 						mr->mb[2] = 3;
1703 						break;
1704 					case CS1_PRLI_FAILED:
1705 						mr->mb[2] = 4;
1706 						break;
1707 					case CS1_PRLI_RESPONSE_FAILED:
1708 						mr->mb[2] = 5;
1709 						break;
1710 					case CS1_COMMAND_LOGGED_OUT:
1711 						mr->mb[2] = 7;
1712 						break;
1713 					case CS1_PLOGI_FAILED:
1714 					default:
1715 						EL(ha, "log iop1 = %xh\n",
1716 						    LSB(pkt->log.io_param[1]))
1717 						mr->mb[2] = 2;
1718 						break;
1719 					}
1720 					break;
1721 				case CS0_PORT_NOT_LOGGED_IN:
1722 					mr->mb[0] = MBS_COMMAND_ERROR;
1723 					mr->mb[1] = 4;
1724 					mr->mb[2] = 7;
1725 					break;
1726 				case CS0_NO_FLOGI_ACC:
1727 				case CS0_NO_FABRIC_PRESENT:
1728 					mr->mb[0] = MBS_COMMAND_ERROR;
1729 					mr->mb[1] = 5;
1730 					break;
1731 				case CS0_ELS_REJECT_RECEIVED:
1732 					mr->mb[0] = MBS_COMMAND_ERROR;
1733 					mr->mb[1] = 0xd;
1734 					break;
1735 				case CS0_PORT_ID_USED:
1736 					mr->mb[0] = MBS_PORT_ID_USED;
1737 					mr->mb[1] = LSW(pkt->log.io_param[1]);
1738 					break;
1739 				case CS0_N_PORT_HANDLE_USED:
1740 					mr->mb[0] = MBS_LOOP_ID_USED;
1741 					mr->mb[1] = MSW(pkt->log.io_param[1]);
1742 					mr->mb[2] = LSW(pkt->log.io_param[1]);
1743 					break;
1744 				case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1745 					mr->mb[0] = MBS_ALL_IDS_IN_USE;
1746 					break;
1747 				case CS0_CMD_PARAMETER_ERROR:
1748 				default:
1749 					EL(ha, "pkt->log iop[0]=%xh\n",
1750 					    pkt->log.io_param[0]);
1751 					mr->mb[0] =
1752 					    MBS_COMMAND_PARAMETER_ERROR;
1753 					break;
1754 				}
1755 			} else {
1756 				QL_PRINT_3(CE_CONT, "(%d): status=%xh\n",
1757 				    ha->instance, pkt->log.status);
1758 
1759 				mr->mb[0] = MBS_COMMAND_COMPLETE;
1760 				mr->mb[1] = (uint16_t)
1761 				    (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1762 				if (pkt->log.io_param[0] & BIT_8) {
1763 					mr->mb[1] = (uint16_t)
1764 					    (mr->mb[1] | BIT_1);
1765 				}
1766 			}
1767 			rval = mr->mb[0];
1768 		}
1769 
1770 	}
1771 
1772 	kmem_free(pkt, pkt_size);
1773 
1774 	if (rval != QL_SUCCESS) {
1775 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1776 	} else {
1777 		/*EMPTY*/
1778 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1779 	}
1780 
1781 	return (rval);
1782 }
1783 
1784 /*
1785  * ql_get_port_database
1786  *	Issue get port database mailbox command
1787  *	and copy context to device queue.
1788  *
1789  * Input:
1790  *	ha:	adapter state pointer.
1791  *	tq:	target queue pointer.
1792  *	opt:	options.
1793  *		PDF_NONE, PDF_PLOGI, PDF_ADISC
1794  * Returns:
1795  *	ql local function return status code.
1796  *
1797  * Context:
1798  *	Kernel context.
1799  */
1800 int
1801 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1802 {
1803 	int			rval;
1804 	dma_mem_t		mem_desc;
1805 	mbx_cmd_t		mc = {0};
1806 	mbx_cmd_t		*mcp = &mc;
1807 	port_database_23_t	*pd23;
1808 
1809 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1810 
1811 	pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1812 	if (pd23 == NULL) {
1813 		rval = QL_MEMORY_ALLOC_FAILED;
1814 		EL(ha, "failed, rval = %xh\n", rval);
1815 		return (rval);
1816 	}
1817 
1818 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1819 	    PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1820 		return (QL_MEMORY_ALLOC_FAILED);
1821 	}
1822 
1823 	if (CFG_IST(ha, CFG_CTRL_242581)) {
1824 		mcp->mb[0] = MBC_GET_PORT_DATABASE;
1825 		mcp->mb[1] = tq->loop_id;
1826 		mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1827 		mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1828 		mcp->mb[9] = ha->vp_index;
1829 		mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1830 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1831 		    MBX_2|MBX_1|MBX_0;
1832 	} else {
1833 		mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1834 		    MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1835 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1836 			mcp->mb[1] = tq->loop_id;
1837 			mcp->mb[10] = opt;
1838 			mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1839 			    MBX_2|MBX_1|MBX_0;
1840 		} else {
1841 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1842 			mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1843 		}
1844 	}
1845 
1846 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1847 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1848 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1849 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1850 	mcp->in_mb = MBX_0;
1851 	mcp->timeout = MAILBOX_TOV;
1852 	rval = ql_mailbox_command(ha, mcp);
1853 
1854 	if (rval == QL_SUCCESS) {
1855 		ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1856 	}
1857 
1858 	ql_free_dma_resource(ha, &mem_desc);
1859 
1860 	if (rval == QL_SUCCESS) {
1861 		if (CFG_IST(ha, CFG_CTRL_242581)) {
1862 			port_database_24_t *pd24 = (port_database_24_t *)pd23;
1863 
1864 			tq->master_state = pd24->current_login_state;
1865 			tq->slave_state = pd24->last_stable_login_state;
1866 			if (PD_PORT_LOGIN(tq)) {
1867 				/* Names are big endian. */
1868 				bcopy((void *)&pd24->port_name[0],
1869 				    (void *)&tq->port_name[0], 8);
1870 				bcopy((void *)&pd24->node_name[0],
1871 				    (void *)&tq->node_name[0], 8);
1872 				tq->hard_addr.b.al_pa = pd24->hard_address[2];
1873 				tq->hard_addr.b.area = pd24->hard_address[1];
1874 				tq->hard_addr.b.domain = pd24->hard_address[0];
1875 				tq->class3_rcv_data_size =
1876 				    pd24->receive_data_size;
1877 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1878 				tq->prli_svc_param_word_0 =
1879 				    pd24->PRLI_service_parameter_word_0;
1880 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1881 				tq->prli_svc_param_word_3 =
1882 				    pd24->PRLI_service_parameter_word_3;
1883 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1884 			}
1885 		} else {
1886 			tq->master_state = pd23->master_state;
1887 			tq->slave_state = pd23->slave_state;
1888 			if (PD_PORT_LOGIN(tq)) {
1889 				/* Names are big endian. */
1890 				bcopy((void *)&pd23->port_name[0],
1891 				    (void *)&tq->port_name[0], 8);
1892 				bcopy((void *)&pd23->node_name[0],
1893 				    (void *)&tq->node_name[0], 8);
1894 				tq->hard_addr.b.al_pa = pd23->hard_address[2];
1895 				tq->hard_addr.b.area = pd23->hard_address[1];
1896 				tq->hard_addr.b.domain = pd23->hard_address[0];
1897 				tq->cmn_features = pd23->common_features;
1898 				LITTLE_ENDIAN_16(&tq->cmn_features);
1899 				tq->conc_sequences =
1900 				    pd23->total_concurrent_sequences;
1901 				LITTLE_ENDIAN_16(&tq->conc_sequences);
1902 				tq->relative_offset =
1903 				    pd23->RO_by_information_category;
1904 				LITTLE_ENDIAN_16(&tq->relative_offset);
1905 				tq->class3_recipient_ctl = pd23->recipient;
1906 				LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
1907 				tq->class3_rcv_data_size =
1908 				    pd23->receive_data_size;
1909 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1910 				tq->class3_conc_sequences =
1911 				    pd23->concurrent_sequences;
1912 				LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
1913 				tq->class3_open_sequences_per_exch =
1914 				    pd23->open_sequences_per_exchange;
1915 				LITTLE_ENDIAN_16(
1916 				    &tq->class3_open_sequences_per_exch);
1917 				tq->prli_payload_length =
1918 				    pd23->PRLI_payload_length;
1919 				LITTLE_ENDIAN_16(&tq->prli_payload_length);
1920 				tq->prli_svc_param_word_0 =
1921 				    pd23->PRLI_service_parameter_word_0;
1922 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1923 				tq->prli_svc_param_word_3 =
1924 				    pd23->PRLI_service_parameter_word_3;
1925 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1926 			}
1927 		}
1928 
1929 		if (!PD_PORT_LOGIN(tq)) {
1930 			EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
1931 			    "master=%xh, slave=%xh\n", tq->d_id.b24,
1932 			    tq->loop_id, tq->master_state, tq->slave_state);
1933 			rval = QL_NOT_LOGGED_IN;
1934 		} else {
1935 			tq->flags = tq->prli_svc_param_word_3 &
1936 			    PRLI_W3_TARGET_FUNCTION ?
1937 			    tq->flags & ~TQF_INITIATOR_DEVICE :
1938 			    tq->flags | TQF_INITIATOR_DEVICE;
1939 
1940 			if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
1941 				tq->flags = tq->prli_svc_param_word_3 &
1942 				    PRLI_W3_RETRY ?
1943 				    tq->flags | TQF_TAPE_DEVICE :
1944 				    tq->flags & ~TQF_TAPE_DEVICE;
1945 			} else {
1946 				tq->flags &= ~TQF_TAPE_DEVICE;
1947 			}
1948 		}
1949 	}
1950 
1951 	kmem_free(pd23, PORT_DATABASE_SIZE);
1952 
1953 	if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) {
1954 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1955 		    tq->loop_id, rval);
1956 	} else {
1957 		/*EMPTY*/
1958 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1959 	}
1960 
1961 	return (rval);
1962 }
1963 
1964 /*
1965  * ql_get_loop_position_map
1966  *	Issue get loop position map mailbox command.
1967  *
1968  * Input:
1969  *	ha:	adapter state pointer.
1970  *	size:	size of data buffer.
1971  *	bufp:	data pointer for DMA data.
1972  *
1973  * Returns:
1974  *	ql local function return status code.
1975  *
1976  * Context:
1977  *	Kernel context.
1978  */
1979 int
1980 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
1981 {
1982 	int		rval;
1983 	dma_mem_t	mem_desc;
1984 	mbx_cmd_t	mc = {0};
1985 	mbx_cmd_t	*mcp = &mc;
1986 
1987 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1988 
1989 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1990 	    (uint32_t)size)) != QL_SUCCESS) {
1991 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
1992 		return (QL_MEMORY_ALLOC_FAILED);
1993 	}
1994 
1995 	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
1996 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1997 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1998 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1999 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2000 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2001 	mcp->in_mb = MBX_1|MBX_0;
2002 	mcp->timeout = MAILBOX_TOV;
2003 	rval = ql_mailbox_command(ha, mcp);
2004 
2005 	if (rval == QL_SUCCESS) {
2006 		ql_get_mbox_dma_data(&mem_desc, bufp);
2007 	}
2008 
2009 	ql_free_dma_resource(ha, &mem_desc);
2010 
2011 	if (rval != QL_SUCCESS) {
2012 		EL(ha, "failed=%xh\n", rval);
2013 	} else {
2014 		/*EMPTY*/
2015 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2016 	}
2017 
2018 	return (rval);
2019 }
2020 
2021 /*
2022  * ql_set_rnid_params
2023  *	Issue set RNID parameters mailbox command.
2024  *
2025  * Input:
2026  *	ha:		adapter state pointer.
2027  *	size:		size of data buffer.
2028  *	bufp:		data pointer for DMA data.
2029  *
2030  * Returns:
2031  *	ql local function return status code.
2032  *
2033  * Context:
2034  *	Kernel context.
2035  */
2036 int
2037 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2038 {
2039 	int		rval;
2040 	dma_mem_t	mem_desc;
2041 	mbx_cmd_t	mc = {0};
2042 	mbx_cmd_t	*mcp = &mc;
2043 
2044 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2045 
2046 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2047 	    (uint32_t)size)) != QL_SUCCESS) {
2048 		EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2049 		return (rval);
2050 	}
2051 
2052 	mcp->mb[0] = MBC_SET_PARAMETERS;
2053 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2054 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2055 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2056 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2057 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2058 	mcp->in_mb = MBX_0;
2059 	mcp->timeout = MAILBOX_TOV;
2060 	rval = ql_mailbox_command(ha, mcp);
2061 
2062 	ql_free_dma_resource(ha, &mem_desc);
2063 
2064 	if (rval != QL_SUCCESS) {
2065 		EL(ha, "failed, rval = %xh\n", rval);
2066 	} else {
2067 		/*EMPTY*/
2068 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2069 	}
2070 
2071 	return (rval);
2072 }
2073 
2074 /*
2075  * ql_send_rnid_els
2076  *	Issue a send node identfication data mailbox command.
2077  *
2078  * Input:
2079  *	ha:		adapter state pointer.
2080  *	loop_id:	FC loop id.
2081  *	opt:		options.
2082  *	size:		size of data buffer.
2083  *	bufp:		data pointer for DMA data.
2084  *
2085  * Returns:
2086  *	ql local function return status code.
2087  *
2088  * Context:
2089  *	Kernel context.
2090  */
2091 int
2092 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2093     size_t size, caddr_t bufp)
2094 {
2095 	int		rval;
2096 	dma_mem_t	mem_desc;
2097 	mbx_cmd_t	mc = {0};
2098 	mbx_cmd_t	*mcp = &mc;
2099 
2100 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2101 
2102 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2103 	    (uint32_t)size)) != QL_SUCCESS) {
2104 		return (QL_MEMORY_ALLOC_FAILED);
2105 	}
2106 
2107 	mcp->mb[0] = MBC_SEND_RNID_ELS;
2108 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2109 		mcp->mb[1] = loop_id;
2110 		mcp->mb[9] = ha->vp_index;
2111 		mcp->mb[10] = opt;
2112 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2113 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2114 		mcp->mb[1] = loop_id;
2115 		mcp->mb[10] = opt;
2116 		mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2117 	} else {
2118 		mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2119 		mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2120 	}
2121 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2122 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2123 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2124 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2125 	mcp->in_mb = MBX_0;
2126 	mcp->timeout = MAILBOX_TOV;
2127 	rval = ql_mailbox_command(ha, mcp);
2128 
2129 	if (rval == QL_SUCCESS) {
2130 		ql_get_mbox_dma_data(&mem_desc, bufp);
2131 	}
2132 
2133 	ql_free_dma_resource(ha, &mem_desc);
2134 
2135 	if (rval != QL_SUCCESS) {
2136 		EL(ha, "failed, rval = %xh\n", rval);
2137 	} else {
2138 		/*EMPTY*/
2139 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2140 	}
2141 
2142 	return (rval);
2143 }
2144 
2145 /*
2146  * ql_get_rnid_params
2147  *	Issue get RNID parameters mailbox command.
2148  *
2149  * Input:
2150  *	ha:	adapter state pointer.
2151  *	size:	size of data buffer.
2152  *	bufp:	data pointer for DMA data.
2153  *
2154  * Returns:
2155  *	ql local function return status code.
2156  *
2157  * Context:
2158  *	Kernel context.
2159  */
2160 int
2161 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2162 {
2163 	int		rval;
2164 	dma_mem_t	mem_desc;
2165 	mbx_cmd_t	mc = {0};
2166 	mbx_cmd_t	*mcp = &mc;
2167 
2168 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2169 
2170 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2171 	    (uint32_t)size)) != QL_SUCCESS) {
2172 		return (QL_MEMORY_ALLOC_FAILED);
2173 	}
2174 
2175 	mcp->mb[0] = MBC_GET_PARAMETERS;
2176 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2177 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2178 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2179 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2180 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2181 	mcp->in_mb = MBX_0;
2182 	mcp->timeout = MAILBOX_TOV;
2183 	rval = ql_mailbox_command(ha, mcp);
2184 
2185 	if (rval == QL_SUCCESS) {
2186 		ql_get_mbox_dma_data(&mem_desc, bufp);
2187 	}
2188 
2189 	ql_free_dma_resource(ha, &mem_desc);
2190 
2191 	if (rval != QL_SUCCESS) {
2192 		EL(ha, "failed=%xh\n", rval);
2193 	} else {
2194 		/*EMPTY*/
2195 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2196 	}
2197 
2198 	return (rval);
2199 }
2200 
2201 /*
2202  * ql_get_link_status
2203  *	Issue get link status mailbox command.
2204  *
2205  * Input:
2206  *	ha:		adapter state pointer.
2207  *	loop_id:	FC loop id or n_port_hdl.
2208  *	size:		size of data buffer.
2209  *	bufp:		data pointer for DMA data.
2210  *	port_no:	port number to query.
2211  *
2212  * Returns:
2213  *	ql local function return status code.
2214  *
2215  * Context:
2216  *	Kernel context.
2217  */
2218 int
2219 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2220     caddr_t bufp, uint8_t port_no)
2221 {
2222 	dma_mem_t	mem_desc;
2223 	mbx_cmd_t	mc = {0};
2224 	mbx_cmd_t	*mcp = &mc;
2225 	int		rval = QL_SUCCESS;
2226 	int		retry = 0;
2227 
2228 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2229 
2230 	do {
2231 		if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2232 		    (uint32_t)size)) != QL_SUCCESS) {
2233 			EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2234 			return (QL_MEMORY_ALLOC_FAILED);
2235 		}
2236 
2237 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2238 		if (CFG_IST(ha, CFG_CTRL_242581)) {
2239 			if (loop_id == ha->loop_id) {
2240 				mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2241 				mcp->mb[8] = (uint16_t)(size >> 2);
2242 				mcp->out_mb = MBX_10|MBX_8;
2243 			} else {
2244 				mcp->mb[1] = loop_id;
2245 				mcp->mb[4] = port_no;
2246 				mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2247 				mcp->out_mb = MBX_10|MBX_4;
2248 			}
2249 		} else {
2250 			if (retry) {
2251 				port_no = (uint8_t)(port_no | BIT_3);
2252 			}
2253 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2254 				mcp->mb[1] = loop_id;
2255 				mcp->mb[10] = port_no;
2256 				mcp->out_mb = MBX_10;
2257 			} else {
2258 				mcp->mb[1] = (uint16_t)((loop_id << 8) |
2259 				    port_no);
2260 				mcp->out_mb = 0;
2261 			}
2262 		}
2263 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2264 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2265 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2266 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2267 		mcp->in_mb = MBX_1|MBX_0;
2268 		mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2269 		mcp->timeout = MAILBOX_TOV;
2270 
2271 		rval = ql_mailbox_command(ha, mcp);
2272 
2273 		if (rval == QL_SUCCESS) {
2274 			ql_get_mbox_dma_data(&mem_desc, bufp);
2275 		}
2276 
2277 		ql_free_dma_resource(ha, &mem_desc);
2278 
2279 		if (rval != QL_SUCCESS) {
2280 			EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2281 		}
2282 
2283 		/*
2284 		 * Some of the devices want d_id in the payload,
2285 		 * strictly as per standard. Let's retry.
2286 		 */
2287 
2288 	} while (rval == QL_COMMAND_ERROR && !retry++);
2289 
2290 	if (rval != QL_SUCCESS) {
2291 		EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2292 	} else {
2293 		/*EMPTY*/
2294 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2295 	}
2296 
2297 	return (rval);
2298 }
2299 
2300 /*
2301  * ql_get_status_counts
2302  *	Issue get adapter link status counts mailbox command.
2303  *
2304  * Input:
2305  *	ha:		adapter state pointer.
2306  *	loop_id:	FC loop id or n_port_hdl.
2307  *	size:		size of data buffer.
2308  *	bufp:		data pointer for DMA data.
2309  *	port_no:	port number to query.
2310  *
2311  * Returns:
2312  *	ql local function return status code.
2313  *
2314  * Context:
2315  *	Kernel context.
2316  */
2317 int
2318 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2319     caddr_t bufp, uint8_t port_no)
2320 {
2321 	dma_mem_t	mem_desc;
2322 	mbx_cmd_t	mc = {0};
2323 	mbx_cmd_t	*mcp = &mc;
2324 	int		rval = QL_SUCCESS;
2325 
2326 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2327 
2328 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2329 	    (uint32_t)size)) != QL_SUCCESS) {
2330 		EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2331 		return (QL_MEMORY_ALLOC_FAILED);
2332 	}
2333 
2334 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2335 		mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2336 		mcp->mb[8] = (uint16_t)(size / 4);
2337 		mcp->out_mb = MBX_10|MBX_8;
2338 	} else {
2339 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2340 
2341 		/* allows reporting when link is down */
2342 		if (CFG_IST(ha, CFG_CTRL_2200) == 0) {
2343 			port_no = (uint8_t)(port_no | BIT_6);
2344 		}
2345 
2346 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2347 			mcp->mb[1] = loop_id;
2348 			mcp->mb[10] = port_no;
2349 			mcp->out_mb = MBX_10|MBX_1;
2350 		} else {
2351 			mcp->mb[1] = (uint16_t)((loop_id << 8) |
2352 			    port_no);
2353 			mcp->out_mb = MBX_1;
2354 		}
2355 	}
2356 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2357 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2358 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2359 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2360 	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2361 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2362 	mcp->timeout = MAILBOX_TOV;
2363 	rval = ql_mailbox_command(ha, mcp);
2364 
2365 	if (rval == QL_SUCCESS) {
2366 		ql_get_mbox_dma_data(&mem_desc, bufp);
2367 	}
2368 
2369 	ql_free_dma_resource(ha, &mem_desc);
2370 
2371 	if (rval != QL_SUCCESS) {
2372 		EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2373 		    mcp->mb[1], mcp->mb[2]);
2374 	} else {
2375 		/*EMPTY*/
2376 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2377 	}
2378 
2379 	return (rval);
2380 }
2381 
2382 /*
2383  * ql_reset_link_status
2384  *	Issue Reset Link Error Status mailbox command
2385  *
2386  * Input:
2387  *	ha:	adapter state pointer.
2388  *
2389  * Returns:
2390  *	ql local function return status code.
2391  *
2392  * Context:
2393  *	Kernel context.
2394  */
2395 int
2396 ql_reset_link_status(ql_adapter_state_t *ha)
2397 {
2398 	int		rval;
2399 	mbx_cmd_t	mc = {0};
2400 	mbx_cmd_t	*mcp = &mc;
2401 
2402 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2403 
2404 	mcp->mb[0] = MBC_RESET_LINK_STATUS;
2405 	mcp->out_mb = MBX_0;
2406 	mcp->in_mb = MBX_0;
2407 	mcp->timeout = MAILBOX_TOV;
2408 	rval = ql_mailbox_command(ha, mcp);
2409 
2410 	if (rval != QL_SUCCESS) {
2411 		EL(ha, "failed=%xh\n", rval);
2412 	} else {
2413 		/*EMPTY*/
2414 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2415 	}
2416 
2417 	return (rval);
2418 }
2419 
2420 /*
2421  * ql_loop_reset
2422  *	Issue loop reset.
2423  *
2424  * Input:
2425  *	ha:	adapter state pointer.
2426  *
2427  * Returns:
2428  *	ql local function return status code.
2429  *
2430  * Context:
2431  *	Kernel context.
2432  */
2433 int
2434 ql_loop_reset(ql_adapter_state_t *ha)
2435 {
2436 	int	rval;
2437 
2438 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2439 
2440 	if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2441 		rval = ql_lip_reset(ha, 0xff);
2442 	} else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2443 		rval = ql_full_login_lip(ha);
2444 	} else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2445 		rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2446 	} else {
2447 		rval = ql_initiate_lip(ha);
2448 	}
2449 
2450 	if (rval != QL_SUCCESS) {
2451 		EL(ha, "failed, rval = %xh\n", rval);
2452 	} else {
2453 		/*EMPTY*/
2454 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2455 	}
2456 
2457 	return (rval);
2458 }
2459 
2460 /*
2461  * ql_initiate_lip
2462  *	Initiate LIP mailbox command.
2463  *
2464  * Input:
2465  *	ha:	adapter state pointer.
2466  *
2467  * Returns:
2468  *	ql local function return status code.
2469  *
2470  * Context:
2471  *	Kernel context.
2472  */
2473 int
2474 ql_initiate_lip(ql_adapter_state_t *ha)
2475 {
2476 	int		rval;
2477 	mbx_cmd_t	mc = {0};
2478 	mbx_cmd_t	*mcp = &mc;
2479 
2480 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2481 
2482 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2483 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2484 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_81XX) ?
2485 		    BIT_1 : BIT_4);
2486 		mcp->mb[3] = ha->loop_reset_delay;
2487 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2488 	} else {
2489 		mcp->mb[0] = MBC_INITIATE_LIP;
2490 		mcp->out_mb = MBX_0;
2491 	}
2492 	mcp->in_mb = MBX_0;
2493 	mcp->timeout = MAILBOX_TOV;
2494 	rval = ql_mailbox_command(ha, mcp);
2495 
2496 	if (rval != QL_SUCCESS) {
2497 		EL(ha, "failed, rval = %xh\n", rval);
2498 	} else {
2499 		/*EMPTY*/
2500 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2501 	}
2502 
2503 	return (rval);
2504 }
2505 
2506 /*
2507  * ql_full_login_lip
2508  *	Issue full login LIP mailbox command.
2509  *
2510  * Input:
2511  *	ha:	adapter state pointer.
2512  *
2513  * Returns:
2514  *	ql local function return status code.
2515  *
2516  * Context:
2517  *	Kernel context.
2518  */
2519 int
2520 ql_full_login_lip(ql_adapter_state_t *ha)
2521 {
2522 	int		rval;
2523 	mbx_cmd_t	mc = {0};
2524 	mbx_cmd_t	*mcp = &mc;
2525 
2526 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2527 
2528 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2529 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2530 		mcp->mb[1] = BIT_3;
2531 	} else if (CFG_IST(ha, CFG_CTRL_81XX)) {
2532 		mcp->mb[1] = BIT_1;
2533 	}
2534 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2535 	mcp->in_mb = MBX_0;
2536 	mcp->timeout = MAILBOX_TOV;
2537 	rval = ql_mailbox_command(ha, mcp);
2538 
2539 	if (rval != QL_SUCCESS) {
2540 		EL(ha, "failed, rval = %xh\n", rval);
2541 	} else {
2542 		/*EMPTY*/
2543 		QL_PRINT_3(CE_CONT, "(%d): done", ha->instance);
2544 	}
2545 
2546 	return (rval);
2547 }
2548 
2549 /*
2550  * ql_lip_reset
2551  *	Issue lip reset to a port.
2552  *
2553  * Input:
2554  *	ha:		adapter state pointer.
2555  *	loop_id:	FC loop id.
2556  *
2557  * Returns:
2558  *	ql local function return status code.
2559  *
2560  * Context:
2561  *	Kernel context.
2562  */
2563 int
2564 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2565 {
2566 	int		rval;
2567 	mbx_cmd_t	mc = {0};
2568 	mbx_cmd_t	*mcp = &mc;
2569 
2570 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2571 
2572 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2573 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2574 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_81XX) ?
2575 		    BIT_1 : BIT_6);
2576 		mcp->mb[3] = ha->loop_reset_delay;
2577 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2578 	} else {
2579 		mcp->mb[0] = MBC_LIP_RESET;
2580 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2581 			mcp->mb[1] = loop_id;
2582 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2583 		} else {
2584 			mcp->mb[1] = (uint16_t)(loop_id << 8);
2585 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2586 		}
2587 		mcp->mb[2] = ha->loop_reset_delay;
2588 	}
2589 	mcp->in_mb = MBX_0;
2590 	mcp->timeout = MAILBOX_TOV;
2591 	rval = ql_mailbox_command(ha, mcp);
2592 
2593 	if (rval != QL_SUCCESS) {
2594 		EL(ha, "failed, rval = %xh\n", rval);
2595 	} else {
2596 		/*EMPTY*/
2597 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2598 	}
2599 
2600 	return (rval);
2601 }
2602 
2603 /*
2604  * ql_abort_command
2605  *	Abort command aborts a specified IOCB.
2606  *
2607  * Input:
2608  *	ha:	adapter state pointer.
2609  *	sp:	SRB structure pointer.
2610  *
2611  * Returns:
2612  *	ql local function return status code.
2613  *
2614  * Context:
2615  *	Kernel context.
2616  */
2617 int
2618 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2619 {
2620 	int		rval;
2621 	mbx_cmd_t	mc = {0};
2622 	mbx_cmd_t	*mcp = &mc;
2623 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2624 
2625 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2626 
2627 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2628 		rval = ql_abort_cmd_iocb(ha, sp);
2629 	} else {
2630 		mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2631 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2632 			mcp->mb[1] = tq->loop_id;
2633 		} else {
2634 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2635 		}
2636 		mcp->mb[2] = LSW(sp->handle);
2637 		mcp->mb[3] = MSW(sp->handle);
2638 		mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2639 		    sp->lun_queue->lun_no : 0);
2640 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2641 		mcp->in_mb = MBX_0;
2642 		mcp->timeout = MAILBOX_TOV;
2643 		rval = ql_mailbox_command(ha, mcp);
2644 	}
2645 
2646 	if (rval != QL_SUCCESS) {
2647 		EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2648 		    tq->d_id.b24, sp->handle);
2649 	} else {
2650 		/*EMPTY*/
2651 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2652 	}
2653 
2654 	return (rval);
2655 }
2656 
2657 /*
2658  * ql_abort_cmd_iocb
2659  *	Function issues abort command IOCB.
2660  *
2661  * Input:
2662  *	ha:	adapter state pointer.
2663  *	sp:	SRB structure pointer.
2664  *
2665  * Returns:
2666  *	ql local function return status code.
2667  *
2668  * Context:
2669  *	Interrupt or Kernel context, no mailbox commands allowed.
2670  */
2671 static int
2672 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2673 {
2674 	ql_mbx_iocb_t	*pkt;
2675 	int		rval;
2676 	uint32_t	pkt_size;
2677 	uint16_t	comp_status;
2678 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2679 
2680 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2681 
2682 	pkt_size = sizeof (ql_mbx_iocb_t);
2683 	if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2684 		EL(ha, "failed, kmem_zalloc\n");
2685 		return (QL_MEMORY_ALLOC_FAILED);
2686 	}
2687 
2688 	pkt->abo.entry_type = ABORT_CMD_TYPE;
2689 	pkt->abo.entry_count = 1;
2690 	pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2691 	pkt->abo.options = AF_NO_ABTS;
2692 	pkt->abo.cmd_handle = LE_32(sp->handle);
2693 	pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2694 	pkt->abo.target_id[1] = tq->d_id.b.area;
2695 	pkt->abo.target_id[2] = tq->d_id.b.domain;
2696 	pkt->abo.vp_index = ha->vp_index;
2697 
2698 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2699 
2700 	if (rval == QL_SUCCESS && (pkt->abo.entry_status  & 0x3c) != 0) {
2701 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2702 		    pkt->abo.entry_status, tq->d_id.b24);
2703 		rval = QL_FUNCTION_PARAMETER_ERROR;
2704 	}
2705 
2706 	comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2707 	if (rval == QL_SUCCESS && comp_status != CS_COMPLETE) {
2708 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2709 		    comp_status, tq->d_id.b24);
2710 		rval = QL_FUNCTION_FAILED;
2711 	}
2712 
2713 	kmem_free(pkt, pkt_size);
2714 
2715 	if (rval != QL_SUCCESS) {
2716 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2717 	} else {
2718 		/*EMPTY*/
2719 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2720 	}
2721 
2722 	return (rval);
2723 }
2724 
2725 /*
2726  * ql_verify_checksum
2727  *	Verify loaded RISC firmware.
2728  *
2729  * Input:
2730  *	ha = adapter state pointer.
2731  *
2732  * Returns:
2733  *	ql local function return status code.
2734  *
2735  * Context:
2736  *	Kernel context.
2737  */
2738 int
2739 ql_verify_checksum(ql_adapter_state_t *ha)
2740 {
2741 	int		rval;
2742 	mbx_cmd_t	mc = {0};
2743 	mbx_cmd_t	*mcp = &mc;
2744 
2745 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2746 
2747 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2748 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2749 		mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2750 		mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2751 	} else {
2752 		mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2753 	}
2754 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
2755 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2756 	mcp->timeout = MAILBOX_TOV;
2757 	rval = ql_mailbox_command(ha, mcp);
2758 
2759 	if (rval != QL_SUCCESS) {
2760 		EL(ha, "failed, rval = %xh\n", rval);
2761 	} else {
2762 		/*EMPTY*/
2763 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2764 	}
2765 
2766 	return (rval);
2767 }
2768 
2769 /*
2770  * ql_get_id_list
2771  *	Get d_id and loop ID list.
2772  *
2773  * Input:
2774  *	ha:	adapter state pointer.
2775  *	bp:	data pointer for DMA data.
2776  *	size:	size of data buffer.
2777  *	mr:	pointer for mailbox data.
2778  *
2779  * Returns:
2780  *	ql local function return status code.
2781  *
2782  * Context:
2783  *	Kernel context.
2784  */
2785 int
2786 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2787     ql_mbx_data_t *mr)
2788 {
2789 	int		rval;
2790 	dma_mem_t	mem_desc;
2791 	mbx_cmd_t	mc = {0};
2792 	mbx_cmd_t	*mcp = &mc;
2793 
2794 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2795 
2796 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2797 	    (uint32_t)size)) != QL_SUCCESS) {
2798 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2799 		return (QL_MEMORY_ALLOC_FAILED);
2800 	}
2801 
2802 	mcp->mb[0] = MBC_GET_ID_LIST;
2803 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2804 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2805 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2806 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2807 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2808 		mcp->mb[8] = (uint16_t)size;
2809 		mcp->mb[9] = ha->vp_index;
2810 		mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2811 	} else {
2812 		mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2813 		mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2814 		mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2815 		mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2816 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2817 	}
2818 	mcp->in_mb = MBX_1|MBX_0;
2819 	mcp->timeout = MAILBOX_TOV;
2820 	rval = ql_mailbox_command(ha, mcp);
2821 
2822 	if (rval == QL_SUCCESS) {
2823 		ql_get_mbox_dma_data(&mem_desc, bp);
2824 	}
2825 
2826 	ql_free_dma_resource(ha, &mem_desc);
2827 
2828 	/* Return mailbox data. */
2829 	if (mr != NULL) {
2830 		mr->mb[0] = mcp->mb[0];
2831 		mr->mb[1] = mcp->mb[1];
2832 	}
2833 
2834 	if (rval != QL_SUCCESS) {
2835 		EL(ha, "failed, rval = %xh\n", rval);
2836 	} else {
2837 		/*EMPTY*/
2838 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2839 	}
2840 
2841 	return (rval);
2842 }
2843 
2844 /*
2845  * ql_wrt_risc_ram
2846  *	Load RISC RAM.
2847  *
2848  * Input:
2849  *	ha:		adapter state pointer.
2850  *	risc_address:	risc ram word address.
2851  *	bp:		DMA pointer.
2852  *	word_count:	16/32bit word count.
2853  *
2854  * Returns:
2855  *	ql local function return status code.
2856  *
2857  * Context:
2858  *	Kernel context.
2859  */
2860 int
2861 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2862     uint32_t word_count)
2863 {
2864 	int		rval;
2865 	mbx_cmd_t	mc = {0};
2866 	mbx_cmd_t	*mcp = &mc;
2867 
2868 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2869 
2870 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2871 		mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
2872 		mcp->mb[4] = MSW(word_count);
2873 		mcp->mb[5] = LSW(word_count);
2874 		mcp->mb[6] = MSW(MSD(bp));
2875 		mcp->mb[7] = LSW(MSD(bp));
2876 		mcp->mb[8] = MSW(risc_address);
2877 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2878 		    MBX_0;
2879 	} else {
2880 		mcp->mb[0] = MBC_LOAD_RAM;
2881 		mcp->mb[4] = LSW(word_count);
2882 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2883 	}
2884 	mcp->mb[1] = LSW(risc_address);
2885 	mcp->mb[2] = MSW(LSD(bp));
2886 	mcp->mb[3] = LSW(LSD(bp));
2887 	mcp->in_mb = MBX_0;
2888 	mcp->timeout = MAILBOX_TOV;
2889 
2890 	rval = ql_mailbox_command(ha, mcp);
2891 
2892 	if (rval != QL_SUCCESS) {
2893 		EL(ha, "failed, rval = %xh\n", rval);
2894 	} else {
2895 		/*EMPTY*/
2896 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2897 	}
2898 
2899 	return (rval);
2900 }
2901 
2902 /*
2903  * ql_rd_risc_ram
2904  *	Get RISC RAM.
2905  *
2906  * Input:
2907  *	ha:		adapter state pointer.
2908  *	risc_address:	risc ram word address.
2909  *	bp:		direct data pointer.
2910  *	word_count:	16/32bit word count.
2911  *
2912  * Returns:
2913  *	ql local function return status code.
2914  *
2915  * Context:
2916  *	Kernel context.
2917  */
2918 int
2919 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2920     uint32_t word_count)
2921 {
2922 	int		rval;
2923 	mbx_cmd_t	mc = {0};
2924 	mbx_cmd_t	*mcp = &mc;
2925 
2926 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2927 
2928 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2929 		mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
2930 		mcp->mb[1] = LSW(risc_address);
2931 		mcp->mb[2] = MSW(LSD(bp));
2932 		mcp->mb[3] = LSW(LSD(bp));
2933 		mcp->mb[4] = MSW(word_count);
2934 		mcp->mb[5] = LSW(word_count);
2935 		mcp->mb[6] = MSW(MSD(bp));
2936 		mcp->mb[7] = LSW(MSD(bp));
2937 		mcp->mb[8] = MSW(risc_address);
2938 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2939 		    MBX_0;
2940 	} else {
2941 		mcp->mb[0] = MBC_DUMP_RAM;	/* doesn't support 64bit addr */
2942 		mcp->mb[1] = LSW(risc_address);
2943 		mcp->mb[2] = MSW(LSD(bp));
2944 		mcp->mb[3] = LSW(LSD(bp));
2945 		mcp->mb[4] = LSW(word_count);
2946 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2947 	}
2948 	mcp->in_mb = MBX_0;
2949 	mcp->timeout = MAILBOX_TOV;
2950 	rval = ql_mailbox_command(ha, mcp);
2951 
2952 	if (rval != QL_SUCCESS) {
2953 		EL(ha, "failed, rval = %xh\n", rval);
2954 	} else {
2955 		/*EMPTY*/
2956 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2957 	}
2958 
2959 	return (rval);
2960 }
2961 
2962 /*
2963  * ql_wrt_risc_ram_word
2964  *	Write RISC RAM word.
2965  *
2966  * Input:
2967  *	ha:		adapter state pointer.
2968  *	risc_address:	risc ram word address.
2969  *	data:		data.
2970  *
2971  * Returns:
2972  *	ql local function return status code.
2973  *
2974  * Context:
2975  *	Kernel context.
2976  */
2977 int
2978 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
2979     uint32_t data)
2980 {
2981 	int		rval;
2982 	mbx_cmd_t	mc = {0};
2983 	mbx_cmd_t	*mcp = &mc;
2984 
2985 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2986 
2987 	mcp->mb[0] = MBC_WRITE_RAM_EXTENDED;
2988 	mcp->mb[1] = LSW(risc_address);
2989 	mcp->mb[2] = LSW(data);
2990 	mcp->mb[3] = MSW(data);
2991 	mcp->mb[8] = MSW(risc_address);
2992 	mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
2993 	mcp->in_mb = MBX_0;
2994 	mcp->timeout = MAILBOX_TOV;
2995 
2996 	rval = ql_mailbox_command(ha, mcp);
2997 
2998 	if (rval != QL_SUCCESS) {
2999 		EL(ha, "failed, rval = %xh\n", rval);
3000 	} else {
3001 		/*EMPTY*/
3002 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3003 	}
3004 
3005 	return (rval);
3006 }
3007 
3008 /*
3009  * ql_rd_risc_ram_word
3010  *	Read RISC RAM word.
3011  *
3012  * Input:
3013  *	ha:		adapter state pointer.
3014  *	risc_address:	risc ram word address.
3015  *	data:		data pointer.
3016  *
3017  * Returns:
3018  *	ql local function return status code.
3019  *
3020  * Context:
3021  *	Kernel context.
3022  */
3023 int
3024 ql_rd_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3025     uint32_t *data)
3026 {
3027 	int		rval;
3028 	mbx_cmd_t	mc = {0};
3029 	mbx_cmd_t	*mcp = &mc;
3030 
3031 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3032 
3033 	mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3034 	mcp->mb[1] = LSW(risc_address);
3035 	mcp->mb[8] = MSW(risc_address);
3036 	mcp->out_mb = MBX_8|MBX_1|MBX_0;
3037 	mcp->in_mb = MBX_3|MBX_2|MBX_0;
3038 	mcp->timeout = MAILBOX_TOV;
3039 
3040 	rval = ql_mailbox_command(ha, mcp);
3041 
3042 	if (rval != QL_SUCCESS) {
3043 		EL(ha, "failed, rval = %xh\n", rval);
3044 	} else {
3045 		*data = mcp->mb[2];
3046 		if (CFG_IST(ha, CFG_CTRL_242581)) {
3047 			*data |= mcp->mb[3] << 16;
3048 		}
3049 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3050 	}
3051 
3052 	return (rval);
3053 }
3054 
3055 /*
3056  * ql_issue_mbx_iocb
3057  *	Issue IOCB using mailbox command
3058  *
3059  * Input:
3060  *	ha:	adapter state pointer.
3061  *	bp:	buffer pointer.
3062  *	size:	buffer size.
3063  *
3064  * Returns:
3065  *	ql local function return status code.
3066  *
3067  * Context:
3068  *	Kernel context.
3069  */
3070 int
3071 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size)
3072 {
3073 	int		rval;
3074 	dma_mem_t	mem_desc;
3075 	mbx_cmd_t	mc = {0};
3076 	mbx_cmd_t	*mcp = &mc;
3077 
3078 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3079 
3080 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3081 	    QL_SUCCESS) {
3082 		EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3083 		return (rval);
3084 	}
3085 
3086 	mcp->mb[0] = MBC_EXECUTE_IOCB;
3087 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3088