Index: head/sys/dev/kbd/kbd.c =================================================================== --- head/sys/dev/kbd/kbd.c +++ head/sys/dev/kbd/kbd.c @@ -70,7 +70,7 @@ static SLIST_HEAD(, keyboard_driver) keyboard_drivers = SLIST_HEAD_INITIALIZER(keyboard_drivers); -SET_DECLARE(kbddriver_set, const keyboard_driver_t); +SET_DECLARE(kbddriver_set, keyboard_driver_t); /* local arrays */ @@ -163,12 +163,18 @@ int kbd_add_driver(keyboard_driver_t *driver) { - if (SLIST_NEXT(driver, link)) - return (EINVAL); + + if ((driver->flags & KBDF_REGISTERED) != 0) + return (0); + + KASSERT(SLIST_NEXT(driver, link) == NULL, + ("%s: keyboard driver list garbage detected", __func__)); if (driver->kbdsw->get_fkeystr == NULL) driver->kbdsw->get_fkeystr = genkbd_get_fkeystr; if (driver->kbdsw->diag == NULL) driver->kbdsw->diag = genkbd_diag; + + driver->flags |= KBDF_REGISTERED; SLIST_INSERT_HEAD(&keyboard_drivers, driver, link); return (0); } @@ -176,6 +182,11 @@ int kbd_delete_driver(keyboard_driver_t *driver) { + + if ((driver->flags & KBDF_REGISTERED) == 0) + return (EINVAL); + + driver->flags &= ~KBDF_REGISTERED; SLIST_REMOVE(&keyboard_drivers, driver, keyboard_driver, link); SLIST_NEXT(driver, link) = NULL; return (0); @@ -185,7 +196,6 @@ int kbd_register(keyboard_t *kbd) { - const keyboard_driver_t **list; const keyboard_driver_t *p; keyboard_t *mux; keyboard_info_t ki; @@ -226,24 +236,7 @@ return (index); } } - SET_FOREACH(list, kbddriver_set) { - p = *list; - if (strcmp(p->name, kbd->kb_name) == 0) { - kbd->kb_drv = p; - keyboard[index] = kbd; - if (mux != NULL) { - bzero(&ki, sizeof(ki)); - strcpy(ki.kb_name, kbd->kb_name); - ki.kb_unit = kbd->kb_unit; - - (void)kbdd_ioctl(mux, KBADDKBD, (caddr_t) &ki); - } - - return (index); - } - } - return (-1); } @@ -282,18 +275,12 @@ keyboard_switch_t * kbd_get_switch(char *driver) { - const keyboard_driver_t **list; const keyboard_driver_t *p; SLIST_FOREACH(p, &keyboard_drivers, link) { if (strcmp(p->name, driver) == 0) return (p->kbdsw); } - SET_FOREACH(list, kbddriver_set) { - p = *list; - if (strcmp(p->name, driver) == 0) - return (p->kbdsw); - } return (NULL); } @@ -435,18 +422,12 @@ int kbd_configure(int flags) { - const keyboard_driver_t **list; const keyboard_driver_t *p; SLIST_FOREACH(p, &keyboard_drivers, link) { if (p->configure != NULL) (*p->configure)(flags); } - SET_FOREACH(list, kbddriver_set) { - p = *list; - if (p->configure != NULL) - (*p->configure)(flags); - } return (0); } @@ -1507,19 +1488,27 @@ } } -static void -kbd_drv_init(void) +void +kbdinit(void) { - const keyboard_driver_t **list; - const keyboard_driver_t *p; + keyboard_driver_t *drv, **list; SET_FOREACH(list, kbddriver_set) { - p = *list; - if (p->kbdsw->get_fkeystr == NULL) - p->kbdsw->get_fkeystr = genkbd_get_fkeystr; - if (p->kbdsw->diag == NULL) - p->kbdsw->diag = genkbd_diag; + drv = *list; + + /* + * The following printfs will almost universally get dropped, + * with exception to kernel configs with EARLY_PRINTF and + * special setups where msgbufinit() is called early with a + * static buffer to capture output occurring before the dynamic + * message buffer is mapped. + */ + if (kbd_add_driver(drv) != 0) + printf("kbd: failed to register driver '%s'\n", + drv->name); + else if (bootverbose) + printf("kbd: registered driver '%s'\n", + drv->name); } -} -SYSINIT(kbd_drv_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, kbd_drv_init, NULL); +} Index: head/sys/dev/kbd/kbdreg.h =================================================================== --- head/sys/dev/kbd/kbdreg.h +++ head/sys/dev/kbd/kbdreg.h @@ -107,8 +107,11 @@ keyboard_switch_t * const kbdsw; /* backdoor for the console driver */ int (* const configure)(int); + int flags; } keyboard_driver_t; +#define KBDF_REGISTERED 0x0001 + /* keyboard */ struct keyboard { /* the following fields are managed by kbdio */ @@ -396,6 +399,9 @@ #define LED_SCR (1 << 2) #define LED_MASK (LED_CAP | LED_NUM | LED_SCR) */ + +/* Initialization for the kbd layer, performed by cninit. */ +void kbdinit(void); int genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg); int genkbd_keyaction(keyboard_t *kbd, int keycode, int up, Index: head/sys/kern/kern_cons.c =================================================================== --- head/sys/kern/kern_cons.c +++ head/sys/kern/kern_cons.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,8 @@ #include +#include + #include #include @@ -122,6 +125,14 @@ |RB_SINGLE |RB_VERBOSE |RB_ASKNAME)) == RB_MUTE); + + /* + * Bring up the kbd layer just in time for cnprobe. Console drivers + * have a dependency on kbd being ready, so this fits nicely between the + * machdep callers of cninit() and MI probing/initialization of consoles + * here. + */ + kbdinit(); /* * Find the first console with the highest priority.