Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / usb / hcd / openhci / ohci_polled.c
blob5fa85bd3d367cbe2b871934c7a322eba5c39438b
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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,
49 ohci_state_t *ohcip,
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,
78 ohci_td_t *td);
79 static void ohci_polled_insert_td(ohci_state_t *ohcip,
80 ohci_td_t *td);
81 static void ohci_polled_fill_in_td(ohci_state_t *ohcip,
82 ohci_td_t *td,
83 ohci_td_t *new_dummy,
84 uint_t hctd_ctrl,
85 uint32_t hctd_iommu_cbp,
86 size_t hctd_length,
87 ohci_trans_wrapper_t *tw);
88 static void ohci_polled_insert_td_on_tw(
89 ohci_state_t *ohcip,
90 ohci_trans_wrapper_t *tw,
91 ohci_td_t *td);
92 static void ohci_polled_handle_frame_number_overflow(
93 ohci_state_t *ohcip);
94 static void ohci_polled_finish_interrupt(
95 ohci_state_t *ohcip,
96 uint_t intr);
97 static void ohci_polled_insert_bulk_td(
98 ohci_polled_t *ohci_polledp);
99 static int ohci_polled_create_tw(
100 ohci_state_t *ohcip,
101 usba_pipe_handle_data_t *ph,
102 usb_flags_t usb_flags);
103 static int ohci_polled_insert_hc_td(
104 ohci_state_t *ohcip,
105 uint_t hctd_ctrl,
106 uint32_t hctd_dma_offs,
107 size_t hctd_length,
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;
130 ohci_state_t *ohcip;
131 int pipe_attr, ret;
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);
148 return (ret);
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;
201 ohci_state_t *ohcip;
202 int ret;
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);
226 return (ret);
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
235 * characters.
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)
297 ohci_state_t *ohcip;
298 ohci_polled_t *ohci_polledp;
299 uint_t intr;
300 ohci_polledp = (ohci_polled_t *)info->uci_private;
302 ohcip = ohci_polledp->ohci_polled_ohcip;
304 _NOTE(NO_COMPETING_THREADS_NOW);
305 *num_characters = 0;
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 */
323 *num_characters =
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;
356 ohci_state_t *ohcip;
357 int ret;
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);
374 return (ret);
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;
407 ohci_state_t *ohcip;
408 int ret;
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);
428 return (ret);
433 * ohci_hcdi_polled_output_enter:
435 * everything is done in input enter
437 /*ARGSUSED*/
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
450 /*ARGSUSED*/
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)
466 ohci_state_t *ohcip;
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;
471 uint32_t ctrl;
472 uint_t intr, bulk_pkg_size;
473 int i;
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;
494 tw = pp->pp_tw_head;
496 ASSERT(tw != NULL);
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 */
526 for (;;) {
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) ==
536 USB_SUCCESS) {
537 *num_characters_written =
538 ohci_polled_process_input_list(
539 ohci_polledp);
540 break;
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);
564 * Internal Functions
568 * Polled initialization routines
573 * ohci_polled_init:
575 * Initialize generic information Uthat is needed to provide USB/POLLED
576 * support.
578 static int
579 ohci_polled_init(
580 usba_pipe_handle_data_t *ph,
581 ohci_state_t *ohcip,
582 usb_console_info_impl_t *console_info)
584 ohci_polled_t *ohci_polledp;
585 ohci_pipe_private_t *pp;
586 int pipe_attr;
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
615 * pipe handle.
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.
632 bcopy((void *)ph,
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
648 * just allocated.
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
660 * satisfy warlock.
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;
708 switch (pipe_attr) {
709 case USB_EP_ATTR_INTR:
711 * Set soft interrupt handler flag in the normal mode usb
712 * pipe handle.
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
723 * this new one.
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);
730 break;
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);
737 break;
738 default:
739 return (USB_FAILURE);
741 return (USB_SUCCESS);
746 * Polled deinitialization routines
751 * ohci_polled_fini:
753 static int
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
790 * pipe.
792 next_tw = pp->pp_tw_head;
794 while (next_tw) {
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.
801 while (next_td) {
802 curr_td = next_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);
810 curr_tw = next_tw;
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
848 * of all this.
850 kmem_free(ohci_polledp, sizeof (ohci_polled_t));
852 return (USB_SUCCESS);
857 * Polled save state routines
862 * ohci_polled_save_state:
864 static void
865 ohci_polled_save_state(ohci_polled_t *ohci_polledp)
867 ohci_state_t *ohcip;
868 int i;
869 uint_t polled_toggle;
870 uint_t real_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;
874 uint8_t ep_addr;
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);
888 return;
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);
899 return;
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
912 * frame list table.
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.
944 * (a) Normal mode:
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
960 * missed interrupts.
962 * (b) Polled mode:
964 * - On entering the polled code, checks for the critical
965 * section code execution within normal mode interrupt
966 * handler.
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
980 * fields.
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
989 * from normal 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);
997 } else {
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
1015 * mode.
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);
1022 if ((done_head) &&
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))) {
1030 done_list =
1031 &ohci_intr_sts->ohci_critical_done_lst;
1032 ohci_intr_sts->ohci_critical_intr_sts |=
1033 HCR_INTR_WDH;
1034 } else {
1035 done_list =
1036 &ohci_intr_sts->ohci_missed_done_lst;
1037 ohci_intr_sts->ohci_missed_intr_sts |=
1038 HCR_INTR_WDH;
1041 if (*done_list) {
1042 td = (ohci_td_t *)
1043 ohci_td_iommu_to_cpu(ohcip,
1044 (uintptr_t)done_head);
1046 while (td) {
1047 prev_td = td;
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;
1055 } else {
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
1073 * status register.
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.
1116 if (ph) {
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;
1122 } else {
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) &
1131 ~HC_EPT_Carry);
1132 } else {
1133 Set_ED(polled_pp->pp_ept->hced_headp,
1134 Get_ED(polled_pp->pp_ept->hced_headp) |
1135 HC_EPT_Carry);
1140 * Check whether Halt bit is set in the ED and if so clear the
1141 * halt bit.
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 &
1179 * TDs again.
1181 Set_OpReg(hcr_control,
1182 (Get_OpReg(hcr_control) | HCR_CONTROL_PLE));
1184 _NOTE(COMPETING_THREADS_NOW);
1189 * ohci_polled_stop_processing:
1191 static void
1192 ohci_polled_stop_processing(ohci_polled_t *ohci_polledp)
1194 ohci_state_t *ohcip;
1195 uint_t count;
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)) {
1225 continue;
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:
1243 static void
1244 ohci_polled_restore_state(ohci_polled_t *ohci_polledp)
1246 ohci_state_t *ohcip;
1247 int i;
1248 uint_t polled_toggle;
1249 uint_t real_toggle;
1250 ohci_pipe_private_t *pp = NULL; /* Normal mode Pipe */
1251 ohci_pipe_private_t *polled_pp; /* Polled mode Pipe */
1252 ohci_td_t *td;
1253 ohci_td_t *next_td; /* TD pointers */
1254 uint_t count;
1255 ohci_save_intr_sts_t *ohci_intr_sts;
1256 ohci_regs_t *ohci_polled_regsp;
1257 uint32_t mask;
1258 usba_pipe_handle_data_t *ph;
1259 uint8_t ep_addr;
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);
1271 return;
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
1295 * normal mode.
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)) {
1307 continue;
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));
1331 while (td) {
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);
1343 td = next_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));
1353 while (td) {
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);
1365 td = next_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.
1401 if (ph) {
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) &
1412 ~HC_EPT_Carry);
1413 } else {
1414 Set_ED(pp->pp_ept->hced_headp,
1415 Get_ED(pp->pp_ept->hced_headp) |
1416 HC_EPT_Carry);
1419 } else {
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);
1451 } else {
1452 Set_OpReg(hcr_intr_enable, mask | HCR_INTR_MIE);
1455 _NOTE(COMPETING_THREADS_NOW);
1459 * ohci_polled_start_processing:
1461 static void
1462 ohci_polled_start_processing(ohci_polled_t *ohci_polledp)
1464 ohci_state_t *ohcip;
1465 uint32_t control;
1466 uint32_t mask;
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.
1491 static int
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) {
1499 Sync_HCCA(ohcip);
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;
1514 } else {
1516 return (USB_FAILURE);
1518 } else {
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
1551 static ohci_td_t *
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;
1592 } else {
1593 Set_TD(current_td->hctd_next_td,
1594 ohci_td_cpu_to_iommu(ohcip, create_head));
1595 create_head = current_td;
1597 } else {
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,
1601 current_td);
1602 } else {
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,
1607 current_td);
1610 current_td = td;
1613 return (create_head);
1618 * ohci_polled_create_input_list:
1620 * Create the input done list from the actual done head list.
1622 static void
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.
1638 while (td) {
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;
1660 } else {
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;
1668 td = cpu_save;
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
1678 * input.
1680 static int
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;
1685 uint_t ctrl;
1686 uint_t num_characters;
1687 ohci_trans_wrapper_t *tw;
1688 ohci_pipe_private_t *pp;
1689 int pipe_dir;
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;
1698 num_characters = 0;
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.
1706 while (td) {
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;
1741 switch (pipe_dir) {
1742 case USB_EP_DIR_IN:
1743 num_characters +=
1744 ohci_polled_handle_normal_td(ohci_polledp,
1745 td);
1748 * Insert this TD back
1749 * onto the ED's TD list
1751 ohci_polled_insert_td(ohcip, td);
1752 break;
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) {
1766 uint32_t td_addr;
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;
1771 } else {
1772 tw->tw_hctd_free_list = td;
1773 Set_TD(td->hctd_tw_next_td, NULL);
1775 break;
1778 td = next_td;
1781 return (num_characters);
1786 * ohci_polled_handle_normal_td:
1788 static int
1789 ohci_polled_handle_normal_td(
1790 ohci_polled_t *ohci_polledp,
1791 ohci_td_t *td)
1793 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip;
1794 uchar_t *buf;
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));
1802 ASSERT(tw != NULL);
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).
1839 static void
1840 ohci_polled_insert_td(
1841 ohci_state_t *ohcip,
1842 ohci_td_t *td)
1844 ohci_pipe_private_t *pp;
1845 ohci_ed_t *ept;
1846 uint_t td_control;
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;
1851 int pipe_attr;
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
1863 * list.
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
1873 * the tail to NULL.
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 */
1887 ept = pp->pp_ept;
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;
1898 } else {
1899 td_control = HC_TD_IN|HC_TD_1I;
1901 break;
1902 case USB_EP_ATTR_BULK:
1903 td_control = tw->tw_direction|HC_TD_DT_0|HC_TD_1I|HC_TD_R;
1904 break;
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
1924 * TD.
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).
1935 static void
1936 ohci_polled_fill_in_td(
1937 ohci_state_t *ohcip,
1938 ohci_td_t *td,
1939 ohci_td_t *new_dummy,
1940 uint_t hctd_ctrl,
1941 uint32_t hctd_dma_offs,
1942 size_t hctd_length,
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);
1948 /* Clear the TD */
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.
1974 static void
1975 ohci_polled_insert_td_on_tw(
1976 ohci_state_t *ohcip,
1977 ohci_trans_wrapper_t *tw,
1978 ohci_td_t *td)
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;
1991 } else {
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.
2012 static void
2013 ohci_polled_handle_frame_number_overflow(ohci_state_t *ohcip)
2015 uint_t intr;
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:
2036 static void
2037 ohci_polled_finish_interrupt(
2038 ohci_state_t *ohcip,
2039 uint_t intr)
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.
2057 static void
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;
2065 uint32_t ctrl;
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;
2073 ASSERT(tw != NULL);
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.
2086 static int
2087 ohci_polled_create_tw(
2088 ohci_state_t *ohcip,
2089 usba_pipe_handle_data_t *ph,
2090 usb_flags_t usb_flags)
2092 uint_t ccount;
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;
2098 size_t real_length;
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)) !=
2116 DDI_SUCCESS) {
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)) !=
2130 DDI_SUCCESS) {
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)) !=
2141 DDI_DMA_MAPPED) {
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 */
2150 if (ccount != 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;
2163 } else {
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;
2177 } else {
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,
2215 uint_t hctd_ctrl,
2216 uint32_t hctd_dma_offs,
2217 size_t hctd_length,
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);