1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate * hci1394_ixl_misc.c
31*0Sstevel@tonic-gate * Isochronous IXL miscellaneous routines.
32*0Sstevel@tonic-gate * Contains common routines used by the ixl compiler, interrupt handler and
33*0Sstevel@tonic-gate * dynamic update.
34*0Sstevel@tonic-gate */
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gate #include <sys/kmem.h>
37*0Sstevel@tonic-gate #include <sys/types.h>
38*0Sstevel@tonic-gate #include <sys/conf.h>
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gate #include <sys/tnf_probe.h>
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gate #include <sys/1394/h1394.h>
43*0Sstevel@tonic-gate #include <sys/1394/ixl1394.h>
44*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate
47*0Sstevel@tonic-gate /* local routines */
48*0Sstevel@tonic-gate static void hci1394_delete_dma_desc_mem(hci1394_state_t *soft_statep,
49*0Sstevel@tonic-gate hci1394_idma_desc_mem_t *);
50*0Sstevel@tonic-gate static void hci1394_delete_xfer_ctl(hci1394_xfer_ctl_t *);
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gate /*
54*0Sstevel@tonic-gate * hci1394_ixl_set_start()
55*0Sstevel@tonic-gate * Set up the context structure with the first ixl command to process
56*0Sstevel@tonic-gate * and the first hci descriptor to execute.
57*0Sstevel@tonic-gate *
58*0Sstevel@tonic-gate * This function assumes the current context is stopped!
59*0Sstevel@tonic-gate *
60*0Sstevel@tonic-gate * If ixlstp IS NOT null AND is not the first compiled ixl command and
61*0Sstevel@tonic-gate * is not an ixl label command, returns an error.
62*0Sstevel@tonic-gate * If ixlstp IS null, uses the first compiled ixl command (ixl_firstp)
63*0Sstevel@tonic-gate * in place of ixlstp.
64*0Sstevel@tonic-gate *
65*0Sstevel@tonic-gate * If no executeable xfer found along exec path from ixlstp, returns error.
66*0Sstevel@tonic-gate */
67*0Sstevel@tonic-gate int
hci1394_ixl_set_start(hci1394_iso_ctxt_t * ctxtp,ixl1394_command_t * ixlstp)68*0Sstevel@tonic-gate hci1394_ixl_set_start(hci1394_iso_ctxt_t *ctxtp, ixl1394_command_t *ixlstp)
69*0Sstevel@tonic-gate {
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gate ixl1394_command_t *ixl_exec_startp;
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_set_start_enter,
74*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
75*0Sstevel@tonic-gate
76*0Sstevel@tonic-gate /* if ixl start command is null, use first compiled ixl command */
77*0Sstevel@tonic-gate if (ixlstp == NULL) {
78*0Sstevel@tonic-gate ixlstp = ctxtp->ixl_firstp;
79*0Sstevel@tonic-gate }
80*0Sstevel@tonic-gate
81*0Sstevel@tonic-gate /*
82*0Sstevel@tonic-gate * if ixl start command is not first ixl compiled and is not a label,
83*0Sstevel@tonic-gate * error
84*0Sstevel@tonic-gate */
85*0Sstevel@tonic-gate if ((ixlstp != ctxtp->ixl_firstp) && (ixlstp->ixl_opcode !=
86*0Sstevel@tonic-gate IXL1394_OP_LABEL)) {
87*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_set_start_exit,
88*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
89*0Sstevel@tonic-gate return (-1);
90*0Sstevel@tonic-gate }
91*0Sstevel@tonic-gate
92*0Sstevel@tonic-gate /* follow exec path to find first ixl command that's an xfer command */
93*0Sstevel@tonic-gate (void) hci1394_ixl_find_next_exec_xfer(ixlstp, NULL, &ixl_exec_startp);
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate /*
96*0Sstevel@tonic-gate * if there was one, then in it's compiler private, its
97*0Sstevel@tonic-gate * hci1394_xfer_ctl structure has the appropriate bound address
98*0Sstevel@tonic-gate */
99*0Sstevel@tonic-gate if (ixl_exec_startp != NULL) {
100*0Sstevel@tonic-gate
101*0Sstevel@tonic-gate /* set up for start of context and return done */
102*0Sstevel@tonic-gate ctxtp->dma_mem_execp = (uint32_t)((hci1394_xfer_ctl_t *)
103*0Sstevel@tonic-gate ixl_exec_startp->compiler_privatep)->dma[0].dma_bound;
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gate ctxtp->dma_last_time = 0;
106*0Sstevel@tonic-gate ctxtp->ixl_exec_depth = 0;
107*0Sstevel@tonic-gate ctxtp->ixl_execp = ixlstp;
108*0Sstevel@tonic-gate ctxtp->rem_noadv_intrs = ctxtp->max_noadv_intrs;
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_set_start_exit,
111*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
112*0Sstevel@tonic-gate return (0);
113*0Sstevel@tonic-gate }
114*0Sstevel@tonic-gate
115*0Sstevel@tonic-gate /* else no executeable xfer command found, return error */
116*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_set_start_exit,
117*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
118*0Sstevel@tonic-gate return (1);
119*0Sstevel@tonic-gate }
120*0Sstevel@tonic-gate #ifdef _KERNEL
121*0Sstevel@tonic-gate /*
122*0Sstevel@tonic-gate * hci1394_ixl_reset_status()
123*0Sstevel@tonic-gate * Reset all statuses in all hci descriptor blocks associated with the
124*0Sstevel@tonic-gate * current linked list of compiled ixl commands.
125*0Sstevel@tonic-gate *
126*0Sstevel@tonic-gate * This function assumes the current context is stopped!
127*0Sstevel@tonic-gate */
128*0Sstevel@tonic-gate void
hci1394_ixl_reset_status(hci1394_iso_ctxt_t * ctxtp)129*0Sstevel@tonic-gate hci1394_ixl_reset_status(hci1394_iso_ctxt_t *ctxtp)
130*0Sstevel@tonic-gate {
131*0Sstevel@tonic-gate ixl1394_command_t *ixlcur;
132*0Sstevel@tonic-gate ixl1394_command_t *ixlnext;
133*0Sstevel@tonic-gate hci1394_xfer_ctl_t *xferctlp;
134*0Sstevel@tonic-gate uint_t ixldepth;
135*0Sstevel@tonic-gate uint16_t timestamp;
136*0Sstevel@tonic-gate
137*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_reset_status_enter,
138*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
139*0Sstevel@tonic-gate
140*0Sstevel@tonic-gate ixlnext = ctxtp->ixl_firstp;
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gate /*
143*0Sstevel@tonic-gate * Scan for next ixl xfer start command along ixl link path.
144*0Sstevel@tonic-gate * Once xfer command found, clear its hci descriptor block's
145*0Sstevel@tonic-gate * status. If is composite ixl xfer command, clear statuses
146*0Sstevel@tonic-gate * in each of its hci descriptor blocks.
147*0Sstevel@tonic-gate */
148*0Sstevel@tonic-gate while (ixlnext != NULL) {
149*0Sstevel@tonic-gate
150*0Sstevel@tonic-gate /* set current and next ixl command */
151*0Sstevel@tonic-gate ixlcur = ixlnext;
152*0Sstevel@tonic-gate ixlnext = ixlcur->next_ixlp;
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate /* skip to examine next if this is not xfer start ixl command */
155*0Sstevel@tonic-gate if (((ixlcur->ixl_opcode & IXL1394_OPF_ISXFER) == 0) ||
156*0Sstevel@tonic-gate ((ixlcur->ixl_opcode & IXL1394_OPTY_MASK) == 0)) {
157*0Sstevel@tonic-gate continue;
158*0Sstevel@tonic-gate }
159*0Sstevel@tonic-gate
160*0Sstevel@tonic-gate /* get control struct for this xfer start ixl command */
161*0Sstevel@tonic-gate xferctlp = (hci1394_xfer_ctl_t *)ixlcur->compiler_privatep;
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gate /* clear status in each hci descriptor block for this ixl cmd */
164*0Sstevel@tonic-gate ixldepth = 0;
165*0Sstevel@tonic-gate while (ixldepth < xferctlp->cnt) {
166*0Sstevel@tonic-gate (void) hci1394_ixl_check_status(
167*0Sstevel@tonic-gate &xferctlp->dma[ixldepth], ixlcur->ixl_opcode,
168*0Sstevel@tonic-gate ×tamp, B_TRUE);
169*0Sstevel@tonic-gate ixldepth++;
170*0Sstevel@tonic-gate }
171*0Sstevel@tonic-gate }
172*0Sstevel@tonic-gate
173*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_reset_status_exit,
174*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
175*0Sstevel@tonic-gate }
176*0Sstevel@tonic-gate #endif
177*0Sstevel@tonic-gate /*
178*0Sstevel@tonic-gate * hci1394_ixl_find_next_exec_xfer()
179*0Sstevel@tonic-gate * Follows execution path of ixl linked list until finds next xfer start IXL
180*0Sstevel@tonic-gate * command, including the current IXL command or finds end of IXL linked
181*0Sstevel@tonic-gate * list. Counts callback commands found along the way. (Previously, counted
182*0Sstevel@tonic-gate * store timestamp commands, as well.)
183*0Sstevel@tonic-gate *
184*0Sstevel@tonic-gate * To detect an infinite loop of label<->jump without an intervening xfer,
185*0Sstevel@tonic-gate * a tolerance level of HCI1394_IXL_MAX_SEQ_JUMPS is used. Once this
186*0Sstevel@tonic-gate * number of jumps is traversed, the IXL prog is assumed to have a loop.
187*0Sstevel@tonic-gate *
188*0Sstevel@tonic-gate * Returns DDI_SUCCESS or DDI_FAILURE. DDI_FAILURE, indicates an infinite
189*0Sstevel@tonic-gate * loop of labels & jumps was detected without any intervening xfers.
190*0Sstevel@tonic-gate * DDI_SUCCESS indicates the next_exec_ixlpp contains the next xfer ixlp
191*0Sstevel@tonic-gate * address, or NULL indicating the end of the list was reached. Note that
192*0Sstevel@tonic-gate * DDI_FAILURE can only be returned during the IXL compilation phase, and
193*0Sstevel@tonic-gate * not during ixl_update processing.
194*0Sstevel@tonic-gate */
195*0Sstevel@tonic-gate int
hci1394_ixl_find_next_exec_xfer(ixl1394_command_t * ixl_start,uint_t * callback_cnt,ixl1394_command_t ** next_exec_ixlpp)196*0Sstevel@tonic-gate hci1394_ixl_find_next_exec_xfer(ixl1394_command_t *ixl_start,
197*0Sstevel@tonic-gate uint_t *callback_cnt, ixl1394_command_t **next_exec_ixlpp)
198*0Sstevel@tonic-gate {
199*0Sstevel@tonic-gate uint16_t ixlopcode;
200*0Sstevel@tonic-gate boolean_t xferfound;
201*0Sstevel@tonic-gate ixl1394_command_t *ixlp;
202*0Sstevel@tonic-gate int ii;
203*0Sstevel@tonic-gate
204*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_find_next_exec_xfer_enter,
205*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
206*0Sstevel@tonic-gate
207*0Sstevel@tonic-gate ixlp = ixl_start;
208*0Sstevel@tonic-gate xferfound = B_FALSE;
209*0Sstevel@tonic-gate ii = HCI1394_IXL_MAX_SEQ_JUMPS;
210*0Sstevel@tonic-gate if (callback_cnt != NULL) {
211*0Sstevel@tonic-gate *callback_cnt = 0;
212*0Sstevel@tonic-gate }
213*0Sstevel@tonic-gate
214*0Sstevel@tonic-gate /* continue until xfer start ixl cmd or end of ixl list found */
215*0Sstevel@tonic-gate while ((xferfound == B_FALSE) && (ixlp != NULL) && (ii > 0)) {
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gate /* get current ixl cmd opcode without update flag */
218*0Sstevel@tonic-gate ixlopcode = ixlp->ixl_opcode & ~IXL1394_OPF_UPDATE;
219*0Sstevel@tonic-gate
220*0Sstevel@tonic-gate /* if found an xfer start ixl command, are done */
221*0Sstevel@tonic-gate if (((ixlopcode & IXL1394_OPF_ISXFER) != 0) &&
222*0Sstevel@tonic-gate ((ixlopcode & IXL1394_OPTY_MASK) != 0)) {
223*0Sstevel@tonic-gate xferfound = B_TRUE;
224*0Sstevel@tonic-gate continue;
225*0Sstevel@tonic-gate }
226*0Sstevel@tonic-gate
227*0Sstevel@tonic-gate /* if found jump command, adjust to follow its path */
228*0Sstevel@tonic-gate if (ixlopcode == IXL1394_OP_JUMP) {
229*0Sstevel@tonic-gate ixlp = (ixl1394_command_t *)
230*0Sstevel@tonic-gate ((ixl1394_jump_t *)ixlp)->label;
231*0Sstevel@tonic-gate ii--;
232*0Sstevel@tonic-gate
233*0Sstevel@tonic-gate /* if exceeded tolerance, give up */
234*0Sstevel@tonic-gate if (ii == 0) {
235*0Sstevel@tonic-gate TNF_PROBE_1(
236*0Sstevel@tonic-gate hci1394_ixl_find_next_exec_xfer_error,
237*0Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
238*0Sstevel@tonic-gate errmsg, "Infinite loop w/no xfers");
239*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(
240*0Sstevel@tonic-gate hci1394_ixl_find_next_exec_xfer_exit,
241*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
242*0Sstevel@tonic-gate return (DDI_FAILURE);
243*0Sstevel@tonic-gate }
244*0Sstevel@tonic-gate continue;
245*0Sstevel@tonic-gate }
246*0Sstevel@tonic-gate
247*0Sstevel@tonic-gate /* if current ixl command is a callback, count it */
248*0Sstevel@tonic-gate if ((ixlopcode == IXL1394_OP_CALLBACK) &&
249*0Sstevel@tonic-gate (callback_cnt != NULL)) {
250*0Sstevel@tonic-gate (*callback_cnt)++;
251*0Sstevel@tonic-gate }
252*0Sstevel@tonic-gate
253*0Sstevel@tonic-gate /* advance to next linked ixl command */
254*0Sstevel@tonic-gate ixlp = ixlp->next_ixlp;
255*0Sstevel@tonic-gate }
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gate /* return ixl xfer start command found, if any */
258*0Sstevel@tonic-gate *next_exec_ixlpp = ixlp;
259*0Sstevel@tonic-gate
260*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_find_next_exec_xfer_exit,
261*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
262*0Sstevel@tonic-gate return (DDI_SUCCESS);
263*0Sstevel@tonic-gate }
264*0Sstevel@tonic-gate #ifdef _KERNEL
265*0Sstevel@tonic-gate /*
266*0Sstevel@tonic-gate * hci1394_ixl_check_status()
267*0Sstevel@tonic-gate * Read the descriptor status and hdrs, clear as appropriate.
268*0Sstevel@tonic-gate */
269*0Sstevel@tonic-gate int32_t
hci1394_ixl_check_status(hci1394_xfer_ctl_dma_t * dma,uint16_t ixlopcode,uint16_t * timestamp,boolean_t do_status_reset)270*0Sstevel@tonic-gate hci1394_ixl_check_status(hci1394_xfer_ctl_dma_t *dma, uint16_t ixlopcode,
271*0Sstevel@tonic-gate uint16_t *timestamp, boolean_t do_status_reset)
272*0Sstevel@tonic-gate {
273*0Sstevel@tonic-gate uint16_t bufsiz;
274*0Sstevel@tonic-gate uint16_t hcicnt;
275*0Sstevel@tonic-gate uint16_t hcirecvcnt;
276*0Sstevel@tonic-gate hci1394_desc_t *hcidescp;
277*0Sstevel@tonic-gate off_t hcidesc_off;
278*0Sstevel@tonic-gate ddi_acc_handle_t acc_hdl;
279*0Sstevel@tonic-gate ddi_dma_handle_t dma_hdl;
280*0Sstevel@tonic-gate uint32_t desc_status;
281*0Sstevel@tonic-gate uint32_t desc_hdr;
282*0Sstevel@tonic-gate int err;
283*0Sstevel@tonic-gate
284*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_check_status_enter,
285*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
286*0Sstevel@tonic-gate
287*0Sstevel@tonic-gate /* last dma descriptor in descriptor block from dma structure */
288*0Sstevel@tonic-gate hcidescp = (hci1394_desc_t *)(dma->dma_descp);
289*0Sstevel@tonic-gate hcidesc_off = (off_t)hcidescp - (off_t)dma->dma_buf->bi_kaddr;
290*0Sstevel@tonic-gate acc_hdl = dma->dma_buf->bi_handle;
291*0Sstevel@tonic-gate dma_hdl = dma->dma_buf->bi_dma_handle;
292*0Sstevel@tonic-gate
293*0Sstevel@tonic-gate /* if current ixl command opcode is xmit */
294*0Sstevel@tonic-gate if ((ixlopcode & IXL1394_OPF_ONXMIT) != 0) {
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate /* Sync the descriptor before we get the status */
297*0Sstevel@tonic-gate err = ddi_dma_sync(dma_hdl, hcidesc_off,
298*0Sstevel@tonic-gate sizeof (hci1394_desc_t), DDI_DMA_SYNC_FORCPU);
299*0Sstevel@tonic-gate if (err != DDI_SUCCESS) {
300*0Sstevel@tonic-gate TNF_PROBE_1(hci1394_ixl_check_status_error,
301*0Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
302*0Sstevel@tonic-gate "dma_sync() failed");
303*0Sstevel@tonic-gate }
304*0Sstevel@tonic-gate desc_status = ddi_get32(acc_hdl, &hcidescp->status);
305*0Sstevel@tonic-gate
306*0Sstevel@tonic-gate /* check if status is set in last dma descriptor in block */
307*0Sstevel@tonic-gate if ((desc_status & DESC_XFER_ACTIVE_MASK) != 0) {
308*0Sstevel@tonic-gate /*
309*0Sstevel@tonic-gate * dma descriptor status set - I/O done.
310*0Sstevel@tonic-gate * if not to reset status, just return; else extract
311*0Sstevel@tonic-gate * timestamp, reset desc status and return dma
312*0Sstevel@tonic-gate * descriptor block status set
313*0Sstevel@tonic-gate */
314*0Sstevel@tonic-gate if (do_status_reset == B_FALSE) {
315*0Sstevel@tonic-gate return (1);
316*0Sstevel@tonic-gate }
317*0Sstevel@tonic-gate *timestamp = (uint16_t)
318*0Sstevel@tonic-gate ((desc_status & DESC_ST_TIMESTAMP_MASK) >>
319*0Sstevel@tonic-gate DESC_ST_TIMESTAMP_SHIFT);
320*0Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->status, 0);
321*0Sstevel@tonic-gate
322*0Sstevel@tonic-gate /* Sync descriptor for device (status was cleared) */
323*0Sstevel@tonic-gate err = ddi_dma_sync(dma_hdl, hcidesc_off,
324*0Sstevel@tonic-gate sizeof (hci1394_desc_t), DDI_DMA_SYNC_FORDEV);
325*0Sstevel@tonic-gate if (err != DDI_SUCCESS) {
326*0Sstevel@tonic-gate TNF_PROBE_1(hci1394_ixl_check_status_error,
327*0Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
328*0Sstevel@tonic-gate errmsg, "dma_sync() failed");
329*0Sstevel@tonic-gate }
330*0Sstevel@tonic-gate
331*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_check_status_exit,
332*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
333*0Sstevel@tonic-gate return (1);
334*0Sstevel@tonic-gate }
335*0Sstevel@tonic-gate /* else, return dma descriptor block status not set */
336*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_check_status_exit,
337*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
338*0Sstevel@tonic-gate return (0);
339*0Sstevel@tonic-gate }
340*0Sstevel@tonic-gate
341*0Sstevel@tonic-gate /* else current ixl opcode is recv */
342*0Sstevel@tonic-gate hcirecvcnt = 0;
343*0Sstevel@tonic-gate
344*0Sstevel@tonic-gate /* get count of descriptors in current dma descriptor block */
345*0Sstevel@tonic-gate hcicnt = dma->dma_bound & DESC_Z_MASK;
346*0Sstevel@tonic-gate hcidescp -= (hcicnt - 1);
347*0Sstevel@tonic-gate hcidesc_off = (off_t)hcidescp - (off_t)dma->dma_buf->bi_kaddr;
348*0Sstevel@tonic-gate
349*0Sstevel@tonic-gate /* iterate fwd through hci descriptors until end or find status set */
350*0Sstevel@tonic-gate while (hcicnt-- != 0) {
351*0Sstevel@tonic-gate
352*0Sstevel@tonic-gate /* Sync the descriptor before we get the status */
353*0Sstevel@tonic-gate err = ddi_dma_sync(dma_hdl, hcidesc_off,
354*0Sstevel@tonic-gate hcicnt * sizeof (hci1394_desc_t), DDI_DMA_SYNC_FORCPU);
355*0Sstevel@tonic-gate if (err != DDI_SUCCESS) {
356*0Sstevel@tonic-gate TNF_PROBE_1(hci1394_ixl_check_status_error,
357*0Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg,
358*0Sstevel@tonic-gate "dma_sync() failed");
359*0Sstevel@tonic-gate }
360*0Sstevel@tonic-gate
361*0Sstevel@tonic-gate desc_hdr = ddi_get32(acc_hdl, &hcidescp->hdr);
362*0Sstevel@tonic-gate
363*0Sstevel@tonic-gate /* get cur buffer size & accumulate potential buffr usage */
364*0Sstevel@tonic-gate bufsiz = (desc_hdr & DESC_HDR_REQCOUNT_MASK) >>
365*0Sstevel@tonic-gate DESC_HDR_REQCOUNT_SHIFT;
366*0Sstevel@tonic-gate hcirecvcnt += bufsiz;
367*0Sstevel@tonic-gate
368*0Sstevel@tonic-gate desc_status = ddi_get32(acc_hdl, &hcidescp->status);
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate /* check if status set on this descriptor block descriptor */
371*0Sstevel@tonic-gate if ((desc_status & DESC_XFER_ACTIVE_MASK) != 0) {
372*0Sstevel@tonic-gate /*
373*0Sstevel@tonic-gate * dma descriptor status set - I/O done.
374*0Sstevel@tonic-gate * if not to reset status, just return; else extract
375*0Sstevel@tonic-gate * buffer space used, reset desc status and return dma
376*0Sstevel@tonic-gate * descriptor block status set
377*0Sstevel@tonic-gate */
378*0Sstevel@tonic-gate if (do_status_reset == B_FALSE) {
379*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_check_status_exit,
380*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
381*0Sstevel@tonic-gate return (1);
382*0Sstevel@tonic-gate }
383*0Sstevel@tonic-gate
384*0Sstevel@tonic-gate hcirecvcnt -= (desc_status & DESC_ST_RESCOUNT_MASK) >>
385*0Sstevel@tonic-gate DESC_ST_RESCOUNT_SHIFT;
386*0Sstevel@tonic-gate *timestamp = hcirecvcnt;
387*0Sstevel@tonic-gate desc_status = (bufsiz << DESC_ST_RESCOUNT_SHIFT) &
388*0Sstevel@tonic-gate DESC_ST_RESCOUNT_MASK;
389*0Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->status, desc_status);
390*0Sstevel@tonic-gate
391*0Sstevel@tonic-gate /* Sync descriptor for device (status was cleared) */
392*0Sstevel@tonic-gate err = ddi_dma_sync(dma_hdl, hcidesc_off,
393*0Sstevel@tonic-gate sizeof (hci1394_desc_t), DDI_DMA_SYNC_FORDEV);
394*0Sstevel@tonic-gate if (err != DDI_SUCCESS) {
395*0Sstevel@tonic-gate TNF_PROBE_1(hci1394_ixl_check_status_error,
396*0Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string,
397*0Sstevel@tonic-gate errmsg, "dma_sync() failed");
398*0Sstevel@tonic-gate }
399*0Sstevel@tonic-gate
400*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_check_status_exit,
401*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
402*0Sstevel@tonic-gate return (1);
403*0Sstevel@tonic-gate } else {
404*0Sstevel@tonic-gate /* else, set to evaluate next descriptor. */
405*0Sstevel@tonic-gate hcidescp++;
406*0Sstevel@tonic-gate hcidesc_off = (off_t)hcidescp -
407*0Sstevel@tonic-gate (off_t)dma->dma_buf->bi_kaddr;
408*0Sstevel@tonic-gate }
409*0Sstevel@tonic-gate }
410*0Sstevel@tonic-gate
411*0Sstevel@tonic-gate /* return input not complete status */
412*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_check_status_exit,
413*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
414*0Sstevel@tonic-gate return (0);
415*0Sstevel@tonic-gate }
416*0Sstevel@tonic-gate #endif
417*0Sstevel@tonic-gate /*
418*0Sstevel@tonic-gate * hci1394_ixl_cleanup()
419*0Sstevel@tonic-gate * Delete all memory that has earlier been allocated for a context's IXL prog
420*0Sstevel@tonic-gate */
421*0Sstevel@tonic-gate void
hci1394_ixl_cleanup(hci1394_state_t * soft_statep,hci1394_iso_ctxt_t * ctxtp)422*0Sstevel@tonic-gate hci1394_ixl_cleanup(hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp)
423*0Sstevel@tonic-gate {
424*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_cleanup_enter,
425*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
426*0Sstevel@tonic-gate
427*0Sstevel@tonic-gate hci1394_delete_xfer_ctl((hci1394_xfer_ctl_t *)ctxtp->xcs_firstp);
428*0Sstevel@tonic-gate hci1394_delete_dma_desc_mem(soft_statep, ctxtp->dma_firstp);
429*0Sstevel@tonic-gate
430*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_ixl_cleanup_exit,
431*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
432*0Sstevel@tonic-gate }
433*0Sstevel@tonic-gate
434*0Sstevel@tonic-gate /*
435*0Sstevel@tonic-gate * hci1394_delete_dma_desc_mem()
436*0Sstevel@tonic-gate * Iterate through linked list of dma memory descriptors, deleting
437*0Sstevel@tonic-gate * allocated dma memory blocks, then deleting the dma memory
438*0Sstevel@tonic-gate * descriptor after advancing to next one
439*0Sstevel@tonic-gate */
440*0Sstevel@tonic-gate static void
441*0Sstevel@tonic-gate /* ARGSUSED */
hci1394_delete_dma_desc_mem(hci1394_state_t * soft_statep,hci1394_idma_desc_mem_t * dma_firstp)442*0Sstevel@tonic-gate hci1394_delete_dma_desc_mem(hci1394_state_t *soft_statep,
443*0Sstevel@tonic-gate hci1394_idma_desc_mem_t *dma_firstp)
444*0Sstevel@tonic-gate {
445*0Sstevel@tonic-gate hci1394_idma_desc_mem_t *dma_next;
446*0Sstevel@tonic-gate
447*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_delete_dma_desc_mem_enter,
448*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
449*0Sstevel@tonic-gate
450*0Sstevel@tonic-gate while (dma_firstp != NULL) {
451*0Sstevel@tonic-gate dma_next = dma_firstp->dma_nextp;
452*0Sstevel@tonic-gate #ifdef _KERNEL
453*0Sstevel@tonic-gate /*
454*0Sstevel@tonic-gate * if this dma descriptor memory block has the handles, then
455*0Sstevel@tonic-gate * free the memory. (Note that valid handles are kept only with
456*0Sstevel@tonic-gate * the most recently acquired cookie, and that each cookie is in
457*0Sstevel@tonic-gate * it's own idma_desc_mem_t struct.)
458*0Sstevel@tonic-gate */
459*0Sstevel@tonic-gate if (dma_firstp->mem_handle != NULL) {
460*0Sstevel@tonic-gate hci1394_buf_free(&dma_firstp->mem_handle);
461*0Sstevel@tonic-gate }
462*0Sstevel@tonic-gate
463*0Sstevel@tonic-gate /* free current dma memory descriptor */
464*0Sstevel@tonic-gate kmem_free(dma_firstp, sizeof (hci1394_idma_desc_mem_t));
465*0Sstevel@tonic-gate #else
466*0Sstevel@tonic-gate /* user mode free */
467*0Sstevel@tonic-gate /* free dma memory block and current dma mem descriptor */
468*0Sstevel@tonic-gate free(dma_firstp->mem.bi_kaddr);
469*0Sstevel@tonic-gate free(dma_firstp);
470*0Sstevel@tonic-gate #endif
471*0Sstevel@tonic-gate /* advance to next dma memory descriptor */
472*0Sstevel@tonic-gate dma_firstp = dma_next;
473*0Sstevel@tonic-gate }
474*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_delete_dma_desc_mem_exit,
475*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
476*0Sstevel@tonic-gate }
477*0Sstevel@tonic-gate
478*0Sstevel@tonic-gate /*
479*0Sstevel@tonic-gate * hci1394_delete_xfer_ctl()
480*0Sstevel@tonic-gate * Iterate thru linked list of xfer_ctl structs, deleting allocated memory.
481*0Sstevel@tonic-gate */
482*0Sstevel@tonic-gate void
hci1394_delete_xfer_ctl(hci1394_xfer_ctl_t * xcsp)483*0Sstevel@tonic-gate hci1394_delete_xfer_ctl(hci1394_xfer_ctl_t *xcsp)
484*0Sstevel@tonic-gate {
485*0Sstevel@tonic-gate hci1394_xfer_ctl_t *delp;
486*0Sstevel@tonic-gate
487*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_delete_xfer_ctl_enter,
488*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
489*0Sstevel@tonic-gate
490*0Sstevel@tonic-gate while ((delp = xcsp) != NULL) {
491*0Sstevel@tonic-gate /* advance ptr to next xfer_ctl struct */
492*0Sstevel@tonic-gate xcsp = xcsp->ctl_nextp;
493*0Sstevel@tonic-gate
494*0Sstevel@tonic-gate /*
495*0Sstevel@tonic-gate * delete current xfer_ctl struct and included
496*0Sstevel@tonic-gate * xfer_ctl_dma structs
497*0Sstevel@tonic-gate */
498*0Sstevel@tonic-gate #ifdef _KERNEL
499*0Sstevel@tonic-gate kmem_free(delp,
500*0Sstevel@tonic-gate sizeof (hci1394_xfer_ctl_t) +
501*0Sstevel@tonic-gate sizeof (hci1394_xfer_ctl_dma_t) * (delp->cnt - 1));
502*0Sstevel@tonic-gate #else
503*0Sstevel@tonic-gate free(delp);
504*0Sstevel@tonic-gate #endif
505*0Sstevel@tonic-gate }
506*0Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_delete_xfer_ctl_exit,
507*0Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "");
508*0Sstevel@tonic-gate }
509