xref: /titanic_51/usr/src/uts/common/io/1394/adapters/hci1394_ixl_comp.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * hci1394_ixl_comp.c
31  *    Isochronous IXL Compiler.
32  *    The compiler converts the general hardware independent IXL command
33  *    blocks into OpenHCI DMA descriptors.
34  */
35 
36 #include <sys/kmem.h>
37 #include <sys/types.h>
38 #include <sys/conf.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 
42 #include <sys/tnf_probe.h>
43 
44 #include <sys/1394/h1394.h>
45 #include <sys/1394/ixl1394.h>
46 #include <sys/1394/adapters/hci1394.h>
47 
48 /* compiler allocation size for DMA descriptors. 8000 is 500 descriptors */
49 #define	HCI1394_IXL_PAGESIZE	8000
50 
51 /* invalid opcode */
52 #define	IXL1394_OP_INVALID  (0 | IXL1394_OPTY_OTHER)
53 
54 /*
55  * maximum number of interrupts permitted for a single context in which
56  * the context does not advance to the next DMA descriptor.  Interrupts are
57  * triggered by 1) hardware completing a DMA descriptor block which has the
58  * interrupt (i) bits set, 2) a cycle_inconsistent interrupt, or 3) a cycle_lost
59  * interrupt.  Once the max is reached, the HCI1394_IXL_INTR_NOADV error is
60  * returned.
61  */
62 int hci1394_ixl_max_noadv_intrs = 8;
63 
64 
65 static void hci1394_compile_ixl_init(hci1394_comp_ixl_vars_t *wvp,
66     hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
67     ixl1394_command_t *ixlp);
68 static void hci1394_compile_ixl_endup(hci1394_comp_ixl_vars_t *wvp);
69 static void hci1394_parse_ixl(hci1394_comp_ixl_vars_t *wvp,
70     ixl1394_command_t *ixlp);
71 static void hci1394_finalize_all_xfer_desc(hci1394_comp_ixl_vars_t *wvp);
72 static void hci1394_finalize_cur_xfer_desc(hci1394_comp_ixl_vars_t *wvp);
73 static void hci1394_bld_recv_pkt_desc(hci1394_comp_ixl_vars_t *wvp);
74 static void hci1394_bld_recv_buf_ppb_desc(hci1394_comp_ixl_vars_t *wvp);
75 static void hci1394_bld_recv_buf_fill_desc(hci1394_comp_ixl_vars_t *wvp);
76 static void hci1394_bld_xmit_pkt_desc(hci1394_comp_ixl_vars_t *wvp);
77 static void hci1394_bld_xmit_buf_desc(hci1394_comp_ixl_vars_t *wvp);
78 static void hci1394_bld_xmit_hdronly_nopkt_desc(hci1394_comp_ixl_vars_t *wvp);
79 static int hci1394_bld_dma_mem_desc_blk(hci1394_comp_ixl_vars_t *wvp,
80     caddr_t *dma_descpp, uint32_t *dma_desc_bound);
81 static void hci1394_set_xmit_pkt_hdr(hci1394_comp_ixl_vars_t *wvp);
82 static void hci1394_set_xmit_skip_mode(hci1394_comp_ixl_vars_t *wvp);
83 static void hci1394_set_xmit_storevalue_desc(hci1394_comp_ixl_vars_t *wvp);
84 static int hci1394_set_next_xfer_buf(hci1394_comp_ixl_vars_t *wvp,
85     uint32_t bufp, uint16_t size);
86 static int hci1394_flush_end_desc_check(hci1394_comp_ixl_vars_t *wvp,
87     uint32_t count);
88 static int hci1394_flush_hci_cache(hci1394_comp_ixl_vars_t *wvp);
89 static uint32_t hci1394_alloc_storevalue_dma_mem(hci1394_comp_ixl_vars_t *wvp);
90 static hci1394_xfer_ctl_t *hci1394_alloc_xfer_ctl(hci1394_comp_ixl_vars_t *wvp,
91     uint32_t dmacnt);
92 static void *hci1394_alloc_dma_mem(hci1394_comp_ixl_vars_t *wvp,
93     uint32_t size, uint32_t *dma_bound);
94 static boolean_t hci1394_is_opcode_valid(uint16_t ixlopcode);
95 
96 
97 /*
98  * FULL LIST OF ACCEPTED IXL COMMAND OPCOCDES:
99  * Receive Only:			Transmit Only:
100  *    IXL1394_OP_RECV_PKT_ST		    IXL1394_OP_SEND_PKT_WHDR_ST
101  *    IXL1394_OP_RECV_PKT		    IXL1394_OP_SEND_PKT_ST
102  *    IXL1394_OP_RECV_BUF		    IXL1394_OP_SEND_PKT
103  *    IXL1394_OP_SET_SYNCWAIT		    IXL1394_OP_SEND_BUF
104  *					    IXL1394_OP_SEND_HDR_ONLY
105  * Receive or Transmit:			    IXL1394_OP_SEND_NO_PKT
106  *    IXL1394_OP_CALLBACK		    IXL1394_OP_SET_TAGSYNC
107  *    IXL1394_OP_LABEL			    IXL1394_OP_SET_SKIPMODE
108  *    IXL1394_OP_JUMP			    IXL1394_OP_STORE_TIMESTAMP
109  */
110 
111 /*
112  * hci1394_compile_ixl()
113  *    Top level ixl compiler entry point.  Scans ixl and builds openHCI 1.0
114  *    descriptor blocks in dma memory.
115  */
116 int
117 hci1394_compile_ixl(hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
118     ixl1394_command_t *ixlp, int *resultp)
119 {
120 	hci1394_comp_ixl_vars_t wv;	/* working variables used throughout */
121 
122 	ASSERT(soft_statep != NULL);
123 	ASSERT(ctxtp != NULL);
124 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_enter,
125 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
126 
127 	/* Initialize compiler working variables */
128 	hci1394_compile_ixl_init(&wv, soft_statep, ctxtp, ixlp);
129 
130 	/*
131 	 * First pass:
132 	 *    Parse ixl commands, building desc blocks, until end of IXL
133 	 *    linked list.
134 	 */
135 	hci1394_parse_ixl(&wv, ixlp);
136 
137 	/*
138 	 * Second pass:
139 	 *    Resolve all generated descriptor block jump and skip addresses.
140 	 *    Set interrupt enable in descriptor blocks which have callback
141 	 *    operations in their execution scope. (Previously store_timesamp
142 	 *    operations were counted also.) Set interrupt enable in descriptor
143 	 *    blocks which were introduced by an ixl label command.
144 	 */
145 	if (wv.dma_bld_error == 0) {
146 		hci1394_finalize_all_xfer_desc(&wv);
147 	}
148 
149 	/* Endup: finalize and cleanup ixl compile, return result */
150 	hci1394_compile_ixl_endup(&wv);
151 
152 	*resultp = wv.dma_bld_error;
153 	if (*resultp != 0) {
154 		TNF_PROBE_0_DEBUG(hci1394_compile_ixl_exit,
155 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
156 		return (DDI_FAILURE);
157 	} else {
158 		TNF_PROBE_0_DEBUG(hci1394_compile_ixl_exit,
159 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
160 		return (DDI_SUCCESS);
161 	}
162 }
163 
164 /*
165  * hci1394_compile_ixl_init()
166  *    Initialize the isoch context structure associated with the IXL
167  *    program, and initialize the temporary working variables structure.
168  */
169 static void
170 hci1394_compile_ixl_init(hci1394_comp_ixl_vars_t *wvp,
171     hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
172     ixl1394_command_t *ixlp)
173 {
174 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_init_enter,
175 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
176 
177 	/* initialize common recv/xmit compile values */
178 	wvp->soft_statep = soft_statep;
179 	wvp->ctxtp = ctxtp;
180 
181 	/* init/clear ctxtp values */
182 	ctxtp->dma_mem_execp = NULL;
183 	ctxtp->dma_firstp = NULL;
184 	ctxtp->dma_last_time = 0;
185 	ctxtp->xcs_firstp = NULL;
186 	ctxtp->ixl_exec_depth = 0;
187 	ctxtp->ixl_execp = NULL;
188 	ctxtp->ixl_firstp = ixlp;
189 	ctxtp->default_skipxferp = NULL;
190 
191 	/*
192 	 * the context's max_noadv_intrs is set here instead of in isoch init
193 	 * because the default is patchable and would only be picked up this way
194 	 */
195 	ctxtp->max_noadv_intrs = hci1394_ixl_max_noadv_intrs;
196 
197 	/* init working variables */
198 	wvp->xcs_firstp = NULL;
199 	wvp->xcs_currentp = NULL;
200 
201 	wvp->dma_firstp = NULL;
202 	wvp->dma_currentp = NULL;
203 	wvp->dma_bld_error = 0;
204 
205 	wvp->ixl_io_mode = ctxtp->ctxt_flags;
206 	wvp->ixl_cur_cmdp = NULL;
207 	wvp->ixl_cur_xfer_stp = NULL;
208 	wvp->ixl_cur_labelp = NULL;
209 
210 	wvp->ixl_xfer_st_cnt = 0;	/* count of xfer start commands found */
211 	wvp->xfer_state = XFER_NONE;	/* none, pkt, buf, skip, hdronly */
212 	wvp->xfer_hci_flush = 0;	/* updateable - xfer, jump, set */
213 	wvp->xfer_pktlen = 0;
214 	wvp->xfer_bufcnt = 0;
215 	wvp->descriptors = 0;
216 
217 	/* START RECV ONLY SECTION */
218 	wvp->ixl_setsyncwait_cnt = 0;
219 
220 	/* START XMIT ONLY SECTION */
221 	wvp->ixl_settagsync_cmdp = NULL;
222 	wvp->ixl_setskipmode_cmdp = NULL;
223 	wvp->default_skipmode = ctxtp->default_skipmode; /* nxt,self,stop,jmp */
224 	wvp->default_skiplabelp = ctxtp->default_skiplabelp;
225 	wvp->default_skipxferp = NULL;
226 	wvp->skipmode = ctxtp->default_skipmode;
227 	wvp->skiplabelp = NULL;
228 	wvp->skipxferp = NULL;
229 	wvp->default_tag = ctxtp->default_tag;
230 	wvp->default_sync = ctxtp->default_sync;
231 	wvp->storevalue_bufp = hci1394_alloc_storevalue_dma_mem(wvp);
232 	wvp->storevalue_data = 0;
233 	wvp->xmit_pkthdr1 = 0;
234 	wvp->xmit_pkthdr2 = 0;
235 	/* END XMIT ONLY SECTION */
236 
237 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_init_exit,
238 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
239 }
240 
241 /*
242  * hci1394_compile_ixl_endup()
243  *    This routine is called just before the main hci1394_compile_ixl() exits.
244  *    It checks for errors and performs the appropriate cleanup, or it rolls any
245  *    relevant info from the working variables struct into the context structure
246  */
247 static void
248 hci1394_compile_ixl_endup(hci1394_comp_ixl_vars_t *wvp)
249 {
250 	ixl1394_command_t *ixl_exec_stp;
251 	hci1394_idma_desc_mem_t *dma_nextp;
252 	int err;
253 
254 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_enter,
255 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
256 
257 	/* error if no descriptor blocks found in ixl & created in dma memory */
258 	if ((wvp->dma_bld_error == 0) && (wvp->ixl_xfer_st_cnt == 0)) {
259 		TNF_PROBE_1(hci1394_compile_ixl_endup_nodata_error,
260 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
261 		    "IXL1394_ENO_DATA_PKTS: prog has no data packets");
262 
263 		wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
264 	}
265 
266 	/* if no errors yet, find the first IXL command that's a transfer cmd */
267 	if (wvp->dma_bld_error == 0) {
268 		err = hci1394_ixl_find_next_exec_xfer(wvp->ctxtp->ixl_firstp,
269 		    NULL, &ixl_exec_stp);
270 
271 		/* error if a label<->jump loop, or no xfer */
272 		if ((err == DDI_FAILURE) || (ixl_exec_stp == NULL)) {
273 			TNF_PROBE_1(hci1394_compile_ixl_endup_error,
274 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
275 			    "IXL1394_ENO_DATA_PKTS: loop or no xfer detected");
276 
277 			wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
278 		}
279 	}
280 
281 	/* Sync all the DMA descriptor buffers */
282 	dma_nextp = wvp->ctxtp->dma_firstp;
283 	while (dma_nextp != NULL) {
284 		err = ddi_dma_sync(dma_nextp->mem.bi_dma_handle,
285 		    (off_t)dma_nextp->mem.bi_kaddr, dma_nextp->mem.bi_length,
286 		    DDI_DMA_SYNC_FORDEV);
287 		if (err != DDI_SUCCESS) {
288 			wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR;
289 
290 			TNF_PROBE_1(hci1394_compile_ixl_endup_error,
291 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
292 			    "IXL1394_INTERNAL_ERROR: dma_sync() failed");
293 			break;
294 		}
295 
296 		/* advance to next dma memory descriptor */
297 		dma_nextp = dma_nextp->dma_nextp;
298 	}
299 
300 	/*
301 	 * If error, cleanup and return. delete all allocated xfer_ctl structs
302 	 * and all dma descriptor page memory and its dma memory blocks too.
303 	 */
304 	if (wvp->dma_bld_error != 0) {
305 		wvp->ctxtp->xcs_firstp = (void *)wvp->xcs_firstp;
306 		wvp->ctxtp->dma_firstp = wvp->dma_firstp;
307 		hci1394_ixl_cleanup(wvp->soft_statep, wvp->ctxtp);
308 
309 		TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_exit,
310 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
311 		return;
312 	}
313 
314 	/* can only get to here if the first ixl transfer command is found */
315 
316 	/* set required processing vars into ctxtp struct */
317 	wvp->ctxtp->default_skipxferp = wvp->default_skipxferp;
318 	wvp->ctxtp->dma_mem_execp = 0;
319 
320 	/*
321 	 * the transfer command's compiler private xfer_ctl structure has the
322 	 * appropriate bound address
323 	 */
324 	wvp->ctxtp->dma_mem_execp = (uint32_t)((hci1394_xfer_ctl_t *)
325 	    ixl_exec_stp->compiler_privatep)->dma[0].dma_bound;
326 	wvp->ctxtp->xcs_firstp = (void *)wvp->xcs_firstp;
327 	wvp->ctxtp->dma_firstp = wvp->dma_firstp;
328 	wvp->ctxtp->dma_last_time = 0;
329 	wvp->ctxtp->ixl_exec_depth = 0;
330 	wvp->ctxtp->ixl_execp = NULL;
331 
332 	/* compile done */
333 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_exit,
334 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
335 }
336 
337 /*
338  * hci1394_parse_ixl()
339  *    Scan IXL program and build ohci DMA descriptor blocks in dma memory.
340  *
341  *    Parse/process succeeding ixl commands until end of IXL linked list is
342  *    reached. Evaluate ixl syntax and build (xmit or recv) descriptor
343  *    blocks.  To aid execution time evaluation of current location, enable
344  *    status recording on each descriptor block built.
345  *    On xmit, set sync & tag bits. On recv, optionally set wait for sync bit.
346  */
347 static void
348 hci1394_parse_ixl(hci1394_comp_ixl_vars_t *wvp, ixl1394_command_t *ixlp)
349 {
350 	ixl1394_command_t *ixlnextp = ixlp;	/* addr of next ixl cmd */
351 	ixl1394_command_t *ixlcurp = NULL;	/* addr of current ixl cmd */
352 	uint16_t ixlopcode = 0;			/* opcode of currnt ixl cmd */
353 
354 	uint32_t pktsize;
355 	uint32_t pktcnt;
356 
357 	TNF_PROBE_0_DEBUG(hci1394_parse_ixl_enter, HCI1394_TNF_HAL_STACK_ISOCH,
358 	    "");
359 
360 	/* follow ixl links until reach end or find error */
361 	while ((ixlnextp != NULL) && (wvp->dma_bld_error == 0)) {
362 
363 		/* set this command as the current ixl command */
364 		wvp->ixl_cur_cmdp = ixlcurp = ixlnextp;
365 		ixlnextp = ixlcurp->next_ixlp;
366 
367 		ixlopcode = ixlcurp->ixl_opcode;
368 
369 		/* init compiler controlled values in current ixl command */
370 		ixlcurp->compiler_privatep = NULL;
371 		ixlcurp->compiler_resv = 0;
372 
373 		/* error if xmit/recv mode not appropriate for current cmd */
374 		if ((((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) &&
375 			((ixlopcode & IXL1394_OPF_ONRECV) == 0)) ||
376 		    (((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) == 0) &&
377 			((ixlopcode & IXL1394_OPF_ONXMIT) == 0))) {
378 
379 			/* check if command op failed because it was invalid */
380 			if (hci1394_is_opcode_valid(ixlopcode) != B_TRUE) {
381 				TNF_PROBE_3(hci1394_parse_ixl_bad_opcode_error,
382 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
383 				    errmsg, "IXL1394_BAD_IXL_OPCODE",
384 				    tnf_opaque, ixl_commandp, ixlcurp,
385 				    tnf_opaque, ixl_opcode, ixlopcode);
386 
387 				wvp->dma_bld_error = IXL1394_EBAD_IXL_OPCODE;
388 			} else {
389 				TNF_PROBE_3(hci1394_parse_ixl_mode_error,
390 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
391 				    errmsg, "IXL1394_EWRONG_XR_CMD_MODE: "
392 				    "invalid ixlop in mode", tnf_uint, io_mode,
393 				    wvp->ixl_io_mode, tnf_opaque, ixl_opcode,
394 				    ixlopcode);
395 
396 				wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE;
397 			}
398 			continue;
399 		}
400 
401 		/*
402 		 * if ends xfer flag set, finalize current xfer descriptor
403 		 * block build
404 		 */
405 		if ((ixlopcode & IXL1394_OPF_ENDSXFER) != 0) {
406 			/* finalize any descriptor block build in progress */
407 			hci1394_finalize_cur_xfer_desc(wvp);
408 
409 			if (wvp->dma_bld_error != 0) {
410 				continue;
411 			}
412 		}
413 
414 		/*
415 		 * now process based on specific opcode value
416 		 */
417 		switch (ixlopcode) {
418 
419 		case IXL1394_OP_RECV_BUF:
420 		case IXL1394_OP_RECV_BUF_U: {
421 			ixl1394_xfer_buf_t *cur_xfer_buf_ixlp;
422 
423 			cur_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)ixlcurp;
424 
425 			/*
426 			 * In packet-per-buffer mode:
427 			 *    This ixl command builds a collection of xfer
428 			 *    descriptor blocks (size/pkt_size of them) each to
429 			 *    recv a packet whose buffer size is pkt_size and
430 			 *    whose buffer ptr is (pktcur*pkt_size + bufp)
431 			 *
432 			 * In buffer fill mode:
433 			 *    This ixl command builds a single xfer descriptor
434 			 *    block to recv as many packets or parts of packets
435 			 *    as can fit into the buffer size specified
436 			 *    (pkt_size is not used).
437 			 */
438 
439 			/* set xfer_state for new descriptor block build */
440 			wvp->xfer_state = XFER_BUF;
441 
442 			/* set this ixl command as current xferstart command */
443 			wvp->ixl_cur_xfer_stp = ixlcurp;
444 
445 			/*
446 			 * perform packet-per-buffer checks
447 			 * (no checks needed when in buffer fill mode)
448 			 */
449 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) == 0) {
450 
451 				/* the packets must use the buffer exactly */
452 				pktsize = cur_xfer_buf_ixlp->pkt_size;
453 				pktcnt = 0;
454 				if (pktsize != 0) {
455 					pktcnt = cur_xfer_buf_ixlp->size /
456 					    pktsize;
457 				}
458 				if ((pktcnt == 0) || ((pktsize * pktcnt) !=
459 				    cur_xfer_buf_ixlp->size)) {
460 
461 					TNF_PROBE_3(hci1394_parse_ixl_rat_error,
462 					    HCI1394_TNF_HAL_ERROR_ISOCH, "",
463 					    tnf_string, errmsg,
464 					    "IXL1394_EPKTSIZE_RATIO", tnf_int,
465 					    buf_size, cur_xfer_buf_ixlp->size,
466 					    tnf_int, pkt_size, pktsize);
467 
468 					wvp->dma_bld_error =
469 					    IXL1394_EPKTSIZE_RATIO;
470 					continue;
471 				}
472 			}
473 
474 			/*
475 			 * set buffer pointer & size into first xfer_bufp
476 			 * and xfer_size
477 			 */
478 			if (hci1394_set_next_xfer_buf(wvp,
479 			    cur_xfer_buf_ixlp->ixl_buf.ixldmac_addr,
480 			    cur_xfer_buf_ixlp->size) != DDI_SUCCESS) {
481 
482 				/* wvp->dma_bld_error is set by above call */
483 				continue;
484 			}
485 			break;
486 		}
487 
488 		case IXL1394_OP_RECV_PKT_ST:
489 		case IXL1394_OP_RECV_PKT_ST_U: {
490 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
491 
492 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
493 
494 			/* error if in buffer fill mode */
495 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) {
496 				TNF_PROBE_1(hci1394_parse_ixl_mode_error,
497 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
498 				    errmsg, "IXL1394_EWRONG_XR_CMD_MODE: "
499 				    "RECV_PKT_ST used in BFFILL mode");
500 
501 				wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE;
502 				continue;
503 			}
504 
505 			/* set xfer_state for new descriptor block build */
506 			/* set this ixl command as current xferstart command */
507 			wvp->xfer_state = XFER_PKT;
508 			wvp->ixl_cur_xfer_stp = ixlcurp;
509 
510 			/*
511 			 * set buffer pointer & size into first xfer_bufp
512 			 * and xfer_size
513 			 */
514 			if (hci1394_set_next_xfer_buf(wvp,
515 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
516 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
517 
518 				/* wvp->dma_bld_error is set by above call */
519 				continue;
520 			}
521 			break;
522 		}
523 
524 		case IXL1394_OP_RECV_PKT:
525 		case IXL1394_OP_RECV_PKT_U: {
526 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
527 
528 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
529 
530 			/* error if in buffer fill mode */
531 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) {
532 				TNF_PROBE_1(hci1394_parse_ixl_mode_error,
533 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
534 				    errmsg, "IXL1394_EWRONG_XR_CMD_MODE: "
535 				    "RECV_PKT_ST used in BFFILL mode");
536 
537 				wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE;
538 				continue;
539 			}
540 
541 			/* error if xfer_state not xfer pkt */
542 			if (wvp->xfer_state != XFER_PKT) {
543 				TNF_PROBE_1(hci1394_parse_ixl_misplacercv_error,
544 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
545 				    errmsg, "IXL1394_EMISPLACED_RECV: "
546 				    "RECV_PKT without RECV_PKT_ST");
547 
548 				wvp->dma_bld_error = IXL1394_EMISPLACED_RECV;
549 				continue;
550 			}
551 
552 			/*
553 			 * save xfer start cmd ixl ptr in compiler_privatep
554 			 * field of this cmd
555 			 */
556 			ixlcurp->compiler_privatep = (void *)
557 			    wvp->ixl_cur_xfer_stp;
558 
559 			/*
560 			 * save pkt index [1-n] in compiler_resv field of
561 			 * this cmd
562 			 */
563 			ixlcurp->compiler_resv = wvp->xfer_bufcnt;
564 
565 			/*
566 			 * set buffer pointer & size into next xfer_bufp
567 			 * and xfer_size
568 			 */
569 			if (hci1394_set_next_xfer_buf(wvp,
570 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
571 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
572 
573 				/* wvp->dma_bld_error is set by above call */
574 				continue;
575 			}
576 
577 			/*
578 			 * set updateable xfer cache flush eval flag if
579 			 * updateable opcode
580 			 */
581 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
582 				wvp->xfer_hci_flush |= UPDATEABLE_XFER;
583 			}
584 			break;
585 		}
586 
587 		case IXL1394_OP_SEND_BUF:
588 		case IXL1394_OP_SEND_BUF_U: {
589 			ixl1394_xfer_buf_t *cur_xfer_buf_ixlp;
590 
591 			cur_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)ixlcurp;
592 
593 			/*
594 			 * These send_buf commands build a collection of xmit
595 			 * descriptor blocks (size/pkt_size of them) each to
596 			 * xfer a packet whose buffer size is pkt_size and whose
597 			 * buffer pt is (pktcur*pkt_size + bufp). (ptr and size
598 			 * are adjusted if they have header form of ixl cmd)
599 			 */
600 
601 			/* set xfer_state for new descriptor block build */
602 			wvp->xfer_state = XFER_BUF;
603 
604 			/* set this ixl command as current xferstart command */
605 			wvp->ixl_cur_xfer_stp = ixlcurp;
606 
607 			/* the packets must use the buffer exactly,else error */
608 			pktsize = cur_xfer_buf_ixlp->pkt_size;
609 			pktcnt = 0;
610 			if (pktsize != 0) {
611 				pktcnt = cur_xfer_buf_ixlp->size / pktsize;
612 			}
613 			if ((pktcnt == 0) || ((pktsize * pktcnt) !=
614 			    cur_xfer_buf_ixlp->size)) {
615 
616 				TNF_PROBE_3(hci1394_parse_ixl_rat_error,
617 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
618 				    errmsg, "IXL1394_EPKTSIZE_RATIO", tnf_int,
619 				    buf_size, cur_xfer_buf_ixlp->size, tnf_int,
620 				    pkt_size, pktsize);
621 
622 				wvp->dma_bld_error = IXL1394_EPKTSIZE_RATIO;
623 				continue;
624 			}
625 
626 			/* set buf ptr & size into 1st xfer_bufp & xfer_size */
627 			if (hci1394_set_next_xfer_buf(wvp,
628 			    cur_xfer_buf_ixlp->ixl_buf.ixldmac_addr,
629 			    cur_xfer_buf_ixlp->size) != DDI_SUCCESS) {
630 
631 				/* wvp->dma_bld_error is set by above call */
632 				continue;
633 			}
634 			break;
635 		}
636 
637 		case IXL1394_OP_SEND_PKT_ST:
638 		case IXL1394_OP_SEND_PKT_ST_U: {
639 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
640 
641 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
642 
643 			/* set xfer_state for new descriptor block build */
644 			/* set this ixl command as current xferstart command */
645 			wvp->xfer_state = XFER_PKT;
646 			wvp->ixl_cur_xfer_stp = ixlcurp;
647 
648 			/*
649 			 * set buffer pointer & size into first xfer_bufp and
650 			 * xfer_size
651 			 */
652 			if (hci1394_set_next_xfer_buf(wvp,
653 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
654 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
655 
656 				/* wvp->dma_bld_error is set by above call */
657 				continue;
658 			}
659 			break;
660 		}
661 
662 		case IXL1394_OP_SEND_PKT_WHDR_ST:
663 		case IXL1394_OP_SEND_PKT_WHDR_ST_U: {
664 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
665 
666 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
667 
668 			/* set xfer_state for new descriptor block build */
669 			/* set this ixl command as current xferstart command */
670 			wvp->xfer_state = XFER_PKT;
671 			wvp->ixl_cur_xfer_stp = ixlcurp;
672 
673 			/*
674 			 * buffer size must be at least 4 (must include header),
675 			 * else error
676 			 */
677 			if (cur_xfer_pkt_ixlp->size < 4) {
678 				TNF_PROBE_2(hci1394_parse_ixl_hdr_missing_error,
679 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
680 				    errmsg, "IXL1394_EPKT_HDR_MISSING", tnf_int,
681 				    pkt_size, cur_xfer_pkt_ixlp->size);
682 
683 				wvp->dma_bld_error = IXL1394_EPKT_HDR_MISSING;
684 				continue;
685 			}
686 
687 			/*
688 			 * set buffer and size(excluding header) into first
689 			 * xfer_bufp and xfer_size
690 			 */
691 			if (hci1394_set_next_xfer_buf(wvp,
692 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr + 4,
693 			    cur_xfer_pkt_ixlp->size - 4) != DDI_SUCCESS) {
694 
695 				/* wvp->dma_bld_error is set by above call */
696 				continue;
697 			}
698 			break;
699 		}
700 
701 		case IXL1394_OP_SEND_PKT:
702 		case IXL1394_OP_SEND_PKT_U: {
703 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
704 
705 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
706 
707 			/* error if xfer_state not xfer pkt */
708 			if (wvp->xfer_state != XFER_PKT) {
709 				TNF_PROBE_1(hci1394_parse_ixl_misplacesnd_error,
710 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
711 				    errmsg, "IXL1394_EMISPLACED_SEND: SEND_PKT "
712 				    "without SEND_PKT_ST");
713 
714 				wvp->dma_bld_error = IXL1394_EMISPLACED_SEND;
715 				continue;
716 			}
717 
718 			/*
719 			 * save xfer start cmd ixl ptr in compiler_privatep
720 			 * field of this cmd
721 			 */
722 			ixlcurp->compiler_privatep = (void *)
723 			    wvp->ixl_cur_xfer_stp;
724 
725 			/*
726 			 * save pkt index [1-n] in compiler_resv field of this
727 			 * cmd
728 			 */
729 			ixlcurp->compiler_resv = wvp->xfer_bufcnt;
730 
731 			/*
732 			 * set buffer pointer & size into next xfer_bufp
733 			 * and xfer_size
734 			 */
735 			if (hci1394_set_next_xfer_buf(wvp,
736 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
737 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
738 
739 				/* wvp->dma_bld_error is set by above call */
740 				continue;
741 			}
742 
743 			/*
744 			 * set updateable xfer cache flush eval flag if
745 			 * updateable opcode
746 			 */
747 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
748 				wvp->xfer_hci_flush |= UPDATEABLE_XFER;
749 			}
750 			break;
751 		}
752 
753 		case IXL1394_OP_SEND_HDR_ONLY:
754 			/* set xfer_state for new descriptor block build */
755 			wvp->xfer_state = XMIT_HDRONLY;
756 
757 			/* set this ixl command as current xferstart command */
758 			wvp->ixl_cur_xfer_stp = ixlcurp;
759 			break;
760 
761 		case IXL1394_OP_SEND_NO_PKT:
762 			/* set xfer_state for new descriptor block build */
763 			wvp->xfer_state = XMIT_NOPKT;
764 
765 			/* set this ixl command as current xferstart command */
766 			wvp->ixl_cur_xfer_stp = ixlcurp;
767 			break;
768 
769 		case IXL1394_OP_JUMP:
770 		case IXL1394_OP_JUMP_U: {
771 			ixl1394_jump_t *cur_jump_ixlp;
772 
773 			cur_jump_ixlp = (ixl1394_jump_t *)ixlcurp;
774 
775 			/*
776 			 * verify label indicated by IXL1394_OP_JUMP is
777 			 * actually an IXL1394_OP_LABEL or NULL
778 			 */
779 			if ((cur_jump_ixlp->label != NULL) &&
780 			    (cur_jump_ixlp->label->ixl_opcode !=
781 			    IXL1394_OP_LABEL)) {
782 				TNF_PROBE_3(hci1394_parse_ixl_jumplabel_error,
783 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
784 				    errmsg, "IXL1394_EJUMP_NOT_TO_LABEL",
785 				    tnf_opaque, jumpixl_commandp, ixlcurp,
786 				    tnf_opaque, jumpto_ixl,
787 				    cur_jump_ixlp->label);
788 
789 				wvp->dma_bld_error = IXL1394_EJUMP_NOT_TO_LABEL;
790 				continue;
791 			}
792 			break;
793 		}
794 
795 		case IXL1394_OP_LABEL:
796 			/*
797 			 * save current ixl label command for xfer cmd
798 			 * finalize processing
799 			 */
800 			wvp->ixl_cur_labelp = ixlcurp;
801 
802 			/* set initiating label flag to cause cache flush */
803 			wvp->xfer_hci_flush |= INITIATING_LBL;
804 			break;
805 
806 		case IXL1394_OP_CALLBACK:
807 		case IXL1394_OP_CALLBACK_U:
808 		case IXL1394_OP_STORE_TIMESTAMP:
809 			/*
810 			 * these commands are accepted during compile,
811 			 * processed during execution (interrupt handling)
812 			 * No further processing is needed here.
813 			 */
814 			break;
815 
816 		case IXL1394_OP_SET_SKIPMODE:
817 		case IXL1394_OP_SET_SKIPMODE_U:
818 			/*
819 			 * Error if already have a set skipmode cmd for
820 			 * this xfer
821 			 */
822 			if (wvp->ixl_setskipmode_cmdp != NULL) {
823 				TNF_PROBE_2(hci1394_parse_ixl_dup_set_error,
824 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
825 				    errmsg, "IXL1394_EDUPLICATE_SET_CMD:"
826 				    " duplicate set skipmode", tnf_opaque,
827 				    ixl_commandp, ixlcurp);
828 
829 				wvp->dma_bld_error = IXL1394_EDUPLICATE_SET_CMD;
830 				continue;
831 			}
832 
833 			/* save skip mode ixl command and verify skipmode */
834 			wvp->ixl_setskipmode_cmdp = (ixl1394_set_skipmode_t *)
835 			    ixlcurp;
836 
837 			if ((wvp->ixl_setskipmode_cmdp->skipmode !=
838 				IXL1394_SKIP_TO_NEXT) &&
839 			    (wvp->ixl_setskipmode_cmdp->skipmode !=
840 				IXL1394_SKIP_TO_SELF) &&
841 			    (wvp->ixl_setskipmode_cmdp->skipmode !=
842 				IXL1394_SKIP_TO_STOP) &&
843 			    (wvp->ixl_setskipmode_cmdp->skipmode !=
844 				IXL1394_SKIP_TO_LABEL)) {
845 
846 				TNF_PROBE_3(hci1394_parse_ixl_dup_set_error,
847 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
848 				    errmsg, "IXL EBAD_SKIPMODE", tnf_opaque,
849 				    ixl_commandp, ixlcurp, tnf_int, skip,
850 				    wvp->ixl_setskipmode_cmdp->skipmode);
851 
852 				wvp->dma_bld_error = IXL1394_EBAD_SKIPMODE;
853 				continue;
854 			}
855 
856 			/*
857 			 * if mode is IXL1394_SKIP_TO_LABEL, verify label
858 			 * references an IXL1394_OP_LABEL
859 			 */
860 			if ((wvp->ixl_setskipmode_cmdp->skipmode ==
861 				IXL1394_SKIP_TO_LABEL) &&
862 			    ((wvp->ixl_setskipmode_cmdp->label == NULL) ||
863 			    (wvp->ixl_setskipmode_cmdp->label->ixl_opcode !=
864 				IXL1394_OP_LABEL))) {
865 
866 				TNF_PROBE_3(hci1394_parse_ixl_jump_error,
867 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
868 				    errmsg, "IXL1394_EJUMP_NOT_TO_LABEL",
869 				    tnf_opaque, jumpixl_commandp, ixlcurp,
870 				    tnf_opaque, jumpto_ixl,
871 				    wvp->ixl_setskipmode_cmdp->label);
872 
873 				wvp->dma_bld_error = IXL1394_EJUMP_NOT_TO_LABEL;
874 				continue;
875 			}
876 			/*
877 			 * set updateable set cmd cache flush eval flag if
878 			 * updateable opcode
879 			 */
880 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
881 				wvp->xfer_hci_flush |= UPDATEABLE_SET;
882 			}
883 			break;
884 
885 		case IXL1394_OP_SET_TAGSYNC:
886 		case IXL1394_OP_SET_TAGSYNC_U:
887 			/*
888 			 * is an error if already have a set tag and sync cmd
889 			 * for this xfer
890 			 */
891 			if (wvp->ixl_settagsync_cmdp != NULL) {
892 				TNF_PROBE_2(hci1394_parse_ixl_dup_set_error,
893 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
894 				    errmsg, "IXL1394_EDUPLICATE_SET_CMD:"
895 				    " duplicate set tagsync", tnf_opaque,
896 				    ixl_commandp, ixlcurp);
897 
898 				wvp->dma_bld_error = IXL1394_EDUPLICATE_SET_CMD;
899 				continue;
900 			}
901 
902 			/* save ixl command containing tag and sync values */
903 			wvp->ixl_settagsync_cmdp =
904 			    (ixl1394_set_tagsync_t *)ixlcurp;
905 
906 			/*
907 			 * set updateable set cmd cache flush eval flag if
908 			 * updateable opcode
909 			 */
910 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
911 				wvp->xfer_hci_flush |= UPDATEABLE_SET;
912 			}
913 			break;
914 
915 		case IXL1394_OP_SET_SYNCWAIT:
916 			/*
917 			 * count ixl wait-for-sync commands since last
918 			 * finalize ignore multiple occurrences for same xfer
919 			 * command
920 			 */
921 			wvp->ixl_setsyncwait_cnt++;
922 			break;
923 
924 		default:
925 			/* error - unknown/unimplemented ixl command */
926 			TNF_PROBE_3(hci1394_parse_ixl_bad_opcode_error,
927 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
928 			    "IXL1394_BAD_IXL_OPCODE", tnf_opaque, ixl_commandp,
929 			    ixlcurp, tnf_opaque, ixl_opcode, ixlopcode);
930 
931 			wvp->dma_bld_error = IXL1394_EBAD_IXL_OPCODE;
932 			continue;
933 		}
934 	} /* while */
935 
936 	/* finalize any last descriptor block build */
937 	wvp->ixl_cur_cmdp = NULL;
938 	if (wvp->dma_bld_error == 0) {
939 		hci1394_finalize_cur_xfer_desc(wvp);
940 	}
941 
942 	TNF_PROBE_0_DEBUG(hci1394_parse_ixl_exit,
943 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
944 }
945 
946 /*
947  * hci1394_finalize_all_xfer_desc()
948  *    Pass 2: Scan IXL resolving all dma descriptor jump and skip addresses.
949  *
950  *    Set interrupt enable on first descriptor block associated with current
951  *    xfer IXL command if current IXL xfer was introduced by an IXL label cmnd.
952  *
953  *    Set interrupt enable on last descriptor block associated with current xfer
954  *    IXL command if any callback ixl commands are found on the execution path
955  *    between the current and the next xfer ixl command.  (Previously, this
956  *    applied to store timestamp ixl commands, as well.)
957  */
958 static void
959 hci1394_finalize_all_xfer_desc(hci1394_comp_ixl_vars_t *wvp)
960 {
961 	ixl1394_command_t *ixlcurp;		/* current ixl command */
962 	ixl1394_command_t *ixlnextp;		/* next ixl command */
963 	ixl1394_command_t *ixlexecnext;
964 	hci1394_xfer_ctl_t	*xferctl_curp;
965 	hci1394_xfer_ctl_t	*xferctl_nxtp;
966 	hci1394_desc_t		*hcidescp;
967 	ddi_acc_handle_t	acc_hdl;
968 	uint32_t	temp;
969 	uint32_t	dma_execnext_addr;
970 	uint32_t	dma_skiplabel_addr;
971 	uint32_t	dma_skip_addr;
972 	uint32_t	callback_cnt;
973 	uint16_t	repcnt;
974 	uint16_t	ixlopcode;
975 	int		ii;
976 	int		err;
977 
978 	TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_enter,
979 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
980 
981 	/*
982 	 * If xmit mode and if default skipmode is skip to label -
983 	 * follow exec path starting at default skipmode label until
984 	 * find the first ixl xfer command which is to be executed.
985 	 * Set its address into default_skipxferp.
986 	 */
987 	if (((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) == 0) &&
988 	    (wvp->ctxtp->default_skipmode == IXL1394_SKIP_TO_LABEL)) {
989 
990 		err = hci1394_ixl_find_next_exec_xfer(wvp->default_skiplabelp,
991 		    NULL, &wvp->default_skipxferp);
992 		if (err == DDI_FAILURE) {
993 			TNF_PROBE_2(hci1394_finalize_all_xfer_desc_error,
994 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
995 			    "IXL1394_ENO_DATA_PKTS: label<->jump loop detected "
996 			    "for skiplabel default w/no xfers", tnf_opaque,
997 			    skipixl_cmdp, wvp->default_skiplabelp);
998 			TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_exit,
999 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
1000 
1001 			wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
1002 			return;
1003 		}
1004 	}
1005 
1006 	/* set first ixl cmd */
1007 	ixlnextp = wvp->ctxtp->ixl_firstp;
1008 
1009 	/* follow ixl links until reach end or find error */
1010 	while ((ixlnextp != NULL) && (wvp->dma_bld_error == 0)) {
1011 
1012 		/* set this command as the current ixl command */
1013 		ixlcurp = ixlnextp;
1014 		ixlnextp = ixlcurp->next_ixlp;
1015 
1016 		/* get command opcode removing unneeded update flag */
1017 		ixlopcode = ixlcurp->ixl_opcode & ~IXL1394_OPF_UPDATE;
1018 
1019 		/*
1020 		 * Scan for next ixl xfer start command (including this one),
1021 		 * along ixl link path. Once xfer command found, find next IXL
1022 		 * xfer cmd along execution path and fill in branch address of
1023 		 * current xfer command. If is composite ixl xfer command, first
1024 		 * link forward branch dma addresses of each descriptor block in
1025 		 * composite, until reach final one then set its branch address
1026 		 * to next execution path xfer found.  Next determine skip mode
1027 		 * and fill in skip address(es) appropriately.
1028 		 */
1029 		/* skip to next if not xfer start ixl command */
1030 		if (((ixlopcode & IXL1394_OPF_ISXFER) == 0) ||
1031 		    ((ixlopcode & IXL1394_OPTY_MASK) == 0)) {
1032 			continue;
1033 		}
1034 
1035 		/*
1036 		 * get xfer_ctl structure and composite repeat count for current
1037 		 * IXL xfer cmd
1038 		 */
1039 		xferctl_curp = (hci1394_xfer_ctl_t *)ixlcurp->compiler_privatep;
1040 		repcnt = xferctl_curp->cnt;
1041 
1042 		/*
1043 		 * if initiated by an IXL label command, set interrupt enable
1044 		 * flag into last component of first descriptor block of
1045 		 * current IXL xfer cmd
1046 		 */
1047 		if ((xferctl_curp->ctl_flags & XCTL_LABELLED) != 0) {
1048 			hcidescp = (hci1394_desc_t *)
1049 			    xferctl_curp->dma[0].dma_descp;
1050 			acc_hdl = xferctl_curp->dma[0].dma_buf->bi_handle;
1051 			temp = ddi_get32(acc_hdl, &hcidescp->hdr);
1052 			temp |= DESC_INTR_ENBL;
1053 			ddi_put32(acc_hdl, &hcidescp->hdr, temp);
1054 		}
1055 
1056 		/* find next xfer IXL cmd by following execution path */
1057 		err = hci1394_ixl_find_next_exec_xfer(ixlcurp->next_ixlp,
1058 		    &callback_cnt, &ixlexecnext);
1059 
1060 		/* if label<->jump loop detected, return error */
1061 		if (err == DDI_FAILURE) {
1062 			wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
1063 
1064 			TNF_PROBE_2(hci1394_finalize_all_xfer_desc_error,
1065 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1066 			    "IXL1394_ENO_DATA_PKTS: label<->jump loop detected "
1067 			    "w/no xfers", tnf_opaque, ixl_cmdp,
1068 			    ixlcurp->next_ixlp);
1069 			continue;
1070 		}
1071 
1072 		/* link current IXL's xfer_ctl to next xfer IXL on exec path */
1073 		xferctl_curp->execp = ixlexecnext;
1074 
1075 		/*
1076 		 * if callbacks have been seen during execution path scan,
1077 		 * set interrupt enable flag into last descriptor of last
1078 		 * descriptor block of current IXL xfer cmd
1079 		 */
1080 		if (callback_cnt != 0) {
1081 			hcidescp = (hci1394_desc_t *)
1082 			    xferctl_curp->dma[repcnt - 1].dma_descp;
1083 			acc_hdl =
1084 			    xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle;
1085 			temp = ddi_get32(acc_hdl, &hcidescp->hdr);
1086 			temp |= DESC_INTR_ENBL;
1087 			ddi_put32(acc_hdl, &hcidescp->hdr, temp);
1088 		}
1089 
1090 		/*
1091 		 * obtain dma bound addr of next exec path IXL xfer command,
1092 		 * if any
1093 		 */
1094 		dma_execnext_addr = 0;
1095 
1096 		if (ixlexecnext != NULL) {
1097 			xferctl_nxtp = (hci1394_xfer_ctl_t *)
1098 			    ixlexecnext->compiler_privatep;
1099 			dma_execnext_addr = xferctl_nxtp->dma[0].dma_bound;
1100 		} else {
1101 			/*
1102 			 * If this is last descriptor (next == NULL), then
1103 			 * make sure the interrupt bit is enabled.  This
1104 			 * way we can ensure that we are notified when the
1105 			 * descriptor chain processing has come to an end.
1106 			 */
1107 			hcidescp = (hci1394_desc_t *)
1108 			    xferctl_curp->dma[repcnt - 1].dma_descp;
1109 			acc_hdl =
1110 			    xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle;
1111 			temp = ddi_get32(acc_hdl, &hcidescp->hdr);
1112 			temp |= DESC_INTR_ENBL;
1113 			ddi_put32(acc_hdl, &hcidescp->hdr, temp);
1114 		}
1115 
1116 		/*
1117 		 * set jump address of final cur IXL xfer cmd to addr next
1118 		 * IXL xfer cmd
1119 		 */
1120 		hcidescp = (hci1394_desc_t *)
1121 		    xferctl_curp->dma[repcnt - 1].dma_descp;
1122 		acc_hdl = xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle;
1123 		ddi_put32(acc_hdl, &hcidescp->branch, dma_execnext_addr);
1124 
1125 		/*
1126 		 * if a composite object, forward link initial jump
1127 		 * dma addresses
1128 		 */
1129 		for (ii = 0; ii < repcnt - 1; ii++) {
1130 			hcidescp = (hci1394_desc_t *)
1131 			    xferctl_curp->dma[ii].dma_descp;
1132 			acc_hdl	 = xferctl_curp->dma[ii].dma_buf->bi_handle;
1133 			ddi_put32(acc_hdl, &hcidescp->branch,
1134 			    xferctl_curp->dma[ii + 1].dma_bound);
1135 		}
1136 
1137 		/*
1138 		 * fill in skip address(es) for all descriptor blocks belonging
1139 		 * to current IXL xfer command; note:skip addresses apply only
1140 		 * to xmit mode commands
1141 		 */
1142 		if ((ixlopcode & IXL1394_OPF_ONXMIT) != 0) {
1143 
1144 			/* first obtain and set skip mode information */
1145 			wvp->ixl_setskipmode_cmdp = xferctl_curp->skipmodep;
1146 			hci1394_set_xmit_skip_mode(wvp);
1147 
1148 			/*
1149 			 * if skip to label,init dma bound addr to be
1150 			 * 1st xfer cmd after label
1151 			 */
1152 			dma_skiplabel_addr = 0;
1153 			if ((wvp->skipmode == IXL1394_SKIP_TO_LABEL) &&
1154 			    (wvp->skipxferp != NULL)) {
1155 				xferctl_nxtp = (hci1394_xfer_ctl_t *)
1156 				    wvp->skipxferp->compiler_privatep;
1157 				dma_skiplabel_addr =
1158 				    xferctl_nxtp->dma[0].dma_bound;
1159 			}
1160 
1161 			/*
1162 			 * set skip addrs for each descriptor blk at this
1163 			 * xfer start IXL cmd
1164 			 */
1165 			for (ii = 0; ii < repcnt; ii++) {
1166 				switch (wvp->skipmode) {
1167 
1168 				case IXL1394_SKIP_TO_LABEL:
1169 					/* set dma bound address - label */
1170 					dma_skip_addr = dma_skiplabel_addr;
1171 					break;
1172 
1173 				case IXL1394_SKIP_TO_NEXT:
1174 					/* set dma bound address - next */
1175 					if (ii < repcnt - 1) {
1176 						dma_skip_addr = xferctl_curp->
1177 						    dma[ii + 1].dma_bound;
1178 					} else {
1179 						dma_skip_addr =
1180 						    dma_execnext_addr;
1181 					}
1182 					break;
1183 
1184 				case IXL1394_SKIP_TO_SELF:
1185 					/* set dma bound address - self */
1186 					dma_skip_addr =
1187 					    xferctl_curp->dma[ii].dma_bound;
1188 					break;
1189 
1190 				case IXL1394_SKIP_TO_STOP:
1191 				default:
1192 					/* set dma bound address - stop */
1193 					dma_skip_addr = 0;
1194 					break;
1195 				}
1196 
1197 				/*
1198 				 * determine address of first descriptor of
1199 				 * current descriptor block by adjusting addr of
1200 				 * last descriptor of current descriptor block
1201 				 */
1202 				hcidescp = ((hci1394_desc_t *)
1203 				    xferctl_curp->dma[ii].dma_descp);
1204 				acc_hdl =
1205 				    xferctl_curp->dma[ii].dma_buf->bi_handle;
1206 
1207 				/*
1208 				 * adjust by count of descriptors in this desc
1209 				 * block not including the last one (size of
1210 				 * descriptor)
1211 				 */
1212 				hcidescp -= ((xferctl_curp->dma[ii].dma_bound &
1213 				    DESC_Z_MASK) - 1);
1214 
1215 				/*
1216 				 * adjust further if the last descriptor is
1217 				 * double sized
1218 				 */
1219 				if (ixlopcode == IXL1394_OP_SEND_HDR_ONLY) {
1220 					hcidescp++;
1221 				}
1222 				/*
1223 				 * now set skip address into first descriptor
1224 				 * of descriptor block
1225 				 */
1226 				ddi_put32(acc_hdl, &hcidescp->branch,
1227 				    dma_skip_addr);
1228 			} /* for */
1229 		} /* if */
1230 	} /* while */
1231 
1232 	TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_exit,
1233 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1234 }
1235 
1236 /*
1237  * hci1394_finalize_cur_xfer_desc()
1238  *    Build the openHCI descriptor for a packet or buffer based on info
1239  *    currently collected into the working vars struct (wvp).  After some
1240  *    checks, this routine dispatches to the appropriate descriptor block
1241  *    build (bld) routine for the packet or buf type.
1242  */
1243 static void
1244 hci1394_finalize_cur_xfer_desc(hci1394_comp_ixl_vars_t *wvp)
1245 {
1246 	uint16_t ixlopcode;
1247 	uint16_t ixlopraw;
1248 
1249 	TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_enter,
1250 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1251 
1252 	/* extract opcode from current IXL cmd (if any) */
1253 	if (wvp->ixl_cur_cmdp != NULL) {
1254 		ixlopcode = wvp->ixl_cur_cmdp->ixl_opcode;
1255 		ixlopraw = ixlopcode & ~IXL1394_OPF_UPDATE;
1256 	} else {
1257 		ixlopcode = ixlopraw = IXL1394_OP_INVALID;
1258 	}
1259 
1260 	/*
1261 	 * if no xfer descriptor block being built, perform validity checks
1262 	 */
1263 	if (wvp->xfer_state == XFER_NONE) {
1264 		/*
1265 		 * error if being finalized by IXL1394_OP_LABEL or
1266 		 * IXL1394_OP_JUMP or if at end, and have an unapplied
1267 		 * IXL1394_OP_SET_TAGSYNC, IXL1394_OP_SET_SKIPMODE or
1268 		 * IXL1394_OP_SET_SYNCWAIT
1269 		 */
1270 		if ((ixlopraw == IXL1394_OP_JUMP) ||
1271 		    (ixlopraw == IXL1394_OP_LABEL) ||
1272 		    (wvp->ixl_cur_cmdp == NULL) ||
1273 		    (wvp->ixl_cur_cmdp->next_ixlp == NULL)) {
1274 			if ((wvp->ixl_settagsync_cmdp != NULL) ||
1275 			    (wvp->ixl_setskipmode_cmdp != NULL) ||
1276 			    (wvp->ixl_setsyncwait_cnt != 0)) {
1277 
1278 				wvp->dma_bld_error = IXL1394_EUNAPPLIED_SET_CMD;
1279 
1280 				TNF_PROBE_2(
1281 				    hci1394_finalize_cur_xfer_desc_set_error,
1282 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
1283 				    errmsg, "IXL1394_UNAPPLIED_SET_CMD: "
1284 				    "orphaned set (no associated packet)",
1285 				    tnf_opaque, ixl_commandp,
1286 				    wvp->ixl_cur_cmdp);
1287 				TNF_PROBE_0_DEBUG(
1288 				    hci1394_finalize_cur_xfer_desc_exit,
1289 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
1290 				return;
1291 			}
1292 		}
1293 
1294 		/* error if finalize is due to updateable jump cmd */
1295 		if (ixlopcode == IXL1394_OP_JUMP_U) {
1296 
1297 			wvp->dma_bld_error = IXL1394_EUPDATE_DISALLOWED;
1298 
1299 			TNF_PROBE_2(hci1394_finalize_cur_xfer_desc_upd_error,
1300 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1301 			    "IXL1394_EUPDATE_DISALLOWED: jumpU w/out pkt",
1302 			    tnf_opaque, ixl_commandp, wvp->ixl_cur_cmdp);
1303 			TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
1304 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
1305 			return;
1306 		}
1307 
1308 		TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
1309 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1310 
1311 		/* no error, no xfer */
1312 		return;
1313 	}
1314 
1315 	/*
1316 	 * finalize current xfer descriptor block being built
1317 	 */
1318 
1319 	/* count IXL xfer start command for descriptor block being built */
1320 	wvp->ixl_xfer_st_cnt++;
1321 
1322 	/*
1323 	 * complete setting of cache flush evaluation flags; flags will already
1324 	 * have been set by updateable set cmds and non-start xfer pkt cmds
1325 	 */
1326 	/* now set cache flush flag if current xfer start cmnd is updateable */
1327 	if ((wvp->ixl_cur_xfer_stp->ixl_opcode & IXL1394_OPF_UPDATE) != 0) {
1328 		wvp->xfer_hci_flush |= UPDATEABLE_XFER;
1329 	}
1330 	/*
1331 	 * also set cache flush flag if xfer being finalized by
1332 	 * updateable jump cmd
1333 	 */
1334 	if ((ixlopcode == IXL1394_OP_JUMP_U) != 0) {
1335 		wvp->xfer_hci_flush |= UPDATEABLE_JUMP;
1336 	}
1337 
1338 	/*
1339 	 * Determine if cache flush required before building next descriptor
1340 	 * block. If xfer pkt command and any cache flush flags are set,
1341 	 * hci flush needed.
1342 	 * If buffer or special xfer command and xfer command is updateable or
1343 	 * an associated set command is updateable, hci flush is required now.
1344 	 * If a single-xfer buffer or special xfer command is finalized by
1345 	 * updateable jump command, hci flush is required now.
1346 	 * Note: a cache flush will be required later, before the last
1347 	 * descriptor block of a multi-xfer set of descriptor blocks is built,
1348 	 * if this (non-pkt) xfer is finalized by an updateable jump command.
1349 	 */
1350 	if (wvp->xfer_hci_flush != 0) {
1351 		if (((wvp->ixl_cur_xfer_stp->ixl_opcode &
1352 		    IXL1394_OPTY_XFER_PKT_ST) != 0) || ((wvp->xfer_hci_flush &
1353 			(UPDATEABLE_XFER | UPDATEABLE_SET | INITIATING_LBL)) !=
1354 			0)) {
1355 
1356 			if (hci1394_flush_hci_cache(wvp) != DDI_SUCCESS) {
1357 				TNF_PROBE_0_DEBUG(
1358 				    hci1394_finalize_cur_xfer_desc_exit,
1359 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
1360 
1361 				/* wvp->dma_bld_error is set by above call */
1362 				return;
1363 			}
1364 		}
1365 	}
1366 
1367 	/*
1368 	 * determine which kind of descriptor block to build based on
1369 	 * xfer state - hdr only, skip cycle, pkt or buf.
1370 	 */
1371 	switch (wvp->xfer_state) {
1372 
1373 	case XFER_PKT:
1374 		if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) {
1375 			hci1394_bld_recv_pkt_desc(wvp);
1376 		} else {
1377 			hci1394_bld_xmit_pkt_desc(wvp);
1378 		}
1379 		break;
1380 
1381 	case XFER_BUF:
1382 		if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) {
1383 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) {
1384 				hci1394_bld_recv_buf_fill_desc(wvp);
1385 			} else {
1386 				hci1394_bld_recv_buf_ppb_desc(wvp);
1387 			}
1388 		} else {
1389 			hci1394_bld_xmit_buf_desc(wvp);
1390 		}
1391 		break;
1392 
1393 	case XMIT_HDRONLY:
1394 	case XMIT_NOPKT:
1395 		hci1394_bld_xmit_hdronly_nopkt_desc(wvp);
1396 		break;
1397 
1398 	default:
1399 		/* internal compiler error */
1400 		TNF_PROBE_2(hci1394_finalize_cur_xfer_desc_internal_error,
1401 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1402 		    "IXL1394_INTERNAL_ERROR: invalid state", tnf_opaque,
1403 		    ixl_commandp, wvp->ixl_cur_cmdp);
1404 		wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR;
1405 	}
1406 
1407 	/* return if error */
1408 	if (wvp->dma_bld_error != 0) {
1409 		TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
1410 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1411 
1412 		/* wvp->dma_bld_error is set by above call */
1413 		return;
1414 	}
1415 
1416 	/*
1417 	 * if was finalizing IXL jump cmd, set compiler_privatep to
1418 	 * cur xfer IXL cmd
1419 	 */
1420 	if (ixlopraw == IXL1394_OP_JUMP) {
1421 		wvp->ixl_cur_cmdp->compiler_privatep =
1422 		    (void *)wvp->ixl_cur_xfer_stp;
1423 	}
1424 
1425 	/* if cur xfer IXL initiated by IXL label cmd, set flag in xfer_ctl */
1426 	if (wvp->ixl_cur_labelp != NULL) {
1427 		((hci1394_xfer_ctl_t *)
1428 		    (wvp->ixl_cur_xfer_stp->compiler_privatep))->ctl_flags |=
1429 		    XCTL_LABELLED;
1430 		wvp->ixl_cur_labelp = NULL;
1431 	}
1432 
1433 	/*
1434 	 * set any associated IXL set skipmode cmd into xfer_ctl of
1435 	 * cur xfer IXL cmd
1436 	 */
1437 	if (wvp->ixl_setskipmode_cmdp != NULL) {
1438 		((hci1394_xfer_ctl_t *)
1439 		    (wvp->ixl_cur_xfer_stp->compiler_privatep))->skipmodep =
1440 		    wvp->ixl_setskipmode_cmdp;
1441 	}
1442 
1443 	/* set no current xfer start cmd */
1444 	wvp->ixl_cur_xfer_stp = NULL;
1445 
1446 	/* set no current set tag&sync, set skipmode or set syncwait commands */
1447 	wvp->ixl_settagsync_cmdp = NULL;
1448 	wvp->ixl_setskipmode_cmdp = NULL;
1449 	wvp->ixl_setsyncwait_cnt = 0;
1450 
1451 	/* set no currently active descriptor blocks */
1452 	wvp->descriptors = 0;
1453 
1454 	/* reset total packet length and buffers count */
1455 	wvp->xfer_pktlen = 0;
1456 	wvp->xfer_bufcnt = 0;
1457 
1458 	/* reset flush cache evaluation flags */
1459 	wvp->xfer_hci_flush = 0;
1460 
1461 	/* set no xmit descriptor block being built */
1462 	wvp->xfer_state = XFER_NONE;
1463 
1464 	TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
1465 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1466 }
1467 
1468 /*
1469  * hci1394_bld_recv_pkt_desc()
1470  *    Used to create the openHCI dma descriptor block(s) for a receive packet.
1471  */
1472 static void
1473 hci1394_bld_recv_pkt_desc(hci1394_comp_ixl_vars_t *wvp)
1474 {
1475 	hci1394_xfer_ctl_t	*xctlp;
1476 	caddr_t			dma_descp;
1477 	uint32_t		dma_desc_bound;
1478 	uint32_t		wait_for_sync;
1479 	uint32_t		ii;
1480 	hci1394_desc_t		*wv_descp;	/* shorthand to local descrpt */
1481 
1482 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_enter,
1483 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1484 
1485 	/*
1486 	 * is error if number of descriptors to be built exceeds maximum
1487 	 * descriptors allowed in a descriptor block.
1488 	 */
1489 	if ((wvp->descriptors + wvp->xfer_bufcnt) > HCI1394_DESC_MAX_Z) {
1490 
1491 		wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO;
1492 
1493 		TNF_PROBE_3(hci1394_bld_recv_pkt_desc_fragment_oflo_error,
1494 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1495 		    "IXL1394_EFRAGMENT_OFLO", tnf_opaque, ixl_commandp,
1496 		    wvp->ixl_cur_xfer_stp, tnf_int, frag_count,
1497 		    wvp->descriptors + wvp->xfer_bufcnt);
1498 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
1499 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1500 		return;
1501 	}
1502 
1503 	/* allocate an xfer_ctl struct, including 1 xfer_ctl_dma struct */
1504 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) {
1505 
1506 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
1507 
1508 		TNF_PROBE_2(hci1394_bld_recv_pkt_desc_mem_alloc_fail,
1509 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1510 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
1511 		    ixl_commandp, wvp->ixl_cur_xfer_stp);
1512 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
1513 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1514 		return;
1515 	}
1516 
1517 	/*
1518 	 * save xfer_ctl struct addr in compiler_privatep of
1519 	 * current IXL xfer cmd
1520 	 */
1521 	wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
1522 
1523 	/*
1524 	 * if enabled, set wait for sync flag in first descriptor of
1525 	 * descriptor block
1526 	 */
1527 	if (wvp->ixl_setsyncwait_cnt > 0) {
1528 		wvp->ixl_setsyncwait_cnt = 1;
1529 		wait_for_sync = DESC_W_ENBL;
1530 	} else {
1531 		wait_for_sync = DESC_W_DSABL;
1532 	}
1533 
1534 	/* create descriptor block for this recv packet (xfer status enabled) */
1535 	for (ii = 0; ii < wvp->xfer_bufcnt; ii++) {
1536 		wv_descp = &wvp->descriptor_block[wvp->descriptors];
1537 
1538 		if (ii == (wvp->xfer_bufcnt - 1)) {
1539 			HCI1394_INIT_IR_PPB_ILAST(wv_descp, DESC_HDR_STAT_ENBL,
1540 			    DESC_INTR_DSABL, wait_for_sync, wvp->xfer_size[ii]);
1541 		} else {
1542 			HCI1394_INIT_IR_PPB_IMORE(wv_descp, wait_for_sync,
1543 			    wvp->xfer_size[ii]);
1544 		}
1545 		wv_descp->data_addr = wvp->xfer_bufp[ii];
1546 		wv_descp->branch = 0;
1547 		wv_descp->status = (wvp->xfer_size[ii] <<
1548 		    DESC_ST_RESCOUNT_SHIFT) & DESC_ST_RESCOUNT_MASK;
1549 		wvp->descriptors++;
1550 	}
1551 
1552 	/* allocate and copy descriptor block to dma memory */
1553 	if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound) !=
1554 	    DDI_SUCCESS) {
1555 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
1556 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1557 
1558 		/* wvp->dma_bld_error is set by above function call */
1559 		return;
1560 	}
1561 
1562 	/*
1563 	 * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual)
1564 	 * is last component)
1565 	 */
1566 	xctlp->dma[0].dma_bound = dma_desc_bound;
1567 	xctlp->dma[0].dma_descp =
1568 	    dma_descp + (wvp->xfer_bufcnt - 1) * sizeof (hci1394_desc_t);
1569 	xctlp->dma[0].dma_buf	= &wvp->dma_currentp->mem;
1570 
1571 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
1572 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1573 }
1574 
1575 /*
1576  * hci1394_bld_recv_buf_ppb_desc()
1577  *    Used to create the openHCI dma descriptor block(s) for a receive buf
1578  *    in packet per buffer mode.
1579  */
1580 static void
1581 hci1394_bld_recv_buf_ppb_desc(hci1394_comp_ixl_vars_t *wvp)
1582 {
1583 	hci1394_xfer_ctl_t	*xctlp;
1584 	ixl1394_xfer_buf_t	*local_ixl_cur_xfer_stp;
1585 	caddr_t		dma_descp;
1586 	uint32_t	dma_desc_bound;
1587 	uint32_t	pktsize;
1588 	uint32_t	pktcnt;
1589 	uint32_t	wait_for_sync;
1590 	uint32_t	ii;
1591 	hci1394_desc_t	*wv_descp;	/* shorthand to local descriptor */
1592 
1593 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_enter,
1594 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1595 
1596 	local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp;
1597 
1598 	/* determine number and size of pkt desc blocks to create */
1599 	pktsize = local_ixl_cur_xfer_stp->pkt_size;
1600 	pktcnt = local_ixl_cur_xfer_stp->size / pktsize;
1601 
1602 	/* allocate an xfer_ctl struct including pktcnt xfer_ctl_dma structs */
1603 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, pktcnt)) == NULL) {
1604 
1605 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
1606 
1607 		TNF_PROBE_2(hci1394_bld_recv_buf_ppb_desc_mem_alloc_fail,
1608 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1609 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
1610 		    ixl_commandp, wvp->ixl_cur_xfer_stp);
1611 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit,
1612 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1613 		return;
1614 	}
1615 
1616 	/*
1617 	 * save xfer_ctl struct addr in compiler_privatep of
1618 	 * current IXL xfer cmd
1619 	 */
1620 	local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
1621 
1622 	/*
1623 	 * if enabled, set wait for sync flag in first descriptor in
1624 	 * descriptor block
1625 	 */
1626 	if (wvp->ixl_setsyncwait_cnt > 0) {
1627 		wvp->ixl_setsyncwait_cnt = 1;
1628 		wait_for_sync = DESC_W_ENBL;
1629 	} else {
1630 		wait_for_sync = DESC_W_DSABL;
1631 	}
1632 
1633 	/* create first descriptor block for this recv packet */
1634 	/* consists of one descriptor and xfer status is enabled */
1635 	wv_descp = &wvp->descriptor_block[wvp->descriptors];
1636 	HCI1394_INIT_IR_PPB_ILAST(wv_descp, DESC_HDR_STAT_ENBL, DESC_INTR_DSABL,
1637 	    wait_for_sync, pktsize);
1638 	wv_descp->data_addr = local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr;
1639 	wv_descp->branch = 0;
1640 	wv_descp->status = (pktsize << DESC_ST_RESCOUNT_SHIFT) &
1641 	    DESC_ST_RESCOUNT_MASK;
1642 	wvp->descriptors++;
1643 
1644 	/* useful debug trace info - IXL command, and packet count and size */
1645 	TNF_PROBE_3_DEBUG(hci1394_bld_recv_buf_ppb_desc_recv_buf_info,
1646 	    HCI1394_TNF_HAL_INFO_ISOCH, "", tnf_opaque, ixl_commandp,
1647 	    wvp->ixl_cur_xfer_stp, tnf_int, pkt_count, pktcnt, tnf_int,
1648 	    pkt_size, pktsize);
1649 
1650 	/*
1651 	 * generate as many contiguous descriptor blocks as there are
1652 	 * recv pkts
1653 	 */
1654 	for (ii = 0; ii < pktcnt; ii++) {
1655 
1656 		/* if about to create last descriptor block */
1657 		if (ii == (pktcnt - 1)) {
1658 			/* check and perform any required hci cache flush */
1659 			if (hci1394_flush_end_desc_check(wvp, ii) !=
1660 			    DDI_SUCCESS) {
1661 				TNF_PROBE_1_DEBUG(
1662 				    hci1394_bld_recv_buf_ppb_desc_fl_error,
1663 				    HCI1394_TNF_HAL_INFO_ISOCH, "", tnf_int,
1664 				    for_ii, ii);
1665 				TNF_PROBE_0_DEBUG(
1666 				    hci1394_bld_recv_buf_ppb_desc_exit,
1667 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
1668 
1669 				/* wvp->dma_bld_error is set by above call */
1670 				return;
1671 			}
1672 		}
1673 
1674 		/* allocate and copy descriptor block to dma memory */
1675 		if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp,
1676 		    &dma_desc_bound) != DDI_SUCCESS) {
1677 
1678 			TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit,
1679 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
1680 
1681 			/* wvp->dma_bld_error is set by above call */
1682 			return;
1683 		}
1684 
1685 		/*
1686 		 * set dma addrs into xfer_ctl struct (unbound addr (kernel
1687 		 * virtual) is last component (descriptor))
1688 		 */
1689 		xctlp->dma[ii].dma_bound = dma_desc_bound;
1690 		xctlp->dma[ii].dma_descp = dma_descp;
1691 		xctlp->dma[ii].dma_buf	 = &wvp->dma_currentp->mem;
1692 
1693 		/* advance buffer ptr by pktsize in descriptor block */
1694 		wvp->descriptor_block[wvp->descriptors - 1].data_addr +=
1695 		    pktsize;
1696 	}
1697 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit,
1698 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1699 }
1700 
1701 /*
1702  * hci1394_bld_recv_buf_fill_desc()
1703  *    Used to create the openHCI dma descriptor block(s) for a receive buf
1704  *    in buffer fill mode.
1705  */
1706 static void
1707 hci1394_bld_recv_buf_fill_desc(hci1394_comp_ixl_vars_t *wvp)
1708 {
1709 	hci1394_xfer_ctl_t	*xctlp;
1710 	caddr_t			dma_descp;
1711 	uint32_t		dma_desc_bound;
1712 	uint32_t		wait_for_sync;
1713 	ixl1394_xfer_buf_t	*local_ixl_cur_xfer_stp;
1714 
1715 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_enter,
1716 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1717 
1718 	local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp;
1719 
1720 
1721 	/* allocate an xfer_ctl struct including 1 xfer_ctl_dma structs */
1722 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) {
1723 
1724 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
1725 
1726 		TNF_PROBE_2(hci1394_bld_recv_buf_fill_desc_mem_alloc_fail,
1727 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1728 		    "IXL1394_EMEM_ALLOC_FAIL: xfer_ctl", tnf_opaque,
1729 		    ixl_commandp, wvp->ixl_cur_xfer_stp);
1730 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
1731 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1732 		return;
1733 	}
1734 
1735 	/*
1736 	 * save xfer_ctl struct addr in compiler_privatep of
1737 	 * current IXL xfer cmd
1738 	 */
1739 	local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
1740 
1741 	/*
1742 	 * if enabled, set wait for sync flag in first descriptor of
1743 	 * descriptor block
1744 	 */
1745 	if (wvp->ixl_setsyncwait_cnt > 0) {
1746 		wvp->ixl_setsyncwait_cnt = 1;
1747 		wait_for_sync = DESC_W_ENBL;
1748 	} else {
1749 		wait_for_sync = DESC_W_DSABL;
1750 	}
1751 
1752 	/*
1753 	 * create descriptor block for this buffer fill mode recv command which
1754 	 * consists of one descriptor with xfer status enabled
1755 	 */
1756 	HCI1394_INIT_IR_BF_IMORE(&wvp->descriptor_block[wvp->descriptors],
1757 	    DESC_INTR_DSABL, wait_for_sync, local_ixl_cur_xfer_stp->size);
1758 
1759 	wvp->descriptor_block[wvp->descriptors].data_addr =
1760 	    local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr;
1761 	wvp->descriptor_block[wvp->descriptors].branch = 0;
1762 	wvp->descriptor_block[wvp->descriptors].status =
1763 	    (local_ixl_cur_xfer_stp->size << DESC_ST_RESCOUNT_SHIFT) &
1764 	    DESC_ST_RESCOUNT_MASK;
1765 	wvp->descriptors++;
1766 
1767 	/* check and perform any required hci cache flush */
1768 	if (hci1394_flush_end_desc_check(wvp, 0) != DDI_SUCCESS) {
1769 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
1770 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1771 
1772 		/* wvp->dma_bld_error is set by above call */
1773 		return;
1774 	}
1775 
1776 	/* allocate and copy descriptor block to dma memory */
1777 	if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound)
1778 	    != DDI_SUCCESS) {
1779 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
1780 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1781 
1782 		/* wvp->dma_bld_error is set by above call */
1783 		return;
1784 	}
1785 
1786 	/*
1787 	 * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual)
1788 	 * is last component.
1789 	 */
1790 	xctlp->dma[0].dma_bound = dma_desc_bound;
1791 	xctlp->dma[0].dma_descp = dma_descp;
1792 	xctlp->dma[0].dma_buf	= &wvp->dma_currentp->mem;
1793 
1794 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
1795 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1796 }
1797 
1798 /*
1799  * hci1394_bld_xmit_pkt_desc()
1800  *    Used to create the openHCI dma descriptor block(s) for a transmit packet.
1801  */
1802 static void
1803 hci1394_bld_xmit_pkt_desc(hci1394_comp_ixl_vars_t *wvp)
1804 {
1805 	hci1394_xfer_ctl_t *xctlp;
1806 	hci1394_output_more_imm_t *wv_omi_descp; /* shorthand to local descrp */
1807 	hci1394_desc_t	*wv_descp;	/* shorthand to local descriptor */
1808 	caddr_t		dma_descp;	/* dma bound memory for descriptor */
1809 	uint32_t	dma_desc_bound;
1810 	uint32_t	ii;
1811 
1812 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_enter,
1813 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1814 
1815 	/*
1816 	 * is error if number of descriptors to be built exceeds maximum
1817 	 * descriptors allowed in a descriptor block. Add 2 for the overhead
1818 	 * of the OMORE-Immediate.
1819 	 */
1820 	if ((wvp->descriptors + 2 + wvp->xfer_bufcnt) > HCI1394_DESC_MAX_Z) {
1821 
1822 		wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO;
1823 
1824 		TNF_PROBE_3(hci1394_bld_xmit_pkt_desc_fragment_oflo_error,
1825 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1826 		    "IXL1394_EFRAGMENT_OFLO", tnf_opaque, ixl_commandp,
1827 		    wvp->ixl_cur_xfer_stp, tnf_int, frag_count,
1828 		    wvp->descriptors + 2 + wvp->xfer_bufcnt);
1829 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
1830 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1831 		return;
1832 	}
1833 
1834 	/* is error if total packet length exceeds 0xFFFF */
1835 	if (wvp->xfer_pktlen > 0xFFFF) {
1836 
1837 		wvp->dma_bld_error = IXL1394_EPKTSIZE_MAX_OFLO;
1838 
1839 		TNF_PROBE_3(hci1394_bld_xmit_pkt_desc_packet_oflo_error,
1840 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1841 		    "IXL1394_EPKTSIZE_MAX_OFLO", tnf_opaque, ixl_commandp,
1842 		    wvp->ixl_cur_xfer_stp, tnf_int, total_pktlen,
1843 		    wvp->xfer_pktlen);
1844 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
1845 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1846 		return;
1847 	}
1848 
1849 	/* allocate an xfer_ctl struct, including 1 xfer_ctl_dma struct */
1850 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) {
1851 
1852 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
1853 
1854 		TNF_PROBE_2(hci1394_bld_xmit_pkt_desc_mem_alloc_fail,
1855 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1856 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
1857 		    ixl_commandp, wvp->ixl_cur_cmdp);
1858 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
1859 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1860 		return;
1861 	}
1862 
1863 	/*
1864 	 * save xfer_ctl struct addr in compiler_privatep of
1865 	 * current IXL xfer cmd
1866 	 */
1867 	wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
1868 
1869 	/* generate values for the xmit pkt hdrs */
1870 	hci1394_set_xmit_pkt_hdr(wvp);
1871 
1872 	/*
1873 	 * xmit pkt starts with an output more immediate,
1874 	 * a double sized hci1394_desc
1875 	 */
1876 	wv_omi_descp = (hci1394_output_more_imm_t *)
1877 	    (&wvp->descriptor_block[wvp->descriptors]);
1878 	HCI1394_INIT_IT_OMORE_IMM(wv_omi_descp);
1879 
1880 	wv_omi_descp->data_addr = 0;
1881 	wv_omi_descp->branch = 0;
1882 	wv_omi_descp->status = 0;
1883 	wv_omi_descp->q1 = wvp->xmit_pkthdr1;
1884 	wv_omi_descp->q2 = wvp->xmit_pkthdr2;
1885 	wv_omi_descp->q3 = 0;
1886 	wv_omi_descp->q4 = 0;
1887 
1888 	wvp->descriptors += 2;
1889 
1890 	/*
1891 	 * create the required output more hci1394_desc descriptor, then create
1892 	 * an output last hci1394_desc descriptor with xfer status enabled
1893 	 */
1894 	for (ii = 0; ii < wvp->xfer_bufcnt; ii++) {
1895 		wv_descp = &wvp->descriptor_block[wvp->descriptors];
1896 
1897 		if (ii == (wvp->xfer_bufcnt - 1)) {
1898 			HCI1394_INIT_IT_OLAST(wv_descp, DESC_HDR_STAT_ENBL,
1899 			    DESC_INTR_DSABL, wvp->xfer_size[ii]);
1900 		} else {
1901 			HCI1394_INIT_IT_OMORE(wv_descp, wvp->xfer_size[ii]);
1902 		}
1903 		wv_descp->data_addr = wvp->xfer_bufp[ii];
1904 		wv_descp->branch = 0;
1905 		wv_descp->status = 0;
1906 		wvp->descriptors++;
1907 	}
1908 
1909 	/* allocate and copy descriptor block to dma memory */
1910 	if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound) !=
1911 	    DDI_SUCCESS) {
1912 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
1913 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1914 
1915 		/* wvp->dma_bld_error is set by above call */
1916 		return;
1917 	}
1918 
1919 	/*
1920 	 * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual)
1921 	 * is last component (descriptor))
1922 	 */
1923 	xctlp->dma[0].dma_bound = dma_desc_bound;
1924 	xctlp->dma[0].dma_descp =
1925 	    dma_descp + (wvp->xfer_bufcnt + 1) * sizeof (hci1394_desc_t);
1926 	xctlp->dma[0].dma_buf	= &wvp->dma_currentp->mem;
1927 
1928 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
1929 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1930 }
1931 
1932 /*
1933  * hci1394_bld_xmit_buf_desc()
1934  *    Used to create the openHCI dma descriptor blocks for a transmit buffer.
1935  */
1936 static void
1937 hci1394_bld_xmit_buf_desc(hci1394_comp_ixl_vars_t *wvp)
1938 {
1939 	hci1394_xfer_ctl_t	*xctlp;
1940 	ixl1394_xfer_buf_t	*local_ixl_cur_xfer_stp;
1941 	hci1394_output_more_imm_t *wv_omi_descp; /* shorthand to local descrp */
1942 	hci1394_desc_t	*wv_descp;	/* shorthand to local descriptor */
1943 	caddr_t		dma_descp;
1944 	uint32_t	dma_desc_bound;
1945 	uint32_t	pktsize;
1946 	uint32_t	pktcnt;
1947 	uint32_t	ii;
1948 
1949 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_enter,
1950 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1951 
1952 	local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp;
1953 
1954 	/* determine number and size of pkt desc blocks to create */
1955 	pktsize = local_ixl_cur_xfer_stp->pkt_size;
1956 	pktcnt = local_ixl_cur_xfer_stp->size / pktsize;
1957 
1958 	/* allocate an xfer_ctl struct including pktcnt xfer_ctl_dma structs */
1959 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, pktcnt)) == NULL) {
1960 
1961 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
1962 
1963 		TNF_PROBE_2(hci1394_bld_xmit_buf_desc_mem_alloc_fail,
1964 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
1965 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
1966 		    ixl_commandp, wvp->ixl_cur_cmdp);
1967 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit,
1968 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1969 		return;
1970 	}
1971 
1972 	/*
1973 	 * save xfer_ctl struct addr in compiler_privatep of
1974 	 * current IXL xfer cmd
1975 	 */
1976 	local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
1977 
1978 	/* generate values for the xmit pkt hdrs */
1979 	wvp->xfer_pktlen = pktsize;
1980 	hci1394_set_xmit_pkt_hdr(wvp);
1981 
1982 	/*
1983 	 * xmit pkt starts with an output more immediate,
1984 	 * a double sized hci1394_desc
1985 	 */
1986 	wv_omi_descp = (hci1394_output_more_imm_t *)
1987 	    &wvp->descriptor_block[wvp->descriptors];
1988 
1989 	HCI1394_INIT_IT_OMORE_IMM(wv_omi_descp);
1990 
1991 	wv_omi_descp->data_addr = 0;
1992 	wv_omi_descp->branch = 0;
1993 	wv_omi_descp->status = 0;
1994 	wv_omi_descp->q1 = wvp->xmit_pkthdr1;
1995 	wv_omi_descp->q2 = wvp->xmit_pkthdr2;
1996 	wv_omi_descp->q3 = 0;
1997 	wv_omi_descp->q4 = 0;
1998 
1999 	wvp->descriptors += 2;
2000 
2001 	/* follow with a single output last descriptor w/status enabled */
2002 	wv_descp = &wvp->descriptor_block[wvp->descriptors];
2003 	HCI1394_INIT_IT_OLAST(wv_descp, DESC_HDR_STAT_ENBL, DESC_INTR_DSABL,
2004 	    pktsize);
2005 	wv_descp->data_addr = local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr;
2006 	wv_descp->branch = 0;
2007 	wv_descp->status = 0;
2008 	wvp->descriptors++;
2009 
2010 	/*
2011 	 * generate as many contiguous descriptor blocks as there are
2012 	 * xmit packets
2013 	 */
2014 	for (ii = 0; ii < pktcnt; ii++) {
2015 
2016 		/* if about to create last descriptor block */
2017 		if (ii == (pktcnt - 1)) {
2018 			/* check and perform any required hci cache flush */
2019 			if (hci1394_flush_end_desc_check(wvp, ii) !=
2020 			    DDI_SUCCESS) {
2021 				TNF_PROBE_0_DEBUG(
2022 				    hci1394_bld_xmit_buf_desc_exit,
2023 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
2024 
2025 				/* wvp->dma_bld_error is set by above call */
2026 				return;
2027 			}
2028 		}
2029 
2030 		/* allocate and copy descriptor block to dma memory */
2031 		if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp,
2032 		    &dma_desc_bound) != DDI_SUCCESS) {
2033 			TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit,
2034 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
2035 
2036 			/* wvp->dma_bld_error is set by above call */
2037 			return;
2038 		}
2039 
2040 		/*
2041 		 * set dma addrs into xfer_ctl structure (unbound addr
2042 		 * (kernel virtual) is last component (descriptor))
2043 		 */
2044 		xctlp->dma[ii].dma_bound = dma_desc_bound;
2045 		xctlp->dma[ii].dma_descp = dma_descp + 2 *
2046 		    sizeof (hci1394_desc_t);
2047 		xctlp->dma[ii].dma_buf	 = &wvp->dma_currentp->mem;
2048 
2049 		/* advance buffer ptr by pktsize in descriptor block */
2050 		wvp->descriptor_block[wvp->descriptors - 1].data_addr +=
2051 		    pktsize;
2052 	}
2053 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit,
2054 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2055 }
2056 
2057 /*
2058  * hci1394_bld_xmit_hdronly_nopkt_desc()
2059  *    Used to create the openHCI dma descriptor blocks for transmitting
2060  *    a packet consisting of an isochronous header with no data payload,
2061  *    or for not sending a packet at all for a cycle.
2062  *
2063  *    A Store_Value openhci descriptor is built at the start of each
2064  *    IXL1394_OP_SEND_HDR_ONLY and IXL1394_OP_SEND_NO_PKT command's dma
2065  *    descriptor block (to allow for skip cycle specification and set skipmode
2066  *    processing for these commands).
2067  */
2068 static void
2069 hci1394_bld_xmit_hdronly_nopkt_desc(hci1394_comp_ixl_vars_t *wvp)
2070 {
2071 	hci1394_xfer_ctl_t	*xctlp;
2072 	hci1394_output_last_t	*wv_ol_descp; /* shorthand to local descrp */
2073 	hci1394_output_last_imm_t *wv_oli_descp; /* shorthand to local descrp */
2074 	caddr_t		dma_descp;
2075 	uint32_t	dma_desc_bound;
2076 	uint32_t	repcnt;
2077 	uint32_t	ii;
2078 
2079 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_enter,
2080 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2081 
2082 	/* determine # of instances of output hdronly/nopkt to generate */
2083 	repcnt = ((ixl1394_xmit_special_t *)wvp->ixl_cur_xfer_stp)->count;
2084 
2085 	/*
2086 	 * allocate an xfer_ctl structure which includes repcnt
2087 	 * xfer_ctl_dma structs
2088 	 */
2089 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, repcnt)) == NULL) {
2090 
2091 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
2092 
2093 		TNF_PROBE_2(hci1394_bld_xmit_hdronly_nopkt_desc_mem_alloc_fail,
2094 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2095 		    "IXL EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
2096 		    ixl_commandp, wvp->ixl_cur_cmdp);
2097 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_exit,
2098 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2099 		return;
2100 	}
2101 
2102 	/*
2103 	 * save xfer_ctl struct addr in compiler_privatep of
2104 	 * current IXL xfer command
2105 	 */
2106 	wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
2107 
2108 	/*
2109 	 * create a storevalue descriptor
2110 	 * (will be used for skip vs jump processing)
2111 	 */
2112 	hci1394_set_xmit_storevalue_desc(wvp);
2113 
2114 	/*
2115 	 * processing now based on opcode:
2116 	 * IXL1394_OP_SEND_HDR_ONLY or IXL1394_OP_SEND_NO_PKT
2117 	 */
2118 	if ((wvp->ixl_cur_xfer_stp->ixl_opcode & ~IXL1394_OPF_UPDATE) ==
2119 	    IXL1394_OP_SEND_HDR_ONLY) {
2120 
2121 		/* for header only, generate values for the xmit pkt hdrs */
2122 		hci1394_set_xmit_pkt_hdr(wvp);
2123 
2124 		/*
2125 		 * create an output last immediate (double sized) descriptor
2126 		 * xfer status enabled
2127 		 */
2128 		wv_oli_descp = (hci1394_output_last_imm_t *)
2129 		    &wvp->descriptor_block[wvp->descriptors];
2130 
2131 		HCI1394_INIT_IT_OLAST_IMM(wv_oli_descp, DESC_HDR_STAT_ENBL,
2132 		    DESC_INTR_DSABL);
2133 
2134 		wv_oli_descp->data_addr = 0;
2135 		wv_oli_descp->branch = 0;
2136 		wv_oli_descp->status = 0;
2137 		wv_oli_descp->q1 = wvp->xmit_pkthdr1;
2138 		wv_oli_descp->q2 = wvp->xmit_pkthdr2;
2139 		wv_oli_descp->q3 = 0;
2140 		wv_oli_descp->q4 = 0;
2141 		wvp->descriptors += 2;
2142 	} else {
2143 		/*
2144 		 * for skip cycle, create a single output last descriptor
2145 		 * with xfer status enabled
2146 		 */
2147 		wv_ol_descp = &wvp->descriptor_block[wvp->descriptors];
2148 		HCI1394_INIT_IT_OLAST(wv_ol_descp, DESC_HDR_STAT_ENBL,
2149 		    DESC_INTR_DSABL, 0);
2150 		wv_ol_descp->data_addr = 0;
2151 		wv_ol_descp->branch = 0;
2152 		wv_ol_descp->status = 0;
2153 		wvp->descriptors++;
2154 	}
2155 
2156 	/*
2157 	 * generate as many contiguous descriptor blocks as repeat count
2158 	 * indicates
2159 	 */
2160 	for (ii = 0; ii < repcnt; ii++) {
2161 
2162 		/* if about to create last descriptor block */
2163 		if (ii == (repcnt - 1)) {
2164 			/* check and perform any required hci cache flush */
2165 			if (hci1394_flush_end_desc_check(wvp, ii) !=
2166 			    DDI_SUCCESS) {
2167 				TNF_PROBE_0_DEBUG(
2168 				    hci1394_bld_xmit_hdronly_nopkt_desc_exit,
2169 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
2170 
2171 				/* wvp->dma_bld_error is set by above call */
2172 				return;
2173 			}
2174 		}
2175 
2176 		/* allocate and copy descriptor block to dma memory */
2177 		if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp,
2178 		    &dma_desc_bound) != DDI_SUCCESS) {
2179 			TNF_PROBE_0_DEBUG(
2180 			    hci1394_bld_xmit_hdronly_nopkt_desc_exit,
2181 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
2182 
2183 			/* wvp->dma_bld_error is set by above call */
2184 			return;
2185 		}
2186 
2187 		/*
2188 		 * set dma addrs into xfer_ctl structure (unbound addr
2189 		 * (kernel virtual) is last component (descriptor)
2190 		 */
2191 		xctlp->dma[ii].dma_bound = dma_desc_bound;
2192 		xctlp->dma[ii].dma_descp = dma_descp + sizeof (hci1394_desc_t);
2193 		xctlp->dma[ii].dma_buf	 = &wvp->dma_currentp->mem;
2194 	}
2195 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_exit,
2196 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2197 }
2198 
2199 /*
2200  * hci1394_bld_dma_mem_desc_blk()
2201  *    Used to put a given OpenHCI descriptor block into dma bound memory.
2202  */
2203 static int
2204 hci1394_bld_dma_mem_desc_blk(hci1394_comp_ixl_vars_t *wvp, caddr_t *dma_descpp,
2205     uint32_t *dma_desc_bound)
2206 {
2207 	uint32_t	dma_bound;
2208 
2209 	TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_enter,
2210 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2211 
2212 	/* set internal error if no descriptor blocks to build */
2213 	if (wvp->descriptors == 0) {
2214 
2215 		wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR;
2216 
2217 		TNF_PROBE_1(hci1394_bld_dma_mem_desc_blk_error,
2218 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2219 		    "IXL1394_INTERNAL_ERROR: no descriptors to build");
2220 		TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit,
2221 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2222 		return (DDI_FAILURE);
2223 	}
2224 
2225 	/* allocate dma memory and move this descriptor block to it */
2226 	*dma_descpp = (caddr_t)hci1394_alloc_dma_mem(wvp, wvp->descriptors *
2227 	    sizeof (hci1394_desc_t), &dma_bound);
2228 
2229 	if (*dma_descpp == NULL) {
2230 
2231 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
2232 
2233 		TNF_PROBE_1(hci1394_bld_dma_mem_desc_blk_fail,
2234 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2235 		    "IXL1394_EMEM_ALLOC_FAIL: for descriptors");
2236 		TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit,
2237 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2238 		return (DDI_FAILURE);
2239 	}
2240 #ifdef _KERNEL
2241 	ddi_rep_put32(wvp->dma_currentp->mem.bi_handle,
2242 	    (uint_t *)wvp->descriptor_block, (uint_t *)*dma_descpp,
2243 	    wvp->descriptors * (sizeof (hci1394_desc_t) >> 2),
2244 	    DDI_DEV_AUTOINCR);
2245 #else
2246 	bcopy(wvp->descriptor_block, *dma_descpp,
2247 	    wvp->descriptors * sizeof (hci1394_desc_t));
2248 #endif
2249 	/*
2250 	 * convert allocated block's memory address to bus address space
2251 	 * include properly set Z bits (descriptor count).
2252 	 */
2253 	*dma_desc_bound = (dma_bound & ~DESC_Z_MASK) | wvp->descriptors;
2254 
2255 	TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit,
2256 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2257 
2258 	return (DDI_SUCCESS);
2259 }
2260 
2261 /*
2262  * hci1394_set_xmit_pkt_hdr()
2263  *    Compose the 2 quadlets for the xmit packet header.
2264  */
2265 static void
2266 hci1394_set_xmit_pkt_hdr(hci1394_comp_ixl_vars_t *wvp)
2267 {
2268 	uint16_t tag;
2269 	uint16_t sync;
2270 
2271 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_pkt_hdr_enter,
2272 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2273 
2274 	/*
2275 	 * choose tag and sync bits for header either from default values or
2276 	 * from currently active set tag and sync IXL command
2277 	 * (clear command after use)
2278 	 */
2279 	if (wvp->ixl_settagsync_cmdp == NULL) {
2280 		tag = wvp->default_tag;
2281 		sync = wvp->default_sync;
2282 	} else {
2283 		tag = wvp->ixl_settagsync_cmdp->tag;
2284 		sync = wvp->ixl_settagsync_cmdp->sync;
2285 		wvp->ixl_settagsync_cmdp = NULL;
2286 	}
2287 	tag &= (DESC_PKT_TAG_MASK >> DESC_PKT_TAG_SHIFT);
2288 	sync &= (DESC_PKT_SY_MASK >> DESC_PKT_SY_SHIFT);
2289 
2290 	/*
2291 	 * build xmit pkt header -
2292 	 * hdr1 has speed, tag, channel number and sync bits
2293 	 * hdr2 has the packet length.
2294 	 */
2295 	wvp->xmit_pkthdr1 = (wvp->ctxtp->isospd << DESC_PKT_SPD_SHIFT) |
2296 	    (tag << DESC_PKT_TAG_SHIFT) | (wvp->ctxtp->isochan <<
2297 	    DESC_PKT_CHAN_SHIFT) | (IEEE1394_TCODE_ISOCH <<
2298 	    DESC_PKT_TCODE_SHIFT) | (sync << DESC_PKT_SY_SHIFT);
2299 
2300 	wvp->xmit_pkthdr2 = wvp->xfer_pktlen << DESC_PKT_DATALEN_SHIFT;
2301 
2302 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_pkt_hdr_exit,
2303 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2304 }
2305 
2306 /*
2307  * hci1394_set_xmit_skip_mode()
2308  *    Set current skip mode from default or from currently active command.
2309  *    If non-default skip mode command's skip mode is skip to label, find
2310  *    and set xfer start IXL command which follows skip to label into
2311  *    compiler_privatep of set skipmode IXL command.
2312  */
2313 static void
2314 hci1394_set_xmit_skip_mode(hci1394_comp_ixl_vars_t *wvp)
2315 {
2316 	int err;
2317 
2318 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_skip_mode_enter,
2319 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2320 
2321 	if (wvp->ixl_setskipmode_cmdp == NULL) {
2322 		wvp->skipmode = wvp->default_skipmode;
2323 		wvp->skiplabelp = wvp->default_skiplabelp;
2324 		wvp->skipxferp = wvp->default_skipxferp;
2325 	} else {
2326 		wvp->skipmode = wvp->ixl_setskipmode_cmdp->skipmode;
2327 		wvp->skiplabelp = wvp->ixl_setskipmode_cmdp->label;
2328 		wvp->skipxferp = NULL;
2329 		if (wvp->skipmode == IXL1394_SKIP_TO_LABEL) {
2330 			err = hci1394_ixl_find_next_exec_xfer(wvp->skiplabelp,
2331 			    NULL, &wvp->skipxferp);
2332 			if (err == DDI_FAILURE) {
2333 				TNF_PROBE_2(hci1394_set_xmit_skip_mode_error,
2334 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
2335 				    errmsg, "IXL1394_ENO_DATA_PKTS: "
2336 				    "label<->jump loop detected for skiplabel "
2337 				    "w/no xfers", tnf_opaque, setskip_cmdp,
2338 				    wvp->ixl_setskipmode_cmdp);
2339 				wvp->skipxferp = NULL;
2340 				wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
2341 			}
2342 		}
2343 		wvp->ixl_setskipmode_cmdp->compiler_privatep =
2344 		    (void *)wvp->skipxferp;
2345 	}
2346 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_skip_mode_exit,
2347 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2348 }
2349 
2350 /*
2351  * hci1394_set_xmit_storevalue_desc()
2352  *    Set up store_value DMA descriptor.
2353  *    XMIT_HDRONLY or XMIT_NOPKT xfer states use a store value as first
2354  *    descriptor in the descriptor block (to handle skip mode processing)
2355  */
2356 static void
2357 hci1394_set_xmit_storevalue_desc(hci1394_comp_ixl_vars_t *wvp)
2358 {
2359 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_storevalue_desc_enter,
2360 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2361 
2362 	wvp->descriptors++;
2363 
2364 	HCI1394_INIT_IT_STORE(&wvp->descriptor_block[wvp->descriptors - 1],
2365 	    wvp->storevalue_data);
2366 	wvp->descriptor_block[wvp->descriptors - 1].data_addr =
2367 	    wvp->storevalue_bufp;
2368 	wvp->descriptor_block[wvp->descriptors - 1].branch = 0;
2369 	wvp->descriptor_block[wvp->descriptors - 1].status = 0;
2370 
2371 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_storevalue_desc_exit,
2372 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2373 }
2374 
2375 /*
2376  * hci1394_set_next_xfer_buf()
2377  *    This routine adds the data buffer to the current wvp list.
2378  *    Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error
2379  *    contains the error code.
2380  */
2381 static int
2382 hci1394_set_next_xfer_buf(hci1394_comp_ixl_vars_t *wvp, uint32_t bufp,
2383     uint16_t size)
2384 {
2385 	TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_enter,
2386 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2387 
2388 	/* error if buffer pointer is null (size may be 0) */
2389 	if (bufp == NULL) {
2390 
2391 		wvp->dma_bld_error = IXL1394_ENULL_BUFFER_ADDR;
2392 
2393 		TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit,
2394 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2395 		return (DDI_FAILURE);
2396 	}
2397 
2398 	/* count new xfer buffer */
2399 	wvp->xfer_bufcnt++;
2400 
2401 	/* error if exceeds maximum xfer buffer components allowed */
2402 	if (wvp->xfer_bufcnt > HCI1394_DESC_MAX_Z) {
2403 
2404 		wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO;
2405 
2406 		TNF_PROBE_2(hci1394_set_next_xfer_buf_error,
2407 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2408 		    "IXL1394_EFRAGMENT_OFLO", tnf_int, frag_count,
2409 		    wvp->xfer_bufcnt);
2410 		TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit,
2411 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2412 		return (DDI_FAILURE);
2413 	}
2414 
2415 	/* save xmit buffer and size */
2416 	wvp->xfer_bufp[wvp->xfer_bufcnt - 1] = bufp;
2417 	wvp->xfer_size[wvp->xfer_bufcnt - 1] = size;
2418 
2419 	/* accumulate total packet length */
2420 	wvp->xfer_pktlen += size;
2421 
2422 	TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit,
2423 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2424 	return (DDI_SUCCESS);
2425 }
2426 
2427 /*
2428  * hci1394_flush_end_desc_check()
2429  *    Check if flush required before last descriptor block of a
2430  *    non-unary set generated by an xfer buff or xmit special command
2431  *    or a unary set provided no other flush has already been done.
2432  *
2433  *    hci flush is required if xfer is finalized by an updateable
2434  *    jump command.
2435  *
2436  *    Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error
2437  *    will contain the error code.
2438  */
2439 static int
2440 hci1394_flush_end_desc_check(hci1394_comp_ixl_vars_t *wvp, uint32_t count)
2441 {
2442 	TNF_PROBE_0_DEBUG(hci1394_flush_end_desc_check_enter,
2443 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2444 
2445 	if ((count != 0) ||
2446 	    ((wvp->xfer_hci_flush & (UPDATEABLE_XFER | UPDATEABLE_SET |
2447 		INITIATING_LBL)) == 0)) {
2448 
2449 		if (wvp->xfer_hci_flush & UPDATEABLE_JUMP) {
2450 			if (hci1394_flush_hci_cache(wvp) != DDI_SUCCESS) {
2451 
2452 				TNF_PROBE_0_DEBUG(
2453 				    hci1394_flush_end_desc_check_exit,
2454 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
2455 
2456 				/* wvp->dma_bld_error is set by above call */
2457 				return (DDI_FAILURE);
2458 			}
2459 		}
2460 	}
2461 
2462 	TNF_PROBE_0_DEBUG(hci1394_flush_end_desc_check_exit,
2463 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2464 	return (DDI_SUCCESS);
2465 }
2466 
2467 /*
2468  * hci1394_flush_hci_cache()
2469  *    Sun hci controller (RIO) implementation specific processing!
2470  *
2471  *    Allocate dma memory for 1 hci descriptor block which will be left unused.
2472  *    During execution this will cause a break in the contiguous address space
2473  *    processing required by Sun's RIO implementation of the ohci controller and
2474  *    will require the controller to refetch the next descriptor block from
2475  *    host memory.
2476  *
2477  *    General rules for cache flush preceeding a descriptor block in dma memory:
2478  *    1. Current IXL Xfer Command Updateable Rule:
2479  *	    Cache flush of IXL xfer command is required if it, or any of the
2480  *	    non-start IXL packet xfer commands associated with it, is flagged
2481  *	    updateable.
2482  *    2. Next IXL Xfer Command Indeterminate Rule:
2483  *	    Cache flush of IXL xfer command is required if an IXL jump command
2484  *	    which is flagged updateable has finalized the current IXL xfer
2485  *	    command.
2486  *    3. Updateable IXL Set Command Rule:
2487  *	    Cache flush of an IXL xfer command is required if any of the IXL
2488  *	    "Set" commands (IXL1394_OP_SET_*) associated with the IXL xfer
2489  *	    command (i.e. immediately preceeding it), is flagged updateable.
2490  *    4. Label Initiating Xfer Command Rule:
2491  *	    Cache flush of IXL xfer command is required if it is initiated by a
2492  *	    label IXL command.  (This is to allow both a flush of the cache and
2493  *	    an interrupt to be generated easily and in close proximity to each
2494  *	    other.  This can make possible simpler more successful reset of
2495  *	    descriptor statuses, especially under circumstances where the cycle
2496  *	    of hci commands is short and/or there are no callbacks distributed
2497  *	    through the span of xfers, etc...  This is especially important for
2498  *	    input where statuses must be reset before execution cycles back
2499  *	    again.
2500  *
2501  *    Application of above rules:
2502  *    Packet mode IXL xfer commands:
2503  *	    If any of the above flush rules apply, flush cache should be done
2504  *	    immediately preceeding the generation of the dma descriptor block
2505  *	    for the packet xfer.
2506  *    Non-packet mode IXL xfer commands (including IXL1394_OP_*BUF*,
2507  *    SEND_HDR_ONLY, and SEND_NO_PKT):
2508  *	    If Rules #1, #3 or #4 applies, a flush cache should be done
2509  *	    immediately before the first generated dma descriptor block of the
2510  *	    non-packet xfer.
2511  *	    If Rule #2 applies, a flush cache should be done immediately before
2512  *	    the last generated dma descriptor block of the non-packet xfer.
2513  *
2514  *    Note: The flush cache should be done at most once in each location that is
2515  *    required to be flushed no matter how many rules apply (i.e. only once
2516  *    before the first descriptor block and/or only once before the last
2517  *    descriptor block generated).  If more than one place requires a flush,
2518  *    then both flush operations must be performed.  This is determined by
2519  *    taking all rules that apply into account.
2520  *
2521  *    Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error
2522  *    will contain the error code.
2523  */
2524 static int
2525 hci1394_flush_hci_cache(hci1394_comp_ixl_vars_t *wvp)
2526 {
2527 	uint32_t	dma_bound;
2528 
2529 	TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_enter,
2530 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2531 
2532 	if (hci1394_alloc_dma_mem(wvp, sizeof (hci1394_desc_t), &dma_bound) ==
2533 	    NULL) {
2534 
2535 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
2536 
2537 		TNF_PROBE_1(hci1394_flush_hci_cache_fail,
2538 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2539 		    "IXL1394_EMEM_ALLOC_FAIL: for flush_hci_cache");
2540 		TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_exit,
2541 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2542 		return (DDI_FAILURE);
2543 	}
2544 
2545 	TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_exit,
2546 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2547 	return (DDI_SUCCESS);
2548 }
2549 
2550 /*
2551  * hci1394_alloc_storevalue_dma_mem()
2552  *    Allocate dma memory for a 1 hci component descriptor block
2553  *    which will be used as the dma memory location that ixl
2554  *    compiler generated storevalue descriptor commands will
2555  *    specify as location to store their data value.
2556  *
2557  *    Returns 32-bit bound address of allocated mem, or NULL.
2558  */
2559 static uint32_t
2560 hci1394_alloc_storevalue_dma_mem(hci1394_comp_ixl_vars_t *wvp)
2561 {
2562 	uint32_t	dma_bound;
2563 
2564 	TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_enter,
2565 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2566 
2567 	if (hci1394_alloc_dma_mem(wvp, sizeof (hci1394_desc_t),
2568 	    &dma_bound) == NULL) {
2569 
2570 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
2571 
2572 		TNF_PROBE_2(hci1394_bld_alloc_storevalue_dma_mem_alloc_fail,
2573 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2574 		    "IXL1394_EMEM_ALLOC_FAIL: for storevalue dma",
2575 		    tnf_opaque, ixl_commandp, wvp->ixl_cur_cmdp);
2576 		TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_exit,
2577 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2578 		return (NULL);
2579 	}
2580 
2581 	TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_exit,
2582 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2583 
2584 	/* return bound address of allocated memory */
2585 	return (dma_bound);
2586 }
2587 
2588 
2589 /*
2590  * hci1394_alloc_xfer_ctl()
2591  *    Allocate an xfer_ctl structure.
2592  */
2593 static hci1394_xfer_ctl_t *
2594 hci1394_alloc_xfer_ctl(hci1394_comp_ixl_vars_t *wvp, uint32_t dmacnt)
2595 {
2596 	hci1394_xfer_ctl_t *xcsp;
2597 
2598 	TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_enter,
2599 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2600 
2601 	/*
2602 	 * allocate an xfer_ctl struct which includes dmacnt of
2603 	 * xfer_ctl_dma structs
2604 	 */
2605 #ifdef _KERNEL
2606 	if ((xcsp = (hci1394_xfer_ctl_t *)kmem_zalloc(
2607 	    (sizeof (hci1394_xfer_ctl_t) + (dmacnt - 1) *
2608 	    sizeof (hci1394_xfer_ctl_dma_t)), KM_NOSLEEP)) == NULL) {
2609 
2610 		TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit,
2611 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2612 		return (NULL);
2613 	}
2614 #else
2615 	/*
2616 	 * This section makes it possible to easily run and test the compiler in
2617 	 * user mode.
2618 	 */
2619 	if ((xcsp = (hci1394_xfer_ctl_t *)calloc(1,
2620 	    sizeof (hci1394_xfer_ctl_t) + (dmacnt - 1) *
2621 	    sizeof (hci1394_xfer_ctl_dma_t))) == NULL) {
2622 
2623 		TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit,
2624 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2625 		return (NULL);
2626 	}
2627 #endif
2628 	/*
2629 	 * set dma structure count into allocated xfer_ctl struct for
2630 	 * later deletion.
2631 	 */
2632 	xcsp->cnt = dmacnt;
2633 
2634 	/* link it to previously allocated xfer_ctl structs or set as first */
2635 	if (wvp->xcs_firstp == NULL) {
2636 		wvp->xcs_firstp = wvp->xcs_currentp = xcsp;
2637 	} else {
2638 		wvp->xcs_currentp->ctl_nextp = xcsp;
2639 		wvp->xcs_currentp = xcsp;
2640 	}
2641 
2642 	TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit,
2643 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2644 
2645 	/* return allocated xfer_ctl structure */
2646 	return (xcsp);
2647 }
2648 
2649 /*
2650  * hci1394_alloc_dma_mem()
2651  *	Allocates and binds memory for openHCI DMA descriptors as needed.
2652  */
2653 static void *
2654 hci1394_alloc_dma_mem(hci1394_comp_ixl_vars_t *wvp, uint32_t size,
2655     uint32_t *dma_bound)
2656 {
2657 	hci1394_idma_desc_mem_t *dma_new;
2658 	hci1394_buf_parms_t parms;
2659 	hci1394_buf_info_t *memp;
2660 	void	*dma_mem_ret;
2661 	int	ret;
2662 
2663 	TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_enter,
2664 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2665 
2666 	/*
2667 	 * if no dma has been allocated or current request exceeds
2668 	 * remaining memory
2669 	 */
2670 	if ((wvp->dma_currentp == NULL) ||
2671 	    (size > (wvp->dma_currentp->mem.bi_cookie.dmac_size -
2672 		wvp->dma_currentp->used))) {
2673 #ifdef _KERNEL
2674 		/* kernel-mode memory allocation for driver */
2675 
2676 		/* allocate struct to track more dma descriptor memory */
2677 		if ((dma_new = (hci1394_idma_desc_mem_t *)
2678 		    kmem_zalloc(sizeof (hci1394_idma_desc_mem_t),
2679 		    KM_NOSLEEP)) == NULL) {
2680 
2681 			TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
2682 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
2683 			return (NULL);
2684 		}
2685 
2686 		/*
2687 		 * if more cookies available from the current mem, try to find
2688 		 * one of suitable size. Cookies that are too small will be
2689 		 * skipped and unused. Given that cookie size is always at least
2690 		 * 1 page long and HCI1394_DESC_MAX_Z is much smaller than that,
2691 		 * it's a small price to pay for code simplicity.
2692 		 */
2693 		if (wvp->dma_currentp != NULL) {
2694 			/* new struct is derived from current */
2695 			memp = &wvp->dma_currentp->mem;
2696 			dma_new->mem = *memp;
2697 			dma_new->offset = wvp->dma_currentp->offset +
2698 			    memp->bi_cookie.dmac_size;
2699 
2700 			for (; memp->bi_cookie_count > 1;
2701 			    memp->bi_cookie_count--) {
2702 				ddi_dma_nextcookie(memp->bi_dma_handle,
2703 				    &dma_new->mem.bi_cookie);
2704 
2705 				if (dma_new->mem.bi_cookie.dmac_size >= size) {
2706 					dma_new->mem_handle =
2707 					    wvp->dma_currentp->mem_handle;
2708 					wvp->dma_currentp->mem_handle = NULL;
2709 					dma_new->mem.bi_cookie_count--;
2710 					break;
2711 				}
2712 				dma_new->offset +=
2713 				    dma_new->mem.bi_cookie.dmac_size;
2714 			}
2715 		}
2716 
2717 		/* if no luck with current buffer, allocate a new one */
2718 		if (dma_new->mem_handle == NULL) {
2719 			parms.bp_length = HCI1394_IXL_PAGESIZE;
2720 			parms.bp_max_cookies = OHCI_MAX_COOKIE;
2721 			parms.bp_alignment = 16;
2722 			ret = hci1394_buf_alloc(&wvp->soft_statep->drvinfo,
2723 			    &parms, &dma_new->mem, &dma_new->mem_handle);
2724 			if (ret != DDI_SUCCESS) {
2725 				kmem_free(dma_new,
2726 				    sizeof (hci1394_idma_desc_mem_t));
2727 
2728 				TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
2729 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
2730 				return (NULL);
2731 			}
2732 
2733 			/* paranoia: this is not supposed to happen */
2734 			if (dma_new->mem.bi_cookie.dmac_size < size) {
2735 				hci1394_buf_free(&dma_new->mem_handle);
2736 				kmem_free(dma_new,
2737 				    sizeof (hci1394_idma_desc_mem_t));
2738 
2739 				TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
2740 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
2741 				return (NULL);
2742 			}
2743 			dma_new->offset = 0;
2744 		}
2745 #else
2746 		/* user-mode memory allocation for user mode compiler tests */
2747 		/* allocate another dma_desc_mem struct */
2748 		if ((dma_new = (hci1394_idma_desc_mem_t *)
2749 			calloc(1, sizeof (hci1394_idma_desc_mem_t))) == NULL) {
2750 			TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
2751 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
2752 			return (NULL);
2753 		}
2754 		dma_new->mem.bi_dma_handle = NULL;
2755 		dma_new->mem.bi_handle = NULL;
2756 		if ((dma_new->mem.bi_kaddr = (caddr_t)calloc(1,
2757 			    HCI1394_IXL_PAGESIZE)) == NULL) {
2758 			TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
2759 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
2760 			return (NULL);
2761 		}
2762 		dma_new->mem.bi_cookie.dmac_address =
2763 		    (unsigned long)dma_new->mem.bi_kaddr;
2764 		dma_new->mem.bi_real_length = HCI1394_IXL_PAGESIZE;
2765 		dma_new->mem.bi_cookie_count = 1;
2766 #endif
2767 
2768 		/* if this is not first dma_desc_mem, link last one to it */
2769 		if (wvp->dma_currentp != NULL) {
2770 			wvp->dma_currentp->dma_nextp = dma_new;
2771 			wvp->dma_currentp = dma_new;
2772 		} else {
2773 			/* else set it as first one */
2774 			wvp->dma_currentp = wvp->dma_firstp = dma_new;
2775 		}
2776 	}
2777 
2778 	/* now allocate requested memory from current block */
2779 	dma_mem_ret = wvp->dma_currentp->mem.bi_kaddr +
2780 	    wvp->dma_currentp->offset + wvp->dma_currentp->used;
2781 	*dma_bound = wvp->dma_currentp->mem.bi_cookie.dmac_address +
2782 	    wvp->dma_currentp->used;
2783 	wvp->dma_currentp->used += size;
2784 
2785 	TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
2786 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2787 	return (dma_mem_ret);
2788 }
2789 
2790 
2791 /*
2792  * hci1394_is_opcode_valid()
2793  *    given an ixl opcode, this routine returns B_TRUE if it is a
2794  *    recognized opcode and B_FALSE if it is not recognized.
2795  *    Note that the FULL 16 bits of the opcode are checked which includes
2796  *    various flags and not just the low order 8 bits of unique code.
2797  */
2798 static boolean_t
2799 hci1394_is_opcode_valid(uint16_t ixlopcode)
2800 {
2801 	TNF_PROBE_0_DEBUG(hci1394_is_opcode_bad_enter,
2802 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2803 
2804 	/* if it's not one we know about, then it's bad */
2805 	switch (ixlopcode) {
2806 	case IXL1394_OP_LABEL:
2807 	case IXL1394_OP_JUMP:
2808 	case IXL1394_OP_CALLBACK:
2809 	case IXL1394_OP_RECV_PKT:
2810 	case IXL1394_OP_RECV_PKT_ST:
2811 	case IXL1394_OP_RECV_BUF:
2812 	case IXL1394_OP_SEND_PKT:
2813 	case IXL1394_OP_SEND_PKT_ST:
2814 	case IXL1394_OP_SEND_PKT_WHDR_ST:
2815 	case IXL1394_OP_SEND_BUF:
2816 	case IXL1394_OP_SEND_HDR_ONLY:
2817 	case IXL1394_OP_SEND_NO_PKT:
2818 	case IXL1394_OP_STORE_TIMESTAMP:
2819 	case IXL1394_OP_SET_TAGSYNC:
2820 	case IXL1394_OP_SET_SKIPMODE:
2821 	case IXL1394_OP_SET_SYNCWAIT:
2822 	case IXL1394_OP_JUMP_U:
2823 	case IXL1394_OP_CALLBACK_U:
2824 	case IXL1394_OP_RECV_PKT_U:
2825 	case IXL1394_OP_RECV_PKT_ST_U:
2826 	case IXL1394_OP_RECV_BUF_U:
2827 	case IXL1394_OP_SEND_PKT_U:
2828 	case IXL1394_OP_SEND_PKT_ST_U:
2829 	case IXL1394_OP_SEND_PKT_WHDR_ST_U:
2830 	case IXL1394_OP_SEND_BUF_U:
2831 	case IXL1394_OP_SET_TAGSYNC_U:
2832 	case IXL1394_OP_SET_SKIPMODE_U:
2833 		TNF_PROBE_1_DEBUG(hci1394_is_opcode_valid_enter,
2834 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, msg,
2835 		    "ixl opcode is valid");
2836 		TNF_PROBE_0_DEBUG(hci1394_is_opcode_bad_enter,
2837 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2838 		return (B_TRUE);
2839 	default:
2840 		TNF_PROBE_2(hci1394_is_opcode_valid_enter,
2841 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, msg,
2842 		    "ixl opcode is NOT valid", tnf_opaque, ixl_opcode,
2843 		    ixlopcode);
2844 		TNF_PROBE_0_DEBUG(hci1394_is_opcode_valid_enter,
2845 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2846 		return (B_FALSE);
2847 	}
2848 }
2849