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