1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * 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.
26 */
27
28 /*
29 * Open Host Controller Driver (OHCI)
30 *
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.
35 *
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.
38 */
39 #include <sys/usb/hcd/openhci/ohcid.h>
40 #include <sys/usb/hcd/openhci/ohci_polled.h>
41
42 /*
43 * Internal Function Prototypes
44 */
45
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);
51
52 /* Polled deinitialization routines */
53 static int ohci_polled_fini(ohci_polled_t *ohci_polledp);
54
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);
59
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);
64
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);
110 /*
111 * POLLED entry points
112 *
113 * These functions are entry points into the POLLED code.
114 */
115
116 /*
117 * ohci_hcdi_polled_input_init:
118 *
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.
122 */
123 int
ohci_hcdi_polled_input_init(usba_pipe_handle_data_t * ph,uchar_t ** polled_buf,usb_console_info_impl_t * console_input_info)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)
128 {
129 ohci_polled_t *ohci_polledp;
130 ohci_state_t *ohcip;
131 int pipe_attr, ret;
132
133 ohcip = ohci_obtain_state(ph->p_usba_device->usb_root_hub_dip);
134
135 /*
136 * Grab the ohci_int_mutex so that things don't change on us
137 * if an interrupt comes in.
138 */
139 mutex_enter(&ohcip->ohci_int_mutex);
140
141 ret = ohci_polled_init(ph, ohcip, console_input_info);
142
143 if (ret != USB_SUCCESS) {
144
145 /* Allow interrupts to continue */
146 mutex_exit(&ohcip->ohci_int_mutex);
147
148 return (ret);
149 }
150
151 ohci_polledp = (ohci_polled_t *)console_input_info->uci_private;
152 /*
153 * Mark the structure so that if we are using it, we don't free
154 * the structures if one of them is unplugged.
155 */
156 ohci_polledp->ohci_polled_flags |= POLLED_INPUT_MODE;
157
158 /* increase the polled kbd counter for keyboard connected */
159 ohcip->ohci_polled_kbd_count ++;
160
161 /*
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.
164 */
165 ohci_polledp->ohci_polled_buf =
166 (uchar_t *)kmem_zalloc(POLLED_RAW_BUF_SIZE, KM_SLEEP);
167
168 *polled_buf = ohci_polledp->ohci_polled_buf;
169
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;
173
174 if (pipe_attr == USB_EP_ATTR_BULK) {
175 ohci_polled_insert_bulk_td(ohci_polledp);
176 }
177 /*
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.
181 */
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;
185 }
186
187 /* Allow interrupts to continue */
188 mutex_exit(&ohcip->ohci_int_mutex);
189
190 return (USB_SUCCESS);
191 }
192
193
194 /*
195 * ohci_hcdi_polled_input_fini:
196 */
197 int
ohci_hcdi_polled_input_fini(usb_console_info_impl_t * info)198 ohci_hcdi_polled_input_fini(usb_console_info_impl_t *info)
199 {
200 ohci_polled_t *ohci_polledp;
201 ohci_state_t *ohcip;
202 int ret;
203
204 ohci_polledp = (ohci_polled_t *)info->uci_private;
205
206 ohcip = ohci_polledp->ohci_polled_ohcip;
207
208 mutex_enter(&ohcip->ohci_int_mutex);
209
210 /*
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.
213 */
214 ohci_polledp->ohci_polled_flags &= ~POLLED_INPUT_MODE;
215
216 /* Decrease the polled kbd counter for keyboard disconnected */
217 ohcip->ohci_polled_kbd_count --;
218
219 /* Free the buffer that we copied data into */
220 kmem_free(ohci_polledp->ohci_polled_buf, POLLED_RAW_BUF_SIZE);
221
222 ret = ohci_polled_fini(ohci_polledp);
223
224 mutex_exit(&ohcip->ohci_int_mutex);
225
226 return (ret);
227 }
228
229
230 /*
231 * ohci_hcdi_polled_input_enter:
232 *
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.
236 */
237 int
ohci_hcdi_polled_input_enter(usb_console_info_impl_t * info)238 ohci_hcdi_polled_input_enter(usb_console_info_impl_t *info)
239 {
240 ohci_polled_t *ohci_polledp;
241
242 ohci_polledp = (ohci_polled_t *)info->uci_private;
243 ohci_polledp->ohci_polled_entry++;
244 /*
245 * If the controller is already switched over, just return
246 */
247 if (ohci_polledp->ohci_polled_entry > 1) {
248
249 return (USB_SUCCESS);
250 }
251 ohci_polled_save_state(ohci_polledp);
252
253 ohci_polledp->ohci_polled_flags |= POLLED_INPUT_MODE_INUSE;
254
255 return (USB_SUCCESS);
256 }
257
258
259 /*
260 * ohci_hcdi_polled_input_exit:
261 *
262 * This is where we exit POLLED mode. This routine restores
263 * everything that is needed to continue operation.
264 */
265 int
ohci_hcdi_polled_input_exit(usb_console_info_impl_t * info)266 ohci_hcdi_polled_input_exit(usb_console_info_impl_t *info)
267 {
268 ohci_polled_t *ohci_polledp;
269
270 ohci_polledp = (ohci_polled_t *)info->uci_private;
271
272 ohci_polledp->ohci_polled_entry--;
273
274 /*
275 * If there are still outstanding "enters", just return
276 */
277 if (ohci_polledp->ohci_polled_entry > 0)
278 return (USB_SUCCESS);
279
280 ohci_polledp->ohci_polled_flags &= ~POLLED_INPUT_MODE_INUSE;
281 ohci_polled_restore_state(ohci_polledp);
282
283 return (USB_SUCCESS);
284 }
285
286
287 /*
288 * ohci_hcdi_polled_read:
289 *
290 * Get a key character
291 */
292 int
ohci_hcdi_polled_read(usb_console_info_impl_t * info,uint_t * num_characters)293 ohci_hcdi_polled_read(
294 usb_console_info_impl_t *info,
295 uint_t *num_characters)
296 {
297 ohci_state_t *ohcip;
298 ohci_polled_t *ohci_polledp;
299 uint_t intr;
300 ohci_polledp = (ohci_polled_t *)info->uci_private;
301
302 ohcip = ohci_polledp->ohci_polled_ohcip;
303
304 #ifndef lint
305 _NOTE(NO_COMPETING_THREADS_NOW);
306 #endif
307 *num_characters = 0;
308 intr = (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable));
309
310 /*
311 * Check whether any Frame Number Overflow interrupt is pending
312 * and if it is pending, process this interrupt.
313 */
314 if (intr & HCR_INTR_FNO) {
315 ohci_handle_frame_number_overflow(ohcip);
316
317 /* Acknowledge the FNO interrupt */
318 ohci_polled_finish_interrupt(ohcip, HCR_INTR_FNO);
319 }
320
321 /* Check to see if there are any TD's for this input device */
322 if (ohci_polled_check_done_list(ohci_polledp) == USB_SUCCESS) {
323
324 /* Process any TD's on the input done list */
325 *num_characters =
326 ohci_polled_process_input_list(ohci_polledp);
327 }
328
329 /*
330 * To make sure after we get the done list from DoneHead,
331 * every input device gets its own TD's in the
332 * ohci_polled_done_list and then clear the interrupt status.
333 */
334 if (intr & HCR_INTR_WDH) {
335
336 /* Acknowledge the WDH interrupt */
337 ohci_polled_finish_interrupt(ohcip, HCR_INTR_WDH);
338 }
339 #ifndef lint
340 _NOTE(COMPETING_THREADS_NOW);
341 #endif
342
343 return (USB_SUCCESS);
344 }
345
346
347 /*
348 * ohci_hcdi_polled_output_init:
349 *
350 * This is the initialization routine for handling the USB serial output
351 * in POLLED mode. This routine is not called from POLLED mode, so
352 * it is OK to acquire mutexes.
353 */
354 int
ohci_hcdi_polled_output_init(usba_pipe_handle_data_t * ph,usb_console_info_impl_t * console_output_info)355 ohci_hcdi_polled_output_init(
356 usba_pipe_handle_data_t *ph,
357 usb_console_info_impl_t *console_output_info)
358 {
359 ohci_polled_t *ohci_polledp;
360 ohci_state_t *ohcip;
361 int ret;
362
363 ohcip = ohci_obtain_state(ph->p_usba_device->usb_root_hub_dip);
364
365 /*
366 * Grab the ohci_int_mutex so that things don't change on us
367 * if an interrupt comes in.
368 */
369 mutex_enter(&ohcip->ohci_int_mutex);
370
371 ret = ohci_polled_init(ph, ohcip, console_output_info);
372
373 if (ret != USB_SUCCESS) {
374
375 /* Allow interrupts to continue */
376 mutex_exit(&ohcip->ohci_int_mutex);
377
378 return (ret);
379 }
380
381 ohci_polledp = (ohci_polled_t *)console_output_info->uci_private;
382 /*
383 * Mark the structure so that if we are using it, we don't free
384 * the structures if one of them is unplugged.
385 */
386 ohci_polledp->ohci_polled_flags |= POLLED_OUTPUT_MODE;
387
388 /*
389 * This is a software workaround to fix schizo hardware bug.
390 * Existence of "no-prom-cdma-sync" property means consistent
391 * dma sync should not be done while in prom or polled mode.
392 */
393 if (ddi_prop_exists(DDI_DEV_T_ANY, ohcip->ohci_dip,
394 DDI_PROP_NOTPROM, "no-prom-cdma-sync")) {
395 ohci_polledp->ohci_polled_no_sync_flag = B_TRUE;
396 }
397
398 /* Allow interrupts to continue */
399 mutex_exit(&ohcip->ohci_int_mutex);
400
401 return (USB_SUCCESS);
402 }
403
404 /*
405 * ohci_hcdi_polled_output_fini:
406 */
407 int
ohci_hcdi_polled_output_fini(usb_console_info_impl_t * info)408 ohci_hcdi_polled_output_fini(usb_console_info_impl_t *info)
409 {
410 ohci_polled_t *ohci_polledp;
411 ohci_state_t *ohcip;
412 int ret;
413
414 ohci_polledp = (ohci_polled_t *)info->uci_private;
415
416 ohcip = ohci_polledp->ohci_polled_ohcip;
417
418 mutex_enter(&ohcip->ohci_int_mutex);
419
420 /*
421 * Reset the POLLED_INPUT_MODE flag so that we can tell if
422 * this structure is in use in the ohci_polled_fini routine.
423 */
424 ohci_polledp->ohci_polled_flags &= ~POLLED_OUTPUT_MODE;
425
426 ret = ohci_polled_fini(ohci_polledp);
427
428 info->uci_private = NULL;
429
430 mutex_exit(&ohcip->ohci_int_mutex);
431
432 return (ret);
433 }
434
435
436 /*
437 * ohci_hcdi_polled_output_enter:
438 *
439 * everything is done in input enter
440 */
441 /*ARGSUSED*/
442 int
ohci_hcdi_polled_output_enter(usb_console_info_impl_t * info)443 ohci_hcdi_polled_output_enter(usb_console_info_impl_t *info)
444 {
445 return (USB_SUCCESS);
446 }
447
448
449 /*
450 * ohci_hcdi_polled_output_exit:
451 *
452 * everything is done in input exit
453 */
454 /*ARGSUSED*/
455 int
ohci_hcdi_polled_output_exit(usb_console_info_impl_t * info)456 ohci_hcdi_polled_output_exit(usb_console_info_impl_t *info)
457 {
458 return (USB_SUCCESS);
459 }
460
461
462 /*
463 * ohci_hcdi_polled_write:
464 * Put a key character -- rewrite this!
465 */
466 int
ohci_hcdi_polled_write(usb_console_info_impl_t * info,uchar_t * buf,uint_t num_characters,uint_t * num_characters_written)467 ohci_hcdi_polled_write(usb_console_info_impl_t *info, uchar_t *buf,
468 uint_t num_characters, uint_t *num_characters_written)
469 {
470 ohci_state_t *ohcip;
471 ohci_polled_t *ohci_polledp;
472 ohci_trans_wrapper_t *tw;
473 ohci_pipe_private_t *pp;
474 usba_pipe_handle_data_t *ph;
475 uint32_t ctrl;
476 uint_t intr, bulk_pkg_size;
477 int i;
478
479 #ifndef lint
480 _NOTE(NO_COMPETING_THREADS_NOW);
481 #endif
482
483 ohci_polledp = (ohci_polled_t *)info->uci_private;
484 ohcip = ohci_polledp->ohci_polled_ohcip;
485
486 /* Disable periodic list processing */
487 Set_OpReg(hcr_control,
488 (Get_OpReg(hcr_control) & (~HCR_CONTROL_PLE)));
489
490 /* Add the endpoint to the lattice */
491 for (i = ohcip->ohci_polled_enter_count; i < NUM_INTR_ED_LISTS;
492 i = i + MIN_LOW_SPEED_POLL_INTERVAL) {
493 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i],
494 ohci_ed_cpu_to_iommu(ohcip,
495 ohci_polledp->ohci_polled_ed));
496 }
497
498 ph = ohci_polledp->ohci_polled_input_pipe_handle;
499 pp = (ohci_pipe_private_t *)ph->p_hcd_private;
500 tw = pp->pp_tw_head;
501
502 ASSERT(tw != NULL);
503 if (tw->tw_hctd_free_list == NULL) {
504 #ifndef lint
505 _NOTE(COMPETING_THREADS_NOW);
506 #endif
507 return (USB_SUCCESS);
508 }
509
510 /* Copy transmit buffer */
511 if (num_characters > POLLED_RAW_BUF_SIZE) {
512 cmn_err(CE_NOTE, "polled write size %d bigger than %d",
513 num_characters, POLLED_RAW_BUF_SIZE);
514 num_characters = POLLED_RAW_BUF_SIZE;
515 }
516 tw->tw_length = num_characters;
517
518 ddi_rep_put8(tw->tw_accesshandle,
519 buf, (uint8_t *)tw->tw_buf,
520 tw->tw_length, DDI_DEV_AUTOINCR);
521 Sync_IO_Buffer_for_device(tw->tw_dmahandle, tw->tw_length);
522
523 /* Insert td into endpoint's tds list */
524 ctrl = tw->tw_direction | HC_TD_DT_0|HC_TD_1I | HC_TD_R;
525 bulk_pkg_size = min(tw->tw_length, OHCI_MAX_TD_XFER_SIZE);
526
527 (void) ohci_polled_insert_hc_td(ohcip, ctrl, 0, bulk_pkg_size, pp, tw);
528
529 /* Enable periodic list processing */
530 Set_OpReg(hcr_control,
531 (Get_OpReg(hcr_control) | HCR_CONTROL_PLE));
532
533 /* Wait for bulk out tds transfer completion */
534 for (;;) {
535 intr = Get_OpReg(hcr_intr_status);
536
537 if (intr & HCR_INTR_FNO) {
538 ohci_handle_frame_number_overflow(ohcip);
539 ohci_polled_finish_interrupt(ohcip, HCR_INTR_FNO);
540 }
541
542 if (intr & HCR_INTR_WDH) {
543 if (ohci_polled_check_done_list(ohci_polledp) ==
544 USB_SUCCESS) {
545 *num_characters_written =
546 ohci_polled_process_input_list(
547 ohci_polledp);
548 break;
549 }
550 }
551
552 Set_OpReg(hcr_intr_status, intr);
553 (void) Get_OpReg(hcr_intr_status);
554 }
555
556 /* Remove the endpoint from the lattice */
557 for (i = ohcip->ohci_polled_enter_count; i < NUM_INTR_ED_LISTS;
558 i = i + MIN_LOW_SPEED_POLL_INTERVAL) {
559 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i],
560 ohci_ed_cpu_to_iommu(ohcip,
561 ohci_polledp->ohci_polled_dummy_ed));
562 }
563
564 Set_OpReg(hcr_intr_status, intr);
565 (void) Get_OpReg(hcr_intr_status);
566 #ifndef lint
567 _NOTE(COMPETING_THREADS_NOW);
568 #endif
569 return (USB_SUCCESS);
570 }
571
572
573 /*
574 * Internal Functions
575 */
576
577 /*
578 * Polled initialization routines
579 */
580
581
582 /*
583 * ohci_polled_init:
584 *
585 * Initialize generic information Uthat is needed to provide USB/POLLED
586 * support.
587 */
588 static int
ohci_polled_init(usba_pipe_handle_data_t * ph,ohci_state_t * ohcip,usb_console_info_impl_t * console_info)589 ohci_polled_init(
590 usba_pipe_handle_data_t *ph,
591 ohci_state_t *ohcip,
592 usb_console_info_impl_t *console_info)
593 {
594 ohci_polled_t *ohci_polledp;
595 ohci_pipe_private_t *pp;
596 int pipe_attr;
597
598 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
599
600 /*
601 * We have already initialized this structure. If the structure
602 * has already been initialized, then we don't need to redo it.
603 */
604 if (console_info->uci_private) {
605
606 return (USB_SUCCESS);
607 }
608
609 /* Allocate and intitialize a state structure */
610 ohci_polledp = (ohci_polled_t *)
611 kmem_zalloc(sizeof (ohci_polled_t), KM_SLEEP);
612
613 console_info->uci_private = (usb_console_info_private_t)ohci_polledp;
614
615 /*
616 * Store away the ohcip so that we can get to it when we are in
617 * POLLED mode. We don't want to have to call ohci_obtain_state
618 * every time we want to access this structure. Also save ohci
619 * polled state information in ohcip.
620 */
621 ohci_polledp->ohci_polled_ohcip = ohcip;
622
623 /*
624 * Save usb device and endpoint number information from the usb
625 * pipe handle.
626 */
627 mutex_enter(&ph->p_mutex);
628 ohci_polledp->ohci_polled_usb_dev = ph->p_usba_device;
629 ohci_polledp->ohci_polled_ep_addr = ph->p_ep.bEndpointAddress;
630 mutex_exit(&ph->p_mutex);
631
632 /*
633 * Allocate memory to make duplicate of original usb pipe handle.
634 */
635 ohci_polledp->ohci_polled_input_pipe_handle =
636 kmem_zalloc(sizeof (usba_pipe_handle_data_t), KM_SLEEP);
637
638 /*
639 * Copy the USB handle into the new pipe handle. Also
640 * create new lock for the new pipe handle.
641 */
642 bcopy((void *)ph,
643 (void *)ohci_polledp->ohci_polled_input_pipe_handle,
644 sizeof (usba_pipe_handle_data_t));
645
646 /*
647 * uint64_t typecast to make sure amd64 can compile
648 */
649 mutex_init(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex,
650 NULL, MUTEX_DRIVER, DDI_INTR_PRI(ohcip->ohci_intr_pri));
651
652 /* Create a new ohci pipe private structure */
653 pp = (ohci_pipe_private_t *)
654 kmem_zalloc(sizeof (ohci_pipe_private_t), KM_SLEEP);
655
656 /*
657 * Store the pointer in the pipe handle. This structure was also
658 * just allocated.
659 */
660 mutex_enter(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex);
661
662 ohci_polledp->ohci_polled_input_pipe_handle->
663 p_hcd_private = (usb_opaque_t)pp;
664
665 mutex_exit(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex);
666
667 /*
668 * Store a pointer to the pipe handle. This structure was just
669 * allocated and it is not in use yet. The locking is there to
670 * satisfy warlock.
671 */
672 mutex_enter(&ph->p_mutex);
673
674 bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t));
675
676 mutex_exit(&ph->p_mutex);
677
678 pp->pp_pipe_handle = ohci_polledp->ohci_polled_input_pipe_handle;
679
680 /*
681 * Allocate a dummy for the interrupt table. This dummy will be
682 * put into the action when we switch interrupt tables during
683 * ohci_hcdi_polled_enter. Dummy is placed on the unused lattice
684 * entries. When the ED is allocated we will replace dummy ED by
685 * valid interrupt ED in one or more locations in the interrupt
686 * lattice depending on the requested polling interval. Also we
687 * will hang a dummy TD to the ED & dummy TD is used to indicate
688 * the end of the TD chain.
689 */
690 ohci_polledp->ohci_polled_dummy_ed = ohci_alloc_hc_ed(ohcip, NULL);
691
692 if (ohci_polledp->ohci_polled_dummy_ed == NULL) {
693
694 return (USB_NO_RESOURCES);
695 }
696
697 /*
698 * Allocate the endpoint. This ED will be inserted in
699 * to the lattice chain for the device. This endpoint
700 * will have the TDs hanging off of it for the processing.
701 */
702 ohci_polledp->ohci_polled_ed = ohci_alloc_hc_ed(ohcip,
703 ohci_polledp->ohci_polled_input_pipe_handle);
704
705 if (ohci_polledp->ohci_polled_ed == NULL) {
706
707 return (USB_NO_RESOURCES);
708 }
709
710 /* Set the state of pipe as idle */
711 pp->pp_state = OHCI_PIPE_STATE_IDLE;
712
713 /* Insert the endpoint onto the pipe handle */
714 pp->pp_ept = ohci_polledp->ohci_polled_ed;
715
716 pipe_attr = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK;
717
718 switch (pipe_attr) {
719 case USB_EP_ATTR_INTR:
720 /*
721 * Set soft interrupt handler flag in the normal mode usb
722 * pipe handle.
723 */
724 mutex_enter(&ph->p_mutex);
725 ph->p_spec_flag |= USBA_PH_FLAG_USE_SOFT_INTR;
726 mutex_exit(&ph->p_mutex);
727
728 /*
729 * Insert a Interrupt polling request onto the endpoint.
730 *
731 * There will now be two TDs on the ED, one is the dummy TD
732 * that was allocated above in the ohci_alloc_hc_ed and
733 * this new one.
734 */
735 if ((ohci_start_periodic_pipe_polling(ohcip,
736 ohci_polledp->ohci_polled_input_pipe_handle,
737 NULL, USB_FLAGS_SLEEP)) != USB_SUCCESS) {
738 return (USB_NO_RESOURCES);
739 }
740 break;
741 case USB_EP_ATTR_BULK:
742 if ((ohci_polled_create_tw(ohcip,
743 ohci_polledp->ohci_polled_input_pipe_handle,
744 USB_FLAGS_SLEEP)) != USB_SUCCESS) {
745 return (USB_NO_RESOURCES);
746 }
747 break;
748 default:
749 return (USB_FAILURE);
750 }
751 return (USB_SUCCESS);
752 }
753
754
755 /*
756 * Polled deinitialization routines
757 */
758
759
760 /*
761 * ohci_polled_fini:
762 */
763 static int
ohci_polled_fini(ohci_polled_t * ohci_polledp)764 ohci_polled_fini(ohci_polled_t *ohci_polledp)
765 {
766 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip;
767 ohci_pipe_private_t *pp;
768 ohci_td_t *curr_td, *next_td;
769 ohci_trans_wrapper_t *curr_tw, *next_tw;
770 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
771
772 /*
773 * If the structure is already in use, then don't free it.
774 */
775 if (ohci_polledp->ohci_polled_flags & POLLED_INPUT_MODE) {
776
777 return (USB_SUCCESS);
778 }
779
780 pp = (ohci_pipe_private_t *)
781 ohci_polledp->ohci_polled_input_pipe_handle->p_hcd_private;
782
783 /*
784 * Deallocate all the pre-allocated interrupt requests
785 */
786 ohci_handle_outstanding_requests(ohcip, pp);
787
788 /*
789 * Traverse the list of TD's on this endpoint and these TD's
790 * have outstanding transfer requests. Since list processing
791 * is stopped, these TDs can be deallocated.
792 */
793 ohci_traverse_tds(ohcip, pp->pp_pipe_handle);
794
795 /*
796 * For each transfer wrapper on this pipe, free the TD and
797 * free the TW. We don't free the last TD in the chain
798 * because it will be freed by ohci_deallocate_ed. All TD's
799 * on this TW are also on the end point associated with this
800 * pipe.
801 */
802 next_tw = pp->pp_tw_head;
803
804 while (next_tw) {
805 next_td = (ohci_td_t *)next_tw->tw_hctd_head;
806
807 /*
808 * Walk through each TD for this transfer
809 * wrapper and free that TD.
810 */
811 while (next_td) {
812 curr_td = next_td;
813
814 next_td = ohci_td_iommu_to_cpu(ohcip,
815 Get_TD(next_td->hctd_tw_next_td));
816
817 ohci_deallocate_td(ohcip, curr_td);
818 }
819
820 curr_tw = next_tw;
821 next_tw = curr_tw->tw_next;
822
823 /* Free the transfer wrapper */
824 ohci_deallocate_tw_resources(ohcip, pp, curr_tw);
825 }
826
827 /*
828 * Deallocate the endpoint descriptors that we allocated
829 * with ohci_alloc_hc_ed.
830 */
831 if (ohci_polledp->ohci_polled_dummy_ed) {
832 ohci_deallocate_ed(ohcip, ohci_polledp->ohci_polled_dummy_ed);
833 }
834
835 if (ohci_polledp->ohci_polled_ed) {
836 ohci_deallocate_ed(ohcip, ohci_polledp->ohci_polled_ed);
837 }
838
839 mutex_destroy(&ohci_polledp->ohci_polled_input_pipe_handle->p_mutex);
840
841 /*
842 * Destroy everything about the pipe that we allocated in
843 * ohci_polled_duplicate_pipe_handle
844 */
845 kmem_free(pp, sizeof (ohci_pipe_private_t));
846
847 kmem_free(ohci_polledp->ohci_polled_input_pipe_handle,
848 sizeof (usba_pipe_handle_data_t));
849
850 /*
851 * We use this field to determine if a TD is for input or not,
852 * so NULL the pointer so we don't check deallocated data.
853 */
854 ohci_polledp->ohci_polled_input_pipe_handle = NULL;
855
856 /*
857 * Finally, free off the structure that we use to keep track
858 * of all this.
859 */
860 kmem_free(ohci_polledp, sizeof (ohci_polled_t));
861
862 return (USB_SUCCESS);
863 }
864
865
866 /*
867 * Polled save state routines
868 */
869
870
871 /*
872 * ohci_polled_save_state:
873 */
874 static void
ohci_polled_save_state(ohci_polled_t * ohci_polledp)875 ohci_polled_save_state(ohci_polled_t *ohci_polledp)
876 {
877 ohci_state_t *ohcip;
878 int i;
879 uint_t polled_toggle;
880 uint_t real_toggle;
881 ohci_pipe_private_t *pp = NULL; /* Normal mode Pipe */
882 ohci_pipe_private_t *polled_pp; /* Polled mode Pipe */
883 usba_pipe_handle_data_t *ph;
884 uint8_t ep_addr;
885 ohci_save_intr_sts_t *ohci_intr_sts;
886 ohci_regs_t *ohci_polled_regsp;
887 ohci_td_t *td, *prev_td;
888 ohci_td_t *done_head, **done_list;
889
890 #ifndef lint
891 _NOTE(NO_COMPETING_THREADS_NOW);
892 #endif
893
894 /*
895 * If either of these two flags are set, then we have already
896 * saved off the state information and setup the controller.
897 */
898 if (ohci_polledp->ohci_polled_flags & POLLED_INPUT_MODE_INUSE) {
899 #ifndef lint
900 _NOTE(COMPETING_THREADS_NOW);
901 #endif
902 return;
903 }
904
905 ohcip = ohci_polledp->ohci_polled_ohcip;
906
907 /*
908 * Check if the number of keyboard reach the max number we can
909 * support in polled mode
910 */
911 if (++ ohcip->ohci_polled_enter_count > MAX_NUM_FOR_KEYBOARD) {
912 #ifndef lint
913 _NOTE(COMPETING_THREADS_NOW);
914 #endif
915 return;
916 }
917 /* Get the endpoint addr. */
918 ep_addr = ohci_polledp->ohci_polled_ep_addr;
919
920 /* Get the normal mode usb pipe handle */
921 ph = usba_hcdi_get_ph_data(ohci_polledp->ohci_polled_usb_dev, ep_addr);
922 ohci_intr_sts = &ohcip->ohci_save_intr_sts;
923 ohci_polled_regsp = &ohcip->ohci_polled_save_regs;
924
925 /*
926 * Only the first enter keyboard entry disable the interrupt, save the
927 * information of normal mode, stop the processing, initialize the
928 * frame list table.
929 */
930 if (ohcip->ohci_polled_enter_count == 1) {
931 /*
932 * Prevent the ohci interrupt handler from handling interrupt.
933 * We will turn off interrupts. This keeps us from generating
934 * a hardware interrupt.This is the useful for testing because
935 * in POLLED mode we can't get interrupts anyway. We can test
936 * this code by shutting off hardware interrupt generation and
937 * polling for the interrupts.
938 */
939 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE);
940 /*
941 * Save the current normal mode ohci registers and later this
942 * saved register copy is used to replace some of required ohci
943 * registers before switching from polled mode to normal mode.
944 */
945 bzero((void *)ohci_polled_regsp, sizeof (ohci_regs_t));
946
947 ohci_polled_regsp->hcr_control = Get_OpReg(hcr_control);
948 ohci_polled_regsp->hcr_cmd_status = Get_OpReg(hcr_cmd_status);
949 ohci_polled_regsp->hcr_intr_enable = Get_OpReg(hcr_intr_enable);
950 ohci_polled_regsp->hcr_HCCA = Get_OpReg(hcr_HCCA);
951 ohci_polled_regsp->hcr_done_head = Get_OpReg(hcr_done_head);
952 ohci_polled_regsp->hcr_bulk_head = Get_OpReg(hcr_bulk_head);
953 ohci_polled_regsp->hcr_ctrl_head = Get_OpReg(hcr_ctrl_head);
954
955 /*
956 * The functionality & importance of critical code section in
957 * the normal mode ohci interrupt handler and its usage in the
958 * polled mode is explained below.
959 *
960 * (a) Normal mode:
961 *
962 * - Set the flag indicating that processing critical code
963 * in ohci interrupt handler.
964 *
965 * - Process the missed ohci interrupts by copying missed
966 * interrupt events & done head list fields information
967 * to the critical interrupt events & done list fields.
968 *
969 * - Reset the missed ohci interrupt events and done head
970 * list fields so that the new missed interrupt events
971 * and done head list information can be saved.
972 *
973 * - All above steps will be executed within the critical
974 * section of the interrupt handler. Then ohci missed
975 * interrupt handler will be called to service the ohci
976 * missed interrupts.
977 *
978 * (b) Polled mode:
979 *
980 * - On entering the polled code, checks for the critical
981 * section code execution within normal mode interrupt
982 * handler.
983 *
984 * - If critical section code is executing in the normal
985 * mode ohci interrupt handler & if copying of the ohci
986 * missed interrupt events and done head list fields to
987 * the critical fields is finished then, save the "any
988 * missed interrupt events and done head list" because
989 * of current polled mode switch into "critical missed
990 * interrupt events & done list fields" instead actual
991 * missed events and done list fields.
992 *
993 * - Otherwise save "any missed interrupt events and done
994 * list" because of this current polled mode switch in
995 * the actual missed interrupt events & done head list
996 * fields.
997 */
998
999 /*
1000 * Check and save the pending SOF interrupt condition for the
1001 * ohci normal mode. This information will be saved either in
1002 * the critical missed event fields or in actual missed event
1003 * fields depending on the whether the critical code section's
1004 * execution flag was set or not when switched to polled mode
1005 * from normal mode.
1006 */
1007 if ((ohci_intr_sts->ohci_intr_flag & OHCI_INTR_CRITICAL) &&
1008 (ohci_intr_sts->ohci_critical_intr_sts != 0)) {
1009
1010 ohci_intr_sts->ohci_critical_intr_sts |=
1011 ((Get_OpReg(hcr_intr_status) &
1012 Get_OpReg(hcr_intr_enable)) & HCR_INTR_SOF);
1013 } else {
1014 ohci_intr_sts->ohci_missed_intr_sts |=
1015 ((Get_OpReg(hcr_intr_status) &
1016 Get_OpReg(hcr_intr_enable)) & HCR_INTR_SOF);
1017 }
1018 ohci_polled_stop_processing(ohci_polledp);
1019
1020 /* Process any missed Frame Number Overflow (FNO) interrupt */
1021 ohci_polled_handle_frame_number_overflow(ohcip);
1022
1023 /*
1024 * By this time all list processing has been stopped.Now check
1025 * and save the information about the pending HCCA done list,
1026 * done head ohci register and WDH bit in the interrupt status
1027 * register. This information will be saved either in critical
1028 * missed event fields or in actual missed event fields depend
1029 * on the whether the critical code section's execution flag
1030 * was set or not when switched to polled mode from the normal
1031 * mode.
1032 */
1033
1034 /* Read and Save the HCCA DoneHead value */
1035 done_head = (ohci_td_t *)(uintptr_t)(Get_HCCA(
1036 ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK);
1037
1038 if ((done_head) &&
1039 (done_head != ohci_intr_sts->ohci_curr_done_lst)) {
1040
1041 if ((ohci_intr_sts->ohci_intr_flag &
1042 OHCI_INTR_CRITICAL) &&
1043 ((ohci_intr_sts->ohci_critical_done_lst) ||
1044 (ohci_intr_sts->ohci_missed_done_lst == NULL))) {
1045
1046 done_list =
1047 &ohci_intr_sts->ohci_critical_done_lst;
1048 ohci_intr_sts->ohci_critical_intr_sts |=
1049 HCR_INTR_WDH;
1050 } else {
1051 done_list =
1052 &ohci_intr_sts->ohci_missed_done_lst;
1053 ohci_intr_sts->ohci_missed_intr_sts |=
1054 HCR_INTR_WDH;
1055 }
1056
1057 if (*done_list) {
1058 td = (ohci_td_t *)
1059 ohci_td_iommu_to_cpu(ohcip,
1060 (uintptr_t)done_head);
1061
1062 while (td) {
1063 prev_td = td;
1064 td = ohci_td_iommu_to_cpu(ohcip,
1065 Get_TD(td->hctd_next_td));
1066 }
1067
1068 Set_TD(prev_td->hctd_next_td, *done_list);
1069
1070 *done_list = done_head;
1071 } else {
1072 *done_list = (ohci_td_t *)done_head;
1073 }
1074 }
1075
1076 /*
1077 * Save the latest hcr_done_head ohci register value, so that
1078 * this value can be replaced when exit from the POLLED mode.
1079 */
1080 ohci_polled_regsp->hcr_done_head = Get_OpReg(hcr_done_head);
1081 /*
1082 * Reset the HCCA done head and ohci done head register.
1083 */
1084 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, 0);
1085 Set_OpReg(hcr_done_head, 0);
1086
1087 /*
1088 * Clear the WriteDoneHead interrupt bit in the ohci interrupt
1089 * status register.
1090 */
1091 Set_OpReg(hcr_intr_status, HCR_INTR_WDH);
1092
1093 /*
1094 * Save the current interrupt lattice and replace this lattice
1095 * with an lattice used in POLLED mode. We will restore lattice
1096 * back when we exit from the POLLED mode.
1097 */
1098 for (i = 0; i < NUM_INTR_ED_LISTS; i++) {
1099 ohcip->ohci_polled_save_IntTble[i] =
1100 (ohci_ed_t *)(uintptr_t)Get_HCCA(
1101 ohcip->ohci_hccap->HccaIntTble[i]);
1102 }
1103 /*
1104 * Fill in the lattice with dummy EDs. These EDs are used so the
1105 * controller can tell that it is at the end of the ED list.
1106 */
1107 for (i = 0; i < NUM_INTR_ED_LISTS; i++) {
1108 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i],
1109 ohci_ed_cpu_to_iommu(ohcip,
1110 ohci_polledp->ohci_polled_dummy_ed));
1111 }
1112 }
1113 /* Get the polled mode ohci pipe private structure */
1114 polled_pp = (ohci_pipe_private_t *)
1115 ohci_polledp->ohci_polled_input_pipe_handle->p_hcd_private;
1116
1117 /*
1118 * Before replacing the lattice, adjust the data togggle on the
1119 * on the ohci's interrupt ed
1120 */
1121 polled_toggle = (Get_ED(polled_pp->pp_ept->hced_headp) &
1122 HC_EPT_Carry) ? DATA1:DATA0;
1123
1124 /*
1125 * If normal mode interrupt pipe endpoint is active, get the data
1126 * toggle from the this interrupt endpoint through the corresponding
1127 * interrupt pipe handle. Else get the data toggle information from
1128 * the usb device structure and this information is saved during the
1129 * normal mode interrupt pipe close. Use this data toggle information
1130 * to fix the data toggle of polled mode interrupt endpoint.
1131 */
1132 if (ph) {
1133 /* Get the normal mode ohci pipe private structure */
1134 pp = (ohci_pipe_private_t *)ph->p_hcd_private;
1135
1136 real_toggle = (Get_ED(pp->pp_ept->hced_headp) &
1137 HC_EPT_Carry) ? DATA1:DATA0;
1138 } else {
1139 real_toggle = usba_hcdi_get_data_toggle(
1140 ohci_polledp->ohci_polled_usb_dev, ep_addr);
1141 }
1142
1143 if (polled_toggle != real_toggle) {
1144 if (real_toggle == DATA0) {
1145 Set_ED(polled_pp->pp_ept->hced_headp,
1146 Get_ED(polled_pp->pp_ept->hced_headp) &
1147 ~HC_EPT_Carry);
1148 } else {
1149 Set_ED(polled_pp->pp_ept->hced_headp,
1150 Get_ED(polled_pp->pp_ept->hced_headp) |
1151 HC_EPT_Carry);
1152 }
1153 }
1154
1155 /*
1156 * Check whether Halt bit is set in the ED and if so clear the
1157 * halt bit.
1158 */
1159 if (polled_pp->pp_ept->hced_headp & HC_EPT_Halt) {
1160
1161 /* Clear the halt bit */
1162 Set_ED(polled_pp->pp_ept->hced_headp,
1163 (Get_ED(polled_pp->pp_ept->hced_headp) & ~HC_EPT_Halt));
1164 }
1165
1166 /*
1167 * Now, add the endpoint to the lattice that we will hang our
1168 * TD's off of. We need to poll this device at every 8 ms and
1169 * hence add this ED needs 4 entries in interrupt lattice.
1170 */
1171 for (i = (ohcip->ohci_polled_enter_count -1); i < NUM_INTR_ED_LISTS;
1172 i = i + MIN_LOW_SPEED_POLL_INTERVAL) {
1173 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i],
1174 ohci_ed_cpu_to_iommu(ohcip,
1175 ohci_polledp->ohci_polled_ed));
1176 }
1177 /*
1178 * Only the first enter keyboard entry clear the contents of
1179 * periodic ED register and enable the WDH interrupt and
1180 * start process the periodic list.
1181 */
1182 if (ohcip->ohci_polled_enter_count == 1) {
1183 /*
1184 * Clear the contents of current ohci periodic ED register that
1185 * is physical address of current Isochronous or Interrupt ED.
1186 */
1187
1188 Set_OpReg(hcr_periodic_curr, (uint32_t)0x0);
1189
1190 /* Make sure WriteDoneHead interrupt is enabled */
1191 Set_OpReg(hcr_intr_enable, HCR_INTR_WDH);
1192
1193 /*
1194 * Enable the periodic list. We will now start processing EDs &
1195 * TDs again.
1196 */
1197 Set_OpReg(hcr_control,
1198 (Get_OpReg(hcr_control) | HCR_CONTROL_PLE));
1199 }
1200 #ifndef lint
1201 _NOTE(COMPETING_THREADS_NOW);
1202 #endif
1203 }
1204
1205
1206 /*
1207 * ohci_polled_stop_processing:
1208 */
1209 static void
ohci_polled_stop_processing(ohci_polled_t * ohci_polledp)1210 ohci_polled_stop_processing(ohci_polled_t *ohci_polledp)
1211 {
1212 ohci_state_t *ohcip;
1213 uint_t count;
1214 ohci_regs_t *ohci_polled_regsp;
1215
1216 ohcip = ohci_polledp->ohci_polled_ohcip;
1217 ohci_polled_regsp = &ohcip->ohci_polled_save_regs;
1218
1219 /*
1220 * Turn off all list processing. This will take place starting
1221 * at the next frame.
1222 */
1223 Set_OpReg(hcr_control,
1224 (ohci_polled_regsp->hcr_control) & ~(HCR_CONTROL_CLE|
1225 HCR_CONTROL_PLE| HCR_CONTROL_BLE|HCR_CONTROL_IE));
1226
1227 /*
1228 * Make sure that the SOF interrupt bit is cleared in the ohci
1229 * interrupt status register.
1230 */
1231 Set_OpReg(hcr_intr_status, HCR_INTR_SOF);
1232
1233 /* Enable SOF interrupt */
1234 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
1235
1236 /*
1237 * According to OHCI Specification, we have to wait for eight
1238 * start of frames to make sure that the Host Controller writes
1239 * contents of done head register to done head filed of HCCA.
1240 */
1241 for (count = 0; count <= DONE_QUEUE_INTR_COUNTER; count++) {
1242 while (!((Get_OpReg(hcr_intr_status)) & HCR_INTR_SOF)) {
1243 continue;
1244 }
1245
1246 /* Acknowledge the SOF interrupt */
1247 ohci_polled_finish_interrupt(ohcip, HCR_INTR_SOF);
1248 }
1249
1250 Set_OpReg(hcr_intr_disable, HCR_INTR_SOF);
1251 }
1252
1253
1254 /*
1255 * Polled restore state routines
1256 */
1257
1258 /*
1259 * ohci_polled_restore_state:
1260 */
1261 static void
ohci_polled_restore_state(ohci_polled_t * ohci_polledp)1262 ohci_polled_restore_state(ohci_polled_t *ohci_polledp)
1263 {
1264 ohci_state_t *ohcip;
1265 int i;
1266 uint_t polled_toggle;
1267 uint_t real_toggle;
1268 ohci_pipe_private_t *pp = NULL; /* Normal mode Pipe */
1269 ohci_pipe_private_t *polled_pp; /* Polled mode Pipe */
1270 ohci_td_t *td;
1271 ohci_td_t *next_td; /* TD pointers */
1272 uint_t count;
1273 ohci_save_intr_sts_t *ohci_intr_sts;
1274 ohci_regs_t *ohci_polled_regsp;
1275 uint32_t mask;
1276 usba_pipe_handle_data_t *ph;
1277 uint8_t ep_addr;
1278
1279 #ifndef lint
1280 _NOTE(NO_COMPETING_THREADS_NOW);
1281 #endif
1282
1283 /*
1284 * If this flag is set, then we are still using this structure,
1285 * so don't restore any controller state information yet.
1286 */
1287 if (ohci_polledp->ohci_polled_flags & POLLED_INPUT_MODE_INUSE) {
1288
1289 #ifndef lint
1290 _NOTE(COMPETING_THREADS_NOW);
1291 #endif
1292
1293 return;
1294 }
1295
1296 ohcip = ohci_polledp->ohci_polled_ohcip;
1297 ohci_intr_sts = &ohcip->ohci_save_intr_sts;
1298 ohci_polled_regsp = &ohcip->ohci_polled_save_regs;
1299 ohcip->ohci_polled_enter_count --;
1300
1301 /* Get the endpoint addr. */
1302 ep_addr = ohci_polledp->ohci_polled_ep_addr;
1303 /* Get the normal mode usb pipe handle */
1304 ph = usba_hcdi_get_ph_data(ohci_polledp->ohci_polled_usb_dev, ep_addr);
1305
1306 /*
1307 * Only the first leave keyboard entry turn off all list processing.
1308 * This will take place starting at the next frame.
1309 */
1310 if (Get_OpReg(hcr_control) & HCR_CONTROL_PLE) {
1311 Set_OpReg(hcr_control,
1312 (Get_OpReg(hcr_control) & ~HCR_CONTROL_PLE));
1313 }
1314
1315 /*
1316 * Only the last leave keyboard entry restore the info for
1317 * normal mode.
1318 */
1319 if (ohcip->ohci_polled_enter_count == 0) {
1320 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
1321
1322 /*
1323 * According to OHCI Specification, we have to wait for eight
1324 * start of frames to make sure that the Host Controller writes
1325 * contents of done head register to done head filed of HCCA.
1326 */
1327 for (count = 0; count <= DONE_QUEUE_INTR_COUNTER; count++) {
1328 while (!((Get_OpReg(hcr_intr_status)) & HCR_INTR_SOF)) {
1329 continue;
1330 }
1331 /* Acknowledge the SOF interrupt */
1332 ohci_polled_finish_interrupt(ohcip, HCR_INTR_SOF);
1333 }
1334
1335 /*
1336 * Check any Frame Number Overflow interrupt (FNO) is pending.
1337 */
1338 ohci_polled_handle_frame_number_overflow(ohcip);
1339
1340 /*
1341 * Before switching back, we have to process last TD in the
1342 * POLLED mode. It may be in the hcr_done_head register or
1343 * in done list or in the lattice. If it is either on the
1344 * hcr_done_head register or in the done list, just re-inserted
1345 * into the ED's TD list.
1346 *
1347 * First look up at the TD's that are in the hcr_done_head
1348 * register and re-insert them back into the ED's TD list.
1349 */
1350 td = ohci_td_iommu_to_cpu(ohcip,
1351 (uintptr_t)Get_OpReg(hcr_done_head));
1352
1353 while (td) {
1354
1355 next_td = ohci_td_iommu_to_cpu(ohcip,
1356 Get_TD(td->hctd_next_td));
1357
1358 /*
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.
1362 */
1363 ohci_polled_insert_td(ohcip, td);
1364
1365 td = next_td;
1366 }
1367
1368 /*
1369 * Now look up at the TD's that are in the HCCA done head list &
1370 * re-insert them back into the ED's TD list.
1371 */
1372 td = ohci_td_iommu_to_cpu(ohcip, (Get_HCCA(
1373 ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK));
1374
1375 while (td) {
1376
1377 next_td = ohci_td_iommu_to_cpu(ohcip,
1378 Get_TD(td->hctd_next_td));
1379
1380 /*
1381 * Insert valid interrupt TD back into ED's
1382 * TD list. No periodic TD's will be processed
1383 * since all processing has been stopped.
1384 */
1385 ohci_polled_insert_td(ohcip, td);
1386
1387 td = next_td;
1388 }
1389 /* Reset the HCCA done head list to NULL */
1390 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, 0);
1391
1392 /*
1393 * Replace the hcr_done_head register field with the saved copy
1394 * of current normal mode hcr_done_head register contents.
1395 */
1396 Set_OpReg(hcr_done_head,
1397 (uint32_t)ohci_polled_regsp->hcr_done_head);
1398
1399 /*
1400 * Clear the WriteDoneHead and SOF interrupt bits in the ohci
1401 * interrupt status register.
1402 */
1403 Set_OpReg(hcr_intr_status, (HCR_INTR_WDH | HCR_INTR_SOF));
1404 }
1405
1406 /* Get the polled mode ohci pipe private structure */
1407 polled_pp = (ohci_pipe_private_t *)
1408 ohci_polledp->ohci_polled_input_pipe_handle->p_hcd_private;
1409
1410 /*
1411 * Before replacing the lattice, adjust the data togggle
1412 * on the on the ohci's interrupt ed
1413 */
1414 polled_toggle = (Get_ED(polled_pp->pp_ept->hced_headp) &
1415 HC_EPT_Carry) ? DATA1:DATA0;
1416
1417 /*
1418 * If normal mode interrupt pipe endpoint is active, fix the
1419 * data toggle for this interrupt endpoint by getting the data
1420 * toggle information from the polled interrupt endpoint. Else
1421 * save the data toggle information in usb device structure.
1422 */
1423 if (ph) {
1424 /* Get the normal mode ohci pipe private structure */
1425 pp = (ohci_pipe_private_t *)ph->p_hcd_private;
1426
1427 real_toggle = (Get_ED(pp->pp_ept->hced_headp) &
1428 HC_EPT_Carry) ? DATA1:DATA0;
1429
1430 if (polled_toggle != real_toggle) {
1431 if (polled_toggle == DATA0) {
1432 Set_ED(pp->pp_ept->hced_headp,
1433 Get_ED(pp->pp_ept->hced_headp) &
1434 ~HC_EPT_Carry);
1435 } else {
1436 Set_ED(pp->pp_ept->hced_headp,
1437 Get_ED(pp->pp_ept->hced_headp) |
1438 HC_EPT_Carry);
1439 }
1440 }
1441 } else {
1442 usba_hcdi_set_data_toggle(ohci_polledp->ohci_polled_usb_dev,
1443 ep_addr, polled_toggle);
1444 }
1445 /*
1446 * Only the last leave keyboard entry restore the Interrupt table,
1447 * start processing and enable the interrupt.
1448 */
1449 if (ohcip->ohci_polled_enter_count == 0) {
1450 /* Replace the lattice */
1451 for (i = 0; i < NUM_INTR_ED_LISTS; i++) {
1452 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[i],
1453 (uintptr_t)ohcip->ohci_polled_save_IntTble[i]);
1454 }
1455
1456 /*
1457 * Clear the contents of current ohci periodic ED register that
1458 * is physical address of current Isochronous or Interrupt ED.
1459 */
1460 Set_OpReg(hcr_periodic_curr, (uint32_t)0x0);
1461
1462 ohci_polled_start_processing(ohci_polledp);
1463
1464 /*
1465 * Check and enable required ohci interrupts before switching
1466 * back to normal mode from the POLLED mode.
1467 */
1468 mask = (uint32_t)ohci_polled_regsp->hcr_intr_enable &
1469 (HCR_INTR_SOF | HCR_INTR_WDH);
1470
1471 if (ohci_intr_sts->ohci_intr_flag & OHCI_INTR_HANDLING) {
1472 Set_OpReg(hcr_intr_enable, mask);
1473 } else {
1474 Set_OpReg(hcr_intr_enable, mask | HCR_INTR_MIE);
1475 }
1476 }
1477 #ifndef lint
1478 _NOTE(COMPETING_THREADS_NOW);
1479 #endif
1480 }
1481
1482 /*
1483 * ohci_polled_start_processing:
1484 */
1485 static void
ohci_polled_start_processing(ohci_polled_t * ohci_polledp)1486 ohci_polled_start_processing(ohci_polled_t *ohci_polledp)
1487 {
1488 ohci_state_t *ohcip;
1489 uint32_t control;
1490 uint32_t mask;
1491 ohci_regs_t *ohci_polled_regsp;
1492
1493 ohcip = ohci_polledp->ohci_polled_ohcip;
1494 ohci_polled_regsp = &ohcip->ohci_polled_save_regs;
1495
1496 mask = ((uint32_t)ohci_polled_regsp->hcr_control) & (HCR_CONTROL_CLE |
1497 HCR_CONTROL_PLE | HCR_CONTROL_BLE | HCR_CONTROL_IE);
1498
1499 control = Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
1500 HCR_CONTROL_PLE | HCR_CONTROL_BLE | HCR_CONTROL_IE);
1501
1502 Set_OpReg(hcr_control, (control | mask));
1503 }
1504
1505
1506 /*
1507 * Polled read routines
1508 */
1509 /*
1510 * ohci_polled_check_done_list:
1511 *
1512 * Check to see it there are any TD's on the done head. If there are
1513 * then reverse the done list and put the TD's on the appropriated list.
1514 */
1515 static int
ohci_polled_check_done_list(ohci_polled_t * ohci_polledp)1516 ohci_polled_check_done_list(ohci_polled_t *ohci_polledp)
1517 {
1518 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip;
1519 ohci_td_t *done_head, *done_list;
1520
1521 /* Sync HCCA area */
1522 if (ohci_polledp->ohci_polled_no_sync_flag == B_FALSE) {
1523 Sync_HCCA(ohcip);
1524 }
1525
1526 /* Read and Save the HCCA DoneHead value */
1527 done_head = (ohci_td_t *)(uintptr_t)
1528 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK);
1529
1530 /*
1531 * Look at the Done Head and if it is NULL and ohci done list is NULL,
1532 * just return; else if ohci done list is not NULL, should check it.
1533 */
1534 if (done_head == NULL) {
1535 if (ohcip->ohci_polled_done_list) {
1536 done_head = ohcip->ohci_polled_done_list;
1537 ohcip->ohci_polled_done_list = NULL;
1538 } else {
1539
1540 return (USB_FAILURE);
1541 }
1542 } else {
1543 /* Reset the done head to NULL */
1544 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, 0);
1545 }
1546
1547 /* Sync ED and TD pool */
1548 if (ohci_polledp->ohci_polled_no_sync_flag == B_FALSE) {
1549 Sync_ED_TD_Pool(ohcip);
1550 }
1551
1552 /* Pickup own tds in the done head */
1553 done_list = ohci_polled_pickup_done_list(ohci_polledp, done_head);
1554
1555 /*
1556 * Look at the own done list which is pickup'ed
1557 * and if it is NULL, just return.
1558 */
1559 if (done_list == NULL) {
1560
1561 return (USB_FAILURE);
1562 }
1563 /* Create the input done list */
1564 ohci_polled_create_input_list(ohci_polledp, done_list);
1565
1566 return (USB_SUCCESS);
1567 }
1568
1569
1570 /*
1571 * ohci_polled_pickup_done_list:
1572 *
1573 * Pickup the TDs of own in the Done Head List
1574 */
1575 static ohci_td_t *
ohci_polled_pickup_done_list(ohci_polled_t * ohci_polledp,ohci_td_t * done_head)1576 ohci_polled_pickup_done_list(
1577 ohci_polled_t *ohci_polledp,
1578 ohci_td_t *done_head)
1579 {
1580 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip;
1581 ohci_td_t *create_head = NULL, *current_td, *td;
1582 ohci_trans_wrapper_t *tw;
1583 ohci_pipe_private_t *pp;
1584
1585 /*
1586 * Current_td pointers point to the done head.
1587 */
1588 current_td = (ohci_td_t *)
1589 ohci_td_iommu_to_cpu(ohcip, (uintptr_t)done_head);
1590 while (current_td) {
1591 td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip,
1592 Get_TD(current_td->hctd_next_td));
1593
1594 Set_TD(current_td->hctd_next_td, NULL);
1595
1596 /* Obtain the transfer wrapper from the TD */
1597 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
1598 (uint32_t)Get_TD(current_td->hctd_trans_wrapper));
1599
1600 /* Get the pipe handle for this transfer wrapper. */
1601 pp = tw->tw_pipe_private;
1602
1603 /*
1604 * Figure out which done list to put this TD on and put it
1605 * there. If the pipe handle of the TD matches the pipe
1606 * handle we are using for the input device, then this must
1607 * be an input TD, reverse the order and link to the list for
1608 * this input device. Else put the TD to the reserve done list
1609 * for other input devices.
1610 */
1611
1612 if (pp->pp_pipe_handle ==
1613 ohci_polledp->ohci_polled_input_pipe_handle) {
1614 if (create_head == NULL) {
1615 create_head = current_td;
1616 } else {
1617 Set_TD(current_td->hctd_next_td,
1618 ohci_td_cpu_to_iommu(ohcip, create_head));
1619 create_head = current_td;
1620 }
1621 } else {
1622 if (ohcip->ohci_polled_done_list == NULL) {
1623 ohcip->ohci_polled_done_list = (ohci_td_t *)
1624 (uintptr_t)ohci_td_cpu_to_iommu(ohcip,
1625 current_td);
1626 } else {
1627 Set_TD(current_td->hctd_next_td,
1628 ohcip->ohci_polled_done_list);
1629 ohcip->ohci_polled_done_list = (ohci_td_t *)
1630 (uintptr_t)ohci_td_cpu_to_iommu(ohcip,
1631 current_td);
1632 }
1633 }
1634 current_td = td;
1635 }
1636
1637 return (create_head);
1638 }
1639
1640
1641 /*
1642 * ohci_polled_create_input_list:
1643 *
1644 * Create the input done list from the actual done head list.
1645 */
1646 static void
ohci_polled_create_input_list(ohci_polled_t * ohci_polledp,ohci_td_t * head_done_list)1647 ohci_polled_create_input_list(
1648 ohci_polled_t *ohci_polledp,
1649 ohci_td_t *head_done_list)
1650 {
1651 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip;
1652 ohci_td_t *cpu_save, *td;
1653
1654 ASSERT(head_done_list != NULL);
1655
1656 /* Get the done head list */
1657 td = (ohci_td_t *)head_done_list;
1658
1659 /*
1660 * Traverse the done list and create the input done list.
1661 */
1662 while (td) {
1663
1664 /*
1665 * Convert the iommu pointer to a cpu pointer. No point
1666 * in doing this over and over, might as well do it once.
1667 */
1668 cpu_save = ohci_td_iommu_to_cpu(ohcip,
1669 Get_TD(td->hctd_next_td));
1670
1671 /*
1672 * Terminate this TD by setting its next pointer to NULL.
1673 */
1674 Set_TD(td->hctd_next_td, NULL);
1675
1676 /* This is an input TD, so put it on the input done list */
1677 if (ohci_polledp->ohci_polled_input_done_head == NULL) {
1678
1679 /*
1680 * There is nothing on the input done list,
1681 * so put this TD on the head.
1682 */
1683 ohci_polledp->ohci_polled_input_done_head = td;
1684 } else {
1685 Set_TD(ohci_polledp->
1686 ohci_polled_input_done_tail->hctd_next_td,
1687 ohci_td_cpu_to_iommu(ohcip, td));
1688 }
1689
1690 /* The tail points to the new TD */
1691 ohci_polledp->ohci_polled_input_done_tail = td;
1692 td = cpu_save;
1693 }
1694 }
1695
1696
1697 /*
1698 * ohci_polled_process_input_list:
1699 *
1700 * This routine takes the TD's off of the input done head and processes
1701 * them. It returns the number of characters that have been copied for
1702 * input.
1703 */
1704 static int
ohci_polled_process_input_list(ohci_polled_t * ohci_polledp)1705 ohci_polled_process_input_list(ohci_polled_t *ohci_polledp)
1706 {
1707 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip;
1708 ohci_td_t *td, *next_td;
1709 uint_t ctrl;
1710 uint_t num_characters;
1711 ohci_trans_wrapper_t *tw;
1712 ohci_pipe_private_t *pp;
1713 int pipe_dir;
1714
1715 /*
1716 * Get the first TD on the input done head.
1717 */
1718 td = ohci_polledp->ohci_polled_input_done_head;
1719
1720 ohci_polledp->ohci_polled_input_done_head = NULL;
1721
1722 num_characters = 0;
1723
1724 /*
1725 * Traverse the list of transfer descriptors. We can't destroy
1726 * hctd_next_td pointers of these TDs because we are using it
1727 * to traverse the done list. Therefore, we can not put these
1728 * TDs back on the ED until we are done processing all of them.
1729 */
1730 while (td) {
1731
1732 /* Get the next TD from the input done list */
1733 next_td = (ohci_td_t *)
1734 ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td));
1735
1736 /* Look at the status */
1737 ctrl = (uint_t)Get_TD(td->hctd_ctrl) & (uint32_t)HC_TD_CC;
1738
1739 /*
1740 * Check to see if there is an error. If there is error
1741 * clear the halt condition in the Endpoint Descriptor
1742 * (ED) associated with this Transfer Descriptor (TD).
1743 */
1744 if (ctrl != HC_TD_CC_NO_E) {
1745 /* Obtain the transfer wrapper from the TD */
1746 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
1747 (uint32_t)Get_TD(td->hctd_trans_wrapper));
1748
1749 /* Get the pipe handle for this transfer wrapper */
1750 pp = tw->tw_pipe_private;
1751
1752 /* Clear the halt bit */
1753 Set_ED(pp->pp_ept->hced_headp,
1754 (Get_ED(pp->pp_ept->hced_headp) & ~HC_EPT_Halt));
1755 }
1756
1757 /* Obtain the transfer wrapper from the TD */
1758 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
1759 (uint32_t)Get_TD(td->hctd_trans_wrapper));
1760
1761 /* Get the pipe direction for this transfer wrapper */
1762 pipe_dir = tw->tw_pipe_private->pp_pipe_handle->
1763 p_ep.bEndpointAddress & USB_EP_DIR_MASK;
1764
1765 switch (pipe_dir) {
1766 case USB_EP_DIR_IN:
1767 num_characters +=
1768 ohci_polled_handle_normal_td(ohci_polledp,
1769 td);
1770
1771 /*
1772 * Insert this TD back
1773 * onto the ED's TD list
1774 */
1775 ohci_polled_insert_td(ohcip, td);
1776 break;
1777 case USB_EP_DIR_OUT:
1778 ASSERT((ohci_td_t *)tw->tw_hctd_head == td);
1779
1780 tw->tw_hctd_head = (ohci_td_t *)
1781 ohci_td_iommu_to_cpu(ohcip,
1782 Get_TD(td->hctd_tw_next_td));
1783 Set_TD(td->hctd_state, HC_TD_DUMMY);
1784
1785 if (tw->tw_hctd_head == NULL) {
1786 tw->tw_hctd_tail = NULL;
1787 }
1788
1789 if (tw->tw_hctd_free_list != NULL) {
1790 uint32_t td_addr;
1791 td_addr = ohci_td_cpu_to_iommu(ohcip,
1792 tw->tw_hctd_free_list);
1793 Set_TD(td->hctd_tw_next_td, td_addr);
1794 tw->tw_hctd_free_list = td;
1795 } else {
1796 tw->tw_hctd_free_list = td;
1797 Set_TD(td->hctd_tw_next_td, NULL);
1798 }
1799 break;
1800 }
1801
1802 td = next_td;
1803 }
1804
1805 return (num_characters);
1806 }
1807
1808
1809 /*
1810 * ohci_polled_handle_normal_td:
1811 */
1812 static int
ohci_polled_handle_normal_td(ohci_polled_t * ohci_polledp,ohci_td_t * td)1813 ohci_polled_handle_normal_td(
1814 ohci_polled_t *ohci_polledp,
1815 ohci_td_t *td)
1816 {
1817 ohci_state_t *ohcip = ohci_polledp->ohci_polled_ohcip;
1818 uchar_t *buf;
1819 ohci_trans_wrapper_t *tw;
1820 size_t length, residue;
1821
1822 /* Obtain the transfer wrapper from the TD */
1823 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID((uint32_t)
1824 Get_TD(td->hctd_trans_wrapper));
1825
1826 ASSERT(tw != NULL);
1827
1828 buf = (uchar_t *)tw->tw_buf;
1829
1830 length = tw->tw_length;
1831 /*
1832 * If "CurrentBufferPointer" of Transfer Descriptor (TD) is
1833 * not equal to zero, then we received less data from the
1834 * device than requested by us. In that case, get the actual
1835 * received data size.
1836 */
1837 if (Get_TD(td->hctd_cbp)) {
1838
1839 residue = ohci_get_td_residue(ohcip, td);
1840 length = Get_TD(td->hctd_xfer_offs) +
1841 Get_TD(td->hctd_xfer_len) - residue;
1842 }
1843
1844 /* Sync IO buffer */
1845 if (ohci_polledp->ohci_polled_no_sync_flag == B_FALSE) {
1846 Sync_IO_Buffer(tw->tw_dmahandle, length);
1847 }
1848
1849 /* Copy the data into the message */
1850 ddi_rep_get8(tw->tw_accesshandle,
1851 (uint8_t *)ohci_polledp->ohci_polled_buf,
1852 (uint8_t *)buf, length, DDI_DEV_AUTOINCR);
1853
1854 return ((int)length);
1855 }
1856
1857
1858 /*
1859 * ohci_polled_insert_td:
1860 *
1861 * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED).
1862 */
1863 static void
ohci_polled_insert_td(ohci_state_t * ohcip,ohci_td_t * td)1864 ohci_polled_insert_td(
1865 ohci_state_t *ohcip,
1866 ohci_td_t *td)
1867 {
1868 ohci_pipe_private_t *pp;
1869 ohci_ed_t *ept;
1870 uint_t td_control;
1871 ohci_trans_wrapper_t *tw;
1872 ohci_td_t *cpu_current_dummy;
1873 usb_intr_req_t *intr_req;
1874 usba_pipe_handle_data_t *ph;
1875 int pipe_attr;
1876
1877 /* Obtain the transfer wrapper from the TD */
1878 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
1879 (uint32_t)Get_TD(td->hctd_trans_wrapper));
1880
1881 /* Ensure the DMA cookie is valid for reuse */
1882 ASSERT((tw->tw_cookie_idx == 0) && (tw->tw_dma_offs == 0));
1883
1884 /*
1885 * Take this TD off the transfer wrapper's list since
1886 * the pipe is FIFO, this must be the first TD on the
1887 * list.
1888 */
1889 ASSERT((ohci_td_t *)tw->tw_hctd_head == td);
1890
1891 tw->tw_hctd_head = (ohci_td_t *)
1892 ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_tw_next_td));
1893
1894 /*
1895 * If the head becomes NULL, then there are no more
1896 * active TD's for this transfer wrapper. Also set
1897 * the tail to NULL.
1898 */
1899 if (tw->tw_hctd_head == NULL) {
1900 tw->tw_hctd_tail = NULL;
1901 }
1902
1903 /* Convert current valid TD as new dummy TD */
1904 bzero((char *)td, sizeof (ohci_td_t));
1905 Set_TD(td->hctd_state, HC_TD_DUMMY);
1906
1907 pp = tw->tw_pipe_private;
1908 ph = pp->pp_pipe_handle;
1909
1910 /* Obtain the endpoint and the request */
1911 ept = pp->pp_ept;
1912
1913 /* Get the pipe attribute */
1914 pipe_attr = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK;
1915
1916 switch (pipe_attr) {
1917 case USB_EP_ATTR_INTR:
1918 intr_req = (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
1919
1920 if (intr_req->intr_attributes & USB_ATTRS_SHORT_XFER_OK) {
1921 td_control = HC_TD_IN|HC_TD_1I|HC_TD_R;
1922 } else {
1923 td_control = HC_TD_IN|HC_TD_1I;
1924 }
1925 break;
1926 case USB_EP_ATTR_BULK:
1927 td_control = tw->tw_direction|HC_TD_DT_0|HC_TD_1I|HC_TD_R;
1928 break;
1929 }
1930
1931 /* Get the current dummy */
1932 cpu_current_dummy = (ohci_td_t *)
1933 (ohci_td_iommu_to_cpu(ohcip, Get_ED(ept->hced_tailp)));
1934
1935 /*
1936 * Fill in the current dummy td and
1937 * add the new dummy to the end.
1938 */
1939 ohci_polled_fill_in_td(ohcip, cpu_current_dummy, td,
1940 td_control, 0, tw->tw_length, tw);
1941
1942 /* Insert this td onto the tw */
1943 ohci_polled_insert_td_on_tw(ohcip, tw, cpu_current_dummy);
1944
1945 /*
1946 * Add the new dummy to the ED's list. When this occurs,
1947 * the Host Controller will see the newly filled in dummy
1948 * TD.
1949 */
1950 Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, td)));
1951 }
1952
1953
1954 /*
1955 * ohci_polled_fill_in_td:
1956 *
1957 * Fill in the fields of a Transfer Descriptor (TD).
1958 */
1959 static void
ohci_polled_fill_in_td(ohci_state_t * ohcip,ohci_td_t * td,ohci_td_t * new_dummy,uint_t hctd_ctrl,uint32_t hctd_dma_offs,size_t hctd_length,ohci_trans_wrapper_t * tw)1960 ohci_polled_fill_in_td(
1961 ohci_state_t *ohcip,
1962 ohci_td_t *td,
1963 ohci_td_t *new_dummy,
1964 uint_t hctd_ctrl,
1965 uint32_t hctd_dma_offs,
1966 size_t hctd_length,
1967 ohci_trans_wrapper_t *tw)
1968 {
1969 /* Assert that the td to be filled in is a dummy */
1970 ASSERT(Get_TD(td->hctd_state) == HC_TD_DUMMY);
1971
1972 /* Clear the TD */
1973 bzero((char *)td, sizeof (ohci_td_t));
1974
1975 /* Update the dummy with control information */
1976 Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA));
1977
1978 /* Update the beginning and end of the buffer */
1979 ohci_init_td(ohcip, tw, hctd_dma_offs, hctd_length, td);
1980
1981 /* The current dummy now points to the new dummy */
1982 Set_TD(td->hctd_next_td, (ohci_td_cpu_to_iommu(ohcip, new_dummy)));
1983
1984 /* Fill in the wrapper portion of the TD */
1985 Set_TD(td->hctd_trans_wrapper, (uint32_t)tw->tw_id);
1986 Set_TD(td->hctd_tw_next_td, NULL);
1987 }
1988
1989
1990 /*
1991 * ohci_polled_insert_td_on_tw:
1992 *
1993 * The transfer wrapper keeps a list of all Transfer Descriptors (TD) that
1994 * are allocated for this transfer. Insert a TD onto this list. The list
1995 * of TD's does not include the dummy TD that is at the end of the list of
1996 * TD's for the endpoint.
1997 */
1998 static void
ohci_polled_insert_td_on_tw(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw,ohci_td_t * td)1999 ohci_polled_insert_td_on_tw(
2000 ohci_state_t *ohcip,
2001 ohci_trans_wrapper_t *tw,
2002 ohci_td_t *td)
2003 {
2004
2005 /*
2006 * Set the next pointer to NULL because
2007 * this is the last TD on list.
2008 */
2009 Set_TD(td->hctd_tw_next_td, NULL);
2010
2011 if (tw->tw_hctd_head == NULL) {
2012 ASSERT(tw->tw_hctd_tail == NULL);
2013 tw->tw_hctd_head = td;
2014 tw->tw_hctd_tail = td;
2015 } else {
2016 ohci_td_t *dummy = (ohci_td_t *)tw->tw_hctd_tail;
2017
2018 ASSERT(dummy != NULL);
2019 ASSERT(dummy != td);
2020 ASSERT(Get_TD(td->hctd_state) == HC_TD_DUMMY);
2021
2022 /* Add the td to the end of the list */
2023 Set_TD(dummy->hctd_tw_next_td, ohci_td_cpu_to_iommu(ohcip, td));
2024 tw->tw_hctd_tail = td;
2025
2026 ASSERT(Get_TD(td->hctd_tw_next_td) == 0);
2027 }
2028 }
2029
2030
2031 /*
2032 * ohci_polled_handle_frame_number_overflow:
2033 *
2034 * Process Frame Number Overflow (FNO) interrupt in polled mode.
2035 */
2036 static void
ohci_polled_handle_frame_number_overflow(ohci_state_t * ohcip)2037 ohci_polled_handle_frame_number_overflow(ohci_state_t *ohcip)
2038 {
2039 uint_t intr;
2040
2041 /* Read the Interrupt Status & Interrupt enable register */
2042 intr = (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable));
2043
2044 /*
2045 * Check whether any Frame Number Overflow interrupt is pending
2046 * and if it is pending, process this interrupt.
2047 */
2048 if (intr & HCR_INTR_FNO) {
2049 ohci_handle_frame_number_overflow(ohcip);
2050
2051 /* Acknowledge the FNO interrupt */
2052 ohci_polled_finish_interrupt(ohcip, HCR_INTR_FNO);
2053 }
2054 }
2055
2056
2057 /*
2058 * ohci_polled_finish_interrupt:
2059 */
2060 static void
ohci_polled_finish_interrupt(ohci_state_t * ohcip,uint_t intr)2061 ohci_polled_finish_interrupt(
2062 ohci_state_t *ohcip,
2063 uint_t intr)
2064 {
2065 /* Acknowledge the interrupt */
2066 Set_OpReg(hcr_intr_status, intr);
2067
2068 /*
2069 * Read interrupt status register to make sure that any PIO
2070 * store to clear the ISR has made it on the PCI bus before
2071 * returning from its interrupt handler.
2072 */
2073 (void) Get_OpReg(hcr_intr_status);
2074 }
2075
2076
2077 /*
2078 * ohci_polled_buikin_start:
2079 * Insert bulkin td into endpoint's td list.
2080 */
2081 static void
ohci_polled_insert_bulk_td(ohci_polled_t * ohci_polledp)2082 ohci_polled_insert_bulk_td(
2083 ohci_polled_t *ohci_polledp)
2084 {
2085 ohci_state_t *ohcip;
2086 ohci_trans_wrapper_t *tw;
2087 ohci_pipe_private_t *pp;
2088 usba_pipe_handle_data_t *ph;
2089 uint32_t ctrl;
2090 uint_t bulk_pkg_size;
2091
2092 ohcip = ohci_polledp->ohci_polled_ohcip;
2093 ph = ohci_polledp->ohci_polled_input_pipe_handle;
2094 pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2095
2096 tw = pp->pp_tw_head;
2097 ASSERT(tw != NULL);
2098
2099 ctrl = tw->tw_direction | HC_TD_DT_0 | HC_TD_1I | HC_TD_R;
2100 bulk_pkg_size = min(POLLED_RAW_BUF_SIZE, OHCI_MAX_TD_XFER_SIZE);
2101
2102 (void) ohci_polled_insert_hc_td(ohcip, ctrl, 0, bulk_pkg_size, pp, tw);
2103 }
2104
2105
2106 /*
2107 * ohci_polled_create_tw:
2108 * Create the transfer wrapper used in polled mode.
2109 */
2110 static int
ohci_polled_create_tw(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_flags_t usb_flags)2111 ohci_polled_create_tw(
2112 ohci_state_t *ohcip,
2113 usba_pipe_handle_data_t *ph,
2114 usb_flags_t usb_flags)
2115 {
2116 uint_t ccount;
2117 ohci_trans_wrapper_t *tw;
2118 ddi_device_acc_attr_t dev_attr;
2119 ddi_dma_attr_t dma_attr;
2120 ohci_pipe_private_t *pp;
2121 int result, pipe_dir, td_count;
2122 size_t real_length;
2123
2124 pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2125 td_count = (POLLED_RAW_BUF_SIZE - 1) / OHCI_MAX_TD_XFER_SIZE + 1;
2126
2127 if ((tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t),
2128 KM_NOSLEEP)) == NULL) {
2129 return (USB_FAILURE);
2130 }
2131
2132 /* allow sg lists for transfer wrapper dma memory */
2133 bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t));
2134 dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TW_SGLLEN;
2135 dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT;
2136
2137 /* Allocate the DMA handle */
2138 if ((result = ddi_dma_alloc_handle(ohcip->ohci_dip,
2139 &dma_attr, DDI_DMA_DONTWAIT, 0, &tw->tw_dmahandle)) !=
2140 DDI_SUCCESS) {
2141 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
2142
2143 return (USB_FAILURE);
2144 }
2145
2146 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
2147 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
2148 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
2149
2150 /* Allocate the memory */
2151 if ((result = ddi_dma_mem_alloc(tw->tw_dmahandle, POLLED_RAW_BUF_SIZE,
2152 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
2153 &tw->tw_buf, &real_length, &tw->tw_accesshandle)) !=
2154 DDI_SUCCESS) {
2155 ddi_dma_free_handle(&tw->tw_dmahandle);
2156 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
2157
2158 return (USB_FAILURE);
2159 }
2160
2161 /* Bind the handle */
2162 if ((result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL,
2163 tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
2164 DDI_DMA_DONTWAIT, NULL, &tw->tw_cookie, &ccount)) !=
2165 DDI_DMA_MAPPED) {
2166 ddi_dma_mem_free(&tw->tw_accesshandle);
2167 ddi_dma_free_handle(&tw->tw_dmahandle);
2168 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
2169
2170 return (USB_FAILURE);
2171 }
2172
2173 /* The cookie count should be 1 */
2174 if (ccount != 1) {
2175 result = ddi_dma_unbind_handle(tw->tw_dmahandle);
2176 ASSERT(result == DDI_SUCCESS);
2177
2178 ddi_dma_mem_free(&tw->tw_accesshandle);
2179 ddi_dma_free_handle(&tw->tw_dmahandle);
2180 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
2181
2182 return (USB_FAILURE);
2183 }
2184
2185 if (ohci_allocate_tds_for_tw(ohcip, tw, td_count) == USB_SUCCESS) {
2186 tw->tw_num_tds = td_count;
2187 } else {
2188 ohci_deallocate_tw_resources(ohcip, pp, tw);
2189 return (USB_FAILURE);
2190 }
2191 tw->tw_cookie_idx = 0;
2192 tw->tw_dma_offs = 0;
2193
2194 /*
2195 * Only allow one wrapper to be added at a time. Insert the
2196 * new transaction wrapper into the list for this pipe.
2197 */
2198 if (pp->pp_tw_head == NULL) {
2199 pp->pp_tw_head = tw;
2200 pp->pp_tw_tail = tw;
2201 } else {
2202 pp->pp_tw_tail->tw_next = tw;
2203 pp->pp_tw_tail = tw;
2204 }
2205
2206 /* Store the transfer length */
2207 tw->tw_length = POLLED_RAW_BUF_SIZE;
2208
2209 /* Store a back pointer to the pipe private structure */
2210 tw->tw_pipe_private = pp;
2211
2212 /* Store the transfer type - synchronous or asynchronous */
2213 tw->tw_flags = usb_flags;
2214
2215 /* Get and Store 32bit ID */
2216 tw->tw_id = OHCI_GET_ID((void *)tw);
2217
2218 ASSERT(tw->tw_id != 0);
2219
2220 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
2221 tw->tw_direction = (pipe_dir == USB_EP_DIR_IN) ? HC_TD_IN : HC_TD_OUT;
2222
2223 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
2224 "ohci_create_transfer_wrapper: tw = 0x%p, ncookies = %u",
2225 (void *)tw, tw->tw_ncookies);
2226
2227 return (USB_SUCCESS);
2228 }
2229
2230
2231 /*
2232 * ohci_polled_insert_hc_td:
2233 *
2234 * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED).
2235 */
2236 int
ohci_polled_insert_hc_td(ohci_state_t * ohcip,uint_t hctd_ctrl,uint32_t hctd_dma_offs,size_t hctd_length,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)2237 ohci_polled_insert_hc_td(
2238 ohci_state_t *ohcip,
2239 uint_t hctd_ctrl,
2240 uint32_t hctd_dma_offs,
2241 size_t hctd_length,
2242 ohci_pipe_private_t *pp,
2243 ohci_trans_wrapper_t *tw)
2244 {
2245 ohci_td_t *new_dummy;
2246 ohci_td_t *cpu_current_dummy;
2247 ohci_ed_t *ept = pp->pp_ept;
2248
2249 /* Retrieve preallocated td from the TW */
2250 new_dummy = tw->tw_hctd_free_list;
2251
2252 ASSERT(new_dummy != NULL);
2253
2254 tw->tw_hctd_free_list = ohci_td_iommu_to_cpu(ohcip,
2255 Get_TD(new_dummy->hctd_tw_next_td));
2256 Set_TD(new_dummy->hctd_tw_next_td, NULL);
2257
2258 /* Fill in the current dummy */
2259 cpu_current_dummy = (ohci_td_t *)
2260 (ohci_td_iommu_to_cpu(ohcip, Get_ED(ept->hced_tailp)));
2261
2262 /*
2263 * Fill in the current dummy td and
2264 * add the new dummy to the end.
2265 */
2266 ohci_polled_fill_in_td(ohcip, cpu_current_dummy, new_dummy,
2267 hctd_ctrl, hctd_dma_offs, hctd_length, tw);
2268
2269 /*
2270 * add the new dummy to the ED's list. When
2271 * this occurs, the Host Controller will see
2272 * the newly filled in dummy TD.
2273 */
2274 Set_ED(ept->hced_tailp,
2275 (ohci_td_cpu_to_iommu(ohcip, new_dummy)));
2276
2277 /* Insert this td onto the tw */
2278 ohci_polled_insert_td_on_tw(ohcip, tw, cpu_current_dummy);
2279
2280 return (USB_SUCCESS);
2281 }
2282