17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * hci1394_ixl_comp.c
297c478bd9Sstevel@tonic-gate  *    Isochronous IXL Compiler.
307c478bd9Sstevel@tonic-gate  *    The compiler converts the general hardware independent IXL command
317c478bd9Sstevel@tonic-gate  *    blocks into OpenHCI DMA descriptors.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
357c478bd9Sstevel@tonic-gate #include <sys/types.h>
367c478bd9Sstevel@tonic-gate #include <sys/conf.h>
377c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
387c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include <sys/tnf_probe.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include <sys/1394/h1394.h>
437c478bd9Sstevel@tonic-gate #include <sys/1394/ixl1394.h>
447c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /* compiler allocation size for DMA descriptors. 8000 is 500 descriptors */
477c478bd9Sstevel@tonic-gate #define	HCI1394_IXL_PAGESIZE	8000
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /* invalid opcode */
507c478bd9Sstevel@tonic-gate #define	IXL1394_OP_INVALID  (0 | IXL1394_OPTY_OTHER)
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /*
537c478bd9Sstevel@tonic-gate  * maximum number of interrupts permitted for a single context in which
547c478bd9Sstevel@tonic-gate  * the context does not advance to the next DMA descriptor.  Interrupts are
557c478bd9Sstevel@tonic-gate  * triggered by 1) hardware completing a DMA descriptor block which has the
567c478bd9Sstevel@tonic-gate  * interrupt (i) bits set, 2) a cycle_inconsistent interrupt, or 3) a cycle_lost
577c478bd9Sstevel@tonic-gate  * interrupt.  Once the max is reached, the HCI1394_IXL_INTR_NOADV error is
587c478bd9Sstevel@tonic-gate  * returned.
597c478bd9Sstevel@tonic-gate  */
607c478bd9Sstevel@tonic-gate int hci1394_ixl_max_noadv_intrs = 8;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate static void hci1394_compile_ixl_init(hci1394_comp_ixl_vars_t *wvp,
647c478bd9Sstevel@tonic-gate     hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
657c478bd9Sstevel@tonic-gate     ixl1394_command_t *ixlp);
667c478bd9Sstevel@tonic-gate static void hci1394_compile_ixl_endup(hci1394_comp_ixl_vars_t *wvp);
677c478bd9Sstevel@tonic-gate static void hci1394_parse_ixl(hci1394_comp_ixl_vars_t *wvp,
687c478bd9Sstevel@tonic-gate     ixl1394_command_t *ixlp);
697c478bd9Sstevel@tonic-gate static void hci1394_finalize_all_xfer_desc(hci1394_comp_ixl_vars_t *wvp);
707c478bd9Sstevel@tonic-gate static void hci1394_finalize_cur_xfer_desc(hci1394_comp_ixl_vars_t *wvp);
717c478bd9Sstevel@tonic-gate static void hci1394_bld_recv_pkt_desc(hci1394_comp_ixl_vars_t *wvp);
727c478bd9Sstevel@tonic-gate static void hci1394_bld_recv_buf_ppb_desc(hci1394_comp_ixl_vars_t *wvp);
737c478bd9Sstevel@tonic-gate static void hci1394_bld_recv_buf_fill_desc(hci1394_comp_ixl_vars_t *wvp);
747c478bd9Sstevel@tonic-gate static void hci1394_bld_xmit_pkt_desc(hci1394_comp_ixl_vars_t *wvp);
757c478bd9Sstevel@tonic-gate static void hci1394_bld_xmit_buf_desc(hci1394_comp_ixl_vars_t *wvp);
767c478bd9Sstevel@tonic-gate static void hci1394_bld_xmit_hdronly_nopkt_desc(hci1394_comp_ixl_vars_t *wvp);
777c478bd9Sstevel@tonic-gate static int hci1394_bld_dma_mem_desc_blk(hci1394_comp_ixl_vars_t *wvp,
787c478bd9Sstevel@tonic-gate     caddr_t *dma_descpp, uint32_t *dma_desc_bound);
797c478bd9Sstevel@tonic-gate static void hci1394_set_xmit_pkt_hdr(hci1394_comp_ixl_vars_t *wvp);
807c478bd9Sstevel@tonic-gate static void hci1394_set_xmit_skip_mode(hci1394_comp_ixl_vars_t *wvp);
817c478bd9Sstevel@tonic-gate static void hci1394_set_xmit_storevalue_desc(hci1394_comp_ixl_vars_t *wvp);
827c478bd9Sstevel@tonic-gate static int hci1394_set_next_xfer_buf(hci1394_comp_ixl_vars_t *wvp,
837c478bd9Sstevel@tonic-gate     uint32_t bufp, uint16_t size);
847c478bd9Sstevel@tonic-gate static int hci1394_flush_end_desc_check(hci1394_comp_ixl_vars_t *wvp,
857c478bd9Sstevel@tonic-gate     uint32_t count);
867c478bd9Sstevel@tonic-gate static int hci1394_flush_hci_cache(hci1394_comp_ixl_vars_t *wvp);
877c478bd9Sstevel@tonic-gate static uint32_t hci1394_alloc_storevalue_dma_mem(hci1394_comp_ixl_vars_t *wvp);
887c478bd9Sstevel@tonic-gate static hci1394_xfer_ctl_t *hci1394_alloc_xfer_ctl(hci1394_comp_ixl_vars_t *wvp,
897c478bd9Sstevel@tonic-gate     uint32_t dmacnt);
907c478bd9Sstevel@tonic-gate static void *hci1394_alloc_dma_mem(hci1394_comp_ixl_vars_t *wvp,
917c478bd9Sstevel@tonic-gate     uint32_t size, uint32_t *dma_bound);
927c478bd9Sstevel@tonic-gate static boolean_t hci1394_is_opcode_valid(uint16_t ixlopcode);
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate  * FULL LIST OF ACCEPTED IXL COMMAND OPCOCDES:
977c478bd9Sstevel@tonic-gate  * Receive Only:			Transmit Only:
987c478bd9Sstevel@tonic-gate  *    IXL1394_OP_RECV_PKT_ST		    IXL1394_OP_SEND_PKT_WHDR_ST
997c478bd9Sstevel@tonic-gate  *    IXL1394_OP_RECV_PKT		    IXL1394_OP_SEND_PKT_ST
1007c478bd9Sstevel@tonic-gate  *    IXL1394_OP_RECV_BUF		    IXL1394_OP_SEND_PKT
1017c478bd9Sstevel@tonic-gate  *    IXL1394_OP_SET_SYNCWAIT		    IXL1394_OP_SEND_BUF
1027c478bd9Sstevel@tonic-gate  *					    IXL1394_OP_SEND_HDR_ONLY
1037c478bd9Sstevel@tonic-gate  * Receive or Transmit:			    IXL1394_OP_SEND_NO_PKT
1047c478bd9Sstevel@tonic-gate  *    IXL1394_OP_CALLBACK		    IXL1394_OP_SET_TAGSYNC
1057c478bd9Sstevel@tonic-gate  *    IXL1394_OP_LABEL			    IXL1394_OP_SET_SKIPMODE
1067c478bd9Sstevel@tonic-gate  *    IXL1394_OP_JUMP			    IXL1394_OP_STORE_TIMESTAMP
1077c478bd9Sstevel@tonic-gate  */
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
1107c478bd9Sstevel@tonic-gate  * hci1394_compile_ixl()
1117c478bd9Sstevel@tonic-gate  *    Top level ixl compiler entry point.  Scans ixl and builds openHCI 1.0
1127c478bd9Sstevel@tonic-gate  *    descriptor blocks in dma memory.
1137c478bd9Sstevel@tonic-gate  */
1147c478bd9Sstevel@tonic-gate int
hci1394_compile_ixl(hci1394_state_t * soft_statep,hci1394_iso_ctxt_t * ctxtp,ixl1394_command_t * ixlp,int * resultp)1157c478bd9Sstevel@tonic-gate hci1394_compile_ixl(hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
1167c478bd9Sstevel@tonic-gate     ixl1394_command_t *ixlp, int *resultp)
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate 	hci1394_comp_ixl_vars_t wv;	/* working variables used throughout */
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	ASSERT(soft_statep != NULL);
1217c478bd9Sstevel@tonic-gate 	ASSERT(ctxtp != NULL);
1227c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_enter,
1237c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	/* Initialize compiler working variables */
1267c478bd9Sstevel@tonic-gate 	hci1394_compile_ixl_init(&wv, soft_statep, ctxtp, ixlp);
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	/*
1297c478bd9Sstevel@tonic-gate 	 * First pass:
1307c478bd9Sstevel@tonic-gate 	 *    Parse ixl commands, building desc blocks, until end of IXL
1317c478bd9Sstevel@tonic-gate 	 *    linked list.
1327c478bd9Sstevel@tonic-gate 	 */
1337c478bd9Sstevel@tonic-gate 	hci1394_parse_ixl(&wv, ixlp);
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	/*
1367c478bd9Sstevel@tonic-gate 	 * Second pass:
1377c478bd9Sstevel@tonic-gate 	 *    Resolve all generated descriptor block jump and skip addresses.
1387c478bd9Sstevel@tonic-gate 	 *    Set interrupt enable in descriptor blocks which have callback
1397c478bd9Sstevel@tonic-gate 	 *    operations in their execution scope. (Previously store_timesamp
1407c478bd9Sstevel@tonic-gate 	 *    operations were counted also.) Set interrupt enable in descriptor
1417c478bd9Sstevel@tonic-gate 	 *    blocks which were introduced by an ixl label command.
1427c478bd9Sstevel@tonic-gate 	 */
1437c478bd9Sstevel@tonic-gate 	if (wv.dma_bld_error == 0) {
1447c478bd9Sstevel@tonic-gate 		hci1394_finalize_all_xfer_desc(&wv);
1457c478bd9Sstevel@tonic-gate 	}
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	/* Endup: finalize and cleanup ixl compile, return result */
1487c478bd9Sstevel@tonic-gate 	hci1394_compile_ixl_endup(&wv);
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	*resultp = wv.dma_bld_error;
1517c478bd9Sstevel@tonic-gate 	if (*resultp != 0) {
1527c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_compile_ixl_exit,
1537c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1547c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
1557c478bd9Sstevel@tonic-gate 	} else {
1567c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_compile_ixl_exit,
1577c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1587c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
1597c478bd9Sstevel@tonic-gate 	}
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate /*
1637c478bd9Sstevel@tonic-gate  * hci1394_compile_ixl_init()
1647c478bd9Sstevel@tonic-gate  *    Initialize the isoch context structure associated with the IXL
1657c478bd9Sstevel@tonic-gate  *    program, and initialize the temporary working variables structure.
1667c478bd9Sstevel@tonic-gate  */
1677c478bd9Sstevel@tonic-gate static void
hci1394_compile_ixl_init(hci1394_comp_ixl_vars_t * wvp,hci1394_state_t * soft_statep,hci1394_iso_ctxt_t * ctxtp,ixl1394_command_t * ixlp)1687c478bd9Sstevel@tonic-gate hci1394_compile_ixl_init(hci1394_comp_ixl_vars_t *wvp,
1697c478bd9Sstevel@tonic-gate     hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
1707c478bd9Sstevel@tonic-gate     ixl1394_command_t *ixlp)
1717c478bd9Sstevel@tonic-gate {
1727c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_init_enter,
1737c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	/* initialize common recv/xmit compile values */
1767c478bd9Sstevel@tonic-gate 	wvp->soft_statep = soft_statep;
1777c478bd9Sstevel@tonic-gate 	wvp->ctxtp = ctxtp;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	/* init/clear ctxtp values */
180*ffc2b7d4SToomas Soome 	ctxtp->dma_mem_execp = 0;
1817c478bd9Sstevel@tonic-gate 	ctxtp->dma_firstp = NULL;
1827c478bd9Sstevel@tonic-gate 	ctxtp->dma_last_time = 0;
1837c478bd9Sstevel@tonic-gate 	ctxtp->xcs_firstp = NULL;
1847c478bd9Sstevel@tonic-gate 	ctxtp->ixl_exec_depth = 0;
1857c478bd9Sstevel@tonic-gate 	ctxtp->ixl_execp = NULL;
1867c478bd9Sstevel@tonic-gate 	ctxtp->ixl_firstp = ixlp;
1877c478bd9Sstevel@tonic-gate 	ctxtp->default_skipxferp = NULL;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	/*
1907c478bd9Sstevel@tonic-gate 	 * the context's max_noadv_intrs is set here instead of in isoch init
1917c478bd9Sstevel@tonic-gate 	 * because the default is patchable and would only be picked up this way
1927c478bd9Sstevel@tonic-gate 	 */
1937c478bd9Sstevel@tonic-gate 	ctxtp->max_noadv_intrs = hci1394_ixl_max_noadv_intrs;
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	/* init working variables */
1967c478bd9Sstevel@tonic-gate 	wvp->xcs_firstp = NULL;
1977c478bd9Sstevel@tonic-gate 	wvp->xcs_currentp = NULL;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	wvp->dma_firstp = NULL;
2007c478bd9Sstevel@tonic-gate 	wvp->dma_currentp = NULL;
2017c478bd9Sstevel@tonic-gate 	wvp->dma_bld_error = 0;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	wvp->ixl_io_mode = ctxtp->ctxt_flags;
2047c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_cmdp = NULL;
2057c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_xfer_stp = NULL;
2067c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_labelp = NULL;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	wvp->ixl_xfer_st_cnt = 0;	/* count of xfer start commands found */
2097c478bd9Sstevel@tonic-gate 	wvp->xfer_state = XFER_NONE;	/* none, pkt, buf, skip, hdronly */
2107c478bd9Sstevel@tonic-gate 	wvp->xfer_hci_flush = 0;	/* updateable - xfer, jump, set */
2117c478bd9Sstevel@tonic-gate 	wvp->xfer_pktlen = 0;
2127c478bd9Sstevel@tonic-gate 	wvp->xfer_bufcnt = 0;
2137c478bd9Sstevel@tonic-gate 	wvp->descriptors = 0;
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	/* START RECV ONLY SECTION */
2167c478bd9Sstevel@tonic-gate 	wvp->ixl_setsyncwait_cnt = 0;
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	/* START XMIT ONLY SECTION */
2197c478bd9Sstevel@tonic-gate 	wvp->ixl_settagsync_cmdp = NULL;
2207c478bd9Sstevel@tonic-gate 	wvp->ixl_setskipmode_cmdp = NULL;
2217c478bd9Sstevel@tonic-gate 	wvp->default_skipmode = ctxtp->default_skipmode; /* nxt,self,stop,jmp */
2227c478bd9Sstevel@tonic-gate 	wvp->default_skiplabelp = ctxtp->default_skiplabelp;
2237c478bd9Sstevel@tonic-gate 	wvp->default_skipxferp = NULL;
2247c478bd9Sstevel@tonic-gate 	wvp->skipmode = ctxtp->default_skipmode;
2257c478bd9Sstevel@tonic-gate 	wvp->skiplabelp = NULL;
2267c478bd9Sstevel@tonic-gate 	wvp->skipxferp = NULL;
2277c478bd9Sstevel@tonic-gate 	wvp->default_tag = ctxtp->default_tag;
2287c478bd9Sstevel@tonic-gate 	wvp->default_sync = ctxtp->default_sync;
2297c478bd9Sstevel@tonic-gate 	wvp->storevalue_bufp = hci1394_alloc_storevalue_dma_mem(wvp);
2307c478bd9Sstevel@tonic-gate 	wvp->storevalue_data = 0;
2317c478bd9Sstevel@tonic-gate 	wvp->xmit_pkthdr1 = 0;
2327c478bd9Sstevel@tonic-gate 	wvp->xmit_pkthdr2 = 0;
2337c478bd9Sstevel@tonic-gate 	/* END XMIT ONLY SECTION */
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_init_exit,
2367c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate  * hci1394_compile_ixl_endup()
2417c478bd9Sstevel@tonic-gate  *    This routine is called just before the main hci1394_compile_ixl() exits.
2427c478bd9Sstevel@tonic-gate  *    It checks for errors and performs the appropriate cleanup, or it rolls any
2437c478bd9Sstevel@tonic-gate  *    relevant info from the working variables struct into the context structure
2447c478bd9Sstevel@tonic-gate  */
2457c478bd9Sstevel@tonic-gate static void
hci1394_compile_ixl_endup(hci1394_comp_ixl_vars_t * wvp)2467c478bd9Sstevel@tonic-gate hci1394_compile_ixl_endup(hci1394_comp_ixl_vars_t *wvp)
2477c478bd9Sstevel@tonic-gate {
2487c478bd9Sstevel@tonic-gate 	ixl1394_command_t *ixl_exec_stp;
2497c478bd9Sstevel@tonic-gate 	hci1394_idma_desc_mem_t *dma_nextp;
2507c478bd9Sstevel@tonic-gate 	int err;
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_enter,
2537c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	/* error if no descriptor blocks found in ixl & created in dma memory */
2567c478bd9Sstevel@tonic-gate 	if ((wvp->dma_bld_error == 0) && (wvp->ixl_xfer_st_cnt == 0)) {
2577c478bd9Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_compile_ixl_endup_nodata_error,
2587c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2597c478bd9Sstevel@tonic-gate 		    "IXL1394_ENO_DATA_PKTS: prog has no data packets");
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
2627c478bd9Sstevel@tonic-gate 	}
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 	/* if no errors yet, find the first IXL command that's a transfer cmd */
2657c478bd9Sstevel@tonic-gate 	if (wvp->dma_bld_error == 0) {
2667c478bd9Sstevel@tonic-gate 		err = hci1394_ixl_find_next_exec_xfer(wvp->ctxtp->ixl_firstp,
2677c478bd9Sstevel@tonic-gate 		    NULL, &ixl_exec_stp);
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 		/* error if a label<->jump loop, or no xfer */
2707c478bd9Sstevel@tonic-gate 		if ((err == DDI_FAILURE) || (ixl_exec_stp == NULL)) {
2717c478bd9Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_compile_ixl_endup_error,
2727c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2737c478bd9Sstevel@tonic-gate 			    "IXL1394_ENO_DATA_PKTS: loop or no xfer detected");
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 			wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
2767c478bd9Sstevel@tonic-gate 		}
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	/* Sync all the DMA descriptor buffers */
2807c478bd9Sstevel@tonic-gate 	dma_nextp = wvp->ctxtp->dma_firstp;
2817c478bd9Sstevel@tonic-gate 	while (dma_nextp != NULL) {
2827c478bd9Sstevel@tonic-gate 		err = ddi_dma_sync(dma_nextp->mem.bi_dma_handle,
2837c478bd9Sstevel@tonic-gate 		    (off_t)dma_nextp->mem.bi_kaddr, dma_nextp->mem.bi_length,
2847c478bd9Sstevel@tonic-gate 		    DDI_DMA_SYNC_FORDEV);
2857c478bd9Sstevel@tonic-gate 		if (err != DDI_SUCCESS) {
2867c478bd9Sstevel@tonic-gate 			wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 			TNF_PROBE_1(hci1394_compile_ixl_endup_error,
2897c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
2907c478bd9Sstevel@tonic-gate 			    "IXL1394_INTERNAL_ERROR: dma_sync() failed");
2917c478bd9Sstevel@tonic-gate 			break;
2927c478bd9Sstevel@tonic-gate 		}
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 		/* advance to next dma memory descriptor */
2957c478bd9Sstevel@tonic-gate 		dma_nextp = dma_nextp->dma_nextp;
2967c478bd9Sstevel@tonic-gate 	}
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	/*
2997c478bd9Sstevel@tonic-gate 	 * If error, cleanup and return. delete all allocated xfer_ctl structs
3007c478bd9Sstevel@tonic-gate 	 * and all dma descriptor page memory and its dma memory blocks too.
3017c478bd9Sstevel@tonic-gate 	 */
3027c478bd9Sstevel@tonic-gate 	if (wvp->dma_bld_error != 0) {
3037c478bd9Sstevel@tonic-gate 		wvp->ctxtp->xcs_firstp = (void *)wvp->xcs_firstp;
3047c478bd9Sstevel@tonic-gate 		wvp->ctxtp->dma_firstp = wvp->dma_firstp;
3057c478bd9Sstevel@tonic-gate 		hci1394_ixl_cleanup(wvp->soft_statep, wvp->ctxtp);
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_exit,
3087c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
3097c478bd9Sstevel@tonic-gate 		return;
3107c478bd9Sstevel@tonic-gate 	}
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	/* can only get to here if the first ixl transfer command is found */
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 	/* set required processing vars into ctxtp struct */
3157c478bd9Sstevel@tonic-gate 	wvp->ctxtp->default_skipxferp = wvp->default_skipxferp;
3167c478bd9Sstevel@tonic-gate 	wvp->ctxtp->dma_mem_execp = 0;
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	/*
3197c478bd9Sstevel@tonic-gate 	 * the transfer command's compiler private xfer_ctl structure has the
3207c478bd9Sstevel@tonic-gate 	 * appropriate bound address
3217c478bd9Sstevel@tonic-gate 	 */
3227c478bd9Sstevel@tonic-gate 	wvp->ctxtp->dma_mem_execp = (uint32_t)((hci1394_xfer_ctl_t *)
3237c478bd9Sstevel@tonic-gate 	    ixl_exec_stp->compiler_privatep)->dma[0].dma_bound;
3247c478bd9Sstevel@tonic-gate 	wvp->ctxtp->xcs_firstp = (void *)wvp->xcs_firstp;
3257c478bd9Sstevel@tonic-gate 	wvp->ctxtp->dma_firstp = wvp->dma_firstp;
3267c478bd9Sstevel@tonic-gate 	wvp->ctxtp->dma_last_time = 0;
3277c478bd9Sstevel@tonic-gate 	wvp->ctxtp->ixl_exec_depth = 0;
3287c478bd9Sstevel@tonic-gate 	wvp->ctxtp->ixl_execp = NULL;
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	/* compile done */
3317c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_exit,
3327c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate /*
3367c478bd9Sstevel@tonic-gate  * hci1394_parse_ixl()
3377c478bd9Sstevel@tonic-gate  *    Scan IXL program and build ohci DMA descriptor blocks in dma memory.
3387c478bd9Sstevel@tonic-gate  *
3397c478bd9Sstevel@tonic-gate  *    Parse/process succeeding ixl commands until end of IXL linked list is
3407c478bd9Sstevel@tonic-gate  *    reached. Evaluate ixl syntax and build (xmit or recv) descriptor
3417c478bd9Sstevel@tonic-gate  *    blocks.  To aid execution time evaluation of current location, enable
3427c478bd9Sstevel@tonic-gate  *    status recording on each descriptor block built.
3437c478bd9Sstevel@tonic-gate  *    On xmit, set sync & tag bits. On recv, optionally set wait for sync bit.
3447c478bd9Sstevel@tonic-gate  */
3457c478bd9Sstevel@tonic-gate static void
hci1394_parse_ixl(hci1394_comp_ixl_vars_t * wvp,ixl1394_command_t * ixlp)3467c478bd9Sstevel@tonic-gate hci1394_parse_ixl(hci1394_comp_ixl_vars_t *wvp, ixl1394_command_t *ixlp)
3477c478bd9Sstevel@tonic-gate {
3487c478bd9Sstevel@tonic-gate 	ixl1394_command_t *ixlnextp = ixlp;	/* addr of next ixl cmd */
3497c478bd9Sstevel@tonic-gate 	ixl1394_command_t *ixlcurp = NULL;	/* addr of current ixl cmd */
3507c478bd9Sstevel@tonic-gate 	uint16_t ixlopcode = 0;			/* opcode of currnt ixl cmd */
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	uint32_t pktsize;
3537c478bd9Sstevel@tonic-gate 	uint32_t pktcnt;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_parse_ixl_enter, HCI1394_TNF_HAL_STACK_ISOCH,
3567c478bd9Sstevel@tonic-gate 	    "");
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	/* follow ixl links until reach end or find error */
3597c478bd9Sstevel@tonic-gate 	while ((ixlnextp != NULL) && (wvp->dma_bld_error == 0)) {
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 		/* set this command as the current ixl command */
3627c478bd9Sstevel@tonic-gate 		wvp->ixl_cur_cmdp = ixlcurp = ixlnextp;
3637c478bd9Sstevel@tonic-gate 		ixlnextp = ixlcurp->next_ixlp;
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate 		ixlopcode = ixlcurp->ixl_opcode;
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 		/* init compiler controlled values in current ixl command */
3687c478bd9Sstevel@tonic-gate 		ixlcurp->compiler_privatep = NULL;
3697c478bd9Sstevel@tonic-gate 		ixlcurp->compiler_resv = 0;
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 		/* error if xmit/recv mode not appropriate for current cmd */
3727c478bd9Sstevel@tonic-gate 		if ((((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) &&
373*ffc2b7d4SToomas Soome 		    ((ixlopcode & IXL1394_OPF_ONRECV) == 0)) ||
3747c478bd9Sstevel@tonic-gate 		    (((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) == 0) &&
375*ffc2b7d4SToomas Soome 		    ((ixlopcode & IXL1394_OPF_ONXMIT) == 0))) {
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 			/* check if command op failed because it was invalid */
3787c478bd9Sstevel@tonic-gate 			if (hci1394_is_opcode_valid(ixlopcode) != B_TRUE) {
3797c478bd9Sstevel@tonic-gate 				TNF_PROBE_3(hci1394_parse_ixl_bad_opcode_error,
3807c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
3817c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_BAD_IXL_OPCODE",
3827c478bd9Sstevel@tonic-gate 				    tnf_opaque, ixl_commandp, ixlcurp,
3837c478bd9Sstevel@tonic-gate 				    tnf_opaque, ixl_opcode, ixlopcode);
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EBAD_IXL_OPCODE;
3867c478bd9Sstevel@tonic-gate 			} else {
3877c478bd9Sstevel@tonic-gate 				TNF_PROBE_3(hci1394_parse_ixl_mode_error,
3887c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
3897c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EWRONG_XR_CMD_MODE: "
3907c478bd9Sstevel@tonic-gate 				    "invalid ixlop in mode", tnf_uint, io_mode,
3917c478bd9Sstevel@tonic-gate 				    wvp->ixl_io_mode, tnf_opaque, ixl_opcode,
3927c478bd9Sstevel@tonic-gate 				    ixlopcode);
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE;
3957c478bd9Sstevel@tonic-gate 			}
3967c478bd9Sstevel@tonic-gate 			continue;
3977c478bd9Sstevel@tonic-gate 		}
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 		/*
4007c478bd9Sstevel@tonic-gate 		 * if ends xfer flag set, finalize current xfer descriptor
4017c478bd9Sstevel@tonic-gate 		 * block build
4027c478bd9Sstevel@tonic-gate 		 */
4037c478bd9Sstevel@tonic-gate 		if ((ixlopcode & IXL1394_OPF_ENDSXFER) != 0) {
4047c478bd9Sstevel@tonic-gate 			/* finalize any descriptor block build in progress */
4057c478bd9Sstevel@tonic-gate 			hci1394_finalize_cur_xfer_desc(wvp);
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 			if (wvp->dma_bld_error != 0) {
4087c478bd9Sstevel@tonic-gate 				continue;
4097c478bd9Sstevel@tonic-gate 			}
4107c478bd9Sstevel@tonic-gate 		}
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 		/*
4137c478bd9Sstevel@tonic-gate 		 * now process based on specific opcode value
4147c478bd9Sstevel@tonic-gate 		 */
4157c478bd9Sstevel@tonic-gate 		switch (ixlopcode) {
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 		case IXL1394_OP_RECV_BUF:
4187c478bd9Sstevel@tonic-gate 		case IXL1394_OP_RECV_BUF_U: {
4197c478bd9Sstevel@tonic-gate 			ixl1394_xfer_buf_t *cur_xfer_buf_ixlp;
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate 			cur_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)ixlcurp;
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 			/*
4247c478bd9Sstevel@tonic-gate 			 * In packet-per-buffer mode:
4257c478bd9Sstevel@tonic-gate 			 *    This ixl command builds a collection of xfer
4267c478bd9Sstevel@tonic-gate 			 *    descriptor blocks (size/pkt_size of them) each to
4277c478bd9Sstevel@tonic-gate 			 *    recv a packet whose buffer size is pkt_size and
4287c478bd9Sstevel@tonic-gate 			 *    whose buffer ptr is (pktcur*pkt_size + bufp)
4297c478bd9Sstevel@tonic-gate 			 *
4307c478bd9Sstevel@tonic-gate 			 * In buffer fill mode:
4317c478bd9Sstevel@tonic-gate 			 *    This ixl command builds a single xfer descriptor
4327c478bd9Sstevel@tonic-gate 			 *    block to recv as many packets or parts of packets
4337c478bd9Sstevel@tonic-gate 			 *    as can fit into the buffer size specified
4347c478bd9Sstevel@tonic-gate 			 *    (pkt_size is not used).
4357c478bd9Sstevel@tonic-gate 			 */
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate 			/* set xfer_state for new descriptor block build */
4387c478bd9Sstevel@tonic-gate 			wvp->xfer_state = XFER_BUF;
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 			/* set this ixl command as current xferstart command */
4417c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_xfer_stp = ixlcurp;
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 			/*
4447c478bd9Sstevel@tonic-gate 			 * perform packet-per-buffer checks
4457c478bd9Sstevel@tonic-gate 			 * (no checks needed when in buffer fill mode)
4467c478bd9Sstevel@tonic-gate 			 */
4477c478bd9Sstevel@tonic-gate 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) == 0) {
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 				/* the packets must use the buffer exactly */
4507c478bd9Sstevel@tonic-gate 				pktsize = cur_xfer_buf_ixlp->pkt_size;
4517c478bd9Sstevel@tonic-gate 				pktcnt = 0;
4527c478bd9Sstevel@tonic-gate 				if (pktsize != 0) {
4537c478bd9Sstevel@tonic-gate 					pktcnt = cur_xfer_buf_ixlp->size /
4547c478bd9Sstevel@tonic-gate 					    pktsize;
4557c478bd9Sstevel@tonic-gate 				}
4567c478bd9Sstevel@tonic-gate 				if ((pktcnt == 0) || ((pktsize * pktcnt) !=
4577c478bd9Sstevel@tonic-gate 				    cur_xfer_buf_ixlp->size)) {
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 					TNF_PROBE_3(hci1394_parse_ixl_rat_error,
4607c478bd9Sstevel@tonic-gate 					    HCI1394_TNF_HAL_ERROR_ISOCH, "",
4617c478bd9Sstevel@tonic-gate 					    tnf_string, errmsg,
4627c478bd9Sstevel@tonic-gate 					    "IXL1394_EPKTSIZE_RATIO", tnf_int,
4637c478bd9Sstevel@tonic-gate 					    buf_size, cur_xfer_buf_ixlp->size,
4647c478bd9Sstevel@tonic-gate 					    tnf_int, pkt_size, pktsize);
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 					wvp->dma_bld_error =
4677c478bd9Sstevel@tonic-gate 					    IXL1394_EPKTSIZE_RATIO;
4687c478bd9Sstevel@tonic-gate 					continue;
4697c478bd9Sstevel@tonic-gate 				}
4707c478bd9Sstevel@tonic-gate 			}
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 			/*
4737c478bd9Sstevel@tonic-gate 			 * set buffer pointer & size into first xfer_bufp
4747c478bd9Sstevel@tonic-gate 			 * and xfer_size
4757c478bd9Sstevel@tonic-gate 			 */
4767c478bd9Sstevel@tonic-gate 			if (hci1394_set_next_xfer_buf(wvp,
4777c478bd9Sstevel@tonic-gate 			    cur_xfer_buf_ixlp->ixl_buf.ixldmac_addr,
4787c478bd9Sstevel@tonic-gate 			    cur_xfer_buf_ixlp->size) != DDI_SUCCESS) {
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
4817c478bd9Sstevel@tonic-gate 				continue;
4827c478bd9Sstevel@tonic-gate 			}
4837c478bd9Sstevel@tonic-gate 			break;
4847c478bd9Sstevel@tonic-gate 		}
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 		case IXL1394_OP_RECV_PKT_ST:
4877c478bd9Sstevel@tonic-gate 		case IXL1394_OP_RECV_PKT_ST_U: {
4887c478bd9Sstevel@tonic-gate 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate 			/* error if in buffer fill mode */
4937c478bd9Sstevel@tonic-gate 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) {
4947c478bd9Sstevel@tonic-gate 				TNF_PROBE_1(hci1394_parse_ixl_mode_error,
4957c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
4967c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EWRONG_XR_CMD_MODE: "
4977c478bd9Sstevel@tonic-gate 				    "RECV_PKT_ST used in BFFILL mode");
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE;
5007c478bd9Sstevel@tonic-gate 				continue;
5017c478bd9Sstevel@tonic-gate 			}
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 			/* set xfer_state for new descriptor block build */
5047c478bd9Sstevel@tonic-gate 			/* set this ixl command as current xferstart command */
5057c478bd9Sstevel@tonic-gate 			wvp->xfer_state = XFER_PKT;
5067c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_xfer_stp = ixlcurp;
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 			/*
5097c478bd9Sstevel@tonic-gate 			 * set buffer pointer & size into first xfer_bufp
5107c478bd9Sstevel@tonic-gate 			 * and xfer_size
5117c478bd9Sstevel@tonic-gate 			 */
5127c478bd9Sstevel@tonic-gate 			if (hci1394_set_next_xfer_buf(wvp,
5137c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
5147c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
5177c478bd9Sstevel@tonic-gate 				continue;
5187c478bd9Sstevel@tonic-gate 			}
5197c478bd9Sstevel@tonic-gate 			break;
5207c478bd9Sstevel@tonic-gate 		}
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 		case IXL1394_OP_RECV_PKT:
5237c478bd9Sstevel@tonic-gate 		case IXL1394_OP_RECV_PKT_U: {
5247c478bd9Sstevel@tonic-gate 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 			/* error if in buffer fill mode */
5297c478bd9Sstevel@tonic-gate 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) {
5307c478bd9Sstevel@tonic-gate 				TNF_PROBE_1(hci1394_parse_ixl_mode_error,
5317c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
5327c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EWRONG_XR_CMD_MODE: "
5337c478bd9Sstevel@tonic-gate 				    "RECV_PKT_ST used in BFFILL mode");
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE;
5367c478bd9Sstevel@tonic-gate 				continue;
5377c478bd9Sstevel@tonic-gate 			}
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate 			/* error if xfer_state not xfer pkt */
5407c478bd9Sstevel@tonic-gate 			if (wvp->xfer_state != XFER_PKT) {
5417c478bd9Sstevel@tonic-gate 				TNF_PROBE_1(hci1394_parse_ixl_misplacercv_error,
5427c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
5437c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EMISPLACED_RECV: "
5447c478bd9Sstevel@tonic-gate 				    "RECV_PKT without RECV_PKT_ST");
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EMISPLACED_RECV;
5477c478bd9Sstevel@tonic-gate 				continue;
5487c478bd9Sstevel@tonic-gate 			}
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 			/*
5517c478bd9Sstevel@tonic-gate 			 * save xfer start cmd ixl ptr in compiler_privatep
5527c478bd9Sstevel@tonic-gate 			 * field of this cmd
5537c478bd9Sstevel@tonic-gate 			 */
5547c478bd9Sstevel@tonic-gate 			ixlcurp->compiler_privatep = (void *)
5557c478bd9Sstevel@tonic-gate 			    wvp->ixl_cur_xfer_stp;
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 			/*
5587c478bd9Sstevel@tonic-gate 			 * save pkt index [1-n] in compiler_resv field of
5597c478bd9Sstevel@tonic-gate 			 * this cmd
5607c478bd9Sstevel@tonic-gate 			 */
5617c478bd9Sstevel@tonic-gate 			ixlcurp->compiler_resv = wvp->xfer_bufcnt;
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 			/*
5647c478bd9Sstevel@tonic-gate 			 * set buffer pointer & size into next xfer_bufp
5657c478bd9Sstevel@tonic-gate 			 * and xfer_size
5667c478bd9Sstevel@tonic-gate 			 */
5677c478bd9Sstevel@tonic-gate 			if (hci1394_set_next_xfer_buf(wvp,
5687c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
5697c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
5727c478bd9Sstevel@tonic-gate 				continue;
5737c478bd9Sstevel@tonic-gate 			}
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 			/*
5767c478bd9Sstevel@tonic-gate 			 * set updateable xfer cache flush eval flag if
5777c478bd9Sstevel@tonic-gate 			 * updateable opcode
5787c478bd9Sstevel@tonic-gate 			 */
5797c478bd9Sstevel@tonic-gate 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
5807c478bd9Sstevel@tonic-gate 				wvp->xfer_hci_flush |= UPDATEABLE_XFER;
5817c478bd9Sstevel@tonic-gate 			}
5827c478bd9Sstevel@tonic-gate 			break;
5837c478bd9Sstevel@tonic-gate 		}
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_BUF:
5867c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_BUF_U: {
5877c478bd9Sstevel@tonic-gate 			ixl1394_xfer_buf_t *cur_xfer_buf_ixlp;
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate 			cur_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)ixlcurp;
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 			/*
5927c478bd9Sstevel@tonic-gate 			 * These send_buf commands build a collection of xmit
5937c478bd9Sstevel@tonic-gate 			 * descriptor blocks (size/pkt_size of them) each to
5947c478bd9Sstevel@tonic-gate 			 * xfer a packet whose buffer size is pkt_size and whose
5957c478bd9Sstevel@tonic-gate 			 * buffer pt is (pktcur*pkt_size + bufp). (ptr and size
5967c478bd9Sstevel@tonic-gate 			 * are adjusted if they have header form of ixl cmd)
5977c478bd9Sstevel@tonic-gate 			 */
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 			/* set xfer_state for new descriptor block build */
6007c478bd9Sstevel@tonic-gate 			wvp->xfer_state = XFER_BUF;
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 			/* set this ixl command as current xferstart command */
6037c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_xfer_stp = ixlcurp;
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate 			/* the packets must use the buffer exactly,else error */
6067c478bd9Sstevel@tonic-gate 			pktsize = cur_xfer_buf_ixlp->pkt_size;
6077c478bd9Sstevel@tonic-gate 			pktcnt = 0;
6087c478bd9Sstevel@tonic-gate 			if (pktsize != 0) {
6097c478bd9Sstevel@tonic-gate 				pktcnt = cur_xfer_buf_ixlp->size / pktsize;
6107c478bd9Sstevel@tonic-gate 			}
6117c478bd9Sstevel@tonic-gate 			if ((pktcnt == 0) || ((pktsize * pktcnt) !=
6127c478bd9Sstevel@tonic-gate 			    cur_xfer_buf_ixlp->size)) {
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate 				TNF_PROBE_3(hci1394_parse_ixl_rat_error,
6157c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
6167c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EPKTSIZE_RATIO", tnf_int,
6177c478bd9Sstevel@tonic-gate 				    buf_size, cur_xfer_buf_ixlp->size, tnf_int,
6187c478bd9Sstevel@tonic-gate 				    pkt_size, pktsize);
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EPKTSIZE_RATIO;
6217c478bd9Sstevel@tonic-gate 				continue;
6227c478bd9Sstevel@tonic-gate 			}
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 			/* set buf ptr & size into 1st xfer_bufp & xfer_size */
6257c478bd9Sstevel@tonic-gate 			if (hci1394_set_next_xfer_buf(wvp,
6267c478bd9Sstevel@tonic-gate 			    cur_xfer_buf_ixlp->ixl_buf.ixldmac_addr,
6277c478bd9Sstevel@tonic-gate 			    cur_xfer_buf_ixlp->size) != DDI_SUCCESS) {
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
6307c478bd9Sstevel@tonic-gate 				continue;
6317c478bd9Sstevel@tonic-gate 			}
6327c478bd9Sstevel@tonic-gate 			break;
6337c478bd9Sstevel@tonic-gate 		}
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_PKT_ST:
6367c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_PKT_ST_U: {
6377c478bd9Sstevel@tonic-gate 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 			/* set xfer_state for new descriptor block build */
6427c478bd9Sstevel@tonic-gate 			/* set this ixl command as current xferstart command */
6437c478bd9Sstevel@tonic-gate 			wvp->xfer_state = XFER_PKT;
6447c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_xfer_stp = ixlcurp;
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 			/*
6477c478bd9Sstevel@tonic-gate 			 * set buffer pointer & size into first xfer_bufp and
6487c478bd9Sstevel@tonic-gate 			 * xfer_size
6497c478bd9Sstevel@tonic-gate 			 */
6507c478bd9Sstevel@tonic-gate 			if (hci1394_set_next_xfer_buf(wvp,
6517c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
6527c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
6557c478bd9Sstevel@tonic-gate 				continue;
6567c478bd9Sstevel@tonic-gate 			}
6577c478bd9Sstevel@tonic-gate 			break;
6587c478bd9Sstevel@tonic-gate 		}
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_PKT_WHDR_ST:
6617c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_PKT_WHDR_ST_U: {
6627c478bd9Sstevel@tonic-gate 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate 			/* set xfer_state for new descriptor block build */
6677c478bd9Sstevel@tonic-gate 			/* set this ixl command as current xferstart command */
6687c478bd9Sstevel@tonic-gate 			wvp->xfer_state = XFER_PKT;
6697c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_xfer_stp = ixlcurp;
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 			/*
6727c478bd9Sstevel@tonic-gate 			 * buffer size must be at least 4 (must include header),
6737c478bd9Sstevel@tonic-gate 			 * else error
6747c478bd9Sstevel@tonic-gate 			 */
6757c478bd9Sstevel@tonic-gate 			if (cur_xfer_pkt_ixlp->size < 4) {
6767c478bd9Sstevel@tonic-gate 				TNF_PROBE_2(hci1394_parse_ixl_hdr_missing_error,
6777c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
6787c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EPKT_HDR_MISSING", tnf_int,
6797c478bd9Sstevel@tonic-gate 				    pkt_size, cur_xfer_pkt_ixlp->size);
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EPKT_HDR_MISSING;
6827c478bd9Sstevel@tonic-gate 				continue;
6837c478bd9Sstevel@tonic-gate 			}
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 			/*
6867c478bd9Sstevel@tonic-gate 			 * set buffer and size(excluding header) into first
6877c478bd9Sstevel@tonic-gate 			 * xfer_bufp and xfer_size
6887c478bd9Sstevel@tonic-gate 			 */
6897c478bd9Sstevel@tonic-gate 			if (hci1394_set_next_xfer_buf(wvp,
6907c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr + 4,
6917c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->size - 4) != DDI_SUCCESS) {
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
6947c478bd9Sstevel@tonic-gate 				continue;
6957c478bd9Sstevel@tonic-gate 			}
6967c478bd9Sstevel@tonic-gate 			break;
6977c478bd9Sstevel@tonic-gate 		}
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_PKT:
7007c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_PKT_U: {
7017c478bd9Sstevel@tonic-gate 			ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp;
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 			cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp;
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 			/* error if xfer_state not xfer pkt */
7067c478bd9Sstevel@tonic-gate 			if (wvp->xfer_state != XFER_PKT) {
7077c478bd9Sstevel@tonic-gate 				TNF_PROBE_1(hci1394_parse_ixl_misplacesnd_error,
7087c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
7097c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EMISPLACED_SEND: SEND_PKT "
7107c478bd9Sstevel@tonic-gate 				    "without SEND_PKT_ST");
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EMISPLACED_SEND;
7137c478bd9Sstevel@tonic-gate 				continue;
7147c478bd9Sstevel@tonic-gate 			}
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 			/*
7177c478bd9Sstevel@tonic-gate 			 * save xfer start cmd ixl ptr in compiler_privatep
7187c478bd9Sstevel@tonic-gate 			 * field of this cmd
7197c478bd9Sstevel@tonic-gate 			 */
7207c478bd9Sstevel@tonic-gate 			ixlcurp->compiler_privatep = (void *)
7217c478bd9Sstevel@tonic-gate 			    wvp->ixl_cur_xfer_stp;
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 			/*
7247c478bd9Sstevel@tonic-gate 			 * save pkt index [1-n] in compiler_resv field of this
7257c478bd9Sstevel@tonic-gate 			 * cmd
7267c478bd9Sstevel@tonic-gate 			 */
7277c478bd9Sstevel@tonic-gate 			ixlcurp->compiler_resv = wvp->xfer_bufcnt;
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 			/*
7307c478bd9Sstevel@tonic-gate 			 * set buffer pointer & size into next xfer_bufp
7317c478bd9Sstevel@tonic-gate 			 * and xfer_size
7327c478bd9Sstevel@tonic-gate 			 */
7337c478bd9Sstevel@tonic-gate 			if (hci1394_set_next_xfer_buf(wvp,
7347c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr,
7357c478bd9Sstevel@tonic-gate 			    cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) {
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
7387c478bd9Sstevel@tonic-gate 				continue;
7397c478bd9Sstevel@tonic-gate 			}
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 			/*
7427c478bd9Sstevel@tonic-gate 			 * set updateable xfer cache flush eval flag if
7437c478bd9Sstevel@tonic-gate 			 * updateable opcode
7447c478bd9Sstevel@tonic-gate 			 */
7457c478bd9Sstevel@tonic-gate 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
7467c478bd9Sstevel@tonic-gate 				wvp->xfer_hci_flush |= UPDATEABLE_XFER;
7477c478bd9Sstevel@tonic-gate 			}
7487c478bd9Sstevel@tonic-gate 			break;
7497c478bd9Sstevel@tonic-gate 		}
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_HDR_ONLY:
7527c478bd9Sstevel@tonic-gate 			/* set xfer_state for new descriptor block build */
7537c478bd9Sstevel@tonic-gate 			wvp->xfer_state = XMIT_HDRONLY;
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 			/* set this ixl command as current xferstart command */
7567c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_xfer_stp = ixlcurp;
7577c478bd9Sstevel@tonic-gate 			break;
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SEND_NO_PKT:
7607c478bd9Sstevel@tonic-gate 			/* set xfer_state for new descriptor block build */
7617c478bd9Sstevel@tonic-gate 			wvp->xfer_state = XMIT_NOPKT;
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 			/* set this ixl command as current xferstart command */
7647c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_xfer_stp = ixlcurp;
7657c478bd9Sstevel@tonic-gate 			break;
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate 		case IXL1394_OP_JUMP:
7687c478bd9Sstevel@tonic-gate 		case IXL1394_OP_JUMP_U: {
7697c478bd9Sstevel@tonic-gate 			ixl1394_jump_t *cur_jump_ixlp;
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 			cur_jump_ixlp = (ixl1394_jump_t *)ixlcurp;
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate 			/*
7747c478bd9Sstevel@tonic-gate 			 * verify label indicated by IXL1394_OP_JUMP is
7757c478bd9Sstevel@tonic-gate 			 * actually an IXL1394_OP_LABEL or NULL
7767c478bd9Sstevel@tonic-gate 			 */
7777c478bd9Sstevel@tonic-gate 			if ((cur_jump_ixlp->label != NULL) &&
7787c478bd9Sstevel@tonic-gate 			    (cur_jump_ixlp->label->ixl_opcode !=
7797c478bd9Sstevel@tonic-gate 			    IXL1394_OP_LABEL)) {
7807c478bd9Sstevel@tonic-gate 				TNF_PROBE_3(hci1394_parse_ixl_jumplabel_error,
7817c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
7827c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EJUMP_NOT_TO_LABEL",
7837c478bd9Sstevel@tonic-gate 				    tnf_opaque, jumpixl_commandp, ixlcurp,
7847c478bd9Sstevel@tonic-gate 				    tnf_opaque, jumpto_ixl,
7857c478bd9Sstevel@tonic-gate 				    cur_jump_ixlp->label);
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EJUMP_NOT_TO_LABEL;
7887c478bd9Sstevel@tonic-gate 				continue;
7897c478bd9Sstevel@tonic-gate 			}
7907c478bd9Sstevel@tonic-gate 			break;
7917c478bd9Sstevel@tonic-gate 		}
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 		case IXL1394_OP_LABEL:
7947c478bd9Sstevel@tonic-gate 			/*
7957c478bd9Sstevel@tonic-gate 			 * save current ixl label command for xfer cmd
7967c478bd9Sstevel@tonic-gate 			 * finalize processing
7977c478bd9Sstevel@tonic-gate 			 */
7987c478bd9Sstevel@tonic-gate 			wvp->ixl_cur_labelp = ixlcurp;
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 			/* set initiating label flag to cause cache flush */
8017c478bd9Sstevel@tonic-gate 			wvp->xfer_hci_flush |= INITIATING_LBL;
8027c478bd9Sstevel@tonic-gate 			break;
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate 		case IXL1394_OP_CALLBACK:
8057c478bd9Sstevel@tonic-gate 		case IXL1394_OP_CALLBACK_U:
8067c478bd9Sstevel@tonic-gate 		case IXL1394_OP_STORE_TIMESTAMP:
8077c478bd9Sstevel@tonic-gate 			/*
8087c478bd9Sstevel@tonic-gate 			 * these commands are accepted during compile,
8097c478bd9Sstevel@tonic-gate 			 * processed during execution (interrupt handling)
8107c478bd9Sstevel@tonic-gate 			 * No further processing is needed here.
8117c478bd9Sstevel@tonic-gate 			 */
8127c478bd9Sstevel@tonic-gate 			break;
8137c478bd9Sstevel@tonic-gate 
8147c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SET_SKIPMODE:
8157c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SET_SKIPMODE_U:
8167c478bd9Sstevel@tonic-gate 			/*
8177c478bd9Sstevel@tonic-gate 			 * Error if already have a set skipmode cmd for
8187c478bd9Sstevel@tonic-gate 			 * this xfer
8197c478bd9Sstevel@tonic-gate 			 */
8207c478bd9Sstevel@tonic-gate 			if (wvp->ixl_setskipmode_cmdp != NULL) {
8217c478bd9Sstevel@tonic-gate 				TNF_PROBE_2(hci1394_parse_ixl_dup_set_error,
8227c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
8237c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EDUPLICATE_SET_CMD:"
8247c478bd9Sstevel@tonic-gate 				    " duplicate set skipmode", tnf_opaque,
8257c478bd9Sstevel@tonic-gate 				    ixl_commandp, ixlcurp);
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EDUPLICATE_SET_CMD;
8287c478bd9Sstevel@tonic-gate 				continue;
8297c478bd9Sstevel@tonic-gate 			}
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 			/* save skip mode ixl command and verify skipmode */
8327c478bd9Sstevel@tonic-gate 			wvp->ixl_setskipmode_cmdp = (ixl1394_set_skipmode_t *)
8337c478bd9Sstevel@tonic-gate 			    ixlcurp;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 			if ((wvp->ixl_setskipmode_cmdp->skipmode !=
836*ffc2b7d4SToomas Soome 			    IXL1394_SKIP_TO_NEXT) &&
8377c478bd9Sstevel@tonic-gate 			    (wvp->ixl_setskipmode_cmdp->skipmode !=
838*ffc2b7d4SToomas Soome 			    IXL1394_SKIP_TO_SELF) &&
8397c478bd9Sstevel@tonic-gate 			    (wvp->ixl_setskipmode_cmdp->skipmode !=
840*ffc2b7d4SToomas Soome 			    IXL1394_SKIP_TO_STOP) &&
8417c478bd9Sstevel@tonic-gate 			    (wvp->ixl_setskipmode_cmdp->skipmode !=
842*ffc2b7d4SToomas Soome 			    IXL1394_SKIP_TO_LABEL)) {
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 				TNF_PROBE_3(hci1394_parse_ixl_dup_set_error,
8457c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
8467c478bd9Sstevel@tonic-gate 				    errmsg, "IXL EBAD_SKIPMODE", tnf_opaque,
8477c478bd9Sstevel@tonic-gate 				    ixl_commandp, ixlcurp, tnf_int, skip,
8487c478bd9Sstevel@tonic-gate 				    wvp->ixl_setskipmode_cmdp->skipmode);
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EBAD_SKIPMODE;
8517c478bd9Sstevel@tonic-gate 				continue;
8527c478bd9Sstevel@tonic-gate 			}
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 			/*
8557c478bd9Sstevel@tonic-gate 			 * if mode is IXL1394_SKIP_TO_LABEL, verify label
8567c478bd9Sstevel@tonic-gate 			 * references an IXL1394_OP_LABEL
8577c478bd9Sstevel@tonic-gate 			 */
8587c478bd9Sstevel@tonic-gate 			if ((wvp->ixl_setskipmode_cmdp->skipmode ==
859*ffc2b7d4SToomas Soome 			    IXL1394_SKIP_TO_LABEL) &&
8607c478bd9Sstevel@tonic-gate 			    ((wvp->ixl_setskipmode_cmdp->label == NULL) ||
8617c478bd9Sstevel@tonic-gate 			    (wvp->ixl_setskipmode_cmdp->label->ixl_opcode !=
862*ffc2b7d4SToomas Soome 			    IXL1394_OP_LABEL))) {
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 				TNF_PROBE_3(hci1394_parse_ixl_jump_error,
8657c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
8667c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EJUMP_NOT_TO_LABEL",
8677c478bd9Sstevel@tonic-gate 				    tnf_opaque, jumpixl_commandp, ixlcurp,
8687c478bd9Sstevel@tonic-gate 				    tnf_opaque, jumpto_ixl,
8697c478bd9Sstevel@tonic-gate 				    wvp->ixl_setskipmode_cmdp->label);
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EJUMP_NOT_TO_LABEL;
8727c478bd9Sstevel@tonic-gate 				continue;
8737c478bd9Sstevel@tonic-gate 			}
8747c478bd9Sstevel@tonic-gate 			/*
8757c478bd9Sstevel@tonic-gate 			 * set updateable set cmd cache flush eval flag if
8767c478bd9Sstevel@tonic-gate 			 * updateable opcode
8777c478bd9Sstevel@tonic-gate 			 */
8787c478bd9Sstevel@tonic-gate 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
8797c478bd9Sstevel@tonic-gate 				wvp->xfer_hci_flush |= UPDATEABLE_SET;
8807c478bd9Sstevel@tonic-gate 			}
8817c478bd9Sstevel@tonic-gate 			break;
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SET_TAGSYNC:
8847c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SET_TAGSYNC_U:
8857c478bd9Sstevel@tonic-gate 			/*
8867c478bd9Sstevel@tonic-gate 			 * is an error if already have a set tag and sync cmd
8877c478bd9Sstevel@tonic-gate 			 * for this xfer
8887c478bd9Sstevel@tonic-gate 			 */
8897c478bd9Sstevel@tonic-gate 			if (wvp->ixl_settagsync_cmdp != NULL) {
8907c478bd9Sstevel@tonic-gate 				TNF_PROBE_2(hci1394_parse_ixl_dup_set_error,
8917c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
8927c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_EDUPLICATE_SET_CMD:"
8937c478bd9Sstevel@tonic-gate 				    " duplicate set tagsync", tnf_opaque,
8947c478bd9Sstevel@tonic-gate 				    ixl_commandp, ixlcurp);
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EDUPLICATE_SET_CMD;
8977c478bd9Sstevel@tonic-gate 				continue;
8987c478bd9Sstevel@tonic-gate 			}
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 			/* save ixl command containing tag and sync values */
9017c478bd9Sstevel@tonic-gate 			wvp->ixl_settagsync_cmdp =
9027c478bd9Sstevel@tonic-gate 			    (ixl1394_set_tagsync_t *)ixlcurp;
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate 			/*
9057c478bd9Sstevel@tonic-gate 			 * set updateable set cmd cache flush eval flag if
9067c478bd9Sstevel@tonic-gate 			 * updateable opcode
9077c478bd9Sstevel@tonic-gate 			 */
9087c478bd9Sstevel@tonic-gate 			if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) {
9097c478bd9Sstevel@tonic-gate 				wvp->xfer_hci_flush |= UPDATEABLE_SET;
9107c478bd9Sstevel@tonic-gate 			}
9117c478bd9Sstevel@tonic-gate 			break;
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 		case IXL1394_OP_SET_SYNCWAIT:
9147c478bd9Sstevel@tonic-gate 			/*
9157c478bd9Sstevel@tonic-gate 			 * count ixl wait-for-sync commands since last
9167c478bd9Sstevel@tonic-gate 			 * finalize ignore multiple occurrences for same xfer
9177c478bd9Sstevel@tonic-gate 			 * command
9187c478bd9Sstevel@tonic-gate 			 */
9197c478bd9Sstevel@tonic-gate 			wvp->ixl_setsyncwait_cnt++;
9207c478bd9Sstevel@tonic-gate 			break;
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 		default:
9237c478bd9Sstevel@tonic-gate 			/* error - unknown/unimplemented ixl command */
9247c478bd9Sstevel@tonic-gate 			TNF_PROBE_3(hci1394_parse_ixl_bad_opcode_error,
9257c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
9267c478bd9Sstevel@tonic-gate 			    "IXL1394_BAD_IXL_OPCODE", tnf_opaque, ixl_commandp,
9277c478bd9Sstevel@tonic-gate 			    ixlcurp, tnf_opaque, ixl_opcode, ixlopcode);
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 			wvp->dma_bld_error = IXL1394_EBAD_IXL_OPCODE;
9307c478bd9Sstevel@tonic-gate 			continue;
9317c478bd9Sstevel@tonic-gate 		}
9327c478bd9Sstevel@tonic-gate 	} /* while */
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate 	/* finalize any last descriptor block build */
9357c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_cmdp = NULL;
9367c478bd9Sstevel@tonic-gate 	if (wvp->dma_bld_error == 0) {
9377c478bd9Sstevel@tonic-gate 		hci1394_finalize_cur_xfer_desc(wvp);
9387c478bd9Sstevel@tonic-gate 	}
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_parse_ixl_exit,
9417c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
9427c478bd9Sstevel@tonic-gate }
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate /*
9457c478bd9Sstevel@tonic-gate  * hci1394_finalize_all_xfer_desc()
9467c478bd9Sstevel@tonic-gate  *    Pass 2: Scan IXL resolving all dma descriptor jump and skip addresses.
9477c478bd9Sstevel@tonic-gate  *
9487c478bd9Sstevel@tonic-gate  *    Set interrupt enable on first descriptor block associated with current
9497c478bd9Sstevel@tonic-gate  *    xfer IXL command if current IXL xfer was introduced by an IXL label cmnd.
9507c478bd9Sstevel@tonic-gate  *
9517c478bd9Sstevel@tonic-gate  *    Set interrupt enable on last descriptor block associated with current xfer
9527c478bd9Sstevel@tonic-gate  *    IXL command if any callback ixl commands are found on the execution path
9537c478bd9Sstevel@tonic-gate  *    between the current and the next xfer ixl command.  (Previously, this
9547c478bd9Sstevel@tonic-gate  *    applied to store timestamp ixl commands, as well.)
9557c478bd9Sstevel@tonic-gate  */
9567c478bd9Sstevel@tonic-gate static void
hci1394_finalize_all_xfer_desc(hci1394_comp_ixl_vars_t * wvp)9577c478bd9Sstevel@tonic-gate hci1394_finalize_all_xfer_desc(hci1394_comp_ixl_vars_t *wvp)
9587c478bd9Sstevel@tonic-gate {
9597c478bd9Sstevel@tonic-gate 	ixl1394_command_t *ixlcurp;		/* current ixl command */
9607c478bd9Sstevel@tonic-gate 	ixl1394_command_t *ixlnextp;		/* next ixl command */
9617c478bd9Sstevel@tonic-gate 	ixl1394_command_t *ixlexecnext;
9627c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xferctl_curp;
9637c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xferctl_nxtp;
9647c478bd9Sstevel@tonic-gate 	hci1394_desc_t		*hcidescp;
9657c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	acc_hdl;
9667c478bd9Sstevel@tonic-gate 	uint32_t	temp;
9677c478bd9Sstevel@tonic-gate 	uint32_t	dma_execnext_addr;
9687c478bd9Sstevel@tonic-gate 	uint32_t	dma_skiplabel_addr;
9697c478bd9Sstevel@tonic-gate 	uint32_t	dma_skip_addr;
9707c478bd9Sstevel@tonic-gate 	uint32_t	callback_cnt;
9717c478bd9Sstevel@tonic-gate 	uint16_t	repcnt;
9727c478bd9Sstevel@tonic-gate 	uint16_t	ixlopcode;
9737c478bd9Sstevel@tonic-gate 	int		ii;
9747c478bd9Sstevel@tonic-gate 	int		err;
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_enter,
9777c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate 	/*
9807c478bd9Sstevel@tonic-gate 	 * If xmit mode and if default skipmode is skip to label -
9817c478bd9Sstevel@tonic-gate 	 * follow exec path starting at default skipmode label until
9827c478bd9Sstevel@tonic-gate 	 * find the first ixl xfer command which is to be executed.
9837c478bd9Sstevel@tonic-gate 	 * Set its address into default_skipxferp.
9847c478bd9Sstevel@tonic-gate 	 */
9857c478bd9Sstevel@tonic-gate 	if (((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) == 0) &&
9867c478bd9Sstevel@tonic-gate 	    (wvp->ctxtp->default_skipmode == IXL1394_SKIP_TO_LABEL)) {
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 		err = hci1394_ixl_find_next_exec_xfer(wvp->default_skiplabelp,
9897c478bd9Sstevel@tonic-gate 		    NULL, &wvp->default_skipxferp);
9907c478bd9Sstevel@tonic-gate 		if (err == DDI_FAILURE) {
9917c478bd9Sstevel@tonic-gate 			TNF_PROBE_2(hci1394_finalize_all_xfer_desc_error,
9927c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
9937c478bd9Sstevel@tonic-gate 			    "IXL1394_ENO_DATA_PKTS: label<->jump loop detected "
9947c478bd9Sstevel@tonic-gate 			    "for skiplabel default w/no xfers", tnf_opaque,
9957c478bd9Sstevel@tonic-gate 			    skipixl_cmdp, wvp->default_skiplabelp);
9967c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_exit,
9977c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate 			wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
10007c478bd9Sstevel@tonic-gate 			return;
10017c478bd9Sstevel@tonic-gate 		}
10027c478bd9Sstevel@tonic-gate 	}
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 	/* set first ixl cmd */
10057c478bd9Sstevel@tonic-gate 	ixlnextp = wvp->ctxtp->ixl_firstp;
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 	/* follow ixl links until reach end or find error */
10087c478bd9Sstevel@tonic-gate 	while ((ixlnextp != NULL) && (wvp->dma_bld_error == 0)) {
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 		/* set this command as the current ixl command */
10117c478bd9Sstevel@tonic-gate 		ixlcurp = ixlnextp;
10127c478bd9Sstevel@tonic-gate 		ixlnextp = ixlcurp->next_ixlp;
10137c478bd9Sstevel@tonic-gate 
10147c478bd9Sstevel@tonic-gate 		/* get command opcode removing unneeded update flag */
10157c478bd9Sstevel@tonic-gate 		ixlopcode = ixlcurp->ixl_opcode & ~IXL1394_OPF_UPDATE;
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 		/*
10187c478bd9Sstevel@tonic-gate 		 * Scan for next ixl xfer start command (including this one),
10197c478bd9Sstevel@tonic-gate 		 * along ixl link path. Once xfer command found, find next IXL
10207c478bd9Sstevel@tonic-gate 		 * xfer cmd along execution path and fill in branch address of
10217c478bd9Sstevel@tonic-gate 		 * current xfer command. If is composite ixl xfer command, first
10227c478bd9Sstevel@tonic-gate 		 * link forward branch dma addresses of each descriptor block in
10237c478bd9Sstevel@tonic-gate 		 * composite, until reach final one then set its branch address
10247c478bd9Sstevel@tonic-gate 		 * to next execution path xfer found.  Next determine skip mode
10257c478bd9Sstevel@tonic-gate 		 * and fill in skip address(es) appropriately.
10267c478bd9Sstevel@tonic-gate 		 */
10277c478bd9Sstevel@tonic-gate 		/* skip to next if not xfer start ixl command */
10287c478bd9Sstevel@tonic-gate 		if (((ixlopcode & IXL1394_OPF_ISXFER) == 0) ||
10297c478bd9Sstevel@tonic-gate 		    ((ixlopcode & IXL1394_OPTY_MASK) == 0)) {
10307c478bd9Sstevel@tonic-gate 			continue;
10317c478bd9Sstevel@tonic-gate 		}
10327c478bd9Sstevel@tonic-gate 
10337c478bd9Sstevel@tonic-gate 		/*
10347c478bd9Sstevel@tonic-gate 		 * get xfer_ctl structure and composite repeat count for current
10357c478bd9Sstevel@tonic-gate 		 * IXL xfer cmd
10367c478bd9Sstevel@tonic-gate 		 */
10377c478bd9Sstevel@tonic-gate 		xferctl_curp = (hci1394_xfer_ctl_t *)ixlcurp->compiler_privatep;
10387c478bd9Sstevel@tonic-gate 		repcnt = xferctl_curp->cnt;
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 		/*
10417c478bd9Sstevel@tonic-gate 		 * if initiated by an IXL label command, set interrupt enable
10427c478bd9Sstevel@tonic-gate 		 * flag into last component of first descriptor block of
10437c478bd9Sstevel@tonic-gate 		 * current IXL xfer cmd
10447c478bd9Sstevel@tonic-gate 		 */
10457c478bd9Sstevel@tonic-gate 		if ((xferctl_curp->ctl_flags & XCTL_LABELLED) != 0) {
10467c478bd9Sstevel@tonic-gate 			hcidescp = (hci1394_desc_t *)
10477c478bd9Sstevel@tonic-gate 			    xferctl_curp->dma[0].dma_descp;
10487c478bd9Sstevel@tonic-gate 			acc_hdl = xferctl_curp->dma[0].dma_buf->bi_handle;
10497c478bd9Sstevel@tonic-gate 			temp = ddi_get32(acc_hdl, &hcidescp->hdr);
10507c478bd9Sstevel@tonic-gate 			temp |= DESC_INTR_ENBL;
10517c478bd9Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->hdr, temp);
10527c478bd9Sstevel@tonic-gate 		}
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate 		/* find next xfer IXL cmd by following execution path */
10557c478bd9Sstevel@tonic-gate 		err = hci1394_ixl_find_next_exec_xfer(ixlcurp->next_ixlp,
10567c478bd9Sstevel@tonic-gate 		    &callback_cnt, &ixlexecnext);
10577c478bd9Sstevel@tonic-gate 
10587c478bd9Sstevel@tonic-gate 		/* if label<->jump loop detected, return error */
10597c478bd9Sstevel@tonic-gate 		if (err == DDI_FAILURE) {
10607c478bd9Sstevel@tonic-gate 			wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate 			TNF_PROBE_2(hci1394_finalize_all_xfer_desc_error,
10637c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
10647c478bd9Sstevel@tonic-gate 			    "IXL1394_ENO_DATA_PKTS: label<->jump loop detected "
10657c478bd9Sstevel@tonic-gate 			    "w/no xfers", tnf_opaque, ixl_cmdp,
10667c478bd9Sstevel@tonic-gate 			    ixlcurp->next_ixlp);
10677c478bd9Sstevel@tonic-gate 			continue;
10687c478bd9Sstevel@tonic-gate 		}
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate 		/* link current IXL's xfer_ctl to next xfer IXL on exec path */
10717c478bd9Sstevel@tonic-gate 		xferctl_curp->execp = ixlexecnext;
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 		/*
10747c478bd9Sstevel@tonic-gate 		 * if callbacks have been seen during execution path scan,
10757c478bd9Sstevel@tonic-gate 		 * set interrupt enable flag into last descriptor of last
10767c478bd9Sstevel@tonic-gate 		 * descriptor block of current IXL xfer cmd
10777c478bd9Sstevel@tonic-gate 		 */
10787c478bd9Sstevel@tonic-gate 		if (callback_cnt != 0) {
10797c478bd9Sstevel@tonic-gate 			hcidescp = (hci1394_desc_t *)
10807c478bd9Sstevel@tonic-gate 			    xferctl_curp->dma[repcnt - 1].dma_descp;
10817c478bd9Sstevel@tonic-gate 			acc_hdl =
10827c478bd9Sstevel@tonic-gate 			    xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle;
10837c478bd9Sstevel@tonic-gate 			temp = ddi_get32(acc_hdl, &hcidescp->hdr);
10847c478bd9Sstevel@tonic-gate 			temp |= DESC_INTR_ENBL;
10857c478bd9Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->hdr, temp);
10867c478bd9Sstevel@tonic-gate 		}
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 		/*
10897c478bd9Sstevel@tonic-gate 		 * obtain dma bound addr of next exec path IXL xfer command,
10907c478bd9Sstevel@tonic-gate 		 * if any
10917c478bd9Sstevel@tonic-gate 		 */
10927c478bd9Sstevel@tonic-gate 		dma_execnext_addr = 0;
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate 		if (ixlexecnext != NULL) {
10957c478bd9Sstevel@tonic-gate 			xferctl_nxtp = (hci1394_xfer_ctl_t *)
10967c478bd9Sstevel@tonic-gate 			    ixlexecnext->compiler_privatep;
10977c478bd9Sstevel@tonic-gate 			dma_execnext_addr = xferctl_nxtp->dma[0].dma_bound;
10987c478bd9Sstevel@tonic-gate 		} else {
10997c478bd9Sstevel@tonic-gate 			/*
11007c478bd9Sstevel@tonic-gate 			 * If this is last descriptor (next == NULL), then
11017c478bd9Sstevel@tonic-gate 			 * make sure the interrupt bit is enabled.  This
11027c478bd9Sstevel@tonic-gate 			 * way we can ensure that we are notified when the
11037c478bd9Sstevel@tonic-gate 			 * descriptor chain processing has come to an end.
11047c478bd9Sstevel@tonic-gate 			 */
11057c478bd9Sstevel@tonic-gate 			hcidescp = (hci1394_desc_t *)
11067c478bd9Sstevel@tonic-gate 			    xferctl_curp->dma[repcnt - 1].dma_descp;
11077c478bd9Sstevel@tonic-gate 			acc_hdl =
11087c478bd9Sstevel@tonic-gate 			    xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle;
11097c478bd9Sstevel@tonic-gate 			temp = ddi_get32(acc_hdl, &hcidescp->hdr);
11107c478bd9Sstevel@tonic-gate 			temp |= DESC_INTR_ENBL;
11117c478bd9Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->hdr, temp);
11127c478bd9Sstevel@tonic-gate 		}
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate 		/*
11157c478bd9Sstevel@tonic-gate 		 * set jump address of final cur IXL xfer cmd to addr next
11167c478bd9Sstevel@tonic-gate 		 * IXL xfer cmd
11177c478bd9Sstevel@tonic-gate 		 */
11187c478bd9Sstevel@tonic-gate 		hcidescp = (hci1394_desc_t *)
11197c478bd9Sstevel@tonic-gate 		    xferctl_curp->dma[repcnt - 1].dma_descp;
11207c478bd9Sstevel@tonic-gate 		acc_hdl = xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle;
11217c478bd9Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->branch, dma_execnext_addr);
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate 		/*
11247c478bd9Sstevel@tonic-gate 		 * if a composite object, forward link initial jump
11257c478bd9Sstevel@tonic-gate 		 * dma addresses
11267c478bd9Sstevel@tonic-gate 		 */
11277c478bd9Sstevel@tonic-gate 		for (ii = 0; ii < repcnt - 1; ii++) {
11287c478bd9Sstevel@tonic-gate 			hcidescp = (hci1394_desc_t *)
11297c478bd9Sstevel@tonic-gate 			    xferctl_curp->dma[ii].dma_descp;
11307c478bd9Sstevel@tonic-gate 			acc_hdl	 = xferctl_curp->dma[ii].dma_buf->bi_handle;
11317c478bd9Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->branch,
11327c478bd9Sstevel@tonic-gate 			    xferctl_curp->dma[ii + 1].dma_bound);
11337c478bd9Sstevel@tonic-gate 		}
11347c478bd9Sstevel@tonic-gate 
11357c478bd9Sstevel@tonic-gate 		/*
11367c478bd9Sstevel@tonic-gate 		 * fill in skip address(es) for all descriptor blocks belonging
11377c478bd9Sstevel@tonic-gate 		 * to current IXL xfer command; note:skip addresses apply only
11387c478bd9Sstevel@tonic-gate 		 * to xmit mode commands
11397c478bd9Sstevel@tonic-gate 		 */
11407c478bd9Sstevel@tonic-gate 		if ((ixlopcode & IXL1394_OPF_ONXMIT) != 0) {
11417c478bd9Sstevel@tonic-gate 
11427c478bd9Sstevel@tonic-gate 			/* first obtain and set skip mode information */
11437c478bd9Sstevel@tonic-gate 			wvp->ixl_setskipmode_cmdp = xferctl_curp->skipmodep;
11447c478bd9Sstevel@tonic-gate 			hci1394_set_xmit_skip_mode(wvp);
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 			/*
11477c478bd9Sstevel@tonic-gate 			 * if skip to label,init dma bound addr to be
11487c478bd9Sstevel@tonic-gate 			 * 1st xfer cmd after label
11497c478bd9Sstevel@tonic-gate 			 */
11507c478bd9Sstevel@tonic-gate 			dma_skiplabel_addr = 0;
11517c478bd9Sstevel@tonic-gate 			if ((wvp->skipmode == IXL1394_SKIP_TO_LABEL) &&
11527c478bd9Sstevel@tonic-gate 			    (wvp->skipxferp != NULL)) {
11537c478bd9Sstevel@tonic-gate 				xferctl_nxtp = (hci1394_xfer_ctl_t *)
11547c478bd9Sstevel@tonic-gate 				    wvp->skipxferp->compiler_privatep;
11557c478bd9Sstevel@tonic-gate 				dma_skiplabel_addr =
11567c478bd9Sstevel@tonic-gate 				    xferctl_nxtp->dma[0].dma_bound;
11577c478bd9Sstevel@tonic-gate 			}
11587c478bd9Sstevel@tonic-gate 
11597c478bd9Sstevel@tonic-gate 			/*
11607c478bd9Sstevel@tonic-gate 			 * set skip addrs for each descriptor blk at this
11617c478bd9Sstevel@tonic-gate 			 * xfer start IXL cmd
11627c478bd9Sstevel@tonic-gate 			 */
11637c478bd9Sstevel@tonic-gate 			for (ii = 0; ii < repcnt; ii++) {
11647c478bd9Sstevel@tonic-gate 				switch (wvp->skipmode) {
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate 				case IXL1394_SKIP_TO_LABEL:
11677c478bd9Sstevel@tonic-gate 					/* set dma bound address - label */
11687c478bd9Sstevel@tonic-gate 					dma_skip_addr = dma_skiplabel_addr;
11697c478bd9Sstevel@tonic-gate 					break;
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate 				case IXL1394_SKIP_TO_NEXT:
11727c478bd9Sstevel@tonic-gate 					/* set dma bound address - next */
11737c478bd9Sstevel@tonic-gate 					if (ii < repcnt - 1) {
11747c478bd9Sstevel@tonic-gate 						dma_skip_addr = xferctl_curp->
11757c478bd9Sstevel@tonic-gate 						    dma[ii + 1].dma_bound;
11767c478bd9Sstevel@tonic-gate 					} else {
11777c478bd9Sstevel@tonic-gate 						dma_skip_addr =
11787c478bd9Sstevel@tonic-gate 						    dma_execnext_addr;
11797c478bd9Sstevel@tonic-gate 					}
11807c478bd9Sstevel@tonic-gate 					break;
11817c478bd9Sstevel@tonic-gate 
11827c478bd9Sstevel@tonic-gate 				case IXL1394_SKIP_TO_SELF:
11837c478bd9Sstevel@tonic-gate 					/* set dma bound address - self */
11847c478bd9Sstevel@tonic-gate 					dma_skip_addr =
11857c478bd9Sstevel@tonic-gate 					    xferctl_curp->dma[ii].dma_bound;
11867c478bd9Sstevel@tonic-gate 					break;
11877c478bd9Sstevel@tonic-gate 
11887c478bd9Sstevel@tonic-gate 				case IXL1394_SKIP_TO_STOP:
11897c478bd9Sstevel@tonic-gate 				default:
11907c478bd9Sstevel@tonic-gate 					/* set dma bound address - stop */
11917c478bd9Sstevel@tonic-gate 					dma_skip_addr = 0;
11927c478bd9Sstevel@tonic-gate 					break;
11937c478bd9Sstevel@tonic-gate 				}
11947c478bd9Sstevel@tonic-gate 
11957c478bd9Sstevel@tonic-gate 				/*
11967c478bd9Sstevel@tonic-gate 				 * determine address of first descriptor of
11977c478bd9Sstevel@tonic-gate 				 * current descriptor block by adjusting addr of
11987c478bd9Sstevel@tonic-gate 				 * last descriptor of current descriptor block
11997c478bd9Sstevel@tonic-gate 				 */
12007c478bd9Sstevel@tonic-gate 				hcidescp = ((hci1394_desc_t *)
1201