xref: /onnv-gate/usr/src/uts/common/io/1394/adapters/hci1394_ixl_update.c (revision 2273:965cd64c1689)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*2273Sap25164  * Common Development and Distribution License (the "License").
6*2273Sap25164  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*2273Sap25164  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * hci1394_ixl_update.c
300Sstevel@tonic-gate  *    Isochronous IXL update routines.
310Sstevel@tonic-gate  *    Routines used to dynamically update a compiled and presumably running
320Sstevel@tonic-gate  *    IXL program.
330Sstevel@tonic-gate  */
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #include <sys/kmem.h>
360Sstevel@tonic-gate #include <sys/types.h>
370Sstevel@tonic-gate #include <sys/conf.h>
38*2273Sap25164 #include <sys/disp.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include <sys/tnf_probe.h>
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <sys/1394/h1394.h>
430Sstevel@tonic-gate #include <sys/1394/ixl1394.h>	/* IXL opcodes & data structs */
440Sstevel@tonic-gate 
450Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
460Sstevel@tonic-gate 
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /* local defines for hci1394_ixl_update_prepare return codes */
490Sstevel@tonic-gate #define	IXL_PREP_READY	    1
500Sstevel@tonic-gate #define	IXL_PREP_SUCCESS    0
510Sstevel@tonic-gate #define	IXL_PREP_FAILURE    (-1)
520Sstevel@tonic-gate 
530Sstevel@tonic-gate /*
540Sstevel@tonic-gate  * variable used to indicate the number of times update will wait for
550Sstevel@tonic-gate  * interrupt routine to complete.
560Sstevel@tonic-gate  */
570Sstevel@tonic-gate int hci1394_upd_retries_before_fail = 50;
580Sstevel@tonic-gate 
590Sstevel@tonic-gate /* IXL runtime update static functions */
600Sstevel@tonic-gate static int hci1394_ixl_update_prepare(hci1394_ixl_update_vars_t *uvp);
610Sstevel@tonic-gate static int hci1394_ixl_update_prep_jump(hci1394_ixl_update_vars_t *uvp);
620Sstevel@tonic-gate static int hci1394_ixl_update_prep_set_skipmode(hci1394_ixl_update_vars_t *uvp);
630Sstevel@tonic-gate static int hci1394_ixl_update_prep_set_tagsync(hci1394_ixl_update_vars_t *uvp);
640Sstevel@tonic-gate static int hci1394_ixl_update_prep_recv_pkt(hci1394_ixl_update_vars_t *uvp);
650Sstevel@tonic-gate static int hci1394_ixl_update_prep_recv_buf(hci1394_ixl_update_vars_t *uvp);
660Sstevel@tonic-gate static int hci1394_ixl_update_prep_send_pkt(hci1394_ixl_update_vars_t *uvp);
670Sstevel@tonic-gate static int hci1394_ixl_update_prep_send_buf(hci1394_ixl_update_vars_t *uvp);
680Sstevel@tonic-gate static int hci1394_ixl_update_perform(hci1394_ixl_update_vars_t *uvp);
690Sstevel@tonic-gate static int hci1394_ixl_update_evaluate(hci1394_ixl_update_vars_t *uvp);
700Sstevel@tonic-gate static int hci1394_ixl_update_analysis(hci1394_ixl_update_vars_t *uvp);
710Sstevel@tonic-gate static void hci1394_ixl_update_set_locn_info(hci1394_ixl_update_vars_t *uvp);
720Sstevel@tonic-gate static int hci1394_ixl_update_enable(hci1394_ixl_update_vars_t *uvp);
730Sstevel@tonic-gate static int hci1394_ixl_update_endup(hci1394_ixl_update_vars_t *uvp);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate /*
760Sstevel@tonic-gate  *	IXL commands and included fields which can be updated
770Sstevel@tonic-gate  * IXL1394_OP_CALLBACK:		callback(), callback_data
780Sstevel@tonic-gate  * IXL1394_OP_JUMP:		label
790Sstevel@tonic-gate  * IXL1394_OP_RECV_PKT		ixl_buf, size, mem_bufp
800Sstevel@tonic-gate  * IXL1394_OP_RECV_PKT_ST	ixl_buf, size, mem_bufp
810Sstevel@tonic-gate  * IXL1394_OP_RECV_BUF(ppb)	ixl_buf, size, pkt_size, mem_bufp, buf_offset
820Sstevel@tonic-gate  * IXL1394_OP_RECV_BUF(fill)	ixl_buf, size, pkt_size, mem_bufp, buf_offset
830Sstevel@tonic-gate  * IXL1394_OP_SEND_PKT		ixl_buf, size, mem_bufp
840Sstevel@tonic-gate  * IXL1394_OP_SEND_PKT_ST	ixl_buf, size, mem_bufp
850Sstevel@tonic-gate  * IXL1394_OP_SEND_PKT_WHDR_ST	ixl_buf, size, mem_bufp
860Sstevel@tonic-gate  * IXL1394_OP_SEND_BUF		ixl_buf, size, pkt_size, mem_bufp, buf_offset
870Sstevel@tonic-gate  * IXL1394_OP_SET_TAGSYNC	tag, sync
880Sstevel@tonic-gate  * IXL1394_OP_SET_SKIPMODE	skipmode, label
890Sstevel@tonic-gate  *
900Sstevel@tonic-gate  *	IXL commands which can not be updated
910Sstevel@tonic-gate  * IXL1394_OP_LABEL
920Sstevel@tonic-gate  * IXL1394_OP_SEND_HDR_ONLY
930Sstevel@tonic-gate  * IXL1394_OP_SEND_NOPKT
940Sstevel@tonic-gate  * IXL1394_OP_STORE_VALUE
950Sstevel@tonic-gate  * IXL1394_OP_STORE_TIMESTAMP
960Sstevel@tonic-gate  * IXL1394_OP_SET_SYNCWAIT
970Sstevel@tonic-gate  */
980Sstevel@tonic-gate 
990Sstevel@tonic-gate /*
1000Sstevel@tonic-gate  * hci1394_ixl_update
1010Sstevel@tonic-gate  *    main entrypoint into dynamic update code: initializes temporary
1020Sstevel@tonic-gate  *    update variables, evaluates request, coordinates with potentially
1030Sstevel@tonic-gate  *    simultaneous run of interrupt stack, evaluates likelyhood of success,
1040Sstevel@tonic-gate  *    performs the update, checks if completed, performs cleanup
1050Sstevel@tonic-gate  *    resulting from coordination with interrupt stack.
1060Sstevel@tonic-gate  */
1070Sstevel@tonic-gate int
hci1394_ixl_update(hci1394_state_t * soft_statep,hci1394_iso_ctxt_t * ctxtp,ixl1394_command_t * ixlnewp,ixl1394_command_t * ixloldp,uint_t riskoverride,int * resultp)1080Sstevel@tonic-gate hci1394_ixl_update(hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
1090Sstevel@tonic-gate     ixl1394_command_t *ixlnewp, ixl1394_command_t *ixloldp,
1100Sstevel@tonic-gate     uint_t riskoverride, int *resultp)
1110Sstevel@tonic-gate {
1120Sstevel@tonic-gate 	hci1394_ixl_update_vars_t uv;	/* update work variables structure */
1130Sstevel@tonic-gate 	int prepstatus;
1140Sstevel@tonic-gate 	int ret;
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_enter,
1170Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	/* save caller specified values in update work variables structure */
1210Sstevel@tonic-gate 	uv.soft_statep = soft_statep;
1220Sstevel@tonic-gate 	uv.ctxtp = ctxtp;
1230Sstevel@tonic-gate 	uv.ixlnewp = ixlnewp;
1240Sstevel@tonic-gate 	uv.ixloldp = ixloldp;
1250Sstevel@tonic-gate 	uv.risklevel = riskoverride;
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	/* initialize remainder of update work variables */
1280Sstevel@tonic-gate 	uv.ixlxferp = NULL;
1290Sstevel@tonic-gate 	uv.skipxferp = NULL;
1300Sstevel@tonic-gate 	uv.skipmode = 0;
1310Sstevel@tonic-gate 	uv.skipaddr = 0;
1320Sstevel@tonic-gate 	uv.jumpaddr = 0;
1330Sstevel@tonic-gate 	uv.pkthdr1 = 0;
1340Sstevel@tonic-gate 	uv.pkthdr2 = 0;
1350Sstevel@tonic-gate 	uv.bufaddr = 0;
1360Sstevel@tonic-gate 	uv.bufsize = 0;
1370Sstevel@tonic-gate 	uv.ixl_opcode = uv.ixlnewp->ixl_opcode;
1380Sstevel@tonic-gate 	uv.hcihdr = 0;
1390Sstevel@tonic-gate 	uv.hcistatus = 0;
1400Sstevel@tonic-gate 	uv.hci_offset = 0;
1410Sstevel@tonic-gate 	uv.hdr_offset = 0;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	/* set done ok return status */
1440Sstevel@tonic-gate 	uv.upd_status = 0;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	/* evaluate request and prepare to perform update */
1470Sstevel@tonic-gate 	prepstatus = hci1394_ixl_update_prepare(&uv);
1480Sstevel@tonic-gate 	if (prepstatus != IXL_PREP_READY) {
1490Sstevel@tonic-gate 		/*
1500Sstevel@tonic-gate 		 * if either done or nothing to do or an evaluation error,
1510Sstevel@tonic-gate 		 * return update status
1520Sstevel@tonic-gate 		 */
1530Sstevel@tonic-gate 		*resultp = uv.upd_status;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 		/* if prep evaluation error, return failure */
1560Sstevel@tonic-gate 		if (prepstatus != IXL_PREP_SUCCESS) {
1570Sstevel@tonic-gate 			TNF_PROBE_1_DEBUG(hci1394_ixl_update_error,
1580Sstevel@tonic-gate 			    HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, msg,
1590Sstevel@tonic-gate 			    "IXL_PREP_FAILURE");
1600Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_exit,
1610Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
1620Sstevel@tonic-gate 			return (DDI_FAILURE);
1630Sstevel@tonic-gate 		}
1640Sstevel@tonic-gate 		/* if no action or update done, return update successful */
1650Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_exit,
1660Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1670Sstevel@tonic-gate 		return (DDI_SUCCESS);
1680Sstevel@tonic-gate 	}
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	/* perform update processing reservation of interrupt context */
1710Sstevel@tonic-gate 	ret = hci1394_ixl_update_enable(&uv);
1720Sstevel@tonic-gate 	if (ret != DDI_SUCCESS) {
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 		/* error acquiring control of context - return */
1750Sstevel@tonic-gate 		*resultp = uv.upd_status;
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_exit,
1780Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
1790Sstevel@tonic-gate 		return (DDI_FAILURE);
1800Sstevel@tonic-gate 	}
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate 	/* perform update risk analysis */
1830Sstevel@tonic-gate 	if (hci1394_ixl_update_analysis(&uv) != DDI_SUCCESS) {
1840Sstevel@tonic-gate 		/*
1850Sstevel@tonic-gate 		 * return, if excessive risk or dma execution processing lost
1860Sstevel@tonic-gate 		 * (note: caller risk override not yet implemented)
1870Sstevel@tonic-gate 		 */
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 		/* attempt intr processing cleanup, unless err is dmalost */
1900Sstevel@tonic-gate 		if (uv.upd_status != IXL1394_EPRE_UPD_DMALOST) {
1910Sstevel@tonic-gate 			(void) hci1394_ixl_update_endup(&uv);
1920Sstevel@tonic-gate 		} else {
1930Sstevel@tonic-gate 			/*
1940Sstevel@tonic-gate 			 * error is dmalost, just release interrupt context.
1950Sstevel@tonic-gate 			 * take the lock here to ensure an atomic read, modify,
1960Sstevel@tonic-gate 			 * write of the "intr_flags" field while we try to
1970Sstevel@tonic-gate 			 * clear the "in update" flag.  protects from the
1980Sstevel@tonic-gate 			 * interrupt routine.
1990Sstevel@tonic-gate 			 */
2000Sstevel@tonic-gate 			mutex_enter(&ctxtp->intrprocmutex);
2010Sstevel@tonic-gate 			ctxtp->intr_flags &= ~HCI1394_ISO_CTXT_INUPDATE;
2020Sstevel@tonic-gate 			mutex_exit(&ctxtp->intrprocmutex);
2030Sstevel@tonic-gate 		}
2040Sstevel@tonic-gate 		*resultp = uv.upd_status;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_exit,
2070Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2080Sstevel@tonic-gate 		return (DDI_FAILURE);
2090Sstevel@tonic-gate 	}
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 	/* perform requested update */
2130Sstevel@tonic-gate 	if (hci1394_ixl_update_perform(&uv) != DDI_SUCCESS) {
2140Sstevel@tonic-gate 		/*
2150Sstevel@tonic-gate 		 * if non-completion condition, return update status
2160Sstevel@tonic-gate 		 * attempt interrupt processing cleanup first
2170Sstevel@tonic-gate 		 */
2180Sstevel@tonic-gate 		(void) hci1394_ixl_update_endup(&uv);
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate 		*resultp = uv.upd_status;
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_exit,
2230Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2240Sstevel@tonic-gate 		return (DDI_FAILURE);
2250Sstevel@tonic-gate 	}
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	/* evaluate update completion, setting completion status */
2280Sstevel@tonic-gate 	if (hci1394_ixl_update_evaluate(&uv) != DDI_SUCCESS) {
2290Sstevel@tonic-gate 		/*
2300Sstevel@tonic-gate 		 * update failed - bad, just release interrupt context
2310Sstevel@tonic-gate 		 * take the lock here too (jsut like above) to ensure an
2320Sstevel@tonic-gate 		 * atomic read, modify, write of the "intr_flags" field
2330Sstevel@tonic-gate 		 * while we try to clear the "in update" flag.  protects
2340Sstevel@tonic-gate 		 * from the interrupt routine.
2350Sstevel@tonic-gate 		 */
2360Sstevel@tonic-gate 		mutex_enter(&ctxtp->intrprocmutex);
2370Sstevel@tonic-gate 		ctxtp->intr_flags &= ~HCI1394_ISO_CTXT_INUPDATE;
2380Sstevel@tonic-gate 		mutex_exit(&ctxtp->intrprocmutex);
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 		/* if DMA stopped or lost, formally stop context */
2410Sstevel@tonic-gate 		if (uv.upd_status == HCI1394_IXL_INTR_DMASTOP) {
2420Sstevel@tonic-gate 			hci1394_do_stop(soft_statep, ctxtp, B_TRUE,
2430Sstevel@tonic-gate 			    ID1394_DONE);
2440Sstevel@tonic-gate 		} else if (uv.upd_status == HCI1394_IXL_INTR_DMALOST) {
2450Sstevel@tonic-gate 			hci1394_do_stop(soft_statep, ctxtp, B_TRUE,
2460Sstevel@tonic-gate 			    ID1394_FAIL);
2470Sstevel@tonic-gate 		}
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 		*resultp = uv.upd_status;
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_exit,
2520Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
2530Sstevel@tonic-gate 		return (DDI_FAILURE);
2540Sstevel@tonic-gate 	}
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	/* perform interrupt processing cleanup */
2570Sstevel@tonic-gate 	uv.upd_status = hci1394_ixl_update_endup(&uv);
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 	/* return update completion status */
2600Sstevel@tonic-gate 	*resultp = uv.upd_status;
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_exit, HCI1394_TNF_HAL_STACK_ISOCH,
2630Sstevel@tonic-gate 	    "");
2640Sstevel@tonic-gate 	return (DDI_SUCCESS);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate /*
2680Sstevel@tonic-gate  * hci1394_ixl_update_enable
2690Sstevel@tonic-gate  *	Used to coordinate dynamic update activities with simultaneous
2700Sstevel@tonic-gate  *	interrupt handler processing, while holding the context mutex
2710Sstevel@tonic-gate  *      for as short a time as possible.
2720Sstevel@tonic-gate  */
2730Sstevel@tonic-gate static int
hci1394_ixl_update_enable(hci1394_ixl_update_vars_t * uvp)2740Sstevel@tonic-gate hci1394_ixl_update_enable(hci1394_ixl_update_vars_t *uvp)
2750Sstevel@tonic-gate {
2760Sstevel@tonic-gate 	int	status;
2770Sstevel@tonic-gate 	boolean_t retry;
2780Sstevel@tonic-gate 	uint_t	remretries;
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_enable_enter,
2810Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
2820Sstevel@tonic-gate 
2830Sstevel@tonic-gate 	retry = B_TRUE;
2840Sstevel@tonic-gate 	/* set arbitrary number of retries before giving up */
2850Sstevel@tonic-gate 	remretries = hci1394_upd_retries_before_fail;
2860Sstevel@tonic-gate 	status = DDI_SUCCESS;
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 	/*
2890Sstevel@tonic-gate 	 * if waited for completion of interrupt processing generated callback,
2900Sstevel@tonic-gate 	 * retry here
2910Sstevel@tonic-gate 	 */
2920Sstevel@tonic-gate 	ASSERT(MUTEX_NOT_HELD(&uvp->ctxtp->intrprocmutex));
2930Sstevel@tonic-gate 	mutex_enter(&uvp->ctxtp->intrprocmutex);
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	while (retry == B_TRUE) {
2960Sstevel@tonic-gate 		retry = B_FALSE;
2970Sstevel@tonic-gate 		remretries--;
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 		/* failure if update processing is already in progress */
3000Sstevel@tonic-gate 		if (uvp->ctxtp->intr_flags & HCI1394_ISO_CTXT_INUPDATE) {
3010Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EUPDATE_DISALLOWED;
3020Sstevel@tonic-gate 			status = DDI_FAILURE;
3030Sstevel@tonic-gate 		} else if (uvp->ctxtp->intr_flags & HCI1394_ISO_CTXT_ININTR) {
3040Sstevel@tonic-gate 			/*
3050Sstevel@tonic-gate 			 * if have retried max number of times or if this update
3060Sstevel@tonic-gate 			 * request is on the interrupt stack, which means that
3070Sstevel@tonic-gate 			 * the callback function of the target driver initiated
3080Sstevel@tonic-gate 			 * the update, set update failure.
3090Sstevel@tonic-gate 			 */
3100Sstevel@tonic-gate 			if ((remretries <= 0) ||
311*2273Sap25164 			    (servicing_interrupt())) {
3120Sstevel@tonic-gate 				uvp->upd_status = IXL1394_EUPDATE_DISALLOWED;
3130Sstevel@tonic-gate 				status = DDI_FAILURE;
3140Sstevel@tonic-gate 			} else {
3150Sstevel@tonic-gate 				/*
3160Sstevel@tonic-gate 				 * if not on interrupt stack and retries not
3170Sstevel@tonic-gate 				 * exhausted, free mutex, wait a short time
3180Sstevel@tonic-gate 				 * and then retry.
3190Sstevel@tonic-gate 				 */
3200Sstevel@tonic-gate 				retry = B_TRUE;
3210Sstevel@tonic-gate 				mutex_exit(&uvp->ctxtp->intrprocmutex);
3220Sstevel@tonic-gate 				drv_usecwait(1);
3230Sstevel@tonic-gate 				mutex_enter(&uvp->ctxtp->intrprocmutex);
3240Sstevel@tonic-gate 				continue;
3250Sstevel@tonic-gate 			}
3260Sstevel@tonic-gate 		} else if (uvp->ctxtp->intr_flags & HCI1394_ISO_CTXT_INCALL) {
3270Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EINTERNAL_ERROR;
3280Sstevel@tonic-gate 			status = DDI_FAILURE;
3290Sstevel@tonic-gate 		}
3300Sstevel@tonic-gate 	}
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 	/* if context is available, reserve it for this update request */
3330Sstevel@tonic-gate 	if (status == DDI_SUCCESS) {
3340Sstevel@tonic-gate 		uvp->ctxtp->intr_flags |= HCI1394_ISO_CTXT_INUPDATE;
3350Sstevel@tonic-gate 	}
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&uvp->ctxtp->intrprocmutex));
3380Sstevel@tonic-gate 	mutex_exit(&uvp->ctxtp->intrprocmutex);
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_enable_exit,
3410Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
3420Sstevel@tonic-gate 	return (status);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate /*
3460Sstevel@tonic-gate  * hci1394_ixl_update_endup()
3470Sstevel@tonic-gate  *    The ending stage of coordinating with simultaneously running interrupts.
3480Sstevel@tonic-gate  *    Perform interrupt processing sync tasks if we (update) had blocked the
3490Sstevel@tonic-gate  *    interrupt out when it wanted a turn.
3500Sstevel@tonic-gate  */
3510Sstevel@tonic-gate static int
hci1394_ixl_update_endup(hci1394_ixl_update_vars_t * uvp)3520Sstevel@tonic-gate hci1394_ixl_update_endup(hci1394_ixl_update_vars_t *uvp)
3530Sstevel@tonic-gate {
3540Sstevel@tonic-gate 	uint_t status;
3550Sstevel@tonic-gate 	hci1394_iso_ctxt_t *ctxtp;
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_endup_enter,
3580Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate 	status = HCI1394_IXL_INTR_NOERROR;
3610Sstevel@tonic-gate 	ctxtp = uvp->ctxtp;
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate 	while (ctxtp->intr_flags & HCI1394_ISO_CTXT_INUPDATE) {
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 		if (ctxtp->intr_flags & HCI1394_ISO_CTXT_INTRSET) {
3660Sstevel@tonic-gate 			/*
3670Sstevel@tonic-gate 			 * We don't need to grab the lock here because
3680Sstevel@tonic-gate 			 * the "intr_flags" field is only modified in two
3690Sstevel@tonic-gate 			 * ways - one in UPDATE and one in INTR routine. Since
3700Sstevel@tonic-gate 			 * we know that it can't be modified simulataneously
3710Sstevel@tonic-gate 			 * in another UDPATE thread - that is assured by the
3720Sstevel@tonic-gate 			 * checks in "update_enable" - we would only be trying
3730Sstevel@tonic-gate 			 * to protect against the INTR thread.  And since we
3740Sstevel@tonic-gate 			 * are going to clear a bit here (and check it again
3750Sstevel@tonic-gate 			 * at the top of the loop) we are not really concerned
3760Sstevel@tonic-gate 			 * about missing its being set by the INTR routine.
3770Sstevel@tonic-gate 			 */
3780Sstevel@tonic-gate 			ctxtp->intr_flags &= ~HCI1394_ISO_CTXT_INTRSET;
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 			status = hci1394_ixl_dma_sync(uvp->soft_statep, ctxtp);
3810Sstevel@tonic-gate 			if (status ==  HCI1394_IXL_INTR_DMALOST) {
3820Sstevel@tonic-gate 				/*
3830Sstevel@tonic-gate 				 * Unlike above, we do care here as we are
3840Sstevel@tonic-gate 				 * trying to clear the "in update" flag, and
3850Sstevel@tonic-gate 				 * we don't want that lost because the INTR
3860Sstevel@tonic-gate 				 * routine is trying to set its flag.
3870Sstevel@tonic-gate 				 */
3880Sstevel@tonic-gate 				mutex_enter(&uvp->ctxtp->intrprocmutex);
3890Sstevel@tonic-gate 				ctxtp->intr_flags &= ~HCI1394_ISO_CTXT_INUPDATE;
3900Sstevel@tonic-gate 				mutex_exit(&uvp->ctxtp->intrprocmutex);
3910Sstevel@tonic-gate 				continue;
3920Sstevel@tonic-gate 			}
3930Sstevel@tonic-gate 		}
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 		ASSERT(MUTEX_NOT_HELD(&uvp->ctxtp->intrprocmutex));
3960Sstevel@tonic-gate 		mutex_enter(&uvp->ctxtp->intrprocmutex);
3970Sstevel@tonic-gate 		if (!(ctxtp->intr_flags & HCI1394_ISO_CTXT_INTRSET)) {
3980Sstevel@tonic-gate 			ctxtp->intr_flags &= ~HCI1394_ISO_CTXT_INUPDATE;
3990Sstevel@tonic-gate 		}
4000Sstevel@tonic-gate 		mutex_exit(&uvp->ctxtp->intrprocmutex);
4010Sstevel@tonic-gate 	}
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate 	/* if DMA stopped or lost, formally stop context */
4040Sstevel@tonic-gate 	if (status == HCI1394_IXL_INTR_DMASTOP) {
4050Sstevel@tonic-gate 		hci1394_do_stop(uvp->soft_statep, ctxtp, B_TRUE, ID1394_DONE);
4060Sstevel@tonic-gate 	} else if (status == HCI1394_IXL_INTR_DMALOST) {
4070Sstevel@tonic-gate 		hci1394_do_stop(uvp->soft_statep, ctxtp, B_TRUE, ID1394_FAIL);
4080Sstevel@tonic-gate 	}
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_endup_exit,
4110Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
4120Sstevel@tonic-gate 	return (status);
4130Sstevel@tonic-gate }
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate /*
4160Sstevel@tonic-gate  * hci1394_ixl_update_prepare()
4170Sstevel@tonic-gate  *    Preparation for the actual update (using temp uvp struct)
4180Sstevel@tonic-gate  */
4190Sstevel@tonic-gate static int
hci1394_ixl_update_prepare(hci1394_ixl_update_vars_t * uvp)4200Sstevel@tonic-gate hci1394_ixl_update_prepare(hci1394_ixl_update_vars_t *uvp)
4210Sstevel@tonic-gate {
4220Sstevel@tonic-gate 	int		    ret;
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_enter,
4250Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 	/* both new and old ixl commands must be the same */
4280Sstevel@tonic-gate 	if (uvp->ixlnewp->ixl_opcode != uvp->ixloldp->ixl_opcode) {
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EOPCODE_MISMATCH;
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prepare_exit,
4330Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, msg,
4340Sstevel@tonic-gate 		    "EOPCODE_MISMATCH");
4350Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
4360Sstevel@tonic-gate 	}
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate 	/*
4390Sstevel@tonic-gate 	 * perform evaluation and prepare update based on specific
4400Sstevel@tonic-gate 	 * IXL command type
4410Sstevel@tonic-gate 	 */
4420Sstevel@tonic-gate 	switch (uvp->ixl_opcode) {
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate 	case IXL1394_OP_CALLBACK_U: {
4450Sstevel@tonic-gate 		ixl1394_callback_t *old_callback_ixlp;
4460Sstevel@tonic-gate 		ixl1394_callback_t *new_callback_ixlp;
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate 		old_callback_ixlp = (ixl1394_callback_t *)uvp->ixloldp;
4490Sstevel@tonic-gate 		new_callback_ixlp = (ixl1394_callback_t *)uvp->ixlnewp;
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 		/* perform update now without further evaluation */
4520Sstevel@tonic-gate 		old_callback_ixlp->callback_arg =
4530Sstevel@tonic-gate 		    new_callback_ixlp->callback_arg;
4540Sstevel@tonic-gate 		old_callback_ixlp->callback = new_callback_ixlp->callback;
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate 		/* nothing else to do, return with done ok status */
4570Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
4580Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
4590Sstevel@tonic-gate 		return (IXL_PREP_SUCCESS);
4600Sstevel@tonic-gate 	}
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 	case IXL1394_OP_JUMP_U:
4630Sstevel@tonic-gate 		ret = hci1394_ixl_update_prep_jump(uvp);
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
4660Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
4670Sstevel@tonic-gate 		return (ret);
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 	case IXL1394_OP_SET_SKIPMODE_U:
4700Sstevel@tonic-gate 		ret = hci1394_ixl_update_prep_set_skipmode(uvp);
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
4730Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
4740Sstevel@tonic-gate 		return (ret);
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 	case IXL1394_OP_SET_TAGSYNC_U:
4770Sstevel@tonic-gate 		ret = hci1394_ixl_update_prep_set_tagsync(uvp);
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
4800Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
4810Sstevel@tonic-gate 		return (ret);
4820Sstevel@tonic-gate 
4830Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT_U:
4840Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT_ST_U:
4850Sstevel@tonic-gate 		ret = hci1394_ixl_update_prep_recv_pkt(uvp);
4860Sstevel@tonic-gate 
4870Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
4880Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
4890Sstevel@tonic-gate 		return (ret);
4900Sstevel@tonic-gate 
4910Sstevel@tonic-gate 	case IXL1394_OP_RECV_BUF_U:
4920Sstevel@tonic-gate 		ret = hci1394_ixl_update_prep_recv_buf(uvp);
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
4950Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
4960Sstevel@tonic-gate 		return (ret);
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_U:
4990Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_ST_U:
5000Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_WHDR_ST_U:
5010Sstevel@tonic-gate 		ret = hci1394_ixl_update_prep_send_pkt(uvp);
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
5040Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
5050Sstevel@tonic-gate 		return (ret);
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate 	case IXL1394_OP_SEND_BUF_U:
5080Sstevel@tonic-gate 		ret = hci1394_ixl_update_prep_send_buf(uvp);
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
5110Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
5120Sstevel@tonic-gate 		return (ret);
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 	default:
5150Sstevel@tonic-gate 		/* ixl command being updated must be one of above, else error */
5160Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EOPCODE_DISALLOWED;
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prepare_exit,
5190Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
5200Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
5210Sstevel@tonic-gate 	}
5220Sstevel@tonic-gate }
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate /*
5250Sstevel@tonic-gate  * hci1394_ixl_update_prep_jump()
5260Sstevel@tonic-gate  *    Preparation for update of an IXL1394_OP_JUMP_U command.
5270Sstevel@tonic-gate  */
5280Sstevel@tonic-gate static int
hci1394_ixl_update_prep_jump(hci1394_ixl_update_vars_t * uvp)5290Sstevel@tonic-gate hci1394_ixl_update_prep_jump(hci1394_ixl_update_vars_t *uvp)
5300Sstevel@tonic-gate {
5310Sstevel@tonic-gate 	ixl1394_jump_t	    *old_jump_ixlp;
5320Sstevel@tonic-gate 	ixl1394_jump_t	    *new_jump_ixlp;
5330Sstevel@tonic-gate 	ixl1394_command_t   *ixlp;
5340Sstevel@tonic-gate 	hci1394_xfer_ctl_t  *xferctlp;
5350Sstevel@tonic-gate 	hci1394_desc_t	    *hcidescp;
5360Sstevel@tonic-gate 	uint_t		    cbcnt;
5370Sstevel@tonic-gate 	ddi_acc_handle_t    acc_hdl;
5380Sstevel@tonic-gate 	ddi_dma_handle_t    dma_hdl;
5390Sstevel@tonic-gate 	uint32_t	    desc_hdr;
5400Sstevel@tonic-gate 	int		    err;
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_jump_enter,
5430Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	old_jump_ixlp = (ixl1394_jump_t *)uvp->ixloldp;
5460Sstevel@tonic-gate 	new_jump_ixlp = (ixl1394_jump_t *)uvp->ixlnewp;
5470Sstevel@tonic-gate 
5480Sstevel@tonic-gate 	/* check if any change between new and old ixl jump command */
5490Sstevel@tonic-gate 	if (new_jump_ixlp->label == old_jump_ixlp->label) {
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 		/* if none, return with done ok status */
5520Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_jump_exit,
5530Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
5540Sstevel@tonic-gate 		return (IXL_PREP_SUCCESS);
5550Sstevel@tonic-gate 	}
5560Sstevel@tonic-gate 
5570Sstevel@tonic-gate 	/* new ixl jump command label must be ptr to valid ixl label or NULL */
5580Sstevel@tonic-gate 	if ((new_jump_ixlp->label != NULL) &&
5590Sstevel@tonic-gate 	    (new_jump_ixlp->label->ixl_opcode != IXL1394_OP_LABEL)) {
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate 		/* if not jumping to label, return an error */
5620Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EJUMP_NOT_TO_LABEL;
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prepare_exit,
5650Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, errmsg,
5660Sstevel@tonic-gate 		    "EJUMP_NOT_TO_LABEL");
5670Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
5680Sstevel@tonic-gate 	}
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate 	/*
5710Sstevel@tonic-gate 	 * follow exec path from new ixl jump command label to determine new
5720Sstevel@tonic-gate 	 * jump destination ixl xfer command
5730Sstevel@tonic-gate 	 */
5740Sstevel@tonic-gate 	(void) hci1394_ixl_find_next_exec_xfer(new_jump_ixlp->label, &cbcnt,
5750Sstevel@tonic-gate 	    &ixlp);
5760Sstevel@tonic-gate 	if (ixlp != NULL) {
5770Sstevel@tonic-gate 		/*
5780Sstevel@tonic-gate 		 * get the bound address of the first descriptor block reached
5790Sstevel@tonic-gate 		 * by the jump destination.  (This descriptor is the first
5800Sstevel@tonic-gate 		 * transfer command following the jumped-to label.)  Set the
5810Sstevel@tonic-gate 		 * descriptor's address (with Z bits) into jumpaddr.
5820Sstevel@tonic-gate 		 */
5830Sstevel@tonic-gate 		uvp->jumpaddr = ((hci1394_xfer_ctl_t *)
5840Sstevel@tonic-gate 		    ixlp->compiler_privatep)->dma[0].dma_bound;
5850Sstevel@tonic-gate 	}
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 	/*
5880Sstevel@tonic-gate 	 * get associated xfer IXL command from compiler_privatep of old
5890Sstevel@tonic-gate 	 * jump command
5900Sstevel@tonic-gate 	 */
5910Sstevel@tonic-gate 	if ((uvp->ixlxferp = (ixl1394_command_t *)
5920Sstevel@tonic-gate 	    old_jump_ixlp->compiler_privatep) == NULL) {
5930Sstevel@tonic-gate 
5940Sstevel@tonic-gate 		/* if none, return an error */
5950Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prep_jump_exit,
5980Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, errmsg,
5990Sstevel@tonic-gate 		    "EORIG_IXL_CORRUPTED");
6000Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
6010Sstevel@tonic-gate 	}
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate 	/*
6040Sstevel@tonic-gate 	 * get the associated IXL xfer command's last dma descriptor block
6050Sstevel@tonic-gate 	 * last descriptor, then get hcihdr from its hdr field,
6060Sstevel@tonic-gate 	 * removing interrupt enabled bits
6070Sstevel@tonic-gate 	 */
6080Sstevel@tonic-gate 	xferctlp = (hci1394_xfer_ctl_t *)uvp->ixlxferp->compiler_privatep;
6090Sstevel@tonic-gate 	hcidescp = (hci1394_desc_t *)xferctlp->dma[xferctlp->cnt - 1].dma_descp;
6100Sstevel@tonic-gate 	acc_hdl  = xferctlp->dma[xferctlp->cnt - 1].dma_buf->bi_handle;
6110Sstevel@tonic-gate 	dma_hdl  = xferctlp->dma[xferctlp->cnt - 1].dma_buf->bi_dma_handle;
6120Sstevel@tonic-gate 
6130Sstevel@tonic-gate 	/* Sync the descriptor before we grab the header(s) */
6140Sstevel@tonic-gate 	err = ddi_dma_sync(dma_hdl, (off_t)hcidescp, sizeof (hci1394_desc_t),
6150Sstevel@tonic-gate 	    DDI_DMA_SYNC_FORCPU);
6160Sstevel@tonic-gate 	if (err != DDI_SUCCESS) {
6170Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EINTERNAL_ERROR;
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prep_jump_exit,
6200Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, errmsg,
6210Sstevel@tonic-gate 		    "EINTERNAL_ERROR: dma_sync() failed");
6220Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
6230Sstevel@tonic-gate 	}
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate 	desc_hdr = ddi_get32(acc_hdl, &hcidescp->hdr);
6260Sstevel@tonic-gate 	uvp->hcihdr = desc_hdr & ~DESC_INTR_ENBL;
6270Sstevel@tonic-gate 
6280Sstevel@tonic-gate 	/* set depth to last dma descriptor block & update count to 1 */
6290Sstevel@tonic-gate 	uvp->ixldepth = xferctlp->cnt - 1;
6300Sstevel@tonic-gate 	uvp->ixlcount = 1;
6310Sstevel@tonic-gate 
6320Sstevel@tonic-gate 	/*
6330Sstevel@tonic-gate 	 * if there is only one dma descriptor block and IXL xfer command
6340Sstevel@tonic-gate 	 * inited by a label or have found callbacks along the exec path to the
6350Sstevel@tonic-gate 	 * new destination IXL xfer command, enable interrupt in hcihdr value
6360Sstevel@tonic-gate 	 */
6370Sstevel@tonic-gate 	if (((xferctlp->cnt == 1) &&
6380Sstevel@tonic-gate 	    ((xferctlp->ctl_flags & XCTL_LABELLED) != 0)) || (cbcnt != 0)) {
6390Sstevel@tonic-gate 
6400Sstevel@tonic-gate 		uvp->hcihdr |= DESC_INTR_ENBL;
6410Sstevel@tonic-gate 	}
6420Sstevel@tonic-gate 
6430Sstevel@tonic-gate 	/* If either old or new destination was/is NULL, enable interrupt */
6440Sstevel@tonic-gate 	if ((new_jump_ixlp->label == NULL) || (old_jump_ixlp->label == NULL)) {
6450Sstevel@tonic-gate 		uvp->hcihdr |= DESC_INTR_ENBL;
6460Sstevel@tonic-gate 	}
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate 	/*
6490Sstevel@tonic-gate 	 * if xfer type is xmit and skip mode for this for this xfer command is
6500Sstevel@tonic-gate 	 * IXL1394_SKIP_TO_NEXT then set uvp->skipmode to IXL1394_SKIP_TO_NEXT
6510Sstevel@tonic-gate 	 * and set uvp->skipxferp to uvp->jumpaddr and set uvp->hci_offset to
6520Sstevel@tonic-gate 	 * offset from last dma descriptor to first dma descriptor
6530Sstevel@tonic-gate 	 * (where skipaddr goes).
6540Sstevel@tonic-gate 	 *
6550Sstevel@tonic-gate 	 * update perform processing will have to set skip branch address to
6560Sstevel@tonic-gate 	 * same location as jump destination in this case.
6570Sstevel@tonic-gate 	 */
6580Sstevel@tonic-gate 	uvp->skipmode = IXL1394_SKIP_TO_STOP;
6590Sstevel@tonic-gate 	if ((uvp->ixlxferp->ixl_opcode & IXL1394_OPF_ONXMIT) != 0) {
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 		if ((xferctlp->skipmodep && (((ixl1394_set_skipmode_t *)
6620Sstevel@tonic-gate 		    xferctlp->skipmodep)->skipmode == IXL1394_SKIP_TO_NEXT)) ||
6630Sstevel@tonic-gate 		    (uvp->ctxtp->default_skipmode == IXL1394_OPF_ONXMIT)) {
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate 			uvp->skipmode = IXL1394_SKIP_TO_NEXT;
6660Sstevel@tonic-gate 			uvp->skipaddr = uvp->jumpaddr;
6670Sstevel@tonic-gate 
6680Sstevel@tonic-gate 			/*
6690Sstevel@tonic-gate 			 * calc hci_offset to first descriptor (where skipaddr
6700Sstevel@tonic-gate 			 * goes) of dma descriptor block from current (last)
6710Sstevel@tonic-gate 			 * descriptor of the descriptor block (accessed in
6720Sstevel@tonic-gate 			 * xfer_ctl dma_descp of IXL xfer command)
6730Sstevel@tonic-gate 			 */
6740Sstevel@tonic-gate 			if (uvp->ixlxferp->ixl_opcode ==
6750Sstevel@tonic-gate 			    IXL1394_OP_SEND_HDR_ONLY) {
6760Sstevel@tonic-gate 				/*
6770Sstevel@tonic-gate 				 * send header only is (Z bits - 2)
6780Sstevel@tonic-gate 				 * descriptor components back from last one
6790Sstevel@tonic-gate 				 */
6800Sstevel@tonic-gate 				uvp->hci_offset -= 2;
6810Sstevel@tonic-gate 			} else {
6820Sstevel@tonic-gate 				/*
6830Sstevel@tonic-gate 				 * all others are (Z bits - 1) descriptor
6840Sstevel@tonic-gate 				 * components back from last component
6850Sstevel@tonic-gate 				 */
6860Sstevel@tonic-gate 				uvp->hci_offset -= 1;
6870Sstevel@tonic-gate 			}
6880Sstevel@tonic-gate 		}
6890Sstevel@tonic-gate 	}
6900Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_jump_exit,
6910Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
6920Sstevel@tonic-gate 	return (IXL_PREP_READY);
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate /*
6960Sstevel@tonic-gate  * hci1394_ixl_update_prep_set_skipmode()
6970Sstevel@tonic-gate  *    Preparation for update of an IXL1394_OP_SET_SKIPMODE_U command.
6980Sstevel@tonic-gate  */
6990Sstevel@tonic-gate static int
hci1394_ixl_update_prep_set_skipmode(hci1394_ixl_update_vars_t * uvp)7000Sstevel@tonic-gate hci1394_ixl_update_prep_set_skipmode(hci1394_ixl_update_vars_t *uvp)
7010Sstevel@tonic-gate {
7020Sstevel@tonic-gate 	ixl1394_set_skipmode_t	*old_set_skipmode_ixlp;
7030Sstevel@tonic-gate 	ixl1394_set_skipmode_t	*new_set_skipmode_ixlp;
7040Sstevel@tonic-gate 	ixl1394_command_t	*ixlp;
7050Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xferctlp;
7060Sstevel@tonic-gate 
7070Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_skipmode_enter,
7080Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate 	old_set_skipmode_ixlp = (ixl1394_set_skipmode_t *)uvp->ixloldp;
7110Sstevel@tonic-gate 	new_set_skipmode_ixlp = (ixl1394_set_skipmode_t *)uvp->ixlnewp;
7120Sstevel@tonic-gate 
7130Sstevel@tonic-gate 	/* check if new set skipmode is change from old set skipmode */
7140Sstevel@tonic-gate 	if (new_set_skipmode_ixlp->skipmode ==
7150Sstevel@tonic-gate 	    old_set_skipmode_ixlp->skipmode) {
7160Sstevel@tonic-gate 
7170Sstevel@tonic-gate 		if ((new_set_skipmode_ixlp->skipmode !=
7180Sstevel@tonic-gate 		    IXL1394_SKIP_TO_LABEL) ||
7190Sstevel@tonic-gate 		    (old_set_skipmode_ixlp->label ==
7200Sstevel@tonic-gate 		    new_set_skipmode_ixlp->label)) {
7210Sstevel@tonic-gate 
7220Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(
7230Sstevel@tonic-gate 				hci1394_ixl_update_prep_set_skipmode_exit,
7240Sstevel@tonic-gate 				HCI1394_TNF_HAL_STACK_ISOCH, "");
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 			/* No change, return with done ok status */
7270Sstevel@tonic-gate 			return (IXL_PREP_SUCCESS);
7280Sstevel@tonic-gate 		}
7290Sstevel@tonic-gate 	}
7300Sstevel@tonic-gate 
7310Sstevel@tonic-gate 	/* find associated ixl xfer commnd by following old ixl links */
7320Sstevel@tonic-gate 	uvp->ixlxferp = uvp->ixloldp->next_ixlp;
7330Sstevel@tonic-gate 	while ((uvp->ixlxferp != NULL) && (((uvp->ixlxferp->ixl_opcode &
7340Sstevel@tonic-gate 	    IXL1394_OPF_ISXFER) == 0) ||
7350Sstevel@tonic-gate 	    ((uvp->ixlxferp->ixl_opcode & IXL1394_OPTY_MASK) !=	0))) {
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate 		uvp->ixlxferp = uvp->ixlxferp->next_ixlp;
7380Sstevel@tonic-gate 	}
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 	/* return an error if no ixl xfer command found */
7410Sstevel@tonic-gate 	if (uvp->ixlxferp == NULL) {
7420Sstevel@tonic-gate 
7430Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
7440Sstevel@tonic-gate 
7450Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prep_set_skipmode_exit,
7460Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string,
7470Sstevel@tonic-gate 		    errmsg, "EORIG_IXL_CORRUPTED");
7480Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
7490Sstevel@tonic-gate 	}
7500Sstevel@tonic-gate 
7510Sstevel@tonic-gate 	/*
7520Sstevel@tonic-gate 	 * get Z bits (number of descriptor components in descriptor block)
7530Sstevel@tonic-gate 	 * from a dma bound addr in the xfer_ctl struct of the IXL xfer command
7540Sstevel@tonic-gate 	 */
7550Sstevel@tonic-gate 	if ((xferctlp = (hci1394_xfer_ctl_t *)
7560Sstevel@tonic-gate 	    uvp->ixlxferp->compiler_privatep) == NULL) {
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prep_set_skipmode_exit,
7610Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, errmsg,
7620Sstevel@tonic-gate 		    "EORIG_IXL_CORRUPTED");
7630Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
7640Sstevel@tonic-gate 	}
7650Sstevel@tonic-gate 	uvp->hci_offset = xferctlp->dma[0].dma_bound & DESC_Z_MASK;
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate 	/*
7680Sstevel@tonic-gate 	 * determine hci_offset to first component (where skipaddr goes) of
7690Sstevel@tonic-gate 	 * dma descriptor block from current (last) descriptor component of
7700Sstevel@tonic-gate 	 * desciptor block (accessed in xfer_ctl dma_descp of IXL xfer command)
7710Sstevel@tonic-gate 	 */
7720Sstevel@tonic-gate 	if (uvp->ixlxferp->ixl_opcode == IXL1394_OP_SEND_HDR_ONLY) {
7730Sstevel@tonic-gate 		/*
7740Sstevel@tonic-gate 		 * "send header only" is (Z bits - 2) descriptors back
7750Sstevel@tonic-gate 		 * from last one
7760Sstevel@tonic-gate 		 */
7770Sstevel@tonic-gate 		uvp->hci_offset -= 2;
7780Sstevel@tonic-gate 	} else {
7790Sstevel@tonic-gate 		/*
7800Sstevel@tonic-gate 		 * all others are (Z bits - 1) descroptors back from
7810Sstevel@tonic-gate 		 * last descriptor.
7820Sstevel@tonic-gate 		 */
7830Sstevel@tonic-gate 		uvp->hci_offset -= 1;
7840Sstevel@tonic-gate 	}
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate 	/* set depth to zero and count to update all dma descriptors */
7870Sstevel@tonic-gate 	uvp->ixldepth = 0;
7880Sstevel@tonic-gate 	uvp->ixlcount = xferctlp->cnt;
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate 	/* set new skipmode and validate */
7910Sstevel@tonic-gate 	uvp->skipmode = new_set_skipmode_ixlp->skipmode;
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 	if ((uvp->skipmode != IXL1394_SKIP_TO_NEXT) &&
7940Sstevel@tonic-gate 	    (uvp->skipmode != IXL1394_SKIP_TO_SELF) &&
7950Sstevel@tonic-gate 	    (uvp->skipmode != IXL1394_SKIP_TO_STOP) &&
7960Sstevel@tonic-gate 	    (uvp->skipmode != IXL1394_SKIP_TO_LABEL)) {
7970Sstevel@tonic-gate 
7980Sstevel@tonic-gate 		/* return an error if invalid mode */
7990Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EBAD_SKIPMODE;
8000Sstevel@tonic-gate 
8010Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prep_set_skipmode_exit,
8020Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string,
8030Sstevel@tonic-gate 		    errmsg, "EBAD_SKIPMODE");
8040Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
8050Sstevel@tonic-gate 	}
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 	/* if mode is skip to label */
8080Sstevel@tonic-gate 	if (uvp->skipmode == IXL1394_SKIP_TO_LABEL) {
8090Sstevel@tonic-gate 
8100Sstevel@tonic-gate 		/* verify label field is valid ixl label cmd */
8110Sstevel@tonic-gate 		if ((new_set_skipmode_ixlp->label == NULL) ||
8120Sstevel@tonic-gate 		    (new_set_skipmode_ixlp->label->ixl_opcode !=
8130Sstevel@tonic-gate 			IXL1394_OP_LABEL)) {
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 			/* Error - not skipping to valid label */
8160Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EBAD_SKIP_LABEL;
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(
8190Sstevel@tonic-gate 				hci1394_ixl_update_prep_set_skipmode_exit,
8200Sstevel@tonic-gate 				HCI1394_TNF_HAL_STACK_ISOCH, "");
8210Sstevel@tonic-gate 			return (IXL_PREP_FAILURE);
8220Sstevel@tonic-gate 		}
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 		/*
8250Sstevel@tonic-gate 		 * follow new skip exec path after label to next xfer
8260Sstevel@tonic-gate 		 * IXL command
8270Sstevel@tonic-gate 		 */
8280Sstevel@tonic-gate 		(void) hci1394_ixl_find_next_exec_xfer(
8290Sstevel@tonic-gate 			new_set_skipmode_ixlp->label, NULL, &ixlp);
8300Sstevel@tonic-gate 
8310Sstevel@tonic-gate 		/*
8320Sstevel@tonic-gate 		 * set skip destination IXL xfer command.
8330Sstevel@tonic-gate 		 * after update set into old set skip mode IXL compiler_privatep
8340Sstevel@tonic-gate 		 */
8350Sstevel@tonic-gate 		if ((uvp->skipxferp = ixlp) != NULL) {
8360Sstevel@tonic-gate 			/*
8370Sstevel@tonic-gate 			 * set skipaddr to be the first dma descriptor block's
8380Sstevel@tonic-gate 			 * dma bound address w/Z bits
8390Sstevel@tonic-gate 			 */
8400Sstevel@tonic-gate 			xferctlp = (hci1394_xfer_ctl_t *)
8410Sstevel@tonic-gate 			    ixlp->compiler_privatep;
8420Sstevel@tonic-gate 			uvp->skipaddr = xferctlp->dma[0].dma_bound;
8430Sstevel@tonic-gate 		}
8440Sstevel@tonic-gate 	}
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate 	/*
8470Sstevel@tonic-gate 	 * if mode is skip to next, get skipaddr for last dma descriptor block
8480Sstevel@tonic-gate 	 */
8490Sstevel@tonic-gate 	if (uvp->skipmode == IXL1394_SKIP_TO_NEXT) {
8500Sstevel@tonic-gate 		/* follow normal exec path to next xfer ixl command */
8510Sstevel@tonic-gate 		(void) hci1394_ixl_find_next_exec_xfer(uvp->ixlxferp->next_ixlp,
8520Sstevel@tonic-gate 		    NULL, &ixlp);
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 		/*
8550Sstevel@tonic-gate 		 * get skip_next destination IXL xfer command
8560Sstevel@tonic-gate 		 * (for last iteration)
8570Sstevel@tonic-gate 		 */
8580Sstevel@tonic-gate 		if (ixlp != NULL) {
8590Sstevel@tonic-gate 			/*
8600Sstevel@tonic-gate 			 * set skipaddr to first dma descriptor block's
8610Sstevel@tonic-gate 			 * dma bound address w/Z bits
8620Sstevel@tonic-gate 			 */
8630Sstevel@tonic-gate 			xferctlp = (hci1394_xfer_ctl_t *)
8640Sstevel@tonic-gate 			    ixlp->compiler_privatep;
8650Sstevel@tonic-gate 			uvp->skipaddr = xferctlp->dma[0].dma_bound;
8660Sstevel@tonic-gate 		}
8670Sstevel@tonic-gate 	}
8680Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_skipmode_exit,
8690Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
8700Sstevel@tonic-gate 	return (IXL_PREP_READY);
8710Sstevel@tonic-gate }
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate /*
8740Sstevel@tonic-gate  * hci1394_ixl_update_prep_set_tagsync()
8750Sstevel@tonic-gate  *    Preparation for update of an IXL1394_OP_SET_TAGSYNC_U command.
8760Sstevel@tonic-gate  */
8770Sstevel@tonic-gate static int
hci1394_ixl_update_prep_set_tagsync(hci1394_ixl_update_vars_t * uvp)8780Sstevel@tonic-gate hci1394_ixl_update_prep_set_tagsync(hci1394_ixl_update_vars_t *uvp)
8790Sstevel@tonic-gate {
8800Sstevel@tonic-gate 	ixl1394_set_tagsync_t	*old_set_tagsync_ixlp;
8810Sstevel@tonic-gate 	ixl1394_set_tagsync_t	*new_set_tagsync_ixlp;
8820Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xferctlp;
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_tagsync_enter,
8850Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
8860Sstevel@tonic-gate 
8870Sstevel@tonic-gate 	old_set_tagsync_ixlp = (ixl1394_set_tagsync_t *)uvp->ixloldp;
8880Sstevel@tonic-gate 	new_set_tagsync_ixlp = (ixl1394_set_tagsync_t *)uvp->ixlnewp;
8890Sstevel@tonic-gate 
8900Sstevel@tonic-gate 	/* check if new set tagsync is change from old set tagsync. */
8910Sstevel@tonic-gate 	if ((new_set_tagsync_ixlp->tag == old_set_tagsync_ixlp->tag) &&
8920Sstevel@tonic-gate 	    (new_set_tagsync_ixlp->sync == old_set_tagsync_ixlp->sync)) {
8930Sstevel@tonic-gate 
8940Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_tagsync_exit,
8950Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
8960Sstevel@tonic-gate 
8970Sstevel@tonic-gate 		/* no change, return with done ok status */
8980Sstevel@tonic-gate 		return (IXL_PREP_SUCCESS);
8990Sstevel@tonic-gate 	}
9000Sstevel@tonic-gate 
9010Sstevel@tonic-gate 	/* find associated IXL xfer commnd by following old ixl links */
9020Sstevel@tonic-gate 	uvp->ixlxferp = uvp->ixloldp->next_ixlp;
9030Sstevel@tonic-gate 	while ((uvp->ixlxferp != NULL) && (((uvp->ixlxferp->ixl_opcode &
9040Sstevel@tonic-gate 	    IXL1394_OPF_ISXFER) == 0) ||
9050Sstevel@tonic-gate 	    ((uvp->ixlxferp->ixl_opcode & IXL1394_OPTY_MASK) != 0))) {
9060Sstevel@tonic-gate 
9070Sstevel@tonic-gate 		uvp->ixlxferp = uvp->ixlxferp->next_ixlp;
9080Sstevel@tonic-gate 	}
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 	/* return an error if no IXL xfer command found */
9110Sstevel@tonic-gate 	if (uvp->ixlxferp == NULL) {
9120Sstevel@tonic-gate 
9130Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
9140Sstevel@tonic-gate 
9150Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_tagsync_exit,
9160Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
9170Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
9180Sstevel@tonic-gate 	}
9190Sstevel@tonic-gate 
9200Sstevel@tonic-gate 	/* is IXL xfer command an IXL1394_OP_SEND_NO_PKT? */
9210Sstevel@tonic-gate 	if (uvp->ixlxferp->ixl_opcode == IXL1394_OP_SEND_NO_PKT) {
9220Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_tagsync_exit,
9230Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
9240Sstevel@tonic-gate 
9250Sstevel@tonic-gate 		/* no update needed, return done ok status */
9260Sstevel@tonic-gate 		return (IXL_PREP_SUCCESS);
9270Sstevel@tonic-gate 	}
9280Sstevel@tonic-gate 
9290Sstevel@tonic-gate 	/* build new pkthdr1 from new IXL tag/sync bits */
9300Sstevel@tonic-gate 	uvp->pkthdr1 = (uvp->ctxtp->isospd << DESC_PKT_SPD_SHIFT) |
9310Sstevel@tonic-gate 	    (new_set_tagsync_ixlp->tag << DESC_PKT_TAG_SHIFT) |
9320Sstevel@tonic-gate 	    (uvp->ctxtp->isochan << DESC_PKT_CHAN_SHIFT) |
9330Sstevel@tonic-gate 	    (new_set_tagsync_ixlp->sync << DESC_PKT_SY_SHIFT);
9340Sstevel@tonic-gate 
9350Sstevel@tonic-gate 	/*
9360Sstevel@tonic-gate 	 * get Z bits (# of descriptor components in descriptor block) from
9370Sstevel@tonic-gate 	 * any dma bound address in the xfer_ctl struct of the IXL xfer cmd
9380Sstevel@tonic-gate 	 */
9390Sstevel@tonic-gate 	if ((xferctlp =	(hci1394_xfer_ctl_t *)
9400Sstevel@tonic-gate 	    uvp->ixlxferp->compiler_privatep) == NULL) {
9410Sstevel@tonic-gate 
9420Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
9430Sstevel@tonic-gate 
9440Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_tagsync_exit,
9450Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
9460Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
9470Sstevel@tonic-gate 	}
9480Sstevel@tonic-gate 	uvp->hdr_offset = xferctlp->dma[0].dma_bound & DESC_Z_MASK;
9490Sstevel@tonic-gate 
9500Sstevel@tonic-gate 	/*
9510Sstevel@tonic-gate 	 * determine hdr_offset from the current(last) descriptor of the
9520Sstevel@tonic-gate 	 * DMA descriptor block to the descriptor where pkthdr1 goes
9530Sstevel@tonic-gate 	 * by examining IXL xfer command
9540Sstevel@tonic-gate 	 */
9550Sstevel@tonic-gate 	if (uvp->ixlxferp->ixl_opcode == IXL1394_OP_SEND_HDR_ONLY) {
9560Sstevel@tonic-gate 		/*
9570Sstevel@tonic-gate 		 * if IXL send header only, the current (last)
9580Sstevel@tonic-gate 		 * descriptor is the one
9590Sstevel@tonic-gate 		 */
9600Sstevel@tonic-gate 		uvp->hdr_offset = 0;
9610Sstevel@tonic-gate 	} else {
9620Sstevel@tonic-gate 		/*
9630Sstevel@tonic-gate 		 * all others are the first descriptor (Z bits - 1)
9640Sstevel@tonic-gate 		 * back from the last
9650Sstevel@tonic-gate 		 */
9660Sstevel@tonic-gate 		uvp->hdr_offset -= 1;
9670Sstevel@tonic-gate 	}
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate 	/* set depth to zero and count to update all dma descriptors */
9700Sstevel@tonic-gate 	uvp->ixldepth = 0;
9710Sstevel@tonic-gate 	uvp->ixlcount = xferctlp->cnt;
9720Sstevel@tonic-gate 
9730Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_set_tagsync_exit,
9740Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
9750Sstevel@tonic-gate 	return (IXL_PREP_READY);
9760Sstevel@tonic-gate }
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate /*
9790Sstevel@tonic-gate  * hci1394_ixl_update_prep_recv_pkt()
9800Sstevel@tonic-gate  *    Preparation for update of an IXL1394_OP_RECV_PKT_U or
9810Sstevel@tonic-gate  *    IXL1394_OP_RECV_PKT_ST_U command.
9820Sstevel@tonic-gate  */
9830Sstevel@tonic-gate static int
hci1394_ixl_update_prep_recv_pkt(hci1394_ixl_update_vars_t * uvp)9840Sstevel@tonic-gate hci1394_ixl_update_prep_recv_pkt(hci1394_ixl_update_vars_t *uvp)
9850Sstevel@tonic-gate {
9860Sstevel@tonic-gate 	ixl1394_xfer_pkt_t *old_xfer_pkt_ixlp;
9870Sstevel@tonic-gate 	ixl1394_xfer_pkt_t *new_xfer_pkt_ixlp;
9880Sstevel@tonic-gate 	hci1394_xfer_ctl_t *xferctlp;
9890Sstevel@tonic-gate 	hci1394_desc_t	   *hcidescp;
9900Sstevel@tonic-gate 	ddi_acc_handle_t   acc_hdl;
9910Sstevel@tonic-gate 	ddi_dma_handle_t   dma_hdl;
9920Sstevel@tonic-gate 	uint32_t	   desc_hdr;
9930Sstevel@tonic-gate 	int		   err;
9940Sstevel@tonic-gate 
9950Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_pkt_enter,
9960Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
9970Sstevel@tonic-gate 
9980Sstevel@tonic-gate 	old_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixloldp;
9990Sstevel@tonic-gate 	new_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixlnewp;
10000Sstevel@tonic-gate 
10010Sstevel@tonic-gate 	/* check if any change between new and old IXL xfer commands */
10020Sstevel@tonic-gate 	if ((new_xfer_pkt_ixlp->size == old_xfer_pkt_ixlp->size) &&
10030Sstevel@tonic-gate 	    (new_xfer_pkt_ixlp->ixl_buf.ixldmac_addr ==
10040Sstevel@tonic-gate 		old_xfer_pkt_ixlp->ixl_buf.ixldmac_addr) &&
10050Sstevel@tonic-gate 	    (new_xfer_pkt_ixlp->mem_bufp == old_xfer_pkt_ixlp->mem_bufp)) {
10060Sstevel@tonic-gate 
10070Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_pkt_exit,
10080Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate 		/* no change. return with done ok status */
10110Sstevel@tonic-gate 		return (IXL_PREP_SUCCESS);
10120Sstevel@tonic-gate 	}
10130Sstevel@tonic-gate 
10140Sstevel@tonic-gate 	/* if new IXL buffer addrs are null, return error */
10150Sstevel@tonic-gate 	if ((new_xfer_pkt_ixlp->ixl_buf.ixldmac_addr == NULL) ||
10160Sstevel@tonic-gate 	    (new_xfer_pkt_ixlp->mem_bufp == NULL)) {
10170Sstevel@tonic-gate 
10180Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EXFER_BUF_MISSING;
10190Sstevel@tonic-gate 
10200Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_pkt_exit,
10210Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
10220Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
10230Sstevel@tonic-gate 	}
10240Sstevel@tonic-gate 
10250Sstevel@tonic-gate 	/* if IXL xfer command is not xfer start command */
10260Sstevel@tonic-gate 	if (uvp->ixl_opcode == IXL1394_OP_RECV_PKT_U) {
10270Sstevel@tonic-gate 		/*
10280Sstevel@tonic-gate 		 * find IXL xfer start command in the compiler_privatep of the
10290Sstevel@tonic-gate 		 * old IXL xfer command
10300Sstevel@tonic-gate 		 */
10310Sstevel@tonic-gate 		uvp->ixlxferp = (ixl1394_command_t *)
10320Sstevel@tonic-gate 		    uvp->ixloldp->compiler_privatep;
10330Sstevel@tonic-gate 
10340Sstevel@tonic-gate 		if (uvp->ixlxferp == NULL) {
10350Sstevel@tonic-gate 
10360Sstevel@tonic-gate 			/* Error - no IXL xfer start command found */
10370Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
10380Sstevel@tonic-gate 
10390Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_pkt_exit,
10400Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
10410Sstevel@tonic-gate 			return (IXL_PREP_FAILURE);
10420Sstevel@tonic-gate 		}
10430Sstevel@tonic-gate 	} else {
10440Sstevel@tonic-gate 		/* IXL xfer command is the IXL xfer start command */
10450Sstevel@tonic-gate 		uvp->ixlxferp = uvp->ixloldp;
10460Sstevel@tonic-gate 	}
10470Sstevel@tonic-gate 
10480Sstevel@tonic-gate 	/* check that xfer_ctl is present in the IXL xfer start command */
10490Sstevel@tonic-gate 	if ((xferctlp = (hci1394_xfer_ctl_t *)
10500Sstevel@tonic-gate 	    uvp->ixlxferp->compiler_privatep) == NULL) {
10510Sstevel@tonic-gate 
10520Sstevel@tonic-gate 		/* Error - no xfer_ctl struct found */
10530Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
10540Sstevel@tonic-gate 
10550Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_pkt_exit,
10560Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
10570Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
10580Sstevel@tonic-gate 	}
10590Sstevel@tonic-gate 
10600Sstevel@tonic-gate 	/* set depth to zero and count to 1 to update dma descriptor */
10610Sstevel@tonic-gate 	uvp->ixldepth = 0;
10620Sstevel@tonic-gate 	uvp->ixlcount = 1;
10630Sstevel@tonic-gate 
10640Sstevel@tonic-gate 	/*
10650Sstevel@tonic-gate 	 * get Z bits (number of descriptors in descriptor block) from the DMA
10660Sstevel@tonic-gate 	 * bound address in the xfer_ctl struct of the IXL xfer start cpmmand.
10670Sstevel@tonic-gate 	 */
10680Sstevel@tonic-gate 	uvp->hci_offset = xferctlp->dma[0].dma_bound & DESC_Z_MASK;
10690Sstevel@tonic-gate 
10700Sstevel@tonic-gate 	/*
10710Sstevel@tonic-gate 	 * set offset from the current(last) descriptor to the descriptor for
10720Sstevel@tonic-gate 	 * this packet command
10730Sstevel@tonic-gate 	 */
10740Sstevel@tonic-gate 	uvp->hci_offset -= (1 + uvp->ixloldp->compiler_resv);
10750Sstevel@tonic-gate 
10760Sstevel@tonic-gate 	/*
10770Sstevel@tonic-gate 	 * set bufsize to the new IXL xfer size, and bufaddr to the new
10780Sstevel@tonic-gate 	 * IXL xfer bufp
10790Sstevel@tonic-gate 	 */
10800Sstevel@tonic-gate 	uvp->bufsize = ((ixl1394_xfer_pkt_t *)uvp->ixlnewp)->size;
10810Sstevel@tonic-gate 	uvp->bufaddr = ((ixl1394_xfer_pkt_t *)
10820Sstevel@tonic-gate 	    uvp->ixlnewp)->ixl_buf.ixldmac_addr;
10830Sstevel@tonic-gate 
10840Sstevel@tonic-gate 	/*
10850Sstevel@tonic-gate 	 * update old hcihdr w/new bufsize, set hcistatus rescnt to
10860Sstevel@tonic-gate 	 * new bufsize
10870Sstevel@tonic-gate 	 */
10880Sstevel@tonic-gate 	hcidescp = (hci1394_desc_t *)xferctlp->dma[0].dma_descp -
10890Sstevel@tonic-gate 	    uvp->hci_offset;
10900Sstevel@tonic-gate 	acc_hdl  = xferctlp->dma[0].dma_buf->bi_handle;
10910Sstevel@tonic-gate 	dma_hdl  = xferctlp->dma[0].dma_buf->bi_dma_handle;
10920Sstevel@tonic-gate 
10930Sstevel@tonic-gate 	/* Sync the descriptor before we grab the header(s) */
10940Sstevel@tonic-gate 	err = ddi_dma_sync(dma_hdl, (off_t)hcidescp, sizeof (hci1394_desc_t),
10950Sstevel@tonic-gate 	    DDI_DMA_SYNC_FORCPU);
10960Sstevel@tonic-gate 	if (err != DDI_SUCCESS) {
10970Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EINTERNAL_ERROR;
10980Sstevel@tonic-gate 
10990Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prep_recv_pkt_exit,
11000Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, errmsg,
11010Sstevel@tonic-gate 		    "EINTERNAL_ERROR: dma_sync() failed");
11020Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
11030Sstevel@tonic-gate 	}
11040Sstevel@tonic-gate 
11050Sstevel@tonic-gate 	desc_hdr = ddi_get32(acc_hdl, &hcidescp->hdr);
11060Sstevel@tonic-gate 	uvp->hcihdr = desc_hdr;
11070Sstevel@tonic-gate 	uvp->hcihdr &= ~DESC_HDR_REQCOUNT_MASK;
11080Sstevel@tonic-gate 	uvp->hcihdr |= (uvp->bufsize << DESC_HDR_REQCOUNT_SHIFT) &
11090Sstevel@tonic-gate 	    DESC_HDR_REQCOUNT_MASK;
11100Sstevel@tonic-gate 	uvp->hcistatus = (uvp->bufsize << DESC_ST_RESCOUNT_SHIFT) &
11110Sstevel@tonic-gate 	    DESC_ST_RESCOUNT_MASK;
11120Sstevel@tonic-gate 
11130Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_pkt_exit,
11140Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
11150Sstevel@tonic-gate 	return (IXL_PREP_READY);
11160Sstevel@tonic-gate }
11170Sstevel@tonic-gate 
11180Sstevel@tonic-gate /*
11190Sstevel@tonic-gate  * hci1394_ixl_update_prep_recv_buf()
11200Sstevel@tonic-gate  *    Preparation for update of an IXL1394_OP_RECV_BUF_U command.
11210Sstevel@tonic-gate  */
11220Sstevel@tonic-gate static int
hci1394_ixl_update_prep_recv_buf(hci1394_ixl_update_vars_t * uvp)11230Sstevel@tonic-gate hci1394_ixl_update_prep_recv_buf(hci1394_ixl_update_vars_t *uvp)
11240Sstevel@tonic-gate {
11250Sstevel@tonic-gate 	ixl1394_xfer_buf_t *old_xfer_buf_ixlp;
11260Sstevel@tonic-gate 	ixl1394_xfer_buf_t *new_xfer_buf_ixlp;
11270Sstevel@tonic-gate 	hci1394_xfer_ctl_t *xferctlp;
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_buf_enter,
11300Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
11310Sstevel@tonic-gate 
11320Sstevel@tonic-gate 	old_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixloldp;
11330Sstevel@tonic-gate 	new_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixlnewp;
11340Sstevel@tonic-gate 
11350Sstevel@tonic-gate 	/* check if any change between new and old IXL xfer commands */
11360Sstevel@tonic-gate 	if ((new_xfer_buf_ixlp->size ==	old_xfer_buf_ixlp->size) &&
11370Sstevel@tonic-gate 	    (new_xfer_buf_ixlp->ixl_buf.ixldmac_addr ==
11380Sstevel@tonic-gate 		old_xfer_buf_ixlp->ixl_buf.ixldmac_addr) &&
11390Sstevel@tonic-gate 	    (new_xfer_buf_ixlp->mem_bufp == new_xfer_buf_ixlp->mem_bufp)) {
11400Sstevel@tonic-gate 
11410Sstevel@tonic-gate 		if (((uvp->ctxtp->ctxt_flags & HCI1394_ISO_CTXT_BFFILL) != 0) ||
11420Sstevel@tonic-gate 		    (new_xfer_buf_ixlp->pkt_size ==
11430Sstevel@tonic-gate 			old_xfer_buf_ixlp->pkt_size)) {
11440Sstevel@tonic-gate 
11450Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_buf_exit,
11460Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
11470Sstevel@tonic-gate 
11480Sstevel@tonic-gate 			/* no change. return with done ok status */
11490Sstevel@tonic-gate 			return (IXL_PREP_SUCCESS);
11500Sstevel@tonic-gate 		}
11510Sstevel@tonic-gate 	}
11520Sstevel@tonic-gate 
11530Sstevel@tonic-gate 	/* if new IXL buffer addrs are null, return error */
11540Sstevel@tonic-gate 	if ((new_xfer_buf_ixlp->ixl_buf.ixldmac_addr == NULL) ||
11550Sstevel@tonic-gate 	    (new_xfer_buf_ixlp->mem_bufp == NULL)) {
11560Sstevel@tonic-gate 
11570Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EXFER_BUF_MISSING;
11580Sstevel@tonic-gate 
11590Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_buf_exit,
11600Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
11610Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
11620Sstevel@tonic-gate 	}
11630Sstevel@tonic-gate 
11640Sstevel@tonic-gate 	/*
11650Sstevel@tonic-gate 	 * if not buffer fill mode, check that the new pkt_size > 0 and
11660Sstevel@tonic-gate 	 * new size/pkt_size doesn't change the count of dma descriptor
11670Sstevel@tonic-gate 	 * blocks required
11680Sstevel@tonic-gate 	 */
11690Sstevel@tonic-gate 	if ((uvp->ctxtp->ctxt_flags & HCI1394_ISO_CTXT_BFFILL) == 0) {
11700Sstevel@tonic-gate 		if ((new_xfer_buf_ixlp->pkt_size == 0) ||
11710Sstevel@tonic-gate 		    ((new_xfer_buf_ixlp->size /	new_xfer_buf_ixlp->pkt_size) !=
11720Sstevel@tonic-gate 		    (old_xfer_buf_ixlp->size / old_xfer_buf_ixlp->pkt_size))) {
11730Sstevel@tonic-gate 
11740Sstevel@tonic-gate 			/* count changes. return an error */
11750Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EXFER_BUF_CNT_DIFF;
11760Sstevel@tonic-gate 
11770Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(
11780Sstevel@tonic-gate 				hci1394_ixl_update_prep_recv_buf_exit,
11790Sstevel@tonic-gate 				HCI1394_TNF_HAL_STACK_ISOCH, "");
11800Sstevel@tonic-gate 			return (IXL_PREP_FAILURE);
11810Sstevel@tonic-gate 		}
11820Sstevel@tonic-gate 	}
11830Sstevel@tonic-gate 
11840Sstevel@tonic-gate 	/* set old IXL xfer command as the current IXL xfer command */
11850Sstevel@tonic-gate 	uvp->ixlxferp = uvp->ixloldp;
11860Sstevel@tonic-gate 
11870Sstevel@tonic-gate 	/* check that the xfer_ctl struct is present in IXL xfer command */
11880Sstevel@tonic-gate 	if ((xferctlp = (hci1394_xfer_ctl_t *)uvp->ixlxferp->compiler_privatep)
11890Sstevel@tonic-gate 	    == NULL) {
11900Sstevel@tonic-gate 
11910Sstevel@tonic-gate 		/* return an error if no xfer_ctl struct is found for command */
11920Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
11930Sstevel@tonic-gate 
11940Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_buf_exit,
11950Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
11960Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
11970Sstevel@tonic-gate 	}
11980Sstevel@tonic-gate 
11990Sstevel@tonic-gate 	/* set depth to zero and count to update all dma descriptors */
12000Sstevel@tonic-gate 	uvp->ixldepth = 0;
12010Sstevel@tonic-gate 	uvp->ixlcount = xferctlp->cnt;
12020Sstevel@tonic-gate 
12030Sstevel@tonic-gate 	/* set bufsize to new pkt_size (or to new size if buffer fill mode) */
12040Sstevel@tonic-gate 	if ((uvp->ctxtp->ctxt_flags & HCI1394_ISO_CTXT_BFFILL) == 0) {
12050Sstevel@tonic-gate 		uvp->bufsize = new_xfer_buf_ixlp->pkt_size;
12060Sstevel@tonic-gate 	} else {
12070Sstevel@tonic-gate 		uvp->bufsize = new_xfer_buf_ixlp->size;
12080Sstevel@tonic-gate 	}
12090Sstevel@tonic-gate 
12100Sstevel@tonic-gate 	/* set bufaddr to new ixl_buf */
12110Sstevel@tonic-gate 	uvp->bufaddr = new_xfer_buf_ixlp->ixl_buf.ixldmac_addr;
12120Sstevel@tonic-gate 
12130Sstevel@tonic-gate 	/* set hcihdr reqcnt and hcistatus rescnt to new bufsize */
12140Sstevel@tonic-gate 	uvp->hci_offset = 0;
12150Sstevel@tonic-gate 	uvp->hcihdr = (uvp->bufsize << DESC_HDR_REQCOUNT_SHIFT) &
12160Sstevel@tonic-gate 	    DESC_HDR_REQCOUNT_MASK;
12170Sstevel@tonic-gate 	uvp->hcistatus = (uvp->bufsize << DESC_ST_RESCOUNT_SHIFT) &
12180Sstevel@tonic-gate 	    DESC_ST_RESCOUNT_MASK;
12190Sstevel@tonic-gate 
12200Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_recv_buf_exit,
12210Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
12220Sstevel@tonic-gate 	return (IXL_PREP_READY);
12230Sstevel@tonic-gate }
12240Sstevel@tonic-gate 
12250Sstevel@tonic-gate /*
12260Sstevel@tonic-gate  * hci1394_ixl_update_prep_send_pkt()
12270Sstevel@tonic-gate  *    Preparation for update of an IXL1394_OP_SEND_PKT_U command,
12280Sstevel@tonic-gate  *    IXL1394_OP_SEND_PKT_ST_U command and IXL1394_OP_SEND_PKT_WHDR_ST_U
12290Sstevel@tonic-gate  *    command.
12300Sstevel@tonic-gate  */
12310Sstevel@tonic-gate static int
hci1394_ixl_update_prep_send_pkt(hci1394_ixl_update_vars_t * uvp)12320Sstevel@tonic-gate hci1394_ixl_update_prep_send_pkt(hci1394_ixl_update_vars_t *uvp)
12330Sstevel@tonic-gate {
12340Sstevel@tonic-gate 	ixl1394_xfer_pkt_t *old_xfer_pkt_ixlp;
12350Sstevel@tonic-gate 	ixl1394_xfer_pkt_t *new_xfer_pkt_ixlp;
12360Sstevel@tonic-gate 	hci1394_xfer_ctl_t *xferctlp;
12370Sstevel@tonic-gate 	hci1394_desc_imm_t *hcidescp;
12380Sstevel@tonic-gate 	ddi_acc_handle_t   acc_hdl;
12390Sstevel@tonic-gate 	ddi_dma_handle_t   dma_hdl;
12400Sstevel@tonic-gate 	uint32_t	   desc_hdr, desc_hdr2;
12410Sstevel@tonic-gate 	int		   err;
12420Sstevel@tonic-gate 
12430Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_enter,
12440Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
12450Sstevel@tonic-gate 
12460Sstevel@tonic-gate 	old_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixloldp;
12470Sstevel@tonic-gate 	new_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixlnewp;
12480Sstevel@tonic-gate 
12490Sstevel@tonic-gate 	/* check if any change between new and old IXL xfer commands */
12500Sstevel@tonic-gate 	if ((new_xfer_pkt_ixlp->size ==	old_xfer_pkt_ixlp->size) &&
12510Sstevel@tonic-gate 	    (new_xfer_pkt_ixlp->ixl_buf.ixldmac_addr ==
12520Sstevel@tonic-gate 		old_xfer_pkt_ixlp->ixl_buf.ixldmac_addr) &&
12530Sstevel@tonic-gate 	    (new_xfer_pkt_ixlp->mem_bufp == old_xfer_pkt_ixlp->mem_bufp)) {
12540Sstevel@tonic-gate 
12550Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
12560Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
12570Sstevel@tonic-gate 
12580Sstevel@tonic-gate 		/* if none, return with done ok status */
12590Sstevel@tonic-gate 		return (IXL_PREP_SUCCESS);
12600Sstevel@tonic-gate 	}
12610Sstevel@tonic-gate 
12620Sstevel@tonic-gate 	/* if new ixl buffer addrs are null, return error */
12630Sstevel@tonic-gate 	if ((new_xfer_pkt_ixlp->ixl_buf.ixldmac_addr == NULL) ||
12640Sstevel@tonic-gate 	    (new_xfer_pkt_ixlp->mem_bufp == NULL)) {
12650Sstevel@tonic-gate 
12660Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EXFER_BUF_MISSING;
12670Sstevel@tonic-gate 
12680Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
12690Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
12700Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
12710Sstevel@tonic-gate 	}
12720Sstevel@tonic-gate 
12730Sstevel@tonic-gate 	/* error if IXL1394_OP_SEND_PKT_WHDR_ST_U opcode and size < 4 */
12740Sstevel@tonic-gate 	if ((uvp->ixl_opcode == IXL1394_OP_SEND_PKT_WHDR_ST_U) &&
12750Sstevel@tonic-gate 	    (new_xfer_pkt_ixlp->size < 4)) {
12760Sstevel@tonic-gate 
12770Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EPKT_HDR_MISSING;
12780Sstevel@tonic-gate 
12790Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
12800Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
12810Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
12820Sstevel@tonic-gate 	}
12830Sstevel@tonic-gate 
12840Sstevel@tonic-gate 	/* if IXL xfer command is not an IXL xfer start command */
12850Sstevel@tonic-gate 	if (uvp->ixl_opcode == IXL1394_OP_SEND_PKT_U) {
12860Sstevel@tonic-gate 		/*
12870Sstevel@tonic-gate 		 * find IXL xfer start command in the compiler_privatep of the
12880Sstevel@tonic-gate 		 * old IXL xfer command
12890Sstevel@tonic-gate 		 */
12900Sstevel@tonic-gate 		uvp->ixlxferp = (ixl1394_command_t *)
12910Sstevel@tonic-gate 		    old_xfer_pkt_ixlp->compiler_privatep;
12920Sstevel@tonic-gate 
12930Sstevel@tonic-gate 		if (uvp->ixlxferp == NULL) {
12940Sstevel@tonic-gate 			/* error if no IXL xfer start command found */
12950Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
12960Sstevel@tonic-gate 
12970Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
12980Sstevel@tonic-gate 				HCI1394_TNF_HAL_STACK_ISOCH, "");
12990Sstevel@tonic-gate 			return (IXL_PREP_FAILURE);
13000Sstevel@tonic-gate 		}
13010Sstevel@tonic-gate 	} else {
13020Sstevel@tonic-gate 		/* IXL xfer command is the IXL xfer start command */
13030Sstevel@tonic-gate 		uvp->ixlxferp = uvp->ixloldp;
13040Sstevel@tonic-gate 	}
13050Sstevel@tonic-gate 
13060Sstevel@tonic-gate 	/*
13070Sstevel@tonic-gate 	 * get Z bits (number of descriptor components in the descriptor block)
13080Sstevel@tonic-gate 	 * from a dma bound address in the xfer_ctl structure of the IXL
13090Sstevel@tonic-gate 	 * xfer start command
13100Sstevel@tonic-gate 	 */
13110Sstevel@tonic-gate 	if ((xferctlp = (hci1394_xfer_ctl_t *)
13120Sstevel@tonic-gate 	    uvp->ixlxferp->compiler_privatep) == NULL) {
13130Sstevel@tonic-gate 
13140Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
13150Sstevel@tonic-gate 
13160Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
13170Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
13180Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
13190Sstevel@tonic-gate 	}
13200Sstevel@tonic-gate 
13210Sstevel@tonic-gate 	/* set depth to zero and count to 1 to update dma descriptor */
13220Sstevel@tonic-gate 	uvp->ixldepth = 0;
13230Sstevel@tonic-gate 	uvp->ixlcount = 1;
13240Sstevel@tonic-gate 
13250Sstevel@tonic-gate 	/*
13260Sstevel@tonic-gate 	 * set offset to the header(first) descriptor from the
13270Sstevel@tonic-gate 	 * current(last) descriptor
13280Sstevel@tonic-gate 	 */
13290Sstevel@tonic-gate 	uvp->hdr_offset = xferctlp->dma[0].dma_bound & DESC_Z_MASK - 1;
13300Sstevel@tonic-gate 
13310Sstevel@tonic-gate 	/*
13320Sstevel@tonic-gate 	 * set offset from the current(last) descriptor to the descriptor for
13330Sstevel@tonic-gate 	 * this packet command
13340Sstevel@tonic-gate 	 */
13350Sstevel@tonic-gate 	uvp->hci_offset = uvp->hdr_offset - 2 - uvp->ixloldp->compiler_resv;
13360Sstevel@tonic-gate 
13370Sstevel@tonic-gate 	/* set bufsize to new pkt buffr size, set bufaddr to new bufp */
13380Sstevel@tonic-gate 	uvp->bufsize = new_xfer_pkt_ixlp->size;
13390Sstevel@tonic-gate 	uvp->bufaddr = new_xfer_pkt_ixlp->ixl_buf.ixldmac_addr;
13400Sstevel@tonic-gate 
13410Sstevel@tonic-gate 	/*
13420Sstevel@tonic-gate 	 * if IXL1394_OP_SEND_PKT_WHDR_ST_U opcode, adjust size & buff,
13430Sstevel@tonic-gate 	 * step over hdr
13440Sstevel@tonic-gate 	 */
13450Sstevel@tonic-gate 	if (uvp->ixl_opcode == IXL1394_OP_SEND_PKT_WHDR_ST_U) {
13460Sstevel@tonic-gate 		uvp->bufsize -= 4;
13470Sstevel@tonic-gate 		uvp->bufaddr += 4;
13480Sstevel@tonic-gate 	}
13490Sstevel@tonic-gate 
13500Sstevel@tonic-gate 	/* update old hcihdr w/new bufsize */
13510Sstevel@tonic-gate 	hcidescp = (hci1394_desc_imm_t *)xferctlp->dma[0].dma_descp -
13520Sstevel@tonic-gate 	    uvp->hci_offset;
13530Sstevel@tonic-gate 	acc_hdl  = xferctlp->dma[0].dma_buf->bi_handle;
13540Sstevel@tonic-gate 	dma_hdl  = xferctlp->dma[0].dma_buf->bi_dma_handle;
13550Sstevel@tonic-gate 
13560Sstevel@tonic-gate 	/* Sync the descriptor before we grab the header(s) */
13570Sstevel@tonic-gate 	err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
13580Sstevel@tonic-gate 	    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORCPU);
13590Sstevel@tonic-gate 	if (err != DDI_SUCCESS) {
13600Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EINTERNAL_ERROR;
13610Sstevel@tonic-gate 
13620Sstevel@tonic-gate 		TNF_PROBE_1_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
13630Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, errmsg,
13640Sstevel@tonic-gate 		    "EINTERNAL_ERROR: dma_sync() failed");
13650Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
13660Sstevel@tonic-gate 	}
13670Sstevel@tonic-gate 
13680Sstevel@tonic-gate 	desc_hdr = ddi_get32(acc_hdl, &hcidescp->hdr);
13690Sstevel@tonic-gate 	uvp->hcihdr = desc_hdr;
13700Sstevel@tonic-gate 	uvp->hcihdr &= ~DESC_HDR_REQCOUNT_MASK;
13710Sstevel@tonic-gate 	uvp->hcihdr |= (uvp->bufsize << DESC_HDR_REQCOUNT_SHIFT) &
13720Sstevel@tonic-gate 	    DESC_HDR_REQCOUNT_MASK;
13730Sstevel@tonic-gate 
13740Sstevel@tonic-gate 	/* update old pkthdr2 w/new bufsize. error if exceeds 16k */
13750Sstevel@tonic-gate 	desc_hdr2 = ddi_get32(acc_hdl, &hcidescp->q2);
13760Sstevel@tonic-gate 	uvp->pkthdr2 = desc_hdr2;
13770Sstevel@tonic-gate 	uvp->pkthdr2 = (uvp->pkthdr2 & DESC_PKT_DATALEN_MASK) >>
13780Sstevel@tonic-gate 	    DESC_PKT_DATALEN_SHIFT;
13790Sstevel@tonic-gate 	uvp->pkthdr2 -= old_xfer_pkt_ixlp->size;
13800Sstevel@tonic-gate 	uvp->pkthdr2 += uvp->bufsize;
13810Sstevel@tonic-gate 
13820Sstevel@tonic-gate 	if (uvp->pkthdr2 > 0xFFFF) {
13830Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EPKTSIZE_MAX_OFLO;
13840Sstevel@tonic-gate 
13850Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
13860Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
13870Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
13880Sstevel@tonic-gate 	}
13890Sstevel@tonic-gate 	uvp->pkthdr2 = (uvp->pkthdr2 << DESC_PKT_DATALEN_SHIFT) &
13900Sstevel@tonic-gate 	    DESC_PKT_DATALEN_MASK;
13910Sstevel@tonic-gate 
13920Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_pkt_exit,
13930Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
13940Sstevel@tonic-gate 	return (IXL_PREP_READY);
13950Sstevel@tonic-gate }
13960Sstevel@tonic-gate 
13970Sstevel@tonic-gate /*
13980Sstevel@tonic-gate  * hci1394_ixl_update_prep_send_buf()
13990Sstevel@tonic-gate  *    Preparation for update of an IXL1394_OP_SEND_BUF_U command.
14000Sstevel@tonic-gate  */
14010Sstevel@tonic-gate static int
hci1394_ixl_update_prep_send_buf(hci1394_ixl_update_vars_t * uvp)14020Sstevel@tonic-gate hci1394_ixl_update_prep_send_buf(hci1394_ixl_update_vars_t *uvp)
14030Sstevel@tonic-gate {
14040Sstevel@tonic-gate 	ixl1394_xfer_buf_t *old_xfer_buf_ixlp;
14050Sstevel@tonic-gate 	ixl1394_xfer_buf_t *new_xfer_buf_ixlp;
14060Sstevel@tonic-gate 	hci1394_xfer_ctl_t *xferctlp;
14070Sstevel@tonic-gate 
14080Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_buf_enter,
14090Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
14100Sstevel@tonic-gate 
14110Sstevel@tonic-gate 	old_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixloldp;
14120Sstevel@tonic-gate 	new_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixlnewp;
14130Sstevel@tonic-gate 
14140Sstevel@tonic-gate 	/* check if any change between new and old IXL xfer commands */
14150Sstevel@tonic-gate 	if ((new_xfer_buf_ixlp->size == old_xfer_buf_ixlp->size) &&
14160Sstevel@tonic-gate 	    (new_xfer_buf_ixlp->pkt_size == old_xfer_buf_ixlp->pkt_size) &&
14170Sstevel@tonic-gate 	    (new_xfer_buf_ixlp->ixl_buf.ixldmac_addr ==
14180Sstevel@tonic-gate 		old_xfer_buf_ixlp->ixl_buf.ixldmac_addr) &&
14190Sstevel@tonic-gate 	    (new_xfer_buf_ixlp->mem_bufp == old_xfer_buf_ixlp->mem_bufp)) {
14200Sstevel@tonic-gate 
14210Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_buf_exit,
14220Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
14230Sstevel@tonic-gate 
14240Sstevel@tonic-gate 		/* no change, return with done ok status */
14250Sstevel@tonic-gate 		return (IXL_PREP_SUCCESS);
14260Sstevel@tonic-gate 	}
14270Sstevel@tonic-gate 
14280Sstevel@tonic-gate 	/* if new IXL buffer addresses are null, return error */
14290Sstevel@tonic-gate 	if ((new_xfer_buf_ixlp->ixl_buf.ixldmac_addr == NULL) ||
14300Sstevel@tonic-gate 	    (new_xfer_buf_ixlp->mem_bufp == NULL)) {
14310Sstevel@tonic-gate 
14320Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EXFER_BUF_MISSING;
14330Sstevel@tonic-gate 
14340Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_buf_exit,
14350Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
14360Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
14370Sstevel@tonic-gate 	}
14380Sstevel@tonic-gate 
14390Sstevel@tonic-gate 	/*
14400Sstevel@tonic-gate 	 * check that the new pkt_size > 0 and the new size/pkt_size
14410Sstevel@tonic-gate 	 * doesn't change the count of DMA descriptor blocks required
14420Sstevel@tonic-gate 	 */
14430Sstevel@tonic-gate 	if ((new_xfer_buf_ixlp->pkt_size == 0) ||
14440Sstevel@tonic-gate 	    ((new_xfer_buf_ixlp->size / new_xfer_buf_ixlp->pkt_size) !=
14450Sstevel@tonic-gate 	    (old_xfer_buf_ixlp->size / old_xfer_buf_ixlp->pkt_size))) {
14460Sstevel@tonic-gate 
14470Sstevel@tonic-gate 		/* Error - new has different pkt count than old */
14480Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EXFER_BUF_CNT_DIFF;
14490Sstevel@tonic-gate 
14500Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_buf_exit,
14510Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
14520Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
14530Sstevel@tonic-gate 	}
14540Sstevel@tonic-gate 
14550Sstevel@tonic-gate 	/* set the old IXL xfer command as the current IXL xfer command */
14560Sstevel@tonic-gate 	uvp->ixlxferp = uvp->ixloldp;
14570Sstevel@tonic-gate 
14580Sstevel@tonic-gate 	/*
14590Sstevel@tonic-gate 	 * get Z bits (number of descriptor components in descriptor block)
14600Sstevel@tonic-gate 	 * from a DMA bound address in the xfer_ctl struct of the
14610Sstevel@tonic-gate 	 * IXL xfer command
14620Sstevel@tonic-gate 	 */
14630Sstevel@tonic-gate 	if ((xferctlp = (hci1394_xfer_ctl_t *)
14640Sstevel@tonic-gate 	    uvp->ixlxferp->compiler_privatep) == NULL) {
14650Sstevel@tonic-gate 
14660Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EORIG_IXL_CORRUPTED;
14670Sstevel@tonic-gate 
14680Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_buf_exit,
14690Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
14700Sstevel@tonic-gate 		return (IXL_PREP_FAILURE);
14710Sstevel@tonic-gate 	}
14720Sstevel@tonic-gate 
14730Sstevel@tonic-gate 	/* set depth to zero and count to update all dma descriptors */
14740Sstevel@tonic-gate 	uvp->ixldepth = 0;
14750Sstevel@tonic-gate 	uvp->ixlcount = xferctlp->cnt;
14760Sstevel@tonic-gate 
14770Sstevel@tonic-gate 	/*
14780Sstevel@tonic-gate 	 * set offset to the header(first) descriptor from the current (last)
14790Sstevel@tonic-gate 	 * descriptor.
14800Sstevel@tonic-gate 	 */
14810Sstevel@tonic-gate 	uvp->hdr_offset = xferctlp->dma[0].dma_bound & DESC_Z_MASK - 1;
14820Sstevel@tonic-gate 
14830Sstevel@tonic-gate 	/* set offset to the only(last) xfer descriptor */
14840Sstevel@tonic-gate 	uvp->hci_offset = 0;
14850Sstevel@tonic-gate 
14860Sstevel@tonic-gate 	/* set bufsize to the new pkt_size, set bufaddr to the new bufp */
14870Sstevel@tonic-gate 	uvp->bufsize = new_xfer_buf_ixlp->pkt_size;
14880Sstevel@tonic-gate 	uvp->bufaddr = new_xfer_buf_ixlp->ixl_buf.ixldmac_addr;
14890Sstevel@tonic-gate 
14900Sstevel@tonic-gate 	/*
14910Sstevel@tonic-gate 	 * if IXL1394_OP_SEND_PKT_WHDR_ST_U opcode, adjust size & buff,
14920Sstevel@tonic-gate 	 * step over header (a quadlet)
14930Sstevel@tonic-gate 	 */
14940Sstevel@tonic-gate 	if (uvp->ixl_opcode == IXL1394_OP_SEND_PKT_WHDR_ST_U) {
14950Sstevel@tonic-gate 		uvp->bufsize -= 4;
14960Sstevel@tonic-gate 		uvp->bufaddr += 4;
14970Sstevel@tonic-gate 	}
14980Sstevel@tonic-gate 
14990Sstevel@tonic-gate 	/* set hcihdr to new bufsize */
15000Sstevel@tonic-gate 	uvp->hcihdr = (uvp->bufsize << DESC_HDR_REQCOUNT_SHIFT) &
15010Sstevel@tonic-gate 	    DESC_HDR_REQCOUNT_MASK;
15020Sstevel@tonic-gate 
15030Sstevel@tonic-gate 	/* set pkthdr2 to new bufsize */
15040Sstevel@tonic-gate 	uvp->pkthdr2 = (uvp->bufsize << DESC_PKT_DATALEN_SHIFT) &
15050Sstevel@tonic-gate 	    DESC_PKT_DATALEN_MASK;
15060Sstevel@tonic-gate 
15070Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_prep_send_buf_exit,
15080Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
15090Sstevel@tonic-gate 	return (IXL_PREP_READY);
15100Sstevel@tonic-gate }
15110Sstevel@tonic-gate 
15120Sstevel@tonic-gate /*
15130Sstevel@tonic-gate  * hci1394_ixl_update_perform()
15140Sstevel@tonic-gate  *    performs the actual update into DMA memory.
15150Sstevel@tonic-gate  */
15160Sstevel@tonic-gate static int
hci1394_ixl_update_perform(hci1394_ixl_update_vars_t * uvp)15170Sstevel@tonic-gate hci1394_ixl_update_perform(hci1394_ixl_update_vars_t *uvp)
15180Sstevel@tonic-gate {
15190Sstevel@tonic-gate 	int			ii;
15200Sstevel@tonic-gate 	uint_t			skipaddrlast;
15210Sstevel@tonic-gate 	hci1394_xfer_ctl_t	*xferctlp;
15220Sstevel@tonic-gate 	hci1394_desc_imm_t	*hcidescp;
15230Sstevel@tonic-gate 	hci1394_iso_ctxt_t	*ctxtp;
15240Sstevel@tonic-gate 	ddi_acc_handle_t	acc_hdl;
15250Sstevel@tonic-gate 	ddi_dma_handle_t	dma_hdl;
15260Sstevel@tonic-gate 	int			err;
15270Sstevel@tonic-gate 
15280Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_enter,
15290Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
15300Sstevel@tonic-gate 
15310Sstevel@tonic-gate 	ctxtp = uvp->ctxtp;
15320Sstevel@tonic-gate 
15330Sstevel@tonic-gate 	/*
15340Sstevel@tonic-gate 	 * if no target ixl xfer command to be updated or it has
15350Sstevel@tonic-gate 	 * no xfer_ctl struct, then internal error.
15360Sstevel@tonic-gate 	 */
15370Sstevel@tonic-gate 	if ((uvp->ixlxferp == NULL) ||
15380Sstevel@tonic-gate 	    ((xferctlp = (hci1394_xfer_ctl_t *)
15390Sstevel@tonic-gate 	    uvp->ixlxferp->compiler_privatep) == NULL)) {
15400Sstevel@tonic-gate 
15410Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EINTERNAL_ERROR;
15420Sstevel@tonic-gate 
15430Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_exit,
15440Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
15450Sstevel@tonic-gate 
15460Sstevel@tonic-gate 		return (DDI_FAILURE);
15470Sstevel@tonic-gate 	}
15480Sstevel@tonic-gate 
15490Sstevel@tonic-gate 	/* perform update based on specific ixl command type */
15500Sstevel@tonic-gate 	switch (uvp->ixl_opcode) {
15510Sstevel@tonic-gate 
15520Sstevel@tonic-gate 	case IXL1394_OP_JUMP_U: {
15530Sstevel@tonic-gate 		ixl1394_jump_t *old_jump_ixlp;
15540Sstevel@tonic-gate 		ixl1394_jump_t *new_jump_ixlp;
15550Sstevel@tonic-gate 
15560Sstevel@tonic-gate 		old_jump_ixlp = (ixl1394_jump_t *)uvp->ixloldp;
15570Sstevel@tonic-gate 		new_jump_ixlp = (ixl1394_jump_t *)uvp->ixlnewp;
15580Sstevel@tonic-gate 
15590Sstevel@tonic-gate 		/*
15600Sstevel@tonic-gate 		 * set new hdr and new branch fields into last component of last
15610Sstevel@tonic-gate 		 * dma descriptor block of ixl xfer cmd associated with
15620Sstevel@tonic-gate 		 * ixl jump cmd
15630Sstevel@tonic-gate 		 */
15640Sstevel@tonic-gate 		hcidescp = (hci1394_desc_imm_t *)
15650Sstevel@tonic-gate 		    xferctlp->dma[xferctlp->cnt - 1].dma_descp;
15660Sstevel@tonic-gate 		acc_hdl	 = xferctlp->dma[xferctlp->cnt - 1].dma_buf->bi_handle;
15670Sstevel@tonic-gate 		dma_hdl	 =
15680Sstevel@tonic-gate 		    xferctlp->dma[xferctlp->cnt - 1].dma_buf->bi_dma_handle;
15690Sstevel@tonic-gate 
15700Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->hdr, uvp->hcihdr);
15710Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->branch, uvp->jumpaddr);
15720Sstevel@tonic-gate 
15730Sstevel@tonic-gate 		/*
15740Sstevel@tonic-gate 		 * if xfer type is send and skip mode is IXL1394__SKIP_TO_NEXT
15750Sstevel@tonic-gate 		 * also set branch location into branch field of first
15760Sstevel@tonic-gate 		 * component (skip to address) of last dma descriptor block
15770Sstevel@tonic-gate 		 */
15780Sstevel@tonic-gate 		if (uvp->skipmode == IXL1394_SKIP_TO_NEXT) {
15790Sstevel@tonic-gate 			hcidescp -= uvp->hci_offset;
15800Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->branch, uvp->skipaddr);
15810Sstevel@tonic-gate 		}
15820Sstevel@tonic-gate 
15830Sstevel@tonic-gate 		/* Sync descriptor for device (desc was modified) */
15840Sstevel@tonic-gate 		err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
15850Sstevel@tonic-gate 		    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORDEV);
15860Sstevel@tonic-gate 		if (err != DDI_SUCCESS) {
15870Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EINTERNAL_ERROR;
15880Sstevel@tonic-gate 
15890Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_exit,
15900Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
15910Sstevel@tonic-gate 			return (DDI_FAILURE);
15920Sstevel@tonic-gate 		}
15930Sstevel@tonic-gate 
15940Sstevel@tonic-gate 		/* set old ixl jump cmd label from new ixl jump cmd label */
15950Sstevel@tonic-gate 		old_jump_ixlp->label = new_jump_ixlp->label;
15960Sstevel@tonic-gate 		break;
15970Sstevel@tonic-gate 	}
15980Sstevel@tonic-gate 	case IXL1394_OP_SET_SKIPMODE_U: {
15990Sstevel@tonic-gate 		ixl1394_set_skipmode_t *old_set_skipmode_ixlp;
16000Sstevel@tonic-gate 		ixl1394_set_skipmode_t *new_set_skipmode_ixlp;
16010Sstevel@tonic-gate 
16020Sstevel@tonic-gate 		old_set_skipmode_ixlp = (ixl1394_set_skipmode_t *)uvp->ixloldp;
16030Sstevel@tonic-gate 		new_set_skipmode_ixlp = (ixl1394_set_skipmode_t *)uvp->ixlnewp;
16040Sstevel@tonic-gate 
16050Sstevel@tonic-gate 		/*
16060Sstevel@tonic-gate 		 * if skip to next mode, save skip addr for last iteration
16070Sstevel@tonic-gate 		 * thru dma descriptor blocks for associated ixl xfer command
16080Sstevel@tonic-gate 		 */
16090Sstevel@tonic-gate 		if (uvp->skipmode == IXL1394_SKIP_TO_NEXT) {
16100Sstevel@tonic-gate 			skipaddrlast = uvp->skipaddr;
16110Sstevel@tonic-gate 		}
16120Sstevel@tonic-gate 
16130Sstevel@tonic-gate 		/*
16140Sstevel@tonic-gate 		 * iterate through set of dma descriptor blocks for associated
16150Sstevel@tonic-gate 		 * ixl xfer start cmd and set new skip address into first hci
16160Sstevel@tonic-gate 		 * descriptor of each if skip next or skip self, first determine
16170Sstevel@tonic-gate 		 * address in each iteration
16180Sstevel@tonic-gate 		 */
16190Sstevel@tonic-gate 		for (ii = 0; ii < xferctlp->cnt; ii++) {
16200Sstevel@tonic-gate 			hcidescp = (hci1394_desc_imm_t *)
16210Sstevel@tonic-gate 			    xferctlp->dma[ii].dma_descp - uvp->hci_offset;
16220Sstevel@tonic-gate 			acc_hdl	 = xferctlp->dma[ii].dma_buf->bi_handle;
16230Sstevel@tonic-gate 			dma_hdl	 = xferctlp->dma[ii].dma_buf->bi_dma_handle;
16240Sstevel@tonic-gate 
16250Sstevel@tonic-gate 			if (uvp->skipmode == IXL1394_SKIP_TO_NEXT) {
16260Sstevel@tonic-gate 				if (ii < (xferctlp->cnt - 1)) {
16270Sstevel@tonic-gate 					uvp->skipaddr =
16280Sstevel@tonic-gate 					    xferctlp->dma[ii + 1].dma_bound;
16290Sstevel@tonic-gate 				} else {
16300Sstevel@tonic-gate 					uvp->skipaddr = skipaddrlast;
16310Sstevel@tonic-gate 				}
16320Sstevel@tonic-gate 			} else if (uvp->skipmode == IXL1394_SKIP_TO_SELF) {
16330Sstevel@tonic-gate 				uvp->skipaddr = xferctlp->dma[ii].dma_bound;
16340Sstevel@tonic-gate 			}
16350Sstevel@tonic-gate 
16360Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->branch, uvp->skipaddr);
16370Sstevel@tonic-gate 
16380Sstevel@tonic-gate 			/* Sync descriptor for device (desc was modified) */
16390Sstevel@tonic-gate 			err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
16400Sstevel@tonic-gate 			    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORDEV);
16410Sstevel@tonic-gate 			if (err != DDI_SUCCESS) {
16420Sstevel@tonic-gate 				uvp->upd_status = IXL1394_EINTERNAL_ERROR;
16430Sstevel@tonic-gate 
16440Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
16450Sstevel@tonic-gate 				    hci1394_ixl_update_perform_exit,
16460Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
16470Sstevel@tonic-gate 				return (DDI_FAILURE);
16480Sstevel@tonic-gate 			}
16490Sstevel@tonic-gate 		}
16500Sstevel@tonic-gate 
16510Sstevel@tonic-gate 		/*
16520Sstevel@tonic-gate 		 * set old ixl set skip mode cmd mode and label from new ixl cmd
16530Sstevel@tonic-gate 		 * set old ixl set skip mode cmd compilier_privatep to
16540Sstevel@tonic-gate 		 * uvp->skipxferp
16550Sstevel@tonic-gate 		 */
16560Sstevel@tonic-gate 		old_set_skipmode_ixlp->skipmode = uvp->skipmode;
16570Sstevel@tonic-gate 		old_set_skipmode_ixlp->label = new_set_skipmode_ixlp->label;
16580Sstevel@tonic-gate 		old_set_skipmode_ixlp->compiler_privatep =
16590Sstevel@tonic-gate 		    (ixl1394_priv_t)uvp->skipxferp;
16600Sstevel@tonic-gate 		break;
16610Sstevel@tonic-gate 	}
16620Sstevel@tonic-gate 	case IXL1394_OP_SET_TAGSYNC_U: {
16630Sstevel@tonic-gate 		ixl1394_set_tagsync_t *old_set_tagsync_ixlp;
16640Sstevel@tonic-gate 		ixl1394_set_tagsync_t *new_set_tagsync_ixlp;
16650Sstevel@tonic-gate 
16660Sstevel@tonic-gate 		old_set_tagsync_ixlp = (ixl1394_set_tagsync_t *)uvp->ixloldp;
16670Sstevel@tonic-gate 		new_set_tagsync_ixlp = (ixl1394_set_tagsync_t *)uvp->ixlnewp;
16680Sstevel@tonic-gate 
16690Sstevel@tonic-gate 		/*
16700Sstevel@tonic-gate 		 * iterate through set of descriptor blocks for associated IXL
16710Sstevel@tonic-gate 		 * xfer command and set new pkthdr1 value into output more/last
16720Sstevel@tonic-gate 		 * immediate hci descriptor (first/last hci descriptor of each
16730Sstevel@tonic-gate 		 * descriptor block)
16740Sstevel@tonic-gate 		 */
16750Sstevel@tonic-gate 		for (ii = 0; ii < xferctlp->cnt; ii++) {
16760Sstevel@tonic-gate 			hcidescp = (hci1394_desc_imm_t *)
16770Sstevel@tonic-gate 			    xferctlp->dma[ii].dma_descp - uvp->hdr_offset;
16780Sstevel@tonic-gate 			acc_hdl	 = xferctlp->dma[ii].dma_buf->bi_handle;
16790Sstevel@tonic-gate 			dma_hdl	 = xferctlp->dma[ii].dma_buf->bi_dma_handle;
16800Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->q1, uvp->pkthdr1);
16810Sstevel@tonic-gate 
16820Sstevel@tonic-gate 			/* Sync descriptor for device (desc was modified) */
16830Sstevel@tonic-gate 			err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
16840Sstevel@tonic-gate 			    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORDEV);
16850Sstevel@tonic-gate 			if (err != DDI_SUCCESS) {
16860Sstevel@tonic-gate 				uvp->upd_status = IXL1394_EINTERNAL_ERROR;
16870Sstevel@tonic-gate 
16880Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
16890Sstevel@tonic-gate 				    hci1394_ixl_update_perform_exit,
16900Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
16910Sstevel@tonic-gate 				return (DDI_FAILURE);
16920Sstevel@tonic-gate 			}
16930Sstevel@tonic-gate 		}
16940Sstevel@tonic-gate 
16950Sstevel@tonic-gate 		/*
16960Sstevel@tonic-gate 		 * set old ixl set tagsync cmd tag & sync from new ixl set
16970Sstevel@tonic-gate 		 * tagsync cmd
16980Sstevel@tonic-gate 		 */
16990Sstevel@tonic-gate 		old_set_tagsync_ixlp->tag = new_set_tagsync_ixlp->tag;
17000Sstevel@tonic-gate 		old_set_tagsync_ixlp->sync = new_set_tagsync_ixlp->sync;
17010Sstevel@tonic-gate 		break;
17020Sstevel@tonic-gate 	}
17030Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT_U:
17040Sstevel@tonic-gate 	case IXL1394_OP_RECV_PKT_ST_U: {
17050Sstevel@tonic-gate 		ixl1394_xfer_pkt_t *old_xfer_pkt_ixlp;
17060Sstevel@tonic-gate 		ixl1394_xfer_pkt_t *new_xfer_pkt_ixlp;
17070Sstevel@tonic-gate 		uint32_t	   desc_status;
17080Sstevel@tonic-gate 
17090Sstevel@tonic-gate 		old_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixloldp;
17100Sstevel@tonic-gate 		new_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixlnewp;
17110Sstevel@tonic-gate 
17120Sstevel@tonic-gate 		/*
17130Sstevel@tonic-gate 		 * alter buffer address, count and rescount in ixl recv pkt cmd
17140Sstevel@tonic-gate 		 * related hci component in dma descriptor block
17150Sstevel@tonic-gate 		 */
17160Sstevel@tonic-gate 		hcidescp = (hci1394_desc_imm_t *)
17170Sstevel@tonic-gate 		    xferctlp->dma[0].dma_descp - uvp->hci_offset;
17180Sstevel@tonic-gate 		acc_hdl	 = xferctlp->dma[0].dma_buf->bi_handle;
17190Sstevel@tonic-gate 		dma_hdl	 = xferctlp->dma[0].dma_buf->bi_dma_handle;
17200Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->hdr, uvp->hcihdr);
17210Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->data_addr, uvp->bufaddr);
17220Sstevel@tonic-gate 
17230Sstevel@tonic-gate 		/* Sync the descriptor before we grab the status */
17240Sstevel@tonic-gate 		err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
17250Sstevel@tonic-gate 		    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORCPU);
17260Sstevel@tonic-gate 		if (err != DDI_SUCCESS) {
17270Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EINTERNAL_ERROR;
17280Sstevel@tonic-gate 
17290Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_exit,
17300Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
17310Sstevel@tonic-gate 			return (DDI_FAILURE);
17320Sstevel@tonic-gate 		}
17330Sstevel@tonic-gate 
17340Sstevel@tonic-gate 		/* change only low 1/2 word and leave status bits unchanged */
17350Sstevel@tonic-gate 		desc_status = ddi_get32(acc_hdl, &hcidescp->status);
17360Sstevel@tonic-gate 		desc_status = (desc_status & ~DESC_ST_RESCOUNT_MASK) |
17370Sstevel@tonic-gate 		    uvp->hcistatus;
17380Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->status, desc_status);
17390Sstevel@tonic-gate 
17400Sstevel@tonic-gate 		/* Sync descriptor for device (desc was modified) */
17410Sstevel@tonic-gate 		err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
17420Sstevel@tonic-gate 		    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORDEV);
17430Sstevel@tonic-gate 		if (err != DDI_SUCCESS) {
17440Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EINTERNAL_ERROR;
17450Sstevel@tonic-gate 
17460Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_exit,
17470Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
17480Sstevel@tonic-gate 			return (DDI_FAILURE);
17490Sstevel@tonic-gate 		}
17500Sstevel@tonic-gate 
17510Sstevel@tonic-gate 		/*
17520Sstevel@tonic-gate 		 * set old ixl recv pkt size and buffers from new
17530Sstevel@tonic-gate 		 * ixl recv pkt command
17540Sstevel@tonic-gate 		 */
17550Sstevel@tonic-gate 		old_xfer_pkt_ixlp->size = new_xfer_pkt_ixlp->size;
17560Sstevel@tonic-gate 		old_xfer_pkt_ixlp->ixl_buf.ixldmac_addr =
17570Sstevel@tonic-gate 		    new_xfer_pkt_ixlp->ixl_buf.ixldmac_addr;
17580Sstevel@tonic-gate 		old_xfer_pkt_ixlp->mem_bufp = new_xfer_pkt_ixlp->mem_bufp;
17590Sstevel@tonic-gate 		break;
17600Sstevel@tonic-gate 	}
17610Sstevel@tonic-gate 	case IXL1394_OP_RECV_BUF_U: {
17620Sstevel@tonic-gate 		ixl1394_xfer_buf_t *old_xfer_buf_ixlp;
17630Sstevel@tonic-gate 		ixl1394_xfer_buf_t *new_xfer_buf_ixlp;
17640Sstevel@tonic-gate 		uint32_t	   desc_hdr;
17650Sstevel@tonic-gate 		uint32_t	   desc_status;
17660Sstevel@tonic-gate 
17670Sstevel@tonic-gate 		old_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixloldp;
17680Sstevel@tonic-gate 		new_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixlnewp;
17690Sstevel@tonic-gate 
17700Sstevel@tonic-gate 		/*
17710Sstevel@tonic-gate 		 * iterate through set of descriptor blocks for this IXL xfer
17720Sstevel@tonic-gate 		 * command altering buffer, count and rescount in each
17730Sstevel@tonic-gate 		 * input more/last(the only) hci descriptor block descriptor.
17740Sstevel@tonic-gate 		 */
17750Sstevel@tonic-gate 		for (ii = 0; ii < xferctlp->cnt; ii++) {
17760Sstevel@tonic-gate 
17770Sstevel@tonic-gate 			hcidescp = (hci1394_desc_imm_t *)
17780Sstevel@tonic-gate 			    xferctlp->dma[ii].dma_descp - uvp->hci_offset;
17790Sstevel@tonic-gate 			acc_hdl	 = xferctlp->dma[ii].dma_buf->bi_handle;
17800Sstevel@tonic-gate 			dma_hdl	 = xferctlp->dma[ii].dma_buf->bi_dma_handle;
17810Sstevel@tonic-gate 
17820Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->data_addr, uvp->bufaddr);
17830Sstevel@tonic-gate 
17840Sstevel@tonic-gate 			/*
17850Sstevel@tonic-gate 			 * advance to next buffer segment, adjust over header
17860Sstevel@tonic-gate 			 * if appropriate
17870Sstevel@tonic-gate 			 */
17880Sstevel@tonic-gate 			uvp->bufaddr += uvp->bufsize;
17890Sstevel@tonic-gate 
17900Sstevel@tonic-gate 			/* Sync the descriptor before we grab the header(s) */
17910Sstevel@tonic-gate 			err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
17920Sstevel@tonic-gate 			    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORCPU);
17930Sstevel@tonic-gate 			if (err != DDI_SUCCESS) {
17940Sstevel@tonic-gate 				uvp->upd_status = IXL1394_EINTERNAL_ERROR;
17950Sstevel@tonic-gate 
17960Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
17970Sstevel@tonic-gate 				    hci1394_ixl_update_perform_exit,
17980Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
17990Sstevel@tonic-gate 				return (DDI_FAILURE);
18000Sstevel@tonic-gate 			}
18010Sstevel@tonic-gate 
18020Sstevel@tonic-gate 			/*
18030Sstevel@tonic-gate 			 * this preserves interrupt enable bits, et al. in each
18040Sstevel@tonic-gate 			 * descriptor block header.
18050Sstevel@tonic-gate 			 */
18060Sstevel@tonic-gate 			desc_hdr = ddi_get32(acc_hdl, &hcidescp->hdr);
18070Sstevel@tonic-gate 			desc_hdr = (desc_hdr & ~DESC_HDR_REQCOUNT_MASK) |
18080Sstevel@tonic-gate 			    uvp->hcihdr;
18090Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->hdr, desc_hdr);
18100Sstevel@tonic-gate 
18110Sstevel@tonic-gate 			/*
18120Sstevel@tonic-gate 			 * change only low 1/2 word leaving status bits
18130Sstevel@tonic-gate 			 * unchanged
18140Sstevel@tonic-gate 			 */
18150Sstevel@tonic-gate 			desc_status = ddi_get32(acc_hdl, &hcidescp->status);
18160Sstevel@tonic-gate 			desc_status = (desc_status & ~DESC_ST_RESCOUNT_MASK) |
18170Sstevel@tonic-gate 			    uvp->hcistatus;
18180Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->status, desc_status);
18190Sstevel@tonic-gate 
18200Sstevel@tonic-gate 			/* Sync descriptor for device (desc was modified) */
18210Sstevel@tonic-gate 			err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
18220Sstevel@tonic-gate 			    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORDEV);
18230Sstevel@tonic-gate 			if (err != DDI_SUCCESS) {
18240Sstevel@tonic-gate 				uvp->upd_status = IXL1394_EINTERNAL_ERROR;
18250Sstevel@tonic-gate 
18260Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
18270Sstevel@tonic-gate 				    hci1394_ixl_update_perform_exit,
18280Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
18290Sstevel@tonic-gate 				return (DDI_FAILURE);
18300Sstevel@tonic-gate 			}
18310Sstevel@tonic-gate 		}
18320Sstevel@tonic-gate 
18330Sstevel@tonic-gate 		/*
18340Sstevel@tonic-gate 		 * set old ixl recv buf sizes and buffers from
18350Sstevel@tonic-gate 		 * new ixl recv pkt cmd
18360Sstevel@tonic-gate 		 */
18370Sstevel@tonic-gate 		old_xfer_buf_ixlp->pkt_size = new_xfer_buf_ixlp->pkt_size;
18380Sstevel@tonic-gate 		old_xfer_buf_ixlp->size = new_xfer_buf_ixlp->size;
18390Sstevel@tonic-gate 		old_xfer_buf_ixlp->ixl_buf.ixldmac_addr =
18400Sstevel@tonic-gate 		    new_xfer_buf_ixlp->ixl_buf.ixldmac_addr;
18410Sstevel@tonic-gate 		old_xfer_buf_ixlp->mem_bufp = new_xfer_buf_ixlp->mem_bufp;
18420Sstevel@tonic-gate 		break;
18430Sstevel@tonic-gate 	}
18440Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_U:
18450Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_ST_U:
18460Sstevel@tonic-gate 	case IXL1394_OP_SEND_PKT_WHDR_ST_U: {
18470Sstevel@tonic-gate 		ixl1394_xfer_pkt_t *old_xfer_pkt_ixlp;
18480Sstevel@tonic-gate 		ixl1394_xfer_pkt_t *new_xfer_pkt_ixlp;
18490Sstevel@tonic-gate 
18500Sstevel@tonic-gate 		old_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixloldp;
18510Sstevel@tonic-gate 		new_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)uvp->ixlnewp;
18520Sstevel@tonic-gate 
18530Sstevel@tonic-gate 		/*
18540Sstevel@tonic-gate 		 * replace pkthdr2 in output more immediate (the first) hci
18550Sstevel@tonic-gate 		 * descriptor in block, then alter buffer address and count in
18560Sstevel@tonic-gate 		 * IXL send pkt command related output more/last hci descriptor.
18570Sstevel@tonic-gate 		 */
18580Sstevel@tonic-gate 		hcidescp = (hci1394_desc_imm_t *)xferctlp->dma[0].dma_descp -
18590Sstevel@tonic-gate 		    uvp->hdr_offset;
18600Sstevel@tonic-gate 		acc_hdl	 = xferctlp->dma[0].dma_buf->bi_handle;
18610Sstevel@tonic-gate 		dma_hdl	 = xferctlp->dma[0].dma_buf->bi_dma_handle;
18620Sstevel@tonic-gate 
18630Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->q2, uvp->pkthdr2);
18640Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->hdr, uvp->hcihdr);
18650Sstevel@tonic-gate 		ddi_put32(acc_hdl, &hcidescp->data_addr, uvp->bufaddr);
18660Sstevel@tonic-gate 
18670Sstevel@tonic-gate 		/* Sync descriptor for device (desc was modified) */
18680Sstevel@tonic-gate 		err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
18690Sstevel@tonic-gate 		    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORDEV);
18700Sstevel@tonic-gate 		if (err != DDI_SUCCESS) {
18710Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EINTERNAL_ERROR;
18720Sstevel@tonic-gate 
18730Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_exit,
18740Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
18750Sstevel@tonic-gate 			return (DDI_FAILURE);
18760Sstevel@tonic-gate 		}
18770Sstevel@tonic-gate 
18780Sstevel@tonic-gate 		/*
18790Sstevel@tonic-gate 		 * set old ixl recv pkt size and buffers from
18800Sstevel@tonic-gate 		 * new ixl recv pkt cmd
18810Sstevel@tonic-gate 		 */
18820Sstevel@tonic-gate 		old_xfer_pkt_ixlp->size = new_xfer_pkt_ixlp->size;
18830Sstevel@tonic-gate 		old_xfer_pkt_ixlp->ixl_buf.ixldmac_addr =
18840Sstevel@tonic-gate 		    new_xfer_pkt_ixlp->ixl_buf.ixldmac_addr;
18850Sstevel@tonic-gate 		old_xfer_pkt_ixlp->mem_bufp = new_xfer_pkt_ixlp->mem_bufp;
18860Sstevel@tonic-gate 		break;
18870Sstevel@tonic-gate 	}
18880Sstevel@tonic-gate 	case IXL1394_OP_SEND_BUF_U: {
18890Sstevel@tonic-gate 		ixl1394_xfer_buf_t *old_xfer_buf_ixlp;
18900Sstevel@tonic-gate 		ixl1394_xfer_buf_t *new_xfer_buf_ixlp;
18910Sstevel@tonic-gate 		uint32_t	   desc_hdr;
18920Sstevel@tonic-gate 
18930Sstevel@tonic-gate 		old_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixloldp;
18940Sstevel@tonic-gate 		new_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)uvp->ixlnewp;
18950Sstevel@tonic-gate 
18960Sstevel@tonic-gate 		/*
18970Sstevel@tonic-gate 		 * iterate through set of descriptor blocks for this IXL xfer
18980Sstevel@tonic-gate 		 * command replacing pkthdr2 in output more immediate
18990Sstevel@tonic-gate 		 * (the first) hci descriptor block descriptor, then altering
19000Sstevel@tonic-gate 		 * buffer address and count in each output last (the only other)
19010Sstevel@tonic-gate 		 * hci descriptor block descriptor.
19020Sstevel@tonic-gate 		 */
19030Sstevel@tonic-gate 		for (ii = 0; ii < xferctlp->cnt; ii++) {
19040Sstevel@tonic-gate 			hcidescp = (hci1394_desc_imm_t *)
19050Sstevel@tonic-gate 			    xferctlp->dma[ii].dma_descp - uvp->hdr_offset;
19060Sstevel@tonic-gate 			acc_hdl	 = xferctlp->dma[ii].dma_buf->bi_handle;
19070Sstevel@tonic-gate 			dma_hdl	 = xferctlp->dma[ii].dma_buf->bi_dma_handle;
19080Sstevel@tonic-gate 
19090Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->q2, uvp->pkthdr2);
19100Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->data_addr, uvp->bufaddr);
19110Sstevel@tonic-gate 
19120Sstevel@tonic-gate 			/* advance to next buffer segment */
19130Sstevel@tonic-gate 			uvp->bufaddr += uvp->bufsize;
19140Sstevel@tonic-gate 
19150Sstevel@tonic-gate 			/* Sync the descriptor before we grab the header(s) */
19160Sstevel@tonic-gate 			err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
19170Sstevel@tonic-gate 			    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORCPU);
19180Sstevel@tonic-gate 			if (err != DDI_SUCCESS) {
19190Sstevel@tonic-gate 				uvp->upd_status = IXL1394_EINTERNAL_ERROR;
19200Sstevel@tonic-gate 
19210Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
19220Sstevel@tonic-gate 				    hci1394_ixl_update_perform_exit,
19230Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
19240Sstevel@tonic-gate 				return (DDI_FAILURE);
19250Sstevel@tonic-gate 			}
19260Sstevel@tonic-gate 
19270Sstevel@tonic-gate 			/*
19280Sstevel@tonic-gate 			 * this preserves interrupt enable bits, et al
19290Sstevel@tonic-gate 			 * in each desc block hdr
19300Sstevel@tonic-gate 			 */
19310Sstevel@tonic-gate 			desc_hdr = ddi_get32(acc_hdl, &hcidescp->hdr);
19320Sstevel@tonic-gate 			desc_hdr = (desc_hdr & ~DESC_HDR_REQCOUNT_MASK) |
19330Sstevel@tonic-gate 			    uvp->hcihdr;
19340Sstevel@tonic-gate 			ddi_put32(acc_hdl, &hcidescp->hdr, desc_hdr);
19350Sstevel@tonic-gate 
19360Sstevel@tonic-gate 			/* Sync descriptor for device (desc was modified) */
19370Sstevel@tonic-gate 			err = ddi_dma_sync(dma_hdl, (off_t)hcidescp,
19380Sstevel@tonic-gate 			    sizeof (hci1394_desc_imm_t), DDI_DMA_SYNC_FORDEV);
19390Sstevel@tonic-gate 			if (err != DDI_SUCCESS) {
19400Sstevel@tonic-gate 				uvp->upd_status = IXL1394_EINTERNAL_ERROR;
19410Sstevel@tonic-gate 
19420Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(
19430Sstevel@tonic-gate 				    hci1394_ixl_update_perform_exit,
19440Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK_ISOCH, "");
19450Sstevel@tonic-gate 				return (DDI_FAILURE);
19460Sstevel@tonic-gate 			}
19470Sstevel@tonic-gate 		}
19480Sstevel@tonic-gate 
19490Sstevel@tonic-gate 		/*
19500Sstevel@tonic-gate 		 * set old ixl recv buf sizes and buffers from
19510Sstevel@tonic-gate 		 * new ixl recv pkt cmd
19520Sstevel@tonic-gate 		 */
19530Sstevel@tonic-gate 		old_xfer_buf_ixlp->pkt_size = new_xfer_buf_ixlp->pkt_size;
19540Sstevel@tonic-gate 		old_xfer_buf_ixlp->size = new_xfer_buf_ixlp->size;
19550Sstevel@tonic-gate 		old_xfer_buf_ixlp->ixl_buf.ixldmac_addr =
19560Sstevel@tonic-gate 		    new_xfer_buf_ixlp->ixl_buf.ixldmac_addr;
19570Sstevel@tonic-gate 		old_xfer_buf_ixlp->mem_bufp = new_xfer_buf_ixlp->mem_bufp;
19580Sstevel@tonic-gate 		break;
19590Sstevel@tonic-gate 	}
19600Sstevel@tonic-gate 	default:
19610Sstevel@tonic-gate 		/* ixl command being updated must be one of above, else error */
19620Sstevel@tonic-gate 		uvp->upd_status = IXL1394_EINTERNAL_ERROR;
19630Sstevel@tonic-gate 
19640Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_exit,
19650Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK_ISOCH, "");
19660Sstevel@tonic-gate 		return (DDI_FAILURE);
19670Sstevel@tonic-gate 	}
19680Sstevel@tonic-gate 
19690Sstevel@tonic-gate 	/* hit the WAKE bit in the context control register */
19700Sstevel@tonic-gate 	if (ctxtp->ctxt_flags & HCI1394_ISO_CTXT_RECV) {
19710Sstevel@tonic-gate 		HCI1394_IRCTXT_CTRL_SET(uvp->soft_statep, ctxtp->ctxt_index,
19720Sstevel@tonic-gate 		    0, 0, 0, 0, 0, 1 /* wake */);
19730Sstevel@tonic-gate 	} else {
19740Sstevel@tonic-gate 		HCI1394_ITCTXT_CTRL_SET(uvp->soft_statep, ctxtp->ctxt_index,
19750Sstevel@tonic-gate 		    0, 0, 0, 1 /* wake */);
19760Sstevel@tonic-gate 	}
19770Sstevel@tonic-gate 
19780Sstevel@tonic-gate 	/* perform update completed successfully */
19790Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_perform_exit,
19800Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
19810Sstevel@tonic-gate 	return (DDI_SUCCESS);
19820Sstevel@tonic-gate }
19830Sstevel@tonic-gate 
19840Sstevel@tonic-gate /*
19850Sstevel@tonic-gate  * hci1394_ixl_update_evaluate()
19860Sstevel@tonic-gate  *    Evaluate where the hardware is in running through the DMA descriptor
19870Sstevel@tonic-gate  *    blocks.
19880Sstevel@tonic-gate  */
19890Sstevel@tonic-gate static int
hci1394_ixl_update_evaluate(hci1394_ixl_update_vars_t * uvp)19900Sstevel@tonic-gate hci1394_ixl_update_evaluate(hci1394_ixl_update_vars_t *uvp)
19910Sstevel@tonic-gate {
19920Sstevel@tonic-gate 	hci1394_iso_ctxt_t	*ctxtp;
19930Sstevel@tonic-gate 	ixl1394_command_t	*ixlp;
19940Sstevel@tonic-gate 	int			ixldepth;
19950Sstevel@tonic-gate 	int			ii;
19960Sstevel@tonic-gate 
19970Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_evaluate_enter,
19980Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
19990Sstevel@tonic-gate 
20000Sstevel@tonic-gate 	ctxtp = uvp->ctxtp;
20010Sstevel@tonic-gate 
20020Sstevel@tonic-gate 	ixlp = NULL;
20030Sstevel@tonic-gate 	ixldepth = 0xFFFFFFFF;
20040Sstevel@tonic-gate 
20050Sstevel@tonic-gate 	/*
20060Sstevel@tonic-gate 	 * repeat until IXL execution status evaluation function returns error
20070Sstevel@tonic-gate 	 * or until pointer to currently executing IXL command and its depth
20080Sstevel@tonic-gate 	 * stablize
20090Sstevel@tonic-gate 	 */
20100Sstevel@tonic-gate 	while ((ixlp != ctxtp->ixl_execp) ||
20110Sstevel@tonic-gate 	    (ixldepth != ctxtp->ixl_exec_depth)) {
20120Sstevel@tonic-gate 
20130Sstevel@tonic-gate 		ixlp = ctxtp->ixl_execp;
20140Sstevel@tonic-gate 		ixldepth = ctxtp->ixl_exec_depth;
20150Sstevel@tonic-gate 
20160Sstevel@tonic-gate 		/*
20170Sstevel@tonic-gate 		 * call IXL execution status evaluation (ixl_dma_sync)
20180Sstevel@tonic-gate 		 * function returning if error (HCI1394_IXL_INTR_DMALOST is
20190Sstevel@tonic-gate 		 * only error condition).
20200Sstevel@tonic-gate 		 *
20210Sstevel@tonic-gate 		 * Note: interrupt processing function can only return one of
20220Sstevel@tonic-gate 		 * the following statuses here:
20230Sstevel@tonic-gate 		 *    HCI1394_IXL_INTR_NOERROR, HCI1394_IXL_INTR_DMASTOP,
20240Sstevel@tonic-gate 		 *    HCI1394_IXL_INTR_DMALOST
20250Sstevel@tonic-gate 		 *
20260Sstevel@tonic-gate 		 * it can not return the following status here:
20270Sstevel@tonic-gate 		 *    HCI1394_IXL_INTR_NOADV
20280Sstevel@tonic-gate 		 *
20290Sstevel@tonic-gate 		 * Don't need to grab the lock here... for the same reason
20300Sstevel@tonic-gate 		 * explained in hci1394_ixl_update_endup() above.
20310Sstevel@tonic-gate 		 */
20320Sstevel@tonic-gate 		ctxtp->intr_flags &= ~HCI1394_ISO_CTXT_INTRSET;
20330Sstevel@tonic-gate 		if (hci1394_ixl_dma_sync(uvp->soft_statep, ctxtp) ==
20340Sstevel@tonic-gate 		    HCI1394_IXL_INTR_DMALOST) {
20350Sstevel@tonic-gate 
20360Sstevel@tonic-gate 			/* return post-perform update failed status */
20370Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EPOST_UPD_DMALOST;
20380Sstevel@tonic-gate 
20390Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_evaluate_exit,
20400Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
20410Sstevel@tonic-gate 			return (DDI_FAILURE);
20420Sstevel@tonic-gate 		}
20430Sstevel@tonic-gate 	}
20440Sstevel@tonic-gate 
20450Sstevel@tonic-gate 	/*
20460Sstevel@tonic-gate 	 * if the currently executing IXL command is one of the IXL_MAX_LOCN
20470Sstevel@tonic-gate 	 * locations saved before update was performed, return update
20480Sstevel@tonic-gate 	 * successful status.
20490Sstevel@tonic-gate 	 */
20500Sstevel@tonic-gate 	for (ii = 0; ii < IXL_MAX_LOCN; ii++) {
20510Sstevel@tonic-gate 		if ((uvp->locn_info[ii].ixlp == ixlp) &&
20520Sstevel@tonic-gate 		    (uvp->locn_info[ii].ixldepth == ixldepth)) {
20530Sstevel@tonic-gate 
20540Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_evaluate_exit,
20550Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
20560Sstevel@tonic-gate 			return (DDI_SUCCESS);
20570Sstevel@tonic-gate 		}
20580Sstevel@tonic-gate 	}
20590Sstevel@tonic-gate 
20600Sstevel@tonic-gate 	/*
20610Sstevel@tonic-gate 	 * else return post-perform update failed status.
20620Sstevel@tonic-gate 	 * note: later can make more sophisticated evaluations about where
20630Sstevel@tonic-gate 	 * execution processing went, and if update has really failed.
20640Sstevel@tonic-gate 	 */
20650Sstevel@tonic-gate 	uvp->upd_status = IXL1394_EPOST_UPD_DMALOST;
20660Sstevel@tonic-gate 
20670Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_evaluate_exit,
20680Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
20690Sstevel@tonic-gate 	return (DDI_FAILURE);
20700Sstevel@tonic-gate }
20710Sstevel@tonic-gate 
20720Sstevel@tonic-gate /*
20730Sstevel@tonic-gate  * hci1394_ixl_update_analysis()
20740Sstevel@tonic-gate  *    Determine if the hardware is within the range we expected it to be.
20750Sstevel@tonic-gate  *    If so the update succeeded.
20760Sstevel@tonic-gate  */
20770Sstevel@tonic-gate static int
hci1394_ixl_update_analysis(hci1394_ixl_update_vars_t * uvp)20780Sstevel@tonic-gate hci1394_ixl_update_analysis(hci1394_ixl_update_vars_t *uvp)
20790Sstevel@tonic-gate {
20800Sstevel@tonic-gate 	hci1394_iso_ctxt_t	*ctxtp;
20810Sstevel@tonic-gate 	ixl1394_command_t	*ixlp;
20820Sstevel@tonic-gate 	int			ixldepth;
20830Sstevel@tonic-gate 	int			ii;
20840Sstevel@tonic-gate 	int			status;
20850Sstevel@tonic-gate 
20860Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_analysis_enter,
20870Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
20880Sstevel@tonic-gate 
20890Sstevel@tonic-gate 	ctxtp = uvp->ctxtp;
20900Sstevel@tonic-gate 
20910Sstevel@tonic-gate 	ixlp = NULL;
20920Sstevel@tonic-gate 	ixldepth = 0xFFFFFFFF;
20930Sstevel@tonic-gate 
20940Sstevel@tonic-gate 	/*
20950Sstevel@tonic-gate 	 * repeat until ixl execution status evaluation function returns error
20960Sstevel@tonic-gate 	 * or until pointer to currently executing ixl command and its depth
20970Sstevel@tonic-gate 	 * stablize.
20980Sstevel@tonic-gate 	 */
20990Sstevel@tonic-gate 	while ((ixlp != ctxtp->ixl_execp) ||
21000Sstevel@tonic-gate 	    (ixldepth != ctxtp->ixl_exec_depth)) {
21010Sstevel@tonic-gate 
21020Sstevel@tonic-gate 		ixlp = ctxtp->ixl_execp;
21030Sstevel@tonic-gate 		ixldepth = ctxtp->ixl_exec_depth;
21040Sstevel@tonic-gate 
21050Sstevel@tonic-gate 		/*
21060Sstevel@tonic-gate 		 * call ixl execution status evaluation (interrupt processing).
21070Sstevel@tonic-gate 		 * set IXL1394_EIDU_PRE_UPD_DMALOST if status INTR_DMALOST and
21080Sstevel@tonic-gate 		 * return.
21090Sstevel@tonic-gate 		 *
21100Sstevel@tonic-gate 		 * Note: interrupt processing function can only return one of
21110Sstevel@tonic-gate 		 * the following statuses here:
21120Sstevel@tonic-gate 		 *    HCI1394_IXL_INTR_NOERROR, HCI1394_IXL_INTR_DMASTOP or
21130Sstevel@tonic-gate 		 *    HCI1394_IXL_INTR_DMALOST
21140Sstevel@tonic-gate 		 *
21150Sstevel@tonic-gate 		 * it can not return the following status here:
21160Sstevel@tonic-gate 		 *    HCI1394_IXL_INTR_NOADV
21170Sstevel@tonic-gate 		 *
21180Sstevel@tonic-gate 		 * Don't need to grab the lock here... for the same reason
21190Sstevel@tonic-gate 		 * explained in hci1394_ixl_update_endup() above.
21200Sstevel@tonic-gate 		 */
21210Sstevel@tonic-gate 		ctxtp->intr_flags &= ~HCI1394_ISO_CTXT_INTRSET;
21220Sstevel@tonic-gate 
21230Sstevel@tonic-gate 		status = hci1394_ixl_dma_sync(uvp->soft_statep, ctxtp);
21240Sstevel@tonic-gate 		if (status == HCI1394_IXL_INTR_DMALOST) {
21250Sstevel@tonic-gate 			/*
21260Sstevel@tonic-gate 			 * set pre-update dma processing lost status and
21270Sstevel@tonic-gate 			 * return error
21280Sstevel@tonic-gate 			 */
21290Sstevel@tonic-gate 			uvp->upd_status = IXL1394_EPRE_UPD_DMALOST;
21300Sstevel@tonic-gate 
21310Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_analysis_exit,
21320Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
21330Sstevel@tonic-gate 			return (DDI_FAILURE);
21340Sstevel@tonic-gate 		}
21350Sstevel@tonic-gate 	}
21360Sstevel@tonic-gate 
21370Sstevel@tonic-gate 	/*
21380Sstevel@tonic-gate 	 * save locations of currently executing ixl command and the
21390Sstevel@tonic-gate 	 * 3 following it.
21400Sstevel@tonic-gate 	 */
21410Sstevel@tonic-gate 	hci1394_ixl_update_set_locn_info(uvp);
21420Sstevel@tonic-gate 
21430Sstevel@tonic-gate 	/*
21440Sstevel@tonic-gate 	 * if xfer_ixl_cmd associated with the IXL_command being updated is one
21450Sstevel@tonic-gate 	 * of the saved (currently executing) IXL commands, risk is too great to
21460Sstevel@tonic-gate 	 * perform update now, set IXL1394_ERISK_PROHIBITS_UPD status and
21470Sstevel@tonic-gate 	 * return error.
21480Sstevel@tonic-gate 	 *
21490Sstevel@tonic-gate 	 * Note: later can implement more sophisticated risk override
21500Sstevel@tonic-gate 	 * evaluations and processing.
21510Sstevel@tonic-gate 	 */
21520Sstevel@tonic-gate 	for (ii = 0; ii < IXL_MAX_LOCN; ii++) {
21530Sstevel@tonic-gate 
21540Sstevel@tonic-gate 		if ((uvp->locn_info[ii].ixlp == uvp->ixlxferp) &&
21550Sstevel@tonic-gate 		    (uvp->locn_info[ii].ixldepth >= uvp->ixldepth) &&
21560Sstevel@tonic-gate 		    (uvp->locn_info[ii].ixldepth <
21570Sstevel@tonic-gate 			(uvp->ixldepth + uvp->ixlcount))) {
21580Sstevel@tonic-gate 
21590Sstevel@tonic-gate 			uvp->upd_status = IXL1394_ERISK_PROHIBITS_UPD;
21600Sstevel@tonic-gate 
21610Sstevel@tonic-gate 			TNF_PROBE_0_DEBUG(hci1394_ixl_update_analysis_exit,
21620Sstevel@tonic-gate 			    HCI1394_TNF_HAL_STACK_ISOCH, "");
21630Sstevel@tonic-gate 			return (DDI_FAILURE);
21640Sstevel@tonic-gate 		}
21650Sstevel@tonic-gate 	}
21660Sstevel@tonic-gate 
21670Sstevel@tonic-gate 	/* is save for update to be performed, return ok status */
21680Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_analysis_exit,
21690Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
21700Sstevel@tonic-gate 	return (DDI_SUCCESS);
21710Sstevel@tonic-gate }
21720Sstevel@tonic-gate 
21730Sstevel@tonic-gate /*
21740Sstevel@tonic-gate  * hci1394_ixl_update_set_locn_info()
21750Sstevel@tonic-gate  *    set up the local list of the IXL_MAX_LOCN next commandPtr locations we
21760Sstevel@tonic-gate  *    expect the hardware to get to in the next 125 microseconds.
21770Sstevel@tonic-gate  */
21780Sstevel@tonic-gate static void
hci1394_ixl_update_set_locn_info(hci1394_ixl_update_vars_t * uvp)21790Sstevel@tonic-gate hci1394_ixl_update_set_locn_info(hci1394_ixl_update_vars_t *uvp)
21800Sstevel@tonic-gate {
21810Sstevel@tonic-gate 	hci1394_iso_ctxt_t	*ctxtp;
21820Sstevel@tonic-gate 	ixl1394_command_t	*ixlp;
21830Sstevel@tonic-gate 	int			ixldepth;
21840Sstevel@tonic-gate 	int			ii;
21850Sstevel@tonic-gate 
21860Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_set_locn_info_enter,
21870Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
21880Sstevel@tonic-gate 
21890Sstevel@tonic-gate 	/*
21900Sstevel@tonic-gate 	 * find next xfer start ixl command, starting with current ixl command
21910Sstevel@tonic-gate 	 * where execution last left off
21920Sstevel@tonic-gate 	 */
21930Sstevel@tonic-gate 	ctxtp = uvp->ctxtp;
21940Sstevel@tonic-gate 
21950Sstevel@tonic-gate 	ixldepth = ctxtp->ixl_exec_depth;
21960Sstevel@tonic-gate 	(void) hci1394_ixl_find_next_exec_xfer(ctxtp->ixl_execp, NULL, &ixlp);
21970Sstevel@tonic-gate 
21980Sstevel@tonic-gate 	/*
21990Sstevel@tonic-gate 	 * if the current IXL command wasn't a xfer start command, then reset
22000Sstevel@tonic-gate 	 * the depth to 0 for xfer command found
22010Sstevel@tonic-gate 	 */
22020Sstevel@tonic-gate 	if (ixlp != ctxtp->ixl_execp)
22030Sstevel@tonic-gate 		ixldepth = 0;
22040Sstevel@tonic-gate 
22050Sstevel@tonic-gate 	/*
22060Sstevel@tonic-gate 	 * save xfer start IXL command & its depth and also save location and
22070Sstevel@tonic-gate 	 * depth of the next IXL_MAX_LOCN-1 xfer start IXL commands following
22080Sstevel@tonic-gate 	 * it (if any)
22090Sstevel@tonic-gate 	 */
22100Sstevel@tonic-gate 	for (ii = 0; ii < IXL_MAX_LOCN; ii++) {
22110Sstevel@tonic-gate 		uvp->locn_info[ii].ixlp = ixlp;
22120Sstevel@tonic-gate 		uvp->locn_info[ii].ixldepth = ixldepth;
22130Sstevel@tonic-gate 
22140Sstevel@tonic-gate 		if (ixlp) {
22150Sstevel@tonic-gate 			/*
22160Sstevel@tonic-gate 			 * if more dma commands generated by this xfer command
22170Sstevel@tonic-gate 			 * still follow, use them. else, find the next xfer
22180Sstevel@tonic-gate 			 * start IXL command and set its depth to 0.
22190Sstevel@tonic-gate 			 */
22200Sstevel@tonic-gate 			if (++ixldepth >= ((hci1394_xfer_ctl_t *)
22210Sstevel@tonic-gate 			    ixlp->compiler_privatep)->cnt) {
22220Sstevel@tonic-gate 
22230Sstevel@tonic-gate 				(void) hci1394_ixl_find_next_exec_xfer(
22240Sstevel@tonic-gate 				    ixlp->next_ixlp, NULL, &ixlp);
22250Sstevel@tonic-gate 				ixldepth = 0;
22260Sstevel@tonic-gate 			}
22270Sstevel@tonic-gate 		}
22280Sstevel@tonic-gate 	}
22290Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_ixl_update_set_locn_info_exit,
22300Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK_ISOCH, "");
22310Sstevel@tonic-gate }
2232