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