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