Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
9259 libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/consconfig_dacf.c
+++ new/usr/src/uts/common/io/consconfig_dacf.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * This module performs two functions. First, it kicks off the driver loading
29 29 * of the console devices during boot in dynamic_console_config().
30 30 * The loading of the drivers for the console devices triggers the
31 31 * additional device autoconfiguration to link the drivers into the keyboard
32 32 * and mouse console streams.
33 33 *
34 34 * The second function of this module is to provide the dacf functions
35 35 * to be called after a driver has attached and before it detaches. For
36 36 * example, a driver associated with the keyboard will have kb_config called
37 37 * after the driver attaches and kb_unconfig before it detaches. Similar
38 38 * configuration actions are performed on behalf of minor nodes representing
39 39 * mice. The configuration functions for the attach case take a module
40 40 * name as a parameter. The module is pushed on top of the driver during
41 41 * the configuration.
42 42 *
43 43 * Although the dacf framework is used to configure all keyboards and mice,
44 44 * its primary function is to allow keyboard and mouse hotplugging.
45 45 *
46 46 * This module supports multiple keyboards and mice at the same time.
47 47 *
48 48 * From the kernel perspective, there are roughly three different possible
49 49 * console configurations. Across these three configurations, the following
50 50 * elements are constant:
51 51 * wsconsvp = IWSCN_PATH
52 52 * rwsconsvp = WC_PATH
53 53 * consms -> msdev
54 54 *
55 55 * The "->" syntax indicates that the streams device on the right is
56 56 * linked under the streams device on the left.
57 57 *
58 58 * The following lists how the system is configured for different setups:
59 59 *
60 60 * stdin is a local keyboard. use stdin and stdout as the console.
61 61 * sp->cons_input_type = CONSOLE_LOCAL
62 62 * rconsvp = IWSCN_PATH
63 63 * wc -> conskbd -> kbddev
64 64 *
65 65 * stdin is not a keyboard and stdin is the same as stdout.
66 66 * assume we running on a tip line and use stdin/stdout as the console.
67 67 * sp->cons_input_type = CONSOLE_TIP
68 68 * rconsvp = (stdindev/stdoutdev)
69 69 * wc -> conskbd -> kbddev
70 70 *
71 71 * stdin is not a keyboard device and it's not the same as stdout.
72 72 * assume we have a serial keyboard hooked up and use it along with
73 73 * stdout as the console.
74 74 * sp->cons_input_type = CONSOLE_SERIAL_KEYBOARD
75 75 * rconsvp = IWSCN_PATH
76 76 * wc -> stdindev
77 77 * conskbd -> kbddev
78 78 *
79 79 * CAVEAT:
80 80 * The above is all true except for one possible Intel configuration.
81 81 * If stdin is set to a local keyboard but stdout is set to something
82 82 * other than the local display (a tip port for example) stdout will
83 83 * still go to the local display. This is an artifact of the console
84 84 * implementation on intel.
85 85 */
86 86
87 87 #include <sys/types.h>
88 88 #include <sys/param.h>
89 89 #include <sys/cmn_err.h>
90 90 #include <sys/user.h>
91 91 #include <sys/vfs.h>
92 92 #include <sys/vnode.h>
93 93 #include <sys/pathname.h>
94 94 #include <sys/systm.h>
95 95 #include <sys/file.h>
96 96 #include <sys/stropts.h>
97 97 #include <sys/stream.h>
98 98 #include <sys/strsubr.h>
99 99
100 100 #include <sys/consdev.h>
101 101 #include <sys/console.h>
102 102 #include <sys/wscons.h>
103 103 #include <sys/kbio.h>
104 104 #include <sys/debug.h>
105 105 #include <sys/reboot.h>
106 106 #include <sys/termios.h>
107 107
108 108 #include <sys/ddi.h>
109 109 #include <sys/sunddi.h>
110 110 #include <sys/sunldi.h>
111 111 #include <sys/sunndi.h>
112 112 #include <sys/ndi_impldefs.h>
113 113 #include <sys/modctl.h>
114 114 #include <sys/ddi_impldefs.h>
115 115 #include <sys/ddi_implfuncs.h>
116 116 #include <sys/promif.h>
117 117 #include <sys/fs/snode.h>
118 118
119 119 #include <sys/errno.h>
120 120 #include <sys/devops.h>
121 121 #include <sys/note.h>
122 122
123 123 #include <sys/tem_impl.h>
124 124 #include <sys/polled_io.h>
125 125 #include <sys/kmem.h>
126 126 #include <sys/dacf.h>
127 127 #include <sys/consconfig_dacf.h>
128 128 #include <sys/consplat.h>
129 129 #include <sys/log.h>
130 130 #include <sys/disp.h>
131 131
132 132 /*
133 133 * External global variables
134 134 */
135 135 extern vnode_t *rconsvp;
136 136 extern dev_t rwsconsdev;
137 137
138 138 /*
139 139 * External functions
140 140 */
141 141 extern uintptr_t space_fetch(char *key);
142 142 extern int space_store(char *key, uintptr_t ptr);
143 143
144 144 /*
145 145 * Tasks
146 146 */
147 147 static int kb_config(dacf_infohdl_t, dacf_arghdl_t, int);
148 148 static int kb_unconfig(dacf_infohdl_t, dacf_arghdl_t, int);
149 149 static int ms_config(dacf_infohdl_t, dacf_arghdl_t, int);
150 150 static int ms_unconfig(dacf_infohdl_t, dacf_arghdl_t, int);
151 151
152 152 /*
153 153 * Internal functions
154 154 */
155 155 static int consconfig_setmodes(dev_t dev, struct termios *termiosp);
156 156 static void consconfig_check_phys_kbd(cons_state_t *);
157 157 static void consconfig_rem_dev(cons_state_t *, dev_t);
158 158 static void consconfig_add_dev(cons_state_t *, cons_prop_t *);
159 159 static cons_prop_t *consconfig_find_dev(cons_state_t *, dev_t);
160 160 static void consconfig_free_prop(cons_prop_t *prop);
161 161 static void flush_deferred_console_buf(void);
162 162
163 163
164 164 /*
165 165 * On supported configurations, the firmware defines the keyboard and mouse
166 166 * paths. However, during USB development, it is useful to be able to use
167 167 * the USB keyboard and mouse on machines without full USB firmware support.
168 168 * These variables may be set in /etc/system according to a machine's
169 169 * USB configuration. This module will override the firmware's values
170 170 * with these.
171 171 *
172 172 * NOTE:
173 173 * The master copies of these variables in the misc/consconfig module.
174 174 * The reason for this is historic. In versions of solaris up to and
175 175 * including solaris 9 the conscole configuration code was split into a
176 176 * seperate sparc and intel version. These variables were defined
177 177 * in misc/consconfig on sparc and dacf/consconfig_dacf on intel.
178 178 *
179 179 * Unfortunatly the sparc variables were well documented.
180 180 * So to aviod breaking either sparc or intel we'll declare the variables
181 181 * in both modules. This will allow any /etc/system entries that
182 182 * users may have to continue working.
183 183 *
184 184 * The variables in misc/consconfig will take precedence over the variables
185 185 * found in this file. Since we eventually want to remove the variables
186 186 * local to this this file, if the user set them we'll emmit an error
187 187 * message telling them they need to set the variables in misc/consconfig
188 188 * instead.
189 189 */
190 190 static char *usb_kb_path = NULL;
191 191 static char *usb_ms_path = NULL;
192 192
193 193 /*
194 194 * Access functions in the misc/consconfig module used to retrieve the
195 195 * values of it local usb_kb_path and usb_ms_path variables
196 196 */
197 197 extern char *consconfig_get_usb_kb_path();
198 198 extern char *consconfig_get_usb_ms_path();
199 199
200 200 /*
201 201 * Local variables used to store the value of the usb_kb_path and
202 202 * usb_ms_path variables found in misc/consconfig
203 203 */
204 204 static char *consconfig_usb_kb_path = NULL;
205 205 static char *consconfig_usb_ms_path = NULL;
206 206
207 207 /*
208 208 * Internal variables
209 209 */
210 210 static dev_t stdoutdev;
211 211 static cons_state_t *consconfig_sp;
212 212
213 213 /*
214 214 * consconfig_errlevel: debug verbosity; smaller numbers are more
215 215 * verbose.
216 216 */
217 217 int consconfig_errlevel = DPRINT_L3;
218 218
219 219 /*
220 220 * Baud rate table
221 221 */
222 222 static struct speed {
223 223 char *name;
224 224 int code;
225 225 } speedtab[] = {
226 226 {"0", B0}, {"50", B50}, {"75", B75},
227 227 {"110", B110}, {"134", B134}, {"150", B150},
228 228 {"200", B200}, {"300", B300}, {"600", B600},
229 229 {"1200", B1200}, {"1800", B1800}, {"2400", B2400},
230 230 {"4800", B4800}, {"9600", B9600}, {"19200", B19200},
231 231 {"38400", B38400}, {"57600", B57600}, {"76800", B76800},
232 232 {"115200", B115200}, {"153600", B153600}, {"230400", B230400},
233 233 {"307200", B307200}, {"460800", B460800}, {"921600", B921600},
234 234 {"", 0}
235 235 };
236 236
237 237 static const int MAX_SPEEDS = sizeof (speedtab) / sizeof (speedtab[0]);
238 238
239 239 static dacf_op_t kbconfig_op[] = {
240 240 { DACF_OPID_POSTATTACH, kb_config },
241 241 { DACF_OPID_PREDETACH, kb_unconfig },
242 242 { DACF_OPID_END, NULL },
243 243 };
244 244
245 245 static dacf_op_t msconfig_op[] = {
246 246 { DACF_OPID_POSTATTACH, ms_config },
247 247 { DACF_OPID_PREDETACH, ms_unconfig },
248 248 { DACF_OPID_END, NULL },
249 249 };
250 250
251 251 static dacf_opset_t opsets[] = {
252 252 { "kb_config", kbconfig_op },
253 253 { "ms_config", msconfig_op },
254 254 { NULL, NULL }
255 255 };
256 256
257 257 struct dacfsw dacfsw = {
258 258 DACF_MODREV_1,
259 259 opsets,
260 260 };
261 261
262 262 static struct modldacf modldacf = {
263 263 &mod_dacfops, /* Type of module */
264 264 "Consconfig DACF",
265 265 &dacfsw
266 266 };
267 267
268 268 static struct modlinkage modlinkage = {
269 269 MODREV_1, (void *)&modldacf, NULL
270 270 };
271 271
272 272 int
273 273 _init(void)
274 274 {
275 275 return (mod_install(&modlinkage));
276 276 }
277 277
278 278 int
279 279 _fini(void)
280 280 {
281 281 /*
282 282 * This modules state is held in the kernel by space.c
283 283 * allowing this module to be unloaded.
284 284 */
285 285 return (mod_remove(&modlinkage));
286 286 }
287 287
288 288 int
289 289 _info(struct modinfo *modinfop)
290 290 {
291 291 return (mod_info(&modlinkage, modinfop));
292 292 }
293 293
294 294 /*PRINTFLIKE2*/
295 295 static void consconfig_dprintf(int, const char *, ...)
296 296 __KPRINTFLIKE(2);
297 297
298 298 static void
299 299 consconfig_dprintf(int l, const char *fmt, ...)
300 300 {
301 301 va_list ap;
302 302
303 303 #ifndef DEBUG
304 304 if (!l) {
305 305 return;
306 306 }
307 307 #endif /* DEBUG */
308 308 if (l < consconfig_errlevel) {
309 309 return;
310 310 }
311 311
312 312 va_start(ap, fmt);
313 313 (void) vprintf(fmt, ap);
314 314 va_end(ap);
315 315 }
316 316
317 317 /*
318 318 * Return a property value for the specified alias in /aliases.
319 319 */
320 320 char *
321 321 get_alias(char *alias, char *buf)
322 322 {
323 323 pnode_t node;
324 324 int len;
325 325
326 326 /* The /aliases node only exists in OBP >= 2.4. */
327 327 if ((node = prom_alias_node()) == OBP_BADNODE)
328 328 return (NULL);
329 329
330 330 if ((len = prom_getproplen(node, (caddr_t)alias)) <= 0)
331 331 return (NULL);
332 332
333 333 (void) prom_getprop(node, (caddr_t)alias, (caddr_t)buf);
334 334
335 335 /*
336 336 * The IEEE 1275 standard specifies that /aliases string property
337 337 * values should be null-terminated. Unfortunatly the reality
338 338 * is that most aren't and the OBP can't easily be modified to
339 339 * add null termination to these strings. So we'll add the
340 340 * null termination here. If the string already contains a
341 341 * null termination character then that's ok too because we'll
342 342 * just be adding a second one.
343 343 */
344 344 buf[len] = '\0';
345 345
346 346 prom_pathname(buf);
347 347 return (buf);
348 348 }
349 349
350 350 /*
351 351 * i_consconfig_createvp:
352 352 * This routine is a convenience routine that is passed a path and returns
353 353 * a vnode.
354 354 */
355 355 static vnode_t *
356 356 i_consconfig_createvp(char *path)
357 357 {
358 358 int error;
359 359 vnode_t *vp;
360 360 char *buf = NULL, *fullpath;
361 361
362 362 DPRINTF(DPRINT_L0, "i_consconfig_createvp: %s\n", path);
363 363 fullpath = kmem_alloc(MAXPATHLEN, KM_SLEEP);
364 364
365 365 if (strchr(path, ':') == NULL) {
366 366 /* convert an OBP path to a /devices path */
367 367 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
368 368 if (i_ddi_prompath_to_devfspath(path, buf) != DDI_SUCCESS) {
369 369 kmem_free(buf, MAXPATHLEN);
370 370 kmem_free(fullpath, MAXPATHLEN);
371 371 return (NULL);
372 372 }
373 373 (void) snprintf(fullpath, MAXPATHLEN, "/devices%s", buf);
374 374 kmem_free(buf, MAXPATHLEN);
375 375 } else {
376 376 /* convert a devfs path to a /devices path */
377 377 (void) snprintf(fullpath, MAXPATHLEN, "/devices%s", path);
378 378 }
379 379
380 380 DPRINTF(DPRINT_L0, "lookupname(%s)\n", fullpath);
381 381 error = lookupname(fullpath, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp);
382 382 kmem_free(fullpath, MAXPATHLEN);
383 383 if (error)
384 384 return (NULL);
385 385
386 386 DPRINTF(DPRINT_L0, "create vnode = 0x%p - dev 0x%lx\n", vp, vp->v_rdev);
387 387 ASSERT(vn_matchops(vp, spec_getvnodeops()));
388 388
389 389 return (vp);
390 390 }
391 391
392 392 /*
393 393 * consconfig_print_paths:
394 394 * Function to print out the various paths
395 395 */
396 396 static void
397 397 consconfig_print_paths(void)
398 398 {
399 399 char *path;
400 400
401 401 if (usb_kb_path != NULL)
402 402 cmn_err(CE_WARN,
403 403 "consconfig_dacf:usb_kb_path has been deprecated, "
404 404 "use consconfig:usb_kb_path instead");
405 405
406 406 if (usb_ms_path != NULL)
407 407 cmn_err(CE_WARN,
408 408 "consconfig_dacf:usb_ms_path has been deprecated, "
409 409 "use consconfig:usb_ms_path instead");
410 410
411 411 if (consconfig_errlevel > DPRINT_L0)
412 412 return;
413 413
414 414 path = NULL;
415 415 if (consconfig_usb_kb_path != NULL)
416 416 path = consconfig_usb_kb_path;
417 417 else if (usb_kb_path != NULL)
418 418 path = usb_kb_path;
419 419 if (path != NULL)
420 420 DPRINTF(DPRINT_L0, "usb keyboard path = %s\n", path);
421 421
422 422 path = plat_kbdpath();
423 423 if (path != NULL)
424 424 DPRINTF(DPRINT_L0, "keyboard path = %s\n", path);
425 425
426 426 path = NULL;
427 427 if (consconfig_usb_ms_path != NULL)
428 428 path = consconfig_usb_ms_path;
429 429 else if (usb_ms_path != NULL)
430 430 path = usb_ms_path;
431 431 if (path != NULL)
432 432 DPRINTF(DPRINT_L0, "usb mouse path = %s\n", path);
433 433
434 434 path = plat_mousepath();
435 435 if (path != NULL)
|
↓ open down ↓ |
435 lines elided |
↑ open up ↑ |
436 436 DPRINTF(DPRINT_L0, "mouse path = %s\n", path);
437 437
438 438 path = plat_stdinpath();
439 439 if (path != NULL)
440 440 DPRINTF(DPRINT_L0, "stdin path = %s\n", path);
441 441
442 442 path = plat_stdoutpath();
443 443 if (path != NULL)
444 444 DPRINTF(DPRINT_L0, "stdout path = %s\n", path);
445 445
446 + path = plat_diagpath();
447 + if (path != NULL)
448 + DPRINTF(DPRINT_L0, "diag path = %s\n", path);
449 +
446 450 path = plat_fbpath();
447 451 if (path != NULL)
448 452 DPRINTF(DPRINT_L0, "fb path = %s\n", path);
449 453 }
450 454
451 455 /*
452 456 * consconfig_kbd_abort_enable:
453 457 * Send the CONSSETABORTENABLE ioctl to the lower layers. This ioctl
454 458 * will only be sent to the device if it is the console device.
455 459 * This ioctl tells the device to pay attention to abort sequences.
456 460 * In the case of kbtrans, this would tell the driver to pay attention
457 461 * to the two key abort sequences like STOP-A. In the case of the
458 462 * serial keyboard, it would be an abort sequence like a break.
459 463 */
460 464 static int
461 465 consconfig_kbd_abort_enable(ldi_handle_t lh)
462 466 {
463 467 int err, rval;
464 468
465 469 DPRINTF(DPRINT_L0, "consconfig_kbd_abort_enable\n");
466 470
467 471 err = ldi_ioctl(lh, CONSSETABORTENABLE, (uintptr_t)B_TRUE,
468 472 FKIOCTL, kcred, &rval);
469 473 return (err);
470 474 }
471 475
472 476 /*
473 477 * consconfig_kbd_abort_disable:
474 478 * Send CONSSETABORTENABLE ioctl to lower layers. This ioctl
475 479 * will only be sent to the device if it is the console device.
476 480 * This ioctl tells the physical device to ignore abort sequences,
477 481 * and send the sequences up to virtual keyboard(conskbd) so that
478 482 * STOP and A (or F1 and A) can be combined.
479 483 */
480 484 static int
481 485 consconfig_kbd_abort_disable(ldi_handle_t lh)
482 486 {
483 487 int err, rval;
484 488
485 489 DPRINTF(DPRINT_L0, "consconfig_kbd_abort_disable\n");
486 490
487 491 err = ldi_ioctl(lh, CONSSETABORTENABLE, (uintptr_t)B_FALSE,
488 492 FKIOCTL, kcred, &rval);
489 493 return (err);
490 494 }
491 495
492 496 #ifdef _HAVE_TEM_FIRMWARE
493 497 static int
494 498 consconfig_tem_supported(cons_state_t *sp)
495 499 {
496 500 dev_t dev;
497 501 dev_info_t *dip;
498 502 int *int_array;
499 503 uint_t nint;
500 504 int rv = 0;
501 505
502 506 if (sp->cons_fb_path == NULL)
503 507 return (0);
504 508
505 509 if ((dev = ddi_pathname_to_dev_t(sp->cons_fb_path)) == NODEV)
506 510 return (0); /* warning printed later by common code */
507 511
508 512 /*
509 513 * Here we hold the driver and check "tem-support" property.
510 514 * We're doing this with e_ddi_hold_devi_by_dev and
511 515 * ddi_prop_lookup_int_array without opening the driver since
512 516 * some video cards that don't support the kernel terminal
513 517 * emulator could hang or crash if opened too early during
514 518 * boot.
515 519 */
516 520 if ((dip = e_ddi_hold_devi_by_dev(dev, 0)) == NULL) {
517 521 cmn_err(CE_WARN, "consconfig: cannot hold fb dev %s",
518 522 sp->cons_fb_path);
519 523 return (0);
520 524 }
521 525
522 526 /*
523 527 * Check that the tem-support property exists AND that
524 528 * it is equal to 1.
525 529 */
526 530 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
527 531 DDI_PROP_DONTPASS, "tem-support", &int_array, &nint) ==
528 532 DDI_SUCCESS) {
529 533 if (nint > 0)
530 534 rv = int_array[0] == 1;
531 535 ddi_prop_free(int_array);
532 536 }
533 537
534 538 ddi_release_devi(dip);
535 539
536 540 return (rv);
537 541 }
538 542 #endif /* _HAVE_TEM_FIRMWARE */
539 543
540 544 /*
541 545 * consconfig_get_polledio:
542 546 * Query the console with the CONSPOLLEDIO ioctl.
543 547 * The polled I/O routines are used by debuggers to perform I/O while
544 548 * interrupts and normal kernel services are disabled.
545 549 */
546 550 static cons_polledio_t *
547 551 consconfig_get_polledio(ldi_handle_t lh)
548 552 {
549 553 int err, rval;
550 554 struct strioctl strioc;
551 555 cons_polledio_t *polled_io;
552 556
553 557 /*
554 558 * Setup the ioctl to be sent down to the lower driver.
555 559 */
556 560 strioc.ic_cmd = CONSOPENPOLLEDIO;
557 561 strioc.ic_timout = INFTIM;
558 562 strioc.ic_len = sizeof (polled_io);
559 563 strioc.ic_dp = (char *)&polled_io;
560 564
561 565 /*
562 566 * Send the ioctl to the driver. The ioctl will wait for
563 567 * the response to come back from wc. wc has already issued
564 568 * the CONSOPENPOLLEDIO to the lower layer driver.
565 569 */
566 570 err = ldi_ioctl(lh, I_STR, (intptr_t)&strioc, FKIOCTL, kcred, &rval);
567 571
568 572 if (err != 0) {
569 573 /*
570 574 * If the lower driver does not support polled I/O, then
571 575 * return NULL. This will be the case if the driver does
572 576 * not handle polled I/O, or OBP is going to handle polled
573 577 * I/O for the device.
574 578 */
575 579
576 580 return (NULL);
577 581 }
578 582
579 583 /*
580 584 * Return the polled I/O structure.
581 585 */
582 586 return (polled_io);
583 587 }
584 588
585 589 /*
586 590 * consconfig_setup_polledio:
587 591 * This routine does the setup work for polled I/O. First we get
588 592 * the polled_io structure from the lower layers
589 593 * and then we register the polled I/O
590 594 * callbacks with the debugger that will be using them.
591 595 */
592 596 static void
593 597 consconfig_setup_polledio(cons_state_t *sp, dev_t dev)
594 598 {
595 599 cons_polledio_t *polled_io;
596 600 ldi_handle_t lh;
597 601
598 602 DPRINTF(DPRINT_L0, "consconfig_setup_polledio: start\n");
599 603
600 604
601 605 if (ldi_open_by_dev(&dev, OTYP_CHR,
602 606 FREAD|FWRITE|FNOCTTY, kcred, &lh, sp->cons_li) != 0)
603 607 return;
604 608
605 609
606 610 /*
607 611 * Get the polled io routines so that we can use this
608 612 * device with the debuggers.
609 613 */
610 614 polled_io = consconfig_get_polledio(lh);
611 615
612 616 /*
613 617 * If the get polledio failed, then we do not want to throw
614 618 * the polled I/O switch.
615 619 */
616 620 if (polled_io == NULL) {
617 621 DPRINTF(DPRINT_L0,
618 622 "consconfig_setup_polledio: get_polledio failed\n");
619 623 (void) ldi_close(lh, FREAD|FWRITE, kcred);
620 624 return;
621 625 }
622 626
623 627 /* Initialize the polled input */
624 628 polled_io_init();
625 629
626 630 /* Register the callbacks */
627 631 DPRINTF(DPRINT_L0,
628 632 "consconfig_setup_polledio: registering callbacks\n");
629 633 (void) polled_io_register_callbacks(polled_io, 0);
630 634
631 635 (void) ldi_close(lh, FREAD|FWRITE, kcred);
632 636
633 637 DPRINTF(DPRINT_L0, "consconfig_setup_polledio: end\n");
634 638 }
635 639
636 640 static cons_state_t *
637 641 consconfig_state_init(void)
638 642 {
639 643 cons_state_t *sp;
640 644 int rval;
641 645
642 646 /* Initialize console information */
643 647 sp = kmem_zalloc(sizeof (cons_state_t), KM_SLEEP);
644 648 sp->cons_keyboard_problem = B_FALSE;
645 649
646 650 mutex_init(&sp->cons_lock, NULL, MUTEX_DRIVER, NULL);
647 651
648 652 /* check if consconfig:usb_kb_path is set in /etc/system */
649 653 consconfig_usb_kb_path = consconfig_get_usb_kb_path();
650 654
651 655 /* check if consconfig:usb_ms_path is set in /etc/system */
652 656 consconfig_usb_ms_path = consconfig_get_usb_ms_path();
|
↓ open down ↓ |
197 lines elided |
↑ open up ↑ |
653 657
654 658 consconfig_print_paths();
655 659
656 660 /* init external globals */
657 661 stdoutdev = NODEV;
658 662
659 663 /*
660 664 * Find keyboard, mouse, stdin and stdout devices, if they
661 665 * exist on this platform.
662 666 */
667 + sp->cons_diag_path = plat_diagpath();
663 668
664 669 if (consconfig_usb_kb_path != NULL) {
665 670 sp->cons_keyboard_path = consconfig_usb_kb_path;
666 671 } else if (usb_kb_path != NULL) {
667 672 sp->cons_keyboard_path = usb_kb_path;
668 673 } else {
669 674 sp->cons_keyboard_path = plat_kbdpath();
670 675 }
671 676
672 677 if (consconfig_usb_ms_path != NULL) {
673 678 sp->cons_mouse_path = consconfig_usb_ms_path;
674 679 } else if (usb_ms_path != NULL) {
675 680 sp->cons_mouse_path = usb_ms_path;
676 681 } else {
677 682 sp->cons_mouse_path = plat_mousepath();
678 683 }
679 684
680 685 /* Identify the stdout driver */
681 686 sp->cons_stdout_path = plat_stdoutpath();
682 687 sp->cons_stdout_is_fb = plat_stdout_is_framebuffer();
683 688
684 689 sp->cons_stdin_is_kbd = plat_stdin_is_keyboard();
685 690
686 691 if (sp->cons_stdin_is_kbd &&
687 692 (usb_kb_path != NULL || consconfig_usb_kb_path != NULL)) {
688 693 sp->cons_stdin_path = sp->cons_keyboard_path;
689 694 } else {
690 695 /*
691 696 * The standard in device may or may not be the same as
692 697 * the keyboard. Even if the keyboard is not the
693 698 * standard input, the keyboard console stream will
694 699 * still be built if the keyboard alias provided by the
695 700 * firmware exists and is valid.
696 701 */
697 702 sp->cons_stdin_path = plat_stdinpath();
698 703 }
699 704
700 705 if (sp->cons_stdout_is_fb) {
701 706 sp->cons_fb_path = sp->cons_stdout_path;
702 707
703 708 #ifdef _HAVE_TEM_FIRMWARE
704 709 sp->cons_tem_supported = consconfig_tem_supported(sp);
705 710
706 711 /*
707 712 * Systems which offer a virtual console must use that
708 713 * as a fallback whenever the fb doesn't support tem.
709 714 * Such systems cannot render characters to the screen
710 715 * using OBP.
711 716 */
712 717 if (!sp->cons_tem_supported) {
713 718 char *path;
714 719
715 720 if (plat_virtual_console_path(&path) >= 0) {
716 721 sp->cons_stdin_is_kbd = 0;
717 722 sp->cons_stdout_is_fb = 0;
718 723 sp->cons_stdin_path = path;
719 724 sp->cons_stdout_path = path;
720 725 sp->cons_fb_path = plat_fbpath();
721 726
722 727 cmn_err(CE_WARN,
723 728 "%s doesn't support terminal emulation "
724 729 "mode; switching to virtual console.",
725 730 sp->cons_fb_path);
726 731 }
727 732 }
728 733 #endif /* _HAVE_TEM_FIRMWARE */
729 734 } else {
730 735 sp->cons_fb_path = plat_fbpath();
731 736 #ifdef _HAVE_TEM_FIRMWARE
732 737 sp->cons_tem_supported = consconfig_tem_supported(sp);
733 738 #endif /* _HAVE_TEM_FIRMWARE */
734 739 }
735 740
736 741 sp->cons_li = ldi_ident_from_anon();
737 742
738 743 /* Save the pointer for retrieval by the dacf functions */
739 744 rval = space_store("consconfig", (uintptr_t)sp);
740 745 ASSERT(rval == 0);
741 746
742 747 return (sp);
743 748 }
744 749
745 750 static int
746 751 consconfig_relink_wc(cons_state_t *sp, ldi_handle_t new_lh, int *muxid)
747 752 {
748 753 int err, rval;
749 754 ldi_handle_t wc_lh;
750 755 dev_t wc_dev;
751 756
752 757 ASSERT(muxid != NULL);
753 758
754 759 /*
755 760 * NOTE: we could be in a dacf callback context right now. normally
756 761 * it's not legal to call any ldi_open_*() function from this context
757 762 * because we're currently holding device tree locks and if the
758 763 * ldi_open_*() call could try to acquire other device tree locks
759 764 * (to attach the device we're trying to open.) if this happens then
760 765 * we could deadlock. To avoid this situation, during initialization
761 766 * we made sure to grab a hold on the dip of the device we plan to
762 767 * open so that it can never be detached. Then we use
763 768 * ldi_open_by_dev() to actually open the device since it will see
764 769 * that the device is already attached and held and instead of
765 770 * acquire any locks it will only increase the reference count
766 771 * on the device.
767 772 */
768 773 wc_dev = sp->cons_wc_vp->v_rdev;
769 774 err = ldi_open_by_dev(&wc_dev, OTYP_CHR, FREAD|FWRITE|FNOCTTY,
770 775 kcred, &wc_lh, sp->cons_li);
771 776 ASSERT(wc_dev == sp->cons_wc_vp->v_rdev);
772 777 if (err) {
773 778 cmn_err(CE_WARN, "consconfig_relink_wc: "
774 779 "unable to open wc device");
775 780 return (err);
776 781 }
777 782
778 783 if (new_lh != NULL) {
779 784 DPRINTF(DPRINT_L0, "linking stream under wc\n");
780 785
781 786 err = ldi_ioctl(wc_lh, I_PLINK, (uintptr_t)new_lh,
782 787 FKIOCTL, kcred, muxid);
783 788 if (err != 0) {
784 789 cmn_err(CE_WARN, "consconfig_relink_wc: "
785 790 "wc link failed, error %d", err);
786 791 }
787 792 } else {
788 793 DPRINTF(DPRINT_L0, "unlinking stream from under wc\n");
789 794
790 795 err = ldi_ioctl(wc_lh, I_PUNLINK, *muxid,
791 796 FKIOCTL, kcred, &rval);
792 797 if (err != 0) {
793 798 cmn_err(CE_WARN, "consconfig_relink_wc: "
794 799 "wc unlink failed, error %d", err);
795 800 } else {
796 801 *muxid = -1;
797 802 }
798 803 }
799 804
800 805 (void) ldi_close(wc_lh, FREAD|FWRITE, kcred);
801 806 return (err);
802 807 }
803 808
804 809 static void
805 810 cons_build_upper_layer(cons_state_t *sp)
806 811 {
807 812 ldi_handle_t wc_lh;
808 813 struct strioctl strioc;
809 814 int rval;
810 815 dev_t dev;
811 816 dev_t wc_dev;
812 817
813 818 /*
814 819 * Build the wc->conskbd portion of the keyboard console stream.
815 820 * Even if no keyboard is attached to the system, the upper
816 821 * layer of the stream will be built. If the user attaches
817 822 * a keyboard after the system is booted, the keyboard driver
818 823 * and module will be linked under conskbd.
819 824 *
820 825 * Errors are generally ignored here because conskbd and wc
821 826 * are pseudo drivers and should be present on the system.
822 827 */
823 828
824 829 /* open the console keyboard device. will never be closed */
825 830 if (ldi_open_by_name(CONSKBD_PATH, FREAD|FWRITE|FNOCTTY,
826 831 kcred, &sp->conskbd_lh, sp->cons_li) != 0) {
827 832 panic("consconfig: unable to open conskbd device");
828 833 /*NOTREACHED*/
829 834 }
830 835
831 836 DPRINTF(DPRINT_L0, "conskbd_lh = %p\n", sp->conskbd_lh);
832 837
833 838 /* open the console mouse device. will never be closed */
834 839 if (ldi_open_by_name(CONSMS_PATH, FREAD|FWRITE|FNOCTTY,
835 840 kcred, &sp->consms_lh, sp->cons_li) != 0) {
836 841 panic("consconfig: unable to open consms device");
837 842 /*NOTREACHED*/
838 843 }
839 844
840 845 DPRINTF(DPRINT_L0, "consms_lh = %p\n", sp->consms_lh);
841 846
842 847 /*
843 848 * Get a vnode for the wc device and then grab a hold on the
844 849 * device dip so it can never detach. We need to do this now
845 850 * because later we'll have to open the wc device in a context
846 851 * were it isn't safe to acquire any device tree locks (ie, during
847 852 * a dacf callback.)
848 853 */
849 854 sp->cons_wc_vp = i_consconfig_createvp(WC_PATH);
850 855 if (sp->cons_wc_vp == NULL)
851 856 panic("consconfig: unable to find wc device");
852 857
853 858 if (e_ddi_hold_devi_by_dev(sp->cons_wc_vp->v_rdev, 0) == NULL)
854 859 panic("consconfig: unable to hold wc device");
855 860
856 861 /*
857 862 * Build the wc->conskbd portion of the keyboard console stream.
858 863 * Even if no keyboard is attached to the system, the upper
859 864 * layer of the stream will be built. If the user attaches
860 865 * a keyboard after the system is booted, the keyboard driver
861 866 * and module will be linked under conskbd.
862 867 *
863 868 * The act of linking conskbd under wc will cause wc to
864 869 * query the lower layers about their polled I/O routines
865 870 * using CONSOPENPOLLEDIO. This will fail on this link because
866 871 * there is not a physical keyboard linked under conskbd.
867 872 *
868 873 * Since conskbd and wc are pseudo drivers, errors are
869 874 * generally ignored when linking and unlinking them.
870 875 */
871 876 (void) consconfig_relink_wc(sp, sp->conskbd_lh, &sp->conskbd_muxid);
872 877
873 878 /*
874 879 * Get a vnode for the redirection device. (It has the
875 880 * connection to the workstation console device wired into it,
876 881 * so that it's not necessary to establish the connection
877 882 * here. If the redirection device is ever generalized to
878 883 * handle multiple client devices, it won't be able to
879 884 * establish the connection itself, and we'll have to do it
880 885 * here.)
881 886 */
882 887 wsconsvp = i_consconfig_createvp(IWSCN_PATH);
883 888 if (wsconsvp == NULL) {
884 889 panic("consconfig: unable to find iwscn device");
885 890 /*NOTREACHED*/
886 891 }
887 892
888 893 if (cons_tem_disable)
889 894 return;
890 895
891 896 if (sp->cons_fb_path == NULL) {
892 897 #if defined(__x86)
893 898 if (sp->cons_stdout_is_fb)
894 899 cmn_err(CE_WARN, "consconfig: no screen found");
895 900 #endif
896 901 return;
897 902 }
898 903
899 904 /* make sure the frame buffer device exists */
900 905 dev = ddi_pathname_to_dev_t(sp->cons_fb_path);
901 906 if (dev == NODEV) {
902 907 cmn_err(CE_WARN, "consconfig: "
903 908 "cannot find driver for screen device %s",
904 909 sp->cons_fb_path);
905 910 return;
906 911 }
907 912
908 913 #ifdef _HAVE_TEM_FIRMWARE
909 914 /*
910 915 * If the underlying fb device doesn't support terminal emulation,
911 916 * we don't want to open the wc device (below) because it depends
912 917 * on features which aren't available (polled mode io).
913 918 */
914 919 if (!sp->cons_tem_supported)
915 920 return;
916 921 #endif /* _HAVE_TEM_FIRMWARE */
917 922
918 923 /* tell wc to open the frame buffer device */
919 924 wc_dev = sp->cons_wc_vp->v_rdev;
920 925 if (ldi_open_by_dev(&wc_dev, OTYP_CHR, FREAD|FWRITE|FNOCTTY, kcred,
921 926 &wc_lh, sp->cons_li)) {
922 927 cmn_err(CE_PANIC, "cons_build_upper_layer: "
923 928 "unable to open wc device");
924 929 return;
925 930 }
926 931 ASSERT(wc_dev == sp->cons_wc_vp->v_rdev);
927 932
928 933 strioc.ic_cmd = WC_OPEN_FB;
929 934 strioc.ic_timout = INFTIM;
930 935 strioc.ic_len = strlen(sp->cons_fb_path) + 1;
931 936 strioc.ic_dp = sp->cons_fb_path;
932 937
933 938 if (ldi_ioctl(wc_lh, I_STR, (intptr_t)&strioc,
934 939 FKIOCTL, kcred, &rval) == 0)
935 940 consmode = CONS_KFB;
936 941 else
937 942 cmn_err(CE_WARN,
938 943 "consconfig: terminal emulator failed to initialize");
939 944 (void) ldi_close(wc_lh, FREAD|FWRITE, kcred);
940 945 }
941 946
942 947 static void
943 948 consconfig_load_drivers(cons_state_t *sp)
944 949 {
945 950 /*
946 951 * Calling ddi_pathname_to_dev_t may cause the USB Host Controller
947 952 * drivers to be loaded. Here we make sure that EHCI is loaded
948 953 * earlier than {U, O}HCI. The order here is important. As
949 954 * we have observed many systems on which hangs occur if the
950 955 * {U,O}HCI companion controllers take over control from the BIOS
951 956 * before EHCI does. These hangs are also caused by BIOSes leaving
952 957 * interrupt-on-port-change enabled in the ehci controller, so that
953 958 * when uhci/ohci reset themselves, it induces a port change on
954 959 * the ehci companion controller. Since there's no interrupt handler
955 960 * installed at the time, the moment that interrupt is unmasked, an
956 961 * interrupt storm will occur. All this is averted when ehci is
957 962 * loaded first. And now you know..... the REST of the story.
958 963 *
959 964 * Regardless of platform, ehci needs to initialize first to avoid
960 965 * unnecessary connects and disconnects on the companion controller
961 966 * when ehci sets up the routing.
962 967 *
963 968 * The same is generally true of xhci. Many platforms have routing
964 969 * between the xhci controller and the ehci controller. To avoid those
965 970 * same disconnects, we load xhci before ehci.
966 971 */
967 972 (void) ddi_hold_installed_driver(ddi_name_to_major("xhci"));
968 973 (void) ddi_hold_installed_driver(ddi_name_to_major("ehci"));
969 974 (void) ddi_hold_installed_driver(ddi_name_to_major("uhci"));
970 975 (void) ddi_hold_installed_driver(ddi_name_to_major("ohci"));
971 976
972 977 /*
973 978 * The attaching of the drivers will cause the creation of the
974 979 * keyboard and mouse minor nodes, which will in turn trigger the
975 980 * dacf framework to call the keyboard and mouse configuration
976 981 * tasks. See PSARC/1998/212 for more details about the dacf
977 982 * framework.
978 983 *
979 984 * on sparc, when the console is ttya, zs0 is stdin/stdout, and zs1
980 985 * is kb/mouse. zs0 must be attached before zs1. The zs driver
981 986 * is written this way and the hardware may depend on this, too.
982 987 * It would be better to enforce this by attaching zs in sibling
983 988 * order with a driver property, such as ddi-attachall.
984 989 */
985 990 if (sp->cons_stdin_path != NULL)
|
↓ open down ↓ |
313 lines elided |
↑ open up ↑ |
986 991 stdindev = ddi_pathname_to_dev_t(sp->cons_stdin_path);
987 992 if (stdindev == NODEV) {
988 993 DPRINTF(DPRINT_L0,
989 994 "!fail to attach stdin: %s\n", sp->cons_stdin_path);
990 995 }
991 996 if (sp->cons_stdout_path != NULL)
992 997 stdoutdev = ddi_pathname_to_dev_t(sp->cons_stdout_path);
993 998 if (sp->cons_keyboard_path != NULL)
994 999 kbddev = ddi_pathname_to_dev_t(sp->cons_keyboard_path);
995 1000 if (sp->cons_mouse_path != NULL)
996 - mousedev = ddi_pathname_to_dev_t(sp->cons_mouse_path);
1001 + mousedev = ddi_pathname_to_dev_t(sp->cons_mouse_path);
1002 + if (sp->cons_diag_path != NULL)
1003 + diagdev = ddi_pathname_to_dev_t(sp->cons_diag_path);
997 1004
998 1005 /*
999 1006 * On x86, make sure the fb driver is loaded even if we don't use it
1000 1007 * for the console. This will ensure that we create a /dev/fb link
1001 1008 * which is required to start Xorg.
1002 1009 */
1003 1010 #if defined(__x86)
1004 1011 if (sp->cons_fb_path != NULL)
1005 1012 fbdev = ddi_pathname_to_dev_t(sp->cons_fb_path);
1006 1013 #endif
1007 1014
1008 1015 DPRINTF(DPRINT_L0, "stdindev %lx, stdoutdev %lx, kbddev %lx, "
1009 - "mousedev %lx\n", stdindev, stdoutdev, kbddev, mousedev);
1016 + "mousedev %lx diagdev %lx\n", stdindev, stdoutdev, kbddev,
1017 + mousedev, diagdev);
1010 1018 }
1011 1019
1012 1020 #if !defined(__x86)
1013 1021 void
1014 1022 consconfig_virtual_console_vp(cons_state_t *sp)
1015 1023 {
1016 1024 char *virtual_cons_path;
1017 1025
1018 1026 if (plat_virtual_console_path(&virtual_cons_path) < 0)
1019 1027 return;
1020 1028
1021 1029 DPRINTF(DPRINT_L0, "consconfig_virtual_console_vp: "
1022 1030 "virtual console device path %s\n", virtual_cons_path);
1023 1031
1024 1032 ASSERT(sp->cons_stdout_path != NULL);
1025 1033 if (strcmp(virtual_cons_path, sp->cons_stdout_path) == 0) {
1026 1034 /* virtual console already in use */
1027 1035 return;
1028 1036 }
1029 1037
1030 1038 vsconsvp = i_consconfig_createvp(virtual_cons_path);
1031 1039 if (vsconsvp == NULL) {
1032 1040 cmn_err(CE_WARN, "consconfig_virtual_console_vp: "
1033 1041 "unable to find serial virtual console device %s",
1034 1042 virtual_cons_path);
1035 1043 return;
1036 1044 }
1037 1045
1038 1046 (void) e_ddi_hold_devi_by_dev(vsconsvp->v_rdev, 0);
1039 1047 }
1040 1048 #endif
1041 1049
1042 1050 static void
1043 1051 consconfig_init_framebuffer(cons_state_t *sp)
1044 1052 {
1045 1053 if (!sp->cons_stdout_is_fb)
1046 1054 return;
1047 1055
1048 1056 DPRINTF(DPRINT_L0, "stdout is framebuffer\n");
1049 1057 ASSERT(strcmp(sp->cons_fb_path, sp->cons_stdout_path) == 0);
1050 1058
1051 1059 /*
1052 1060 * Console output is a framebuffer.
1053 1061 * Find the framebuffer driver if we can, and make
1054 1062 * ourselves a shadow vnode to track it with.
1055 1063 */
1056 1064 fbdev = stdoutdev;
1057 1065 if (fbdev == NODEV) {
1058 1066 DPRINTF(DPRINT_L3,
1059 1067 "Can't find driver for console framebuffer\n");
1060 1068 } else {
1061 1069 /* stdoutdev is valid, of fbvp should exist */
1062 1070 fbvp = i_consconfig_createvp(sp->cons_stdout_path);
1063 1071 if (fbvp == NULL) {
1064 1072 panic("consconfig_init_framebuffer: "
1065 1073 "unable to find frame buffer device");
1066 1074 /*NOTREACHED*/
1067 1075 }
1068 1076 ASSERT(fbvp->v_rdev == fbdev);
1069 1077
1070 1078 /* console device is never released */
1071 1079 fbdip = e_ddi_hold_devi_by_dev(fbdev, 0);
1072 1080 }
1073 1081 pm_cfb_setup(sp->cons_stdout_path);
1074 1082 }
1075 1083
1076 1084 /*
1077 1085 * consconfig_prepare_dev:
1078 1086 * Flush the stream, push "pushmod" onto the stream.
1079 1087 * for keyboard, issue the KIOCTRANSABLE ioctl, and
1080 1088 * possible enable abort.
1081 1089 */
1082 1090 static void
1083 1091 consconfig_prepare_dev(
1084 1092 ldi_handle_t new_lh,
1085 1093 const char *pushmod,
1086 1094 int kbdtranslatable,
1087 1095 int input_type,
1088 1096 int dev_type)
1089 1097 {
1090 1098 int err, rval;
1091 1099
1092 1100 /* send a flush down the stream to the keyboard driver */
1093 1101 (void) ldi_ioctl(new_lh, I_FLUSH, (intptr_t)FLUSHRW,
1094 1102 FKIOCTL, kcred, &rval);
1095 1103
1096 1104 if (pushmod) {
1097 1105 err = ldi_ioctl(new_lh, I_PUSH, (intptr_t)pushmod,
1098 1106 FKIOCTL, kcred, &rval);
1099 1107 if (err) {
1100 1108 cmn_err(CE_WARN, "consconfig_prepare_dev: "
1101 1109 "can't push streams module \"%s\", error %d",
1102 1110 pushmod, err);
1103 1111 }
1104 1112 }
1105 1113
1106 1114 if (dev_type == CONS_MS)
1107 1115 return;
1108 1116
1109 1117 ASSERT(dev_type == CONS_KBD);
1110 1118
1111 1119 err = ldi_ioctl(new_lh, KIOCTRANSABLE,
1112 1120 (intptr_t)&kbdtranslatable, FKIOCTL, kcred, &rval);
1113 1121 if (err) {
1114 1122 cmn_err(CE_WARN, "consconfig_prepare_dev: "
1115 1123 "KIOCTRANSABLE failed, error: %d", err);
1116 1124 }
1117 1125
1118 1126 /*
1119 1127 * During boot, dynamic_console_config() will call the
1120 1128 * function to enable abort on the console. If the
1121 1129 * keyboard is hotplugged after boot, check to see if
1122 1130 * the keyboard is the console input. If it is
1123 1131 * enable abort on it.
1124 1132 */
1125 1133 if (input_type == CONSOLE_LOCAL)
1126 1134 (void) consconfig_kbd_abort_enable(new_lh);
1127 1135 }
1128 1136
1129 1137 /*
1130 1138 * consconfig_relink_conskbd:
1131 1139 * If new_lh is not NULL it should represent a driver with a
1132 1140 * keyboard module pushed on top of it. The driver is then linked
1133 1141 * underneath conskbd. the resulting stream will be
1134 1142 * wc->conskbd->"new_lh driver".
1135 1143 *
1136 1144 * If new_lh is NULL, then an unlink operation is done on conskbd
1137 1145 * that attempts to unlink the stream specified by *muxid.
1138 1146 * the resulting stream will be wc->conskbd.
1139 1147 */
1140 1148 static int
1141 1149 consconfig_relink_conskbd(cons_state_t *sp, ldi_handle_t new_lh, int *muxid)
1142 1150 {
1143 1151 int err, rval;
1144 1152 int conskbd_relink = 0;
1145 1153
1146 1154 ASSERT(muxid != NULL);
1147 1155
1148 1156 DPRINTF(DPRINT_L0, "consconfig_relink_conskbd: "
1149 1157 "conskbd_lh = %p, new_lh = %p, muxid = %x\n",
1150 1158 sp->conskbd_lh, new_lh, *muxid);
1151 1159
1152 1160 /*
1153 1161 * If conskbd is linked under wc then temporarily unlink it
1154 1162 * from under wc so that the new_lh stream may be linked under
1155 1163 * conskbd. This has to be done because streams are built bottom
1156 1164 * up and linking a stream under conskbd isn't allowed when
1157 1165 * conskbd is linked under wc.
1158 1166 */
1159 1167 if (sp->conskbd_muxid != -1) {
1160 1168 DPRINTF(DPRINT_L0, "unlinking conskbd from under wc\n");
1161 1169 conskbd_relink = 1;
1162 1170 err = consconfig_relink_wc(sp, NULL, &sp->conskbd_muxid);
1163 1171 if (err) {
1164 1172 cmn_err(CE_WARN, "consconfig_relink_conskbd: "
1165 1173 "wc unlink failed, error %d", err);
1166 1174 return (err);
1167 1175 }
1168 1176 }
1169 1177
1170 1178 if (new_lh != NULL) {
1171 1179 DPRINTF(DPRINT_L0, "linking keyboard under conskbd\n");
1172 1180
1173 1181 /* Link the stream represented by new_lh under conskbd */
1174 1182 err = ldi_ioctl(sp->conskbd_lh, I_PLINK, (uintptr_t)new_lh,
1175 1183 FKIOCTL, kcred, muxid);
1176 1184 if (err != 0) {
1177 1185 cmn_err(CE_WARN, "consconfig_relink_conskbd: "
1178 1186 "conskbd link failed, error %d", err);
1179 1187 goto relink_failed;
1180 1188 }
1181 1189 } else {
1182 1190 DPRINTF(DPRINT_L0, "unlinking keyboard from under conskbd\n");
1183 1191
1184 1192 /*
1185 1193 * This will cause the keyboard driver to be closed,
1186 1194 * all modules to be popped, and the keyboard vnode released.
1187 1195 */
1188 1196 err = ldi_ioctl(sp->conskbd_lh, I_PUNLINK, *muxid,
1189 1197 FKIOCTL, kcred, &rval);
1190 1198 if (err != 0) {
1191 1199 cmn_err(CE_WARN, "consconfig_relink_conskbd: "
1192 1200 "conskbd unlink failed, error %d", err);
1193 1201 goto relink_failed;
1194 1202 } else {
1195 1203 *muxid = -1;
1196 1204 }
1197 1205
1198 1206 consconfig_check_phys_kbd(sp);
1199 1207 }
1200 1208
1201 1209 if (!conskbd_relink)
1202 1210 return (err);
1203 1211
1204 1212 /*
1205 1213 * Link consbkd back under wc.
1206 1214 *
1207 1215 * The act of linking conskbd back under wc will cause wc
1208 1216 * to query the lower lower layers about their polled I/O
1209 1217 * routines. This time the request will succeed because there
1210 1218 * is a physical keyboard linked under conskbd.
1211 1219 */
1212 1220 DPRINTF(DPRINT_L0, "re-linking conskbd under wc\n");
1213 1221 err = consconfig_relink_wc(sp, sp->conskbd_lh, &sp->conskbd_muxid);
1214 1222 if (err) {
1215 1223 cmn_err(CE_WARN, "consconfig_relink_conskbd: "
1216 1224 "wc link failed, error %d", err);
1217 1225 }
1218 1226 return (err);
1219 1227
1220 1228 relink_failed:
1221 1229 if (!conskbd_relink)
1222 1230 return (err);
1223 1231
1224 1232 /* something went wrong, try to reconnect conskbd back under wc */
1225 1233 DPRINTF(DPRINT_L0, "re-linking conskbd under wc\n");
1226 1234 (void) consconfig_relink_wc(sp, sp->conskbd_lh, &sp->conskbd_muxid);
1227 1235 return (err);
1228 1236 }
1229 1237
1230 1238 /*
1231 1239 * consconfig_relink_consms:
1232 1240 * If new_lh is not NULL it should represent a driver with a
1233 1241 * mouse module pushed on top of it. The driver is then linked
1234 1242 * underneath consms. the resulting stream will be
1235 1243 * consms->"new_lh driver".
1236 1244 *
1237 1245 * If new_lh is NULL, then an unlink operation is done on consms
1238 1246 * that attempts to unlink the stream specified by *muxid.
1239 1247 */
1240 1248 static int
1241 1249 consconfig_relink_consms(cons_state_t *sp, ldi_handle_t new_lh, int *muxid)
1242 1250 {
1243 1251 int err, rval;
1244 1252
1245 1253 DPRINTF(DPRINT_L0, "consconfig_relink_consms: "
1246 1254 "consms_lh = %p, new_lh = %p, muxid = %x\n",
1247 1255 (void *)sp->consms_lh, (void *)new_lh, *muxid);
1248 1256
1249 1257 if (new_lh != NULL) {
1250 1258 DPRINTF(DPRINT_L0, "linking mouse under consms\n");
1251 1259
1252 1260 /* Link ms/usbms stream underneath consms multiplexor. */
1253 1261 err = ldi_ioctl(sp->consms_lh, I_PLINK, (uintptr_t)new_lh,
1254 1262 FKIOCTL, kcred, muxid);
1255 1263 if (err != 0) {
1256 1264 cmn_err(CE_WARN, "consconfig_relink_consms: "
1257 1265 "mouse link failed, error %d", err);
1258 1266 }
1259 1267 } else {
1260 1268 DPRINTF(DPRINT_L0, "unlinking mouse from under consms\n");
1261 1269
1262 1270 /* Tear down the mouse stream */
1263 1271 err = ldi_ioctl(sp->consms_lh, I_PUNLINK, *muxid,
1264 1272 FKIOCTL, kcred, &rval);
1265 1273 if (err != 0) {
1266 1274 cmn_err(CE_WARN, "consconfig_relink_consms: "
1267 1275 "mouse unlink failed, error %d", err);
1268 1276 } else {
1269 1277 *muxid = -1;
1270 1278 }
1271 1279 }
1272 1280 return (err);
1273 1281 }
1274 1282
1275 1283 static int
1276 1284 cons_get_input_type(cons_state_t *sp)
1277 1285 {
1278 1286 int type;
1279 1287
1280 1288 /*
1281 1289 * Now that we know what all the devices are, we can figure out
1282 1290 * what kind of console we have.
1283 1291 */
1284 1292 if (sp->cons_stdin_is_kbd) {
1285 1293 /* Stdin is from the system keyboard */
1286 1294 type = CONSOLE_LOCAL;
1287 1295 } else if ((stdindev != NODEV) && (stdindev == stdoutdev)) {
1288 1296 /*
1289 1297 * A reliable indicator that we are doing a remote console
1290 1298 * is that stdin and stdout are the same.
1291 1299 * This is probably a tip line.
1292 1300 */
1293 1301 type = CONSOLE_TIP;
1294 1302 } else {
1295 1303 type = CONSOLE_SERIAL_KEYBOARD;
1296 1304 }
1297 1305
1298 1306 return (type);
1299 1307 }
1300 1308
1301 1309 static void
1302 1310 consconfig_init_input(cons_state_t *sp)
1303 1311 {
1304 1312 ldi_handle_t new_lh;
1305 1313 dev_t cons_final_dev;
1306 1314 int err;
1307 1315
1308 1316 cons_final_dev = NODEV;
1309 1317
1310 1318 switch (sp->cons_input_type) {
1311 1319 case CONSOLE_LOCAL:
1312 1320 DPRINTF(DPRINT_L0, "stdin is keyboard\n");
1313 1321
1314 1322 /*
1315 1323 * The machine is allowed to boot without a keyboard.
1316 1324 * If a user attaches a keyboard later, the keyboard
1317 1325 * will be hooked into the console stream with the dacf
1318 1326 * functions.
1319 1327 *
1320 1328 * The only drivers that look at kbbdev are the
1321 1329 * serial drivers, which looks at kbdev to see if
1322 1330 * they should allow abort on a break. In the absence
1323 1331 * of keyboard, the serial drivers won't be attached
1324 1332 * for any keyboard instance.
1325 1333 */
1326 1334 if (kbddev == NODEV) {
1327 1335 /*
1328 1336 * If there is a problem with the keyboard
1329 1337 * during the driver loading, then the polled
1330 1338 * input won't get setup properly if polled
1331 1339 * input is needed. This means that if the
1332 1340 * keyboard is hotplugged, the keyboard would
1333 1341 * work normally, but going down to the
1334 1342 * debugger would not work if polled input is
1335 1343 * required. This field is set here. The next
1336 1344 * time a keyboard is plugged in, the field is
1337 1345 * checked in order to give the next keyboard a
1338 1346 * chance at being registered for console
1339 1347 * input.
1340 1348 *
1341 1349 * Although this code will rarely be needed,
1342 1350 * USB keyboards can be flaky, so this code
1343 1351 * will be useful on the occasion that the
1344 1352 * keyboard doesn't enumerate when the drivers
1345 1353 * are loaded.
1346 1354 */
1347 1355 DPRINTF(DPRINT_L2, "Error with console keyboard\n");
1348 1356 sp->cons_keyboard_problem = B_TRUE;
1349 1357 }
1350 1358 stdindev = kbddev;
1351 1359 cons_final_dev = sp->cons_wc_vp->v_rdev;
1352 1360 break;
1353 1361
1354 1362 case CONSOLE_TIP:
1355 1363 DPRINTF(DPRINT_L0, "console input is tty (%s)\n",
1356 1364 sp->cons_stdin_path);
1357 1365
1358 1366 /*
1359 1367 * Console device drivers must be able to output
1360 1368 * after being closed.
1361 1369 */
1362 1370 rconsvp = i_consconfig_createvp(sp->cons_stdin_path);
1363 1371 if (rconsvp == NULL) {
1364 1372 panic("consconfig_init_input: "
1365 1373 "unable to find stdin device (%s)",
1366 1374 sp->cons_stdin_path);
1367 1375 /*NOTREACHED*/
1368 1376 }
1369 1377 rconsdev = rconsvp->v_rdev;
1370 1378
1371 1379 ASSERT(rconsdev == stdindev);
1372 1380
1373 1381 cons_final_dev = rconsdev;
1374 1382 break;
1375 1383
1376 1384 case CONSOLE_SERIAL_KEYBOARD:
1377 1385 DPRINTF(DPRINT_L0, "stdin is serial keyboard\n");
1378 1386
1379 1387 /*
1380 1388 * Non-keyboard input device, but not rconsdev.
1381 1389 * This is known as the "serial keyboard" case - the
1382 1390 * most likely use is someone has a keyboard attached
1383 1391 * to a serial port (tip) and still has output on a
1384 1392 * framebuffer.
1385 1393 *
1386 1394 * In this case, the serial driver must be linked
1387 1395 * directly beneath wc. Since conskbd was linked
1388 1396 * underneath wc above, first we unlink conskbd.
1389 1397 */
1390 1398 (void) consconfig_relink_wc(sp, NULL, &sp->conskbd_muxid);
1391 1399 sp->conskbd_muxid = -1;
1392 1400
1393 1401 /*
1394 1402 * Open the serial keyboard, configure it,
1395 1403 * and link it underneath wc.
1396 1404 */
1397 1405 err = ldi_open_by_name(sp->cons_stdin_path,
1398 1406 FREAD|FWRITE|FNOCTTY, kcred, &new_lh, sp->cons_li);
1399 1407 if (err == 0) {
1400 1408 struct termios termios;
1401 1409 int rval;
1402 1410 int stdin_muxid;
1403 1411
1404 1412 consconfig_prepare_dev(new_lh,
1405 1413 "kb", TR_CANNOT, sp->cons_input_type, CONS_KBD);
1406 1414
1407 1415 /* Re-set baud rate */
1408 1416 (void) ldi_ioctl(new_lh, TCGETS, (intptr_t)&termios,
1409 1417 FKIOCTL, kcred, &rval);
1410 1418
1411 1419 /* Set baud rate */
1412 1420 if (consconfig_setmodes(stdindev, &termios) == 0) {
1413 1421 err = ldi_ioctl(new_lh,
1414 1422 TCSETSF, (intptr_t)&termios,
1415 1423 FKIOCTL, kcred, &rval);
1416 1424 if (err) {
1417 1425 cmn_err(CE_WARN,
1418 1426 "consconfig_init_input: "
1419 1427 "TCSETSF failed, error %d", err);
1420 1428 }
1421 1429 }
1422 1430
1423 1431 /*
1424 1432 * Now link the serial keyboard direcly under wc
1425 1433 * we don't save the returned muxid because we
1426 1434 * don't support changing/hotplugging the console
1427 1435 * keyboard when it is a serial keyboard.
1428 1436 */
1429 1437 (void) consconfig_relink_wc(sp, new_lh, &stdin_muxid);
1430 1438
1431 1439 (void) ldi_close(new_lh, FREAD|FWRITE, kcred);
1432 1440 }
1433 1441
1434 1442 cons_final_dev = sp->cons_wc_vp->v_rdev;
1435 1443 break;
1436 1444
1437 1445 default:
1438 1446 panic("consconfig_init_input: "
1439 1447 "unsupported console input/output combination");
1440 1448 /*NOTREACHED*/
1441 1449 }
1442 1450
1443 1451 /*
1444 1452 * Use the redirection device/workstation console pair as the "real"
1445 1453 * console if the latter hasn't already been set.
1446 1454 * The workstation console driver needs to see rwsconsvp, but
1447 1455 * all other access should be through the redirecting driver.
1448 1456 */
1449 1457 if (rconsvp == NULL) {
1450 1458 consconfig_dprintf(DPRINT_L0, "setup redirection driver\n");
1451 1459 rconsvp = wsconsvp;
1452 1460 rconsdev = wsconsvp->v_rdev;
1453 1461 }
1454 1462
1455 1463 ASSERT(cons_final_dev != NODEV);
1456 1464
1457 1465 err = ldi_open_by_dev(&cons_final_dev, OTYP_CHR, FREAD|FWRITE|FNOCTTY,
1458 1466 kcred, &new_lh, sp->cons_li);
1459 1467 if (err) {
1460 1468 panic("consconfig_init_input: "
1461 1469 "unable to open console device");
1462 1470 /*NOTREACHED*/
1463 1471 }
1464 1472
1465 1473 /* Enable abort on the console */
1466 1474 (void) consconfig_kbd_abort_enable(new_lh);
1467 1475
1468 1476 /* Now we must close it to make console logins happy */
1469 1477 (void) ldi_close(new_lh, FREAD|FWRITE, kcred);
|
↓ open down ↓ |
450 lines elided |
↑ open up ↑ |
1470 1478
1471 1479 /* Set up polled input if it is supported by the console device */
1472 1480 if (plat_use_polled_debug()) {
1473 1481 /*
1474 1482 * In the debug case, register the keyboard polled entry
1475 1483 * points, but don't throw the switch in the debugger. This
1476 1484 * allows the polled entry points to be checked by hand
1477 1485 */
1478 1486 consconfig_setup_polledio(sp, sp->cons_wc_vp->v_rdev);
1479 1487 } else {
1480 - consconfig_setup_polledio(sp, cons_final_dev);
1488 + if (diagdev != NODEV)
1489 + consconfig_setup_polledio(sp, diagdev);
1490 + else
1491 + consconfig_setup_polledio(sp, cons_final_dev);
1481 1492 }
1482 1493
1483 1494 kadb_uses_kernel();
1484 1495 }
1485 1496
1486 1497 /*
1487 1498 * This function kicks off the console configuration.
1488 1499 * Configure keyboard and mouse. Main entry here.
1489 1500 */
1490 1501 void
1491 1502 dynamic_console_config(void)
1492 1503 {
1493 1504 /* initialize space.c globals */
1494 1505 stdindev = NODEV;
1495 1506 mousedev = NODEV;
1496 1507 kbddev = NODEV;
1497 1508 fbdev = NODEV;
1509 + diagdev = NODEV;
1498 1510 fbvp = NULL;
1499 1511 fbdip = NULL;
1500 1512 wsconsvp = NULL;
1501 1513 rwsconsvp = NULL;
1502 1514 rwsconsdev = NODEV;
1503 1515 rconsvp = NULL;
1504 1516 rconsdev = NODEV;
1505 1517
1506 1518 /* Initialize cons_state_t structure and console device paths */
1507 1519 consconfig_sp = consconfig_state_init();
1508 1520 ASSERT(consconfig_sp);
1509 1521
1510 1522 /* Build upper layer of console stream */
1511 1523 cons_build_upper_layer(consconfig_sp);
1512 1524
1513 1525 /*
1514 1526 * Load keyboard/mouse drivers. The dacf routines will
1515 1527 * plumb the devices into the console stream
1516 1528 *
1517 1529 * At the conclusion of the ddi_pathname_to_dev_t calls, the keyboard
1518 1530 * and mouse drivers are linked into their respective console
1519 1531 * streams if the pathnames are valid.
1520 1532 */
1521 1533 consconfig_load_drivers(consconfig_sp);
1522 1534 consconfig_sp->cons_input_type = cons_get_input_type(consconfig_sp);
1523 1535
1524 1536 /*
1525 1537 * This is legacy special case code for the "cool" virtual console
1526 1538 * for the Starfire project. Starfire has a dummy "ssp-serial"
1527 1539 * node in the OBP device tree and cvc is a pseudo driver.
1528 1540 */
1529 1541 if (consconfig_sp->cons_stdout_path != NULL && stdindev == NODEV &&
1530 1542 strstr(consconfig_sp->cons_stdout_path, "ssp-serial")) {
1531 1543 /*
1532 1544 * Setup the virtual console driver for Starfire
1533 1545 * Note that console I/O will still go through prom for now
1534 1546 * (notice we don't open the driver here). The cvc driver
1535 1547 * will be activated when /dev/console is opened by init.
1536 1548 * During that time, a cvcd daemon will be started that
1537 1549 * will open the cvcredirection driver to facilitate
1538 1550 * the redirection of console I/O from cvc to cvcd.
1539 1551 */
1540 1552 rconsvp = i_consconfig_createvp(CVC_PATH);
1541 1553 if (rconsvp == NULL)
1542 1554 goto done;
1543 1555 rconsdev = rconsvp->v_rdev;
1544 1556 goto done;
1545 1557 }
1546 1558
1547 1559 rwsconsvp = consconfig_sp->cons_wc_vp;
1548 1560 rwsconsdev = consconfig_sp->cons_wc_vp->v_rdev;
1549 1561
1550 1562
1551 1563 /* initialize framebuffer, console input, and redirection device */
1552 1564 consconfig_init_framebuffer(consconfig_sp);
1553 1565 consconfig_init_input(consconfig_sp);
1554 1566
1555 1567 #if !defined(__x86)
1556 1568 /* initialize virtual console vp for logging if needed */
1557 1569 consconfig_virtual_console_vp(consconfig_sp);
1558 1570 #endif
1559 1571
1560 1572 DPRINTF(DPRINT_L0,
1561 1573 "mousedev %lx, kbddev %lx, fbdev %lx, rconsdev %lx\n",
1562 1574 mousedev, kbddev, fbdev, rconsdev);
1563 1575
1564 1576 flush_deferred_console_buf();
1565 1577 done:
1566 1578 consconfig_sp->cons_initialized = B_TRUE;
1567 1579 }
1568 1580
1569 1581
1570 1582 /*
1571 1583 * Start of DACF interfaces
1572 1584 */
1573 1585
1574 1586 /*
1575 1587 * Do the real job for keyboard/mouse auto-configuration.
1576 1588 */
1577 1589 static int
1578 1590 do_config(cons_state_t *sp, cons_prop_t *prop)
1579 1591 {
1580 1592 ldi_handle_t lh;
1581 1593 dev_t dev;
1582 1594 int error;
1583 1595
1584 1596 ASSERT((prop->cp_type == CONS_KBD) || (prop->cp_type == CONS_MS));
1585 1597
1586 1598 dev = prop->cp_dev;
1587 1599 error = ldi_open_by_dev(&dev, OTYP_CHR,
1588 1600 FREAD|FWRITE|FNOCTTY, kcred, &lh, sp->cons_li);
1589 1601 if (error) {
1590 1602 return (DACF_FAILURE);
1591 1603 }
1592 1604 ASSERT(dev == prop->cp_dev); /* clone not supported */
1593 1605
1594 1606 /*
1595 1607 * Prepare the new keyboard/mouse driver
1596 1608 * to be linked under conskbd/consms.
1597 1609 */
1598 1610 consconfig_prepare_dev(lh, prop->cp_pushmod, TR_CAN,
1599 1611 sp->cons_input_type, prop->cp_type);
1600 1612
1601 1613 if (prop->cp_type == CONS_KBD) {
1602 1614 /*
1603 1615 * Tell the physical keyboard driver to send
1604 1616 * the abort sequences up to the virtual keyboard
1605 1617 * driver so that STOP and A (or F1 and A)
1606 1618 * can be applied to different keyboards.
1607 1619 */
1608 1620 (void) consconfig_kbd_abort_disable(lh);
1609 1621
1610 1622 /* Link the stream underneath conskbd */
1611 1623 error = consconfig_relink_conskbd(sp, lh, &prop->cp_muxid);
1612 1624 } else {
1613 1625 /* Link the stream underneath consms */
1614 1626 error = consconfig_relink_consms(sp, lh, &prop->cp_muxid);
1615 1627 }
1616 1628
1617 1629 /*
1618 1630 * At this point, the stream is:
1619 1631 * for keyboard: wc->conskbd->["pushmod"->"kbd_vp driver"]
1620 1632 * for mouse: consms->["module_name"->]"mouse_avp driver"
1621 1633 */
1622 1634
1623 1635 /* Close the driver stream, it will stay linked under conskbd */
1624 1636 (void) ldi_close(lh, FREAD|FWRITE, kcred);
1625 1637
1626 1638 if (error) {
1627 1639 return (DACF_FAILURE);
1628 1640 }
1629 1641
1630 1642 return (DACF_SUCCESS);
1631 1643 }
1632 1644
1633 1645 static int
1634 1646 do_unconfig(cons_state_t *sp, cons_prop_t *prop)
1635 1647 {
1636 1648 ASSERT((prop->cp_type == CONS_KBD) || (prop->cp_type == CONS_MS));
1637 1649
1638 1650 if (prop->cp_type == CONS_KBD)
1639 1651 return (consconfig_relink_conskbd(sp, NULL, &prop->cp_muxid));
1640 1652 else
1641 1653 return (consconfig_relink_consms(sp, NULL, &prop->cp_muxid));
1642 1654 }
1643 1655
1644 1656 static int
1645 1657 kb_ms_config(dacf_infohdl_t minor_hdl, dacf_arghdl_t arg_hdl, int type)
1646 1658 {
1647 1659 major_t major;
1648 1660 minor_t minor;
1649 1661 dev_t dev;
1650 1662 dev_info_t *dip;
1651 1663 cons_state_t *sp;
1652 1664 cons_prop_t *prop;
1653 1665 const char *pushmod;
1654 1666
1655 1667 /*
1656 1668 * Retrieve the state information
1657 1669 * Some platforms may use the old-style "consconfig" to configure
1658 1670 * console stream modules but may also support devices that happen
1659 1671 * to match a rule in /etc/dacf.conf. This will cause a problem
1660 1672 * since the console state structure will not be initialized.
1661 1673 * In that case, these entry points should silently fail and
1662 1674 * permit console to be plumbed later in boot.
1663 1675 */
1664 1676 if ((sp = (cons_state_t *)space_fetch("consconfig")) == NULL)
1665 1677 return (DACF_FAILURE);
1666 1678
1667 1679 dip = dacf_devinfo_node(minor_hdl);
1668 1680 major = ddi_driver_major(dip);
1669 1681 ASSERT(major != DDI_MAJOR_T_NONE);
1670 1682 minor = dacf_minor_number(minor_hdl);
1671 1683 dev = makedevice(major, minor);
1672 1684 ASSERT(dev != NODEV);
1673 1685
1674 1686 DPRINTF(DPRINT_L0, "driver name = \"%s\", dev = 0x%lx, major = 0x%x\n",
1675 1687 (char *)dacf_driver_name(minor_hdl), dev, major);
1676 1688
1677 1689 /* Access to the global variables is synchronized */
1678 1690 mutex_enter(&sp->cons_lock);
1679 1691
1680 1692 /*
1681 1693 * Check if the keyboard/mouse has already configured.
1682 1694 */
1683 1695 if (consconfig_find_dev(sp, dev) != NULL) {
1684 1696 mutex_exit(&sp->cons_lock);
1685 1697 return (DACF_SUCCESS);
1686 1698 }
1687 1699
1688 1700 prop = kmem_zalloc(sizeof (cons_prop_t), KM_SLEEP);
1689 1701
1690 1702 /* Config the new keyboard/mouse device */
1691 1703 prop->cp_dev = dev;
1692 1704
1693 1705 pushmod = dacf_get_arg(arg_hdl, "pushmod");
1694 1706 prop->cp_pushmod = i_ddi_strdup((char *)pushmod, KM_SLEEP);
1695 1707
1696 1708 prop->cp_type = type;
1697 1709 if (do_config(sp, prop) != DACF_SUCCESS) {
1698 1710 /*
1699 1711 * The keyboard/mouse node failed to open.
1700 1712 * Set the major and minor numbers to 0 so
1701 1713 * kb_unconfig/ms_unconfig won't unconfigure
1702 1714 * this node if it is detached.
1703 1715 */
1704 1716 mutex_exit(&sp->cons_lock);
1705 1717 consconfig_free_prop(prop);
1706 1718 return (DACF_FAILURE);
1707 1719 }
1708 1720
1709 1721 consconfig_add_dev(sp, prop);
1710 1722
1711 1723 /*
1712 1724 * See if there was a problem with the console keyboard during boot.
1713 1725 * If so, try to register polled input for this keyboard.
1714 1726 */
1715 1727 if ((type == CONS_KBD) && (sp->cons_keyboard_problem)) {
1716 1728 consconfig_setup_polledio(sp, sp->cons_wc_vp->v_rdev);
1717 1729 sp->cons_keyboard_problem = B_FALSE;
1718 1730 }
1719 1731
1720 1732 /* Prevent autodetach due to memory pressure */
1721 1733 (void) ddi_prop_update_int(DDI_DEV_T_NONE, dip, DDI_NO_AUTODETACH, 1);
1722 1734
1723 1735 mutex_exit(&sp->cons_lock);
1724 1736
1725 1737 return (DACF_SUCCESS);
1726 1738 }
1727 1739
1728 1740 static int
1729 1741 kb_ms_unconfig(dacf_infohdl_t minor_hdl, dacf_arghdl_t arg_hdl)
1730 1742 {
1731 1743 _NOTE(ARGUNUSED(arg_hdl))
1732 1744
1733 1745 major_t major;
1734 1746 minor_t minor;
1735 1747 dev_t dev;
1736 1748 dev_info_t *dip;
1737 1749 cons_state_t *sp;
1738 1750 cons_prop_t *prop;
1739 1751
1740 1752 /*
1741 1753 * Retrieve the state information
1742 1754 * So if there isn't a state available, then this entry point just
1743 1755 * returns. See note in kb_config().
1744 1756 */
1745 1757 if ((sp = (cons_state_t *)space_fetch("consconfig")) == NULL)
1746 1758 return (DACF_SUCCESS);
1747 1759
1748 1760 dip = dacf_devinfo_node(minor_hdl);
1749 1761 major = ddi_driver_major(dip);
1750 1762 ASSERT(major != DDI_MAJOR_T_NONE);
1751 1763 minor = dacf_minor_number(minor_hdl);
1752 1764 dev = makedevice(major, minor);
1753 1765 ASSERT(dev != NODEV);
1754 1766
1755 1767 /*
1756 1768 * Check if the keyboard/mouse that is being detached
1757 1769 * is the console keyboard/mouse or not.
1758 1770 */
1759 1771 mutex_enter(&sp->cons_lock);
1760 1772 if ((prop = consconfig_find_dev(sp, dev)) == NULL) {
1761 1773 mutex_exit(&sp->cons_lock);
1762 1774 return (DACF_SUCCESS);
1763 1775 }
1764 1776
1765 1777 /*
1766 1778 * This dev may be opened physically and then hotplugged out.
1767 1779 */
1768 1780 if (prop->cp_muxid != -1) {
1769 1781 (void) do_unconfig(sp, prop);
1770 1782 consconfig_rem_dev(sp, dev);
1771 1783 }
1772 1784
1773 1785 mutex_exit(&sp->cons_lock);
1774 1786
1775 1787 return (DACF_SUCCESS);
1776 1788 }
1777 1789
1778 1790 /*
1779 1791 * This is the post-attach / pre-detach action function for the keyboard
1780 1792 * and mouse. This function is associated with a node type in /etc/dacf.conf.
1781 1793 */
1782 1794 static int
1783 1795 kb_config(dacf_infohdl_t minor_hdl, dacf_arghdl_t arg_hdl, int flags)
1784 1796 {
1785 1797 _NOTE(ARGUNUSED(flags))
1786 1798
1787 1799 return (kb_ms_config(minor_hdl, arg_hdl, CONS_KBD));
1788 1800 }
1789 1801
1790 1802 static int
1791 1803 ms_config(dacf_infohdl_t minor_hdl, dacf_arghdl_t arg_hdl, int flags)
1792 1804 {
1793 1805 _NOTE(ARGUNUSED(flags))
1794 1806
1795 1807 return (kb_ms_config(minor_hdl, arg_hdl, CONS_MS));
1796 1808 }
1797 1809
1798 1810 static int
1799 1811 kb_unconfig(dacf_infohdl_t minor_hdl, dacf_arghdl_t arg_hdl, int flags)
1800 1812 {
1801 1813 _NOTE(ARGUNUSED(flags))
1802 1814
1803 1815 return (kb_ms_unconfig(minor_hdl, arg_hdl));
1804 1816 }
1805 1817
1806 1818 static int
1807 1819 ms_unconfig(dacf_infohdl_t minor_hdl, dacf_arghdl_t arg_hdl, int flags)
1808 1820 {
1809 1821 _NOTE(ARGUNUSED(flags))
1810 1822
1811 1823 return (kb_ms_unconfig(minor_hdl, arg_hdl));
1812 1824 }
1813 1825
1814 1826 /*
1815 1827 * consconfig_link and consconfig_unlink are provided to support
1816 1828 * direct access to physical keyboard/mouse underlying conskbd/
1817 1829 * consms.
1818 1830 * When the keyboard/mouse is opened physically via its device
1819 1831 * file, it will be unlinked from the virtual one, and when it
1820 1832 * is closed physically, it will be linked back under the virtual
1821 1833 * one.
1822 1834 */
1823 1835 void
1824 1836 consconfig_link(major_t major, minor_t minor)
1825 1837 {
1826 1838 char buf[MAXPATHLEN];
1827 1839 dev_t dev;
1828 1840 cons_state_t *sp;
1829 1841 cons_prop_t *prop;
1830 1842
1831 1843 if ((sp = (cons_state_t *)space_fetch("consconfig")) == NULL)
1832 1844 return;
1833 1845
1834 1846 dev = makedevice(major, minor);
1835 1847 ASSERT(dev != NODEV);
1836 1848
1837 1849 mutex_enter(&sp->cons_lock);
1838 1850 if ((prop = consconfig_find_dev(sp, dev)) == NULL) {
1839 1851 mutex_exit(&sp->cons_lock);
1840 1852 return;
1841 1853 }
1842 1854
1843 1855 if (do_config(sp, prop) != DACF_SUCCESS) {
1844 1856 (void) ddi_dev_pathname(dev, 0, buf);
1845 1857 if (prop->cp_type == CONS_KBD)
1846 1858 cmn_err(CE_WARN, "Failed to relink the keyboard "
1847 1859 "(%s) underneath virtual keyboard", buf);
1848 1860 else
1849 1861 cmn_err(CE_WARN, "Failed to relink the mouse "
1850 1862 "(%s) underneath virtual mouse", buf);
1851 1863 consconfig_rem_dev(sp, dev);
1852 1864 }
1853 1865
1854 1866 mutex_exit(&sp->cons_lock);
1855 1867 }
1856 1868
1857 1869
1858 1870 int
1859 1871 consconfig_unlink(major_t major, minor_t minor)
1860 1872 {
1861 1873 dev_t dev;
1862 1874 cons_state_t *sp;
1863 1875 cons_prop_t *prop;
1864 1876 int error;
1865 1877
1866 1878 if ((sp = (cons_state_t *)space_fetch("consconfig")) == NULL)
1867 1879 return (DACF_SUCCESS);
1868 1880
1869 1881 dev = makedevice(major, minor);
1870 1882 ASSERT(dev != NODEV);
1871 1883
1872 1884 mutex_enter(&sp->cons_lock);
1873 1885 if ((prop = consconfig_find_dev(sp, dev)) == NULL) {
1874 1886 mutex_exit(&sp->cons_lock);
1875 1887 return (DACF_FAILURE);
1876 1888 }
1877 1889
1878 1890 error = do_unconfig(sp, prop);
1879 1891
1880 1892 /*
1881 1893 * Keep this dev on the list, for this dev is still online.
1882 1894 */
1883 1895 mutex_exit(&sp->cons_lock);
1884 1896
1885 1897 return (error);
1886 1898 }
1887 1899
1888 1900 /*
1889 1901 * Routine to set baud rate, bits-per-char, parity and stop bits
1890 1902 * on the console line when necessary.
1891 1903 */
1892 1904 static int
1893 1905 consconfig_setmodes(dev_t dev, struct termios *termiosp)
1894 1906 {
1895 1907 char buf[MAXPATHLEN];
1896 1908 int len = MAXPATHLEN;
1897 1909 char name[16];
1898 1910 int ppos, i;
1899 1911 char *path;
1900 1912 dev_t tdev;
1901 1913
1902 1914 /*
1903 1915 * First, search for a devalias which matches this dev_t.
1904 1916 * Try all of ttya through ttyz until no such alias
1905 1917 */
1906 1918 (void) strcpy(name, "ttya");
1907 1919 for (i = 0; i < ('z'-'a'); i++) {
1908 1920 name[3] = 'a' + i; /* increment device name */
1909 1921 path = get_alias(name, buf);
1910 1922 if (path == NULL)
1911 1923 return (1);
1912 1924
1913 1925 tdev = ddi_pathname_to_dev_t(path);
1914 1926 if (tdev == dev)
1915 1927 break; /* Exit loop if found */
1916 1928 }
1917 1929
1918 1930 if (i >= ('z'-'a'))
1919 1931 return (1); /* If we didn't find it, return */
1920 1932
1921 1933 /*
1922 1934 * Now that we know which "tty" this corresponds to, retrieve
1923 1935 * the "ttya-mode" options property, which tells us how to configure
1924 1936 * the line.
1925 1937 */
1926 1938 (void) strcpy(name, "ttya-mode"); /* name of option we want */
1927 1939 name[3] = 'a' + i; /* Adjust to correct line */
1928 1940
1929 1941 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ddi_root_node(), 0, name,
1930 1942 buf, &len) != DDI_PROP_SUCCESS)
1931 1943 return (1); /* if no such option, just return */
1932 1944
1933 1945 /*
1934 1946 * The IEEE 1275 standard specifies that /aliases string property
1935 1947 * values should be null-terminated. Unfortunately the reality
1936 1948 * is that most aren't and the OBP can't easily be modified to
1937 1949 * add null termination to these strings. So we'll add the
1938 1950 * null termination here. If the string already contains a
1939 1951 * null termination character then that's ok too because we'll
1940 1952 * just be adding a second one.
1941 1953 */
1942 1954 buf[len] = '\0';
1943 1955
1944 1956 /* Clear out options we will be setting */
1945 1957 termiosp->c_cflag &=
1946 1958 ~(CSIZE | CBAUD | CBAUDEXT | PARODD | PARENB | CSTOPB);
1947 1959
1948 1960 /* Clear options which potentially conflict with new settings */
1949 1961 termiosp->c_cflag &= ~(CIBAUD | CIBAUDEXT);
1950 1962
1951 1963 /*
1952 1964 * Now, parse the string. Wish I could use sscanf().
1953 1965 * Format 9600,8,n,1,-
1954 1966 * baud rate, bits-per-char, parity, stop-bits, ignored
1955 1967 */
1956 1968 for (ppos = 0; ppos < (MAXPATHLEN-8); ppos++) { /* Find first comma */
1957 1969 if ((buf[ppos] == 0) || (buf[ppos] == ','))
1958 1970 break;
1959 1971 }
1960 1972
1961 1973 if (buf[ppos] != ',') {
1962 1974 cmn_err(CE_WARN, "consconfig_setmodes: "
1963 1975 "invalid mode string %s", buf);
1964 1976 return (1);
1965 1977 }
1966 1978
1967 1979 for (i = 0; i < MAX_SPEEDS; i++) {
1968 1980 if (strncmp(buf, speedtab[i].name, ppos) == 0)
1969 1981 break;
1970 1982 }
1971 1983
1972 1984 if (i >= MAX_SPEEDS) {
1973 1985 cmn_err(CE_WARN,
1974 1986 "consconfig_setmodes: unrecognized speed in %s", buf);
1975 1987 return (1);
1976 1988 }
1977 1989
1978 1990 /* Found the baud rate, set it */
1979 1991 termiosp->c_cflag |= speedtab[i].code & CBAUD;
1980 1992 if (speedtab[i].code > 16) /* cfsetospeed! */
1981 1993 termiosp->c_cflag |= CBAUDEXT;
1982 1994
1983 1995 /* Set bits per character */
1984 1996 switch (buf[ppos+1]) {
1985 1997 case '8':
1986 1998 termiosp->c_cflag |= CS8;
1987 1999 break;
1988 2000 case '7':
1989 2001 termiosp->c_cflag |= CS7;
1990 2002 break;
1991 2003 default:
1992 2004 cmn_err(CE_WARN,
1993 2005 "consconfig_setmodes: illegal bits-per-char %s", buf);
1994 2006 return (1);
1995 2007 }
1996 2008
1997 2009 /* Set parity */
1998 2010 switch (buf[ppos+3]) {
1999 2011 case 'o':
2000 2012 termiosp->c_cflag |= PARENB | PARODD;
2001 2013 break;
2002 2014 case 'e':
2003 2015 termiosp->c_cflag |= PARENB; /* enabled, not odd */
2004 2016 break;
2005 2017 case 'n':
2006 2018 break; /* not enabled. */
2007 2019 default:
2008 2020 cmn_err(CE_WARN, "consconfig_setmodes: illegal parity %s", buf);
2009 2021 return (1);
2010 2022 }
2011 2023
2012 2024 /* Set stop bits */
2013 2025 switch (buf[ppos+5]) {
2014 2026 case '1':
2015 2027 break; /* No extra stop bit */
2016 2028 case '2':
2017 2029 termiosp->c_cflag |= CSTOPB; /* 1 extra stop bit */
2018 2030 break;
2019 2031 default:
2020 2032 cmn_err(CE_WARN, "consconfig_setmodes: "
2021 2033 "illegal stop bits %s", buf);
2022 2034 return (1);
2023 2035 }
2024 2036
2025 2037 return (0);
2026 2038 }
2027 2039
2028 2040 /*
2029 2041 * Check to see if underlying keyboard devices are still online,
2030 2042 * if any one is offline now, unlink it.
2031 2043 */
2032 2044 static void
2033 2045 consconfig_check_phys_kbd(cons_state_t *sp)
2034 2046 {
2035 2047 ldi_handle_t kb_lh;
2036 2048 cons_prop_t *prop;
2037 2049 int error;
2038 2050 int rval;
2039 2051
2040 2052 for (prop = sp->cons_km_prop; prop; prop = prop->cp_next) {
2041 2053 if ((prop->cp_type != CONS_KBD) || (prop->cp_muxid == -1))
2042 2054 continue;
2043 2055
2044 2056 error = ldi_open_by_dev(&prop->cp_dev, OTYP_CHR,
2045 2057 FREAD|FWRITE|FNOCTTY, kcred, &kb_lh, sp->cons_li);
2046 2058
2047 2059 if (error) {
2048 2060 (void) ldi_ioctl(sp->conskbd_lh, I_PUNLINK,
2049 2061 prop->cp_muxid, FKIOCTL, kcred, &rval);
2050 2062 prop->cp_dev = NODEV;
2051 2063 } else {
2052 2064 (void) ldi_close(kb_lh, FREAD|FWRITE, kcred);
2053 2065 }
2054 2066 }
2055 2067
2056 2068 /*
2057 2069 * Remove all disconnected keyboards,
2058 2070 * whose dev is turned into NODEV above.
2059 2071 */
2060 2072 consconfig_rem_dev(sp, NODEV);
2061 2073 }
2062 2074
2063 2075 /*
2064 2076 * Remove devices according to dev, which may be NODEV
2065 2077 */
2066 2078 static void
2067 2079 consconfig_rem_dev(cons_state_t *sp, dev_t dev)
2068 2080 {
2069 2081 cons_prop_t *prop;
2070 2082 cons_prop_t *prev_prop;
2071 2083 cons_prop_t *tmp_prop;
2072 2084 cons_prop_t *head_prop;
2073 2085
2074 2086 head_prop = NULL;
2075 2087 prev_prop = NULL;
2076 2088 for (prop = sp->cons_km_prop; prop != NULL; ) {
2077 2089 if (prop->cp_dev == dev) {
2078 2090 tmp_prop = prop->cp_next;
2079 2091 consconfig_free_prop(prop);
2080 2092 prop = tmp_prop;
2081 2093 if (prev_prop)
2082 2094 prev_prop->cp_next = prop;
2083 2095 } else {
2084 2096 if (head_prop == NULL)
2085 2097 head_prop = prop;
2086 2098 prev_prop = prop;
2087 2099 prop = prop->cp_next;
2088 2100 }
2089 2101 }
2090 2102 sp->cons_km_prop = head_prop;
2091 2103 }
2092 2104
2093 2105 /*
2094 2106 * Add a dev according to prop
2095 2107 */
2096 2108 static void
2097 2109 consconfig_add_dev(cons_state_t *sp, cons_prop_t *prop)
2098 2110 {
2099 2111 prop->cp_next = sp->cons_km_prop;
2100 2112 sp->cons_km_prop = prop;
2101 2113 }
2102 2114
2103 2115 /*
2104 2116 * Find a device from our list according to dev
2105 2117 */
2106 2118 static cons_prop_t *
2107 2119 consconfig_find_dev(cons_state_t *sp, dev_t dev)
2108 2120 {
2109 2121 cons_prop_t *prop;
2110 2122
2111 2123 for (prop = sp->cons_km_prop; prop; prop = prop->cp_next) {
2112 2124 if (prop->cp_dev == dev)
2113 2125 break;
2114 2126 }
2115 2127
2116 2128 return (prop);
2117 2129 }
2118 2130
2119 2131 /*
2120 2132 * Free a cons prop associated with a keyboard or mouse
2121 2133 */
2122 2134 static void
2123 2135 consconfig_free_prop(cons_prop_t *prop)
2124 2136 {
2125 2137 if (prop->cp_pushmod)
2126 2138 kmem_free(prop->cp_pushmod, strlen(prop->cp_pushmod) + 1);
2127 2139 kmem_free(prop, sizeof (cons_prop_t));
2128 2140 }
2129 2141
2130 2142 /*
2131 2143 * The early boot code can't print to a usb serial device or the
2132 2144 * graphical boot screen.
2133 2145 *
2134 2146 * The early boot messages are saved in a buffer at the address indicated
2135 2147 * by "deferred-console-buf" This function flushes the message to the
2136 2148 * current console now that it is set up.
2137 2149 */
2138 2150 static void
2139 2151 flush_deferred_console_buf(void)
2140 2152 {
2141 2153 int rval;
2142 2154 vnode_t *vp;
2143 2155 uint_t defcons_buf;
2144 2156 char *kc, *bc, *defcons_kern_buf;
2145 2157
2146 2158 /* defcons_buf is in low memory, so an int works here */
2147 2159 defcons_buf = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(),
2148 2160 DDI_PROP_DONTPASS, "deferred-console-buf", 0);
2149 2161
2150 2162 if (defcons_buf == 0)
2151 2163 return;
2152 2164
2153 2165 /*
2154 2166 * After consconfig() and before userland opens /dev/sysmsg,
2155 2167 * console I/O is goes to polled I/O entry points.
2156 2168 *
2157 2169 * If usb-serial doesn't implement polled I/O, we need
2158 2170 * to open /dev/console now to get kernel console I/O to work.
2159 2171 * We also push ttcompat and ldterm explicitly to get the
2160 2172 * correct output format (autopush isn't set up yet). We
2161 2173 * ignore push errors because they are non-fatal.
2162 2174 * Note that opening /dev/console causes rconsvp to be
2163 2175 * opened as well.
2164 2176 */
2165 2177 if (cons_polledio == NULL) {
2166 2178 if (vn_open("/dev/console", UIO_SYSSPACE, FWRITE | FNOCTTY,
2167 2179 0, &vp, 0, 0) != 0)
2168 2180 return;
2169 2181
2170 2182 if (rconsvp) {
2171 2183 (void) strioctl(rconsvp, __I_PUSH_NOCTTY,
2172 2184 (intptr_t)"ldterm", FKIOCTL, K_TO_K, kcred, &rval);
2173 2185 (void) strioctl(rconsvp, __I_PUSH_NOCTTY,
2174 2186 (intptr_t)"ttcompat", FKIOCTL, K_TO_K,
2175 2187 kcred, &rval);
2176 2188 }
2177 2189 }
2178 2190
2179 2191 /*
2180 2192 * Copy message to a kernel buffer. Various kernel routines
2181 2193 * expect buffer to be above kernelbase
2182 2194 */
2183 2195 kc = defcons_kern_buf = kmem_zalloc(MMU_PAGESIZE, KM_SLEEP);
2184 2196 bc = (char *)(uintptr_t)defcons_buf;
2185 2197 while (*kc++ = *bc++)
2186 2198 ;
2187 2199 console_printf("%s", defcons_kern_buf);
2188 2200
2189 2201 kmem_free(defcons_kern_buf, MMU_PAGESIZE);
2190 2202 }
2191 2203
2192 2204 boolean_t
2193 2205 consconfig_console_is_tipline(void)
2194 2206 {
2195 2207 cons_state_t *sp;
2196 2208
2197 2209 if ((sp = (cons_state_t *)space_fetch("consconfig")) == NULL)
2198 2210 return (B_FALSE);
2199 2211
2200 2212 if (sp->cons_input_type == CONSOLE_TIP)
2201 2213 return (B_TRUE);
2202 2214
2203 2215 return (B_FALSE);
2204 2216 }
2205 2217
2206 2218 boolean_t
2207 2219 consconfig_dacf_initialized(void)
2208 2220 {
2209 2221 cons_state_t *sp;
2210 2222
2211 2223 if ((sp = (cons_state_t *)space_fetch("consconfig")) == NULL)
2212 2224 return (B_FALSE);
2213 2225
2214 2226 return (sp->cons_initialized);
2215 2227 }
|
↓ open down ↓ |
708 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX