xref: /titanic_50/usr/src/uts/common/io/usb/hcd/openhci/ohci_polled.c (revision 9b58c2ad19d1f06f07604b0f61b7ff38f757c8fa)
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