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