xref: /illumos-gate/usr/src/uts/common/io/usb/hcd/ehci/ehci_isoch_util.c (revision 0a1044f1d1346ec799488913a15abfae3e3c848a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Copyright (c) 2016 by Delphix. All rights reserved.
25  */
26 
27 /*
28  * EHCI Host Controller Driver (EHCI)
29  *
30  * The EHCI driver is a software driver which interfaces to the Universal
31  * Serial Bus layer (USBA) and the Host Controller (HC). The interface to
32  * the Host Controller is defined by the EHCI Host Controller Interface.
33  *
34  * This module contains the EHCI driver isochronous code, which handles all
35  * Checking of status of USB transfers, error recovery and callbacks.
36  */
37 #include <sys/usb/hcd/ehci/ehcid.h>
38 #include <sys/usb/hcd/ehci/ehci_xfer.h>
39 #include <sys/usb/hcd/ehci/ehci_util.h>
40 
41 /* Adjustable variables for the size of isoc pools */
42 int ehci_itd_pool_size = EHCI_ITD_POOL_SIZE;
43 
44 /*
45  * pool functions
46  */
47 int ehci_allocate_isoc_pools(
48 	ehci_state_t		*ehcip);
49 int ehci_get_itd_pool_size();
50 
51 /*
52  * Isochronous Transfer Wrapper Functions
53  */
54 ehci_isoc_xwrapper_t *ehci_allocate_itw_resources(
55 	ehci_state_t		*ehcip,
56 	ehci_pipe_private_t	*pp,
57 	size_t			itw_length,
58 	usb_flags_t		usb_flags,
59 	size_t			pkt_count);
60 static ehci_isoc_xwrapper_t *ehci_allocate_itw(
61 	ehci_state_t		*ehcip,
62 	ehci_pipe_private_t	*pp,
63 	size_t			length,
64 	usb_flags_t		usb_flags);
65 void ehci_deallocate_itw(
66 	ehci_state_t		*ehcip,
67 	ehci_pipe_private_t	*pp,
68 	ehci_isoc_xwrapper_t	*itw);
69 static void ehci_free_itw_dma(
70 	ehci_state_t		*ehcip,
71 	ehci_pipe_private_t	*pp,
72 	ehci_isoc_xwrapper_t	*itw);
73 
74 /*
75  * transfer descriptor functions
76  */
77 static ehci_itd_t *ehci_allocate_itd(
78 	ehci_state_t		*ehcip);
79 void ehci_deallocate_itd(
80 	ehci_state_t		*ehcip,
81 	ehci_isoc_xwrapper_t	*itw,
82 	ehci_itd_t		*old_itd);
83 uint_t ehci_calc_num_itds(
84 	ehci_isoc_xwrapper_t	*itw,
85 	size_t			pkt_count);
86 int ehci_allocate_itds_for_itw(
87 	ehci_state_t		*ehcip,
88 	ehci_isoc_xwrapper_t	*itw,
89 	uint_t			itd_count);
90 static void ehci_deallocate_itds_for_itw(
91 	ehci_state_t		*ehcip,
92 	ehci_isoc_xwrapper_t	*itw);
93 void ehci_insert_itd_on_itw(
94 	ehci_state_t		*ehcip,
95 	ehci_isoc_xwrapper_t	*itw,
96 	ehci_itd_t		*itd);
97 void ehci_insert_itd_into_active_list(
98 	ehci_state_t		*ehcip,
99 	ehci_itd_t		*itd);
100 void ehci_remove_itd_from_active_list(
101 	ehci_state_t		*ehcip,
102 	ehci_itd_t		*itd);
103 ehci_itd_t *ehci_create_done_itd_list(
104 	ehci_state_t		*ehcip);
105 int ehci_insert_isoc_to_pfl(
106 	ehci_state_t		*ehcip,
107 	ehci_pipe_private_t	*pp,
108 	ehci_isoc_xwrapper_t	*itw);
109 void ehci_remove_isoc_from_pfl(
110 	ehci_state_t		*ehcip,
111 	ehci_itd_t		*curr_itd);
112 
113 
114 /*
115  * Isochronous in resource functions
116  */
117 int ehci_allocate_isoc_in_resource(
118 	ehci_state_t		*ehcip,
119 	ehci_pipe_private_t	*pp,
120 	ehci_isoc_xwrapper_t	*tw,
121 	usb_flags_t		flags);
122 void ehci_deallocate_isoc_in_resource(
123 	ehci_state_t		*ehcip,
124 	ehci_pipe_private_t	*pp,
125 	ehci_isoc_xwrapper_t	*itw);
126 
127 /*
128  * memory addr functions
129  */
130 uint32_t ehci_itd_cpu_to_iommu(
131 	ehci_state_t		*ehcip,
132 	ehci_itd_t		*addr);
133 ehci_itd_t *ehci_itd_iommu_to_cpu(
134 	ehci_state_t		*ehcip,
135 	uintptr_t		addr);
136 
137 /*
138  * Error parsing functions
139  */
140 void ehci_parse_isoc_error(
141 	ehci_state_t		*ehcip,
142 	ehci_isoc_xwrapper_t	*itw,
143 	ehci_itd_t		*itd);
144 static usb_cr_t ehci_parse_itd_error(
145 	ehci_state_t		*ehcip,
146 	ehci_isoc_xwrapper_t	*itw,
147 	ehci_itd_t		*itd);
148 static usb_cr_t ehci_parse_sitd_error(
149 	ehci_state_t		*ehcip,
150 	ehci_isoc_xwrapper_t	*itw,
151 	ehci_itd_t		*itd);
152 
153 /*
154  * print functions
155  */
156 void ehci_print_itd(
157 	ehci_state_t		*ehcip,
158 	ehci_itd_t		*itd);
159 void ehci_print_sitd(
160 	ehci_state_t		*ehcip,
161 	ehci_itd_t		*itd);
162 
163 
164 /*
165  * ehci_allocate_isoc_pools:
166  *
167  * Allocate the system memory for itd which are for low/full/high speed
168  * Transfer Descriptors. Must be aligned to a 32 byte boundary.
169  */
170 int
ehci_allocate_isoc_pools(ehci_state_t * ehcip)171 ehci_allocate_isoc_pools(ehci_state_t	*ehcip)
172 {
173 	ddi_device_acc_attr_t		dev_attr;
174 	size_t				real_length;
175 	int				result;
176 	uint_t				ccount;
177 	int				i;
178 
179 	USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
180 	    "ehci_allocate_isoc_pools:");
181 
182 	/* Byte alignment */
183 	ehcip->ehci_dma_attr.dma_attr_align = EHCI_DMA_ATTR_TD_QH_ALIGNMENT;
184 
185 	/* Allocate the itd pool DMA handle */
186 	result = ddi_dma_alloc_handle(ehcip->ehci_dip,
187 	    &ehcip->ehci_dma_attr,
188 	    DDI_DMA_SLEEP,
189 	    0,
190 	    &ehcip->ehci_itd_pool_dma_handle);
191 
192 	if (result != DDI_SUCCESS) {
193 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
194 		    "ehci_allocate_isoc_pools: Alloc handle failed");
195 
196 		return (DDI_FAILURE);
197 	}
198 
199 	/* The host controller will be little endian */
200 	dev_attr.devacc_attr_version		= DDI_DEVICE_ATTR_V0;
201 	dev_attr.devacc_attr_endian_flags	= DDI_STRUCTURE_LE_ACC;
202 	dev_attr.devacc_attr_dataorder		= DDI_STRICTORDER_ACC;
203 
204 	/* Allocate the memory */
205 	result = ddi_dma_mem_alloc(ehcip->ehci_itd_pool_dma_handle,
206 	    ehci_itd_pool_size * sizeof (ehci_itd_t),
207 	    &dev_attr,
208 	    DDI_DMA_CONSISTENT,
209 	    DDI_DMA_SLEEP,
210 	    0,
211 	    (caddr_t *)&ehcip->ehci_itd_pool_addr,
212 	    &real_length,
213 	    &ehcip->ehci_itd_pool_mem_handle);
214 
215 	if (result != DDI_SUCCESS) {
216 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
217 		    "ehci_allocate_isoc_pools: Alloc memory failed");
218 
219 		return (DDI_FAILURE);
220 	}
221 
222 	/* Map the ITD pool into the I/O address space */
223 	result = ddi_dma_addr_bind_handle(
224 	    ehcip->ehci_itd_pool_dma_handle,
225 	    NULL,
226 	    (caddr_t)ehcip->ehci_itd_pool_addr,
227 	    real_length,
228 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
229 	    DDI_DMA_SLEEP,
230 	    NULL,
231 	    &ehcip->ehci_itd_pool_cookie,
232 	    &ccount);
233 
234 	bzero((void *)ehcip->ehci_itd_pool_addr,
235 	    ehci_itd_pool_size * sizeof (ehci_itd_t));
236 
237 	/* Process the result */
238 	if (result == DDI_DMA_MAPPED) {
239 		/* The cookie count should be 1 */
240 		if (ccount != 1) {
241 			USB_DPRINTF_L2(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
242 			    "ehci_allocate_isoc_pools: More than 1 cookie");
243 
244 			return (DDI_FAILURE);
245 		}
246 	} else {
247 		USB_DPRINTF_L4(PRINT_MASK_ATTA, ehcip->ehci_log_hdl,
248 		    "ehci_allocate_isoc_pools: Result = %d", result);
249 
250 		ehci_decode_ddi_dma_addr_bind_handle_result(ehcip, result);
251 
252 		return (DDI_FAILURE);
253 	}
254 
255 	/*
256 	 * DMA addresses for ITD pools are bound
257 	 */
258 	ehcip->ehci_dma_addr_bind_flag |= EHCI_ITD_POOL_BOUND;
259 
260 	/* Initialize the ITD pool */
261 	for (i = 0; i < ehci_itd_pool_size; i++) {
262 		Set_ITD(ehcip->ehci_itd_pool_addr[i].itd_state,
263 		    EHCI_ITD_FREE);
264 	}
265 
266 	return (DDI_SUCCESS);
267 }
268 
269 
270 int
ehci_get_itd_pool_size()271 ehci_get_itd_pool_size()
272 {
273 	return (ehci_itd_pool_size);
274 }
275 
276 
277 /*
278  * Isochronous Transfer Wrapper Functions
279  */
280 /*
281  * ehci_allocate_itw_resources:
282  *
283  * Allocate an iTW and n iTD from the iTD buffer pool and places it into the
284  * ITW.  It does an all or nothing transaction.
285  *
286  * Calculates the number of iTD needed based on pipe speed.
287  * For LOW/FULL speed devices, 1 iTD is needed for each packet.
288  * For HIGH speed device, 1 iTD is needed for 8 to 24 packets, depending on
289  *     the multiplier for "HIGH BANDWIDTH" transfers look at 4.7 in EHCI spec.
290  *
291  * Returns NULL if there is insufficient resources otherwise ITW.
292  */
293 ehci_isoc_xwrapper_t *
ehci_allocate_itw_resources(ehci_state_t * ehcip,ehci_pipe_private_t * pp,size_t itw_length,usb_flags_t usb_flags,size_t pkt_count)294 ehci_allocate_itw_resources(
295 	ehci_state_t		*ehcip,
296 	ehci_pipe_private_t	*pp,
297 	size_t			itw_length,
298 	usb_flags_t		usb_flags,
299 	size_t			pkt_count)
300 {
301 	uint_t			itd_count;
302 	ehci_isoc_xwrapper_t	*itw;
303 
304 	itw = ehci_allocate_itw(ehcip, pp, itw_length, usb_flags);
305 
306 	if (itw == NULL) {
307 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
308 		    "ehci_allocate_itw_resources: Unable to allocate ITW");
309 	} else {
310 		itd_count = ehci_calc_num_itds(itw, pkt_count);
311 		USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
312 		    "ehci_allocate_itw_resources: itd_count = 0x%d", itd_count);
313 
314 		if (ehci_allocate_itds_for_itw(ehcip, itw, itd_count) ==
315 		    USB_SUCCESS) {
316 			itw->itw_num_itds = itd_count;
317 		} else {
318 			ehci_deallocate_itw(ehcip, pp, itw);
319 			itw = NULL;
320 		}
321 	}
322 
323 	return (itw);
324 }
325 
326 
327 /*
328  * ehci_allocate_itw:
329  *
330  * Creates a Isochronous Transfer Wrapper (itw) and populate it with this
331  * endpoint's data.  This involves the allocation of DMA resources.
332  *
333  * ITW Fields not set by this function:
334  * - will be populated itds are allocated
335  *   num_ids
336  *   itd_head
337  *   itd_tail
338  *   curr_xfer_reqp
339  *   curr_isoc_pktp
340  *   itw_itd_free_list
341  * - Should be set by the calling function
342  *   itw_handle_callback_value
343  */
344 static ehci_isoc_xwrapper_t *
ehci_allocate_itw(ehci_state_t * ehcip,ehci_pipe_private_t * pp,size_t length,usb_flags_t usb_flags)345 ehci_allocate_itw(
346 	ehci_state_t		*ehcip,
347 	ehci_pipe_private_t	*pp,
348 	size_t			length,
349 	usb_flags_t		usb_flags)
350 {
351 	ddi_device_acc_attr_t	dev_attr;
352 	int			result;
353 	size_t			real_length;
354 	uint_t			ccount;	/* Cookie count */
355 	usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
356 	usba_device_t		*usba_device = ph->p_usba_device;
357 	usb_ep_descr_t		*endpoint = &ph->p_ep;
358 	ehci_isoc_xwrapper_t	*itw;
359 
360 	USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
361 	    "ehci_allocate_itw: length = 0x%lx flags = 0x%x",
362 	    length, usb_flags);
363 
364 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
365 
366 	/* Allocate space for the transfer wrapper */
367 	itw = kmem_zalloc(sizeof (ehci_isoc_xwrapper_t), KM_NOSLEEP);
368 
369 	if (itw == NULL) {
370 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
371 		    "ehci_allocate_itw: kmem_zalloc failed");
372 
373 		return (NULL);
374 	}
375 
376 	ehcip->ehci_dma_attr.dma_attr_align = EHCI_DMA_ATTR_ALIGNMENT;
377 
378 	/* Allocate the DMA handle */
379 	result = ddi_dma_alloc_handle(ehcip->ehci_dip,
380 	    &ehcip->ehci_dma_attr,
381 	    DDI_DMA_DONTWAIT,
382 	    0,
383 	    &itw->itw_dmahandle);
384 
385 	if (result != DDI_SUCCESS) {
386 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
387 		    "ehci_create_transfer_wrapper: Alloc handle failed");
388 
389 		kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
390 
391 		return (NULL);
392 	}
393 
394 	/* no need for swapping the raw data in the buffers */
395 	dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
396 	dev_attr.devacc_attr_endian_flags  = DDI_NEVERSWAP_ACC;
397 	dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
398 
399 	/* Allocate the memory */
400 	result = ddi_dma_mem_alloc(itw->itw_dmahandle,
401 	    length,
402 	    &dev_attr,
403 	    DDI_DMA_CONSISTENT,
404 	    DDI_DMA_DONTWAIT,
405 	    NULL,
406 	    (caddr_t *)&itw->itw_buf,
407 	    &real_length,
408 	    &itw->itw_accesshandle);
409 
410 	if (result != DDI_SUCCESS) {
411 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
412 		    "ehci_create_transfer_wrapper: dma_mem_alloc fail");
413 
414 		ddi_dma_free_handle(&itw->itw_dmahandle);
415 		kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
416 
417 		return (NULL);
418 	}
419 
420 	ASSERT(real_length >= length);
421 
422 	/* Bind the handle */
423 	result = ddi_dma_addr_bind_handle(itw->itw_dmahandle,
424 	    NULL,
425 	    (caddr_t)itw->itw_buf,
426 	    real_length,
427 	    DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
428 	    DDI_DMA_DONTWAIT,
429 	    NULL,
430 	    &itw->itw_cookie,
431 	    &ccount);
432 
433 	if (result == DDI_DMA_MAPPED) {
434 		/* The cookie count should be 1 */
435 		if (ccount != 1) {
436 			USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
437 			    "ehci_create_transfer_wrapper: More than 1 cookie");
438 
439 			result = ddi_dma_unbind_handle(itw->itw_dmahandle);
440 			ASSERT(result == DDI_SUCCESS);
441 
442 			ddi_dma_mem_free(&itw->itw_accesshandle);
443 			ddi_dma_free_handle(&itw->itw_dmahandle);
444 			kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
445 
446 			return (NULL);
447 		}
448 	} else {
449 		ehci_decode_ddi_dma_addr_bind_handle_result(ehcip, result);
450 
451 		ddi_dma_mem_free(&itw->itw_accesshandle);
452 		ddi_dma_free_handle(&itw->itw_dmahandle);
453 		kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
454 
455 		return (NULL);
456 	}
457 
458 	/* Store a back pointer to the pipe private structure */
459 	itw->itw_pipe_private = pp;
460 	if (pp->pp_itw_head == NULL) {
461 		pp->pp_itw_head = itw;
462 		pp->pp_itw_tail = itw;
463 	} else {
464 		pp->pp_itw_tail->itw_next = itw;
465 		pp->pp_itw_tail = itw;
466 	}
467 
468 	/*
469 	 * Store transfer information
470 	 * itw_buf has been allocated and will be set later
471 	 */
472 	itw->itw_length = length;
473 	itw->itw_flags = usb_flags;
474 	itw->itw_port_status = usba_device->usb_port_status;
475 	itw->itw_direction = endpoint->bEndpointAddress & USB_EP_DIR_MASK;
476 
477 	/*
478 	 * Store the endpoint information that will be used by the
479 	 * transfer descriptors later.
480 	 */
481 	mutex_enter(&usba_device->usb_mutex);
482 	itw->itw_hub_addr = usba_device->usb_hs_hub_addr;
483 	itw->itw_hub_port = usba_device->usb_hs_hub_port;
484 	itw->itw_endpoint_num = endpoint->bEndpointAddress & USB_EP_NUM_MASK;
485 	itw->itw_device_addr = usba_device->usb_addr;
486 	mutex_exit(&usba_device->usb_mutex);
487 
488 	/* Get and Store 32bit ID */
489 	itw->itw_id = EHCI_GET_ID((void *)itw);
490 	ASSERT(itw->itw_id != 0);
491 
492 	USB_DPRINTF_L3(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
493 	    "ehci_create_itw: itw = 0x%p real_length = 0x%lx",
494 	    (void *)itw, real_length);
495 
496 	ehcip->ehci_periodic_req_count++;
497 	ehci_toggle_scheduler(ehcip);
498 
499 	return (itw);
500 }
501 
502 
503 /*
504  * ehci_deallocate_itw:
505  *
506  * Deallocate of a Isochronous Transaction Wrapper (TW) and this involves the
507  * freeing of DMA resources.
508  */
509 void
ehci_deallocate_itw(ehci_state_t * ehcip,ehci_pipe_private_t * pp,ehci_isoc_xwrapper_t * itw)510 ehci_deallocate_itw(
511 	ehci_state_t		*ehcip,
512 	ehci_pipe_private_t	*pp,
513 	ehci_isoc_xwrapper_t	*itw)
514 {
515 	ehci_isoc_xwrapper_t	*prev, *next;
516 
517 	USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
518 	    "ehci_deallocate_itw: itw = 0x%p", (void *)itw);
519 
520 	/*
521 	 * If the transfer wrapper has no Host Controller (HC)
522 	 * Transfer Descriptors (ITD) associated with it,  then
523 	 * remove the transfer wrapper.
524 	 */
525 	if (itw->itw_itd_head) {
526 		ASSERT(itw->itw_itd_tail != NULL);
527 
528 		return;
529 	}
530 
531 	ASSERT(itw->itw_itd_tail == NULL);
532 
533 	/* Make sure we return all the unused itd's to the pool as well */
534 	ehci_deallocate_itds_for_itw(ehcip, itw);
535 
536 	/*
537 	 * If pp->pp_tw_head and pp->pp_tw_tail are pointing to
538 	 * given TW then set the head and  tail  equal to NULL.
539 	 * Otherwise search for this TW in the linked TW's list
540 	 * and then remove this TW from the list.
541 	 */
542 	if (pp->pp_itw_head == itw) {
543 		if (pp->pp_itw_tail == itw) {
544 			pp->pp_itw_head = NULL;
545 			pp->pp_itw_tail = NULL;
546 		} else {
547 			pp->pp_itw_head = itw->itw_next;
548 		}
549 	} else {
550 		prev = pp->pp_itw_head;
551 		next = prev->itw_next;
552 
553 		while (next && (next != itw)) {
554 			prev = next;
555 			next = next->itw_next;
556 		}
557 
558 		if (next == itw) {
559 			prev->itw_next = next->itw_next;
560 
561 			if (pp->pp_itw_tail == itw) {
562 				pp->pp_itw_tail = prev;
563 			}
564 		}
565 	}
566 
567 	/* Free this iTWs dma resources */
568 	ehci_free_itw_dma(ehcip, pp, itw);
569 
570 	ehcip->ehci_periodic_req_count--;
571 	ehci_toggle_scheduler(ehcip);
572 }
573 
574 
575 /*
576  * ehci_free_itw_dma:
577  *
578  * Free the Isochronous Transfer Wrapper dma resources.
579  */
580 /*ARGSUSED*/
581 static void
ehci_free_itw_dma(ehci_state_t * ehcip,ehci_pipe_private_t * pp,ehci_isoc_xwrapper_t * itw)582 ehci_free_itw_dma(
583 	ehci_state_t		*ehcip,
584 	ehci_pipe_private_t	*pp,
585 	ehci_isoc_xwrapper_t	*itw)
586 {
587 	int	rval;
588 
589 	USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
590 	    "ehci_free_itw_dma: itw = 0x%p", (void *)itw);
591 
592 	ASSERT(itw != NULL);
593 	ASSERT(itw->itw_id != 0);
594 
595 	/* Free 32bit ID */
596 	EHCI_FREE_ID((uint32_t)itw->itw_id);
597 
598 	rval = ddi_dma_unbind_handle(itw->itw_dmahandle);
599 	ASSERT(rval == DDI_SUCCESS);
600 
601 	ddi_dma_mem_free(&itw->itw_accesshandle);
602 	ddi_dma_free_handle(&itw->itw_dmahandle);
603 
604 	/* Free transfer wrapper */
605 	kmem_free(itw, sizeof (ehci_isoc_xwrapper_t));
606 }
607 
608 
609 /*
610  * transfer descriptor functions
611  */
612 /*
613  * ehci_allocate_itd:
614  *
615  * Allocate a Transfer Descriptor (iTD) from the iTD buffer pool.
616  */
617 static ehci_itd_t *
ehci_allocate_itd(ehci_state_t * ehcip)618 ehci_allocate_itd(ehci_state_t	*ehcip)
619 {
620 	int		i, state;
621 	ehci_itd_t	*itd;
622 
623 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
624 
625 	/*
626 	 * Search for a blank Transfer Descriptor (iTD)
627 	 * in the iTD buffer pool.
628 	 */
629 	for (i = 0; i < ehci_itd_pool_size; i ++) {
630 		state = Get_ITD(ehcip->ehci_itd_pool_addr[i].itd_state);
631 		if (state == EHCI_ITD_FREE) {
632 			break;
633 		}
634 	}
635 
636 	if (i >= ehci_itd_pool_size) {
637 		USB_DPRINTF_L2(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
638 		    "ehci_allocate_itd: ITD exhausted");
639 
640 		return (NULL);
641 	}
642 
643 	USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
644 	    "ehci_allocate_itd: Allocated %d", i);
645 
646 	/* Create a new dummy for the end of the ITD list */
647 	itd = &ehcip->ehci_itd_pool_addr[i];
648 
649 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
650 	    "ehci_allocate_itd: itd 0x%p", (void *)itd);
651 
652 	/* Mark the newly allocated ITD as a empty */
653 	Set_ITD(itd->itd_state, EHCI_ITD_DUMMY);
654 
655 	return (itd);
656 }
657 
658 
659 /*
660  * ehci_deallocate_itd:
661  *
662  * Deallocate a Host Controller's (HC) Transfer Descriptor (ITD).
663  *
664  */
665 void
ehci_deallocate_itd(ehci_state_t * ehcip,ehci_isoc_xwrapper_t * itw,ehci_itd_t * old_itd)666 ehci_deallocate_itd(
667 	ehci_state_t		*ehcip,
668 	ehci_isoc_xwrapper_t	*itw,
669 	ehci_itd_t		*old_itd)
670 {
671 	ehci_itd_t	*itd, *next_itd;
672 
673 	USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
674 	    "ehci_deallocate_itd: old_itd = 0x%p", (void *)old_itd);
675 
676 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
677 
678 	/* If it has been marked RECLAIM it has already been removed */
679 	if (Get_ITD(old_itd->itd_state) != EHCI_ITD_RECLAIM) {
680 		ehci_remove_isoc_from_pfl(ehcip, old_itd);
681 	}
682 
683 	/* Make sure the ITD is not in the PFL */
684 	ASSERT(Get_ITD_FRAME(old_itd->itd_frame_number) == 0);
685 
686 	/* Remove the itd from the itw */
687 	itd = itw->itw_itd_head;
688 	if (old_itd != itd) {
689 		next_itd = ehci_itd_iommu_to_cpu(ehcip,
690 		    Get_ITD(itd->itd_itw_next_itd));
691 
692 		while (next_itd != old_itd) {
693 			itd = next_itd;
694 			next_itd = ehci_itd_iommu_to_cpu(ehcip,
695 			    Get_ITD(itd->itd_itw_next_itd));
696 		}
697 
698 		Set_ITD(itd->itd_itw_next_itd, old_itd->itd_itw_next_itd);
699 
700 		if (itd->itd_itw_next_itd == 0) {
701 			itw->itw_itd_tail = itd;
702 		}
703 	} else {
704 		itw->itw_itd_head = ehci_itd_iommu_to_cpu(
705 		    ehcip, Get_ITD(old_itd->itd_itw_next_itd));
706 
707 		if (itw->itw_itd_head == NULL) {
708 			itw->itw_itd_tail = NULL;
709 		}
710 	}
711 
712 	bzero((char *)old_itd, sizeof (ehci_itd_t));
713 	Set_ITD(old_itd->itd_state, EHCI_ITD_FREE);
714 
715 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
716 	    "Dealloc_itd: itd 0x%p", (void *)old_itd);
717 }
718 
719 
720 /*
721  * ehci_calc_num_itds:
722  *
723  * Calculates how many ITDs are needed for this request.
724  * The calculation is based on weather it is an HIGH speed
725  * transaction of a FULL/LOW transaction.
726  *
727  * For FULL/LOW transaction more itds are necessary if it
728  * spans frames.
729  */
730 uint_t
ehci_calc_num_itds(ehci_isoc_xwrapper_t * itw,size_t pkt_count)731 ehci_calc_num_itds(
732 	ehci_isoc_xwrapper_t	*itw,
733 	size_t			pkt_count)
734 {
735 	uint_t			multiplier, itd_count;
736 
737 	/* Allocate the appropriate isoc resources */
738 	if (itw->itw_port_status == USBA_HIGH_SPEED_DEV) {
739 		/* Multiplier needs to be passed in somehow */
740 		multiplier = 1 * 8;
741 		itd_count = pkt_count / multiplier;
742 		if (pkt_count % multiplier) {
743 			itd_count++;
744 		}
745 	} else {
746 		itd_count = (uint_t)pkt_count;
747 	}
748 
749 	return (itd_count);
750 }
751 
752 /*
753  * ehci_allocate_itds_for_itw:
754  *
755  * Allocate n Transfer Descriptors (TD) from the TD buffer pool and places it
756  * into the TW.
757  *
758  * Returns USB_NO_RESOURCES if it was not able to allocate all the requested TD
759  * otherwise USB_SUCCESS.
760  */
761 int
ehci_allocate_itds_for_itw(ehci_state_t * ehcip,ehci_isoc_xwrapper_t * itw,uint_t itd_count)762 ehci_allocate_itds_for_itw(
763 	ehci_state_t		*ehcip,
764 	ehci_isoc_xwrapper_t	*itw,
765 	uint_t			itd_count)
766 {
767 	ehci_itd_t		*itd;
768 	uint32_t		itd_addr;
769 	int			i;
770 	int			error = USB_SUCCESS;
771 
772 	for (i = 0; i < itd_count; i += 1) {
773 		itd = ehci_allocate_itd(ehcip);
774 		if (itd == NULL) {
775 			error = USB_NO_RESOURCES;
776 			USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
777 			    "ehci_allocate_itds_for_itw: "
778 			    "Unable to allocate %d ITDs",
779 			    itd_count);
780 			break;
781 		}
782 		if (i > 0) {
783 			itd_addr = ehci_itd_cpu_to_iommu(ehcip,
784 			    itw->itw_itd_free_list);
785 			Set_ITD(itd->itd_link_ptr, itd_addr);
786 		}
787 		Set_ITD_INDEX(itd, 0, EHCI_ITD_UNUSED_INDEX);
788 		Set_ITD_INDEX(itd, 1, EHCI_ITD_UNUSED_INDEX);
789 		Set_ITD_INDEX(itd, 2, EHCI_ITD_UNUSED_INDEX);
790 		Set_ITD_INDEX(itd, 3, EHCI_ITD_UNUSED_INDEX);
791 		Set_ITD_INDEX(itd, 4, EHCI_ITD_UNUSED_INDEX);
792 		Set_ITD_INDEX(itd, 5, EHCI_ITD_UNUSED_INDEX);
793 		Set_ITD_INDEX(itd, 6, EHCI_ITD_UNUSED_INDEX);
794 		Set_ITD_INDEX(itd, 7, EHCI_ITD_UNUSED_INDEX);
795 		itw->itw_itd_free_list = itd;
796 	}
797 
798 	return (error);
799 }
800 
801 
802 /*
803  * ehci_deallocate_itds_for_itw:
804  *
805  * Free all allocated resources for Transaction Wrapper (TW).
806  * Does not free the iTW itself.
807  */
808 static void
ehci_deallocate_itds_for_itw(ehci_state_t * ehcip,ehci_isoc_xwrapper_t * itw)809 ehci_deallocate_itds_for_itw(
810 	ehci_state_t		*ehcip,
811 	ehci_isoc_xwrapper_t	*itw)
812 {
813 	ehci_itd_t		*itd = NULL;
814 	ehci_itd_t		*temp_itd = NULL;
815 
816 	USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
817 	    "ehci_free_itw_itd_resources: itw = 0x%p", (void *)itw);
818 
819 	itd = itw->itw_itd_free_list;
820 	while (itd != NULL) {
821 		/* Save the pointer to the next itd before destroying it */
822 		temp_itd = ehci_itd_iommu_to_cpu(ehcip,
823 		    Get_ITD(itd->itd_link_ptr));
824 		ehci_deallocate_itd(ehcip, itw, itd);
825 		itd = temp_itd;
826 	}
827 	itw->itw_itd_free_list = NULL;
828 }
829 
830 
831 /*
832  * ehci_insert_itd_on_itw:
833  *
834  * The transfer wrapper keeps a list of all Transfer Descriptors (iTD) that
835  * are allocated for this transfer. Insert a iTD onto this list.
836  */
ehci_insert_itd_on_itw(ehci_state_t * ehcip,ehci_isoc_xwrapper_t * itw,ehci_itd_t * itd)837 void ehci_insert_itd_on_itw(
838 	ehci_state_t		*ehcip,
839 	ehci_isoc_xwrapper_t	*itw,
840 	ehci_itd_t		*itd)
841 {
842 	/*
843 	 * Set the next pointer to NULL because
844 	 * this is the last ITD on list.
845 	 */
846 	Set_ITD(itd->itd_itw_next_itd, 0);
847 
848 	if (itw->itw_itd_head == NULL) {
849 		ASSERT(itw->itw_itd_tail == NULL);
850 		itw->itw_itd_head = itd;
851 		itw->itw_itd_tail = itd;
852 	} else {
853 		ehci_itd_t *dummy = (ehci_itd_t *)itw->itw_itd_tail;
854 
855 		ASSERT(dummy != NULL);
856 		ASSERT(Get_ITD(itd->itd_state) == EHCI_ITD_ACTIVE);
857 
858 		/* Add the itd to the end of the list */
859 		Set_ITD(dummy->itd_itw_next_itd,
860 		    ehci_itd_cpu_to_iommu(ehcip, itd));
861 
862 		itw->itw_itd_tail = itd;
863 	}
864 
865 	Set_ITD(itd->itd_trans_wrapper, (uint32_t)itw->itw_id);
866 }
867 
868 
869 /*
870  * ehci_insert_itd_into_active_list:
871  *
872  * Add current ITD into the active ITD list in reverse order.
873  * When the done list is created, remove it in the reverse order.
874  */
875 void
ehci_insert_itd_into_active_list(ehci_state_t * ehcip,ehci_itd_t * itd)876 ehci_insert_itd_into_active_list(
877 	ehci_state_t		*ehcip,
878 	ehci_itd_t		*itd)
879 {
880 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
881 	ASSERT(itd != NULL);
882 
883 	Set_ITD(itd->itd_next_active_itd,
884 	    ehci_itd_cpu_to_iommu(ehcip, ehcip->ehci_active_itd_list));
885 	ehcip->ehci_active_itd_list = itd;
886 }
887 
888 
889 /*
890  * ehci_remove_itd_from_active_list:
891  *
892  * Remove current ITD from the active ITD list.
893  */
894 void
ehci_remove_itd_from_active_list(ehci_state_t * ehcip,ehci_itd_t * itd)895 ehci_remove_itd_from_active_list(
896 	ehci_state_t		*ehcip,
897 	ehci_itd_t		*itd)
898 {
899 	ehci_itd_t		*curr_itd, *next_itd;
900 
901 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
902 	ASSERT(itd != NULL);
903 
904 	USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
905 	    "ehci_remove_itd_from_active_list: "
906 	    "ehci_active_itd_list = 0x%p itd = 0x%p",
907 	    (void *)ehcip->ehci_active_itd_list, (void *)itd);
908 
909 	curr_itd = ehcip->ehci_active_itd_list;
910 
911 	if (curr_itd == itd) {
912 		ehcip->ehci_active_itd_list =
913 		    ehci_itd_iommu_to_cpu(ehcip, itd->itd_next_active_itd);
914 		itd->itd_next_active_itd = 0;
915 
916 		return;
917 	}
918 
919 	next_itd = ehci_itd_iommu_to_cpu(ehcip, curr_itd->itd_next_active_itd);
920 	while (next_itd != itd) {
921 		curr_itd = next_itd;
922 		if (curr_itd) {
923 			next_itd = ehci_itd_iommu_to_cpu(ehcip,
924 			    curr_itd->itd_next_active_itd);
925 		} else {
926 			break;
927 		}
928 	}
929 
930 	if ((curr_itd) && (next_itd == itd)) {
931 		Set_ITD(curr_itd->itd_next_active_itd,
932 		    Get_ITD(itd->itd_next_active_itd));
933 		Set_ITD(itd->itd_next_active_itd, 0);
934 	} else {
935 		USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
936 		    "ehci_remove_itd_from_active_list: "
937 		    "Unable to find ITD in active_itd_list");
938 	}
939 }
940 
941 
942 /*
943  * ehci_create_done_itd_list:
944  *
945  * Traverse the active list and create a done list and remove them
946  * from the active list.
947  */
948 ehci_itd_t *
ehci_create_done_itd_list(ehci_state_t * ehcip)949 ehci_create_done_itd_list(
950 	ehci_state_t		*ehcip)
951 {
952 	usb_frame_number_t	current_frame_number;
953 	usb_frame_number_t	itd_frame_number, itd_reclaim_number;
954 	ehci_itd_t		*curr_itd = NULL, *next_itd = NULL;
955 	ehci_itd_t		*done_itd_list = NULL;
956 	uint_t			state;
957 
958 	USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
959 	    "ehci_create_done_itd_list:");
960 
961 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
962 
963 	/*
964 	 * Get the current frame number.
965 	 * Only process itd that were inserted before the current
966 	 * frame number.
967 	 */
968 	current_frame_number = ehci_get_current_frame_number(ehcip);
969 
970 	curr_itd = ehcip->ehci_active_itd_list;
971 
972 	while (curr_itd) {
973 		/* Get next itd from the active itd list */
974 		next_itd = ehci_itd_iommu_to_cpu(ehcip,
975 		    Get_ITD(curr_itd->itd_next_active_itd));
976 
977 		/*
978 		 * If haven't past the frame number that the ITD was
979 		 * suppose to be executed, don't touch it.  Just in
980 		 * case it is being processed by the HCD and cause
981 		 * a race condition.
982 		 */
983 		itd_frame_number = Get_ITD_FRAME(curr_itd->itd_frame_number);
984 		itd_reclaim_number =
985 		    Get_ITD_FRAME(curr_itd->itd_reclaim_number);
986 
987 		/* Get the ITD state */
988 		state = Get_ITD(curr_itd->itd_state);
989 
990 		if (((state == EHCI_ITD_ACTIVE) &&
991 		    (itd_frame_number < current_frame_number)) ||
992 		    ((state == EHCI_ITD_RECLAIM) &&
993 		    (itd_reclaim_number < current_frame_number))) {
994 
995 			/* Remove this ITD from active ITD list */
996 			ehci_remove_itd_from_active_list(ehcip, curr_itd);
997 
998 			/*
999 			 * Create the done list in reverse order, since the
1000 			 * active list was also created in reverse order.
1001 			 */
1002 			Set_ITD(curr_itd->itd_next_active_itd,
1003 			    ehci_itd_cpu_to_iommu(ehcip, done_itd_list));
1004 			done_itd_list = curr_itd;
1005 		}
1006 
1007 		curr_itd = next_itd;
1008 	}
1009 
1010 	return (done_itd_list);
1011 }
1012 
1013 
1014 /*
1015  * ehci_insert_isoc_to_pfl:
1016  *
1017  * Insert a ITD request into the Host Controller's isochronous list.
1018  * All the ITDs in the ITW will be added the PFL at once.  Either all
1019  * of them will make it or none of them will.
1020  */
1021 int
ehci_insert_isoc_to_pfl(ehci_state_t * ehcip,ehci_pipe_private_t * pp,ehci_isoc_xwrapper_t * itw)1022 ehci_insert_isoc_to_pfl(
1023 	ehci_state_t		*ehcip,
1024 	ehci_pipe_private_t	*pp,
1025 	ehci_isoc_xwrapper_t	*itw)
1026 {
1027 	usb_isoc_req_t		*isoc_reqp = itw->itw_curr_xfer_reqp;
1028 	usb_frame_number_t	current_frame_number, start_frame_number;
1029 	uint_t			ddic, pfl_number;
1030 	ehci_periodic_frame_list_t *periodic_frame_list =
1031 	    ehcip->ehci_periodic_frame_list_tablep;
1032 	uint32_t		addr, port_status;
1033 	ehci_itd_t		*itd;
1034 
1035 	USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1036 	    "ehci_insert_isoc_to_pfl: "
1037 	    "isoc flags 0x%x itw = 0x%p",
1038 	    isoc_reqp->isoc_attributes, (void *)itw);
1039 
1040 	/*
1041 	 * Enter critical, while programming the usb frame number
1042 	 * and inserting current isochronous TD into the ED's list.
1043 	 */
1044 	ddic = ddi_enter_critical();
1045 
1046 	/* Get the current frame number */
1047 	current_frame_number = ehci_get_current_frame_number(ehcip);
1048 
1049 	/*
1050 	 * Check the given isochronous flags and get the frame number
1051 	 * to insert the itd into.
1052 	 */
1053 	switch (isoc_reqp->isoc_attributes &
1054 	    (USB_ATTRS_ISOC_START_FRAME | USB_ATTRS_ISOC_XFER_ASAP)) {
1055 	case USB_ATTRS_ISOC_START_FRAME:
1056 
1057 		/* Starting frame number is specified */
1058 		if (pp->pp_flag & EHCI_ISOC_XFER_CONTINUE) {
1059 			/* Get the starting usb frame number */
1060 			start_frame_number = pp->pp_next_frame_number;
1061 		} else {
1062 			/* Check for the Starting usb frame number */
1063 			if ((isoc_reqp->isoc_frame_no == 0) ||
1064 			    ((isoc_reqp->isoc_frame_no +
1065 			    isoc_reqp->isoc_pkts_count) <
1066 			    current_frame_number)) {
1067 
1068 				/* Exit the critical */
1069 				ddi_exit_critical(ddic);
1070 
1071 				USB_DPRINTF_L2(PRINT_MASK_LISTS,
1072 				    ehcip->ehci_log_hdl,
1073 				    "ehci_insert_isoc_to_pfl:"
1074 				    "Invalid starting frame number");
1075 
1076 				return (USB_INVALID_START_FRAME);
1077 			}
1078 
1079 			/* Get the starting usb frame number */
1080 			start_frame_number = isoc_reqp->isoc_frame_no;
1081 
1082 			pp->pp_next_frame_number = 0;
1083 		}
1084 		break;
1085 	case USB_ATTRS_ISOC_XFER_ASAP:
1086 		/* ehci has to specify starting frame number */
1087 		if ((pp->pp_next_frame_number) &&
1088 		    (pp->pp_next_frame_number > current_frame_number)) {
1089 			/*
1090 			 * Get the next usb frame number.
1091 			 */
1092 			start_frame_number = pp->pp_next_frame_number;
1093 		} else {
1094 			/*
1095 			 * Add appropriate offset to the current usb
1096 			 * frame number and use it as a starting frame
1097 			 * number.
1098 			 */
1099 			start_frame_number =
1100 			    current_frame_number + EHCI_FRAME_OFFSET;
1101 		}
1102 
1103 		if (!(pp->pp_flag & EHCI_ISOC_XFER_CONTINUE)) {
1104 			isoc_reqp->isoc_frame_no = start_frame_number;
1105 		}
1106 		break;
1107 	default:
1108 		/* Exit the critical */
1109 		ddi_exit_critical(ddic);
1110 
1111 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1112 		    "ehci_insert_isoc_to_pfl: Either starting "
1113 		    "frame number or ASAP flags are not set, attrs = 0x%x",
1114 		    isoc_reqp->isoc_attributes);
1115 
1116 		return (USB_NO_FRAME_NUMBER);
1117 	}
1118 
1119 	if (itw->itw_port_status == USBA_HIGH_SPEED_DEV) {
1120 		port_status = EHCI_ITD_LINK_REF_ITD;
1121 	} else {
1122 		port_status = EHCI_ITD_LINK_REF_SITD;
1123 	}
1124 
1125 	itd = itw->itw_itd_head;
1126 	while (itd) {
1127 		/* Find the appropriate frame list to put the itd into */
1128 		pfl_number = start_frame_number % EHCI_NUM_PERIODIC_FRAME_LISTS;
1129 
1130 		addr = Get_PFLT(periodic_frame_list->
1131 		    ehci_periodic_frame_list_table[pfl_number]);
1132 		Set_ITD(itd->itd_link_ptr, addr);
1133 
1134 		/* Set the link_ref correctly as ITD or SITD. */
1135 		addr = ehci_itd_cpu_to_iommu(ehcip, itd) & EHCI_ITD_LINK_PTR;
1136 		addr |= port_status;
1137 
1138 		Set_PFLT(periodic_frame_list->
1139 		    ehci_periodic_frame_list_table[pfl_number], addr);
1140 
1141 		/* Save which frame the ITD was inserted into */
1142 		Set_ITD_FRAME(itd->itd_frame_number, start_frame_number);
1143 
1144 		ehci_insert_itd_into_active_list(ehcip, itd);
1145 
1146 		/* Get the next ITD in the ITW */
1147 		itd = ehci_itd_iommu_to_cpu(ehcip,
1148 		    Get_ITD(itd->itd_itw_next_itd));
1149 
1150 		start_frame_number++;
1151 	}
1152 
1153 	/* Exit the critical */
1154 	ddi_exit_critical(ddic);
1155 
1156 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1157 	    "ehci_insert_isoc_to_pfl: "
1158 	    "current frame number 0x%llx start frame number 0x%llx num itds %d",
1159 	    (unsigned long long)current_frame_number,
1160 	    (unsigned long long)start_frame_number, itw->itw_num_itds);
1161 
1162 	/*
1163 	 * Increment this saved frame number by current number
1164 	 * of data packets needs to be transfer.
1165 	 */
1166 	pp->pp_next_frame_number = start_frame_number;
1167 
1168 	/*
1169 	 * Set EHCI_ISOC_XFER_CONTINUE flag in order to send other
1170 	 * isochronous packets,  part of the current isoch request
1171 	 * in the subsequent frames.
1172 	 */
1173 	pp->pp_flag |= EHCI_ISOC_XFER_CONTINUE;
1174 
1175 	return (USB_SUCCESS);
1176 }
1177 
1178 
1179 /*
1180  * ehci_remove_isoc_to_pfl:
1181  *
1182  * Remove an ITD request from the Host Controller's isochronous list.
1183  * If we can't find it, something has gone wrong.
1184  */
1185 void
ehci_remove_isoc_from_pfl(ehci_state_t * ehcip,ehci_itd_t * curr_itd)1186 ehci_remove_isoc_from_pfl(
1187 	ehci_state_t		*ehcip,
1188 	ehci_itd_t		*curr_itd)
1189 {
1190 	ehci_periodic_frame_list_t *periodic_frame_list;
1191 	uint_t		pfl_number;
1192 	uint32_t	next_addr, curr_itd_addr;
1193 	uint32_t	link_ref;
1194 	ehci_itd_t	*prev_itd = NULL;
1195 
1196 	USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
1197 	    "ehci_remove_isoc_from_pfl:");
1198 
1199 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
1200 
1201 	/* Get the address of the current itd */
1202 	curr_itd_addr = ehci_itd_cpu_to_iommu(ehcip, curr_itd);
1203 
1204 	/*
1205 	 * Remove this ITD from the PFL
1206 	 * But first we need to find it in the PFL
1207 	 */
1208 	periodic_frame_list = ehcip->ehci_periodic_frame_list_tablep;
1209 	pfl_number = Get_ITD_FRAME(curr_itd->itd_frame_number) %
1210 	    EHCI_NUM_PERIODIC_FRAME_LISTS;
1211 
1212 	USB_DPRINTF_L4(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
1213 	    "ehci_remove_isoc_from_pfl: itd = 0x%p pfl number 0x%x",
1214 	    (void *)curr_itd, pfl_number);
1215 
1216 	next_addr = Get_PFLT(periodic_frame_list->
1217 	    ehci_periodic_frame_list_table[pfl_number]);
1218 	while ((next_addr & EHCI_ITD_LINK_PTR) !=
1219 	    (curr_itd_addr & EHCI_ITD_LINK_PTR)) {
1220 
1221 		link_ref = next_addr & EHCI_ITD_LINK_REF;
1222 
1223 		if ((link_ref == EHCI_ITD_LINK_REF_ITD) ||
1224 		    (link_ref == EHCI_ITD_LINK_REF_SITD)) {
1225 
1226 			prev_itd = ehci_itd_iommu_to_cpu(ehcip,
1227 			    (next_addr & EHCI_ITD_LINK_PTR));
1228 			next_addr = Get_ITD(prev_itd->itd_link_ptr);
1229 		} else {
1230 
1231 			break;
1232 		}
1233 	}
1234 
1235 	/*
1236 	 * If the next itd is the current itd, that means we found it.
1237 	 * Set the previous's ITD link ptr to the Curr_ITD's link ptr.
1238 	 * But do not touch the Curr_ITD's link ptr.
1239 	 */
1240 	if ((next_addr & EHCI_ITD_LINK_PTR) ==
1241 	    (curr_itd_addr & EHCI_ITD_LINK_PTR)) {
1242 
1243 		next_addr = Get_ITD(curr_itd->itd_link_ptr);
1244 
1245 		if (prev_itd == NULL) {
1246 			/* This means PFL points to this ITD */
1247 			Set_PFLT(periodic_frame_list->
1248 			    ehci_periodic_frame_list_table[pfl_number],
1249 			    next_addr);
1250 		} else {
1251 			/* Set the previous ITD's itd_link_ptr */
1252 			Set_ITD(prev_itd->itd_link_ptr, next_addr);
1253 		}
1254 
1255 		Set_ITD_FRAME(curr_itd->itd_frame_number, 0);
1256 	} else {
1257 		ASSERT((next_addr & EHCI_ITD_LINK_PTR) ==
1258 		    (curr_itd_addr & EHCI_ITD_LINK_PTR));
1259 		USB_DPRINTF_L3(PRINT_MASK_ALLOC, ehcip->ehci_log_hdl,
1260 		    "ehci_remove_isoc_from_pfl: Unable to find ITD in PFL");
1261 	}
1262 }
1263 
1264 
1265 /*
1266  * Isochronous in resource functions
1267  */
1268 /*
1269  * ehci_allocate_periodic_in_resource
1270  *
1271  * Allocate interrupt request structure for the interrupt IN transfer.
1272  */
1273 int
ehci_allocate_isoc_in_resource(ehci_state_t * ehcip,ehci_pipe_private_t * pp,ehci_isoc_xwrapper_t * itw,usb_flags_t flags)1274 ehci_allocate_isoc_in_resource(
1275 	ehci_state_t		*ehcip,
1276 	ehci_pipe_private_t	*pp,
1277 	ehci_isoc_xwrapper_t	*itw,
1278 	usb_flags_t		flags)
1279 {
1280 	usba_pipe_handle_data_t	*ph = pp->pp_pipe_handle;
1281 	usb_isoc_req_t		*orig_isoc_reqp, *clone_isoc_reqp;
1282 
1283 	USB_DPRINTF_L4(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1284 	    "ehci_allocate_isoc_in_resource:"
1285 	    "pp = 0x%p itw = 0x%p flags = 0x%x", (void *)pp, (void *)itw,
1286 	    flags);
1287 
1288 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
1289 	ASSERT(itw->itw_curr_xfer_reqp == NULL);
1290 
1291 	/* Get the client periodic in request pointer */
1292 	orig_isoc_reqp = (usb_isoc_req_t *)(pp->pp_client_periodic_in_reqp);
1293 
1294 	ASSERT(orig_isoc_reqp != NULL);
1295 
1296 	clone_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip,
1297 	    orig_isoc_reqp, flags);
1298 
1299 	if (clone_isoc_reqp == NULL) {
1300 		USB_DPRINTF_L2(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1301 		    "ehci_allocate_isoc_in_resource: Isochronous"
1302 		    "request structure allocation failed");
1303 
1304 		return (USB_NO_RESOURCES);
1305 	}
1306 
1307 	/*
1308 	 * Save the client's isochronous request pointer and
1309 	 * length of isochronous transfer in transfer wrapper.
1310 	 * The dup'ed request is saved in pp_client_periodic_in_reqp
1311 	 */
1312 	itw->itw_curr_xfer_reqp = orig_isoc_reqp;
1313 
1314 	pp->pp_client_periodic_in_reqp = (usb_opaque_t)clone_isoc_reqp;
1315 
1316 	mutex_enter(&ph->p_mutex);
1317 	ph->p_req_count++;
1318 	mutex_exit(&ph->p_mutex);
1319 
1320 	pp->pp_state = EHCI_PIPE_STATE_ACTIVE;
1321 
1322 	return (USB_SUCCESS);
1323 }
1324 
1325 
1326 /*
1327  * ehci_deallocate_isoc_in_resource
1328  *
1329  * Deallocate interrupt request structure for the interrupt IN transfer.
1330  */
1331 void
ehci_deallocate_isoc_in_resource(ehci_state_t * ehcip,ehci_pipe_private_t * pp,ehci_isoc_xwrapper_t * itw)1332 ehci_deallocate_isoc_in_resource(
1333 	ehci_state_t		*ehcip,
1334 	ehci_pipe_private_t	*pp,
1335 	ehci_isoc_xwrapper_t	*itw)
1336 {
1337 	usba_pipe_handle_data_t	*ph = pp->pp_pipe_handle;
1338 	uchar_t			ep_attr = ph->p_ep.bmAttributes;
1339 	usb_isoc_req_t		*isoc_reqp;
1340 
1341 	USB_DPRINTF_L4(PRINT_MASK_LISTS,
1342 	    ehcip->ehci_log_hdl,
1343 	    "ehci_deallocate_isoc_in_resource: "
1344 	    "pp = 0x%p itw = 0x%p", (void *)pp, (void *)itw);
1345 
1346 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
1347 	ASSERT((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH);
1348 
1349 	isoc_reqp = itw->itw_curr_xfer_reqp;
1350 
1351 	/* Check the current periodic in request pointer */
1352 	if (isoc_reqp) {
1353 		itw->itw_curr_xfer_reqp = NULL;
1354 		itw->itw_curr_isoc_pktp = NULL;
1355 
1356 		mutex_enter(&ph->p_mutex);
1357 		ph->p_req_count--;
1358 		mutex_exit(&ph->p_mutex);
1359 
1360 		usb_free_isoc_req(isoc_reqp);
1361 
1362 		/* Set periodic in pipe state to idle */
1363 		pp->pp_state = EHCI_PIPE_STATE_IDLE;
1364 	}
1365 }
1366 
1367 
1368 /*
1369  * ehci_itd_cpu_to_iommu:
1370  *
1371  * This function converts for the given Transfer Descriptor (ITD) CPU address
1372  * to IO address.
1373  */
1374 uint32_t
ehci_itd_cpu_to_iommu(ehci_state_t * ehcip,ehci_itd_t * addr)1375 ehci_itd_cpu_to_iommu(
1376 	ehci_state_t	*ehcip,
1377 	ehci_itd_t	*addr)
1378 {
1379 	uint32_t	td;
1380 
1381 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
1382 
1383 	if (addr == NULL)
1384 		return (0);
1385 
1386 	td = (uint32_t)ehcip->ehci_itd_pool_cookie.dmac_address +
1387 	    (uint32_t)((uintptr_t)addr -
1388 	    (uintptr_t)(ehcip->ehci_itd_pool_addr));
1389 
1390 	ASSERT(((uint32_t) (sizeof (ehci_itd_t) *
1391 	    (addr - ehcip->ehci_itd_pool_addr))) ==
1392 	    ((uint32_t)((uintptr_t)addr - (uintptr_t)
1393 	    (ehcip->ehci_itd_pool_addr))));
1394 
1395 	ASSERT(td >= ehcip->ehci_itd_pool_cookie.dmac_address);
1396 	ASSERT(td <= ehcip->ehci_itd_pool_cookie.dmac_address +
1397 	    sizeof (ehci_itd_t) * ehci_itd_pool_size);
1398 
1399 	return (td);
1400 }
1401 
1402 
1403 /*
1404  * ehci_itd_iommu_to_cpu:
1405  *
1406  * This function converts for the given Transfer Descriptor (ITD) IO address
1407  * to CPU address.
1408  */
1409 ehci_itd_t *
ehci_itd_iommu_to_cpu(ehci_state_t * ehcip,uintptr_t addr)1410 ehci_itd_iommu_to_cpu(
1411 	ehci_state_t	*ehcip,
1412 	uintptr_t	addr)
1413 {
1414 	ehci_itd_t	*itd;
1415 
1416 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
1417 
1418 	if (addr == 0)
1419 		return (NULL);
1420 
1421 	itd = (ehci_itd_t *)((uintptr_t)
1422 	    (addr - ehcip->ehci_itd_pool_cookie.dmac_address) +
1423 	    (uintptr_t)ehcip->ehci_itd_pool_addr);
1424 
1425 	ASSERT(itd >= ehcip->ehci_itd_pool_addr);
1426 	ASSERT((uintptr_t)itd <= (uintptr_t)ehcip->ehci_itd_pool_addr +
1427 	    (uintptr_t)(sizeof (ehci_itd_t) * ehci_itd_pool_size));
1428 
1429 	return (itd);
1430 }
1431 
1432 
1433 /*
1434  * Error parsing functions
1435  */
ehci_parse_isoc_error(ehci_state_t * ehcip,ehci_isoc_xwrapper_t * itw,ehci_itd_t * itd)1436 void ehci_parse_isoc_error(
1437 	ehci_state_t		*ehcip,
1438 	ehci_isoc_xwrapper_t	*itw,
1439 	ehci_itd_t		*itd)
1440 {
1441 	usb_isoc_req_t		*isoc_reqp;
1442 	usb_cr_t		error;
1443 
1444 	ASSERT(mutex_owned(&ehcip->ehci_int_mutex));
1445 
1446 	isoc_reqp = itw->itw_curr_xfer_reqp;
1447 
1448 	if (itw->itw_port_status == USBA_HIGH_SPEED_DEV) {
1449 		error = ehci_parse_itd_error(ehcip, itw, itd);
1450 	} else {
1451 		error = ehci_parse_sitd_error(ehcip, itw, itd);
1452 
1453 		if (error != USB_CR_OK) {
1454 			isoc_reqp->isoc_error_count++;
1455 
1456 			USB_DPRINTF_L2(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1457 			    "ehci_parse_sitd_error: Error %d Device Address %d"
1458 			    " Endpoint number %d", error, itw->itw_device_addr,
1459 			    itw->itw_endpoint_num);
1460 		}
1461 
1462 	}
1463 }
1464 
1465 
1466 /* ARGSUSED */
ehci_parse_itd_error(ehci_state_t * ehcip,ehci_isoc_xwrapper_t * itw,ehci_itd_t * itd)1467 static usb_cr_t ehci_parse_itd_error(
1468 	ehci_state_t		*ehcip,
1469 	ehci_isoc_xwrapper_t	*itw,
1470 	ehci_itd_t		*itd)
1471 {
1472 	uint32_t		status, index;
1473 	usb_cr_t		error = USB_CR_OK;
1474 	uint32_t		i;
1475 	usb_isoc_req_t		*isoc_reqp;
1476 
1477 	isoc_reqp = itw->itw_curr_xfer_reqp;
1478 
1479 	for (i = 0; i < EHCI_ITD_CTRL_LIST_SIZE; i++) {
1480 		index = Get_ITD_INDEX(itd, i);
1481 		if (index == 0xffffffff) {
1482 
1483 			continue;
1484 		}
1485 
1486 		error = USB_CR_OK;
1487 
1488 		status = Get_ITD_BODY(itd, EHCI_ITD_CTRL0 + i) &
1489 		    EHCI_ITD_XFER_STATUS_MASK;
1490 
1491 		if (status & EHCI_ITD_XFER_DATA_BUFFER_ERR) {
1492 			if (itw->itw_direction == USB_EP_DIR_OUT) {
1493 				USB_DPRINTF_L3(PRINT_MASK_INTR,
1494 				    ehcip->ehci_log_hdl,
1495 				    "ehci_parse_itd_error: BUFFER Underrun");
1496 
1497 				error = USB_CR_BUFFER_UNDERRUN;
1498 			} else {
1499 				USB_DPRINTF_L3(PRINT_MASK_INTR,
1500 				    ehcip->ehci_log_hdl,
1501 				    "ehci_parse_itd_error: BUFFER Overrun");
1502 
1503 				error = USB_CR_BUFFER_OVERRUN;
1504 			}
1505 		}
1506 
1507 		if (status & EHCI_ITD_XFER_BABBLE) {
1508 			USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1509 			    "ehci_parse_itd_error: BABBLE DETECTED");
1510 
1511 			error = USB_CR_DATA_OVERRUN;
1512 		}
1513 
1514 		if (status & EHCI_ITD_XFER_ERROR) {
1515 			USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1516 			    "ehci_parse_itd_error: XACT ERROR");
1517 
1518 			error = USB_CR_DEV_NOT_RESP;
1519 		}
1520 
1521 		if (status & EHCI_ITD_XFER_ACTIVE) {
1522 			USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1523 			    "ehci_parse_itd_error: NOT ACCESSED");
1524 
1525 			error = USB_CR_NOT_ACCESSED;
1526 		}
1527 
1528 		itw->itw_curr_isoc_pktp->isoc_pkt_actual_length = 0;
1529 
1530 		/* Write the status of isoc data packet */
1531 		itw->itw_curr_isoc_pktp->isoc_pkt_status = error;
1532 
1533 		/* counts total number of error packets in this req */
1534 		if (error != USB_CR_OK) {
1535 			isoc_reqp->isoc_error_count++;
1536 			USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1537 			    "ehci_parse_itd_error: Error %d Device Address %d "
1538 			    "Endpoint number %d", error, itw->itw_device_addr,
1539 			    itw->itw_endpoint_num);
1540 		}
1541 
1542 		itw->itw_curr_isoc_pktp++;
1543 	}
1544 
1545 	return (error);
1546 }
1547 
ehci_parse_sitd_error(ehci_state_t * ehcip,ehci_isoc_xwrapper_t * itw,ehci_itd_t * itd)1548 static usb_cr_t ehci_parse_sitd_error(
1549 	ehci_state_t		*ehcip,
1550 	ehci_isoc_xwrapper_t	*itw,
1551 	ehci_itd_t		*itd)
1552 {
1553 	uint32_t		status;
1554 	usb_cr_t		error;
1555 	usb_isoc_pkt_descr_t	*isoc_pkt_descr;
1556 	uint32_t		residue;
1557 
1558 	isoc_pkt_descr = itw->itw_curr_isoc_pktp;
1559 
1560 	status = Get_ITD_BODY(itd, EHCI_SITD_XFER_STATE) &
1561 	    EHCI_SITD_XFER_STATUS_MASK;
1562 
1563 	switch (status) {
1564 	case EHCI_SITD_XFER_ACTIVE:
1565 		USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1566 		    "ehci_check_for_sitd_error: NOT ACCESSED");
1567 		error = USB_CR_NOT_ACCESSED;
1568 
1569 		break;
1570 	case EHCI_SITD_XFER_ERROR:
1571 		USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1572 		    "ehci_check_for_sitd_error: TT ERROR");
1573 
1574 		error = USB_CR_UNSPECIFIED_ERR;
1575 
1576 		break;
1577 	case EHCI_SITD_XFER_DATA_BUFFER_ERR:
1578 		if (itw->itw_direction == USB_EP_DIR_OUT) {
1579 			USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1580 			    "ehci_check_for_sitd_error: BUFFER Underrun");
1581 			error = USB_CR_BUFFER_UNDERRUN;
1582 		} else {
1583 			USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1584 			    "ehci_check_for_sitd_error: BUFFER Overrun");
1585 			error = USB_CR_BUFFER_OVERRUN;
1586 		}
1587 
1588 		break;
1589 	case EHCI_SITD_XFER_BABBLE:
1590 		USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1591 		    "ehci_check_for_sitd_error: BABBLE");
1592 		error = USB_CR_DATA_OVERRUN;
1593 
1594 		break;
1595 	case EHCI_SITD_XFER_XACT_ERROR:
1596 		USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1597 		    "ehci_check_for_sitd_error: XACT ERROR");
1598 
1599 		error = USB_CR_DEV_NOT_RESP;
1600 		break;
1601 	case EHCI_SITD_XFER_MISSED_UFRAME:
1602 		USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1603 		    "ehci_check_for_sitd_error: MISSED UFRAME");
1604 
1605 		error = USB_CR_NOT_ACCESSED;
1606 		break;
1607 	default:
1608 		USB_DPRINTF_L4(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
1609 		    "ehci_check_for_sitd_error: NO ERROR");
1610 		error = USB_CR_OK;
1611 
1612 		break;
1613 	}
1614 
1615 	/* This is HCD specific and may not have this information */
1616 	residue =
1617 	    (Get_ITD_BODY(itd, EHCI_SITD_XFER_STATE) &
1618 	    EHCI_SITD_XFER_TOTAL_MASK) >>
1619 	    EHCI_SITD_XFER_TOTAL_SHIFT;
1620 
1621 	/*
1622 	 * Subtract the residue from the isoc_pkt_descr that
1623 	 * was set when this ITD was inserted.
1624 	 */
1625 	isoc_pkt_descr->isoc_pkt_actual_length -= residue;
1626 
1627 	/* Write the status of isoc data packet */
1628 	isoc_pkt_descr->isoc_pkt_status = error;
1629 
1630 	itw->itw_curr_isoc_pktp++;
1631 
1632 	return (error);
1633 }
1634 
1635 
1636 /*
1637  * debug print functions
1638  */
1639 void
ehci_print_itd(ehci_state_t * ehcip,ehci_itd_t * itd)1640 ehci_print_itd(
1641 	ehci_state_t	*ehcip,
1642 	ehci_itd_t	*itd)
1643 {
1644 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1645 	    "ehci_print_itd: itd = 0x%p", (void *)itd);
1646 
1647 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1648 	    "\titd_link_ptr: 0x%x ", Get_ITD(itd->itd_link_ptr));
1649 
1650 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1651 	    "\titd_ctrl0: 0x%x ",
1652 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL0]));
1653 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1654 	    "\titd_ctrl1: 0x%x ",
1655 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL1]));
1656 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1657 	    "\titd_ctrl2: 0x%x ",
1658 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL2]));
1659 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1660 	    "\titd_ctrl3: 0x%x ",
1661 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL3]));
1662 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1663 	    "\titd_ctrl4: 0x%x ",
1664 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL4]));
1665 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1666 	    "\titd_ctrl5: 0x%x ",
1667 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL5]));
1668 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1669 	    "\titd_ctrl6: 0x%x ",
1670 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL6]));
1671 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1672 	    "\titd_ctrl7: 0x%x ",
1673 	    Get_ITD(itd->itd_body[EHCI_ITD_CTRL7]));
1674 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1675 	    "\titd_buffer0: 0x%x ",
1676 	    Get_ITD(itd->itd_body[EHCI_ITD_BUFFER0]));
1677 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1678 	    "\titd_buffer1: 0x%x ",
1679 	    Get_ITD(itd->itd_body[EHCI_ITD_BUFFER1]));
1680 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1681 	    "\titd_buffer2: 0x%x ",
1682 	    Get_ITD(itd->itd_body[EHCI_ITD_BUFFER2]));
1683 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1684 	    "\titd_buffer3: 0x%x ",
1685 	    Get_ITD(itd->itd_body[EHCI_ITD_BUFFER3]));
1686 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1687 	    "\titd_buffer4: 0x%x ",
1688 	    Get_ITD(itd->itd_body[EHCI_ITD_BUFFER4]));
1689 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1690 	    "\titd_buffer5: 0x%x ",
1691 	    Get_ITD(itd->itd_body[EHCI_ITD_BUFFER5]));
1692 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1693 	    "\titd_buffer6: 0x%x ",
1694 	    Get_ITD(itd->itd_body[EHCI_ITD_BUFFER6]));
1695 
1696 	/* HCD private fields */
1697 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1698 	    "\titd_trans_wrapper: 0x%x ",
1699 	    Get_ITD(itd->itd_trans_wrapper));
1700 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1701 	    "\titd_itw_next_itd: 0x%x ",
1702 	    Get_ITD(itd->itd_itw_next_itd));
1703 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1704 	    "\titd_state: 0x%x ",
1705 	    Get_ITD(itd->itd_state));
1706 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1707 	    "\titd_index: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ",
1708 	    Get_ITD_INDEX(itd, 0), Get_ITD_INDEX(itd, 1),
1709 	    Get_ITD_INDEX(itd, 2), Get_ITD_INDEX(itd, 3),
1710 	    Get_ITD_INDEX(itd, 4), Get_ITD_INDEX(itd, 5),
1711 	    Get_ITD_INDEX(itd, 6), Get_ITD_INDEX(itd, 7));
1712 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1713 	    "\titd_frame_number: 0x%x ",
1714 	    Get_ITD(itd->itd_frame_number));
1715 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1716 	    "\titd_reclaim_number: 0x%x ",
1717 	    Get_ITD(itd->itd_reclaim_number));
1718 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1719 	    "\titd_next_active_itd: 0x%x ",
1720 	    Get_ITD(itd->itd_next_active_itd));
1721 }
1722 
1723 
1724 void
ehci_print_sitd(ehci_state_t * ehcip,ehci_itd_t * itd)1725 ehci_print_sitd(
1726 	ehci_state_t	*ehcip,
1727 	ehci_itd_t	*itd)
1728 {
1729 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1730 	    "ehci_print_itd: itd = 0x%p", (void *)itd);
1731 
1732 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1733 	    "\titd_link_ptr: 0x%x ", Get_ITD(itd->itd_link_ptr));
1734 
1735 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1736 	    "\tsitd_ctrl: 0x%x ",
1737 	    Get_ITD(itd->itd_body[EHCI_SITD_CTRL]));
1738 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1739 	    "\tsitd_uframe_sched: 0x%x ",
1740 	    Get_ITD(itd->itd_body[EHCI_SITD_UFRAME_SCHED]));
1741 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1742 	    "\tsitd_xfer_state: 0x%x ",
1743 	    Get_ITD(itd->itd_body[EHCI_SITD_XFER_STATE]));
1744 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1745 	    "\tsitd_buffer0: 0x%x ",
1746 	    Get_ITD(itd->itd_body[EHCI_SITD_BUFFER0]));
1747 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1748 	    "\tsitd_buffer1: 0x%x ",
1749 	    Get_ITD(itd->itd_body[EHCI_SITD_BUFFER1]));
1750 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1751 	    "\tsitd_prev_sitd: 0x%x ",
1752 	    Get_ITD(itd->itd_body[EHCI_SITD_PREV_SITD]));
1753 
1754 	/* HCD private fields */
1755 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1756 	    "\titd_trans_wrapper: 0x%x ",
1757 	    Get_ITD(itd->itd_trans_wrapper));
1758 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1759 	    "\titd_itw_next_itd: 0x%x ",
1760 	    Get_ITD(itd->itd_itw_next_itd));
1761 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1762 	    "\titd_state: 0x%x ",
1763 	    Get_ITD(itd->itd_state));
1764 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1765 	    "\titd_frame_number: 0x%x ",
1766 	    Get_ITD(itd->itd_frame_number));
1767 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1768 	    "\titd_reclaim_number: 0x%x ",
1769 	    Get_ITD(itd->itd_reclaim_number));
1770 	USB_DPRINTF_L3(PRINT_MASK_LISTS, ehcip->ehci_log_hdl,
1771 	    "\titd_next_active_itd: 0x%x ",
1772 	    Get_ITD(itd->itd_next_active_itd));
1773 }
1774