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