1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte 
22*fcf3ce44SJohn Forte /* Copyright 2008 QLogic Corporation */
23*fcf3ce44SJohn Forte 
24*fcf3ce44SJohn Forte /*
25*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26*fcf3ce44SJohn Forte  * Use is subject to license terms.
27*fcf3ce44SJohn Forte  */
28*fcf3ce44SJohn Forte 
29*fcf3ce44SJohn Forte #pragma ident	"Copyright 2008 QLogic Corporation; ql_iocb.c"
30*fcf3ce44SJohn Forte 
31*fcf3ce44SJohn Forte /*
32*fcf3ce44SJohn Forte  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33*fcf3ce44SJohn Forte  *
34*fcf3ce44SJohn Forte  * ***********************************************************************
35*fcf3ce44SJohn Forte  * *									**
36*fcf3ce44SJohn Forte  * *				NOTICE					**
37*fcf3ce44SJohn Forte  * *		COPYRIGHT (C) 1996-2008 QLOGIC CORPORATION		**
38*fcf3ce44SJohn Forte  * *			ALL RIGHTS RESERVED				**
39*fcf3ce44SJohn Forte  * *									**
40*fcf3ce44SJohn Forte  * ***********************************************************************
41*fcf3ce44SJohn Forte  *
42*fcf3ce44SJohn Forte  */
43*fcf3ce44SJohn Forte 
44*fcf3ce44SJohn Forte #include <ql_apps.h>
45*fcf3ce44SJohn Forte #include <ql_api.h>
46*fcf3ce44SJohn Forte #include <ql_debug.h>
47*fcf3ce44SJohn Forte #include <ql_iocb.h>
48*fcf3ce44SJohn Forte #include <ql_isr.h>
49*fcf3ce44SJohn Forte #include <ql_xioctl.h>
50*fcf3ce44SJohn Forte 
51*fcf3ce44SJohn Forte /*
52*fcf3ce44SJohn Forte  * Local Function Prototypes.
53*fcf3ce44SJohn Forte  */
54*fcf3ce44SJohn Forte static void ql_continuation_iocb(ql_adapter_state_t *, ddi_dma_cookie_t *,
55*fcf3ce44SJohn Forte     uint16_t, boolean_t);
56*fcf3ce44SJohn Forte static void ql_isp24xx_rcvbuf(ql_adapter_state_t *);
57*fcf3ce44SJohn Forte 
58*fcf3ce44SJohn Forte /*
59*fcf3ce44SJohn Forte  * ql_start_iocb
60*fcf3ce44SJohn Forte  *	The start IOCB is responsible for building request packets
61*fcf3ce44SJohn Forte  *	on request ring and modifying ISP input pointer.
62*fcf3ce44SJohn Forte  *
63*fcf3ce44SJohn Forte  * Input:
64*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
65*fcf3ce44SJohn Forte  *	sp:	srb structure pointer.
66*fcf3ce44SJohn Forte  *
67*fcf3ce44SJohn Forte  * Context:
68*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
69*fcf3ce44SJohn Forte  */
70*fcf3ce44SJohn Forte void
71*fcf3ce44SJohn Forte ql_start_iocb(ql_adapter_state_t *vha, ql_srb_t *sp)
72*fcf3ce44SJohn Forte {
73*fcf3ce44SJohn Forte 	ql_link_t		*link;
74*fcf3ce44SJohn Forte 	request_t		*pkt;
75*fcf3ce44SJohn Forte 	uint64_t		*ptr64;
76*fcf3ce44SJohn Forte 	uint32_t		cnt;
77*fcf3ce44SJohn Forte 	ql_adapter_state_t	*ha = vha->pha;
78*fcf3ce44SJohn Forte 
79*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
80*fcf3ce44SJohn Forte 
81*fcf3ce44SJohn Forte 	/* Acquire ring lock. */
82*fcf3ce44SJohn Forte 	REQUEST_RING_LOCK(ha);
83*fcf3ce44SJohn Forte 
84*fcf3ce44SJohn Forte 	if (sp != NULL) {
85*fcf3ce44SJohn Forte 		/*
86*fcf3ce44SJohn Forte 		 * Start any pending ones before this one.
87*fcf3ce44SJohn Forte 		 * Add command to pending command queue if not empty.
88*fcf3ce44SJohn Forte 		 */
89*fcf3ce44SJohn Forte 		if ((link = ha->pending_cmds.first) != NULL) {
90*fcf3ce44SJohn Forte 			ql_add_link_b(&ha->pending_cmds, &sp->cmd);
91*fcf3ce44SJohn Forte 			/* Remove command from pending command queue */
92*fcf3ce44SJohn Forte 			sp = link->base_address;
93*fcf3ce44SJohn Forte 			ql_remove_link(&ha->pending_cmds, &sp->cmd);
94*fcf3ce44SJohn Forte 		}
95*fcf3ce44SJohn Forte 	} else {
96*fcf3ce44SJohn Forte 		/* Get command from pending command queue if not empty. */
97*fcf3ce44SJohn Forte 		if ((link = ha->pending_cmds.first) == NULL) {
98*fcf3ce44SJohn Forte 			/* Release ring specific lock */
99*fcf3ce44SJohn Forte 			REQUEST_RING_UNLOCK(ha);
100*fcf3ce44SJohn Forte 			QL_PRINT_3(CE_CONT, "(%d): empty done\n",
101*fcf3ce44SJohn Forte 			    ha->instance);
102*fcf3ce44SJohn Forte 			return;
103*fcf3ce44SJohn Forte 		}
104*fcf3ce44SJohn Forte 		/* Remove command from pending command queue */
105*fcf3ce44SJohn Forte 		sp = link->base_address;
106*fcf3ce44SJohn Forte 		ql_remove_link(&ha->pending_cmds, &sp->cmd);
107*fcf3ce44SJohn Forte 	}
108*fcf3ce44SJohn Forte 
109*fcf3ce44SJohn Forte 	/* start as many as possible */
110*fcf3ce44SJohn Forte 	for (;;) {
111*fcf3ce44SJohn Forte 		if (ha->req_q_cnt < sp->req_cnt) {
112*fcf3ce44SJohn Forte 			/* Calculate number of free request entries. */
113*fcf3ce44SJohn Forte 			cnt = RD16_IO_REG(ha, req_out);
114*fcf3ce44SJohn Forte 			if (ha->req_ring_index < cnt)  {
115*fcf3ce44SJohn Forte 				ha->req_q_cnt = (uint16_t)
116*fcf3ce44SJohn Forte 				    (cnt - ha->req_ring_index);
117*fcf3ce44SJohn Forte 			} else {
118*fcf3ce44SJohn Forte 				ha->req_q_cnt = (uint16_t)(REQUEST_ENTRY_CNT -
119*fcf3ce44SJohn Forte 				    (ha->req_ring_index - cnt));
120*fcf3ce44SJohn Forte 			}
121*fcf3ce44SJohn Forte 			if (ha->req_q_cnt != 0) {
122*fcf3ce44SJohn Forte 				ha->req_q_cnt--;
123*fcf3ce44SJohn Forte 			}
124*fcf3ce44SJohn Forte 
125*fcf3ce44SJohn Forte 			/* If no room for request in request ring. */
126*fcf3ce44SJohn Forte 			if (ha->req_q_cnt < sp->req_cnt) {
127*fcf3ce44SJohn Forte 				QL_PRINT_8(CE_CONT, "(%d): request ring full,"
128*fcf3ce44SJohn Forte 				    " req_q_cnt=%d, req_ring_index=%d\n",
129*fcf3ce44SJohn Forte 				    ha->instance, ha->req_q_cnt,
130*fcf3ce44SJohn Forte 				    ha->req_ring_index);
131*fcf3ce44SJohn Forte 				ql_add_link_t(&ha->pending_cmds, &sp->cmd);
132*fcf3ce44SJohn Forte 				break;
133*fcf3ce44SJohn Forte 			}
134*fcf3ce44SJohn Forte 		}
135*fcf3ce44SJohn Forte 
136*fcf3ce44SJohn Forte 		/* Check for room in outstanding command list. */
137*fcf3ce44SJohn Forte 		for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
138*fcf3ce44SJohn Forte 			ha->osc_index++;
139*fcf3ce44SJohn Forte 			if (ha->osc_index == MAX_OUTSTANDING_COMMANDS) {
140*fcf3ce44SJohn Forte 				ha->osc_index = 1;
141*fcf3ce44SJohn Forte 			}
142*fcf3ce44SJohn Forte 			if (ha->outstanding_cmds[ha->osc_index] == NULL) {
143*fcf3ce44SJohn Forte 				break;
144*fcf3ce44SJohn Forte 			}
145*fcf3ce44SJohn Forte 		}
146*fcf3ce44SJohn Forte 
147*fcf3ce44SJohn Forte 		if (cnt == MAX_OUTSTANDING_COMMANDS) {
148*fcf3ce44SJohn Forte 			QL_PRINT_8(CE_CONT, "(%d): no room in outstanding "
149*fcf3ce44SJohn Forte 			    "array\n", ha->instance);
150*fcf3ce44SJohn Forte 			ql_add_link_t(&ha->pending_cmds, &sp->cmd);
151*fcf3ce44SJohn Forte 			break;
152*fcf3ce44SJohn Forte 		}
153*fcf3ce44SJohn Forte 
154*fcf3ce44SJohn Forte 		/* If room for request in request ring. */
155*fcf3ce44SJohn Forte 		ha->outstanding_cmds[ha->osc_index] = sp;
156*fcf3ce44SJohn Forte 		sp->handle = ha->adapter_stats->ncmds << OSC_INDEX_SHIFT |
157*fcf3ce44SJohn Forte 		    ha->osc_index;
158*fcf3ce44SJohn Forte 		ha->req_q_cnt -= sp->req_cnt;
159*fcf3ce44SJohn Forte 		pkt = ha->request_ring_ptr;
160*fcf3ce44SJohn Forte 		sp->flags |= SRB_IN_TOKEN_ARRAY;
161*fcf3ce44SJohn Forte 
162*fcf3ce44SJohn Forte 		/* Zero out packet. */
163*fcf3ce44SJohn Forte 		ptr64 = (uint64_t *)pkt;
164*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64++ = 0;
165*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64++ = 0;
166*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64++ = 0;
167*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64 = 0;
168*fcf3ce44SJohn Forte 
169*fcf3ce44SJohn Forte 		/* Setup IOCB common data. */
170*fcf3ce44SJohn Forte 		pkt->entry_count = (uint8_t)sp->req_cnt;
171*fcf3ce44SJohn Forte 		pkt->sys_define = (uint8_t)ha->req_ring_index;
172*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle, &pkt->handle,
173*fcf3ce44SJohn Forte 		    (uint32_t)sp->handle);
174*fcf3ce44SJohn Forte 
175*fcf3ce44SJohn Forte 		/* Setup remaining IOCB data. */
176*fcf3ce44SJohn Forte 		(sp->iocb)(vha, sp, pkt);
177*fcf3ce44SJohn Forte 
178*fcf3ce44SJohn Forte 		sp->flags |= SRB_ISP_STARTED;
179*fcf3ce44SJohn Forte 
180*fcf3ce44SJohn Forte 		QL_PRINT_5(CE_CONT, "(%d,%d): req packet, sp=%p\n",
181*fcf3ce44SJohn Forte 		    ha->instance, vha->vp_index, (void *)sp);
182*fcf3ce44SJohn Forte 		QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE);
183*fcf3ce44SJohn Forte 
184*fcf3ce44SJohn Forte 		/* Sync DMA buffer. */
185*fcf3ce44SJohn Forte 		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
186*fcf3ce44SJohn Forte 		    (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE +
187*fcf3ce44SJohn Forte 		    REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE,
188*fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORDEV);
189*fcf3ce44SJohn Forte 
190*fcf3ce44SJohn Forte 		/* Adjust ring index. */
191*fcf3ce44SJohn Forte 		ha->req_ring_index++;
192*fcf3ce44SJohn Forte 		if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
193*fcf3ce44SJohn Forte 			ha->req_ring_index = 0;
194*fcf3ce44SJohn Forte 			ha->request_ring_ptr = ha->request_ring_bp;
195*fcf3ce44SJohn Forte 		} else {
196*fcf3ce44SJohn Forte 			ha->request_ring_ptr++;
197*fcf3ce44SJohn Forte 		}
198*fcf3ce44SJohn Forte 
199*fcf3ce44SJohn Forte 		/* Reset watchdog timer */
200*fcf3ce44SJohn Forte 		sp->wdg_q_time = sp->init_wdg_q_time;
201*fcf3ce44SJohn Forte 
202*fcf3ce44SJohn Forte 		/* Set chip new ring index. */
203*fcf3ce44SJohn Forte 		WRT16_IO_REG(ha, req_in, ha->req_ring_index);
204*fcf3ce44SJohn Forte 
205*fcf3ce44SJohn Forte 		/* Update outstanding command count statistic. */
206*fcf3ce44SJohn Forte 		ha->adapter_stats->ncmds++;
207*fcf3ce44SJohn Forte 
208*fcf3ce44SJohn Forte 		if ((link = ha->pending_cmds.first) == NULL) {
209*fcf3ce44SJohn Forte 			break;
210*fcf3ce44SJohn Forte 		}
211*fcf3ce44SJohn Forte 
212*fcf3ce44SJohn Forte 		/* Remove command from pending command queue */
213*fcf3ce44SJohn Forte 		sp = link->base_address;
214*fcf3ce44SJohn Forte 		ql_remove_link(&ha->pending_cmds, &sp->cmd);
215*fcf3ce44SJohn Forte 	}
216*fcf3ce44SJohn Forte 
217*fcf3ce44SJohn Forte 	/* Release ring specific lock */
218*fcf3ce44SJohn Forte 	REQUEST_RING_UNLOCK(ha);
219*fcf3ce44SJohn Forte 
220*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
221*fcf3ce44SJohn Forte }
222*fcf3ce44SJohn Forte 
223*fcf3ce44SJohn Forte /*
224*fcf3ce44SJohn Forte  * ql_req_pkt
225*fcf3ce44SJohn Forte  *	Function is responsible for locking ring and
226*fcf3ce44SJohn Forte  *	getting a zeroed out request packet.
227*fcf3ce44SJohn Forte  *
228*fcf3ce44SJohn Forte  * Input:
229*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
230*fcf3ce44SJohn Forte  *	pkt:	address for packet pointer.
231*fcf3ce44SJohn Forte  *
232*fcf3ce44SJohn Forte  * Returns:
233*fcf3ce44SJohn Forte  *	ql local function return status code.
234*fcf3ce44SJohn Forte  *
235*fcf3ce44SJohn Forte  * Context:
236*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
237*fcf3ce44SJohn Forte  */
238*fcf3ce44SJohn Forte int
239*fcf3ce44SJohn Forte ql_req_pkt(ql_adapter_state_t *vha, request_t **pktp)
240*fcf3ce44SJohn Forte {
241*fcf3ce44SJohn Forte 	uint16_t		cnt;
242*fcf3ce44SJohn Forte 	uint32_t		*long_ptr;
243*fcf3ce44SJohn Forte 	uint32_t		timer;
244*fcf3ce44SJohn Forte 	int			rval = QL_FUNCTION_TIMEOUT;
245*fcf3ce44SJohn Forte 	ql_adapter_state_t	*ha = vha->pha;
246*fcf3ce44SJohn Forte 
247*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
248*fcf3ce44SJohn Forte 
249*fcf3ce44SJohn Forte 	/* Wait for 30 seconds for slot. */
250*fcf3ce44SJohn Forte 	for (timer = 30000; timer != 0; timer--) {
251*fcf3ce44SJohn Forte 		/* Acquire ring lock. */
252*fcf3ce44SJohn Forte 		REQUEST_RING_LOCK(ha);
253*fcf3ce44SJohn Forte 
254*fcf3ce44SJohn Forte 		if (ha->req_q_cnt == 0) {
255*fcf3ce44SJohn Forte 			/* Calculate number of free request entries. */
256*fcf3ce44SJohn Forte 			cnt = RD16_IO_REG(ha, req_out);
257*fcf3ce44SJohn Forte 			if (ha->req_ring_index < cnt) {
258*fcf3ce44SJohn Forte 				ha->req_q_cnt = (uint16_t)
259*fcf3ce44SJohn Forte 				    (cnt - ha->req_ring_index);
260*fcf3ce44SJohn Forte 			} else {
261*fcf3ce44SJohn Forte 				ha->req_q_cnt = (uint16_t)
262*fcf3ce44SJohn Forte 				    (REQUEST_ENTRY_CNT -
263*fcf3ce44SJohn Forte 				    (ha->req_ring_index - cnt));
264*fcf3ce44SJohn Forte 			}
265*fcf3ce44SJohn Forte 			if (ha->req_q_cnt != 0) {
266*fcf3ce44SJohn Forte 				ha->req_q_cnt--;
267*fcf3ce44SJohn Forte 			}
268*fcf3ce44SJohn Forte 		}
269*fcf3ce44SJohn Forte 
270*fcf3ce44SJohn Forte 		/* Found empty request ring slot? */
271*fcf3ce44SJohn Forte 		if (ha->req_q_cnt != 0) {
272*fcf3ce44SJohn Forte 			ha->req_q_cnt--;
273*fcf3ce44SJohn Forte 			*pktp = ha->request_ring_ptr;
274*fcf3ce44SJohn Forte 
275*fcf3ce44SJohn Forte 			/* Zero out packet. */
276*fcf3ce44SJohn Forte 			long_ptr = (uint32_t *)ha->request_ring_ptr;
277*fcf3ce44SJohn Forte 			for (cnt = 0; cnt < REQUEST_ENTRY_SIZE/4; cnt++) {
278*fcf3ce44SJohn Forte 				*long_ptr++ = 0;
279*fcf3ce44SJohn Forte 			}
280*fcf3ce44SJohn Forte 
281*fcf3ce44SJohn Forte 			/* Setup IOCB common data. */
282*fcf3ce44SJohn Forte 			ha->request_ring_ptr->entry_count = 1;
283*fcf3ce44SJohn Forte 			ha->request_ring_ptr->sys_define =
284*fcf3ce44SJohn Forte 			    (uint8_t)ha->req_ring_index;
285*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
286*fcf3ce44SJohn Forte 			    &ha->request_ring_ptr->handle,
287*fcf3ce44SJohn Forte 			    (uint32_t)QL_FCA_BRAND);
288*fcf3ce44SJohn Forte 
289*fcf3ce44SJohn Forte 			rval = QL_SUCCESS;
290*fcf3ce44SJohn Forte 
291*fcf3ce44SJohn Forte 			break;
292*fcf3ce44SJohn Forte 		}
293*fcf3ce44SJohn Forte 
294*fcf3ce44SJohn Forte 		/* Release request queue lock. */
295*fcf3ce44SJohn Forte 		REQUEST_RING_UNLOCK(ha);
296*fcf3ce44SJohn Forte 
297*fcf3ce44SJohn Forte 		drv_usecwait(MILLISEC);
298*fcf3ce44SJohn Forte 
299*fcf3ce44SJohn Forte 		/* Check for pending interrupts. */
300*fcf3ce44SJohn Forte 		/*
301*fcf3ce44SJohn Forte 		 * XXX protect interrupt routine from calling itself.
302*fcf3ce44SJohn Forte 		 * Need to revisit this routine. So far we never
303*fcf3ce44SJohn Forte 		 * hit this case as req slot was available
304*fcf3ce44SJohn Forte 		 */
305*fcf3ce44SJohn Forte 		if ((!(curthread->t_flag & T_INTR_THREAD)) &&
306*fcf3ce44SJohn Forte 		    (RD16_IO_REG(ha, istatus) & RISC_INT)) {
307*fcf3ce44SJohn Forte 			(void) ql_isr((caddr_t)ha);
308*fcf3ce44SJohn Forte 			INTR_LOCK(ha);
309*fcf3ce44SJohn Forte 			ha->intr_claimed = TRUE;
310*fcf3ce44SJohn Forte 			INTR_UNLOCK(ha);
311*fcf3ce44SJohn Forte 		}
312*fcf3ce44SJohn Forte 	}
313*fcf3ce44SJohn Forte 
314*fcf3ce44SJohn Forte 	if (rval != QL_SUCCESS) {
315*fcf3ce44SJohn Forte 		ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0);
316*fcf3ce44SJohn Forte 		EL(ha, "failed, rval = %xh, isp_abort_needed\n", rval);
317*fcf3ce44SJohn Forte 	} else {
318*fcf3ce44SJohn Forte 		/*EMPTY*/
319*fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
320*fcf3ce44SJohn Forte 	}
321*fcf3ce44SJohn Forte 	return (rval);
322*fcf3ce44SJohn Forte }
323*fcf3ce44SJohn Forte 
324*fcf3ce44SJohn Forte /*
325*fcf3ce44SJohn Forte  * ql_isp_cmd
326*fcf3ce44SJohn Forte  *	Function is responsible for modifying ISP input pointer.
327*fcf3ce44SJohn Forte  *	Releases ring lock.
328*fcf3ce44SJohn Forte  *
329*fcf3ce44SJohn Forte  * Input:
330*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
331*fcf3ce44SJohn Forte  *
332*fcf3ce44SJohn Forte  * Context:
333*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
334*fcf3ce44SJohn Forte  */
335*fcf3ce44SJohn Forte void
336*fcf3ce44SJohn Forte ql_isp_cmd(ql_adapter_state_t *vha)
337*fcf3ce44SJohn Forte {
338*fcf3ce44SJohn Forte 	ql_adapter_state_t	*ha = vha->pha;
339*fcf3ce44SJohn Forte 
340*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
341*fcf3ce44SJohn Forte 
342*fcf3ce44SJohn Forte 	QL_PRINT_5(CE_CONT, "(%d): req packet:\n", ha->instance);
343*fcf3ce44SJohn Forte 	QL_DUMP_5((uint8_t *)ha->request_ring_ptr, 8, REQUEST_ENTRY_SIZE);
344*fcf3ce44SJohn Forte 
345*fcf3ce44SJohn Forte 	/* Sync DMA buffer. */
346*fcf3ce44SJohn Forte 	(void) ddi_dma_sync(ha->hba_buf.dma_handle,
347*fcf3ce44SJohn Forte 	    (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE +
348*fcf3ce44SJohn Forte 	    REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE,
349*fcf3ce44SJohn Forte 	    DDI_DMA_SYNC_FORDEV);
350*fcf3ce44SJohn Forte 
351*fcf3ce44SJohn Forte 	/* Adjust ring index. */
352*fcf3ce44SJohn Forte 	ha->req_ring_index++;
353*fcf3ce44SJohn Forte 	if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
354*fcf3ce44SJohn Forte 		ha->req_ring_index = 0;
355*fcf3ce44SJohn Forte 		ha->request_ring_ptr = ha->request_ring_bp;
356*fcf3ce44SJohn Forte 	} else {
357*fcf3ce44SJohn Forte 		ha->request_ring_ptr++;
358*fcf3ce44SJohn Forte 	}
359*fcf3ce44SJohn Forte 
360*fcf3ce44SJohn Forte 	/* Set chip new ring index. */
361*fcf3ce44SJohn Forte 	WRT16_IO_REG(ha, req_in, ha->req_ring_index);
362*fcf3ce44SJohn Forte 
363*fcf3ce44SJohn Forte 	/* Release ring lock. */
364*fcf3ce44SJohn Forte 	REQUEST_RING_UNLOCK(ha);
365*fcf3ce44SJohn Forte 
366*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
367*fcf3ce44SJohn Forte }
368*fcf3ce44SJohn Forte 
369*fcf3ce44SJohn Forte /*
370*fcf3ce44SJohn Forte  * ql_command_iocb
371*fcf3ce44SJohn Forte  *	Setup of command IOCB.
372*fcf3ce44SJohn Forte  *
373*fcf3ce44SJohn Forte  * Input:
374*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
375*fcf3ce44SJohn Forte  *	sp:	srb structure pointer.
376*fcf3ce44SJohn Forte  *
377*fcf3ce44SJohn Forte  *	arg:	request queue packet.
378*fcf3ce44SJohn Forte  *
379*fcf3ce44SJohn Forte  * Context:
380*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
381*fcf3ce44SJohn Forte  */
382*fcf3ce44SJohn Forte void
383*fcf3ce44SJohn Forte ql_command_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
384*fcf3ce44SJohn Forte {
385*fcf3ce44SJohn Forte 	ddi_dma_cookie_t	*cp;
386*fcf3ce44SJohn Forte 	uint32_t		*ptr32, cnt;
387*fcf3ce44SJohn Forte 	uint16_t		seg_cnt;
388*fcf3ce44SJohn Forte 	fcp_cmd_t		*fcp = sp->fcp;
389*fcf3ce44SJohn Forte 	ql_tgt_t		*tq = sp->lun_queue->target_queue;
390*fcf3ce44SJohn Forte 	cmd_entry_t		*pkt = arg;
391*fcf3ce44SJohn Forte 
392*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
393*fcf3ce44SJohn Forte 
394*fcf3ce44SJohn Forte 	/* Set LUN number */
395*fcf3ce44SJohn Forte 	pkt->lun_l = LSB(sp->lun_queue->lun_no);
396*fcf3ce44SJohn Forte 	pkt->lun_h = MSB(sp->lun_queue->lun_no);
397*fcf3ce44SJohn Forte 
398*fcf3ce44SJohn Forte 	/* Set target ID */
399*fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
400*fcf3ce44SJohn Forte 		pkt->target_l = LSB(tq->loop_id);
401*fcf3ce44SJohn Forte 		pkt->target_h = MSB(tq->loop_id);
402*fcf3ce44SJohn Forte 	} else {
403*fcf3ce44SJohn Forte 		pkt->target_h = LSB(tq->loop_id);
404*fcf3ce44SJohn Forte 	}
405*fcf3ce44SJohn Forte 
406*fcf3ce44SJohn Forte 	/* Set tag queue control flags */
407*fcf3ce44SJohn Forte 	if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_HEAD_OF_Q) {
408*fcf3ce44SJohn Forte 		pkt->control_flags_l = (uint8_t)
409*fcf3ce44SJohn Forte 		    (pkt->control_flags_l | CF_HTAG);
410*fcf3ce44SJohn Forte 	} else if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_ORDERED) {
411*fcf3ce44SJohn Forte 		pkt->control_flags_l = (uint8_t)
412*fcf3ce44SJohn Forte 		    (pkt->control_flags_l | CF_OTAG);
413*fcf3ce44SJohn Forte 	/* else if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_SIMPLE) */
414*fcf3ce44SJohn Forte 	} else {
415*fcf3ce44SJohn Forte 		pkt->control_flags_l = (uint8_t)
416*fcf3ce44SJohn Forte 		    (pkt->control_flags_l | CF_STAG);
417*fcf3ce44SJohn Forte 	}
418*fcf3ce44SJohn Forte 
419*fcf3ce44SJohn Forte 	/* Set ISP command timeout. */
420*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout);
421*fcf3ce44SJohn Forte 
422*fcf3ce44SJohn Forte 	/* Load SCSI CDB */
423*fcf3ce44SJohn Forte 	ddi_rep_put8(ha->hba_buf.acc_handle, fcp->fcp_cdb,
424*fcf3ce44SJohn Forte 	    pkt->scsi_cdb, MAX_CMDSZ, DDI_DEV_AUTOINCR);
425*fcf3ce44SJohn Forte 
426*fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
427*fcf3ce44SJohn Forte 		pkt->entry_type = IOCB_CMD_TYPE_3;
428*fcf3ce44SJohn Forte 		cnt = CMD_TYPE_3_DATA_SEGMENTS;
429*fcf3ce44SJohn Forte 	} else {
430*fcf3ce44SJohn Forte 		pkt->entry_type = IOCB_CMD_TYPE_2;
431*fcf3ce44SJohn Forte 		cnt = CMD_TYPE_2_DATA_SEGMENTS;
432*fcf3ce44SJohn Forte 	}
433*fcf3ce44SJohn Forte 
434*fcf3ce44SJohn Forte 	if (fcp->fcp_data_len == 0) {
435*fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
436*fcf3ce44SJohn Forte 		ha->xioctl->IOControlRequests++;
437*fcf3ce44SJohn Forte 		return;
438*fcf3ce44SJohn Forte 	}
439*fcf3ce44SJohn Forte 
440*fcf3ce44SJohn Forte 	/*
441*fcf3ce44SJohn Forte 	 * Set transfer direction. Load Data segments.
442*fcf3ce44SJohn Forte 	 */
443*fcf3ce44SJohn Forte 	if (fcp->fcp_cntl.cntl_write_data) {
444*fcf3ce44SJohn Forte 		pkt->control_flags_l = (uint8_t)
445*fcf3ce44SJohn Forte 		    (pkt->control_flags_l | CF_DATA_OUT);
446*fcf3ce44SJohn Forte 		ha->xioctl->IOOutputRequests++;
447*fcf3ce44SJohn Forte 		ha->xioctl->IOOutputByteCnt += fcp->fcp_data_len;
448*fcf3ce44SJohn Forte 	} else if (fcp->fcp_cntl.cntl_read_data) {
449*fcf3ce44SJohn Forte 		pkt->control_flags_l = (uint8_t)
450*fcf3ce44SJohn Forte 		    (pkt->control_flags_l | CF_DATA_IN);
451*fcf3ce44SJohn Forte 		ha->xioctl->IOInputRequests++;
452*fcf3ce44SJohn Forte 		ha->xioctl->IOInputByteCnt += fcp->fcp_data_len;
453*fcf3ce44SJohn Forte 	}
454*fcf3ce44SJohn Forte 
455*fcf3ce44SJohn Forte 	/* Set data segment count. */
456*fcf3ce44SJohn Forte 	seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt;
457*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
458*fcf3ce44SJohn Forte 
459*fcf3ce44SJohn Forte 	/* Load total byte count. */
460*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, fcp->fcp_data_len);
461*fcf3ce44SJohn Forte 
462*fcf3ce44SJohn Forte 	/* Load command data segment. */
463*fcf3ce44SJohn Forte 	ptr32 = (uint32_t *)&pkt->dseg_0_address;
464*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_data_cookie;
465*fcf3ce44SJohn Forte 	while (cnt && seg_cnt) {
466*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
467*fcf3ce44SJohn Forte 		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
468*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle, ptr32++,
469*fcf3ce44SJohn Forte 			    cp->dmac_notused);
470*fcf3ce44SJohn Forte 		}
471*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle, ptr32++,
472*fcf3ce44SJohn Forte 		    (uint32_t)cp->dmac_size);
473*fcf3ce44SJohn Forte 		seg_cnt--;
474*fcf3ce44SJohn Forte 		cnt--;
475*fcf3ce44SJohn Forte 		cp++;
476*fcf3ce44SJohn Forte 	}
477*fcf3ce44SJohn Forte 
478*fcf3ce44SJohn Forte 	/*
479*fcf3ce44SJohn Forte 	 * Build continuation packets.
480*fcf3ce44SJohn Forte 	 */
481*fcf3ce44SJohn Forte 	if (seg_cnt) {
482*fcf3ce44SJohn Forte 		ql_continuation_iocb(ha, cp, seg_cnt,
483*fcf3ce44SJohn Forte 		    (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)));
484*fcf3ce44SJohn Forte 	}
485*fcf3ce44SJohn Forte 
486*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
487*fcf3ce44SJohn Forte }
488*fcf3ce44SJohn Forte 
489*fcf3ce44SJohn Forte /*
490*fcf3ce44SJohn Forte  * ql_continuation_iocb
491*fcf3ce44SJohn Forte  *	Setup of continuation IOCB.
492*fcf3ce44SJohn Forte  *
493*fcf3ce44SJohn Forte  * Input:
494*fcf3ce44SJohn Forte  *	ha:		adapter state pointer.
495*fcf3ce44SJohn Forte  *	cp:		cookie list pointer.
496*fcf3ce44SJohn Forte  *	seg_cnt:	number of segments.
497*fcf3ce44SJohn Forte  *	addr64:		64 bit addresses.
498*fcf3ce44SJohn Forte  *
499*fcf3ce44SJohn Forte  * Context:
500*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
501*fcf3ce44SJohn Forte  */
502*fcf3ce44SJohn Forte static void
503*fcf3ce44SJohn Forte ql_continuation_iocb(ql_adapter_state_t *ha, ddi_dma_cookie_t *cp,
504*fcf3ce44SJohn Forte     uint16_t seg_cnt, boolean_t addr64)
505*fcf3ce44SJohn Forte {
506*fcf3ce44SJohn Forte 	cont_entry_t	*pkt;
507*fcf3ce44SJohn Forte 	uint64_t	*ptr64;
508*fcf3ce44SJohn Forte 	uint32_t	*ptr32, cnt;
509*fcf3ce44SJohn Forte 
510*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
511*fcf3ce44SJohn Forte 
512*fcf3ce44SJohn Forte 	/*
513*fcf3ce44SJohn Forte 	 * Build continuation packets.
514*fcf3ce44SJohn Forte 	 */
515*fcf3ce44SJohn Forte 	while (seg_cnt) {
516*fcf3ce44SJohn Forte 		/* Sync DMA buffer. */
517*fcf3ce44SJohn Forte 		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
518*fcf3ce44SJohn Forte 		    (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE +
519*fcf3ce44SJohn Forte 		    REQUEST_Q_BUFFER_OFFSET), REQUEST_ENTRY_SIZE,
520*fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORDEV);
521*fcf3ce44SJohn Forte 
522*fcf3ce44SJohn Forte 		/* Adjust ring pointer, and deal with wrap. */
523*fcf3ce44SJohn Forte 		ha->req_ring_index++;
524*fcf3ce44SJohn Forte 		if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
525*fcf3ce44SJohn Forte 			ha->req_ring_index = 0;
526*fcf3ce44SJohn Forte 			ha->request_ring_ptr = ha->request_ring_bp;
527*fcf3ce44SJohn Forte 		} else {
528*fcf3ce44SJohn Forte 			ha->request_ring_ptr++;
529*fcf3ce44SJohn Forte 		}
530*fcf3ce44SJohn Forte 		pkt = (cont_entry_t *)ha->request_ring_ptr;
531*fcf3ce44SJohn Forte 
532*fcf3ce44SJohn Forte 		/* Zero out packet. */
533*fcf3ce44SJohn Forte 		ptr64 = (uint64_t *)pkt;
534*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64++ = 0;
535*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64++ = 0;
536*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64++ = 0;
537*fcf3ce44SJohn Forte 		*ptr64++ = 0; *ptr64 = 0;
538*fcf3ce44SJohn Forte 
539*fcf3ce44SJohn Forte 		/*
540*fcf3ce44SJohn Forte 		 * Build continuation packet.
541*fcf3ce44SJohn Forte 		 */
542*fcf3ce44SJohn Forte 		pkt->entry_count = 1;
543*fcf3ce44SJohn Forte 		pkt->sys_define = (uint8_t)ha->req_ring_index;
544*fcf3ce44SJohn Forte 		if (addr64) {
545*fcf3ce44SJohn Forte 			pkt->entry_type = CONTINUATION_TYPE_1;
546*fcf3ce44SJohn Forte 			cnt = CONT_TYPE_1_DATA_SEGMENTS;
547*fcf3ce44SJohn Forte 			ptr32 = (uint32_t *)
548*fcf3ce44SJohn Forte 			    &((cont_type_1_entry_t *)pkt)->dseg_0_address;
549*fcf3ce44SJohn Forte 			while (cnt && seg_cnt) {
550*fcf3ce44SJohn Forte 				ddi_put32(ha->hba_buf.acc_handle, ptr32++,
551*fcf3ce44SJohn Forte 				    cp->dmac_address);
552*fcf3ce44SJohn Forte 				ddi_put32(ha->hba_buf.acc_handle, ptr32++,
553*fcf3ce44SJohn Forte 				    cp->dmac_notused);
554*fcf3ce44SJohn Forte 				ddi_put32(ha->hba_buf.acc_handle, ptr32++,
555*fcf3ce44SJohn Forte 				    (uint32_t)cp->dmac_size);
556*fcf3ce44SJohn Forte 				seg_cnt--;
557*fcf3ce44SJohn Forte 				cnt--;
558*fcf3ce44SJohn Forte 				cp++;
559*fcf3ce44SJohn Forte 			}
560*fcf3ce44SJohn Forte 		} else {
561*fcf3ce44SJohn Forte 			pkt->entry_type = CONTINUATION_TYPE_0;
562*fcf3ce44SJohn Forte 			cnt = CONT_TYPE_0_DATA_SEGMENTS;
563*fcf3ce44SJohn Forte 			ptr32 = (uint32_t *)&pkt->dseg_0_address;
564*fcf3ce44SJohn Forte 			while (cnt && seg_cnt) {
565*fcf3ce44SJohn Forte 				ddi_put32(ha->hba_buf.acc_handle, ptr32++,
566*fcf3ce44SJohn Forte 				    cp->dmac_address);
567*fcf3ce44SJohn Forte 				ddi_put32(ha->hba_buf.acc_handle, ptr32++,
568*fcf3ce44SJohn Forte 				    (uint32_t)cp->dmac_size);
569*fcf3ce44SJohn Forte 				seg_cnt--;
570*fcf3ce44SJohn Forte 				cnt--;
571*fcf3ce44SJohn Forte 				cp++;
572*fcf3ce44SJohn Forte 			}
573*fcf3ce44SJohn Forte 		}
574*fcf3ce44SJohn Forte 
575*fcf3ce44SJohn Forte 		QL_PRINT_5(CE_CONT, "(%d): packet:\n", ha->instance);
576*fcf3ce44SJohn Forte 		QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE);
577*fcf3ce44SJohn Forte 	}
578*fcf3ce44SJohn Forte 
579*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
580*fcf3ce44SJohn Forte }
581*fcf3ce44SJohn Forte 
582*fcf3ce44SJohn Forte /*
583*fcf3ce44SJohn Forte  * ql_command_24xx_iocb
584*fcf3ce44SJohn Forte  *	Setup of ISP24xx command IOCB.
585*fcf3ce44SJohn Forte  *
586*fcf3ce44SJohn Forte  * Input:
587*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
588*fcf3ce44SJohn Forte  *	sp:	srb structure pointer.
589*fcf3ce44SJohn Forte  *	arg:	request queue packet.
590*fcf3ce44SJohn Forte  *
591*fcf3ce44SJohn Forte  * Context:
592*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
593*fcf3ce44SJohn Forte  */
594*fcf3ce44SJohn Forte void
595*fcf3ce44SJohn Forte ql_command_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
596*fcf3ce44SJohn Forte {
597*fcf3ce44SJohn Forte 	ddi_dma_cookie_t	*cp;
598*fcf3ce44SJohn Forte 	uint32_t		*ptr32, cnt;
599*fcf3ce44SJohn Forte 	uint16_t		seg_cnt;
600*fcf3ce44SJohn Forte 	fcp_cmd_t		*fcp = sp->fcp;
601*fcf3ce44SJohn Forte 	ql_tgt_t		*tq = sp->lun_queue->target_queue;
602*fcf3ce44SJohn Forte 	cmd_24xx_entry_t	*pkt = arg;
603*fcf3ce44SJohn Forte 	ql_adapter_state_t	*pha = ha->pha;
604*fcf3ce44SJohn Forte 
605*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
606*fcf3ce44SJohn Forte 
607*fcf3ce44SJohn Forte 	pkt->entry_type = IOCB_CMD_TYPE_7;
608*fcf3ce44SJohn Forte 
609*fcf3ce44SJohn Forte 	/* Set LUN number */
610*fcf3ce44SJohn Forte 	pkt->fcp_lun[2] = LSB(sp->lun_queue->lun_no);
611*fcf3ce44SJohn Forte 	pkt->fcp_lun[3] = MSB(sp->lun_queue->lun_no);
612*fcf3ce44SJohn Forte 
613*fcf3ce44SJohn Forte 	/* Set N_port handle */
614*fcf3ce44SJohn Forte 	ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id);
615*fcf3ce44SJohn Forte 
616*fcf3ce44SJohn Forte 	/* Set target ID */
617*fcf3ce44SJohn Forte 	pkt->target_id[0] = tq->d_id.b.al_pa;
618*fcf3ce44SJohn Forte 	pkt->target_id[1] = tq->d_id.b.area;
619*fcf3ce44SJohn Forte 	pkt->target_id[2] = tq->d_id.b.domain;
620*fcf3ce44SJohn Forte 
621*fcf3ce44SJohn Forte 	pkt->vp_index = ha->vp_index;
622*fcf3ce44SJohn Forte 
623*fcf3ce44SJohn Forte 	/* Set ISP command timeout. */
624*fcf3ce44SJohn Forte 	if (sp->isp_timeout < 0x1999) {
625*fcf3ce44SJohn Forte 		ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout,
626*fcf3ce44SJohn Forte 		    sp->isp_timeout);
627*fcf3ce44SJohn Forte 	}
628*fcf3ce44SJohn Forte 
629*fcf3ce44SJohn Forte 	/* Load SCSI CDB */
630*fcf3ce44SJohn Forte 	ddi_rep_put8(pha->hba_buf.acc_handle, fcp->fcp_cdb, pkt->scsi_cdb,
631*fcf3ce44SJohn Forte 	    MAX_CMDSZ, DDI_DEV_AUTOINCR);
632*fcf3ce44SJohn Forte 	for (cnt = 0; cnt < MAX_CMDSZ; cnt += 4) {
633*fcf3ce44SJohn Forte 		ql_chg_endian((uint8_t *)&pkt->scsi_cdb + cnt, 4);
634*fcf3ce44SJohn Forte 	}
635*fcf3ce44SJohn Forte 
636*fcf3ce44SJohn Forte 	/*
637*fcf3ce44SJohn Forte 	 * Set tag queue control flags
638*fcf3ce44SJohn Forte 	 * Note:
639*fcf3ce44SJohn Forte 	 *	Cannot copy fcp->fcp_cntl.cntl_qtype directly,
640*fcf3ce44SJohn Forte 	 *	problem with x86 in 32bit kernel mode
641*fcf3ce44SJohn Forte 	 */
642*fcf3ce44SJohn Forte 	switch (fcp->fcp_cntl.cntl_qtype) {
643*fcf3ce44SJohn Forte 	case FCP_QTYPE_SIMPLE:
644*fcf3ce44SJohn Forte 		pkt->task = TA_STAG;
645*fcf3ce44SJohn Forte 		break;
646*fcf3ce44SJohn Forte 	case FCP_QTYPE_HEAD_OF_Q:
647*fcf3ce44SJohn Forte 		pkt->task = TA_HTAG;
648*fcf3ce44SJohn Forte 		break;
649*fcf3ce44SJohn Forte 	case FCP_QTYPE_ORDERED:
650*fcf3ce44SJohn Forte 		pkt->task = TA_OTAG;
651*fcf3ce44SJohn Forte 		break;
652*fcf3ce44SJohn Forte 	case FCP_QTYPE_ACA_Q_TAG:
653*fcf3ce44SJohn Forte 		pkt->task = TA_ACA;
654*fcf3ce44SJohn Forte 		break;
655*fcf3ce44SJohn Forte 	case FCP_QTYPE_UNTAGGED:
656*fcf3ce44SJohn Forte 		pkt->task = TA_UNTAGGED;
657*fcf3ce44SJohn Forte 		break;
658*fcf3ce44SJohn Forte 	default:
659*fcf3ce44SJohn Forte 		break;
660*fcf3ce44SJohn Forte 	}
661*fcf3ce44SJohn Forte 
662*fcf3ce44SJohn Forte 	if (fcp->fcp_data_len == 0) {
663*fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
664*fcf3ce44SJohn Forte 		pha->xioctl->IOControlRequests++;
665*fcf3ce44SJohn Forte 		return;
666*fcf3ce44SJohn Forte 	}
667*fcf3ce44SJohn Forte 
668*fcf3ce44SJohn Forte 	/* Set transfer direction. */
669*fcf3ce44SJohn Forte 	if (fcp->fcp_cntl.cntl_write_data) {
670*fcf3ce44SJohn Forte 		pkt->control_flags = CF_WR;
671*fcf3ce44SJohn Forte 		pha->xioctl->IOOutputRequests++;
672*fcf3ce44SJohn Forte 		pha->xioctl->IOOutputByteCnt += fcp->fcp_data_len;
673*fcf3ce44SJohn Forte 	} else if (fcp->fcp_cntl.cntl_read_data) {
674*fcf3ce44SJohn Forte 		pkt->control_flags = CF_RD;
675*fcf3ce44SJohn Forte 		pha->xioctl->IOInputRequests++;
676*fcf3ce44SJohn Forte 		pha->xioctl->IOInputByteCnt += fcp->fcp_data_len;
677*fcf3ce44SJohn Forte 	}
678*fcf3ce44SJohn Forte 
679*fcf3ce44SJohn Forte 	/* Set data segment count. */
680*fcf3ce44SJohn Forte 	seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt;
681*fcf3ce44SJohn Forte 	ddi_put16(pha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
682*fcf3ce44SJohn Forte 
683*fcf3ce44SJohn Forte 	/* Load total byte count. */
684*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, &pkt->total_byte_count,
685*fcf3ce44SJohn Forte 	    fcp->fcp_data_len);
686*fcf3ce44SJohn Forte 
687*fcf3ce44SJohn Forte 	/* Load command data segment. */
688*fcf3ce44SJohn Forte 	ptr32 = (uint32_t *)&pkt->dseg_0_address;
689*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_data_cookie;
690*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
691*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
692*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
693*fcf3ce44SJohn Forte 	seg_cnt--;
694*fcf3ce44SJohn Forte 	cp++;
695*fcf3ce44SJohn Forte 
696*fcf3ce44SJohn Forte 	/*
697*fcf3ce44SJohn Forte 	 * Build continuation packets.
698*fcf3ce44SJohn Forte 	 */
699*fcf3ce44SJohn Forte 	if (seg_cnt) {
700*fcf3ce44SJohn Forte 		ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE);
701*fcf3ce44SJohn Forte 	}
702*fcf3ce44SJohn Forte 
703*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
704*fcf3ce44SJohn Forte }
705*fcf3ce44SJohn Forte 
706*fcf3ce44SJohn Forte /*
707*fcf3ce44SJohn Forte  * ql_marker
708*fcf3ce44SJohn Forte  *	Function issues marker IOCB.
709*fcf3ce44SJohn Forte  *
710*fcf3ce44SJohn Forte  * Input:
711*fcf3ce44SJohn Forte  *	ha:		adapter state pointer.
712*fcf3ce44SJohn Forte  *	loop_id:	device loop ID
713*fcf3ce44SJohn Forte  *	lun:		device LUN
714*fcf3ce44SJohn Forte  *	type:		marker modifier
715*fcf3ce44SJohn Forte  *
716*fcf3ce44SJohn Forte  * Returns:
717*fcf3ce44SJohn Forte  *	ql local function return status code.
718*fcf3ce44SJohn Forte  *
719*fcf3ce44SJohn Forte  * Context:
720*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
721*fcf3ce44SJohn Forte  */
722*fcf3ce44SJohn Forte int
723*fcf3ce44SJohn Forte ql_marker(ql_adapter_state_t *ha, uint16_t loop_id, uint16_t lun,
724*fcf3ce44SJohn Forte     uint8_t type)
725*fcf3ce44SJohn Forte {
726*fcf3ce44SJohn Forte 	mrk_entry_t	*pkt;
727*fcf3ce44SJohn Forte 	int		rval;
728*fcf3ce44SJohn Forte 
729*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
730*fcf3ce44SJohn Forte 
731*fcf3ce44SJohn Forte 	rval = ql_req_pkt(ha, (request_t **)&pkt);
732*fcf3ce44SJohn Forte 	if (rval == QL_SUCCESS) {
733*fcf3ce44SJohn Forte 		pkt->entry_type = MARKER_TYPE;
734*fcf3ce44SJohn Forte 
735*fcf3ce44SJohn Forte 		if (CFG_IST(ha, CFG_CTRL_2425)) {
736*fcf3ce44SJohn Forte 			marker_24xx_entry_t	*pkt24 =
737*fcf3ce44SJohn Forte 			    (marker_24xx_entry_t *)pkt;
738*fcf3ce44SJohn Forte 
739*fcf3ce44SJohn Forte 			pkt24->modifier = type;
740*fcf3ce44SJohn Forte 
741*fcf3ce44SJohn Forte 			/* Set LUN number */
742*fcf3ce44SJohn Forte 			pkt24->fcp_lun[2] = LSB(lun);
743*fcf3ce44SJohn Forte 			pkt24->fcp_lun[3] = MSB(lun);
744*fcf3ce44SJohn Forte 
745*fcf3ce44SJohn Forte 			pkt24->vp_index = ha->vp_index;
746*fcf3ce44SJohn Forte 
747*fcf3ce44SJohn Forte 			/* Set N_port handle */
748*fcf3ce44SJohn Forte 			ddi_put16(ha->pha->hba_buf.acc_handle,
749*fcf3ce44SJohn Forte 			    &pkt24->n_port_hdl, loop_id);
750*fcf3ce44SJohn Forte 
751*fcf3ce44SJohn Forte 		} else {
752*fcf3ce44SJohn Forte 			pkt->modifier = type;
753*fcf3ce44SJohn Forte 
754*fcf3ce44SJohn Forte 			pkt->lun_l = LSB(lun);
755*fcf3ce44SJohn Forte 			pkt->lun_h = MSB(lun);
756*fcf3ce44SJohn Forte 
757*fcf3ce44SJohn Forte 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
758*fcf3ce44SJohn Forte 				pkt->target_l = LSB(loop_id);
759*fcf3ce44SJohn Forte 				pkt->target_h = MSB(loop_id);
760*fcf3ce44SJohn Forte 			} else {
761*fcf3ce44SJohn Forte 				pkt->target_h = LSB(loop_id);
762*fcf3ce44SJohn Forte 			}
763*fcf3ce44SJohn Forte 		}
764*fcf3ce44SJohn Forte 
765*fcf3ce44SJohn Forte 		/* Issue command to ISP */
766*fcf3ce44SJohn Forte 		ql_isp_cmd(ha);
767*fcf3ce44SJohn Forte 	}
768*fcf3ce44SJohn Forte 
769*fcf3ce44SJohn Forte 	if (rval != QL_SUCCESS) {
770*fcf3ce44SJohn Forte 		EL(ha, "failed, rval = %xh\n", rval);
771*fcf3ce44SJohn Forte 	} else {
772*fcf3ce44SJohn Forte 		/*EMPTY*/
773*fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
774*fcf3ce44SJohn Forte 	}
775*fcf3ce44SJohn Forte 	return (rval);
776*fcf3ce44SJohn Forte }
777*fcf3ce44SJohn Forte 
778*fcf3ce44SJohn Forte /*
779*fcf3ce44SJohn Forte  * ql_ms_iocb
780*fcf3ce44SJohn Forte  *	Setup of name/management server IOCB.
781*fcf3ce44SJohn Forte  *
782*fcf3ce44SJohn Forte  * Input:
783*fcf3ce44SJohn Forte  *	ha = adapter state pointer.
784*fcf3ce44SJohn Forte  *	sp = srb structure pointer.
785*fcf3ce44SJohn Forte  *	arg = request queue packet.
786*fcf3ce44SJohn Forte  *
787*fcf3ce44SJohn Forte  * Context:
788*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
789*fcf3ce44SJohn Forte  */
790*fcf3ce44SJohn Forte void
791*fcf3ce44SJohn Forte ql_ms_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
792*fcf3ce44SJohn Forte {
793*fcf3ce44SJohn Forte 	ddi_dma_cookie_t	*cp;
794*fcf3ce44SJohn Forte 	uint32_t		*ptr32;
795*fcf3ce44SJohn Forte 	uint16_t		seg_cnt;
796*fcf3ce44SJohn Forte 	ql_tgt_t		*tq = sp->lun_queue->target_queue;
797*fcf3ce44SJohn Forte 	ms_entry_t		*pkt = arg;
798*fcf3ce44SJohn Forte 
799*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
800*fcf3ce44SJohn Forte #if 0
801*fcf3ce44SJohn Forte 	QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen);
802*fcf3ce44SJohn Forte #endif
803*fcf3ce44SJohn Forte 	/*
804*fcf3ce44SJohn Forte 	 * Build command packet.
805*fcf3ce44SJohn Forte 	 */
806*fcf3ce44SJohn Forte 	pkt->entry_type = MS_TYPE;
807*fcf3ce44SJohn Forte 
808*fcf3ce44SJohn Forte 	/* Set loop ID */
809*fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
810*fcf3ce44SJohn Forte 		pkt->loop_id_l = LSB(tq->loop_id);
811*fcf3ce44SJohn Forte 		pkt->loop_id_h = MSB(tq->loop_id);
812*fcf3ce44SJohn Forte 	} else {
813*fcf3ce44SJohn Forte 		pkt->loop_id_h = LSB(tq->loop_id);
814*fcf3ce44SJohn Forte 	}
815*fcf3ce44SJohn Forte 
816*fcf3ce44SJohn Forte 	/* Set ISP command timeout. */
817*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout);
818*fcf3ce44SJohn Forte 
819*fcf3ce44SJohn Forte 	/* Set cmd data segment count. */
820*fcf3ce44SJohn Forte 	pkt->cmd_dseg_count_l = 1;
821*fcf3ce44SJohn Forte 
822*fcf3ce44SJohn Forte 	/* Set total data segment count */
823*fcf3ce44SJohn Forte 	seg_cnt = (uint16_t)(sp->pkt->pkt_resp_cookie_cnt + 1);
824*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->total_dseg_count, seg_cnt);
825*fcf3ce44SJohn Forte 
826*fcf3ce44SJohn Forte 	/* Load ct cmd byte count. */
827*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, &pkt->cmd_byte_count,
828*fcf3ce44SJohn Forte 	    (uint32_t)sp->pkt->pkt_cmdlen);
829*fcf3ce44SJohn Forte 
830*fcf3ce44SJohn Forte 	/* Load ct rsp byte count. */
831*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, &pkt->resp_byte_count,
832*fcf3ce44SJohn Forte 	    (uint32_t)sp->pkt->pkt_rsplen);
833*fcf3ce44SJohn Forte 
834*fcf3ce44SJohn Forte 	/* Load MS command data segments. */
835*fcf3ce44SJohn Forte 	ptr32 = (uint32_t *)&pkt->dseg_0_address;
836*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_cmd_cookie;
837*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
838*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
839*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size);
840*fcf3ce44SJohn Forte 	seg_cnt--;
841*fcf3ce44SJohn Forte 
842*fcf3ce44SJohn Forte 	/* Load MS response entry data segments. */
843*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_resp_cookie;
844*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
845*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
846*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
847*fcf3ce44SJohn Forte 	seg_cnt--;
848*fcf3ce44SJohn Forte 	cp++;
849*fcf3ce44SJohn Forte 
850*fcf3ce44SJohn Forte 	/*
851*fcf3ce44SJohn Forte 	 * Build continuation packets.
852*fcf3ce44SJohn Forte 	 */
853*fcf3ce44SJohn Forte 	if (seg_cnt) {
854*fcf3ce44SJohn Forte 		ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE);
855*fcf3ce44SJohn Forte 	}
856*fcf3ce44SJohn Forte 
857*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
858*fcf3ce44SJohn Forte }
859*fcf3ce44SJohn Forte 
860*fcf3ce44SJohn Forte /*
861*fcf3ce44SJohn Forte  * ql_ms_24xx_iocb
862*fcf3ce44SJohn Forte  *	Setup of name/management server IOCB.
863*fcf3ce44SJohn Forte  *
864*fcf3ce44SJohn Forte  * Input:
865*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
866*fcf3ce44SJohn Forte  *	sp:	srb structure pointer.
867*fcf3ce44SJohn Forte  *	arg:	request queue packet.
868*fcf3ce44SJohn Forte  *
869*fcf3ce44SJohn Forte  * Context:
870*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
871*fcf3ce44SJohn Forte  */
872*fcf3ce44SJohn Forte void
873*fcf3ce44SJohn Forte ql_ms_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
874*fcf3ce44SJohn Forte {
875*fcf3ce44SJohn Forte 	ddi_dma_cookie_t	*cp;
876*fcf3ce44SJohn Forte 	uint32_t		*ptr32;
877*fcf3ce44SJohn Forte 	uint16_t		seg_cnt;
878*fcf3ce44SJohn Forte 	ql_tgt_t		*tq = sp->lun_queue->target_queue;
879*fcf3ce44SJohn Forte 	ct_passthru_entry_t	*pkt = arg;
880*fcf3ce44SJohn Forte 	ql_adapter_state_t	*pha = ha->pha;
881*fcf3ce44SJohn Forte 
882*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
883*fcf3ce44SJohn Forte #if 0
884*fcf3ce44SJohn Forte 	QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen);
885*fcf3ce44SJohn Forte #endif
886*fcf3ce44SJohn Forte 	/*
887*fcf3ce44SJohn Forte 	 * Build command packet.
888*fcf3ce44SJohn Forte 	 */
889*fcf3ce44SJohn Forte 	pkt->entry_type = CT_PASSTHRU_TYPE;
890*fcf3ce44SJohn Forte 
891*fcf3ce44SJohn Forte 	/* Set loop ID */
892*fcf3ce44SJohn Forte 	ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id);
893*fcf3ce44SJohn Forte 
894*fcf3ce44SJohn Forte 	pkt->vp_index = ha->vp_index;
895*fcf3ce44SJohn Forte 
896*fcf3ce44SJohn Forte 	/* Set ISP command timeout. */
897*fcf3ce44SJohn Forte 	if (sp->isp_timeout < 0x1999) {
898*fcf3ce44SJohn Forte 		ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout,
899*fcf3ce44SJohn Forte 		    sp->isp_timeout);
900*fcf3ce44SJohn Forte 	}
901*fcf3ce44SJohn Forte 
902*fcf3ce44SJohn Forte 	/* Set cmd/response data segment counts. */
903*fcf3ce44SJohn Forte 	ddi_put16(pha->hba_buf.acc_handle, &pkt->cmd_dseg_count, 1);
904*fcf3ce44SJohn Forte 	seg_cnt = (uint16_t)sp->pkt->pkt_resp_cookie_cnt;
905*fcf3ce44SJohn Forte 	ddi_put16(pha->hba_buf.acc_handle, &pkt->resp_dseg_count, seg_cnt);
906*fcf3ce44SJohn Forte 
907*fcf3ce44SJohn Forte 	/* Load ct cmd byte count. */
908*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, &pkt->cmd_byte_count,
909*fcf3ce44SJohn Forte 	    (uint32_t)sp->pkt->pkt_cmdlen);
910*fcf3ce44SJohn Forte 
911*fcf3ce44SJohn Forte 	/* Load ct rsp byte count. */
912*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, &pkt->resp_byte_count,
913*fcf3ce44SJohn Forte 	    (uint32_t)sp->pkt->pkt_rsplen);
914*fcf3ce44SJohn Forte 
915*fcf3ce44SJohn Forte 	/* Load MS command entry data segments. */
916*fcf3ce44SJohn Forte 	ptr32 = (uint32_t *)&pkt->dseg_0_address;
917*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_cmd_cookie;
918*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
919*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
920*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size);
921*fcf3ce44SJohn Forte 
922*fcf3ce44SJohn Forte 	/* Load MS response entry data segments. */
923*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_resp_cookie;
924*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
925*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
926*fcf3ce44SJohn Forte 	ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
927*fcf3ce44SJohn Forte 	seg_cnt--;
928*fcf3ce44SJohn Forte 	cp++;
929*fcf3ce44SJohn Forte 
930*fcf3ce44SJohn Forte 	/*
931*fcf3ce44SJohn Forte 	 * Build continuation packets.
932*fcf3ce44SJohn Forte 	 */
933*fcf3ce44SJohn Forte 	if (seg_cnt) {
934*fcf3ce44SJohn Forte 		ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE);
935*fcf3ce44SJohn Forte 	}
936*fcf3ce44SJohn Forte 
937*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
938*fcf3ce44SJohn Forte }
939*fcf3ce44SJohn Forte 
940*fcf3ce44SJohn Forte /*
941*fcf3ce44SJohn Forte  * ql_ip_iocb
942*fcf3ce44SJohn Forte  *	Setup of IP IOCB.
943*fcf3ce44SJohn Forte  *
944*fcf3ce44SJohn Forte  * Input:
945*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
946*fcf3ce44SJohn Forte  *	sp:	srb structure pointer.
947*fcf3ce44SJohn Forte  *	arg:	request queue packet.
948*fcf3ce44SJohn Forte  *
949*fcf3ce44SJohn Forte  * Context:
950*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
951*fcf3ce44SJohn Forte  */
952*fcf3ce44SJohn Forte void
953*fcf3ce44SJohn Forte ql_ip_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
954*fcf3ce44SJohn Forte {
955*fcf3ce44SJohn Forte 	ddi_dma_cookie_t	*cp;
956*fcf3ce44SJohn Forte 	uint32_t		*ptr32, cnt;
957*fcf3ce44SJohn Forte 	uint16_t		seg_cnt;
958*fcf3ce44SJohn Forte 	ql_tgt_t		*tq = sp->lun_queue->target_queue;
959*fcf3ce44SJohn Forte 	ip_entry_t		*pkt = arg;
960*fcf3ce44SJohn Forte 
961*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
962*fcf3ce44SJohn Forte 
963*fcf3ce44SJohn Forte 	/* Set loop ID */
964*fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
965*fcf3ce44SJohn Forte 		pkt->loop_id_l = LSB(tq->loop_id);
966*fcf3ce44SJohn Forte 		pkt->loop_id_h = MSB(tq->loop_id);
967*fcf3ce44SJohn Forte 	} else {
968*fcf3ce44SJohn Forte 		pkt->loop_id_h = LSB(tq->loop_id);
969*fcf3ce44SJohn Forte 	}
970*fcf3ce44SJohn Forte 
971*fcf3ce44SJohn Forte 	/* Set control flags */
972*fcf3ce44SJohn Forte 	pkt->control_flags_l = BIT_6;
973*fcf3ce44SJohn Forte 	if (sp->pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) {
974*fcf3ce44SJohn Forte 		pkt->control_flags_h = BIT_7;
975*fcf3ce44SJohn Forte 	}
976*fcf3ce44SJohn Forte 
977*fcf3ce44SJohn Forte 	/* Set ISP command timeout. */
978*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout);
979*fcf3ce44SJohn Forte 
980*fcf3ce44SJohn Forte 	/* Set data segment count. */
981*fcf3ce44SJohn Forte 	seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt;
982*fcf3ce44SJohn Forte 	/* Load total byte count. */
983*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count,
984*fcf3ce44SJohn Forte 	    (uint32_t)sp->pkt->pkt_cmdlen);
985*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
986*fcf3ce44SJohn Forte 
987*fcf3ce44SJohn Forte 	/*
988*fcf3ce44SJohn Forte 	 * Build command packet.
989*fcf3ce44SJohn Forte 	 */
990*fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
991*fcf3ce44SJohn Forte 		pkt->entry_type = IP_A64_TYPE;
992*fcf3ce44SJohn Forte 		cnt = IP_A64_DATA_SEGMENTS;
993*fcf3ce44SJohn Forte 	} else {
994*fcf3ce44SJohn Forte 		pkt->entry_type = IP_TYPE;
995*fcf3ce44SJohn Forte 		cnt = IP_DATA_SEGMENTS;
996*fcf3ce44SJohn Forte 	}
997*fcf3ce44SJohn Forte 
998*fcf3ce44SJohn Forte 	/* Load command entry data segments. */
999*fcf3ce44SJohn Forte 	ptr32 = (uint32_t *)&pkt->dseg_0_address;
1000*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_cmd_cookie;
1001*fcf3ce44SJohn Forte 	while (cnt && seg_cnt) {
1002*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1003*fcf3ce44SJohn Forte 		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1004*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle, ptr32++,
1005*fcf3ce44SJohn Forte 			    cp->dmac_notused);
1006*fcf3ce44SJohn Forte 		}
1007*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle, ptr32++,
1008*fcf3ce44SJohn Forte 		    (uint32_t)cp->dmac_size);
1009*fcf3ce44SJohn Forte 		seg_cnt--;
1010*fcf3ce44SJohn Forte 		cnt--;
1011*fcf3ce44SJohn Forte 		cp++;
1012*fcf3ce44SJohn Forte 	}
1013*fcf3ce44SJohn Forte 
1014*fcf3ce44SJohn Forte 	/*
1015*fcf3ce44SJohn Forte 	 * Build continuation packets.
1016*fcf3ce44SJohn Forte 	 */
1017*fcf3ce44SJohn Forte 	if (seg_cnt) {
1018*fcf3ce44SJohn Forte 		ql_continuation_iocb(ha, cp, seg_cnt,
1019*fcf3ce44SJohn Forte 		    (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)));
1020*fcf3ce44SJohn Forte 	}
1021*fcf3ce44SJohn Forte 
1022*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1023*fcf3ce44SJohn Forte }
1024*fcf3ce44SJohn Forte 
1025*fcf3ce44SJohn Forte /*
1026*fcf3ce44SJohn Forte  * ql_ip_24xx_iocb
1027*fcf3ce44SJohn Forte  *	Setup of IP IOCB for ISP24xx.
1028*fcf3ce44SJohn Forte  *
1029*fcf3ce44SJohn Forte  * Input:
1030*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
1031*fcf3ce44SJohn Forte  *	sp:	srb structure pointer.
1032*fcf3ce44SJohn Forte  *	arg:	request queue packet.
1033*fcf3ce44SJohn Forte  *
1034*fcf3ce44SJohn Forte  * Context:
1035*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
1036*fcf3ce44SJohn Forte  */
1037*fcf3ce44SJohn Forte void
1038*fcf3ce44SJohn Forte ql_ip_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
1039*fcf3ce44SJohn Forte {
1040*fcf3ce44SJohn Forte 	ddi_dma_cookie_t	*cp;
1041*fcf3ce44SJohn Forte 	uint32_t		*ptr32;
1042*fcf3ce44SJohn Forte 	uint16_t		seg_cnt;
1043*fcf3ce44SJohn Forte 	ql_tgt_t		*tq = sp->lun_queue->target_queue;
1044*fcf3ce44SJohn Forte 	ip_cmd_entry_t		*pkt = arg;
1045*fcf3ce44SJohn Forte 
1046*fcf3ce44SJohn Forte 	pkt->entry_type = IP_CMD_TYPE;
1047*fcf3ce44SJohn Forte 
1048*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1049*fcf3ce44SJohn Forte 
1050*fcf3ce44SJohn Forte 	/* Set N_port handle */
1051*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->hdl_status, tq->loop_id);
1052*fcf3ce44SJohn Forte 
1053*fcf3ce44SJohn Forte 	/* Set ISP command timeout. */
1054*fcf3ce44SJohn Forte 	if (sp->isp_timeout < 0x1999) {
1055*fcf3ce44SJohn Forte 		ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout_hdl,
1056*fcf3ce44SJohn Forte 		    sp->isp_timeout);
1057*fcf3ce44SJohn Forte 	}
1058*fcf3ce44SJohn Forte 
1059*fcf3ce44SJohn Forte 	/* Set data segment count. */
1060*fcf3ce44SJohn Forte 	seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt;
1061*fcf3ce44SJohn Forte 	/* Load total byte count. */
1062*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count,
1063*fcf3ce44SJohn Forte 	    (uint32_t)sp->pkt->pkt_cmdlen);
1064*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt);
1065*fcf3ce44SJohn Forte 
1066*fcf3ce44SJohn Forte 	/* Set control flags */
1067*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->control_flags,
1068*fcf3ce44SJohn Forte 	    (uint16_t)(BIT_0));
1069*fcf3ce44SJohn Forte 
1070*fcf3ce44SJohn Forte 	/* Set frame header control flags */
1071*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->frame_hdr_cntrl_flgs,
1072*fcf3ce44SJohn Forte 	    (uint16_t)(IPCF_LAST_SEQ | IPCF_FIRST_SEQ));
1073*fcf3ce44SJohn Forte 
1074*fcf3ce44SJohn Forte 	/* Load command data segment. */
1075*fcf3ce44SJohn Forte 	ptr32 = (uint32_t *)&pkt->dseg_0_address;
1076*fcf3ce44SJohn Forte 	cp = sp->pkt->pkt_cmd_cookie;
1077*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address);
1078*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused);
1079*fcf3ce44SJohn Forte 	ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size);
1080*fcf3ce44SJohn Forte 	seg_cnt--;
1081*fcf3ce44SJohn Forte 	cp++;
1082*fcf3ce44SJohn Forte 
1083*fcf3ce44SJohn Forte 	/*
1084*fcf3ce44SJohn Forte 	 * Build continuation packets.
1085*fcf3ce44SJohn Forte 	 */
1086*fcf3ce44SJohn Forte 	if (seg_cnt) {
1087*fcf3ce44SJohn Forte 		ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE);
1088*fcf3ce44SJohn Forte 	}
1089*fcf3ce44SJohn Forte 
1090*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1091*fcf3ce44SJohn Forte }
1092*fcf3ce44SJohn Forte 
1093*fcf3ce44SJohn Forte /*
1094*fcf3ce44SJohn Forte  * ql_isp_rcvbuf
1095*fcf3ce44SJohn Forte  *	Locates free buffers and places it on the receive buffer queue.
1096*fcf3ce44SJohn Forte  *
1097*fcf3ce44SJohn Forte  * Input:
1098*fcf3ce44SJohn Forte  *	ha = adapter state pointer.
1099*fcf3ce44SJohn Forte  *
1100*fcf3ce44SJohn Forte  * Context:
1101*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
1102*fcf3ce44SJohn Forte  */
1103*fcf3ce44SJohn Forte void
1104*fcf3ce44SJohn Forte ql_isp_rcvbuf(ql_adapter_state_t *ha)
1105*fcf3ce44SJohn Forte {
1106*fcf3ce44SJohn Forte 	rcvbuf_t	*container;
1107*fcf3ce44SJohn Forte 	int16_t		rcv_q_cnt;
1108*fcf3ce44SJohn Forte 	uint16_t	index = 0;
1109*fcf3ce44SJohn Forte 	uint16_t	index1 = 1;
1110*fcf3ce44SJohn Forte 	int		debounce_count = QL_MAX_DEBOUNCE;
1111*fcf3ce44SJohn Forte 	ql_srb_t	*sp;
1112*fcf3ce44SJohn Forte 	fc_unsol_buf_t	*ubp;
1113*fcf3ce44SJohn Forte 	int		ring_updated = FALSE;
1114*fcf3ce44SJohn Forte 
1115*fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1116*fcf3ce44SJohn Forte 		ql_isp24xx_rcvbuf(ha);
1117*fcf3ce44SJohn Forte 		return;
1118*fcf3ce44SJohn Forte 	}
1119*fcf3ce44SJohn Forte 
1120*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1121*fcf3ce44SJohn Forte 
1122*fcf3ce44SJohn Forte 	/* Acquire adapter state lock. */
1123*fcf3ce44SJohn Forte 	ADAPTER_STATE_LOCK(ha);
1124*fcf3ce44SJohn Forte 
1125*fcf3ce44SJohn Forte 	/* Calculate number of free receive buffer entries. */
1126*fcf3ce44SJohn Forte 	index = RD16_IO_REG(ha, mailbox[8]);
1127*fcf3ce44SJohn Forte 	do {
1128*fcf3ce44SJohn Forte 		index1 = RD16_IO_REG(ha, mailbox[8]);
1129*fcf3ce44SJohn Forte 		if (index1 == index) {
1130*fcf3ce44SJohn Forte 			break;
1131*fcf3ce44SJohn Forte 		} else {
1132*fcf3ce44SJohn Forte 			index = index1;
1133*fcf3ce44SJohn Forte 		}
1134*fcf3ce44SJohn Forte 	} while (debounce_count --);
1135*fcf3ce44SJohn Forte 
1136*fcf3ce44SJohn Forte 	if (debounce_count < 0) {
1137*fcf3ce44SJohn Forte 		/* This should never happen */
1138*fcf3ce44SJohn Forte 		EL(ha, "max mb8 debounce retries exceeded\n");
1139*fcf3ce44SJohn Forte 	}
1140*fcf3ce44SJohn Forte 
1141*fcf3ce44SJohn Forte 	rcv_q_cnt = (uint16_t)(ha->rcvbuf_ring_index < index ?
1142*fcf3ce44SJohn Forte 	    index - ha->rcvbuf_ring_index : RCVBUF_CONTAINER_CNT -
1143*fcf3ce44SJohn Forte 	    (ha->rcvbuf_ring_index - index));
1144*fcf3ce44SJohn Forte 
1145*fcf3ce44SJohn Forte 	if (rcv_q_cnt == RCVBUF_CONTAINER_CNT) {
1146*fcf3ce44SJohn Forte 		rcv_q_cnt--;
1147*fcf3ce44SJohn Forte 	}
1148*fcf3ce44SJohn Forte 
1149*fcf3ce44SJohn Forte 	/* Load all free buffers in ISP receive buffer ring. */
1150*fcf3ce44SJohn Forte 	index = 0;
1151*fcf3ce44SJohn Forte 	while (rcv_q_cnt >= (uint16_t)0 && index < QL_UB_LIMIT) {
1152*fcf3ce44SJohn Forte 		/* Locate a buffer to give. */
1153*fcf3ce44SJohn Forte 		QL_UB_LOCK(ha);
1154*fcf3ce44SJohn Forte 		while (index < QL_UB_LIMIT) {
1155*fcf3ce44SJohn Forte 			ubp = ha->ub_array[index];
1156*fcf3ce44SJohn Forte 			if (ubp != NULL) {
1157*fcf3ce44SJohn Forte 				sp = ubp->ub_fca_private;
1158*fcf3ce44SJohn Forte 				if ((sp->ub_type == FC_TYPE_IS8802_SNAP) &&
1159*fcf3ce44SJohn Forte 				    (ha->flags & IP_INITIALIZED) &&
1160*fcf3ce44SJohn Forte 				    (sp->flags & SRB_UB_IN_FCA) &&
1161*fcf3ce44SJohn Forte 				    (!(sp->flags & (SRB_UB_IN_ISP |
1162*fcf3ce44SJohn Forte 				    SRB_UB_FREE_REQUESTED | SRB_UB_CALLBACK |
1163*fcf3ce44SJohn Forte 				    SRB_UB_ACQUIRED)))) {
1164*fcf3ce44SJohn Forte 					sp->flags |= SRB_UB_IN_ISP;
1165*fcf3ce44SJohn Forte 					break;
1166*fcf3ce44SJohn Forte 				}
1167*fcf3ce44SJohn Forte 			}
1168*fcf3ce44SJohn Forte 			index++;
1169*fcf3ce44SJohn Forte 		}
1170*fcf3ce44SJohn Forte 
1171*fcf3ce44SJohn Forte 		if (index < QL_UB_LIMIT) {
1172*fcf3ce44SJohn Forte 			rcv_q_cnt--;
1173*fcf3ce44SJohn Forte 			index++;
1174*fcf3ce44SJohn Forte 			container = ha->rcvbuf_ring_ptr;
1175*fcf3ce44SJohn Forte 
1176*fcf3ce44SJohn Forte 			/*
1177*fcf3ce44SJohn Forte 			 * Build container.
1178*fcf3ce44SJohn Forte 			 */
1179*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
1180*fcf3ce44SJohn Forte 			    (uint32_t *)(void *)&container->bufp[0],
1181*fcf3ce44SJohn Forte 			    sp->ub_buffer.cookie.dmac_address);
1182*fcf3ce44SJohn Forte 
1183*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
1184*fcf3ce44SJohn Forte 			    (uint32_t *)(void *)&container->bufp[1],
1185*fcf3ce44SJohn Forte 			    sp->ub_buffer.cookie.dmac_notused);
1186*fcf3ce44SJohn Forte 
1187*fcf3ce44SJohn Forte 			ddi_put16(ha->hba_buf.acc_handle, &container->handle,
1188*fcf3ce44SJohn Forte 			    LSW(sp->handle));
1189*fcf3ce44SJohn Forte 
1190*fcf3ce44SJohn Forte 			ha->ub_outcnt++;
1191*fcf3ce44SJohn Forte 
1192*fcf3ce44SJohn Forte 			/* Adjust ring index. */
1193*fcf3ce44SJohn Forte 			ha->rcvbuf_ring_index++;
1194*fcf3ce44SJohn Forte 			if (ha->rcvbuf_ring_index == RCVBUF_CONTAINER_CNT) {
1195*fcf3ce44SJohn Forte 				ha->rcvbuf_ring_index = 0;
1196*fcf3ce44SJohn Forte 				ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp;
1197*fcf3ce44SJohn Forte 			} else {
1198*fcf3ce44SJohn Forte 				ha->rcvbuf_ring_ptr++;
1199*fcf3ce44SJohn Forte 			}
1200*fcf3ce44SJohn Forte 
1201*fcf3ce44SJohn Forte 			ring_updated = TRUE;
1202*fcf3ce44SJohn Forte 		}
1203*fcf3ce44SJohn Forte 		QL_UB_UNLOCK(ha);
1204*fcf3ce44SJohn Forte 	}
1205*fcf3ce44SJohn Forte 
1206*fcf3ce44SJohn Forte 	if (ring_updated) {
1207*fcf3ce44SJohn Forte 		/* Sync queue. */
1208*fcf3ce44SJohn Forte 		(void) ddi_dma_sync(ha->hba_buf.dma_handle,
1209*fcf3ce44SJohn Forte 		    (off_t)RCVBUF_Q_BUFFER_OFFSET, (size_t)RCVBUF_QUEUE_SIZE,
1210*fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORDEV);
1211*fcf3ce44SJohn Forte 
1212*fcf3ce44SJohn Forte 		/* Set chip new ring index. */
1213*fcf3ce44SJohn Forte 		WRT16_IO_REG(ha, mailbox[8], ha->rcvbuf_ring_index);
1214*fcf3ce44SJohn Forte 	}
1215*fcf3ce44SJohn Forte 
1216*fcf3ce44SJohn Forte 	/* Release adapter state lock. */
1217*fcf3ce44SJohn Forte 	ADAPTER_STATE_UNLOCK(ha);
1218*fcf3ce44SJohn Forte 
1219*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1220*fcf3ce44SJohn Forte }
1221*fcf3ce44SJohn Forte 
1222*fcf3ce44SJohn Forte /*
1223*fcf3ce44SJohn Forte  * ql_isp24xx_rcvbuf
1224*fcf3ce44SJohn Forte  *	Locates free buffers and send it to adapter.
1225*fcf3ce44SJohn Forte  *
1226*fcf3ce44SJohn Forte  * Input:
1227*fcf3ce44SJohn Forte  *	ha = adapter state pointer.
1228*fcf3ce44SJohn Forte  *
1229*fcf3ce44SJohn Forte  * Context:
1230*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
1231*fcf3ce44SJohn Forte  */
1232*fcf3ce44SJohn Forte static void
1233*fcf3ce44SJohn Forte ql_isp24xx_rcvbuf(ql_adapter_state_t *ha)
1234*fcf3ce44SJohn Forte {
1235*fcf3ce44SJohn Forte 	rcvbuf_t		*container;
1236*fcf3ce44SJohn Forte 	uint16_t		index;
1237*fcf3ce44SJohn Forte 	ql_srb_t		*sp;
1238*fcf3ce44SJohn Forte 	fc_unsol_buf_t		*ubp;
1239*fcf3ce44SJohn Forte 	int			rval;
1240*fcf3ce44SJohn Forte 	ip_buf_pool_entry_t	*pkt = NULL;
1241*fcf3ce44SJohn Forte 
1242*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1243*fcf3ce44SJohn Forte 
1244*fcf3ce44SJohn Forte 	for (;;) {
1245*fcf3ce44SJohn Forte 		/* Locate a buffer to give. */
1246*fcf3ce44SJohn Forte 		QL_UB_LOCK(ha);
1247*fcf3ce44SJohn Forte 		for (index = 0; index < QL_UB_LIMIT; index++) {
1248*fcf3ce44SJohn Forte 			ubp = ha->ub_array[index];
1249*fcf3ce44SJohn Forte 			if (ubp != NULL) {
1250*fcf3ce44SJohn Forte 				sp = ubp->ub_fca_private;
1251*fcf3ce44SJohn Forte 				if ((sp->ub_type == FC_TYPE_IS8802_SNAP) &&
1252*fcf3ce44SJohn Forte 				    (ha->flags & IP_INITIALIZED) &&
1253*fcf3ce44SJohn Forte 				    (sp->flags & SRB_UB_IN_FCA) &&
1254*fcf3ce44SJohn Forte 				    (!(sp->flags & (SRB_UB_IN_ISP |
1255*fcf3ce44SJohn Forte 				    SRB_UB_FREE_REQUESTED | SRB_UB_CALLBACK |
1256*fcf3ce44SJohn Forte 				    SRB_UB_ACQUIRED)))) {
1257*fcf3ce44SJohn Forte 					ha->ub_outcnt++;
1258*fcf3ce44SJohn Forte 					sp->flags |= SRB_UB_IN_ISP;
1259*fcf3ce44SJohn Forte 					break;
1260*fcf3ce44SJohn Forte 				}
1261*fcf3ce44SJohn Forte 			}
1262*fcf3ce44SJohn Forte 		}
1263*fcf3ce44SJohn Forte 		QL_UB_UNLOCK(ha);
1264*fcf3ce44SJohn Forte 		if (index == QL_UB_LIMIT) {
1265*fcf3ce44SJohn Forte 			break;
1266*fcf3ce44SJohn Forte 		}
1267*fcf3ce44SJohn Forte 
1268*fcf3ce44SJohn Forte 		/* Get IOCB packet for buffers. */
1269*fcf3ce44SJohn Forte 		if (pkt == NULL) {
1270*fcf3ce44SJohn Forte 			rval = ql_req_pkt(ha, (request_t **)&pkt);
1271*fcf3ce44SJohn Forte 			if (rval != QL_SUCCESS) {
1272*fcf3ce44SJohn Forte 				EL(ha, "failed, ql_req_pkt=%x\n", rval);
1273*fcf3ce44SJohn Forte 				QL_UB_LOCK(ha);
1274*fcf3ce44SJohn Forte 				ha->ub_outcnt--;
1275*fcf3ce44SJohn Forte 				sp->flags &= ~SRB_UB_IN_ISP;
1276*fcf3ce44SJohn Forte 				QL_UB_UNLOCK(ha);
1277*fcf3ce44SJohn Forte 				break;
1278*fcf3ce44SJohn Forte 			}
1279*fcf3ce44SJohn Forte 			pkt->entry_type = IP_BUF_POOL_TYPE;
1280*fcf3ce44SJohn Forte 			container = &pkt->buffers[0];
1281*fcf3ce44SJohn Forte 		}
1282*fcf3ce44SJohn Forte 
1283*fcf3ce44SJohn Forte 		/*
1284*fcf3ce44SJohn Forte 		 * Build container.
1285*fcf3ce44SJohn Forte 		 */
1286*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle, &container->bufp[0],
1287*fcf3ce44SJohn Forte 		    sp->ub_buffer.cookie.dmac_address);
1288*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle, &container->bufp[1],
1289*fcf3ce44SJohn Forte 		    sp->ub_buffer.cookie.dmac_notused);
1290*fcf3ce44SJohn Forte 		ddi_put16(ha->hba_buf.acc_handle, &container->handle,
1291*fcf3ce44SJohn Forte 		    LSW(sp->handle));
1292*fcf3ce44SJohn Forte 
1293*fcf3ce44SJohn Forte 		pkt->buffer_count++;
1294*fcf3ce44SJohn Forte 		container++;
1295*fcf3ce44SJohn Forte 
1296*fcf3ce44SJohn Forte 		if (pkt->buffer_count == IP_POOL_BUFFERS) {
1297*fcf3ce44SJohn Forte 			ql_isp_cmd(ha);
1298*fcf3ce44SJohn Forte 			pkt = NULL;
1299*fcf3ce44SJohn Forte 		}
1300*fcf3ce44SJohn Forte 	}
1301*fcf3ce44SJohn Forte 
1302*fcf3ce44SJohn Forte 	if (pkt != NULL) {
1303*fcf3ce44SJohn Forte 		ql_isp_cmd(ha);
1304*fcf3ce44SJohn Forte 	}
1305*fcf3ce44SJohn Forte 
1306*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1307*fcf3ce44SJohn Forte }
1308*fcf3ce44SJohn Forte 
1309*fcf3ce44SJohn Forte /*
1310*fcf3ce44SJohn Forte  * ql_modify_lun
1311*fcf3ce44SJohn Forte  *	Function enables, modifies or disables ISP to respond as a target.
1312*fcf3ce44SJohn Forte  *
1313*fcf3ce44SJohn Forte  * Input:
1314*fcf3ce44SJohn Forte  *	ha = adapter state pointer.
1315*fcf3ce44SJohn Forte  *	count = number buffers for incoming commands.
1316*fcf3ce44SJohn Forte  *
1317*fcf3ce44SJohn Forte  * Returns:
1318*fcf3ce44SJohn Forte  *	ql local function return status code.
1319*fcf3ce44SJohn Forte  *
1320*fcf3ce44SJohn Forte  * Context:
1321*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
1322*fcf3ce44SJohn Forte  */
1323*fcf3ce44SJohn Forte int
1324*fcf3ce44SJohn Forte ql_modify_lun(ql_adapter_state_t *ha)
1325*fcf3ce44SJohn Forte {
1326*fcf3ce44SJohn Forte 	enable_lun_entry_t	*pkt;
1327*fcf3ce44SJohn Forte 	int			rval = QL_SUCCESS;
1328*fcf3ce44SJohn Forte 	uint32_t		index, ubcount;
1329*fcf3ce44SJohn Forte 	fc_unsol_buf_t		*ubp;
1330*fcf3ce44SJohn Forte 
1331*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1332*fcf3ce44SJohn Forte 
1333*fcf3ce44SJohn Forte 	/*
1334*fcf3ce44SJohn Forte 	 * Count the number of SCSI unsolicited buffers, that have been
1335*fcf3ce44SJohn Forte 	 * allocated.
1336*fcf3ce44SJohn Forte 	 */
1337*fcf3ce44SJohn Forte 	ADAPTER_STATE_LOCK(ha);
1338*fcf3ce44SJohn Forte 
1339*fcf3ce44SJohn Forte 	ubp = NULL;
1340*fcf3ce44SJohn Forte 	ubcount = 0;
1341*fcf3ce44SJohn Forte 	QL_UB_LOCK(ha);
1342*fcf3ce44SJohn Forte 	for (index = 0; index < QL_UB_LIMIT; index++) {
1343*fcf3ce44SJohn Forte 		ubp = ha->ub_array[index];
1344*fcf3ce44SJohn Forte 		if (ubp != NULL) {
1345*fcf3ce44SJohn Forte 			ql_srb_t *sp = ubp->ub_fca_private;
1346*fcf3ce44SJohn Forte 
1347*fcf3ce44SJohn Forte 			if (sp->ub_type == FC_TYPE_SCSI_FCP &&
1348*fcf3ce44SJohn Forte 			    !(sp->flags & SRB_UB_FREE_REQUESTED)) {
1349*fcf3ce44SJohn Forte 				ubcount++;
1350*fcf3ce44SJohn Forte 			}
1351*fcf3ce44SJohn Forte 		}
1352*fcf3ce44SJohn Forte 	}
1353*fcf3ce44SJohn Forte 	QL_UB_UNLOCK(ha);
1354*fcf3ce44SJohn Forte 
1355*fcf3ce44SJohn Forte 	if (!(ha->flags & TARGET_MODE_INITIALIZED) && (ubcount == 0)) {
1356*fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1357*fcf3ce44SJohn Forte 		return (rval);
1358*fcf3ce44SJohn Forte 	}
1359*fcf3ce44SJohn Forte 
1360*fcf3ce44SJohn Forte 	rval = ql_req_pkt(ha, (request_t **)&pkt);
1361*fcf3ce44SJohn Forte 
1362*fcf3ce44SJohn Forte 	if (ha->flags & TARGET_MODE_INITIALIZED) {
1363*fcf3ce44SJohn Forte 		if (ubcount == 0) {
1364*fcf3ce44SJohn Forte 			/* Disable the target mode Luns */
1365*fcf3ce44SJohn Forte 			ASSERT(ha->ub_command_count != 0);
1366*fcf3ce44SJohn Forte 			ASSERT(ha->ub_notify_count != 0);
1367*fcf3ce44SJohn Forte 
1368*fcf3ce44SJohn Forte 			ha->flags &= ~(TARGET_MODE_INITIALIZED);
1369*fcf3ce44SJohn Forte 
1370*fcf3ce44SJohn Forte 			ha->ub_command_count = 0;
1371*fcf3ce44SJohn Forte 			ha->ub_notify_count = 0;
1372*fcf3ce44SJohn Forte 
1373*fcf3ce44SJohn Forte 			pkt->entry_type = ENABLE_LUN_TYPE;
1374*fcf3ce44SJohn Forte 			pkt->command_count = 0;
1375*fcf3ce44SJohn Forte 			pkt->immediate_notify_count = 0;
1376*fcf3ce44SJohn Forte 
1377*fcf3ce44SJohn Forte 		} else {
1378*fcf3ce44SJohn Forte 			/* Modify the command count for target mode */
1379*fcf3ce44SJohn Forte 			modify_lun_entry_t	*ml_pkt;
1380*fcf3ce44SJohn Forte 			uint8_t			cmd_count, notify_count;
1381*fcf3ce44SJohn Forte 
1382*fcf3ce44SJohn Forte 			ASSERT(ha->ub_command_count != 0);
1383*fcf3ce44SJohn Forte 			ASSERT(ha->ub_notify_count != 0);
1384*fcf3ce44SJohn Forte 
1385*fcf3ce44SJohn Forte 			/*
1386*fcf3ce44SJohn Forte 			 * calculate the new value of command count
1387*fcf3ce44SJohn Forte 			 * and notify count and then issue the command
1388*fcf3ce44SJohn Forte 			 * to change the values in the firmware.
1389*fcf3ce44SJohn Forte 			 */
1390*fcf3ce44SJohn Forte 			ml_pkt = (modify_lun_entry_t *)pkt;
1391*fcf3ce44SJohn Forte 			ml_pkt->entry_type = MODIFY_LUN_TYPE;
1392*fcf3ce44SJohn Forte 			if (ubcount < 255) {
1393*fcf3ce44SJohn Forte 				/* Save one for immediate notify. */
1394*fcf3ce44SJohn Forte 				if (ubcount > 1) {
1395*fcf3ce44SJohn Forte 					cmd_count = (uint8_t)(ubcount - 1);
1396*fcf3ce44SJohn Forte 				} else {
1397*fcf3ce44SJohn Forte 					cmd_count = (uint8_t)ubcount;
1398*fcf3ce44SJohn Forte 				}
1399*fcf3ce44SJohn Forte 				notify_count = 1;
1400*fcf3ce44SJohn Forte 			} else {
1401*fcf3ce44SJohn Forte 				cmd_count = 255;
1402*fcf3ce44SJohn Forte 				if (ubcount - 255 < 255) {
1403*fcf3ce44SJohn Forte 					notify_count = (uint8_t)
1404*fcf3ce44SJohn Forte 					    (ubcount - 255);
1405*fcf3ce44SJohn Forte 				} else {
1406*fcf3ce44SJohn Forte 					notify_count = 255;
1407*fcf3ce44SJohn Forte 				}
1408*fcf3ce44SJohn Forte 			}
1409*fcf3ce44SJohn Forte 
1410*fcf3ce44SJohn Forte 			if (cmd_count > ha->ub_command_count) {
1411*fcf3ce44SJohn Forte 				/* cmd_count value increased */
1412*fcf3ce44SJohn Forte 				ml_pkt->command_count =	(uint8_t)
1413*fcf3ce44SJohn Forte 				    (cmd_count - ha->ub_command_count);
1414*fcf3ce44SJohn Forte 				ml_pkt->operators = (uint8_t)
1415*fcf3ce44SJohn Forte 				    (ml_pkt->operators | BIT_0);
1416*fcf3ce44SJohn Forte 
1417*fcf3ce44SJohn Forte 				if (notify_count > ha->ub_notify_count) {
1418*fcf3ce44SJohn Forte 					ml_pkt->immediate_notify_count =
1419*fcf3ce44SJohn Forte 					    (uint8_t)(notify_count -
1420*fcf3ce44SJohn Forte 					    ha->ub_notify_count);
1421*fcf3ce44SJohn Forte 					ml_pkt->operators = (uint8_t)
1422*fcf3ce44SJohn Forte 					    (ml_pkt->operators | BIT_2);
1423*fcf3ce44SJohn Forte 				} else if (notify_count <
1424*fcf3ce44SJohn Forte 				    ha->ub_notify_count) {
1425*fcf3ce44SJohn Forte 					ml_pkt->immediate_notify_count =
1426*fcf3ce44SJohn Forte 					    (uint8_t)(ha->ub_notify_count -
1427*fcf3ce44SJohn Forte 					    notify_count);
1428*fcf3ce44SJohn Forte 					ml_pkt->operators = (uint8_t)
1429*fcf3ce44SJohn Forte 					    (ml_pkt->operators | BIT_3);
1430*fcf3ce44SJohn Forte 				}
1431*fcf3ce44SJohn Forte 			} else {
1432*fcf3ce44SJohn Forte 				/* cmd_count value reduced */
1433*fcf3ce44SJohn Forte 				ml_pkt->command_count =	(uint8_t)
1434*fcf3ce44SJohn Forte 				    (ha->ub_command_count - cmd_count);
1435*fcf3ce44SJohn Forte 				if (ml_pkt->command_count != 0) {
1436*fcf3ce44SJohn Forte 					ml_pkt->operators = (uint8_t)
1437*fcf3ce44SJohn Forte 					    (ml_pkt->operators | BIT_1);
1438*fcf3ce44SJohn Forte 				}
1439*fcf3ce44SJohn Forte 				if (notify_count > ha->ub_notify_count) {
1440*fcf3ce44SJohn Forte 					ml_pkt->immediate_notify_count =
1441*fcf3ce44SJohn Forte 					    (uint8_t)(notify_count -
1442*fcf3ce44SJohn Forte 					    ha->ub_notify_count);
1443*fcf3ce44SJohn Forte 					ml_pkt->operators = (uint8_t)
1444*fcf3ce44SJohn Forte 					    (ml_pkt->operators | BIT_2);
1445*fcf3ce44SJohn Forte 				} else if (notify_count <
1446*fcf3ce44SJohn Forte 				    ha->ub_notify_count) {
1447*fcf3ce44SJohn Forte 					ml_pkt->immediate_notify_count =
1448*fcf3ce44SJohn Forte 					    (uint8_t)(ha->ub_notify_count -
1449*fcf3ce44SJohn Forte 					    notify_count);
1450*fcf3ce44SJohn Forte 					ml_pkt->operators = (uint8_t)
1451*fcf3ce44SJohn Forte 					    (ml_pkt->operators | BIT_3);
1452*fcf3ce44SJohn Forte 				}
1453*fcf3ce44SJohn Forte 			}
1454*fcf3ce44SJohn Forte 
1455*fcf3ce44SJohn Forte 			/* Update the driver's command/notify count values */
1456*fcf3ce44SJohn Forte 			ha->ub_command_count = cmd_count;
1457*fcf3ce44SJohn Forte 			ha->ub_notify_count = notify_count;
1458*fcf3ce44SJohn Forte 		}
1459*fcf3ce44SJohn Forte 	} else {
1460*fcf3ce44SJohn Forte 		ASSERT(ubcount != 0);
1461*fcf3ce44SJohn Forte 
1462*fcf3ce44SJohn Forte 		/* Enable the Luns for the target mode */
1463*fcf3ce44SJohn Forte 		pkt->entry_type = ENABLE_LUN_TYPE;
1464*fcf3ce44SJohn Forte 
1465*fcf3ce44SJohn Forte 		if (ubcount < 255) {
1466*fcf3ce44SJohn Forte 			/* Save one for immediate notify. */
1467*fcf3ce44SJohn Forte 			if (ubcount > 1) {
1468*fcf3ce44SJohn Forte 				ha->ub_command_count = (uint8_t)(ubcount - 1);
1469*fcf3ce44SJohn Forte 			} else {
1470*fcf3ce44SJohn Forte 				ha->ub_command_count = (uint8_t)ubcount;
1471*fcf3ce44SJohn Forte 			}
1472*fcf3ce44SJohn Forte 			ha->ub_notify_count = 1;
1473*fcf3ce44SJohn Forte 		} else {
1474*fcf3ce44SJohn Forte 			ha->ub_command_count = 255;
1475*fcf3ce44SJohn Forte 			if (ubcount - 255 < 255) {
1476*fcf3ce44SJohn Forte 				ha->ub_notify_count = (uint8_t)(ubcount - 255);
1477*fcf3ce44SJohn Forte 			} else {
1478*fcf3ce44SJohn Forte 				ha->ub_notify_count = 255;
1479*fcf3ce44SJohn Forte 			}
1480*fcf3ce44SJohn Forte 		}
1481*fcf3ce44SJohn Forte 		ha->flags |= TARGET_MODE_INITIALIZED;
1482*fcf3ce44SJohn Forte 
1483*fcf3ce44SJohn Forte 		pkt->command_count = ha->ub_command_count;
1484*fcf3ce44SJohn Forte 		pkt->immediate_notify_count = ha->ub_notify_count;
1485*fcf3ce44SJohn Forte 	}
1486*fcf3ce44SJohn Forte 	ADAPTER_STATE_UNLOCK(ha);
1487*fcf3ce44SJohn Forte 
1488*fcf3ce44SJohn Forte 	/* Issue command to ISP */
1489*fcf3ce44SJohn Forte 	ql_isp_cmd(ha);
1490*fcf3ce44SJohn Forte 
1491*fcf3ce44SJohn Forte 	if (rval != QL_SUCCESS) {
1492*fcf3ce44SJohn Forte 		EL(ha, "failed=%xh\n", rval);
1493*fcf3ce44SJohn Forte 	} else {
1494*fcf3ce44SJohn Forte 		/*EMPTY*/
1495*fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1496*fcf3ce44SJohn Forte 	}
1497*fcf3ce44SJohn Forte 	return (rval);
1498*fcf3ce44SJohn Forte }
1499*fcf3ce44SJohn Forte 
1500*fcf3ce44SJohn Forte /*
1501*fcf3ce44SJohn Forte  * ql_notify_acknowledge_iocb
1502*fcf3ce44SJohn Forte  *	Setup of notify acknowledge IOCB for pending
1503*fcf3ce44SJohn Forte  *	immediate notify entry.
1504*fcf3ce44SJohn Forte  *
1505*fcf3ce44SJohn Forte  * Input:
1506*fcf3ce44SJohn Forte  *	ha:	adapter state pointer.
1507*fcf3ce44SJohn Forte  *	cmd:	target command context pointer.
1508*fcf3ce44SJohn Forte  *	pkt:	request queue packet.
1509*fcf3ce44SJohn Forte  *
1510*fcf3ce44SJohn Forte  * Context:
1511*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
1512*fcf3ce44SJohn Forte  */
1513*fcf3ce44SJohn Forte void
1514*fcf3ce44SJohn Forte ql_notify_acknowledge_iocb(ql_adapter_state_t *ha, tgt_cmd_t *cmd,
1515*fcf3ce44SJohn Forte     notify_acknowledge_entry_t *pkt)
1516*fcf3ce44SJohn Forte {
1517*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1518*fcf3ce44SJohn Forte 
1519*fcf3ce44SJohn Forte 	pkt->entry_type = NOTIFY_ACKNOWLEDGE_TYPE;
1520*fcf3ce44SJohn Forte 	pkt->initiator_id_l = cmd->initiator_id_l;
1521*fcf3ce44SJohn Forte 	pkt->initiator_id_h = cmd->initiator_id_h;
1522*fcf3ce44SJohn Forte 
1523*fcf3ce44SJohn Forte 	/* Handle LIP reset event. */
1524*fcf3ce44SJohn Forte 	if (cmd->status == 0xe) {
1525*fcf3ce44SJohn Forte 		pkt->flags_l = BIT_5;
1526*fcf3ce44SJohn Forte 	}
1527*fcf3ce44SJohn Forte 
1528*fcf3ce44SJohn Forte 	pkt->flags_h = BIT_0;
1529*fcf3ce44SJohn Forte 	ddi_put16(ha->hba_buf.acc_handle, &pkt->status, cmd->status);
1530*fcf3ce44SJohn Forte 	pkt->task_flags_l = cmd->task_flags_l;
1531*fcf3ce44SJohn Forte 	pkt->task_flags_h = cmd->task_flags_h;
1532*fcf3ce44SJohn Forte 	pkt->sequence_id = cmd->rx_id;
1533*fcf3ce44SJohn Forte 
1534*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1535*fcf3ce44SJohn Forte }
1536*fcf3ce44SJohn Forte 
1537*fcf3ce44SJohn Forte /*
1538*fcf3ce44SJohn Forte  * ql_continue_target_io_iocb
1539*fcf3ce44SJohn Forte  *	Setup of continue target I/O IOCB for pending
1540*fcf3ce44SJohn Forte  *	accept target I/O entry.
1541*fcf3ce44SJohn Forte  *
1542*fcf3ce44SJohn Forte  * Input:
1543*fcf3ce44SJohn Forte  *	ha = adapter state pointer.
1544*fcf3ce44SJohn Forte  *	sp = srb structure pointer.
1545*fcf3ce44SJohn Forte  *	arg = request queue packet.
1546*fcf3ce44SJohn Forte  *
1547*fcf3ce44SJohn Forte  * Context:
1548*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
1549*fcf3ce44SJohn Forte  */
1550*fcf3ce44SJohn Forte void
1551*fcf3ce44SJohn Forte ql_continue_target_io_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg)
1552*fcf3ce44SJohn Forte {
1553*fcf3ce44SJohn Forte 	ddi_dma_cookie_t	*cp;
1554*fcf3ce44SJohn Forte 	port_id_t		d_id;
1555*fcf3ce44SJohn Forte 	ql_tgt_t		*tq;
1556*fcf3ce44SJohn Forte 	ctio_entry_t		*pkt = arg;
1557*fcf3ce44SJohn Forte 
1558*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1559*fcf3ce44SJohn Forte 
1560*fcf3ce44SJohn Forte 	d_id.b24 = sp->pkt->pkt_cmd_fhdr.d_id;
1561*fcf3ce44SJohn Forte 	tq = ql_d_id_to_queue(ha, d_id);
1562*fcf3ce44SJohn Forte 
1563*fcf3ce44SJohn Forte 	if (tq == NULL) {
1564*fcf3ce44SJohn Forte 		EL(ha, "Unknown Initiator d_id %xh", d_id.b24);
1565*fcf3ce44SJohn Forte 		return;
1566*fcf3ce44SJohn Forte 	}
1567*fcf3ce44SJohn Forte 
1568*fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1569*fcf3ce44SJohn Forte 		pkt->initiator_id_l = LSB(tq->loop_id);
1570*fcf3ce44SJohn Forte 		pkt->initiator_id_h = MSB(tq->loop_id);
1571*fcf3ce44SJohn Forte 	} else {
1572*fcf3ce44SJohn Forte 		pkt->initiator_id_h = LSB(tq->loop_id);
1573*fcf3ce44SJohn Forte 	}
1574*fcf3ce44SJohn Forte 	pkt->rx_id = sp->pkt->pkt_cmd_fhdr.rx_id;
1575*fcf3ce44SJohn Forte 
1576*fcf3ce44SJohn Forte 	/* Set ISP command timeout. */
1577*fcf3ce44SJohn Forte 	if (sp->isp_timeout < 0x1999) {
1578*fcf3ce44SJohn Forte 		ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout,
1579*fcf3ce44SJohn Forte 		    sp->isp_timeout);
1580*fcf3ce44SJohn Forte 	}
1581*fcf3ce44SJohn Forte 
1582*fcf3ce44SJohn Forte 	if (sp->flags & SRB_FCP_DATA_PKT) {
1583*fcf3ce44SJohn Forte 
1584*fcf3ce44SJohn Forte 		if (sp->pkt->pkt_tran_type == FC_PKT_OUTBOUND) {
1585*fcf3ce44SJohn Forte 			pkt->flags_l = BIT_6;
1586*fcf3ce44SJohn Forte 		} else if (sp->pkt->pkt_tran_type == FC_PKT_INBOUND) {
1587*fcf3ce44SJohn Forte 			pkt->flags_l = BIT_7;
1588*fcf3ce44SJohn Forte 		}
1589*fcf3ce44SJohn Forte 
1590*fcf3ce44SJohn Forte 		pkt->flags_h = BIT_1;
1591*fcf3ce44SJohn Forte 		/* Set relative offset. */
1592*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle,
1593*fcf3ce44SJohn Forte 		    (uint32_t *)(void *)&pkt->relative_offset,
1594*fcf3ce44SJohn Forte 		    (uint32_t)sp->pkt->pkt_cmd_fhdr.ro);
1595*fcf3ce44SJohn Forte 	} else {
1596*fcf3ce44SJohn Forte 		/* (sp->flags & SRB_FCP_RSP_PKT) */
1597*fcf3ce44SJohn Forte 		pkt->flags_l = BIT_7 | BIT_6 | BIT_1;
1598*fcf3ce44SJohn Forte 		pkt->flags_h = BIT_7 | BIT_1;
1599*fcf3ce44SJohn Forte 	}
1600*fcf3ce44SJohn Forte 
1601*fcf3ce44SJohn Forte 	/*
1602*fcf3ce44SJohn Forte 	 * Load data segments.
1603*fcf3ce44SJohn Forte 	 */
1604*fcf3ce44SJohn Forte 	if (sp->pkt->pkt_cmdlen != 0) {
1605*fcf3ce44SJohn Forte 		cp = sp->pkt->pkt_cmd_cookie;
1606*fcf3ce44SJohn Forte 
1607*fcf3ce44SJohn Forte 		/* Transfer length. */
1608*fcf3ce44SJohn Forte 		ddi_put32(ha->hba_buf.acc_handle,
1609*fcf3ce44SJohn Forte 		    (uint32_t *)(void *)&pkt->type.s0_32bit.byte_count,
1610*fcf3ce44SJohn Forte 		    (uint32_t)cp->dmac_size);
1611*fcf3ce44SJohn Forte 
1612*fcf3ce44SJohn Forte 		/* Load data segments. */
1613*fcf3ce44SJohn Forte 		pkt->dseg_count_l = 1;
1614*fcf3ce44SJohn Forte 		if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
1615*fcf3ce44SJohn Forte 			pkt->entry_type = CTIO_TYPE_3;
1616*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
1617*fcf3ce44SJohn Forte 			    (uint32_t *)(void *)
1618*fcf3ce44SJohn Forte 			    &pkt->type.s0_64bit.dseg_0_address[0],
1619*fcf3ce44SJohn Forte 			    cp->dmac_address);
1620*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
1621*fcf3ce44SJohn Forte 			    (uint32_t *)(void *)
1622*fcf3ce44SJohn Forte 			    &pkt->type.s0_64bit.dseg_0_address[1],
1623*fcf3ce44SJohn Forte 			    cp->dmac_notused);
1624*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
1625*fcf3ce44SJohn Forte 			    (uint32_t *)(void *)
1626*fcf3ce44SJohn Forte 			    &pkt->type.s0_64bit.dseg_0_length,
1627*fcf3ce44SJohn Forte 			    (uint32_t)cp->dmac_size);
1628*fcf3ce44SJohn Forte 		} else {
1629*fcf3ce44SJohn Forte 			pkt->entry_type = CTIO_TYPE_2;
1630*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
1631*fcf3ce44SJohn Forte 			    (uint32_t *)(void *)
1632*fcf3ce44SJohn Forte 			    &pkt->type.s0_32bit.dseg_0_address,
1633*fcf3ce44SJohn Forte 			    cp->dmac_address);
1634*fcf3ce44SJohn Forte 			ddi_put32(ha->hba_buf.acc_handle,
1635*fcf3ce44SJohn Forte 			    (uint32_t *)(void *)
1636*fcf3ce44SJohn Forte 			    &pkt->type.s0_32bit.dseg_0_length,
1637*fcf3ce44SJohn Forte 			    (uint32_t)cp->dmac_size);
1638*fcf3ce44SJohn Forte 		}
1639*fcf3ce44SJohn Forte 	}
1640*fcf3ce44SJohn Forte 
1641*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1642*fcf3ce44SJohn Forte }
1643*fcf3ce44SJohn Forte 
1644*fcf3ce44SJohn Forte /*
1645*fcf3ce44SJohn Forte  * ql_continue_target_io_2400_iocb
1646*fcf3ce44SJohn Forte  *	Setup of continue target I/O IOCB for pending
1647*fcf3ce44SJohn Forte  *	accept target I/O entry.
1648*fcf3ce44SJohn Forte  *
1649*fcf3ce44SJohn Forte  * Input:
1650*fcf3ce44SJohn Forte  *	ha = adapter state pointer.
1651*fcf3ce44SJohn Forte  *	sp = srb structure pointer.
1652*fcf3ce44SJohn Forte  *	arg = request queue packet.
1653*fcf3ce44SJohn Forte  *
1654*fcf3ce44SJohn Forte  * Context:
1655*fcf3ce44SJohn Forte  *	Interrupt or Kernel context, no mailbox commands allowed.
1656*fcf3ce44SJohn Forte  */
1657*fcf3ce44SJohn Forte /* ARGSUSED */
1658*fcf3ce44SJohn Forte void
1659*fcf3ce44SJohn Forte ql_continue_target_io_2400_iocb(ql_adapter_state_t *ha, ql_srb_t *sp,
1660*fcf3ce44SJohn Forte     void *arg)
1661*fcf3ce44SJohn Forte {
1662*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1663*fcf3ce44SJohn Forte 
1664*fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1665*fcf3ce44SJohn Forte }
1666