xref: /onnv-gate/usr/src/uts/common/io/usb/usba/genconsole.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate /*
29*0Sstevel@tonic-gate  * USBA: Solaris USB Architecture support
30*0Sstevel@tonic-gate  *
31*0Sstevel@tonic-gate  * ISSUES:
32*0Sstevel@tonic-gate  */
33*0Sstevel@tonic-gate #define	USBA_FRAMEWORK
34*0Sstevel@tonic-gate #include <sys/usb/usba.h>
35*0Sstevel@tonic-gate #include <sys/usb/usba/hcdi.h>
36*0Sstevel@tonic-gate #include <sys/usb/usba/genconsole.h>
37*0Sstevel@tonic-gate #include <sys/usb/usba/usba_types.h>
38*0Sstevel@tonic-gate #include <sys/usb/usba/usba_impl.h>
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate /*
41*0Sstevel@tonic-gate  * Initialize USB OBP support.	This routine calls down to the lower
42*0Sstevel@tonic-gate  * layers to initialize any state information.
43*0Sstevel@tonic-gate  */
44*0Sstevel@tonic-gate int
45*0Sstevel@tonic-gate usb_console_input_init(dev_info_t		*dip,
46*0Sstevel@tonic-gate 			usb_pipe_handle_t	pipe_handle,
47*0Sstevel@tonic-gate 			uchar_t			**obp_buf,
48*0Sstevel@tonic-gate 			usb_console_info_t	*console_input_info)
49*0Sstevel@tonic-gate {
50*0Sstevel@tonic-gate 	int			ret;
51*0Sstevel@tonic-gate 	usba_device_t		*usba_device;
52*0Sstevel@tonic-gate 	usb_console_info_impl_t	*usb_console_input = kmem_zalloc(
53*0Sstevel@tonic-gate 			sizeof (struct usb_console_info_impl), KM_SLEEP);
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate 	/*
56*0Sstevel@tonic-gate 	 * Save the dip
57*0Sstevel@tonic-gate 	 */
58*0Sstevel@tonic-gate 	usb_console_input->uci_dip = dip;
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate 	/*
61*0Sstevel@tonic-gate 	 * Translate the dip into a device.
62*0Sstevel@tonic-gate 	 */
63*0Sstevel@tonic-gate 	usba_device = usba_get_usba_device(dip);
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	/*
66*0Sstevel@tonic-gate 	 * Call the lower layer to initialize any state information
67*0Sstevel@tonic-gate 	 */
68*0Sstevel@tonic-gate 	ret = usba_device->usb_hcdi_ops->usba_hcdi_console_input_init(
69*0Sstevel@tonic-gate 		usba_get_ph_data(pipe_handle), obp_buf, usb_console_input);
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate 	if (ret != USB_SUCCESS) {
72*0Sstevel@tonic-gate 		kmem_free(usb_console_input,
73*0Sstevel@tonic-gate 			sizeof (struct usb_console_info_impl));
74*0Sstevel@tonic-gate 	} else {
75*0Sstevel@tonic-gate 		*console_input_info = (usb_console_info_t)usb_console_input;
76*0Sstevel@tonic-gate 	}
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate 	return (ret);
79*0Sstevel@tonic-gate }
80*0Sstevel@tonic-gate 
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate /*
83*0Sstevel@tonic-gate  * Free up any resources that we allocated in the above initialization
84*0Sstevel@tonic-gate  * routine.
85*0Sstevel@tonic-gate  */
86*0Sstevel@tonic-gate int
87*0Sstevel@tonic-gate usb_console_input_fini(usb_console_info_t console_input_info)
88*0Sstevel@tonic-gate {
89*0Sstevel@tonic-gate 	usb_console_info_impl_t		*usb_console_input;
90*0Sstevel@tonic-gate 	usba_device_t			*usba_device;
91*0Sstevel@tonic-gate 	int				ret;
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 	usb_console_input = (usb_console_info_impl_t *)console_input_info;
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 	/*
96*0Sstevel@tonic-gate 	 * Translate the dip into a device.
97*0Sstevel@tonic-gate 	 */
98*0Sstevel@tonic-gate 	usba_device = usba_get_usba_device(usb_console_input->uci_dip);
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate 	/*
101*0Sstevel@tonic-gate 	 * Call the lower layer to free any state information.
102*0Sstevel@tonic-gate 	 */
103*0Sstevel@tonic-gate 	ret = usba_device->usb_hcdi_ops->usba_hcdi_console_input_fini(
104*0Sstevel@tonic-gate 		usb_console_input);
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate 	if (ret == USB_FAILURE) {
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 		return (ret);
109*0Sstevel@tonic-gate 	}
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 	/*
112*0Sstevel@tonic-gate 	 * We won't be needing this information anymore.
113*0Sstevel@tonic-gate 	 */
114*0Sstevel@tonic-gate 	kmem_free(usb_console_input, sizeof (struct usb_console_info_impl));
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 	return (USB_SUCCESS);
117*0Sstevel@tonic-gate }
118*0Sstevel@tonic-gate 
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate /*
121*0Sstevel@tonic-gate  * This is the routine that OBP calls to save the USB state information
122*0Sstevel@tonic-gate  * before using the USB keyboard as an input device.  This routine,
123*0Sstevel@tonic-gate  * and all of the routines that it calls, are responsible for saving
124*0Sstevel@tonic-gate  * any state information so that it can be restored when OBP mode is
125*0Sstevel@tonic-gate  * over.  At this layer, this code is mainly just a pass through.
126*0Sstevel@tonic-gate  *
127*0Sstevel@tonic-gate  * Warning:  this code runs in polled mode.
128*0Sstevel@tonic-gate  */
129*0Sstevel@tonic-gate int
130*0Sstevel@tonic-gate usb_console_input_enter(usb_console_info_t console_input_info)
131*0Sstevel@tonic-gate {
132*0Sstevel@tonic-gate 	usba_device_t				*usba_device;
133*0Sstevel@tonic-gate 	usb_console_info_impl_t			*usb_console_input;
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	usb_console_input = (usb_console_info_impl_t *)console_input_info;
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 	/*
138*0Sstevel@tonic-gate 	 * Translate the dip into a device.
139*0Sstevel@tonic-gate 	 * Do this by directly looking at the dip, do not call
140*0Sstevel@tonic-gate 	 * usba_get_usba_device() because this function calls into the DDI.
141*0Sstevel@tonic-gate 	 * The ddi then tries to acquire a mutex and the machine hard hangs.
142*0Sstevel@tonic-gate 	 */
143*0Sstevel@tonic-gate 	usba_device = usba_polled_get_usba_device(usb_console_input->uci_dip);
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate 	/*
146*0Sstevel@tonic-gate 	 * Call the lower layer to save state information.
147*0Sstevel@tonic-gate 	 */
148*0Sstevel@tonic-gate 	usba_device->usb_hcdi_ops->usba_hcdi_console_input_enter(
149*0Sstevel@tonic-gate 		usb_console_input);
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 	return (USB_SUCCESS);
152*0Sstevel@tonic-gate }
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate /*
156*0Sstevel@tonic-gate  * This is the routine that OBP calls when it wants to read a character.
157*0Sstevel@tonic-gate  * We will call to the lower layers to see if there is any input data
158*0Sstevel@tonic-gate  * available.  At this layer, this code is mainly just a pass through.
159*0Sstevel@tonic-gate  *
160*0Sstevel@tonic-gate  * Warning: This code runs in polled mode.
161*0Sstevel@tonic-gate  */
162*0Sstevel@tonic-gate int
163*0Sstevel@tonic-gate usb_console_read(usb_console_info_t console_input_info, uint_t *num_characters)
164*0Sstevel@tonic-gate {
165*0Sstevel@tonic-gate 	usba_device_t				*usba_device;
166*0Sstevel@tonic-gate 	usb_console_info_impl_t			*usb_console_input;
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate 	usb_console_input = (usb_console_info_impl_t *)console_input_info;
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate 	/*
171*0Sstevel@tonic-gate 	 * Translate the dip into a device.
172*0Sstevel@tonic-gate 	 * Do this by directly looking at the dip, do not call
173*0Sstevel@tonic-gate 	 * usba_get_usba_device() because this function calls into the DDI.
174*0Sstevel@tonic-gate 	 * The ddi then tries to acquire a mutex and the machine hard hangs.
175*0Sstevel@tonic-gate 	 */
176*0Sstevel@tonic-gate 	usba_device = usba_polled_get_usba_device(usb_console_input->uci_dip);
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate 	/*
179*0Sstevel@tonic-gate 	 * Call the lower layer to get a a character.  Return the number
180*0Sstevel@tonic-gate 	 * of characters read into the buffer.
181*0Sstevel@tonic-gate 	 */
182*0Sstevel@tonic-gate 	return (usba_device->usb_hcdi_ops->usba_hcdi_console_read(
183*0Sstevel@tonic-gate 		usb_console_input, num_characters));
184*0Sstevel@tonic-gate }
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate /*
188*0Sstevel@tonic-gate  * This is the routine that OBP calls when it is giving up control of the
189*0Sstevel@tonic-gate  * USB keyboard.  This routine, and the lower layer routines that it calls,
190*0Sstevel@tonic-gate  * are responsible for restoring the controller state to the state it was
191*0Sstevel@tonic-gate  * in before OBP took control. At this layer, this code is mainly just a
192*0Sstevel@tonic-gate  * pass through.
193*0Sstevel@tonic-gate  *
194*0Sstevel@tonic-gate  * Warning: This code runs in polled mode.
195*0Sstevel@tonic-gate  */
196*0Sstevel@tonic-gate int
197*0Sstevel@tonic-gate usb_console_input_exit(usb_console_info_t console_input_info)
198*0Sstevel@tonic-gate {
199*0Sstevel@tonic-gate 	usba_device_t				*usba_device;
200*0Sstevel@tonic-gate 	usb_console_info_impl_t			*usb_console_input;
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate 	usb_console_input = (usb_console_info_impl_t *)console_input_info;
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 	/*
205*0Sstevel@tonic-gate 	 * Translate the dip into a device.
206*0Sstevel@tonic-gate 	 * Do this by directly looking at the dip, do not call
207*0Sstevel@tonic-gate 	 * usba_get_usba_device() because this function calls into the DDI.
208*0Sstevel@tonic-gate 	 * The ddi then tries to acquire a mutex and the machine hard hangs.
209*0Sstevel@tonic-gate 	 */
210*0Sstevel@tonic-gate 	usba_device = usba_polled_get_usba_device(usb_console_input->uci_dip);
211*0Sstevel@tonic-gate 
212*0Sstevel@tonic-gate 	/*
213*0Sstevel@tonic-gate 	 * Restore the state information.
214*0Sstevel@tonic-gate 	 */
215*0Sstevel@tonic-gate 	usba_device->usb_hcdi_ops->usba_hcdi_console_input_exit(
216*0Sstevel@tonic-gate 		usb_console_input);
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 	return (USB_SUCCESS);
219*0Sstevel@tonic-gate }
220