Index: sys/dev/kbd/kbd.c =================================================================== --- sys/dev/kbd/kbd.c +++ 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,23 +236,6 @@ 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); } @@ -1510,16 +1491,19 @@ static void kbd_drv_init(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; + + 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: sys/dev/kbd/kbdreg.h =================================================================== --- sys/dev/kbd/kbdreg.h +++ 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 */