4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <sys/stropts.h>
29 #include <sys/devops.h>
30 #include <sys/modctl.h>
32 #include <sys/sunddi.h>
33 #include <sys/promif.h>
35 #include <sys/consdev.h>
36 #include <sys/polled_io.h>
39 * consconfig is aware of which devices are the stdin and stout. The
40 * post-attach/pre-detach functions are an extension of consconfig because
41 * they know about the dynamic changes to the stdin device. Neither an
42 * individual driver nor the DDI framework knows what device is really the
47 * o There are probably race conditions between vx_handler for "read"
48 * being called by OBP and the update of the polled_input_t
49 * structure. We need to be careful how the structure is updated.
51 * Solaris/Intel note: While OBP is not in the picture, there are probably
52 * similar issues with kmdb.
55 #if defined(MAYBE_SOMETIME)
56 static void polled_give_input(void);
57 static void polled_take_input(void);
58 static void polled_give_output(void);
59 static void polled_take_output(void);
61 static void polled_io_register(cons_polledio_t
*,
62 polled_io_console_type_t
, int);
64 static void polled_io_unregister(polled_io_console_type_t
, int);
68 * Make the registered device become the console for OBP
70 static int polled_io_take_console(polled_io_console_type_t
, int);
73 * Restore the old console device for OBP.
75 static int polled_io_release_console(polled_io_console_type_t
, int);
76 #endif /* MAYBE_SOMETIME */
78 static polled_device_t polled_input_device
;
79 static polled_device_t polled_output_device
;
82 * This routine is called to initialize polled I/O. We insert our entry
83 * points so that OBP will call into this code when the switch is thrown
84 * in polled_io_take_console().
90 * Initialize lock to protect multiple thread access to the
91 * polled_input_device structure. This does not protect
92 * us from access in OBP mode.
94 mutex_init(&polled_input_device
.polled_device_lock
,
95 NULL
, MUTEX_DRIVER
, NULL
);
98 * Initialize lock to protect multiple thread access to the
99 * polled_output_device structure. This does not protect
100 * us from access in OBP mode.
102 mutex_init(&polled_output_device
.polled_device_lock
,
103 NULL
, MUTEX_DRIVER
, NULL
);
107 * Register a device for input or output. The polled_io structure
108 * will be filled in with the callbacks that are appropriate for
112 polled_io_register_callbacks(
113 cons_polledio_t
*polled_io
,
117 #if defined(MAYBE_SOMETIME)
119 * If the input structure entries are filled in, then register this
120 * structure as an input device.
122 if ((polled_io
->cons_polledio_getchar
!= NULL
) &&
123 (polled_io
->cons_polledio_ischar
!= NULL
)) {
125 polled_io_register(polled_io
,
126 POLLED_IO_CONSOLE_INPUT
, flags
);
130 * If the output structure entries are filled in, then register this
131 * structure as an output device.
133 if (polled_io
->cons_polledio_putchar
!= NULL
) {
135 polled_io_register(polled_io
,
136 POLLED_IO_CONSOLE_OUTPUT
, flags
);
139 _NOTE(ARGUNUSED(flags
))
140 cons_polledio
= polled_io
;
143 return (DDI_SUCCESS
);
147 * Unregister a device for console input/output.
150 polled_io_unregister_callbacks(
151 cons_polledio_t
*polled_io
,
155 #if defined(MAYBE_SOMETIME)
157 * If polled_io is being used for input, then unregister it.
159 if (polled_io
== polled_input_device
.polled_io
) {
161 polled_io_unregister(
162 POLLED_IO_CONSOLE_INPUT
, flags
);
166 * If polled_io is being used for output, then unregister it.
168 if (polled_io
== polled_output_device
.polled_io
) {
170 polled_io_unregister(
171 POLLED_IO_CONSOLE_OUTPUT
, flags
);
174 _NOTE(ARGUNUSED(polled_io
,flags
))
175 #endif /* MAYBE_SOMETIME */
177 return (DDI_SUCCESS
);
181 * This routine is called when we are done handling polled io. We will
182 * remove all of our handlers and destroy any memory that we have allocated.
188 * Destroy the mutexes, we will not need them anymore.
190 mutex_destroy(&polled_input_device
.polled_device_lock
);
192 mutex_destroy(&polled_output_device
.polled_device_lock
);
195 #if defined(MAYBE_SOMETIME)
197 * Generic internal routine for registering a polled input or output device.
202 cons_polledio_t
*polled_io
,
203 polled_io_console_type_t type
,
208 case POLLED_IO_CONSOLE_INPUT
:
210 * Grab the device lock, because we are going to access
211 * protected structure entries. We do this before the
212 * POLLED_IO_CONSOLE_OPEN_INPUT so that we serialize
215 mutex_enter(&polled_input_device
.polled_device_lock
);
218 * Save the polled_io pointers so that we can access
221 polled_input_device
.polled_io
= polled_io
;
223 mutex_exit(&polled_input_device
.polled_device_lock
);
226 * Tell the generic console framework to
227 * repoint OBP's stdin to this keyboard device.
229 (void) polled_io_take_console(type
, 0);
233 case POLLED_IO_CONSOLE_OUTPUT
:
235 * Grab the device lock, because we are going to access
236 * protected structure entries. We do this before the
237 * POLLED_IO_CONSOLE_OPEN_OUTPUT so that we serialize
240 mutex_enter(&polled_output_device
.polled_device_lock
);
243 * Save the polled_io pointers so that we can access
246 polled_input_device
.polled_io
= polled_io
;
248 mutex_exit(&polled_output_device
.polled_device_lock
);
255 * Generic internal routine for unregistering a polled input or output device.
259 polled_io_unregister(
260 polled_io_console_type_t type
,
265 case POLLED_IO_CONSOLE_INPUT
:
267 * Tell the generic console framework to restore OBP's
268 * old stdin pointers.
270 (void) polled_io_release_console(type
, 0);
273 * Grab the device lock, because we are going to access
274 * protected structure entries.
276 mutex_enter(&polled_input_device
.polled_device_lock
);
279 * We are closing the device, so get the value for the op
280 * pointer. We use the polled_io structure to determine if
281 * there is a device registered, so null the dev_ops
284 polled_input_device
.polled_io
= NULL
;
286 mutex_exit(&polled_input_device
.polled_device_lock
);
290 case POLLED_IO_CONSOLE_OUTPUT
:
292 * Grab the device lock, because we are going to access
293 * protected structure entries.
295 mutex_enter(&polled_output_device
.polled_device_lock
);
298 * We are closing the device, so get the value for the op
299 * pointer. We use the polled_io structure to determine if
300 * there is a device registered.
302 polled_output_device
.polled_io
= NULL
;
304 mutex_exit(&polled_output_device
.polled_device_lock
);
311 * This is the routine that is called to throw the switch from boot
312 * ownership of stdout/stdin to the kernel.
316 polled_io_take_console(
317 polled_io_console_type_t type
,
322 case POLLED_IO_CONSOLE_INPUT
:
324 * Perhaps this should be where we switch *sysp
328 case POLLED_IO_CONSOLE_OUTPUT
:
330 * Perhaps this should be where we switch *sysp
335 return (DDI_SUCCESS
);
339 * This routine gives control of console input/output back to ???.
341 * Solaris/Intel has nobody to give it back to. Hope we don't get here!
345 polled_io_release_console(
346 polled_io_console_type_t type
,
351 "polled_io_release_console: nobody to hand console back to");
353 return (DDI_SUCCESS
);
357 * This is the routine that kmdb calls to save any state information
358 * before using the input device. This routine, and all of the
359 * routines that it calls, are responsible for saving any state
360 * information so that it can be restored when polled mode is over.
363 polled_give_input(void)
365 cons_polledio_t
*polled_io
;
368 * We check the dev_ops pointer to see if there is an
369 * input device that has been registered.
371 polled_io
= polled_input_device
.polled_io
;
373 if (polled_io
== NULL
|| polled_io
->cons_polledio_enter
== NULL
) {
378 * Call down to the lower layers to save the state.
380 polled_io
->cons_polledio_enter(
381 polled_io
->cons_polledio_argument
);
385 * This is the routine that kmdb calls when it is giving up control of the
386 * input device. This routine, and the lower layer routines that it calls,
387 * are responsible for restoring the controller state to the state it was
388 * in before kmdb took control.
391 polled_take_input(void)
393 cons_polledio_t
*polled_io
;
396 * We check the dev_ops pointer to see if there is an
397 * input device that has been registered.
399 polled_io
= polled_input_device
.polled_io
;
401 if (polled_io
== NULL
|| polled_io
->cons_polledio_exit
== NULL
) {
406 * Call down to the lower layers to save the state.
408 polled_io
->cons_polledio_exit(
409 polled_io
->cons_polledio_argument
);
413 * This is the routine that kmdb calls to save any state information
414 * before using the output device. This routine, and all of the
415 * routines that it calls, are responsible for saving any state
416 * information so that it can be restored when polled mode is over.
421 cons_polledio_t
*polled_io
;
424 * We check the dev_ops pointer to see if there is an
425 * output device that has been registered.
427 polled_io
= polled_output_device
.polled_io
;
429 if (polled_io
== NULL
|| polled_io
->cons_polledio_enter
== NULL
) {
434 * Call down to the lower layers to save the state.
436 polled_io
->cons_polledio_enter(
437 polled_io
->cons_polledio_argument
);
441 * This is the routine that kmdb calls when it is giving up control of the
442 * output device. This routine, and the lower layer routines that it calls,
443 * are responsible for restoring the controller state to the state it was
444 * in before kmdb took control.
447 polled_take_output(void)
449 cons_polledio_t
*polled_io
;
452 * We check the dev_ops pointer to see if there is an
453 * output device that has been registered.
455 polled_io
= polled_output_device
.polled_io
;
457 if (polled_io
== NULL
|| polled_io
->cons_polledio_exit
== NULL
) {
462 * Call down to the lower layers to save the state.
464 polled_io
->cons_polledio_exit(
465 polled_io
->cons_polledio_argument
);
467 #endif /* MAYBE_SOMETIME */