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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright (c) 2016 by Delphix. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
29 * Open Host Controller Driver (OHCI)
31 * The USB Open Host Controller driver is a software driver which interfaces
32 * to the Universal Serial Bus layer (USBA) and the USB Open Host Controller.
33 * The interface to USB Open Host Controller is defined by the OpenHCI Host
34 * Controller Interface.
36 * This module contains the specific ohci code used in POLLED mode and this
37 * code is in a separate file since it will never become part of ohci driver.
39 #include <sys/usb/hcd/openhci/ohcid.h>
40 #include <sys/usb/hcd/openhci/ohci_polled.h>
43 * Internal Function Prototypes
46 /* Polled initialization routines */
47 static int ohci_polled_init(
48 usba_pipe_handle_data_t
*ph
,
50 usb_console_info_impl_t
*console_input_info
);
52 /* Polled deinitialization routines */
53 static int ohci_polled_fini(ohci_polled_t
*ohci_polledp
);
55 /* Polled save state routines */
56 static void ohci_polled_save_state(ohci_polled_t
*ohci_polledp
);
57 static void ohci_polled_stop_processing(
58 ohci_polled_t
*ohci_polledp
);
60 /* Polled restore state routines */
61 static void ohci_polled_restore_state(ohci_polled_t
*ohci_polledp
);
62 static void ohci_polled_start_processing(
63 ohci_polled_t
*ohci_polledp
);
65 /* Polled read routines */
66 static ohci_td_t
*ohci_polled_pickup_done_list(
67 ohci_polled_t
*ohci_polledp
,
68 ohci_td_t
*done_head
);
69 static int ohci_polled_check_done_list(
70 ohci_polled_t
*ohci_polledp
);
71 static void ohci_polled_create_input_list(
72 ohci_polled_t
*ohci_polledp
,
73 ohci_td_t
*head_done_list
);
74 static int ohci_polled_process_input_list(
75 ohci_polled_t
*ohci_polledp
);
76 static int ohci_polled_handle_normal_td(
77 ohci_polled_t
*ohci_polledp
,
79 static void ohci_polled_insert_td(ohci_state_t
*ohcip
,
81 static void ohci_polled_fill_in_td(ohci_state_t
*ohcip
,
85 uint32_t hctd_iommu_cbp
,
87 ohci_trans_wrapper_t
*tw
);
88 static void ohci_polled_insert_td_on_tw(
90 ohci_trans_wrapper_t
*tw
,
92 static void ohci_polled_handle_frame_number_overflow(
94 static void ohci_polled_finish_interrupt(
97 static void ohci_polled_insert_bulk_td(
98 ohci_polled_t
*ohci_polledp
);
99 static int ohci_polled_create_tw(
101 usba_pipe_handle_data_t
*ph
,
102 usb_flags_t usb_flags
);
103 static int ohci_polled_insert_hc_td(
106 uint32_t hctd_dma_offs
,
108 ohci_pipe_private_t
*pp
,
109 ohci_trans_wrapper_t
*tw
);
111 * POLLED entry points
113 * These functions are entry points into the POLLED code.
117 * ohci_hcdi_polled_input_init:
119 * This is the initialization routine for handling the USB input device
120 * in POLLED mode. This routine is not called from POLLED mode, so
121 * it is OK to acquire mutexes.
124 ohci_hcdi_polled_input_init(
125 usba_pipe_handle_data_t
*ph
,
126 uchar_t
**polled_buf
,
127 usb_console_info_impl_t
*console_input_info
)
129 ohci_polled_t
*ohci_polledp
;
133 ohcip
= ohci_obtain_state(ph
->p_usba_device
->usb_root_hub_dip
);
136 * Grab the ohci_int_mutex so that things don't change on us
137 * if an interrupt comes in.
139 mutex_enter(&ohcip
->ohci_int_mutex
);
141 ret
= ohci_polled_init(ph
, ohcip
, console_input_info
);
143 if (ret
!= USB_SUCCESS
) {
145 /* Allow interrupts to continue */
146 mutex_exit(&ohcip
->ohci_int_mutex
);
151 ohci_polledp
= (ohci_polled_t
*)console_input_info
->uci_private
;
153 * Mark the structure so that if we are using it, we don't free
154 * the structures if one of them is unplugged.
156 ohci_polledp
->ohci_polled_flags
|= POLLED_INPUT_MODE
;
158 /* increase the polled kbd counter for keyboard connected */
159 ohcip
->ohci_polled_kbd_count
++;
162 * This is the buffer we will copy characters into. It will be
163 * copied into at this layer, so we need to keep track of it.
165 ohci_polledp
->ohci_polled_buf
=
166 (uchar_t
*)kmem_zalloc(POLLED_RAW_BUF_SIZE
, KM_SLEEP
);
168 *polled_buf
= ohci_polledp
->ohci_polled_buf
;
170 /* Insert bulkin td into endpoint's tds list */
171 pipe_attr
= ohci_polledp
->ohci_polled_input_pipe_handle
->
172 p_ep
.bmAttributes
& USB_EP_ATTR_MASK
;
174 if (pipe_attr
== USB_EP_ATTR_BULK
) {
175 ohci_polled_insert_bulk_td(ohci_polledp
);
178 * This is a software workaround to fix schizo hardware bug.
179 * Existence of "no-prom-cdma-sync" property means consistent
180 * dma sync should not be done while in prom or polled mode.
182 if (ddi_prop_exists(DDI_DEV_T_ANY
, ohcip
->ohci_dip
,
183 DDI_PROP_NOTPROM
, "no-prom-cdma-sync")) {
184 ohci_polledp
->ohci_polled_no_sync_flag
= B_TRUE
;
187 /* Allow interrupts to continue */
188 mutex_exit(&ohcip
->ohci_int_mutex
);
190 return (USB_SUCCESS
);
195 * ohci_hcdi_polled_input_fini:
198 ohci_hcdi_polled_input_fini(usb_console_info_impl_t
*info
)
200 ohci_polled_t
*ohci_polledp
;
204 ohci_polledp
= (ohci_polled_t
*)info
->uci_private
;
206 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
208 mutex_enter(&ohcip
->ohci_int_mutex
);
211 * Reset the POLLED_INPUT_MODE flag so that we can tell if
212 * this structure is in use in the ohci_polled_fini routine.
214 ohci_polledp
->ohci_polled_flags
&= ~POLLED_INPUT_MODE
;
216 /* Decrease the polled kbd counter for keyboard disconnected */
217 ohcip
->ohci_polled_kbd_count
--;
219 /* Free the buffer that we copied data into */
220 kmem_free(ohci_polledp
->ohci_polled_buf
, POLLED_RAW_BUF_SIZE
);
222 ret
= ohci_polled_fini(ohci_polledp
);
224 mutex_exit(&ohcip
->ohci_int_mutex
);
231 * ohci_hcdi_polled_input_enter:
233 * This is where we enter into POLLED mode. This routine sets up
234 * everything so that calls to ohci_hcdi_polled_read will return
238 ohci_hcdi_polled_input_enter(usb_console_info_impl_t
*info
)
240 ohci_polled_t
*ohci_polledp
;
242 ohci_polledp
= (ohci_polled_t
*)info
->uci_private
;
243 ohci_polledp
->ohci_polled_entry
++;
245 * If the controller is already switched over, just return
247 if (ohci_polledp
->ohci_polled_entry
> 1) {
249 return (USB_SUCCESS
);
251 ohci_polled_save_state(ohci_polledp
);
253 ohci_polledp
->ohci_polled_flags
|= POLLED_INPUT_MODE_INUSE
;
255 return (USB_SUCCESS
);
260 * ohci_hcdi_polled_input_exit:
262 * This is where we exit POLLED mode. This routine restores
263 * everything that is needed to continue operation.
266 ohci_hcdi_polled_input_exit(usb_console_info_impl_t
*info
)
268 ohci_polled_t
*ohci_polledp
;
270 ohci_polledp
= (ohci_polled_t
*)info
->uci_private
;
272 ohci_polledp
->ohci_polled_entry
--;
275 * If there are still outstanding "enters", just return
277 if (ohci_polledp
->ohci_polled_entry
> 0)
278 return (USB_SUCCESS
);
280 ohci_polledp
->ohci_polled_flags
&= ~POLLED_INPUT_MODE_INUSE
;
281 ohci_polled_restore_state(ohci_polledp
);
283 return (USB_SUCCESS
);
288 * ohci_hcdi_polled_read:
290 * Get a key character
293 ohci_hcdi_polled_read(
294 usb_console_info_impl_t
*info
,
295 uint_t
*num_characters
)
298 ohci_polled_t
*ohci_polledp
;
300 ohci_polledp
= (ohci_polled_t
*)info
->uci_private
;
302 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
304 _NOTE(NO_COMPETING_THREADS_NOW
);
306 intr
= (Get_OpReg(hcr_intr_status
) & Get_OpReg(hcr_intr_enable
));
309 * Check whether any Frame Number Overflow interrupt is pending
310 * and if it is pending, process this interrupt.
312 if (intr
& HCR_INTR_FNO
) {
313 ohci_handle_frame_number_overflow(ohcip
);
315 /* Acknowledge the FNO interrupt */
316 ohci_polled_finish_interrupt(ohcip
, HCR_INTR_FNO
);
319 /* Check to see if there are any TD's for this input device */
320 if (ohci_polled_check_done_list(ohci_polledp
) == USB_SUCCESS
) {
322 /* Process any TD's on the input done list */
324 ohci_polled_process_input_list(ohci_polledp
);
328 * To make sure after we get the done list from DoneHead,
329 * every input device gets its own TD's in the
330 * ohci_polled_done_list and then clear the interrupt status.
332 if (intr
& HCR_INTR_WDH
) {
334 /* Acknowledge the WDH interrupt */
335 ohci_polled_finish_interrupt(ohcip
, HCR_INTR_WDH
);
337 _NOTE(COMPETING_THREADS_NOW
);
339 return (USB_SUCCESS
);
344 * ohci_hcdi_polled_output_init:
346 * This is the initialization routine for handling the USB serial output
347 * in POLLED mode. This routine is not called from POLLED mode, so
348 * it is OK to acquire mutexes.
351 ohci_hcdi_polled_output_init(
352 usba_pipe_handle_data_t
*ph
,
353 usb_console_info_impl_t
*console_output_info
)
355 ohci_polled_t
*ohci_polledp
;
359 ohcip
= ohci_obtain_state(ph
->p_usba_device
->usb_root_hub_dip
);
362 * Grab the ohci_int_mutex so that things don't change on us
363 * if an interrupt comes in.
365 mutex_enter(&ohcip
->ohci_int_mutex
);
367 ret
= ohci_polled_init(ph
, ohcip
, console_output_info
);
369 if (ret
!= USB_SUCCESS
) {
371 /* Allow interrupts to continue */
372 mutex_exit(&ohcip
->ohci_int_mutex
);
377 ohci_polledp
= (ohci_polled_t
*)console_output_info
->uci_private
;
379 * Mark the structure so that if we are using it, we don't free
380 * the structures if one of them is unplugged.
382 ohci_polledp
->ohci_polled_flags
|= POLLED_OUTPUT_MODE
;
385 * This is a software workaround to fix schizo hardware bug.
386 * Existence of "no-prom-cdma-sync" property means consistent
387 * dma sync should not be done while in prom or polled mode.
389 if (ddi_prop_exists(DDI_DEV_T_ANY
, ohcip
->ohci_dip
,
390 DDI_PROP_NOTPROM
, "no-prom-cdma-sync")) {
391 ohci_polledp
->ohci_polled_no_sync_flag
= B_TRUE
;
394 /* Allow interrupts to continue */
395 mutex_exit(&ohcip
->ohci_int_mutex
);
397 return (USB_SUCCESS
);
401 * ohci_hcdi_polled_output_fini:
404 ohci_hcdi_polled_output_fini(usb_console_info_impl_t
*info
)
406 ohci_polled_t
*ohci_polledp
;
410 ohci_polledp
= (ohci_polled_t
*)info
->uci_private
;
412 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
414 mutex_enter(&ohcip
->ohci_int_mutex
);
417 * Reset the POLLED_INPUT_MODE flag so that we can tell if
418 * this structure is in use in the ohci_polled_fini routine.
420 ohci_polledp
->ohci_polled_flags
&= ~POLLED_OUTPUT_MODE
;
422 ret
= ohci_polled_fini(ohci_polledp
);
424 info
->uci_private
= NULL
;
426 mutex_exit(&ohcip
->ohci_int_mutex
);
433 * ohci_hcdi_polled_output_enter:
435 * everything is done in input enter
439 ohci_hcdi_polled_output_enter(usb_console_info_impl_t
*info
)
441 return (USB_SUCCESS
);
446 * ohci_hcdi_polled_output_exit:
448 * everything is done in input exit
452 ohci_hcdi_polled_output_exit(usb_console_info_impl_t
*info
)
454 return (USB_SUCCESS
);
459 * ohci_hcdi_polled_write:
460 * Put a key character -- rewrite this!
463 ohci_hcdi_polled_write(usb_console_info_impl_t
*info
, uchar_t
*buf
,
464 uint_t num_characters
, uint_t
*num_characters_written
)
467 ohci_polled_t
*ohci_polledp
;
468 ohci_trans_wrapper_t
*tw
;
469 ohci_pipe_private_t
*pp
;
470 usba_pipe_handle_data_t
*ph
;
472 uint_t intr
, bulk_pkg_size
;
475 _NOTE(NO_COMPETING_THREADS_NOW
);
477 ohci_polledp
= (ohci_polled_t
*)info
->uci_private
;
478 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
480 /* Disable periodic list processing */
481 Set_OpReg(hcr_control
,
482 (Get_OpReg(hcr_control
) & (~HCR_CONTROL_PLE
)));
484 /* Add the endpoint to the lattice */
485 for (i
= ohcip
->ohci_polled_enter_count
; i
< NUM_INTR_ED_LISTS
;
486 i
= i
+ MIN_LOW_SPEED_POLL_INTERVAL
) {
487 Set_HCCA(ohcip
->ohci_hccap
->HccaIntTble
[i
],
488 ohci_ed_cpu_to_iommu(ohcip
,
489 ohci_polledp
->ohci_polled_ed
));
492 ph
= ohci_polledp
->ohci_polled_input_pipe_handle
;
493 pp
= (ohci_pipe_private_t
*)ph
->p_hcd_private
;
497 if (tw
->tw_hctd_free_list
== NULL
) {
498 _NOTE(COMPETING_THREADS_NOW
);
499 return (USB_SUCCESS
);
502 /* Copy transmit buffer */
503 if (num_characters
> POLLED_RAW_BUF_SIZE
) {
504 cmn_err(CE_NOTE
, "polled write size %d bigger than %d",
505 num_characters
, POLLED_RAW_BUF_SIZE
);
506 num_characters
= POLLED_RAW_BUF_SIZE
;
508 tw
->tw_length
= num_characters
;
510 ddi_rep_put8(tw
->tw_accesshandle
,
511 buf
, (uint8_t *)tw
->tw_buf
,
512 tw
->tw_length
, DDI_DEV_AUTOINCR
);
513 Sync_IO_Buffer_for_device(tw
->tw_dmahandle
, tw
->tw_length
);
515 /* Insert td into endpoint's tds list */
516 ctrl
= tw
->tw_direction
| HC_TD_DT_0
|HC_TD_1I
| HC_TD_R
;
517 bulk_pkg_size
= min(tw
->tw_length
, OHCI_MAX_TD_XFER_SIZE
);
519 (void) ohci_polled_insert_hc_td(ohcip
, ctrl
, 0, bulk_pkg_size
, pp
, tw
);
521 /* Enable periodic list processing */
522 Set_OpReg(hcr_control
,
523 (Get_OpReg(hcr_control
) | HCR_CONTROL_PLE
));
525 /* Wait for bulk out tds transfer completion */
527 intr
= Get_OpReg(hcr_intr_status
);
529 if (intr
& HCR_INTR_FNO
) {
530 ohci_handle_frame_number_overflow(ohcip
);
531 ohci_polled_finish_interrupt(ohcip
, HCR_INTR_FNO
);
534 if (intr
& HCR_INTR_WDH
) {
535 if (ohci_polled_check_done_list(ohci_polledp
) ==
537 *num_characters_written
=
538 ohci_polled_process_input_list(
544 Set_OpReg(hcr_intr_status
, intr
);
545 (void) Get_OpReg(hcr_intr_status
);
548 /* Remove the endpoint from the lattice */
549 for (i
= ohcip
->ohci_polled_enter_count
; i
< NUM_INTR_ED_LISTS
;
550 i
= i
+ MIN_LOW_SPEED_POLL_INTERVAL
) {
551 Set_HCCA(ohcip
->ohci_hccap
->HccaIntTble
[i
],
552 ohci_ed_cpu_to_iommu(ohcip
,
553 ohci_polledp
->ohci_polled_dummy_ed
));
556 Set_OpReg(hcr_intr_status
, intr
);
557 (void) Get_OpReg(hcr_intr_status
);
558 _NOTE(COMPETING_THREADS_NOW
);
559 return (USB_SUCCESS
);
568 * Polled initialization routines
575 * Initialize generic information Uthat is needed to provide USB/POLLED
580 usba_pipe_handle_data_t
*ph
,
582 usb_console_info_impl_t
*console_info
)
584 ohci_polled_t
*ohci_polledp
;
585 ohci_pipe_private_t
*pp
;
588 ASSERT(mutex_owned(&ohcip
->ohci_int_mutex
));
591 * We have already initialized this structure. If the structure
592 * has already been initialized, then we don't need to redo it.
594 if (console_info
->uci_private
) {
596 return (USB_SUCCESS
);
599 /* Allocate and intitialize a state structure */
600 ohci_polledp
= (ohci_polled_t
*)
601 kmem_zalloc(sizeof (ohci_polled_t
), KM_SLEEP
);
603 console_info
->uci_private
= (usb_console_info_private_t
)ohci_polledp
;
606 * Store away the ohcip so that we can get to it when we are in
607 * POLLED mode. We don't want to have to call ohci_obtain_state
608 * every time we want to access this structure. Also save ohci
609 * polled state information in ohcip.
611 ohci_polledp
->ohci_polled_ohcip
= ohcip
;
614 * Save usb device and endpoint number information from the usb
617 mutex_enter(&ph
->p_mutex
);
618 ohci_polledp
->ohci_polled_usb_dev
= ph
->p_usba_device
;
619 ohci_polledp
->ohci_polled_ep_addr
= ph
->p_ep
.bEndpointAddress
;
620 mutex_exit(&ph
->p_mutex
);
623 * Allocate memory to make duplicate of original usb pipe handle.
625 ohci_polledp
->ohci_polled_input_pipe_handle
=
626 kmem_zalloc(sizeof (usba_pipe_handle_data_t
), KM_SLEEP
);
629 * Copy the USB handle into the new pipe handle. Also
630 * create new lock for the new pipe handle.
633 (void *)ohci_polledp
->ohci_polled_input_pipe_handle
,
634 sizeof (usba_pipe_handle_data_t
));
637 * uint64_t typecast to make sure amd64 can compile
639 mutex_init(&ohci_polledp
->ohci_polled_input_pipe_handle
->p_mutex
,
640 NULL
, MUTEX_DRIVER
, DDI_INTR_PRI(ohcip
->ohci_intr_pri
));
642 /* Create a new ohci pipe private structure */
643 pp
= (ohci_pipe_private_t
*)
644 kmem_zalloc(sizeof (ohci_pipe_private_t
), KM_SLEEP
);
647 * Store the pointer in the pipe handle. This structure was also
650 mutex_enter(&ohci_polledp
->ohci_polled_input_pipe_handle
->p_mutex
);
652 ohci_polledp
->ohci_polled_input_pipe_handle
->
653 p_hcd_private
= (usb_opaque_t
)pp
;
655 mutex_exit(&ohci_polledp
->ohci_polled_input_pipe_handle
->p_mutex
);
658 * Store a pointer to the pipe handle. This structure was just
659 * allocated and it is not in use yet. The locking is there to
662 mutex_enter(&ph
->p_mutex
);
664 bcopy(&ph
->p_policy
, &pp
->pp_policy
, sizeof (usb_pipe_policy_t
));
666 mutex_exit(&ph
->p_mutex
);
668 pp
->pp_pipe_handle
= ohci_polledp
->ohci_polled_input_pipe_handle
;
671 * Allocate a dummy for the interrupt table. This dummy will be
672 * put into the action when we switch interrupt tables during
673 * ohci_hcdi_polled_enter. Dummy is placed on the unused lattice
674 * entries. When the ED is allocated we will replace dummy ED by
675 * valid interrupt ED in one or more locations in the interrupt
676 * lattice depending on the requested polling interval. Also we
677 * will hang a dummy TD to the ED & dummy TD is used to indicate
678 * the end of the TD chain.
680 ohci_polledp
->ohci_polled_dummy_ed
= ohci_alloc_hc_ed(ohcip
, NULL
);
682 if (ohci_polledp
->ohci_polled_dummy_ed
== NULL
) {
684 return (USB_NO_RESOURCES
);
688 * Allocate the endpoint. This ED will be inserted in
689 * to the lattice chain for the device. This endpoint
690 * will have the TDs hanging off of it for the processing.
692 ohci_polledp
->ohci_polled_ed
= ohci_alloc_hc_ed(ohcip
,
693 ohci_polledp
->ohci_polled_input_pipe_handle
);
695 if (ohci_polledp
->ohci_polled_ed
== NULL
) {
697 return (USB_NO_RESOURCES
);
700 /* Set the state of pipe as idle */
701 pp
->pp_state
= OHCI_PIPE_STATE_IDLE
;
703 /* Insert the endpoint onto the pipe handle */
704 pp
->pp_ept
= ohci_polledp
->ohci_polled_ed
;
706 pipe_attr
= ph
->p_ep
.bmAttributes
& USB_EP_ATTR_MASK
;
709 case USB_EP_ATTR_INTR
:
711 * Set soft interrupt handler flag in the normal mode usb
714 mutex_enter(&ph
->p_mutex
);
715 ph
->p_spec_flag
|= USBA_PH_FLAG_USE_SOFT_INTR
;
716 mutex_exit(&ph
->p_mutex
);
719 * Insert a Interrupt polling request onto the endpoint.
721 * There will now be two TDs on the ED, one is the dummy TD
722 * that was allocated above in the ohci_alloc_hc_ed and
725 if ((ohci_start_periodic_pipe_polling(ohcip
,
726 ohci_polledp
->ohci_polled_input_pipe_handle
,
727 NULL
, USB_FLAGS_SLEEP
)) != USB_SUCCESS
) {
728 return (USB_NO_RESOURCES
);
731 case USB_EP_ATTR_BULK
:
732 if ((ohci_polled_create_tw(ohcip
,
733 ohci_polledp
->ohci_polled_input_pipe_handle
,
734 USB_FLAGS_SLEEP
)) != USB_SUCCESS
) {
735 return (USB_NO_RESOURCES
);
739 return (USB_FAILURE
);
741 return (USB_SUCCESS
);
746 * Polled deinitialization routines
754 ohci_polled_fini(ohci_polled_t
*ohci_polledp
)
756 ohci_state_t
*ohcip
= ohci_polledp
->ohci_polled_ohcip
;
757 ohci_pipe_private_t
*pp
;
758 ohci_td_t
*curr_td
, *next_td
;
759 ohci_trans_wrapper_t
*curr_tw
, *next_tw
;
760 ASSERT(mutex_owned(&ohcip
->ohci_int_mutex
));
763 * If the structure is already in use, then don't free it.
765 if (ohci_polledp
->ohci_polled_flags
& POLLED_INPUT_MODE
) {
767 return (USB_SUCCESS
);
770 pp
= (ohci_pipe_private_t
*)
771 ohci_polledp
->ohci_polled_input_pipe_handle
->p_hcd_private
;
774 * Deallocate all the pre-allocated interrupt requests
776 ohci_handle_outstanding_requests(ohcip
, pp
);
779 * Traverse the list of TD's on this endpoint and these TD's
780 * have outstanding transfer requests. Since list processing
781 * is stopped, these TDs can be deallocated.
783 ohci_traverse_tds(ohcip
, pp
->pp_pipe_handle
);
786 * For each transfer wrapper on this pipe, free the TD and
787 * free the TW. We don't free the last TD in the chain
788 * because it will be freed by ohci_deallocate_ed. All TD's
789 * on this TW are also on the end point associated with this
792 next_tw
= pp
->pp_tw_head
;
795 next_td
= (ohci_td_t
*)next_tw
->tw_hctd_head
;
798 * Walk through each TD for this transfer
799 * wrapper and free that TD.
804 next_td
= ohci_td_iommu_to_cpu(ohcip
,
805 Get_TD(next_td
->hctd_tw_next_td
));
807 ohci_deallocate_td(ohcip
, curr_td
);
811 next_tw
= curr_tw
->tw_next
;
813 /* Free the transfer wrapper */
814 ohci_deallocate_tw_resources(ohcip
, pp
, curr_tw
);
818 * Deallocate the endpoint descriptors that we allocated
819 * with ohci_alloc_hc_ed.
821 if (ohci_polledp
->ohci_polled_dummy_ed
) {
822 ohci_deallocate_ed(ohcip
, ohci_polledp
->ohci_polled_dummy_ed
);
825 if (ohci_polledp
->ohci_polled_ed
) {
826 ohci_deallocate_ed(ohcip
, ohci_polledp
->ohci_polled_ed
);
829 mutex_destroy(&ohci_polledp
->ohci_polled_input_pipe_handle
->p_mutex
);
832 * Destroy everything about the pipe that we allocated in
833 * ohci_polled_duplicate_pipe_handle
835 kmem_free(pp
, sizeof (ohci_pipe_private_t
));
837 kmem_free(ohci_polledp
->ohci_polled_input_pipe_handle
,
838 sizeof (usba_pipe_handle_data_t
));
841 * We use this field to determine if a TD is for input or not,
842 * so NULL the pointer so we don't check deallocated data.
844 ohci_polledp
->ohci_polled_input_pipe_handle
= NULL
;
847 * Finally, free off the structure that we use to keep track
850 kmem_free(ohci_polledp
, sizeof (ohci_polled_t
));
852 return (USB_SUCCESS
);
857 * Polled save state routines
862 * ohci_polled_save_state:
865 ohci_polled_save_state(ohci_polled_t
*ohci_polledp
)
869 uint_t polled_toggle
;
871 ohci_pipe_private_t
*pp
= NULL
; /* Normal mode Pipe */
872 ohci_pipe_private_t
*polled_pp
; /* Polled mode Pipe */
873 usba_pipe_handle_data_t
*ph
;
875 ohci_save_intr_sts_t
*ohci_intr_sts
;
876 ohci_regs_t
*ohci_polled_regsp
;
877 ohci_td_t
*td
, *prev_td
;
878 ohci_td_t
*done_head
, **done_list
;
880 _NOTE(NO_COMPETING_THREADS_NOW
);
883 * If either of these two flags are set, then we have already
884 * saved off the state information and setup the controller.
886 if (ohci_polledp
->ohci_polled_flags
& POLLED_INPUT_MODE_INUSE
) {
887 _NOTE(COMPETING_THREADS_NOW
);
891 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
894 * Check if the number of keyboard reach the max number we can
895 * support in polled mode
897 if (++ ohcip
->ohci_polled_enter_count
> MAX_NUM_FOR_KEYBOARD
) {
898 _NOTE(COMPETING_THREADS_NOW
);
901 /* Get the endpoint addr. */
902 ep_addr
= ohci_polledp
->ohci_polled_ep_addr
;
904 /* Get the normal mode usb pipe handle */
905 ph
= usba_hcdi_get_ph_data(ohci_polledp
->ohci_polled_usb_dev
, ep_addr
);
906 ohci_intr_sts
= &ohcip
->ohci_save_intr_sts
;
907 ohci_polled_regsp
= &ohcip
->ohci_polled_save_regs
;
910 * Only the first enter keyboard entry disable the interrupt, save the
911 * information of normal mode, stop the processing, initialize the
914 if (ohcip
->ohci_polled_enter_count
== 1) {
916 * Prevent the ohci interrupt handler from handling interrupt.
917 * We will turn off interrupts. This keeps us from generating
918 * a hardware interrupt.This is the useful for testing because
919 * in POLLED mode we can't get interrupts anyway. We can test
920 * this code by shutting off hardware interrupt generation and
921 * polling for the interrupts.
923 Set_OpReg(hcr_intr_disable
, HCR_INTR_MIE
);
925 * Save the current normal mode ohci registers and later this
926 * saved register copy is used to replace some of required ohci
927 * registers before switching from polled mode to normal mode.
929 bzero((void *)ohci_polled_regsp
, sizeof (ohci_regs_t
));
931 ohci_polled_regsp
->hcr_control
= Get_OpReg(hcr_control
);
932 ohci_polled_regsp
->hcr_cmd_status
= Get_OpReg(hcr_cmd_status
);
933 ohci_polled_regsp
->hcr_intr_enable
= Get_OpReg(hcr_intr_enable
);
934 ohci_polled_regsp
->hcr_HCCA
= Get_OpReg(hcr_HCCA
);
935 ohci_polled_regsp
->hcr_done_head
= Get_OpReg(hcr_done_head
);
936 ohci_polled_regsp
->hcr_bulk_head
= Get_OpReg(hcr_bulk_head
);
937 ohci_polled_regsp
->hcr_ctrl_head
= Get_OpReg(hcr_ctrl_head
);
940 * The functionality & importance of critical code section in
941 * the normal mode ohci interrupt handler and its usage in the
942 * polled mode is explained below.
946 * - Set the flag indicating that processing critical code
947 * in ohci interrupt handler.
949 * - Process the missed ohci interrupts by copying missed
950 * interrupt events & done head list fields information
951 * to the critical interrupt events & done list fields.
953 * - Reset the missed ohci interrupt events and done head
954 * list fields so that the new missed interrupt events
955 * and done head list information can be saved.
957 * - All above steps will be executed within the critical
958 * section of the interrupt handler. Then ohci missed
959 * interrupt handler will be called to service the ohci
964 * - On entering the polled code, checks for the critical
965 * section code execution within normal mode interrupt
968 * - If critical section code is executing in the normal
969 * mode ohci interrupt handler & if copying of the ohci
970 * missed interrupt events and done head list fields to
971 * the critical fields is finished then, save the "any
972 * missed interrupt events and done head list" because
973 * of current polled mode switch into "critical missed
974 * interrupt events & done list fields" instead actual
975 * missed events and done list fields.
977 * - Otherwise save "any missed interrupt events and done
978 * list" because of this current polled mode switch in
979 * the actual missed interrupt events & done head list
984 * Check and save the pending SOF interrupt condition for the
985 * ohci normal mode. This information will be saved either in
986 * the critical missed event fields or in actual missed event
987 * fields depending on the whether the critical code section's
988 * execution flag was set or not when switched to polled mode
991 if ((ohci_intr_sts
->ohci_intr_flag
& OHCI_INTR_CRITICAL
) &&
992 (ohci_intr_sts
->ohci_critical_intr_sts
!= 0)) {
994 ohci_intr_sts
->ohci_critical_intr_sts
|=
995 ((Get_OpReg(hcr_intr_status
) &
996 Get_OpReg(hcr_intr_enable
)) & HCR_INTR_SOF
);
998 ohci_intr_sts
->ohci_missed_intr_sts
|=
999 ((Get_OpReg(hcr_intr_status
) &
1000 Get_OpReg(hcr_intr_enable
)) & HCR_INTR_SOF
);
1002 ohci_polled_stop_processing(ohci_polledp
);
1004 /* Process any missed Frame Number Overflow (FNO) interrupt */
1005 ohci_polled_handle_frame_number_overflow(ohcip
);
1008 * By this time all list processing has been stopped.Now check
1009 * and save the information about the pending HCCA done list,
1010 * done head ohci register and WDH bit in the interrupt status
1011 * register. This information will be saved either in critical
1012 * missed event fields or in actual missed event fields depend
1013 * on the whether the critical code section's execution flag
1014 * was set or not when switched to polled mode from the normal
1018 /* Read and Save the HCCA DoneHead value */
1019 done_head
= (ohci_td_t
*)(uintptr_t)(Get_HCCA(
1020 ohcip
->ohci_hccap
->HccaDoneHead
) & HCCA_DONE_HEAD_MASK
);
1023 (done_head
!= ohci_intr_sts
->ohci_curr_done_lst
)) {
1025 if ((ohci_intr_sts
->ohci_intr_flag
&
1026 OHCI_INTR_CRITICAL
) &&
1027 ((ohci_intr_sts
->ohci_critical_done_lst
) ||
1028 (ohci_intr_sts
->ohci_missed_done_lst
== NULL
))) {
1031 &ohci_intr_sts
->ohci_critical_done_lst
;
1032 ohci_intr_sts
->ohci_critical_intr_sts
|=
1036 &ohci_intr_sts
->ohci_missed_done_lst
;
1037 ohci_intr_sts
->ohci_missed_intr_sts
|=
1043 ohci_td_iommu_to_cpu(ohcip
,
1044 (uintptr_t)done_head
);
1048 td
= ohci_td_iommu_to_cpu(ohcip
,
1049 Get_TD(td
->hctd_next_td
));
1052 Set_TD(prev_td
->hctd_next_td
, *done_list
);
1054 *done_list
= done_head
;
1056 *done_list
= (ohci_td_t
*)done_head
;
1061 * Save the latest hcr_done_head ohci register value, so that
1062 * this value can be replaced when exit from the POLLED mode.
1064 ohci_polled_regsp
->hcr_done_head
= Get_OpReg(hcr_done_head
);
1066 * Reset the HCCA done head and ohci done head register.
1068 Set_HCCA(ohcip
->ohci_hccap
->HccaDoneHead
, 0);
1069 Set_OpReg(hcr_done_head
, (uint32_t)0x0);
1072 * Clear the WriteDoneHead interrupt bit in the ohci interrupt
1075 Set_OpReg(hcr_intr_status
, HCR_INTR_WDH
);
1078 * Save the current interrupt lattice and replace this lattice
1079 * with an lattice used in POLLED mode. We will restore lattice
1080 * back when we exit from the POLLED mode.
1082 for (i
= 0; i
< NUM_INTR_ED_LISTS
; i
++) {
1083 ohcip
->ohci_polled_save_IntTble
[i
] =
1084 (ohci_ed_t
*)(uintptr_t)Get_HCCA(
1085 ohcip
->ohci_hccap
->HccaIntTble
[i
]);
1088 * Fill in the lattice with dummy EDs. These EDs are used so the
1089 * controller can tell that it is at the end of the ED list.
1091 for (i
= 0; i
< NUM_INTR_ED_LISTS
; i
++) {
1092 Set_HCCA(ohcip
->ohci_hccap
->HccaIntTble
[i
],
1093 ohci_ed_cpu_to_iommu(ohcip
,
1094 ohci_polledp
->ohci_polled_dummy_ed
));
1097 /* Get the polled mode ohci pipe private structure */
1098 polled_pp
= (ohci_pipe_private_t
*)
1099 ohci_polledp
->ohci_polled_input_pipe_handle
->p_hcd_private
;
1102 * Before replacing the lattice, adjust the data togggle on the
1103 * on the ohci's interrupt ed
1105 polled_toggle
= (Get_ED(polled_pp
->pp_ept
->hced_headp
) &
1106 HC_EPT_Carry
) ? DATA1
:DATA0
;
1109 * If normal mode interrupt pipe endpoint is active, get the data
1110 * toggle from the this interrupt endpoint through the corresponding
1111 * interrupt pipe handle. Else get the data toggle information from
1112 * the usb device structure and this information is saved during the
1113 * normal mode interrupt pipe close. Use this data toggle information
1114 * to fix the data toggle of polled mode interrupt endpoint.
1117 /* Get the normal mode ohci pipe private structure */
1118 pp
= (ohci_pipe_private_t
*)ph
->p_hcd_private
;
1120 real_toggle
= (Get_ED(pp
->pp_ept
->hced_headp
) &
1121 HC_EPT_Carry
) ? DATA1
:DATA0
;
1123 real_toggle
= usba_hcdi_get_data_toggle(
1124 ohci_polledp
->ohci_polled_usb_dev
, ep_addr
);
1127 if (polled_toggle
!= real_toggle
) {
1128 if (real_toggle
== DATA0
) {
1129 Set_ED(polled_pp
->pp_ept
->hced_headp
,
1130 Get_ED(polled_pp
->pp_ept
->hced_headp
) &
1133 Set_ED(polled_pp
->pp_ept
->hced_headp
,
1134 Get_ED(polled_pp
->pp_ept
->hced_headp
) |
1140 * Check whether Halt bit is set in the ED and if so clear the
1143 if (polled_pp
->pp_ept
->hced_headp
& HC_EPT_Halt
) {
1145 /* Clear the halt bit */
1146 Set_ED(polled_pp
->pp_ept
->hced_headp
,
1147 (Get_ED(polled_pp
->pp_ept
->hced_headp
) & ~HC_EPT_Halt
));
1151 * Now, add the endpoint to the lattice that we will hang our
1152 * TD's off of. We need to poll this device at every 8 ms and
1153 * hence add this ED needs 4 entries in interrupt lattice.
1155 for (i
= (ohcip
->ohci_polled_enter_count
-1); i
< NUM_INTR_ED_LISTS
;
1156 i
= i
+ MIN_LOW_SPEED_POLL_INTERVAL
) {
1157 Set_HCCA(ohcip
->ohci_hccap
->HccaIntTble
[i
],
1158 ohci_ed_cpu_to_iommu(ohcip
,
1159 ohci_polledp
->ohci_polled_ed
));
1162 * Only the first enter keyboard entry clear the contents of
1163 * periodic ED register and enable the WDH interrupt and
1164 * start process the periodic list.
1166 if (ohcip
->ohci_polled_enter_count
== 1) {
1168 * Clear the contents of current ohci periodic ED register that
1169 * is physical address of current Isochronous or Interrupt ED.
1172 Set_OpReg(hcr_periodic_curr
, (uint32_t)0x0);
1174 /* Make sure WriteDoneHead interrupt is enabled */
1175 Set_OpReg(hcr_intr_enable
, HCR_INTR_WDH
);
1178 * Enable the periodic list. We will now start processing EDs &
1181 Set_OpReg(hcr_control
,
1182 (Get_OpReg(hcr_control
) | HCR_CONTROL_PLE
));
1184 _NOTE(COMPETING_THREADS_NOW
);
1189 * ohci_polled_stop_processing:
1192 ohci_polled_stop_processing(ohci_polled_t
*ohci_polledp
)
1194 ohci_state_t
*ohcip
;
1196 ohci_regs_t
*ohci_polled_regsp
;
1198 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1199 ohci_polled_regsp
= &ohcip
->ohci_polled_save_regs
;
1202 * Turn off all list processing. This will take place starting
1203 * at the next frame.
1205 Set_OpReg(hcr_control
,
1206 (ohci_polled_regsp
->hcr_control
) & ~(HCR_CONTROL_CLE
|
1207 HCR_CONTROL_PLE
| HCR_CONTROL_BLE
|HCR_CONTROL_IE
));
1210 * Make sure that the SOF interrupt bit is cleared in the ohci
1211 * interrupt status register.
1213 Set_OpReg(hcr_intr_status
, HCR_INTR_SOF
);
1215 /* Enable SOF interrupt */
1216 Set_OpReg(hcr_intr_enable
, HCR_INTR_SOF
);
1219 * According to OHCI Specification, we have to wait for eight
1220 * start of frames to make sure that the Host Controller writes
1221 * contents of done head register to done head filed of HCCA.
1223 for (count
= 0; count
<= DONE_QUEUE_INTR_COUNTER
; count
++) {
1224 while (!((Get_OpReg(hcr_intr_status
)) & HCR_INTR_SOF
)) {
1228 /* Acknowledge the SOF interrupt */
1229 ohci_polled_finish_interrupt(ohcip
, HCR_INTR_SOF
);
1232 Set_OpReg(hcr_intr_disable
, HCR_INTR_SOF
);
1237 * Polled restore state routines
1241 * ohci_polled_restore_state:
1244 ohci_polled_restore_state(ohci_polled_t
*ohci_polledp
)
1246 ohci_state_t
*ohcip
;
1248 uint_t polled_toggle
;
1250 ohci_pipe_private_t
*pp
= NULL
; /* Normal mode Pipe */
1251 ohci_pipe_private_t
*polled_pp
; /* Polled mode Pipe */
1253 ohci_td_t
*next_td
; /* TD pointers */
1255 ohci_save_intr_sts_t
*ohci_intr_sts
;
1256 ohci_regs_t
*ohci_polled_regsp
;
1258 usba_pipe_handle_data_t
*ph
;
1261 _NOTE(NO_COMPETING_THREADS_NOW
);
1264 * If this flag is set, then we are still using this structure,
1265 * so don't restore any controller state information yet.
1267 if (ohci_polledp
->ohci_polled_flags
& POLLED_INPUT_MODE_INUSE
) {
1269 _NOTE(COMPETING_THREADS_NOW
);
1274 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1275 ohci_intr_sts
= &ohcip
->ohci_save_intr_sts
;
1276 ohci_polled_regsp
= &ohcip
->ohci_polled_save_regs
;
1277 ohcip
->ohci_polled_enter_count
--;
1279 /* Get the endpoint addr. */
1280 ep_addr
= ohci_polledp
->ohci_polled_ep_addr
;
1281 /* Get the normal mode usb pipe handle */
1282 ph
= usba_hcdi_get_ph_data(ohci_polledp
->ohci_polled_usb_dev
, ep_addr
);
1285 * Only the first leave keyboard entry turn off all list processing.
1286 * This will take place starting at the next frame.
1288 if (Get_OpReg(hcr_control
) & HCR_CONTROL_PLE
) {
1289 Set_OpReg(hcr_control
,
1290 (Get_OpReg(hcr_control
) & ~HCR_CONTROL_PLE
));
1294 * Only the last leave keyboard entry restore the info for
1297 if (ohcip
->ohci_polled_enter_count
== 0) {
1298 Set_OpReg(hcr_intr_enable
, HCR_INTR_SOF
);
1301 * According to OHCI Specification, we have to wait for eight
1302 * start of frames to make sure that the Host Controller writes
1303 * contents of done head register to done head filed of HCCA.
1305 for (count
= 0; count
<= DONE_QUEUE_INTR_COUNTER
; count
++) {
1306 while (!((Get_OpReg(hcr_intr_status
)) & HCR_INTR_SOF
)) {
1309 /* Acknowledge the SOF interrupt */
1310 ohci_polled_finish_interrupt(ohcip
, HCR_INTR_SOF
);
1314 * Check any Frame Number Overflow interrupt (FNO) is pending.
1316 ohci_polled_handle_frame_number_overflow(ohcip
);
1319 * Before switching back, we have to process last TD in the
1320 * POLLED mode. It may be in the hcr_done_head register or
1321 * in done list or in the lattice. If it is either on the
1322 * hcr_done_head register or in the done list, just re-inserted
1323 * into the ED's TD list.
1325 * First look up at the TD's that are in the hcr_done_head
1326 * register and re-insert them back into the ED's TD list.
1328 td
= ohci_td_iommu_to_cpu(ohcip
,
1329 (uintptr_t)Get_OpReg(hcr_done_head
));
1333 next_td
= ohci_td_iommu_to_cpu(ohcip
,
1334 Get_TD(td
->hctd_next_td
));
1337 * Insert valid interrupt TD back into ED's
1338 * TD list. No periodic TD's will be processed
1339 * since all processing has been stopped.
1341 ohci_polled_insert_td(ohcip
, td
);
1347 * Now look up at the TD's that are in the HCCA done head list &
1348 * re-insert them back into the ED's TD list.
1350 td
= ohci_td_iommu_to_cpu(ohcip
, (Get_HCCA(
1351 ohcip
->ohci_hccap
->HccaDoneHead
) & HCCA_DONE_HEAD_MASK
));
1355 next_td
= ohci_td_iommu_to_cpu(ohcip
,
1356 Get_TD(td
->hctd_next_td
));
1359 * Insert valid interrupt TD back into ED's
1360 * TD list. No periodic TD's will be processed
1361 * since all processing has been stopped.
1363 ohci_polled_insert_td(ohcip
, td
);
1367 /* Reset the HCCA done head list to NULL */
1368 Set_HCCA(ohcip
->ohci_hccap
->HccaDoneHead
, 0);
1371 * Replace the hcr_done_head register field with the saved copy
1372 * of current normal mode hcr_done_head register contents.
1374 Set_OpReg(hcr_done_head
,
1375 (uint32_t)ohci_polled_regsp
->hcr_done_head
);
1378 * Clear the WriteDoneHead and SOF interrupt bits in the ohci
1379 * interrupt status register.
1381 Set_OpReg(hcr_intr_status
, (HCR_INTR_WDH
| HCR_INTR_SOF
));
1384 /* Get the polled mode ohci pipe private structure */
1385 polled_pp
= (ohci_pipe_private_t
*)
1386 ohci_polledp
->ohci_polled_input_pipe_handle
->p_hcd_private
;
1389 * Before replacing the lattice, adjust the data togggle
1390 * on the on the ohci's interrupt ed
1392 polled_toggle
= (Get_ED(polled_pp
->pp_ept
->hced_headp
) &
1393 HC_EPT_Carry
) ? DATA1
:DATA0
;
1396 * If normal mode interrupt pipe endpoint is active, fix the
1397 * data toggle for this interrupt endpoint by getting the data
1398 * toggle information from the polled interrupt endpoint. Else
1399 * save the data toggle information in usb device structure.
1402 /* Get the normal mode ohci pipe private structure */
1403 pp
= (ohci_pipe_private_t
*)ph
->p_hcd_private
;
1405 real_toggle
= (Get_ED(pp
->pp_ept
->hced_headp
) &
1406 HC_EPT_Carry
) ? DATA1
:DATA0
;
1408 if (polled_toggle
!= real_toggle
) {
1409 if (polled_toggle
== DATA0
) {
1410 Set_ED(pp
->pp_ept
->hced_headp
,
1411 Get_ED(pp
->pp_ept
->hced_headp
) &
1414 Set_ED(pp
->pp_ept
->hced_headp
,
1415 Get_ED(pp
->pp_ept
->hced_headp
) |
1420 usba_hcdi_set_data_toggle(ohci_polledp
->ohci_polled_usb_dev
,
1421 ep_addr
, polled_toggle
);
1424 * Only the last leave keyboard entry restore the Interrupt table,
1425 * start processing and enable the interrupt.
1427 if (ohcip
->ohci_polled_enter_count
== 0) {
1428 /* Replace the lattice */
1429 for (i
= 0; i
< NUM_INTR_ED_LISTS
; i
++) {
1430 Set_HCCA(ohcip
->ohci_hccap
->HccaIntTble
[i
],
1431 (uintptr_t)ohcip
->ohci_polled_save_IntTble
[i
]);
1435 * Clear the contents of current ohci periodic ED register that
1436 * is physical address of current Isochronous or Interrupt ED.
1438 Set_OpReg(hcr_periodic_curr
, (uint32_t)0x0);
1440 ohci_polled_start_processing(ohci_polledp
);
1443 * Check and enable required ohci interrupts before switching
1444 * back to normal mode from the POLLED mode.
1446 mask
= (uint32_t)ohci_polled_regsp
->hcr_intr_enable
&
1447 (HCR_INTR_SOF
| HCR_INTR_WDH
);
1449 if (ohci_intr_sts
->ohci_intr_flag
& OHCI_INTR_HANDLING
) {
1450 Set_OpReg(hcr_intr_enable
, mask
);
1452 Set_OpReg(hcr_intr_enable
, mask
| HCR_INTR_MIE
);
1455 _NOTE(COMPETING_THREADS_NOW
);
1459 * ohci_polled_start_processing:
1462 ohci_polled_start_processing(ohci_polled_t
*ohci_polledp
)
1464 ohci_state_t
*ohcip
;
1467 ohci_regs_t
*ohci_polled_regsp
;
1469 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1470 ohci_polled_regsp
= &ohcip
->ohci_polled_save_regs
;
1472 mask
= ((uint32_t)ohci_polled_regsp
->hcr_control
) & (HCR_CONTROL_CLE
|
1473 HCR_CONTROL_PLE
| HCR_CONTROL_BLE
| HCR_CONTROL_IE
);
1475 control
= Get_OpReg(hcr_control
) & ~(HCR_CONTROL_CLE
|
1476 HCR_CONTROL_PLE
| HCR_CONTROL_BLE
| HCR_CONTROL_IE
);
1478 Set_OpReg(hcr_control
, (control
| mask
));
1483 * Polled read routines
1486 * ohci_polled_check_done_list:
1488 * Check to see it there are any TD's on the done head. If there are
1489 * then reverse the done list and put the TD's on the appropriated list.
1492 ohci_polled_check_done_list(ohci_polled_t
*ohci_polledp
)
1494 ohci_state_t
*ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1495 ohci_td_t
*done_head
, *done_list
;
1497 /* Sync HCCA area */
1498 if (ohci_polledp
->ohci_polled_no_sync_flag
== B_FALSE
) {
1502 /* Read and Save the HCCA DoneHead value */
1503 done_head
= (ohci_td_t
*)(uintptr_t)
1504 (Get_HCCA(ohcip
->ohci_hccap
->HccaDoneHead
) & HCCA_DONE_HEAD_MASK
);
1507 * Look at the Done Head and if it is NULL and ohci done list is NULL,
1508 * just return; else if ohci done list is not NULL, should check it.
1510 if (done_head
== NULL
) {
1511 if (ohcip
->ohci_polled_done_list
) {
1512 done_head
= ohcip
->ohci_polled_done_list
;
1513 ohcip
->ohci_polled_done_list
= NULL
;
1516 return (USB_FAILURE
);
1519 /* Reset the done head to NULL */
1520 Set_HCCA(ohcip
->ohci_hccap
->HccaDoneHead
, 0);
1523 /* Sync ED and TD pool */
1524 if (ohci_polledp
->ohci_polled_no_sync_flag
== B_FALSE
) {
1525 Sync_ED_TD_Pool(ohcip
);
1528 /* Pickup own tds in the done head */
1529 done_list
= ohci_polled_pickup_done_list(ohci_polledp
, done_head
);
1532 * Look at the own done list which is pickup'ed
1533 * and if it is NULL, just return.
1535 if (done_list
== NULL
) {
1537 return (USB_FAILURE
);
1539 /* Create the input done list */
1540 ohci_polled_create_input_list(ohci_polledp
, done_list
);
1542 return (USB_SUCCESS
);
1547 * ohci_polled_pickup_done_list:
1549 * Pickup the TDs of own in the Done Head List
1552 ohci_polled_pickup_done_list(
1553 ohci_polled_t
*ohci_polledp
,
1554 ohci_td_t
*done_head
)
1556 ohci_state_t
*ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1557 ohci_td_t
*create_head
= NULL
, *current_td
, *td
;
1558 ohci_trans_wrapper_t
*tw
;
1559 ohci_pipe_private_t
*pp
;
1562 * Current_td pointers point to the done head.
1564 current_td
= (ohci_td_t
*)
1565 ohci_td_iommu_to_cpu(ohcip
, (uintptr_t)done_head
);
1566 while (current_td
) {
1567 td
= (ohci_td_t
*)ohci_td_iommu_to_cpu(ohcip
,
1568 Get_TD(current_td
->hctd_next_td
));
1570 Set_TD(current_td
->hctd_next_td
, NULL
);
1572 /* Obtain the transfer wrapper from the TD */
1573 tw
= (ohci_trans_wrapper_t
*)OHCI_LOOKUP_ID(
1574 (uint32_t)Get_TD(current_td
->hctd_trans_wrapper
));
1576 /* Get the pipe handle for this transfer wrapper. */
1577 pp
= tw
->tw_pipe_private
;
1580 * Figure out which done list to put this TD on and put it
1581 * there. If the pipe handle of the TD matches the pipe
1582 * handle we are using for the input device, then this must
1583 * be an input TD, reverse the order and link to the list for
1584 * this input device. Else put the TD to the reserve done list
1585 * for other input devices.
1588 if (pp
->pp_pipe_handle
==
1589 ohci_polledp
->ohci_polled_input_pipe_handle
) {
1590 if (create_head
== NULL
) {
1591 create_head
= current_td
;
1593 Set_TD(current_td
->hctd_next_td
,
1594 ohci_td_cpu_to_iommu(ohcip
, create_head
));
1595 create_head
= current_td
;
1598 if (ohcip
->ohci_polled_done_list
== NULL
) {
1599 ohcip
->ohci_polled_done_list
= (ohci_td_t
*)
1600 (uintptr_t)ohci_td_cpu_to_iommu(ohcip
,
1603 Set_TD(current_td
->hctd_next_td
,
1604 ohcip
->ohci_polled_done_list
);
1605 ohcip
->ohci_polled_done_list
= (ohci_td_t
*)
1606 (uintptr_t)ohci_td_cpu_to_iommu(ohcip
,
1613 return (create_head
);
1618 * ohci_polled_create_input_list:
1620 * Create the input done list from the actual done head list.
1623 ohci_polled_create_input_list(
1624 ohci_polled_t
*ohci_polledp
,
1625 ohci_td_t
*head_done_list
)
1627 ohci_state_t
*ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1628 ohci_td_t
*cpu_save
, *td
;
1630 ASSERT(head_done_list
!= NULL
);
1632 /* Get the done head list */
1633 td
= (ohci_td_t
*)head_done_list
;
1636 * Traverse the done list and create the input done list.
1641 * Convert the iommu pointer to a cpu pointer. No point
1642 * in doing this over and over, might as well do it once.
1644 cpu_save
= ohci_td_iommu_to_cpu(ohcip
,
1645 Get_TD(td
->hctd_next_td
));
1648 * Terminate this TD by setting its next pointer to NULL.
1650 Set_TD(td
->hctd_next_td
, NULL
);
1652 /* This is an input TD, so put it on the input done list */
1653 if (ohci_polledp
->ohci_polled_input_done_head
== NULL
) {
1656 * There is nothing on the input done list,
1657 * so put this TD on the head.
1659 ohci_polledp
->ohci_polled_input_done_head
= td
;
1661 Set_TD(ohci_polledp
->
1662 ohci_polled_input_done_tail
->hctd_next_td
,
1663 ohci_td_cpu_to_iommu(ohcip
, td
));
1666 /* The tail points to the new TD */
1667 ohci_polledp
->ohci_polled_input_done_tail
= td
;
1674 * ohci_polled_process_input_list:
1676 * This routine takes the TD's off of the input done head and processes
1677 * them. It returns the number of characters that have been copied for
1681 ohci_polled_process_input_list(ohci_polled_t
*ohci_polledp
)
1683 ohci_state_t
*ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1684 ohci_td_t
*td
, *next_td
;
1686 uint_t num_characters
;
1687 ohci_trans_wrapper_t
*tw
;
1688 ohci_pipe_private_t
*pp
;
1692 * Get the first TD on the input done head.
1694 td
= ohci_polledp
->ohci_polled_input_done_head
;
1696 ohci_polledp
->ohci_polled_input_done_head
= NULL
;
1701 * Traverse the list of transfer descriptors. We can't destroy
1702 * hctd_next_td pointers of these TDs because we are using it
1703 * to traverse the done list. Therefore, we can not put these
1704 * TDs back on the ED until we are done processing all of them.
1708 /* Get the next TD from the input done list */
1709 next_td
= (ohci_td_t
*)
1710 ohci_td_iommu_to_cpu(ohcip
, Get_TD(td
->hctd_next_td
));
1712 /* Look at the status */
1713 ctrl
= (uint_t
)Get_TD(td
->hctd_ctrl
) & (uint32_t)HC_TD_CC
;
1716 * Check to see if there is an error. If there is error
1717 * clear the halt condition in the Endpoint Descriptor
1718 * (ED) associated with this Transfer Descriptor (TD).
1720 if (ctrl
!= HC_TD_CC_NO_E
) {
1721 /* Obtain the transfer wrapper from the TD */
1722 tw
= (ohci_trans_wrapper_t
*)OHCI_LOOKUP_ID(
1723 (uint32_t)Get_TD(td
->hctd_trans_wrapper
));
1725 /* Get the pipe handle for this transfer wrapper */
1726 pp
= tw
->tw_pipe_private
;
1728 /* Clear the halt bit */
1729 Set_ED(pp
->pp_ept
->hced_headp
,
1730 (Get_ED(pp
->pp_ept
->hced_headp
) & ~HC_EPT_Halt
));
1733 /* Obtain the transfer wrapper from the TD */
1734 tw
= (ohci_trans_wrapper_t
*)OHCI_LOOKUP_ID(
1735 (uint32_t)Get_TD(td
->hctd_trans_wrapper
));
1737 /* Get the pipe direction for this transfer wrapper */
1738 pipe_dir
= tw
->tw_pipe_private
->pp_pipe_handle
->
1739 p_ep
.bEndpointAddress
& USB_EP_DIR_MASK
;
1744 ohci_polled_handle_normal_td(ohci_polledp
,
1748 * Insert this TD back
1749 * onto the ED's TD list
1751 ohci_polled_insert_td(ohcip
, td
);
1753 case USB_EP_DIR_OUT
:
1754 ASSERT((ohci_td_t
*)tw
->tw_hctd_head
== td
);
1756 tw
->tw_hctd_head
= (ohci_td_t
*)
1757 ohci_td_iommu_to_cpu(ohcip
,
1758 Get_TD(td
->hctd_tw_next_td
));
1759 Set_TD(td
->hctd_state
, HC_TD_DUMMY
);
1761 if (tw
->tw_hctd_head
== NULL
) {
1762 tw
->tw_hctd_tail
= NULL
;
1765 if (tw
->tw_hctd_free_list
!= NULL
) {
1767 td_addr
= ohci_td_cpu_to_iommu(ohcip
,
1768 tw
->tw_hctd_free_list
);
1769 Set_TD(td
->hctd_tw_next_td
, td_addr
);
1770 tw
->tw_hctd_free_list
= td
;
1772 tw
->tw_hctd_free_list
= td
;
1773 Set_TD(td
->hctd_tw_next_td
, NULL
);
1781 return (num_characters
);
1786 * ohci_polled_handle_normal_td:
1789 ohci_polled_handle_normal_td(
1790 ohci_polled_t
*ohci_polledp
,
1793 ohci_state_t
*ohcip
= ohci_polledp
->ohci_polled_ohcip
;
1795 ohci_trans_wrapper_t
*tw
;
1796 size_t length
, residue
;
1798 /* Obtain the transfer wrapper from the TD */
1799 tw
= (ohci_trans_wrapper_t
*)OHCI_LOOKUP_ID((uint32_t)
1800 Get_TD(td
->hctd_trans_wrapper
));
1804 buf
= (uchar_t
*)tw
->tw_buf
;
1806 length
= tw
->tw_length
;
1808 * If "CurrentBufferPointer" of Transfer Descriptor (TD) is
1809 * not equal to zero, then we received less data from the
1810 * device than requested by us. In that case, get the actual
1811 * received data size.
1813 if (Get_TD(td
->hctd_cbp
)) {
1815 residue
= ohci_get_td_residue(ohcip
, td
);
1816 length
= Get_TD(td
->hctd_xfer_offs
) +
1817 Get_TD(td
->hctd_xfer_len
) - residue
;
1820 /* Sync IO buffer */
1821 if (ohci_polledp
->ohci_polled_no_sync_flag
== B_FALSE
) {
1822 Sync_IO_Buffer(tw
->tw_dmahandle
, length
);
1825 /* Copy the data into the message */
1826 ddi_rep_get8(tw
->tw_accesshandle
,
1827 (uint8_t *)ohci_polledp
->ohci_polled_buf
,
1828 (uint8_t *)buf
, length
, DDI_DEV_AUTOINCR
);
1830 return ((int)length
);
1835 * ohci_polled_insert_td:
1837 * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED).
1840 ohci_polled_insert_td(
1841 ohci_state_t
*ohcip
,
1844 ohci_pipe_private_t
*pp
;
1847 ohci_trans_wrapper_t
*tw
;
1848 ohci_td_t
*cpu_current_dummy
;
1849 usb_intr_req_t
*intr_req
;
1850 usba_pipe_handle_data_t
*ph
;
1853 /* Obtain the transfer wrapper from the TD */
1854 tw
= (ohci_trans_wrapper_t
*)OHCI_LOOKUP_ID(
1855 (uint32_t)Get_TD(td
->hctd_trans_wrapper
));
1857 /* Ensure the DMA cookie is valid for reuse */
1858 ASSERT((tw
->tw_cookie_idx
== 0) && (tw
->tw_dma_offs
== 0));
1861 * Take this TD off the transfer wrapper's list since
1862 * the pipe is FIFO, this must be the first TD on the
1865 ASSERT((ohci_td_t
*)tw
->tw_hctd_head
== td
);
1867 tw
->tw_hctd_head
= (ohci_td_t
*)
1868 ohci_td_iommu_to_cpu(ohcip
, Get_TD(td
->hctd_tw_next_td
));
1871 * If the head becomes NULL, then there are no more
1872 * active TD's for this transfer wrapper. Also set
1875 if (tw
->tw_hctd_head
== NULL
) {
1876 tw
->tw_hctd_tail
= NULL
;
1879 /* Convert current valid TD as new dummy TD */
1880 bzero((char *)td
, sizeof (ohci_td_t
));
1881 Set_TD(td
->hctd_state
, HC_TD_DUMMY
);
1883 pp
= tw
->tw_pipe_private
;
1884 ph
= pp
->pp_pipe_handle
;
1886 /* Obtain the endpoint and the request */
1889 /* Get the pipe attribute */
1890 pipe_attr
= ph
->p_ep
.bmAttributes
& USB_EP_ATTR_MASK
;
1892 switch (pipe_attr
) {
1893 case USB_EP_ATTR_INTR
:
1894 intr_req
= (usb_intr_req_t
*)tw
->tw_curr_xfer_reqp
;
1896 if (intr_req
->intr_attributes
& USB_ATTRS_SHORT_XFER_OK
) {
1897 td_control
= HC_TD_IN
|HC_TD_1I
|HC_TD_R
;
1899 td_control
= HC_TD_IN
|HC_TD_1I
;
1902 case USB_EP_ATTR_BULK
:
1903 td_control
= tw
->tw_direction
|HC_TD_DT_0
|HC_TD_1I
|HC_TD_R
;
1907 /* Get the current dummy */
1908 cpu_current_dummy
= (ohci_td_t
*)
1909 (ohci_td_iommu_to_cpu(ohcip
, Get_ED(ept
->hced_tailp
)));
1912 * Fill in the current dummy td and
1913 * add the new dummy to the end.
1915 ohci_polled_fill_in_td(ohcip
, cpu_current_dummy
, td
,
1916 td_control
, 0, tw
->tw_length
, tw
);
1918 /* Insert this td onto the tw */
1919 ohci_polled_insert_td_on_tw(ohcip
, tw
, cpu_current_dummy
);
1922 * Add the new dummy to the ED's list. When this occurs,
1923 * the Host Controller will see the newly filled in dummy
1926 Set_ED(ept
->hced_tailp
, (ohci_td_cpu_to_iommu(ohcip
, td
)));
1931 * ohci_polled_fill_in_td:
1933 * Fill in the fields of a Transfer Descriptor (TD).
1936 ohci_polled_fill_in_td(
1937 ohci_state_t
*ohcip
,
1939 ohci_td_t
*new_dummy
,
1941 uint32_t hctd_dma_offs
,
1943 ohci_trans_wrapper_t
*tw
)
1945 /* Assert that the td to be filled in is a dummy */
1946 ASSERT(Get_TD(td
->hctd_state
) == HC_TD_DUMMY
);
1949 bzero((char *)td
, sizeof (ohci_td_t
));
1951 /* Update the dummy with control information */
1952 Set_TD(td
->hctd_ctrl
, (hctd_ctrl
| HC_TD_CC_NA
));
1954 /* Update the beginning and end of the buffer */
1955 ohci_init_td(ohcip
, tw
, hctd_dma_offs
, hctd_length
, td
);
1957 /* The current dummy now points to the new dummy */
1958 Set_TD(td
->hctd_next_td
, (ohci_td_cpu_to_iommu(ohcip
, new_dummy
)));
1960 /* Fill in the wrapper portion of the TD */
1961 Set_TD(td
->hctd_trans_wrapper
, (uint32_t)tw
->tw_id
);
1962 Set_TD(td
->hctd_tw_next_td
, NULL
);
1967 * ohci_polled_insert_td_on_tw:
1969 * The transfer wrapper keeps a list of all Transfer Descriptors (TD) that
1970 * are allocated for this transfer. Insert a TD onto this list. The list
1971 * of TD's does not include the dummy TD that is at the end of the list of
1972 * TD's for the endpoint.
1975 ohci_polled_insert_td_on_tw(
1976 ohci_state_t
*ohcip
,
1977 ohci_trans_wrapper_t
*tw
,
1982 * Set the next pointer to NULL because
1983 * this is the last TD on list.
1985 Set_TD(td
->hctd_tw_next_td
, NULL
);
1987 if (tw
->tw_hctd_head
== NULL
) {
1988 ASSERT(tw
->tw_hctd_tail
== NULL
);
1989 tw
->tw_hctd_head
= td
;
1990 tw
->tw_hctd_tail
= td
;
1992 ohci_td_t
*dummy
= (ohci_td_t
*)tw
->tw_hctd_tail
;
1994 ASSERT(dummy
!= NULL
);
1995 ASSERT(dummy
!= td
);
1996 ASSERT(Get_TD(td
->hctd_state
) == HC_TD_DUMMY
);
1998 /* Add the td to the end of the list */
1999 Set_TD(dummy
->hctd_tw_next_td
, ohci_td_cpu_to_iommu(ohcip
, td
));
2000 tw
->tw_hctd_tail
= td
;
2002 ASSERT(Get_TD(td
->hctd_tw_next_td
) == 0);
2008 * ohci_polled_handle_frame_number_overflow:
2010 * Process Frame Number Overflow (FNO) interrupt in polled mode.
2013 ohci_polled_handle_frame_number_overflow(ohci_state_t
*ohcip
)
2017 /* Read the Interrupt Status & Interrupt enable register */
2018 intr
= (Get_OpReg(hcr_intr_status
) & Get_OpReg(hcr_intr_enable
));
2021 * Check whether any Frame Number Overflow interrupt is pending
2022 * and if it is pending, process this interrupt.
2024 if (intr
& HCR_INTR_FNO
) {
2025 ohci_handle_frame_number_overflow(ohcip
);
2027 /* Acknowledge the FNO interrupt */
2028 ohci_polled_finish_interrupt(ohcip
, HCR_INTR_FNO
);
2034 * ohci_polled_finish_interrupt:
2037 ohci_polled_finish_interrupt(
2038 ohci_state_t
*ohcip
,
2041 /* Acknowledge the interrupt */
2042 Set_OpReg(hcr_intr_status
, intr
);
2045 * Read interrupt status register to make sure that any PIO
2046 * store to clear the ISR has made it on the PCI bus before
2047 * returning from its interrupt handler.
2049 (void) Get_OpReg(hcr_intr_status
);
2054 * ohci_polled_buikin_start:
2055 * Insert bulkin td into endpoint's td list.
2058 ohci_polled_insert_bulk_td(
2059 ohci_polled_t
*ohci_polledp
)
2061 ohci_state_t
*ohcip
;
2062 ohci_trans_wrapper_t
*tw
;
2063 ohci_pipe_private_t
*pp
;
2064 usba_pipe_handle_data_t
*ph
;
2066 uint_t bulk_pkg_size
;
2068 ohcip
= ohci_polledp
->ohci_polled_ohcip
;
2069 ph
= ohci_polledp
->ohci_polled_input_pipe_handle
;
2070 pp
= (ohci_pipe_private_t
*)ph
->p_hcd_private
;
2072 tw
= pp
->pp_tw_head
;
2075 ctrl
= tw
->tw_direction
| HC_TD_DT_0
| HC_TD_1I
| HC_TD_R
;
2076 bulk_pkg_size
= min(POLLED_RAW_BUF_SIZE
, OHCI_MAX_TD_XFER_SIZE
);
2078 (void) ohci_polled_insert_hc_td(ohcip
, ctrl
, 0, bulk_pkg_size
, pp
, tw
);
2083 * ohci_polled_create_tw:
2084 * Create the transfer wrapper used in polled mode.
2087 ohci_polled_create_tw(
2088 ohci_state_t
*ohcip
,
2089 usba_pipe_handle_data_t
*ph
,
2090 usb_flags_t usb_flags
)
2093 ohci_trans_wrapper_t
*tw
;
2094 ddi_device_acc_attr_t dev_attr
;
2095 ddi_dma_attr_t dma_attr
;
2096 ohci_pipe_private_t
*pp
;
2097 int result
, pipe_dir
, td_count
;
2100 pp
= (ohci_pipe_private_t
*)ph
->p_hcd_private
;
2101 td_count
= (POLLED_RAW_BUF_SIZE
- 1) / OHCI_MAX_TD_XFER_SIZE
+ 1;
2103 if ((tw
= kmem_zalloc(sizeof (ohci_trans_wrapper_t
),
2104 KM_NOSLEEP
)) == NULL
) {
2105 return (USB_FAILURE
);
2108 /* allow sg lists for transfer wrapper dma memory */
2109 bcopy(&ohcip
->ohci_dma_attr
, &dma_attr
, sizeof (ddi_dma_attr_t
));
2110 dma_attr
.dma_attr_sgllen
= OHCI_DMA_ATTR_TW_SGLLEN
;
2111 dma_attr
.dma_attr_align
= OHCI_DMA_ATTR_ALIGNMENT
;
2113 /* Allocate the DMA handle */
2114 if ((result
= ddi_dma_alloc_handle(ohcip
->ohci_dip
,
2115 &dma_attr
, DDI_DMA_DONTWAIT
, 0, &tw
->tw_dmahandle
)) !=
2117 kmem_free(tw
, sizeof (ohci_trans_wrapper_t
));
2119 return (USB_FAILURE
);
2122 dev_attr
.devacc_attr_version
= DDI_DEVICE_ATTR_V0
;
2123 dev_attr
.devacc_attr_endian_flags
= DDI_STRUCTURE_LE_ACC
;
2124 dev_attr
.devacc_attr_dataorder
= DDI_STRICTORDER_ACC
;
2126 /* Allocate the memory */
2127 if ((result
= ddi_dma_mem_alloc(tw
->tw_dmahandle
, POLLED_RAW_BUF_SIZE
,
2128 &dev_attr
, DDI_DMA_CONSISTENT
, DDI_DMA_DONTWAIT
, NULL
,
2129 &tw
->tw_buf
, &real_length
, &tw
->tw_accesshandle
)) !=
2131 ddi_dma_free_handle(&tw
->tw_dmahandle
);
2132 kmem_free(tw
, sizeof (ohci_trans_wrapper_t
));
2134 return (USB_FAILURE
);
2137 /* Bind the handle */
2138 if ((result
= ddi_dma_addr_bind_handle(tw
->tw_dmahandle
, NULL
,
2139 tw
->tw_buf
, real_length
, DDI_DMA_RDWR
|DDI_DMA_CONSISTENT
,
2140 DDI_DMA_DONTWAIT
, NULL
, &tw
->tw_cookie
, &ccount
)) !=
2142 ddi_dma_mem_free(&tw
->tw_accesshandle
);
2143 ddi_dma_free_handle(&tw
->tw_dmahandle
);
2144 kmem_free(tw
, sizeof (ohci_trans_wrapper_t
));
2146 return (USB_FAILURE
);
2149 /* The cookie count should be 1 */
2151 result
= ddi_dma_unbind_handle(tw
->tw_dmahandle
);
2152 ASSERT(result
== DDI_SUCCESS
);
2154 ddi_dma_mem_free(&tw
->tw_accesshandle
);
2155 ddi_dma_free_handle(&tw
->tw_dmahandle
);
2156 kmem_free(tw
, sizeof (ohci_trans_wrapper_t
));
2158 return (USB_FAILURE
);
2161 if (ohci_allocate_tds_for_tw(ohcip
, tw
, td_count
) == USB_SUCCESS
) {
2162 tw
->tw_num_tds
= td_count
;
2164 ohci_deallocate_tw_resources(ohcip
, pp
, tw
);
2165 return (USB_FAILURE
);
2167 tw
->tw_cookie_idx
= 0;
2168 tw
->tw_dma_offs
= 0;
2171 * Only allow one wrapper to be added at a time. Insert the
2172 * new transaction wrapper into the list for this pipe.
2174 if (pp
->pp_tw_head
== NULL
) {
2175 pp
->pp_tw_head
= tw
;
2176 pp
->pp_tw_tail
= tw
;
2178 pp
->pp_tw_tail
->tw_next
= tw
;
2179 pp
->pp_tw_tail
= tw
;
2182 /* Store the transfer length */
2183 tw
->tw_length
= POLLED_RAW_BUF_SIZE
;
2185 /* Store a back pointer to the pipe private structure */
2186 tw
->tw_pipe_private
= pp
;
2188 /* Store the transfer type - synchronous or asynchronous */
2189 tw
->tw_flags
= usb_flags
;
2191 /* Get and Store 32bit ID */
2192 tw
->tw_id
= OHCI_GET_ID((void *)tw
);
2194 ASSERT(tw
->tw_id
!= 0);
2196 pipe_dir
= ph
->p_ep
.bEndpointAddress
& USB_EP_DIR_MASK
;
2197 tw
->tw_direction
= (pipe_dir
== USB_EP_DIR_IN
) ? HC_TD_IN
: HC_TD_OUT
;
2199 USB_DPRINTF_L4(PRINT_MASK_ALLOC
, ohcip
->ohci_log_hdl
,
2200 "ohci_create_transfer_wrapper: tw = 0x%p, ncookies = %u",
2201 (void *)tw
, tw
->tw_ncookies
);
2203 return (USB_SUCCESS
);
2208 * ohci_polled_insert_hc_td:
2210 * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED).
2213 ohci_polled_insert_hc_td(
2214 ohci_state_t
*ohcip
,
2216 uint32_t hctd_dma_offs
,
2218 ohci_pipe_private_t
*pp
,
2219 ohci_trans_wrapper_t
*tw
)
2221 ohci_td_t
*new_dummy
;
2222 ohci_td_t
*cpu_current_dummy
;
2223 ohci_ed_t
*ept
= pp
->pp_ept
;
2225 /* Retrieve preallocated td from the TW */
2226 new_dummy
= tw
->tw_hctd_free_list
;
2228 ASSERT(new_dummy
!= NULL
);
2230 tw
->tw_hctd_free_list
= ohci_td_iommu_to_cpu(ohcip
,
2231 Get_TD(new_dummy
->hctd_tw_next_td
));
2232 Set_TD(new_dummy
->hctd_tw_next_td
, NULL
);
2234 /* Fill in the current dummy */
2235 cpu_current_dummy
= (ohci_td_t
*)
2236 (ohci_td_iommu_to_cpu(ohcip
, Get_ED(ept
->hced_tailp
)));
2239 * Fill in the current dummy td and
2240 * add the new dummy to the end.
2242 ohci_polled_fill_in_td(ohcip
, cpu_current_dummy
, new_dummy
,
2243 hctd_ctrl
, hctd_dma_offs
, hctd_length
, tw
);
2246 * add the new dummy to the ED's list. When
2247 * this occurs, the Host Controller will see
2248 * the newly filled in dummy TD.
2250 Set_ED(ept
->hced_tailp
,
2251 (ohci_td_cpu_to_iommu(ohcip
, new_dummy
)));
2253 /* Insert this td onto the tw */
2254 ohci_polled_insert_td_on_tw(ohcip
, tw
, cpu_current_dummy
);
2256 return (USB_SUCCESS
);