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
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
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
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
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
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 *)
12017c478bd9Sstevel@tonic-gate 				    xferctl_curp->dma[ii].dma_descp);
12027c478bd9Sstevel@tonic-gate 				acc_hdl =
12037c478bd9Sstevel@tonic-gate 				    xferctl_curp->dma[ii].dma_buf->bi_handle;
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate 				/*
12067c478bd9Sstevel@tonic-gate 				 * adjust by count of descriptors in this desc
12077c478bd9Sstevel@tonic-gate 				 * block not including the last one (size of
12087c478bd9Sstevel@tonic-gate 				 * descriptor)
12097c478bd9Sstevel@tonic-gate 				 */
12107c478bd9Sstevel@tonic-gate 				hcidescp -= ((xferctl_curp->dma[ii].dma_bound &
12117c478bd9Sstevel@tonic-gate 				    DESC_Z_MASK) - 1);
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate 				/*
12147c478bd9Sstevel@tonic-gate 				 * adjust further if the last descriptor is
12157c478bd9Sstevel@tonic-gate 				 * double sized
12167c478bd9Sstevel@tonic-gate 				 */
12177c478bd9Sstevel@tonic-gate 				if (ixlopcode == IXL1394_OP_SEND_HDR_ONLY) {
12187c478bd9Sstevel@tonic-gate 					hcidescp++;
12197c478bd9Sstevel@tonic-gate 				}
12207c478bd9Sstevel@tonic-gate 				/*
12217c478bd9Sstevel@tonic-gate 				 * now set skip address into first descriptor
12227c478bd9Sstevel@tonic-gate 				 * of descriptor block
12237c478bd9Sstevel@tonic-gate 				 */
12247c478bd9Sstevel@tonic-gate 				ddi_put32(acc_hdl, &hcidescp->branch,
12257c478bd9Sstevel@tonic-gate 				    dma_skip_addr);
12267c478bd9Sstevel@tonic-gate 			} /* for */
12277c478bd9Sstevel@tonic-gate 		} /* if */
12287c478bd9Sstevel@tonic-gate 	} /* while */
12297c478bd9Sstevel@tonic-gate 
12307c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_exit,
12317c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
12327c478bd9Sstevel@tonic-gate }
12337c478bd9Sstevel@tonic-gate 
12347c478bd9Sstevel@tonic-gate /*
12357c478bd9Sstevel@tonic-gate  * hci1394_finalize_cur_xfer_desc()
12367c478bd9Sstevel@tonic-gate  *    Build the openHCI descriptor for a packet or buffer based on info
12377c478bd9Sstevel@tonic-gate  *    currently collected into the working vars struct (wvp).  After some
12387c478bd9Sstevel@tonic-gate  *    checks, this routine dispatches to the appropriate descriptor block
12397c478bd9Sstevel@tonic-gate  *    build (bld) routine for the packet or buf type.
12407c478bd9Sstevel@tonic-gate  */
12417c478bd9Sstevel@tonic-gate static void
12427c478bd9Sstevel@tonic-gate hci1394_finalize_cur_xfer_desc(hci1394_comp_ixl_vars_t *wvp)
12437c478bd9Sstevel@tonic-gate {
12447c478bd9Sstevel@tonic-gate 	uint16_t ixlopcode;
12457c478bd9Sstevel@tonic-gate 	uint16_t ixlopraw;
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_enter,
12487c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 	/* extract opcode from current IXL cmd (if any) */
12517c478bd9Sstevel@tonic-gate 	if (wvp->ixl_cur_cmdp != NULL) {
12527c478bd9Sstevel@tonic-gate 		ixlopcode = wvp->ixl_cur_cmdp->ixl_opcode;
12537c478bd9Sstevel@tonic-gate 		ixlopraw = ixlopcode & ~IXL1394_OPF_UPDATE;
12547c478bd9Sstevel@tonic-gate 	} else {
12557c478bd9Sstevel@tonic-gate 		ixlopcode = ixlopraw = IXL1394_OP_INVALID;
12567c478bd9Sstevel@tonic-gate 	}
12577c478bd9Sstevel@tonic-gate 
12587c478bd9Sstevel@tonic-gate 	/*
12597c478bd9Sstevel@tonic-gate 	 * if no xfer descriptor block being built, perform validity checks
12607c478bd9Sstevel@tonic-gate 	 */
12617c478bd9Sstevel@tonic-gate 	if (wvp->xfer_state == XFER_NONE) {
12627c478bd9Sstevel@tonic-gate 		/*
12637c478bd9Sstevel@tonic-gate 		 * error if being finalized by IXL1394_OP_LABEL or
12647c478bd9Sstevel@tonic-gate 		 * IXL1394_OP_JUMP or if at end, and have an unapplied
12657c478bd9Sstevel@tonic-gate 		 * IXL1394_OP_SET_TAGSYNC, IXL1394_OP_SET_SKIPMODE or
12667c478bd9Sstevel@tonic-gate 		 * IXL1394_OP_SET_SYNCWAIT
12677c478bd9Sstevel@tonic-gate 		 */
12687c478bd9Sstevel@tonic-gate 		if ((ixlopraw == IXL1394_OP_JUMP) ||
12697c478bd9Sstevel@tonic-gate 		    (ixlopraw == IXL1394_OP_LABEL) ||
12707c478bd9Sstevel@tonic-gate 		    (wvp->ixl_cur_cmdp == NULL) ||
12717c478bd9Sstevel@tonic-gate 		    (wvp->ixl_cur_cmdp->next_ixlp == NULL)) {
12727c478bd9Sstevel@tonic-gate 			if ((wvp->ixl_settagsync_cmdp != NULL) ||
12737c478bd9Sstevel@tonic-gate 			    (wvp->ixl_setskipmode_cmdp != NULL) ||
12747c478bd9Sstevel@tonic-gate 			    (wvp->ixl_setsyncwait_cnt != 0)) {
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_EUNAPPLIED_SET_CMD;
12777c478bd9Sstevel@tonic-gate 
12787c478bd9Sstevel@tonic-gate 				TNF_PROBE_2(
12797c478bd9Sstevel@tonic-gate 				    hci1394_finalize_cur_xfer_desc_set_error,
12807c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
12817c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_UNAPPLIED_SET_CMD: "
12827c478bd9Sstevel@tonic-gate 				    "orphaned set (no associated packet)",
12837c478bd9Sstevel@tonic-gate 				    tnf_opaque, ixl_commandp,
12847c478bd9Sstevel@tonic-gate 				    wvp->ixl_cur_cmdp);
12857c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
12867c478bd9Sstevel@tonic-gate 				    hci1394_finalize_cur_xfer_desc_exit,
12877c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
12887c478bd9Sstevel@tonic-gate 				return;
12897c478bd9Sstevel@tonic-gate 			}
12907c478bd9Sstevel@tonic-gate 		}
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate 		/* error if finalize is due to updateable jump cmd */
12937c478bd9Sstevel@tonic-gate 		if (ixlopcode == IXL1394_OP_JUMP_U) {
12947c478bd9Sstevel@tonic-gate 
12957c478bd9Sstevel@tonic-gate 			wvp->dma_bld_error = IXL1394_EUPDATE_DISALLOWED;
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 			TNF_PROBE_2(hci1394_finalize_cur_xfer_desc_upd_error,
12987c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
12997c478bd9Sstevel@tonic-gate 			    "IXL1394_EUPDATE_DISALLOWED: jumpU w/out pkt",
13007c478bd9Sstevel@tonic-gate 			    tnf_opaque, ixl_commandp, wvp->ixl_cur_cmdp);
13017c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
13027c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
13037c478bd9Sstevel@tonic-gate 			return;
13047c478bd9Sstevel@tonic-gate 		}
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
13077c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
13087c478bd9Sstevel@tonic-gate 
13097c478bd9Sstevel@tonic-gate 		/* no error, no xfer */
13107c478bd9Sstevel@tonic-gate 		return;
13117c478bd9Sstevel@tonic-gate 	}
13127c478bd9Sstevel@tonic-gate 
13137c478bd9Sstevel@tonic-gate 	/*
13147c478bd9Sstevel@tonic-gate 	 * finalize current xfer descriptor block being built
13157c478bd9Sstevel@tonic-gate 	 */
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	/* count IXL xfer start command for descriptor block being built */
13187c478bd9Sstevel@tonic-gate 	wvp->ixl_xfer_st_cnt++;
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate 	/*
13217c478bd9Sstevel@tonic-gate 	 * complete setting of cache flush evaluation flags; flags will already
13227c478bd9Sstevel@tonic-gate 	 * have been set by updateable set cmds and non-start xfer pkt cmds
13237c478bd9Sstevel@tonic-gate 	 */
13247c478bd9Sstevel@tonic-gate 	/* now set cache flush flag if current xfer start cmnd is updateable */
13257c478bd9Sstevel@tonic-gate 	if ((wvp->ixl_cur_xfer_stp->ixl_opcode & IXL1394_OPF_UPDATE) != 0) {
13267c478bd9Sstevel@tonic-gate 		wvp->xfer_hci_flush |= UPDATEABLE_XFER;
13277c478bd9Sstevel@tonic-gate 	}
13287c478bd9Sstevel@tonic-gate 	/*
13297c478bd9Sstevel@tonic-gate 	 * also set cache flush flag if xfer being finalized by
13307c478bd9Sstevel@tonic-gate 	 * updateable jump cmd
13317c478bd9Sstevel@tonic-gate 	 */
13327c478bd9Sstevel@tonic-gate 	if ((ixlopcode == IXL1394_OP_JUMP_U) != 0) {
13337c478bd9Sstevel@tonic-gate 		wvp->xfer_hci_flush |= UPDATEABLE_JUMP;
13347c478bd9Sstevel@tonic-gate 	}
13357c478bd9Sstevel@tonic-gate 
13367c478bd9Sstevel@tonic-gate 	/*
13377c478bd9Sstevel@tonic-gate 	 * Determine if cache flush required before building next descriptor
13387c478bd9Sstevel@tonic-gate 	 * block. If xfer pkt command and any cache flush flags are set,
13397c478bd9Sstevel@tonic-gate 	 * hci flush needed.
13407c478bd9Sstevel@tonic-gate 	 * If buffer or special xfer command and xfer command is updateable or
13417c478bd9Sstevel@tonic-gate 	 * an associated set command is updateable, hci flush is required now.
13427c478bd9Sstevel@tonic-gate 	 * If a single-xfer buffer or special xfer command is finalized by
13437c478bd9Sstevel@tonic-gate 	 * updateable jump command, hci flush is required now.
13447c478bd9Sstevel@tonic-gate 	 * Note: a cache flush will be required later, before the last
13457c478bd9Sstevel@tonic-gate 	 * descriptor block of a multi-xfer set of descriptor blocks is built,
13467c478bd9Sstevel@tonic-gate 	 * if this (non-pkt) xfer is finalized by an updateable jump command.
13477c478bd9Sstevel@tonic-gate 	 */
13487c478bd9Sstevel@tonic-gate 	if (wvp->xfer_hci_flush != 0) {
13497c478bd9Sstevel@tonic-gate 		if (((wvp->ixl_cur_xfer_stp->ixl_opcode &
13507c478bd9Sstevel@tonic-gate 		    IXL1394_OPTY_XFER_PKT_ST) != 0) || ((wvp->xfer_hci_flush &
1351*ffc2b7d4SToomas Soome 		    (UPDATEABLE_XFER | UPDATEABLE_SET | INITIATING_LBL)) !=
1352*ffc2b7d4SToomas Soome 		    0)) {
13537c478bd9Sstevel@tonic-gate 
13547c478bd9Sstevel@tonic-gate 			if (hci1394_flush_hci_cache(wvp) != DDI_SUCCESS) {
13557c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
13567c478bd9Sstevel@tonic-gate 				    hci1394_finalize_cur_xfer_desc_exit,
13577c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
13587c478bd9Sstevel@tonic-gate 
13597c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
13607c478bd9Sstevel@tonic-gate 				return;
13617c478bd9Sstevel@tonic-gate 			}
13627c478bd9Sstevel@tonic-gate 		}
13637c478bd9Sstevel@tonic-gate 	}
13647c478bd9Sstevel@tonic-gate 
13657c478bd9Sstevel@tonic-gate 	/*
13667c478bd9Sstevel@tonic-gate 	 * determine which kind of descriptor block to build based on
13677c478bd9Sstevel@tonic-gate 	 * xfer state - hdr only, skip cycle, pkt or buf.
13687c478bd9Sstevel@tonic-gate 	 */
13697c478bd9Sstevel@tonic-gate 	switch (wvp->xfer_state) {
13707c478bd9Sstevel@tonic-gate 
13717c478bd9Sstevel@tonic-gate 	case XFER_PKT:
13727c478bd9Sstevel@tonic-gate 		if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) {
13737c478bd9Sstevel@tonic-gate 			hci1394_bld_recv_pkt_desc(wvp);
13747c478bd9Sstevel@tonic-gate 		} else {
13757c478bd9Sstevel@tonic-gate 			hci1394_bld_xmit_pkt_desc(wvp);
13767c478bd9Sstevel@tonic-gate 		}
13777c478bd9Sstevel@tonic-gate 		break;
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate 	case XFER_BUF:
13807c478bd9Sstevel@tonic-gate 		if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) {
13817c478bd9Sstevel@tonic-gate 			if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) {
13827c478bd9Sstevel@tonic-gate 				hci1394_bld_recv_buf_fill_desc(wvp);
13837c478bd9Sstevel@tonic-gate 			} else {
13847c478bd9Sstevel@tonic-gate 				hci1394_bld_recv_buf_ppb_desc(wvp);
13857c478bd9Sstevel@tonic-gate 			}
13867c478bd9Sstevel@tonic-gate 		} else {
13877c478bd9Sstevel@tonic-gate 			hci1394_bld_xmit_buf_desc(wvp);
13887c478bd9Sstevel@tonic-gate 		}
13897c478bd9Sstevel@tonic-gate 		break;
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate 	case XMIT_HDRONLY:
13927c478bd9Sstevel@tonic-gate 	case XMIT_NOPKT:
13937c478bd9Sstevel@tonic-gate 		hci1394_bld_xmit_hdronly_nopkt_desc(wvp);
13947c478bd9Sstevel@tonic-gate 		break;
13957c478bd9Sstevel@tonic-gate 
13967c478bd9Sstevel@tonic-gate 	default:
13977c478bd9Sstevel@tonic-gate 		/* internal compiler error */
13987c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_finalize_cur_xfer_desc_internal_error,
13997c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
14007c478bd9Sstevel@tonic-gate 		    "IXL1394_INTERNAL_ERROR: invalid state", tnf_opaque,
14017c478bd9Sstevel@tonic-gate 		    ixl_commandp, wvp->ixl_cur_cmdp);
14027c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR;
14037c478bd9Sstevel@tonic-gate 	}
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 	/* return if error */
14067c478bd9Sstevel@tonic-gate 	if (wvp->dma_bld_error != 0) {
14077c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
14087c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate 		/* wvp->dma_bld_error is set by above call */
14117c478bd9Sstevel@tonic-gate 		return;
14127c478bd9Sstevel@tonic-gate 	}
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate 	/*
14157c478bd9Sstevel@tonic-gate 	 * if was finalizing IXL jump cmd, set compiler_privatep to
14167c478bd9Sstevel@tonic-gate 	 * cur xfer IXL cmd
14177c478bd9Sstevel@tonic-gate 	 */
14187c478bd9Sstevel@tonic-gate 	if (ixlopraw == IXL1394_OP_JUMP) {
14197c478bd9Sstevel@tonic-gate 		wvp->ixl_cur_cmdp->compiler_privatep =
14207c478bd9Sstevel@tonic-gate 		    (void *)wvp->ixl_cur_xfer_stp;
14217c478bd9Sstevel@tonic-gate 	}
14227c478bd9Sstevel@tonic-gate 
14237c478bd9Sstevel@tonic-gate 	/* if cur xfer IXL initiated by IXL label cmd, set flag in xfer_ctl */
14247c478bd9Sstevel@tonic-gate 	if (wvp->ixl_cur_labelp != NULL) {
14257c478bd9Sstevel@tonic-gate 		((hci1394_xfer_ctl_t *)
14267c478bd9Sstevel@tonic-gate 		    (wvp->ixl_cur_xfer_stp->compiler_privatep))->ctl_flags |=
14277c478bd9Sstevel@tonic-gate 		    XCTL_LABELLED;
14287c478bd9Sstevel@tonic-gate 		wvp->ixl_cur_labelp = NULL;
14297c478bd9Sstevel@tonic-gate 	}
14307c478bd9Sstevel@tonic-gate 
14317c478bd9Sstevel@tonic-gate 	/*
14327c478bd9Sstevel@tonic-gate 	 * set any associated IXL set skipmode cmd into xfer_ctl of
14337c478bd9Sstevel@tonic-gate 	 * cur xfer IXL cmd
14347c478bd9Sstevel@tonic-gate 	 */
14357c478bd9Sstevel@tonic-gate 	if (wvp->ixl_setskipmode_cmdp != NULL) {
14367c478bd9Sstevel@tonic-gate 		((hci1394_xfer_ctl_t *)
14377c478bd9Sstevel@tonic-gate 		    (wvp->ixl_cur_xfer_stp->compiler_privatep))->skipmodep =
14387c478bd9Sstevel@tonic-gate 		    wvp->ixl_setskipmode_cmdp;
14397c478bd9Sstevel@tonic-gate 	}
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 	/* set no current xfer start cmd */
14427c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_xfer_stp = NULL;
14437c478bd9Sstevel@tonic-gate 
14447c478bd9Sstevel@tonic-gate 	/* set no current set tag&sync, set skipmode or set syncwait commands */
14457c478bd9Sstevel@tonic-gate 	wvp->ixl_settagsync_cmdp = NULL;
14467c478bd9Sstevel@tonic-gate 	wvp->ixl_setskipmode_cmdp = NULL;
14477c478bd9Sstevel@tonic-gate 	wvp->ixl_setsyncwait_cnt = 0;
14487c478bd9Sstevel@tonic-gate 
14497c478bd9Sstevel@tonic-gate 	/* set no currently active descriptor blocks */
14507c478bd9Sstevel@tonic-gate 	wvp->descriptors = 0;
14517c478bd9Sstevel@tonic-gate 
14527c478bd9Sstevel@tonic-gate 	/* reset total packet length and buffers count */
14537c478bd9Sstevel@tonic-gate 	wvp->xfer_pktlen = 0;
14547c478bd9Sstevel@tonic-gate 	wvp->xfer_bufcnt = 0;
14557c478bd9Sstevel@tonic-gate 
14567c478bd9Sstevel@tonic-gate 	/* reset flush cache evaluation flags */
14577c478bd9Sstevel@tonic-gate 	wvp->xfer_hci_flush = 0;
14587c478bd9Sstevel@tonic-gate 
14597c478bd9Sstevel@tonic-gate 	/* set no xmit descriptor block being built */
14607c478bd9Sstevel@tonic-gate 	wvp->xfer_state = XFER_NONE;
14617c478bd9Sstevel@tonic-gate 
14627c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit,
14637c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
14647c478bd9Sstevel@tonic-gate }
14657c478bd9Sstevel@tonic-gate 
14667c478bd9Sstevel@tonic-gate /*
14677c478bd9Sstevel@tonic-gate  * hci1394_bld_recv_pkt_desc()
14687c478bd9Sstevel@tonic-gate  *    Used to create the openHCI dma descriptor block(s) for a receive packet.
14697c478bd9Sstevel@tonic-gate  */
14707c478bd9Sstevel@tonic-gate static void
14717c478bd9Sstevel@tonic-gate hci1394_bld_recv_pkt_desc(hci1394_comp_ixl_vars_t *wvp)
14727c478bd9Sstevel@tonic-gate {
14737c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xctlp;
14747c478bd9Sstevel@tonic-gate 	caddr_t			dma_descp;
14757c478bd9Sstevel@tonic-gate 	uint32_t		dma_desc_bound;
14767c478bd9Sstevel@tonic-gate 	uint32_t		wait_for_sync;
14777c478bd9Sstevel@tonic-gate 	uint32_t		ii;
14787c478bd9Sstevel@tonic-gate 	hci1394_desc_t		*wv_descp;	/* shorthand to local descrpt */
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_enter,
14817c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate 	/*
14847c478bd9Sstevel@tonic-gate 	 * is error if number of descriptors to be built exceeds maximum
14857c478bd9Sstevel@tonic-gate 	 * descriptors allowed in a descriptor block.
14867c478bd9Sstevel@tonic-gate 	 */
14877c478bd9Sstevel@tonic-gate 	if ((wvp->descriptors + wvp->xfer_bufcnt) > HCI1394_DESC_MAX_Z) {
14887c478bd9Sstevel@tonic-gate 
14897c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO;
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 		TNF_PROBE_3(hci1394_bld_recv_pkt_desc_fragment_oflo_error,
14927c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
14937c478bd9Sstevel@tonic-gate 		    "IXL1394_EFRAGMENT_OFLO", tnf_opaque, ixl_commandp,
14947c478bd9Sstevel@tonic-gate 		    wvp->ixl_cur_xfer_stp, tnf_int, frag_count,
14957c478bd9Sstevel@tonic-gate 		    wvp->descriptors + wvp->xfer_bufcnt);
14967c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
14977c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
14987c478bd9Sstevel@tonic-gate 		return;
14997c478bd9Sstevel@tonic-gate 	}
15007c478bd9Sstevel@tonic-gate 
15017c478bd9Sstevel@tonic-gate 	/* allocate an xfer_ctl struct, including 1 xfer_ctl_dma struct */
15027c478bd9Sstevel@tonic-gate 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) {
15037c478bd9Sstevel@tonic-gate 
15047c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
15057c478bd9Sstevel@tonic-gate 
15067c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_bld_recv_pkt_desc_mem_alloc_fail,
15077c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
15087c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
15097c478bd9Sstevel@tonic-gate 		    ixl_commandp, wvp->ixl_cur_xfer_stp);
15107c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
15117c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
15127c478bd9Sstevel@tonic-gate 		return;
15137c478bd9Sstevel@tonic-gate 	}
15147c478bd9Sstevel@tonic-gate 
15157c478bd9Sstevel@tonic-gate 	/*
15167c478bd9Sstevel@tonic-gate 	 * save xfer_ctl struct addr in compiler_privatep of
15177c478bd9Sstevel@tonic-gate 	 * current IXL xfer cmd
15187c478bd9Sstevel@tonic-gate 	 */
15197c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate 	/*
15227c478bd9Sstevel@tonic-gate 	 * if enabled, set wait for sync flag in first descriptor of
15237c478bd9Sstevel@tonic-gate 	 * descriptor block
15247c478bd9Sstevel@tonic-gate 	 */
15257c478bd9Sstevel@tonic-gate 	if (wvp->ixl_setsyncwait_cnt > 0) {
15267c478bd9Sstevel@tonic-gate 		wvp->ixl_setsyncwait_cnt = 1;
15277c478bd9Sstevel@tonic-gate 		wait_for_sync = DESC_W_ENBL;
15287c478bd9Sstevel@tonic-gate 	} else {
15297c478bd9Sstevel@tonic-gate 		wait_for_sync = DESC_W_DSABL;
15307c478bd9Sstevel@tonic-gate 	}
15317c478bd9Sstevel@tonic-gate 
15327c478bd9Sstevel@tonic-gate 	/* create descriptor block for this recv packet (xfer status enabled) */
15337c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < wvp->xfer_bufcnt; ii++) {
15347c478bd9Sstevel@tonic-gate 		wv_descp = &wvp->descriptor_block[wvp->descriptors];
15357c478bd9Sstevel@tonic-gate 
15367c478bd9Sstevel@tonic-gate 		if (ii == (wvp->xfer_bufcnt - 1)) {
15377c478bd9Sstevel@tonic-gate 			HCI1394_INIT_IR_PPB_ILAST(wv_descp, DESC_HDR_STAT_ENBL,
15387c478bd9Sstevel@tonic-gate 			    DESC_INTR_DSABL, wait_for_sync, wvp->xfer_size[ii]);
15397c478bd9Sstevel@tonic-gate 		} else {
15407c478bd9Sstevel@tonic-gate 			HCI1394_INIT_IR_PPB_IMORE(wv_descp, wait_for_sync,
15417c478bd9Sstevel@tonic-gate 			    wvp->xfer_size[ii]);
15427c478bd9Sstevel@tonic-gate 		}
15437c478bd9Sstevel@tonic-gate 		wv_descp->data_addr = wvp->xfer_bufp[ii];
15447c478bd9Sstevel@tonic-gate 		wv_descp->branch = 0;
15457c478bd9Sstevel@tonic-gate 		wv_descp->status = (wvp->xfer_size[ii] <<
15467c478bd9Sstevel@tonic-gate 		    DESC_ST_RESCOUNT_SHIFT) & DESC_ST_RESCOUNT_MASK;
15477c478bd9Sstevel@tonic-gate 		wvp->descriptors++;
15487c478bd9Sstevel@tonic-gate 	}
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate 	/* allocate and copy descriptor block to dma memory */
15517c478bd9Sstevel@tonic-gate 	if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound) !=
15527c478bd9Sstevel@tonic-gate 	    DDI_SUCCESS) {
15537c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
15547c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
15557c478bd9Sstevel@tonic-gate 
15567c478bd9Sstevel@tonic-gate 		/* wvp->dma_bld_error is set by above function call */
15577c478bd9Sstevel@tonic-gate 		return;
15587c478bd9Sstevel@tonic-gate 	}
15597c478bd9Sstevel@tonic-gate 
15607c478bd9Sstevel@tonic-gate 	/*
15617c478bd9Sstevel@tonic-gate 	 * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual)
15627c478bd9Sstevel@tonic-gate 	 * is last component)
15637c478bd9Sstevel@tonic-gate 	 */
15647c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_bound = dma_desc_bound;
15657c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_descp =
15667c478bd9Sstevel@tonic-gate 	    dma_descp + (wvp->xfer_bufcnt - 1) * sizeof (hci1394_desc_t);
15677c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_buf	= &wvp->dma_currentp->mem;
15687c478bd9Sstevel@tonic-gate 
15697c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit,
15707c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
15717c478bd9Sstevel@tonic-gate }
15727c478bd9Sstevel@tonic-gate 
15737c478bd9Sstevel@tonic-gate /*
15747c478bd9Sstevel@tonic-gate  * hci1394_bld_recv_buf_ppb_desc()
15757c478bd9Sstevel@tonic-gate  *    Used to create the openHCI dma descriptor block(s) for a receive buf
15767c478bd9Sstevel@tonic-gate  *    in packet per buffer mode.
15777c478bd9Sstevel@tonic-gate  */
15787c478bd9Sstevel@tonic-gate static void
15797c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_ppb_desc(hci1394_comp_ixl_vars_t *wvp)
15807c478bd9Sstevel@tonic-gate {
15817c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xctlp;
15827c478bd9Sstevel@tonic-gate 	ixl1394_xfer_buf_t	*local_ixl_cur_xfer_stp;
15837c478bd9Sstevel@tonic-gate 	caddr_t		dma_descp;
15847c478bd9Sstevel@tonic-gate 	uint32_t	dma_desc_bound;
15857c478bd9Sstevel@tonic-gate 	uint32_t	pktsize;
15867c478bd9Sstevel@tonic-gate 	uint32_t	pktcnt;
15877c478bd9Sstevel@tonic-gate 	uint32_t	wait_for_sync;
15887c478bd9Sstevel@tonic-gate 	uint32_t	ii;
15897c478bd9Sstevel@tonic-gate 	hci1394_desc_t	*wv_descp;	/* shorthand to local descriptor */
15907c478bd9Sstevel@tonic-gate 
15917c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_enter,
15927c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
15937c478bd9Sstevel@tonic-gate 
15947c478bd9Sstevel@tonic-gate 	local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp;
15957c478bd9Sstevel@tonic-gate 
15967c478bd9Sstevel@tonic-gate 	/* determine number and size of pkt desc blocks to create */
15977c478bd9Sstevel@tonic-gate 	pktsize = local_ixl_cur_xfer_stp->pkt_size;
15987c478bd9Sstevel@tonic-gate 	pktcnt = local_ixl_cur_xfer_stp->size / pktsize;
15997c478bd9Sstevel@tonic-gate 
16007c478bd9Sstevel@tonic-gate 	/* allocate an xfer_ctl struct including pktcnt xfer_ctl_dma structs */
16017c478bd9Sstevel@tonic-gate 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, pktcnt)) == NULL) {
16027c478bd9Sstevel@tonic-gate 
16037c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
16047c478bd9Sstevel@tonic-gate 
16057c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_bld_recv_buf_ppb_desc_mem_alloc_fail,
16067c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
16077c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
16087c478bd9Sstevel@tonic-gate 		    ixl_commandp, wvp->ixl_cur_xfer_stp);
16097c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit,
16107c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
16117c478bd9Sstevel@tonic-gate 		return;
16127c478bd9Sstevel@tonic-gate 	}
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate 	/*
16157c478bd9Sstevel@tonic-gate 	 * save xfer_ctl struct addr in compiler_privatep of
16167c478bd9Sstevel@tonic-gate 	 * current IXL xfer cmd
16177c478bd9Sstevel@tonic-gate 	 */
16187c478bd9Sstevel@tonic-gate 	local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
16197c478bd9Sstevel@tonic-gate 
16207c478bd9Sstevel@tonic-gate 	/*
16217c478bd9Sstevel@tonic-gate 	 * if enabled, set wait for sync flag in first descriptor in
16227c478bd9Sstevel@tonic-gate 	 * descriptor block
16237c478bd9Sstevel@tonic-gate 	 */
16247c478bd9Sstevel@tonic-gate 	if (wvp->ixl_setsyncwait_cnt > 0) {
16257c478bd9Sstevel@tonic-gate 		wvp->ixl_setsyncwait_cnt = 1;
16267c478bd9Sstevel@tonic-gate 		wait_for_sync = DESC_W_ENBL;
16277c478bd9Sstevel@tonic-gate 	} else {
16287c478bd9Sstevel@tonic-gate 		wait_for_sync = DESC_W_DSABL;
16297c478bd9Sstevel@tonic-gate 	}
16307c478bd9Sstevel@tonic-gate 
16317c478bd9Sstevel@tonic-gate 	/* create first descriptor block for this recv packet */
16327c478bd9Sstevel@tonic-gate 	/* consists of one descriptor and xfer status is enabled */
16337c478bd9Sstevel@tonic-gate 	wv_descp = &wvp->descriptor_block[wvp->descriptors];
16347c478bd9Sstevel@tonic-gate 	HCI1394_INIT_IR_PPB_ILAST(wv_descp, DESC_HDR_STAT_ENBL, DESC_INTR_DSABL,
16357c478bd9Sstevel@tonic-gate 	    wait_for_sync, pktsize);
16367c478bd9Sstevel@tonic-gate 	wv_descp->data_addr = local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr;
16377c478bd9Sstevel@tonic-gate 	wv_descp->branch = 0;
16387c478bd9Sstevel@tonic-gate 	wv_descp->status = (pktsize << DESC_ST_RESCOUNT_SHIFT) &
16397c478bd9Sstevel@tonic-gate 	    DESC_ST_RESCOUNT_MASK;
16407c478bd9Sstevel@tonic-gate 	wvp->descriptors++;
16417c478bd9Sstevel@tonic-gate 
16427c478bd9Sstevel@tonic-gate 	/* useful debug trace info - IXL command, and packet count and size */
16437c478bd9Sstevel@tonic-gate 	TNF_PROBE_3_DEBUG(hci1394_bld_recv_buf_ppb_desc_recv_buf_info,
16447c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_INFO_ISOCH, "", tnf_opaque, ixl_commandp,
16457c478bd9Sstevel@tonic-gate 	    wvp->ixl_cur_xfer_stp, tnf_int, pkt_count, pktcnt, tnf_int,
16467c478bd9Sstevel@tonic-gate 	    pkt_size, pktsize);
16477c478bd9Sstevel@tonic-gate 
16487c478bd9Sstevel@tonic-gate 	/*
16497c478bd9Sstevel@tonic-gate 	 * generate as many contiguous descriptor blocks as there are
16507c478bd9Sstevel@tonic-gate 	 * recv pkts
16517c478bd9Sstevel@tonic-gate 	 */
16527c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < pktcnt; ii++) {
16537c478bd9Sstevel@tonic-gate 
16547c478bd9Sstevel@tonic-gate 		/* if about to create last descriptor block */
16557c478bd9Sstevel@tonic-gate 		if (ii == (pktcnt - 1)) {
16567c478bd9Sstevel@tonic-gate 			/* check and perform any required hci cache flush */
16577c478bd9Sstevel@tonic-gate 			if (hci1394_flush_end_desc_check(wvp, ii) !=
16587c478bd9Sstevel@tonic-gate 			    DDI_SUCCESS) {
16597c478bd9Sstevel@tonic-gate 				TNF_PROBE_1_DEBUG(
16607c478bd9Sstevel@tonic-gate 				    hci1394_bld_recv_buf_ppb_desc_fl_error,
16617c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_INFO_ISOCH, "", tnf_int,
16627c478bd9Sstevel@tonic-gate 				    for_ii, ii);
16637c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
16647c478bd9Sstevel@tonic-gate 				    hci1394_bld_recv_buf_ppb_desc_exit,
16657c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
16667c478bd9Sstevel@tonic-gate 
16677c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
16687c478bd9Sstevel@tonic-gate 				return;
16697c478bd9Sstevel@tonic-gate 			}
16707c478bd9Sstevel@tonic-gate 		}
16717c478bd9Sstevel@tonic-gate 
16727c478bd9Sstevel@tonic-gate 		/* allocate and copy descriptor block to dma memory */
16737c478bd9Sstevel@tonic-gate 		if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp,
16747c478bd9Sstevel@tonic-gate 		    &dma_desc_bound) != DDI_SUCCESS) {
16757c478bd9Sstevel@tonic-gate 
16767c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit,
16777c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
16787c478bd9Sstevel@tonic-gate 
16797c478bd9Sstevel@tonic-gate 			/* wvp->dma_bld_error is set by above call */
16807c478bd9Sstevel@tonic-gate 			return;
16817c478bd9Sstevel@tonic-gate 		}
16827c478bd9Sstevel@tonic-gate 
16837c478bd9Sstevel@tonic-gate 		/*
16847c478bd9Sstevel@tonic-gate 		 * set dma addrs into xfer_ctl struct (unbound addr (kernel
16857c478bd9Sstevel@tonic-gate 		 * virtual) is last component (descriptor))
16867c478bd9Sstevel@tonic-gate 		 */
16877c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_bound = dma_desc_bound;
16887c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_descp = dma_descp;
16897c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_buf	 = &wvp->dma_currentp->mem;
16907c478bd9Sstevel@tonic-gate 
16917c478bd9Sstevel@tonic-gate 		/* advance buffer ptr by pktsize in descriptor block */
16927c478bd9Sstevel@tonic-gate 		wvp->descriptor_block[wvp->descriptors - 1].data_addr +=
16937c478bd9Sstevel@tonic-gate 		    pktsize;
16947c478bd9Sstevel@tonic-gate 	}
16957c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit,
16967c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
16977c478bd9Sstevel@tonic-gate }
16987c478bd9Sstevel@tonic-gate 
16997c478bd9Sstevel@tonic-gate /*
17007c478bd9Sstevel@tonic-gate  * hci1394_bld_recv_buf_fill_desc()
17017c478bd9Sstevel@tonic-gate  *    Used to create the openHCI dma descriptor block(s) for a receive buf
17027c478bd9Sstevel@tonic-gate  *    in buffer fill mode.
17037c478bd9Sstevel@tonic-gate  */
17047c478bd9Sstevel@tonic-gate static void
17057c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_fill_desc(hci1394_comp_ixl_vars_t *wvp)
17067c478bd9Sstevel@tonic-gate {
17077c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xctlp;
17087c478bd9Sstevel@tonic-gate 	caddr_t			dma_descp;
17097c478bd9Sstevel@tonic-gate 	uint32_t		dma_desc_bound;
17107c478bd9Sstevel@tonic-gate 	uint32_t		wait_for_sync;
17117c478bd9Sstevel@tonic-gate 	ixl1394_xfer_buf_t	*local_ixl_cur_xfer_stp;
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_enter,
17147c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
17157c478bd9Sstevel@tonic-gate 
17167c478bd9Sstevel@tonic-gate 	local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp;
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate 	/* allocate an xfer_ctl struct including 1 xfer_ctl_dma structs */
17207c478bd9Sstevel@tonic-gate 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) {
17217c478bd9Sstevel@tonic-gate 
17227c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
17237c478bd9Sstevel@tonic-gate 
17247c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_bld_recv_buf_fill_desc_mem_alloc_fail,
17257c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
17267c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: xfer_ctl", tnf_opaque,
17277c478bd9Sstevel@tonic-gate 		    ixl_commandp, wvp->ixl_cur_xfer_stp);
17287c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
17297c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
17307c478bd9Sstevel@tonic-gate 		return;
17317c478bd9Sstevel@tonic-gate 	}
17327c478bd9Sstevel@tonic-gate 
17337c478bd9Sstevel@tonic-gate 	/*
17347c478bd9Sstevel@tonic-gate 	 * save xfer_ctl struct addr in compiler_privatep of
17357c478bd9Sstevel@tonic-gate 	 * current IXL xfer cmd
17367c478bd9Sstevel@tonic-gate 	 */
17377c478bd9Sstevel@tonic-gate 	local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
17387c478bd9Sstevel@tonic-gate 
17397c478bd9Sstevel@tonic-gate 	/*
17407c478bd9Sstevel@tonic-gate 	 * if enabled, set wait for sync flag in first descriptor of
17417c478bd9Sstevel@tonic-gate 	 * descriptor block
17427c478bd9Sstevel@tonic-gate 	 */
17437c478bd9Sstevel@tonic-gate 	if (wvp->ixl_setsyncwait_cnt > 0) {
17447c478bd9Sstevel@tonic-gate 		wvp->ixl_setsyncwait_cnt = 1;
17457c478bd9Sstevel@tonic-gate 		wait_for_sync = DESC_W_ENBL;
17467c478bd9Sstevel@tonic-gate 	} else {
17477c478bd9Sstevel@tonic-gate 		wait_for_sync = DESC_W_DSABL;
17487c478bd9Sstevel@tonic-gate 	}
17497c478bd9Sstevel@tonic-gate 
17507c478bd9Sstevel@tonic-gate 	/*
17517c478bd9Sstevel@tonic-gate 	 * create descriptor block for this buffer fill mode recv command which
17527c478bd9Sstevel@tonic-gate 	 * consists of one descriptor with xfer status enabled
17537c478bd9Sstevel@tonic-gate 	 */
17547c478bd9Sstevel@tonic-gate 	HCI1394_INIT_IR_BF_IMORE(&wvp->descriptor_block[wvp->descriptors],
17557c478bd9Sstevel@tonic-gate 	    DESC_INTR_DSABL, wait_for_sync, local_ixl_cur_xfer_stp->size);
17567c478bd9Sstevel@tonic-gate 
17577c478bd9Sstevel@tonic-gate 	wvp->descriptor_block[wvp->descriptors].data_addr =
17587c478bd9Sstevel@tonic-gate 	    local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr;
17597c478bd9Sstevel@tonic-gate 	wvp->descriptor_block[wvp->descriptors].branch = 0;
17607c478bd9Sstevel@tonic-gate 	wvp->descriptor_block[wvp->descriptors].status =
17617c478bd9Sstevel@tonic-gate 	    (local_ixl_cur_xfer_stp->size << DESC_ST_RESCOUNT_SHIFT) &
17627c478bd9Sstevel@tonic-gate 	    DESC_ST_RESCOUNT_MASK;
17637c478bd9Sstevel@tonic-gate 	wvp->descriptors++;
17647c478bd9Sstevel@tonic-gate 
17657c478bd9Sstevel@tonic-gate 	/* check and perform any required hci cache flush */
17667c478bd9Sstevel@tonic-gate 	if (hci1394_flush_end_desc_check(wvp, 0) != DDI_SUCCESS) {
17677c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
17687c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
17697c478bd9Sstevel@tonic-gate 
17707c478bd9Sstevel@tonic-gate 		/* wvp->dma_bld_error is set by above call */
17717c478bd9Sstevel@tonic-gate 		return;
17727c478bd9Sstevel@tonic-gate 	}
17737c478bd9Sstevel@tonic-gate 
17747c478bd9Sstevel@tonic-gate 	/* allocate and copy descriptor block to dma memory */
17757c478bd9Sstevel@tonic-gate 	if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound)
17767c478bd9Sstevel@tonic-gate 	    != DDI_SUCCESS) {
17777c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
17787c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
17797c478bd9Sstevel@tonic-gate 
17807c478bd9Sstevel@tonic-gate 		/* wvp->dma_bld_error is set by above call */
17817c478bd9Sstevel@tonic-gate 		return;
17827c478bd9Sstevel@tonic-gate 	}
17837c478bd9Sstevel@tonic-gate 
17847c478bd9Sstevel@tonic-gate 	/*
17857c478bd9Sstevel@tonic-gate 	 * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual)
17867c478bd9Sstevel@tonic-gate 	 * is last component.
17877c478bd9Sstevel@tonic-gate 	 */
17887c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_bound = dma_desc_bound;
17897c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_descp = dma_descp;
17907c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_buf	= &wvp->dma_currentp->mem;
17917c478bd9Sstevel@tonic-gate 
17927c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit,
17937c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
17947c478bd9Sstevel@tonic-gate }
17957c478bd9Sstevel@tonic-gate 
17967c478bd9Sstevel@tonic-gate /*
17977c478bd9Sstevel@tonic-gate  * hci1394_bld_xmit_pkt_desc()
17987c478bd9Sstevel@tonic-gate  *    Used to create the openHCI dma descriptor block(s) for a transmit packet.
17997c478bd9Sstevel@tonic-gate  */
18007c478bd9Sstevel@tonic-gate static void
18017c478bd9Sstevel@tonic-gate hci1394_bld_xmit_pkt_desc(hci1394_comp_ixl_vars_t *wvp)
18027c478bd9Sstevel@tonic-gate {
18037c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t *xctlp;
18047c478bd9Sstevel@tonic-gate 	hci1394_output_more_imm_t *wv_omi_descp; /* shorthand to local descrp */
18057c478bd9Sstevel@tonic-gate 	hci1394_desc_t	*wv_descp;	/* shorthand to local descriptor */
18067c478bd9Sstevel@tonic-gate 	caddr_t		dma_descp;	/* dma bound memory for descriptor */
18077c478bd9Sstevel@tonic-gate 	uint32_t	dma_desc_bound;
18087c478bd9Sstevel@tonic-gate 	uint32_t	ii;
18097c478bd9Sstevel@tonic-gate 
18107c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_enter,
18117c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
18127c478bd9Sstevel@tonic-gate 
18137c478bd9Sstevel@tonic-gate 	/*
18147c478bd9Sstevel@tonic-gate 	 * is error if number of descriptors to be built exceeds maximum
18157c478bd9Sstevel@tonic-gate 	 * descriptors allowed in a descriptor block. Add 2 for the overhead
18167c478bd9Sstevel@tonic-gate 	 * of the OMORE-Immediate.
18177c478bd9Sstevel@tonic-gate 	 */
18187c478bd9Sstevel@tonic-gate 	if ((wvp->descriptors + 2 + wvp->xfer_bufcnt) > HCI1394_DESC_MAX_Z) {
18197c478bd9Sstevel@tonic-gate 
18207c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO;
18217c478bd9Sstevel@tonic-gate 
18227c478bd9Sstevel@tonic-gate 		TNF_PROBE_3(hci1394_bld_xmit_pkt_desc_fragment_oflo_error,
18237c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
18247c478bd9Sstevel@tonic-gate 		    "IXL1394_EFRAGMENT_OFLO", tnf_opaque, ixl_commandp,
18257c478bd9Sstevel@tonic-gate 		    wvp->ixl_cur_xfer_stp, tnf_int, frag_count,
18267c478bd9Sstevel@tonic-gate 		    wvp->descriptors + 2 + wvp->xfer_bufcnt);
18277c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
18287c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
18297c478bd9Sstevel@tonic-gate 		return;
18307c478bd9Sstevel@tonic-gate 	}
18317c478bd9Sstevel@tonic-gate 
18327c478bd9Sstevel@tonic-gate 	/* is error if total packet length exceeds 0xFFFF */
18337c478bd9Sstevel@tonic-gate 	if (wvp->xfer_pktlen > 0xFFFF) {
18347c478bd9Sstevel@tonic-gate 
18357c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EPKTSIZE_MAX_OFLO;
18367c478bd9Sstevel@tonic-gate 
18377c478bd9Sstevel@tonic-gate 		TNF_PROBE_3(hci1394_bld_xmit_pkt_desc_packet_oflo_error,
18387c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
18397c478bd9Sstevel@tonic-gate 		    "IXL1394_EPKTSIZE_MAX_OFLO", tnf_opaque, ixl_commandp,
18407c478bd9Sstevel@tonic-gate 		    wvp->ixl_cur_xfer_stp, tnf_int, total_pktlen,
18417c478bd9Sstevel@tonic-gate 		    wvp->xfer_pktlen);
18427c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
18437c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
18447c478bd9Sstevel@tonic-gate 		return;
18457c478bd9Sstevel@tonic-gate 	}
18467c478bd9Sstevel@tonic-gate 
18477c478bd9Sstevel@tonic-gate 	/* allocate an xfer_ctl struct, including 1 xfer_ctl_dma struct */
18487c478bd9Sstevel@tonic-gate 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) {
18497c478bd9Sstevel@tonic-gate 
18507c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
18517c478bd9Sstevel@tonic-gate 
18527c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_bld_xmit_pkt_desc_mem_alloc_fail,
18537c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
18547c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
18557c478bd9Sstevel@tonic-gate 		    ixl_commandp, wvp->ixl_cur_cmdp);
18567c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
18577c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
18587c478bd9Sstevel@tonic-gate 		return;
18597c478bd9Sstevel@tonic-gate 	}
18607c478bd9Sstevel@tonic-gate 
18617c478bd9Sstevel@tonic-gate 	/*
18627c478bd9Sstevel@tonic-gate 	 * save xfer_ctl struct addr in compiler_privatep of
18637c478bd9Sstevel@tonic-gate 	 * current IXL xfer cmd
18647c478bd9Sstevel@tonic-gate 	 */
18657c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
18667c478bd9Sstevel@tonic-gate 
18677c478bd9Sstevel@tonic-gate 	/* generate values for the xmit pkt hdrs */
18687c478bd9Sstevel@tonic-gate 	hci1394_set_xmit_pkt_hdr(wvp);
18697c478bd9Sstevel@tonic-gate 
18707c478bd9Sstevel@tonic-gate 	/*
18717c478bd9Sstevel@tonic-gate 	 * xmit pkt starts with an output more immediate,
18727c478bd9Sstevel@tonic-gate 	 * a double sized hci1394_desc
18737c478bd9Sstevel@tonic-gate 	 */
18747c478bd9Sstevel@tonic-gate 	wv_omi_descp = (hci1394_output_more_imm_t *)
18757c478bd9Sstevel@tonic-gate 	    (&wvp->descriptor_block[wvp->descriptors]);
18767c478bd9Sstevel@tonic-gate 	HCI1394_INIT_IT_OMORE_IMM(wv_omi_descp);
18777c478bd9Sstevel@tonic-gate 
18787c478bd9Sstevel@tonic-gate 	wv_omi_descp->data_addr = 0;
18797c478bd9Sstevel@tonic-gate 	wv_omi_descp->branch = 0;
18807c478bd9Sstevel@tonic-gate 	wv_omi_descp->status = 0;
18817c478bd9Sstevel@tonic-gate 	wv_omi_descp->q1 = wvp->xmit_pkthdr1;
18827c478bd9Sstevel@tonic-gate 	wv_omi_descp->q2 = wvp->xmit_pkthdr2;
18837c478bd9Sstevel@tonic-gate 	wv_omi_descp->q3 = 0;
18847c478bd9Sstevel@tonic-gate 	wv_omi_descp->q4 = 0;
18857c478bd9Sstevel@tonic-gate 
18867c478bd9Sstevel@tonic-gate 	wvp->descriptors += 2;
18877c478bd9Sstevel@tonic-gate 
18887c478bd9Sstevel@tonic-gate 	/*
18897c478bd9Sstevel@tonic-gate 	 * create the required output more hci1394_desc descriptor, then create
18907c478bd9Sstevel@tonic-gate 	 * an output last hci1394_desc descriptor with xfer status enabled
18917c478bd9Sstevel@tonic-gate 	 */
18927c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < wvp->xfer_bufcnt; ii++) {
18937c478bd9Sstevel@tonic-gate 		wv_descp = &wvp->descriptor_block[wvp->descriptors];
18947c478bd9Sstevel@tonic-gate 
18957c478bd9Sstevel@tonic-gate 		if (ii == (wvp->xfer_bufcnt - 1)) {
18967c478bd9Sstevel@tonic-gate 			HCI1394_INIT_IT_OLAST(wv_descp, DESC_HDR_STAT_ENBL,
18977c478bd9Sstevel@tonic-gate 			    DESC_INTR_DSABL, wvp->xfer_size[ii]);
18987c478bd9Sstevel@tonic-gate 		} else {
18997c478bd9Sstevel@tonic-gate 			HCI1394_INIT_IT_OMORE(wv_descp, wvp->xfer_size[ii]);
19007c478bd9Sstevel@tonic-gate 		}
19017c478bd9Sstevel@tonic-gate 		wv_descp->data_addr = wvp->xfer_bufp[ii];
19027c478bd9Sstevel@tonic-gate 		wv_descp->branch = 0;
19037c478bd9Sstevel@tonic-gate 		wv_descp->status = 0;
19047c478bd9Sstevel@tonic-gate 		wvp->descriptors++;
19057c478bd9Sstevel@tonic-gate 	}
19067c478bd9Sstevel@tonic-gate 
19077c478bd9Sstevel@tonic-gate 	/* allocate and copy descriptor block to dma memory */
19087c478bd9Sstevel@tonic-gate 	if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound) !=
19097c478bd9Sstevel@tonic-gate 	    DDI_SUCCESS) {
19107c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
19117c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
19127c478bd9Sstevel@tonic-gate 
19137c478bd9Sstevel@tonic-gate 		/* wvp->dma_bld_error is set by above call */
19147c478bd9Sstevel@tonic-gate 		return;
19157c478bd9Sstevel@tonic-gate 	}
19167c478bd9Sstevel@tonic-gate 
19177c478bd9Sstevel@tonic-gate 	/*
19187c478bd9Sstevel@tonic-gate 	 * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual)
19197c478bd9Sstevel@tonic-gate 	 * is last component (descriptor))
19207c478bd9Sstevel@tonic-gate 	 */
19217c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_bound = dma_desc_bound;
19227c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_descp =
19237c478bd9Sstevel@tonic-gate 	    dma_descp + (wvp->xfer_bufcnt + 1) * sizeof (hci1394_desc_t);
19247c478bd9Sstevel@tonic-gate 	xctlp->dma[0].dma_buf	= &wvp->dma_currentp->mem;
19257c478bd9Sstevel@tonic-gate 
19267c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit,
19277c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
19287c478bd9Sstevel@tonic-gate }
19297c478bd9Sstevel@tonic-gate 
19307c478bd9Sstevel@tonic-gate /*
19317c478bd9Sstevel@tonic-gate  * hci1394_bld_xmit_buf_desc()
19327c478bd9Sstevel@tonic-gate  *    Used to create the openHCI dma descriptor blocks for a transmit buffer.
19337c478bd9Sstevel@tonic-gate  */
19347c478bd9Sstevel@tonic-gate static void
19357c478bd9Sstevel@tonic-gate hci1394_bld_xmit_buf_desc(hci1394_comp_ixl_vars_t *wvp)
19367c478bd9Sstevel@tonic-gate {
19377c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xctlp;
19387c478bd9Sstevel@tonic-gate 	ixl1394_xfer_buf_t	*local_ixl_cur_xfer_stp;
19397c478bd9Sstevel@tonic-gate 	hci1394_output_more_imm_t *wv_omi_descp; /* shorthand to local descrp */
19407c478bd9Sstevel@tonic-gate 	hci1394_desc_t	*wv_descp;	/* shorthand to local descriptor */
19417c478bd9Sstevel@tonic-gate 	caddr_t		dma_descp;
19427c478bd9Sstevel@tonic-gate 	uint32_t	dma_desc_bound;
19437c478bd9Sstevel@tonic-gate 	uint32_t	pktsize;
19447c478bd9Sstevel@tonic-gate 	uint32_t	pktcnt;
19457c478bd9Sstevel@tonic-gate 	uint32_t	ii;
19467c478bd9Sstevel@tonic-gate 
19477c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_enter,
19487c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
19497c478bd9Sstevel@tonic-gate 
19507c478bd9Sstevel@tonic-gate 	local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp;
19517c478bd9Sstevel@tonic-gate 
19527c478bd9Sstevel@tonic-gate 	/* determine number and size of pkt desc blocks to create */
19537c478bd9Sstevel@tonic-gate 	pktsize = local_ixl_cur_xfer_stp->pkt_size;
19547c478bd9Sstevel@tonic-gate 	pktcnt = local_ixl_cur_xfer_stp->size / pktsize;
19557c478bd9Sstevel@tonic-gate 
19567c478bd9Sstevel@tonic-gate 	/* allocate an xfer_ctl struct including pktcnt xfer_ctl_dma structs */
19577c478bd9Sstevel@tonic-gate 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, pktcnt)) == NULL) {
19587c478bd9Sstevel@tonic-gate 
19597c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
19607c478bd9Sstevel@tonic-gate 
19617c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_bld_xmit_buf_desc_mem_alloc_fail,
19627c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
19637c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
19647c478bd9Sstevel@tonic-gate 		    ixl_commandp, wvp->ixl_cur_cmdp);
19657c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit,
19667c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
19677c478bd9Sstevel@tonic-gate 		return;
19687c478bd9Sstevel@tonic-gate 	}
19697c478bd9Sstevel@tonic-gate 
19707c478bd9Sstevel@tonic-gate 	/*
19717c478bd9Sstevel@tonic-gate 	 * save xfer_ctl struct addr in compiler_privatep of
19727c478bd9Sstevel@tonic-gate 	 * current IXL xfer cmd
19737c478bd9Sstevel@tonic-gate 	 */
19747c478bd9Sstevel@tonic-gate 	local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
19757c478bd9Sstevel@tonic-gate 
19767c478bd9Sstevel@tonic-gate 	/* generate values for the xmit pkt hdrs */
19777c478bd9Sstevel@tonic-gate 	wvp->xfer_pktlen = pktsize;
19787c478bd9Sstevel@tonic-gate 	hci1394_set_xmit_pkt_hdr(wvp);
19797c478bd9Sstevel@tonic-gate 
19807c478bd9Sstevel@tonic-gate 	/*
19817c478bd9Sstevel@tonic-gate 	 * xmit pkt starts with an output more immediate,
19827c478bd9Sstevel@tonic-gate 	 * a double sized hci1394_desc
19837c478bd9Sstevel@tonic-gate 	 */
19847c478bd9Sstevel@tonic-gate 	wv_omi_descp = (hci1394_output_more_imm_t *)
19857c478bd9Sstevel@tonic-gate 	    &wvp->descriptor_block[wvp->descriptors];
19867c478bd9Sstevel@tonic-gate 
19877c478bd9Sstevel@tonic-gate 	HCI1394_INIT_IT_OMORE_IMM(wv_omi_descp);
19887c478bd9Sstevel@tonic-gate 
19897c478bd9Sstevel@tonic-gate 	wv_omi_descp->data_addr = 0;
19907c478bd9Sstevel@tonic-gate 	wv_omi_descp->branch = 0;
19917c478bd9Sstevel@tonic-gate 	wv_omi_descp->status = 0;
19927c478bd9Sstevel@tonic-gate 	wv_omi_descp->q1 = wvp->xmit_pkthdr1;
19937c478bd9Sstevel@tonic-gate 	wv_omi_descp->q2 = wvp->xmit_pkthdr2;
19947c478bd9Sstevel@tonic-gate 	wv_omi_descp->q3 = 0;
19957c478bd9Sstevel@tonic-gate 	wv_omi_descp->q4 = 0;
19967c478bd9Sstevel@tonic-gate 
19977c478bd9Sstevel@tonic-gate 	wvp->descriptors += 2;
19987c478bd9Sstevel@tonic-gate 
19997c478bd9Sstevel@tonic-gate 	/* follow with a single output last descriptor w/status enabled */
20007c478bd9Sstevel@tonic-gate 	wv_descp = &wvp->descriptor_block[wvp->descriptors];
20017c478bd9Sstevel@tonic-gate 	HCI1394_INIT_IT_OLAST(wv_descp, DESC_HDR_STAT_ENBL, DESC_INTR_DSABL,
20027c478bd9Sstevel@tonic-gate 	    pktsize);
20037c478bd9Sstevel@tonic-gate 	wv_descp->data_addr = local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr;
20047c478bd9Sstevel@tonic-gate 	wv_descp->branch = 0;
20057c478bd9Sstevel@tonic-gate 	wv_descp->status = 0;
20067c478bd9Sstevel@tonic-gate 	wvp->descriptors++;
20077c478bd9Sstevel@tonic-gate 
20087c478bd9Sstevel@tonic-gate 	/*
20097c478bd9Sstevel@tonic-gate 	 * generate as many contiguous descriptor blocks as there are
20107c478bd9Sstevel@tonic-gate 	 * xmit packets
20117c478bd9Sstevel@tonic-gate 	 */
20127c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < pktcnt; ii++) {
20137c478bd9Sstevel@tonic-gate 
20147c478bd9Sstevel@tonic-gate 		/* if about to create last descriptor block */
20157c478bd9Sstevel@tonic-gate 		if (ii == (pktcnt - 1)) {
20167c478bd9Sstevel@tonic-gate 			/* check and perform any required hci cache flush */
20177c478bd9Sstevel@tonic-gate 			if (hci1394_flush_end_desc_check(wvp, ii) !=
20187c478bd9Sstevel@tonic-gate 			    DDI_SUCCESS) {
20197c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
20207c478bd9Sstevel@tonic-gate 				    hci1394_bld_xmit_buf_desc_exit,
20217c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
20227c478bd9Sstevel@tonic-gate 
20237c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
20247c478bd9Sstevel@tonic-gate 				return;
20257c478bd9Sstevel@tonic-gate 			}
20267c478bd9Sstevel@tonic-gate 		}
20277c478bd9Sstevel@tonic-gate 
20287c478bd9Sstevel@tonic-gate 		/* allocate and copy descriptor block to dma memory */
20297c478bd9Sstevel@tonic-gate 		if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp,
20307c478bd9Sstevel@tonic-gate 		    &dma_desc_bound) != DDI_SUCCESS) {
20317c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit,
20327c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate 			/* wvp->dma_bld_error is set by above call */
20357c478bd9Sstevel@tonic-gate 			return;
20367c478bd9Sstevel@tonic-gate 		}
20377c478bd9Sstevel@tonic-gate 
20387c478bd9Sstevel@tonic-gate 		/*
20397c478bd9Sstevel@tonic-gate 		 * set dma addrs into xfer_ctl structure (unbound addr
20407c478bd9Sstevel@tonic-gate 		 * (kernel virtual) is last component (descriptor))
20417c478bd9Sstevel@tonic-gate 		 */
20427c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_bound = dma_desc_bound;
20437c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_descp = dma_descp + 2 *
20447c478bd9Sstevel@tonic-gate 		    sizeof (hci1394_desc_t);
20457c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_buf	 = &wvp->dma_currentp->mem;
20467c478bd9Sstevel@tonic-gate 
20477c478bd9Sstevel@tonic-gate 		/* advance buffer ptr by pktsize in descriptor block */
20487c478bd9Sstevel@tonic-gate 		wvp->descriptor_block[wvp->descriptors - 1].data_addr +=
20497c478bd9Sstevel@tonic-gate 		    pktsize;
20507c478bd9Sstevel@tonic-gate 	}
20517c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit,
20527c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
20537c478bd9Sstevel@tonic-gate }
20547c478bd9Sstevel@tonic-gate 
20557c478bd9Sstevel@tonic-gate /*
20567c478bd9Sstevel@tonic-gate  * hci1394_bld_xmit_hdronly_nopkt_desc()
20577c478bd9Sstevel@tonic-gate  *    Used to create the openHCI dma descriptor blocks for transmitting
20587c478bd9Sstevel@tonic-gate  *    a packet consisting of an isochronous header with no data payload,
20597c478bd9Sstevel@tonic-gate  *    or for not sending a packet at all for a cycle.
20607c478bd9Sstevel@tonic-gate  *
20617c478bd9Sstevel@tonic-gate  *    A Store_Value openhci descriptor is built at the start of each
20627c478bd9Sstevel@tonic-gate  *    IXL1394_OP_SEND_HDR_ONLY and IXL1394_OP_SEND_NO_PKT command's dma
20637c478bd9Sstevel@tonic-gate  *    descriptor block (to allow for skip cycle specification and set skipmode
20647c478bd9Sstevel@tonic-gate  *    processing for these commands).
20657c478bd9Sstevel@tonic-gate  */
20667c478bd9Sstevel@tonic-gate static void
20677c478bd9Sstevel@tonic-gate hci1394_bld_xmit_hdronly_nopkt_desc(hci1394_comp_ixl_vars_t *wvp)
20687c478bd9Sstevel@tonic-gate {
20697c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xctlp;
20707c478bd9Sstevel@tonic-gate 	hci1394_output_last_t	*wv_ol_descp; /* shorthand to local descrp */
20717c478bd9Sstevel@tonic-gate 	hci1394_output_last_imm_t *wv_oli_descp; /* shorthand to local descrp */
20727c478bd9Sstevel@tonic-gate 	caddr_t		dma_descp;
20737c478bd9Sstevel@tonic-gate 	uint32_t	dma_desc_bound;
20747c478bd9Sstevel@tonic-gate 	uint32_t	repcnt;
20757c478bd9Sstevel@tonic-gate 	uint32_t	ii;
20767c478bd9Sstevel@tonic-gate 
20777c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_enter,
20787c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
20797c478bd9Sstevel@tonic-gate 
20807c478bd9Sstevel@tonic-gate 	/* determine # of instances of output hdronly/nopkt to generate */
20817c478bd9Sstevel@tonic-gate 	repcnt = ((ixl1394_xmit_special_t *)wvp->ixl_cur_xfer_stp)->count;
20827c478bd9Sstevel@tonic-gate 
20837c478bd9Sstevel@tonic-gate 	/*
20847c478bd9Sstevel@tonic-gate 	 * allocate an xfer_ctl structure which includes repcnt
20857c478bd9Sstevel@tonic-gate 	 * xfer_ctl_dma structs
20867c478bd9Sstevel@tonic-gate 	 */
20877c478bd9Sstevel@tonic-gate 	if ((xctlp = hci1394_alloc_xfer_ctl(wvp, repcnt)) == NULL) {
20887c478bd9Sstevel@tonic-gate 
20897c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
20907c478bd9Sstevel@tonic-gate 
20917c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_bld_xmit_hdronly_nopkt_desc_mem_alloc_fail,
20927c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
20937c478bd9Sstevel@tonic-gate 		    "IXL EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque,
20947c478bd9Sstevel@tonic-gate 		    ixl_commandp, wvp->ixl_cur_cmdp);
20957c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_exit,
20967c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
20977c478bd9Sstevel@tonic-gate 		return;
20987c478bd9Sstevel@tonic-gate 	}
20997c478bd9Sstevel@tonic-gate 
21007c478bd9Sstevel@tonic-gate 	/*
21017c478bd9Sstevel@tonic-gate 	 * save xfer_ctl struct addr in compiler_privatep of
21027c478bd9Sstevel@tonic-gate 	 * current IXL xfer command
21037c478bd9Sstevel@tonic-gate 	 */
21047c478bd9Sstevel@tonic-gate 	wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp;
21057c478bd9Sstevel@tonic-gate 
21067c478bd9Sstevel@tonic-gate 	/*
21077c478bd9Sstevel@tonic-gate 	 * create a storevalue descriptor
21087c478bd9Sstevel@tonic-gate 	 * (will be used for skip vs jump processing)
21097c478bd9Sstevel@tonic-gate 	 */
21107c478bd9Sstevel@tonic-gate 	hci1394_set_xmit_storevalue_desc(wvp);
21117c478bd9Sstevel@tonic-gate 
21127c478bd9Sstevel@tonic-gate 	/*
21137c478bd9Sstevel@tonic-gate 	 * processing now based on opcode:
21147c478bd9Sstevel@tonic-gate 	 * IXL1394_OP_SEND_HDR_ONLY or IXL1394_OP_SEND_NO_PKT
21157c478bd9Sstevel@tonic-gate 	 */
21167c478bd9Sstevel@tonic-gate 	if ((wvp->ixl_cur_xfer_stp->ixl_opcode & ~IXL1394_OPF_UPDATE) ==
21177c478bd9Sstevel@tonic-gate 	    IXL1394_OP_SEND_HDR_ONLY) {
21187c478bd9Sstevel@tonic-gate 
21197c478bd9Sstevel@tonic-gate 		/* for header only, generate values for the xmit pkt hdrs */
21207c478bd9Sstevel@tonic-gate 		hci1394_set_xmit_pkt_hdr(wvp);
21217c478bd9Sstevel@tonic-gate 
21227c478bd9Sstevel@tonic-gate 		/*
21237c478bd9Sstevel@tonic-gate 		 * create an output last immediate (double sized) descriptor
21247c478bd9Sstevel@tonic-gate 		 * xfer status enabled
21257c478bd9Sstevel@tonic-gate 		 */
21267c478bd9Sstevel@tonic-gate 		wv_oli_descp = (hci1394_output_last_imm_t *)
21277c478bd9Sstevel@tonic-gate 		    &wvp->descriptor_block[wvp->descriptors];
21287c478bd9Sstevel@tonic-gate 
21297c478bd9Sstevel@tonic-gate 		HCI1394_INIT_IT_OLAST_IMM(wv_oli_descp, DESC_HDR_STAT_ENBL,
21307c478bd9Sstevel@tonic-gate 		    DESC_INTR_DSABL);
21317c478bd9Sstevel@tonic-gate 
21327c478bd9Sstevel@tonic-gate 		wv_oli_descp->data_addr = 0;
21337c478bd9Sstevel@tonic-gate 		wv_oli_descp->branch = 0;
21347c478bd9Sstevel@tonic-gate 		wv_oli_descp->status = 0;
21357c478bd9Sstevel@tonic-gate 		wv_oli_descp->q1 = wvp->xmit_pkthdr1;
21367c478bd9Sstevel@tonic-gate 		wv_oli_descp->q2 = wvp->xmit_pkthdr2;
21377c478bd9Sstevel@tonic-gate 		wv_oli_descp->q3 = 0;
21387c478bd9Sstevel@tonic-gate 		wv_oli_descp->q4 = 0;
21397c478bd9Sstevel@tonic-gate 		wvp->descriptors += 2;
21407c478bd9Sstevel@tonic-gate 	} else {
21417c478bd9Sstevel@tonic-gate 		/*
21427c478bd9Sstevel@tonic-gate 		 * for skip cycle, create a single output last descriptor
21437c478bd9Sstevel@tonic-gate 		 * with xfer status enabled
21447c478bd9Sstevel@tonic-gate 		 */
21457c478bd9Sstevel@tonic-gate 		wv_ol_descp = &wvp->descriptor_block[wvp->descriptors];
21467c478bd9Sstevel@tonic-gate 		HCI1394_INIT_IT_OLAST(wv_ol_descp, DESC_HDR_STAT_ENBL,
21477c478bd9Sstevel@tonic-gate 		    DESC_INTR_DSABL, 0);
21487c478bd9Sstevel@tonic-gate 		wv_ol_descp->data_addr = 0;
21497c478bd9Sstevel@tonic-gate 		wv_ol_descp->branch = 0;
21507c478bd9Sstevel@tonic-gate 		wv_ol_descp->status = 0;
21517c478bd9Sstevel@tonic-gate 		wvp->descriptors++;
21527c478bd9Sstevel@tonic-gate 	}
21537c478bd9Sstevel@tonic-gate 
21547c478bd9Sstevel@tonic-gate 	/*
21557c478bd9Sstevel@tonic-gate 	 * generate as many contiguous descriptor blocks as repeat count
21567c478bd9Sstevel@tonic-gate 	 * indicates
21577c478bd9Sstevel@tonic-gate 	 */
21587c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < repcnt; ii++) {
21597c478bd9Sstevel@tonic-gate 
21607c478bd9Sstevel@tonic-gate 		/* if about to create last descriptor block */
21617c478bd9Sstevel@tonic-gate 		if (ii == (repcnt - 1)) {
21627c478bd9Sstevel@tonic-gate 			/* check and perform any required hci cache flush */
21637c478bd9Sstevel@tonic-gate 			if (hci1394_flush_end_desc_check(wvp, ii) !=
21647c478bd9Sstevel@tonic-gate 			    DDI_SUCCESS) {
21657c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
21667c478bd9Sstevel@tonic-gate 				    hci1394_bld_xmit_hdronly_nopkt_desc_exit,
21677c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
21687c478bd9Sstevel@tonic-gate 
21697c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
21707c478bd9Sstevel@tonic-gate 				return;
21717c478bd9Sstevel@tonic-gate 			}
21727c478bd9Sstevel@tonic-gate 		}
21737c478bd9Sstevel@tonic-gate 
21747c478bd9Sstevel@tonic-gate 		/* allocate and copy descriptor block to dma memory */
21757c478bd9Sstevel@tonic-gate 		if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp,
21767c478bd9Sstevel@tonic-gate 		    &dma_desc_bound) != DDI_SUCCESS) {
21777c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(
21787c478bd9Sstevel@tonic-gate 			    hci1394_bld_xmit_hdronly_nopkt_desc_exit,
21797c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
21807c478bd9Sstevel@tonic-gate 
21817c478bd9Sstevel@tonic-gate 			/* wvp->dma_bld_error is set by above call */
21827c478bd9Sstevel@tonic-gate 			return;
21837c478bd9Sstevel@tonic-gate 		}
21847c478bd9Sstevel@tonic-gate 
21857c478bd9Sstevel@tonic-gate 		/*
21867c478bd9Sstevel@tonic-gate 		 * set dma addrs into xfer_ctl structure (unbound addr
21877c478bd9Sstevel@tonic-gate 		 * (kernel virtual) is last component (descriptor)
21887c478bd9Sstevel@tonic-gate 		 */
21897c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_bound = dma_desc_bound;
21907c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_descp = dma_descp + sizeof (hci1394_desc_t);
21917c478bd9Sstevel@tonic-gate 		xctlp->dma[ii].dma_buf	 = &wvp->dma_currentp->mem;
21927c478bd9Sstevel@tonic-gate 	}
21937c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_exit,
21947c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
21957c478bd9Sstevel@tonic-gate }
21967c478bd9Sstevel@tonic-gate 
21977c478bd9Sstevel@tonic-gate /*
21987c478bd9Sstevel@tonic-gate  * hci1394_bld_dma_mem_desc_blk()
21997c478bd9Sstevel@tonic-gate  *    Used to put a given OpenHCI descriptor block into dma bound memory.
22007c478bd9Sstevel@tonic-gate  */
22017c478bd9Sstevel@tonic-gate static int
22027c478bd9Sstevel@tonic-gate hci1394_bld_dma_mem_desc_blk(hci1394_comp_ixl_vars_t *wvp, caddr_t *dma_descpp,
22037c478bd9Sstevel@tonic-gate     uint32_t *dma_desc_bound)
22047c478bd9Sstevel@tonic-gate {
22057c478bd9Sstevel@tonic-gate 	uint32_t	dma_bound;
22067c478bd9Sstevel@tonic-gate 
22077c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_enter,
22087c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
22097c478bd9Sstevel@tonic-gate 
22107c478bd9Sstevel@tonic-gate 	/* set internal error if no descriptor blocks to build */
22117c478bd9Sstevel@tonic-gate 	if (wvp->descriptors == 0) {
22127c478bd9Sstevel@tonic-gate 
22137c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR;
22147c478bd9Sstevel@tonic-gate 
22157c478bd9Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_bld_dma_mem_desc_blk_error,
22167c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
22177c478bd9Sstevel@tonic-gate 		    "IXL1394_INTERNAL_ERROR: no descriptors to build");
22187c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit,
22197c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
22207c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
22217c478bd9Sstevel@tonic-gate 	}
22227c478bd9Sstevel@tonic-gate 
22237c478bd9Sstevel@tonic-gate 	/* allocate dma memory and move this descriptor block to it */
22247c478bd9Sstevel@tonic-gate 	*dma_descpp = (caddr_t)hci1394_alloc_dma_mem(wvp, wvp->descriptors *
22257c478bd9Sstevel@tonic-gate 	    sizeof (hci1394_desc_t), &dma_bound);
22267c478bd9Sstevel@tonic-gate 
22277c478bd9Sstevel@tonic-gate 	if (*dma_descpp == NULL) {
22287c478bd9Sstevel@tonic-gate 
22297c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
22307c478bd9Sstevel@tonic-gate 
22317c478bd9Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_bld_dma_mem_desc_blk_fail,
22327c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
22337c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: for descriptors");
22347c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit,
22357c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
22367c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
22377c478bd9Sstevel@tonic-gate 	}
22387c478bd9Sstevel@tonic-gate #ifdef _KERNEL
22397c478bd9Sstevel@tonic-gate 	ddi_rep_put32(wvp->dma_currentp->mem.bi_handle,
22407c478bd9Sstevel@tonic-gate 	    (uint_t *)wvp->descriptor_block, (uint_t *)*dma_descpp,
22417c478bd9Sstevel@tonic-gate 	    wvp->descriptors * (sizeof (hci1394_desc_t) >> 2),
22427c478bd9Sstevel@tonic-gate 	    DDI_DEV_AUTOINCR);
22437c478bd9Sstevel@tonic-gate #else
22447c478bd9Sstevel@tonic-gate 	bcopy(wvp->descriptor_block, *dma_descpp,
22457c478bd9Sstevel@tonic-gate 	    wvp->descriptors * sizeof (hci1394_desc_t));
22467c478bd9Sstevel@tonic-gate #endif
22477c478bd9Sstevel@tonic-gate 	/*
22487c478bd9Sstevel@tonic-gate 	 * convert allocated block's memory address to bus address space
22497c478bd9Sstevel@tonic-gate 	 * include properly set Z bits (descriptor count).
22507c478bd9Sstevel@tonic-gate 	 */
22517c478bd9Sstevel@tonic-gate 	*dma_desc_bound = (dma_bound & ~DESC_Z_MASK) | wvp->descriptors;
22527c478bd9Sstevel@tonic-gate 
22537c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit,
22547c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
22557c478bd9Sstevel@tonic-gate 
22567c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
22577c478bd9Sstevel@tonic-gate }
22587c478bd9Sstevel@tonic-gate 
22597c478bd9Sstevel@tonic-gate /*
22607c478bd9Sstevel@tonic-gate  * hci1394_set_xmit_pkt_hdr()
22617c478bd9Sstevel@tonic-gate  *    Compose the 2 quadlets for the xmit packet header.
22627c478bd9Sstevel@tonic-gate  */
22637c478bd9Sstevel@tonic-gate static void
22647c478bd9Sstevel@tonic-gate hci1394_set_xmit_pkt_hdr(hci1394_comp_ixl_vars_t *wvp)
22657c478bd9Sstevel@tonic-gate {
22667c478bd9Sstevel@tonic-gate 	uint16_t tag;
22677c478bd9Sstevel@tonic-gate 	uint16_t sync;
22687c478bd9Sstevel@tonic-gate 
22697c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_pkt_hdr_enter,
22707c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
22717c478bd9Sstevel@tonic-gate 
22727c478bd9Sstevel@tonic-gate 	/*
22737c478bd9Sstevel@tonic-gate 	 * choose tag and sync bits for header either from default values or
22747c478bd9Sstevel@tonic-gate 	 * from currently active set tag and sync IXL command
22757c478bd9Sstevel@tonic-gate 	 * (clear command after use)
22767c478bd9Sstevel@tonic-gate 	 */
22777c478bd9Sstevel@tonic-gate 	if (wvp->ixl_settagsync_cmdp == NULL) {
22787c478bd9Sstevel@tonic-gate 		tag = wvp->default_tag;
22797c478bd9Sstevel@tonic-gate 		sync = wvp->default_sync;
22807c478bd9Sstevel@tonic-gate 	} else {
22817c478bd9Sstevel@tonic-gate 		tag = wvp->ixl_settagsync_cmdp->tag;
22827c478bd9Sstevel@tonic-gate 		sync = wvp->ixl_settagsync_cmdp->sync;
22837c478bd9Sstevel@tonic-gate 		wvp->ixl_settagsync_cmdp = NULL;
22847c478bd9Sstevel@tonic-gate 	}
22857c478bd9Sstevel@tonic-gate 	tag &= (DESC_PKT_TAG_MASK >> DESC_PKT_TAG_SHIFT);
22867c478bd9Sstevel@tonic-gate 	sync &= (DESC_PKT_SY_MASK >> DESC_PKT_SY_SHIFT);
22877c478bd9Sstevel@tonic-gate 
22887c478bd9Sstevel@tonic-gate 	/*
22897c478bd9Sstevel@tonic-gate 	 * build xmit pkt header -
22907c478bd9Sstevel@tonic-gate 	 * hdr1 has speed, tag, channel number and sync bits
22917c478bd9Sstevel@tonic-gate 	 * hdr2 has the packet length.
22927c478bd9Sstevel@tonic-gate 	 */
22937c478bd9Sstevel@tonic-gate 	wvp->xmit_pkthdr1 = (wvp->ctxtp->isospd << DESC_PKT_SPD_SHIFT) |
22947c478bd9Sstevel@tonic-gate 	    (tag << DESC_PKT_TAG_SHIFT) | (wvp->ctxtp->isochan <<
22957c478bd9Sstevel@tonic-gate 	    DESC_PKT_CHAN_SHIFT) | (IEEE1394_TCODE_ISOCH <<
22967c478bd9Sstevel@tonic-gate 	    DESC_PKT_TCODE_SHIFT) | (sync << DESC_PKT_SY_SHIFT);
22977c478bd9Sstevel@tonic-gate 
22987c478bd9Sstevel@tonic-gate 	wvp->xmit_pkthdr2 = wvp->xfer_pktlen << DESC_PKT_DATALEN_SHIFT;
22997c478bd9Sstevel@tonic-gate 
23007c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_pkt_hdr_exit,
23017c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
23027c478bd9Sstevel@tonic-gate }
23037c478bd9Sstevel@tonic-gate 
23047c478bd9Sstevel@tonic-gate /*
23057c478bd9Sstevel@tonic-gate  * hci1394_set_xmit_skip_mode()
23067c478bd9Sstevel@tonic-gate  *    Set current skip mode from default or from currently active command.
23077c478bd9Sstevel@tonic-gate  *    If non-default skip mode command's skip mode is skip to label, find
23087c478bd9Sstevel@tonic-gate  *    and set xfer start IXL command which follows skip to label into
23097c478bd9Sstevel@tonic-gate  *    compiler_privatep of set skipmode IXL command.
23107c478bd9Sstevel@tonic-gate  */
23117c478bd9Sstevel@tonic-gate static void
23127c478bd9Sstevel@tonic-gate hci1394_set_xmit_skip_mode(hci1394_comp_ixl_vars_t *wvp)
23137c478bd9Sstevel@tonic-gate {
23147c478bd9Sstevel@tonic-gate 	int err;
23157c478bd9Sstevel@tonic-gate 
23167c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_skip_mode_enter,
23177c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
23187c478bd9Sstevel@tonic-gate 
23197c478bd9Sstevel@tonic-gate 	if (wvp->ixl_setskipmode_cmdp == NULL) {
23207c478bd9Sstevel@tonic-gate 		wvp->skipmode = wvp->default_skipmode;
23217c478bd9Sstevel@tonic-gate 		wvp->skiplabelp = wvp->default_skiplabelp;
23227c478bd9Sstevel@tonic-gate 		wvp->skipxferp = wvp->default_skipxferp;
23237c478bd9Sstevel@tonic-gate 	} else {
23247c478bd9Sstevel@tonic-gate 		wvp->skipmode = wvp->ixl_setskipmode_cmdp->skipmode;
23257c478bd9Sstevel@tonic-gate 		wvp->skiplabelp = wvp->ixl_setskipmode_cmdp->label;
23267c478bd9Sstevel@tonic-gate 		wvp->skipxferp = NULL;
23277c478bd9Sstevel@tonic-gate 		if (wvp->skipmode == IXL1394_SKIP_TO_LABEL) {
23287c478bd9Sstevel@tonic-gate 			err = hci1394_ixl_find_next_exec_xfer(wvp->skiplabelp,
23297c478bd9Sstevel@tonic-gate 			    NULL, &wvp->skipxferp);
23307c478bd9Sstevel@tonic-gate 			if (err == DDI_FAILURE) {
23317c478bd9Sstevel@tonic-gate 				TNF_PROBE_2(hci1394_set_xmit_skip_mode_error,
23327c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
23337c478bd9Sstevel@tonic-gate 				    errmsg, "IXL1394_ENO_DATA_PKTS: "
23347c478bd9Sstevel@tonic-gate 				    "label<->jump loop detected for skiplabel "
23357c478bd9Sstevel@tonic-gate 				    "w/no xfers", tnf_opaque, setskip_cmdp,
23367c478bd9Sstevel@tonic-gate 				    wvp->ixl_setskipmode_cmdp);
23377c478bd9Sstevel@tonic-gate 				wvp->skipxferp = NULL;
23387c478bd9Sstevel@tonic-gate 				wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS;
23397c478bd9Sstevel@tonic-gate 			}
23407c478bd9Sstevel@tonic-gate 		}
23417c478bd9Sstevel@tonic-gate 		wvp->ixl_setskipmode_cmdp->compiler_privatep =
23427c478bd9Sstevel@tonic-gate 		    (void *)wvp->skipxferp;
23437c478bd9Sstevel@tonic-gate 	}
23447c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_skip_mode_exit,
23457c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
23467c478bd9Sstevel@tonic-gate }
23477c478bd9Sstevel@tonic-gate 
23487c478bd9Sstevel@tonic-gate /*
23497c478bd9Sstevel@tonic-gate  * hci1394_set_xmit_storevalue_desc()
23507c478bd9Sstevel@tonic-gate  *    Set up store_value DMA descriptor.
23517c478bd9Sstevel@tonic-gate  *    XMIT_HDRONLY or XMIT_NOPKT xfer states use a store value as first
23527c478bd9Sstevel@tonic-gate  *    descriptor in the descriptor block (to handle skip mode processing)
23537c478bd9Sstevel@tonic-gate  */
23547c478bd9Sstevel@tonic-gate static void
23557c478bd9Sstevel@tonic-gate hci1394_set_xmit_storevalue_desc(hci1394_comp_ixl_vars_t *wvp)
23567c478bd9Sstevel@tonic-gate {
23577c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_storevalue_desc_enter,
23587c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
23597c478bd9Sstevel@tonic-gate 
23607c478bd9Sstevel@tonic-gate 	wvp->descriptors++;
23617c478bd9Sstevel@tonic-gate 
23627c478bd9Sstevel@tonic-gate 	HCI1394_INIT_IT_STORE(&wvp->descriptor_block[wvp->descriptors - 1],
23637c478bd9Sstevel@tonic-gate 	    wvp->storevalue_data);
23647c478bd9Sstevel@tonic-gate 	wvp->descriptor_block[wvp->descriptors - 1].data_addr =
23657c478bd9Sstevel@tonic-gate 	    wvp->storevalue_bufp;
23667c478bd9Sstevel@tonic-gate 	wvp->descriptor_block[wvp->descriptors - 1].branch = 0;
23677c478bd9Sstevel@tonic-gate 	wvp->descriptor_block[wvp->descriptors - 1].status = 0;
23687c478bd9Sstevel@tonic-gate 
23697c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_xmit_storevalue_desc_exit,
23707c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
23717c478bd9Sstevel@tonic-gate }
23727c478bd9Sstevel@tonic-gate 
23737c478bd9Sstevel@tonic-gate /*
23747c478bd9Sstevel@tonic-gate  * hci1394_set_next_xfer_buf()
23757c478bd9Sstevel@tonic-gate  *    This routine adds the data buffer to the current wvp list.
23767c478bd9Sstevel@tonic-gate  *    Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error
23777c478bd9Sstevel@tonic-gate  *    contains the error code.
23787c478bd9Sstevel@tonic-gate  */
23797c478bd9Sstevel@tonic-gate static int
23807c478bd9Sstevel@tonic-gate hci1394_set_next_xfer_buf(hci1394_comp_ixl_vars_t *wvp, uint32_t bufp,
23817c478bd9Sstevel@tonic-gate     uint16_t size)
23827c478bd9Sstevel@tonic-gate {
23837c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_enter,
23847c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
23857c478bd9Sstevel@tonic-gate 
23867c478bd9Sstevel@tonic-gate 	/* error if buffer pointer is null (size may be 0) */
2387*ffc2b7d4SToomas Soome 	if (bufp == 0) {
23887c478bd9Sstevel@tonic-gate 
23897c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_ENULL_BUFFER_ADDR;
23907c478bd9Sstevel@tonic-gate 
23917c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit,
23927c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
23937c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
23947c478bd9Sstevel@tonic-gate 	}
23957c478bd9Sstevel@tonic-gate 
23967c478bd9Sstevel@tonic-gate 	/* count new xfer buffer */
23977c478bd9Sstevel@tonic-gate 	wvp->xfer_bufcnt++;
23987c478bd9Sstevel@tonic-gate 
23997c478bd9Sstevel@tonic-gate 	/* error if exceeds maximum xfer buffer components allowed */
24007c478bd9Sstevel@tonic-gate 	if (wvp->xfer_bufcnt > HCI1394_DESC_MAX_Z) {
24017c478bd9Sstevel@tonic-gate 
24027c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO;
24037c478bd9Sstevel@tonic-gate 
24047c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_set_next_xfer_buf_error,
24057c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
24067c478bd9Sstevel@tonic-gate 		    "IXL1394_EFRAGMENT_OFLO", tnf_int, frag_count,
24077c478bd9Sstevel@tonic-gate 		    wvp->xfer_bufcnt);
24087c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit,
24097c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
24107c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
24117c478bd9Sstevel@tonic-gate 	}
24127c478bd9Sstevel@tonic-gate 
24137c478bd9Sstevel@tonic-gate 	/* save xmit buffer and size */
24147c478bd9Sstevel@tonic-gate 	wvp->xfer_bufp[wvp->xfer_bufcnt - 1] = bufp;
24157c478bd9Sstevel@tonic-gate 	wvp->xfer_size[wvp->xfer_bufcnt - 1] = size;
24167c478bd9Sstevel@tonic-gate 
24177c478bd9Sstevel@tonic-gate 	/* accumulate total packet length */
24187c478bd9Sstevel@tonic-gate 	wvp->xfer_pktlen += size;
24197c478bd9Sstevel@tonic-gate 
24207c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit,
24217c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
24227c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
24237c478bd9Sstevel@tonic-gate }
24247c478bd9Sstevel@tonic-gate 
24257c478bd9Sstevel@tonic-gate /*
24267c478bd9Sstevel@tonic-gate  * hci1394_flush_end_desc_check()
24277c478bd9Sstevel@tonic-gate  *    Check if flush required before last descriptor block of a
24287c478bd9Sstevel@tonic-gate  *    non-unary set generated by an xfer buff or xmit special command
24297c478bd9Sstevel@tonic-gate  *    or a unary set provided no other flush has already been done.
24307c478bd9Sstevel@tonic-gate  *
24317c478bd9Sstevel@tonic-gate  *    hci flush is required if xfer is finalized by an updateable
24327c478bd9Sstevel@tonic-gate  *    jump command.
24337c478bd9Sstevel@tonic-gate  *
24347c478bd9Sstevel@tonic-gate  *    Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error
24357c478bd9Sstevel@tonic-gate  *    will contain the error code.
24367c478bd9Sstevel@tonic-gate  */
24377c478bd9Sstevel@tonic-gate static int
24387c478bd9Sstevel@tonic-gate hci1394_flush_end_desc_check(hci1394_comp_ixl_vars_t *wvp, uint32_t count)
24397c478bd9Sstevel@tonic-gate {
24407c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_flush_end_desc_check_enter,
24417c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 	if ((count != 0) ||
24447c478bd9Sstevel@tonic-gate 	    ((wvp->xfer_hci_flush & (UPDATEABLE_XFER | UPDATEABLE_SET |
2445*ffc2b7d4SToomas Soome 	    INITIATING_LBL)) == 0)) {
24467c478bd9Sstevel@tonic-gate 
24477c478bd9Sstevel@tonic-gate 		if (wvp->xfer_hci_flush & UPDATEABLE_JUMP) {
24487c478bd9Sstevel@tonic-gate 			if (hci1394_flush_hci_cache(wvp) != DDI_SUCCESS) {
24497c478bd9Sstevel@tonic-gate 
24507c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
24517c478bd9Sstevel@tonic-gate 				    hci1394_flush_end_desc_check_exit,
24527c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
24537c478bd9Sstevel@tonic-gate 
24547c478bd9Sstevel@tonic-gate 				/* wvp->dma_bld_error is set by above call */
24557c478bd9Sstevel@tonic-gate 				return (DDI_FAILURE);
24567c478bd9Sstevel@tonic-gate 			}
24577c478bd9Sstevel@tonic-gate 		}
24587c478bd9Sstevel@tonic-gate 	}
24597c478bd9Sstevel@tonic-gate 
24607c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_flush_end_desc_check_exit,
24617c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
24627c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
24637c478bd9Sstevel@tonic-gate }
24647c478bd9Sstevel@tonic-gate 
24657c478bd9Sstevel@tonic-gate /*
24667c478bd9Sstevel@tonic-gate  * hci1394_flush_hci_cache()
24677c478bd9Sstevel@tonic-gate  *    Sun hci controller (RIO) implementation specific processing!
24687c478bd9Sstevel@tonic-gate  *
24697c478bd9Sstevel@tonic-gate  *    Allocate dma memory for 1 hci descriptor block which will be left unused.
24707c478bd9Sstevel@tonic-gate  *    During execution this will cause a break in the contiguous address space
24717c478bd9Sstevel@tonic-gate  *    processing required by Sun's RIO implementation of the ohci controller and
24727c478bd9Sstevel@tonic-gate  *    will require the controller to refetch the next descriptor block from
24737c478bd9Sstevel@tonic-gate  *    host memory.
24747c478bd9Sstevel@tonic-gate  *
24757c478bd9Sstevel@tonic-gate  *    General rules for cache flush preceeding a descriptor block in dma memory:
24767c478bd9Sstevel@tonic-gate  *    1. Current IXL Xfer Command Updateable Rule:
24777c478bd9Sstevel@tonic-gate  *	    Cache flush of IXL xfer command is required if it, or any of the
24787c478bd9Sstevel@tonic-gate  *	    non-start IXL packet xfer commands associated with it, is flagged
24797c478bd9Sstevel@tonic-gate  *	    updateable.
24807c478bd9Sstevel@tonic-gate  *    2. Next IXL Xfer Command Indeterminate Rule:
24817c478bd9Sstevel@tonic-gate  *	    Cache flush of IXL xfer command is required if an IXL jump command
24827c478bd9Sstevel@tonic-gate  *	    which is flagged updateable has finalized the current IXL xfer
24837c478bd9Sstevel@tonic-gate  *	    command.
24847c478bd9Sstevel@tonic-gate  *    3. Updateable IXL Set Command Rule:
24857c478bd9Sstevel@tonic-gate  *	    Cache flush of an IXL xfer command is required if any of the IXL
24867c478bd9Sstevel@tonic-gate  *	    "Set" commands (IXL1394_OP_SET_*) associated with the IXL xfer
24877c478bd9Sstevel@tonic-gate  *	    command (i.e. immediately preceeding it), is flagged updateable.
24887c478bd9Sstevel@tonic-gate  *    4. Label Initiating Xfer Command Rule:
24897c478bd9Sstevel@tonic-gate  *	    Cache flush of IXL xfer command is required if it is initiated by a
24907c478bd9Sstevel@tonic-gate  *	    label IXL command.  (This is to allow both a flush of the cache and
24917c478bd9Sstevel@tonic-gate  *	    an interrupt to be generated easily and in close proximity to each
24927c478bd9Sstevel@tonic-gate  *	    other.  This can make possible simpler more successful reset of
24937c478bd9Sstevel@tonic-gate  *	    descriptor statuses, especially under circumstances where the cycle
24947c478bd9Sstevel@tonic-gate  *	    of hci commands is short and/or there are no callbacks distributed
24957c478bd9Sstevel@tonic-gate  *	    through the span of xfers, etc...  This is especially important for
24967c478bd9Sstevel@tonic-gate  *	    input where statuses must be reset before execution cycles back
24977c478bd9Sstevel@tonic-gate  *	    again.
24987c478bd9Sstevel@tonic-gate  *
24997c478bd9Sstevel@tonic-gate  *    Application of above rules:
25007c478bd9Sstevel@tonic-gate  *    Packet mode IXL xfer commands:
25017c478bd9Sstevel@tonic-gate  *	    If any of the above flush rules apply, flush cache should be done
25027c478bd9Sstevel@tonic-gate  *	    immediately preceeding the generation of the dma descriptor block
25037c478bd9Sstevel@tonic-gate  *	    for the packet xfer.
25047c478bd9Sstevel@tonic-gate  *    Non-packet mode IXL xfer commands (including IXL1394_OP_*BUF*,
25057c478bd9Sstevel@tonic-gate  *    SEND_HDR_ONLY, and SEND_NO_PKT):
25067c478bd9Sstevel@tonic-gate  *	    If Rules #1, #3 or #4 applies, a flush cache should be done
25077c478bd9Sstevel@tonic-gate  *	    immediately before the first generated dma descriptor block of the
25087c478bd9Sstevel@tonic-gate  *	    non-packet xfer.
25097c478bd9Sstevel@tonic-gate  *	    If Rule #2 applies, a flush cache should be done immediately before
25107c478bd9Sstevel@tonic-gate  *	    the last generated dma descriptor block of the non-packet xfer.
25117c478bd9Sstevel@tonic-gate  *
25127c478bd9Sstevel@tonic-gate  *    Note: The flush cache should be done at most once in each location that is
25137c478bd9Sstevel@tonic-gate  *    required to be flushed no matter how many rules apply (i.e. only once
25147c478bd9Sstevel@tonic-gate  *    before the first descriptor block and/or only once before the last
25157c478bd9Sstevel@tonic-gate  *    descriptor block generated).  If more than one place requires a flush,
25167c478bd9Sstevel@tonic-gate  *    then both flush operations must be performed.  This is determined by
25177c478bd9Sstevel@tonic-gate  *    taking all rules that apply into account.
25187c478bd9Sstevel@tonic-gate  *
25197c478bd9Sstevel@tonic-gate  *    Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error
25207c478bd9Sstevel@tonic-gate  *    will contain the error code.
25217c478bd9Sstevel@tonic-gate  */
25227c478bd9Sstevel@tonic-gate static int
25237c478bd9Sstevel@tonic-gate hci1394_flush_hci_cache(hci1394_comp_ixl_vars_t *wvp)
25247c478bd9Sstevel@tonic-gate {
25257c478bd9Sstevel@tonic-gate 	uint32_t	dma_bound;
25267c478bd9Sstevel@tonic-gate 
25277c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_enter,
25287c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
25297c478bd9Sstevel@tonic-gate 
25307c478bd9Sstevel@tonic-gate 	if (hci1394_alloc_dma_mem(wvp, sizeof (hci1394_desc_t), &dma_bound) ==
25317c478bd9Sstevel@tonic-gate 	    NULL) {
25327c478bd9Sstevel@tonic-gate 
25337c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
25347c478bd9Sstevel@tonic-gate 
25357c478bd9Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_flush_hci_cache_fail,
25367c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
25377c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: for flush_hci_cache");
25387c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_exit,
25397c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
25407c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
25417c478bd9Sstevel@tonic-gate 	}
25427c478bd9Sstevel@tonic-gate 
25437c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_exit,
25447c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
25457c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
25467c478bd9Sstevel@tonic-gate }
25477c478bd9Sstevel@tonic-gate 
25487c478bd9Sstevel@tonic-gate /*
25497c478bd9Sstevel@tonic-gate  * hci1394_alloc_storevalue_dma_mem()
25507c478bd9Sstevel@tonic-gate  *    Allocate dma memory for a 1 hci component descriptor block
25517c478bd9Sstevel@tonic-gate  *    which will be used as the dma memory location that ixl
25527c478bd9Sstevel@tonic-gate  *    compiler generated storevalue descriptor commands will
25537c478bd9Sstevel@tonic-gate  *    specify as location to store their data value.
25547c478bd9Sstevel@tonic-gate  *
25557c478bd9Sstevel@tonic-gate  *    Returns 32-bit bound address of allocated mem, or NULL.
25567c478bd9Sstevel@tonic-gate  */
25577c478bd9Sstevel@tonic-gate static uint32_t
25587c478bd9Sstevel@tonic-gate hci1394_alloc_storevalue_dma_mem(hci1394_comp_ixl_vars_t *wvp)
25597c478bd9Sstevel@tonic-gate {
25607c478bd9Sstevel@tonic-gate 	uint32_t	dma_bound;
25617c478bd9Sstevel@tonic-gate 
25627c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_enter,
25637c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
25647c478bd9Sstevel@tonic-gate 
25657c478bd9Sstevel@tonic-gate 	if (hci1394_alloc_dma_mem(wvp, sizeof (hci1394_desc_t),
25667c478bd9Sstevel@tonic-gate 	    &dma_bound) == NULL) {
25677c478bd9Sstevel@tonic-gate 
25687c478bd9Sstevel@tonic-gate 		wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL;
25697c478bd9Sstevel@tonic-gate 
25707c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_bld_alloc_storevalue_dma_mem_alloc_fail,
25717c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
25727c478bd9Sstevel@tonic-gate 		    "IXL1394_EMEM_ALLOC_FAIL: for storevalue dma",
25737c478bd9Sstevel@tonic-gate 		    tnf_opaque, ixl_commandp, wvp->ixl_cur_cmdp);
25747c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_exit,
25757c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2576*ffc2b7d4SToomas Soome 		return (0);
25777c478bd9Sstevel@tonic-gate 	}
25787c478bd9Sstevel@tonic-gate 
25797c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_exit,
25807c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
25817c478bd9Sstevel@tonic-gate 
25827c478bd9Sstevel@tonic-gate 	/* return bound address of allocated memory */
25837c478bd9Sstevel@tonic-gate 	return (dma_bound);
25847c478bd9Sstevel@tonic-gate }
25857c478bd9Sstevel@tonic-gate 
25867c478bd9Sstevel@tonic-gate 
25877c478bd9Sstevel@tonic-gate /*
25887c478bd9Sstevel@tonic-gate  * hci1394_alloc_xfer_ctl()
25897c478bd9Sstevel@tonic-gate  *    Allocate an xfer_ctl structure.
25907c478bd9Sstevel@tonic-gate  */
25917c478bd9Sstevel@tonic-gate static hci1394_xfer_ctl_t *
25927c478bd9Sstevel@tonic-gate hci1394_alloc_xfer_ctl(hci1394_comp_ixl_vars_t *wvp, uint32_t dmacnt)
25937c478bd9Sstevel@tonic-gate {
25947c478bd9Sstevel@tonic-gate 	hci1394_xfer_ctl_t *xcsp;
25957c478bd9Sstevel@tonic-gate 
25967c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_enter,
25977c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
25987c478bd9Sstevel@tonic-gate 
25997c478bd9Sstevel@tonic-gate 	/*
26007c478bd9Sstevel@tonic-gate 	 * allocate an xfer_ctl struct which includes dmacnt of
26017c478bd9Sstevel@tonic-gate 	 * xfer_ctl_dma structs
26027c478bd9Sstevel@tonic-gate 	 */
26037c478bd9Sstevel@tonic-gate #ifdef _KERNEL
26047c478bd9Sstevel@tonic-gate 	if ((xcsp = (hci1394_xfer_ctl_t *)kmem_zalloc(
26057c478bd9Sstevel@tonic-gate 	    (sizeof (hci1394_xfer_ctl_t) + (dmacnt - 1) *
26067c478bd9Sstevel@tonic-gate 	    sizeof (hci1394_xfer_ctl_dma_t)), KM_NOSLEEP)) == NULL) {
26077c478bd9Sstevel@tonic-gate 
26087c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit,
26097c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
26107c478bd9Sstevel@tonic-gate 		return (NULL);
26117c478bd9Sstevel@tonic-gate 	}
26127c478bd9Sstevel@tonic-gate #else
26137c478bd9Sstevel@tonic-gate 	/*
26147c478bd9Sstevel@tonic-gate 	 * This section makes it possible to easily run and test the compiler in
26157c478bd9Sstevel@tonic-gate 	 * user mode.
26167c478bd9Sstevel@tonic-gate 	 */
26177c478bd9Sstevel@tonic-gate 	if ((xcsp = (hci1394_xfer_ctl_t *)calloc(1,
26187c478bd9Sstevel@tonic-gate 	    sizeof (hci1394_xfer_ctl_t) + (dmacnt - 1) *
26197c478bd9Sstevel@tonic-gate 	    sizeof (hci1394_xfer_ctl_dma_t))) == NULL) {
26207c478bd9Sstevel@tonic-gate 
26217c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit,
26227c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
26237c478bd9Sstevel@tonic-gate 		return (NULL);
26247c478bd9Sstevel@tonic-gate 	}
26257c478bd9Sstevel@tonic-gate #endif
26267c478bd9Sstevel@tonic-gate 	/*
26277c478bd9Sstevel@tonic-gate 	 * set dma structure count into allocated xfer_ctl struct for
26287c478bd9Sstevel@tonic-gate 	 * later deletion.
26297c478bd9Sstevel@tonic-gate 	 */
26307c478bd9Sstevel@tonic-gate 	xcsp->cnt = dmacnt;
26317c478bd9Sstevel@tonic-gate 
26327c478bd9Sstevel@tonic-gate 	/* link it to previously allocated xfer_ctl structs or set as first */
26337c478bd9Sstevel@tonic-gate 	if (wvp->xcs_firstp == NULL) {
26347c478bd9Sstevel@tonic-gate 		wvp->xcs_firstp = wvp->xcs_currentp = xcsp;
26357c478bd9Sstevel@tonic-gate 	} else {
26367c478bd9Sstevel@tonic-gate 		wvp->xcs_currentp->ctl_nextp = xcsp;
26377c478bd9Sstevel@tonic-gate 		wvp->xcs_currentp = xcsp;
26387c478bd9Sstevel@tonic-gate 	}
26397c478bd9Sstevel@tonic-gate 
26407c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit,
26417c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
26427c478bd9Sstevel@tonic-gate 
26437c478bd9Sstevel@tonic-gate 	/* return allocated xfer_ctl structure */
26447c478bd9Sstevel@tonic-gate 	return (xcsp);
26457c478bd9Sstevel@tonic-gate }
26467c478bd9Sstevel@tonic-gate 
26477c478bd9Sstevel@tonic-gate /*
26487c478bd9Sstevel@tonic-gate  * hci1394_alloc_dma_mem()
26497c478bd9Sstevel@tonic-gate  *	Allocates and binds memory for openHCI DMA descriptors as needed.
26507c478bd9Sstevel@tonic-gate  */
26517c478bd9Sstevel@tonic-gate static void *
26527c478bd9Sstevel@tonic-gate hci1394_alloc_dma_mem(hci1394_comp_ixl_vars_t *wvp, uint32_t size,
26537c478bd9Sstevel@tonic-gate     uint32_t *dma_bound)
26547c478bd9Sstevel@tonic-gate {
26557c478bd9Sstevel@tonic-gate 	hci1394_idma_desc_mem_t *dma_new;
26567c478bd9Sstevel@tonic-gate 	hci1394_buf_parms_t parms;
26577c478bd9Sstevel@tonic-gate 	hci1394_buf_info_t *memp;
26587c478bd9Sstevel@tonic-gate 	void	*dma_mem_ret;
26597c478bd9Sstevel@tonic-gate 	int	ret;
26607c478bd9Sstevel@tonic-gate 
26617c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_enter,
26627c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
26637c478bd9Sstevel@tonic-gate 
26647c478bd9Sstevel@tonic-gate 	/*
26657c478bd9Sstevel@tonic-gate 	 * if no dma has been allocated or current request exceeds
26667c478bd9Sstevel@tonic-gate 	 * remaining memory
26677c478bd9Sstevel@tonic-gate 	 */
26687c478bd9Sstevel@tonic-gate 	if ((wvp->dma_currentp == NULL) ||
26697c478bd9Sstevel@tonic-gate 	    (size > (wvp->dma_currentp->mem.bi_cookie.dmac_size -
2670*ffc2b7d4SToomas Soome 	    wvp->dma_currentp->used))) {
26717c478bd9Sstevel@tonic-gate #ifdef _KERNEL
26727c478bd9Sstevel@tonic-gate 		/* kernel-mode memory allocation for driver */
26737c478bd9Sstevel@tonic-gate 
26747c478bd9Sstevel@tonic-gate 		/* allocate struct to track more dma descriptor memory */
26757c478bd9Sstevel@tonic-gate 		if ((dma_new = (hci1394_idma_desc_mem_t *)
26767c478bd9Sstevel@tonic-gate 		    kmem_zalloc(sizeof (hci1394_idma_desc_mem_t),
26777c478bd9Sstevel@tonic-gate 		    KM_NOSLEEP)) == NULL) {
26787c478bd9Sstevel@tonic-gate 
26797c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
26807c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
26817c478bd9Sstevel@tonic-gate 			return (NULL);
26827c478bd9Sstevel@tonic-gate 		}
26837c478bd9Sstevel@tonic-gate 
26847c478bd9Sstevel@tonic-gate 		/*
26857c478bd9Sstevel@tonic-gate 		 * if more cookies available from the current mem, try to find
26867c478bd9Sstevel@tonic-gate 		 * one of suitable size. Cookies that are too small will be
26877c478bd9Sstevel@tonic-gate 		 * skipped and unused. Given that cookie size is always at least
26887c478bd9Sstevel@tonic-gate 		 * 1 page long and HCI1394_DESC_MAX_Z is much smaller than that,
26897c478bd9Sstevel@tonic-gate 		 * it's a small price to pay for code simplicity.
26907c478bd9Sstevel@tonic-gate 		 */
26917c478bd9Sstevel@tonic-gate 		if (wvp->dma_currentp != NULL) {
26927c478bd9Sstevel@tonic-gate 			/* new struct is derived from current */
26937c478bd9Sstevel@tonic-gate 			memp = &wvp->dma_currentp->mem;
26947c478bd9Sstevel@tonic-gate 			dma_new->mem = *memp;
26957c478bd9Sstevel@tonic-gate 			dma_new->offset = wvp->dma_currentp->offset +
26967c478bd9Sstevel@tonic-gate 			    memp->bi_cookie.dmac_size;
26977c478bd9Sstevel@tonic-gate 
26987c478bd9Sstevel@tonic-gate 			for (; memp->bi_cookie_count > 1;
26997c478bd9Sstevel@tonic-gate 			    memp->bi_cookie_count--) {
27007c478bd9Sstevel@tonic-gate 				ddi_dma_nextcookie(memp->bi_dma_handle,
27017c478bd9Sstevel@tonic-gate 				    &dma_new->mem.bi_cookie);
27027c478bd9Sstevel@tonic-gate 
27037c478bd9Sstevel@tonic-gate 				if (dma_new->mem.bi_cookie.dmac_size >= size) {
27047c478bd9Sstevel@tonic-gate 					dma_new->mem_handle =
27057c478bd9Sstevel@tonic-gate 					    wvp->dma_currentp->mem_handle;
27067c478bd9Sstevel@tonic-gate 					wvp->dma_currentp->mem_handle = NULL;
27077c478bd9Sstevel@tonic-gate 					dma_new->mem.bi_cookie_count--;
27087c478bd9Sstevel@tonic-gate 					break;
27097c478bd9Sstevel@tonic-gate 				}
27107c478bd9Sstevel@tonic-gate 				dma_new->offset +=
27117c478bd9Sstevel@tonic-gate 				    dma_new->mem.bi_cookie.dmac_size;
27127c478bd9Sstevel@tonic-gate 			}
27137c478bd9Sstevel@tonic-gate 		}
27147c478bd9Sstevel@tonic-gate 
27157c478bd9Sstevel@tonic-gate 		/* if no luck with current buffer, allocate a new one */
27167c478bd9Sstevel@tonic-gate 		if (dma_new->mem_handle == NULL) {
27177c478bd9Sstevel@tonic-gate 			parms.bp_length = HCI1394_IXL_PAGESIZE;
27187c478bd9Sstevel@tonic-gate 			parms.bp_max_cookies = OHCI_MAX_COOKIE;
27197c478bd9Sstevel@tonic-gate 			parms.bp_alignment = 16;
27207c478bd9Sstevel@tonic-gate 			ret = hci1394_buf_alloc(&wvp->soft_statep->drvinfo,
27217c478bd9Sstevel@tonic-gate 			    &parms, &dma_new->mem, &dma_new->mem_handle);
27227c478bd9Sstevel@tonic-gate 			if (ret != DDI_SUCCESS) {
27237c478bd9Sstevel@tonic-gate 				kmem_free(dma_new,
27247c478bd9Sstevel@tonic-gate 				    sizeof (hci1394_idma_desc_mem_t));
27257c478bd9Sstevel@tonic-gate 
27267c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
27277c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
27287c478bd9Sstevel@tonic-gate 				return (NULL);
27297c478bd9Sstevel@tonic-gate 			}
27307c478bd9Sstevel@tonic-gate 
27317c478bd9Sstevel@tonic-gate 			/* paranoia: this is not supposed to happen */
27327c478bd9Sstevel@tonic-gate 			if (dma_new->mem.bi_cookie.dmac_size < size) {
27337c478bd9Sstevel@tonic-gate 				hci1394_buf_free(&dma_new->mem_handle);
27347c478bd9Sstevel@tonic-gate 				kmem_free(dma_new,
27357c478bd9Sstevel@tonic-gate 				    sizeof (hci1394_idma_desc_mem_t));
27367c478bd9Sstevel@tonic-gate 
27377c478bd9Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
27387c478bd9Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
27397c478bd9Sstevel@tonic-gate 				return (NULL);
27407c478bd9Sstevel@tonic-gate 			}
27417c478bd9Sstevel@tonic-gate 			dma_new->offset = 0;
27427c478bd9Sstevel@tonic-gate 		}
27437c478bd9Sstevel@tonic-gate #else
27447c478bd9Sstevel@tonic-gate 		/* user-mode memory allocation for user mode compiler tests */
27457c478bd9Sstevel@tonic-gate 		/* allocate another dma_desc_mem struct */
27467c478bd9Sstevel@tonic-gate 		if ((dma_new = (hci1394_idma_desc_mem_t *)
2747*ffc2b7d4SToomas Soome 		    calloc(1, sizeof (hci1394_idma_desc_mem_t))) == NULL) {
27487c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
27497c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
27507c478bd9Sstevel@tonic-gate 			return (NULL);
27517c478bd9Sstevel@tonic-gate 		}
27527c478bd9Sstevel@tonic-gate 		dma_new->mem.bi_dma_handle = NULL;
27537c478bd9Sstevel@tonic-gate 		dma_new->mem.bi_handle = NULL;
27547c478bd9Sstevel@tonic-gate 		if ((dma_new->mem.bi_kaddr = (caddr_t)calloc(1,
2755*ffc2b7d4SToomas Soome 		    HCI1394_IXL_PAGESIZE)) == NULL) {
27567c478bd9Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
27577c478bd9Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
27587c478bd9Sstevel@tonic-gate 			return (NULL);
27597c478bd9Sstevel@tonic-gate 		}
27607c478bd9Sstevel@tonic-gate 		dma_new->mem.bi_cookie.dmac_address =
27617c478bd9Sstevel@tonic-gate 		    (unsigned long)dma_new->mem.bi_kaddr;
27627c478bd9Sstevel@tonic-gate 		dma_new->mem.bi_real_length = HCI1394_IXL_PAGESIZE;
27637c478bd9Sstevel@tonic-gate 		dma_new->mem.bi_cookie_count = 1;
27647c478bd9Sstevel@tonic-gate #endif
27657c478bd9Sstevel@tonic-gate 
27667c478bd9Sstevel@tonic-gate 		/* if this is not first dma_desc_mem, link last one to it */
27677c478bd9Sstevel@tonic-gate 		if (wvp->dma_currentp != NULL) {
27687c478bd9Sstevel@tonic-gate 			wvp->dma_currentp->dma_nextp = dma_new;
27697c478bd9Sstevel@tonic-gate 			wvp->dma_currentp = dma_new;
27707c478bd9Sstevel@tonic-gate 		} else {
27717c478bd9Sstevel@tonic-gate 			/* else set it as first one */
27727c478bd9Sstevel@tonic-gate 			wvp->dma_currentp = wvp->dma_firstp = dma_new;
27737c478bd9Sstevel@tonic-gate 		}
27747c478bd9Sstevel@tonic-gate 	}
27757c478bd9Sstevel@tonic-gate 
27767c478bd9Sstevel@tonic-gate 	/* now allocate requested memory from current block */
27777c478bd9Sstevel@tonic-gate 	dma_mem_ret = wvp->dma_currentp->mem.bi_kaddr +
27787c478bd9Sstevel@tonic-gate 	    wvp->dma_currentp->offset + wvp->dma_currentp->used;
27797c478bd9Sstevel@tonic-gate 	*dma_bound = wvp->dma_currentp->mem.bi_cookie.dmac_address +
27807c478bd9Sstevel@tonic-gate 	    wvp->dma_currentp->used;
27817c478bd9Sstevel@tonic-gate 	wvp->dma_currentp->used += size;
27827c478bd9Sstevel@tonic-gate 
27837c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit,
27847c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
27857c478bd9Sstevel@tonic-gate 	return (dma_mem_ret);
27867c478bd9Sstevel@tonic-gate }
27877c478bd9Sstevel@tonic-gate 
27887c478bd9Sstevel@tonic-gate 
27897c478bd9Sstevel@tonic-gate /*
27907c478bd9Sstevel@tonic-gate  * hci1394_is_opcode_valid()
27917c478bd9Sstevel@tonic-gate  *    given an ixl opcode, this routine returns B_TRUE if it is a
27927c478bd9Sstevel@tonic-gate  *    recognized opcode and B_FALSE if it is not recognized.
27937c478bd9Sstevel@tonic-gate  *    Note that the FULL 16 bits of the opcode are checked which includes
27947c478bd9Sstevel@tonic-gate  *    various flags and not just the low order 8 bits of unique code.
27957c478bd9Sstevel@tonic-gate  */
27967c478bd9Sstevel@tonic-gate static boolean_t
27977c478bd9Sstevel@tonic-gate hci1394_is_opcode_valid(uint16_t ixlopcode)
27987c478bd9Sstevel@tonic-gate {
27997c478bd9Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_is_opcode_bad_enter,
28007c478bd9Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
28017c478bd9Sstevel@tonic-gate 
28027c478bd9Sstevel@tonic-gate 	/* if it's not one we know about, then it's bad */
28037c478bd9Sstevel@tonic-gate 	switch (ixlopcode) {
28047c478bd9Sstevel@tonic-gate 	case IXL1394_OP_LABEL:
28057c478bd9Sstevel@tonic-gate 	case IXL1394_OP_JUMP:
28067c478bd9Sstevel@tonic-gate 	case IXL1394_OP_CALLBACK:
28077c478bd9Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT:
28087c478bd9Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT_ST:
28097c478bd9Sstevel@tonic-gate 	case IXL1394_OP_RECV_BUF:
28107c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT:
28117c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_ST:
28127c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_WHDR_ST:
28137c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_BUF:
28147c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_HDR_ONLY:
28157c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_NO_PKT:
28167c478bd9Sstevel@tonic-gate 	case IXL1394_OP_STORE_TIMESTAMP:
28177c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SET_TAGSYNC:
28187c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SET_SKIPMODE:
28197c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SET_SYNCWAIT:
28207c478bd9Sstevel@tonic-gate 	case IXL1394_OP_JUMP_U:
28217c478bd9Sstevel@tonic-gate 	case IXL1394_OP_CALLBACK_U:
28227c478bd9Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT_U:
28237c478bd9Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT_ST_U:
28247c478bd9Sstevel@tonic-gate 	case IXL1394_OP_RECV_BUF_U:
28257c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_U:
28267c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_ST_U:
28277c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_WHDR_ST_U:
28287c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SEND_BUF_U:
28297c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SET_TAGSYNC_U:
28307c478bd9Sstevel@tonic-gate 	case IXL1394_OP_SET_SKIPMODE_U:
28317c478bd9Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_is_opcode_valid_enter,
28327c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, msg,
28337c478bd9Sstevel@tonic-gate 		    "ixl opcode is valid");
28347c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_is_opcode_bad_enter,
28357c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
28367c478bd9Sstevel@tonic-gate 		return (B_TRUE);
28377c478bd9Sstevel@tonic-gate 	default:
28387c478bd9Sstevel@tonic-gate 		TNF_PROBE_2(hci1394_is_opcode_valid_enter,
28397c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, msg,
28407c478bd9Sstevel@tonic-gate 		    "ixl opcode is NOT valid", tnf_opaque, ixl_opcode,
28417c478bd9Sstevel@tonic-gate 		    ixlopcode);
28427c478bd9Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_is_opcode_valid_enter,
28437c478bd9Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
28447c478bd9Sstevel@tonic-gate 		return (B_FALSE);
28457c478bd9Sstevel@tonic-gate 	}
28467c478bd9Sstevel@tonic-gate }
2847