kbd: remove kbdsw, store pointer to driver in each keyboard_t
The previous implementation relied on a kbdsw array that mirrored the global keyboards array. This is fine, but also requires extra locking consideration when accessing to ensure that it's not being resized as new keyboards are added. The extra pointer costs little in a struct that there are relatively few of on any given system, and simplifies locking requirements ever-so-slightly as we only need to consider the locking requirements of whichever method is being invoked. __FreeBSD_version is bumped as any kbd modules will need rebuilt following this change.
This commit is contained in:
parent
5796c91792
commit
cb3066a8ff
@ -83,8 +83,6 @@ SET_DECLARE(kbddriver_set, const keyboard_driver_t);
|
||||
static int keyboards = 1;
|
||||
static keyboard_t *kbd_ini;
|
||||
static keyboard_t **keyboard = &kbd_ini;
|
||||
static keyboard_switch_t *kbdsw_ini;
|
||||
keyboard_switch_t **kbdsw = &kbdsw_ini;
|
||||
|
||||
static int keymap_restrict_change;
|
||||
static SYSCTL_NODE(_hw, OID_AUTO, kbd, CTLFLAG_RD, 0, "kbd");
|
||||
@ -97,7 +95,6 @@ static int
|
||||
kbd_realloc_array(void)
|
||||
{
|
||||
keyboard_t **new_kbd;
|
||||
keyboard_switch_t **new_kbdsw;
|
||||
int newsize;
|
||||
int s;
|
||||
|
||||
@ -108,21 +105,10 @@ kbd_realloc_array(void)
|
||||
splx(s);
|
||||
return (ENOMEM);
|
||||
}
|
||||
new_kbdsw = malloc(sizeof(*new_kbdsw)*newsize, M_DEVBUF,
|
||||
M_NOWAIT|M_ZERO);
|
||||
if (new_kbdsw == NULL) {
|
||||
free(new_kbd, M_DEVBUF);
|
||||
splx(s);
|
||||
return (ENOMEM);
|
||||
}
|
||||
bcopy(keyboard, new_kbd, sizeof(*keyboard)*keyboards);
|
||||
bcopy(kbdsw, new_kbdsw, sizeof(*kbdsw)*keyboards);
|
||||
if (keyboards > 1) {
|
||||
if (keyboards > 1)
|
||||
free(keyboard, M_DEVBUF);
|
||||
free(kbdsw, M_DEVBUF);
|
||||
}
|
||||
keyboard = new_kbd;
|
||||
kbdsw = new_kbdsw;
|
||||
keyboards = newsize;
|
||||
splx(s);
|
||||
|
||||
@ -226,8 +212,8 @@ kbd_register(keyboard_t *kbd)
|
||||
|
||||
SLIST_FOREACH(p, &keyboard_drivers, link) {
|
||||
if (strcmp(p->name, kbd->kb_name) == 0) {
|
||||
kbd->kb_drv = p;
|
||||
keyboard[index] = kbd;
|
||||
kbdsw[index] = p->kbdsw;
|
||||
|
||||
if (mux != NULL) {
|
||||
bzero(&ki, sizeof(ki));
|
||||
@ -243,8 +229,8 @@ kbd_register(keyboard_t *kbd)
|
||||
SET_FOREACH(list, kbddriver_set) {
|
||||
p = *list;
|
||||
if (strcmp(p->name, kbd->kb_name) == 0) {
|
||||
kbd->kb_drv = p;
|
||||
keyboard[index] = kbd;
|
||||
kbdsw[index] = p->kbdsw;
|
||||
|
||||
if (mux != NULL) {
|
||||
bzero(&ki, sizeof(ki));
|
||||
@ -287,7 +273,6 @@ kbd_unregister(keyboard_t *kbd)
|
||||
}
|
||||
KBD_INVALID(kbd);
|
||||
keyboard[kbd->kb_index] = NULL;
|
||||
kbdsw[kbd->kb_index] = NULL;
|
||||
|
||||
splx(s);
|
||||
return (0);
|
||||
|
@ -41,6 +41,30 @@ struct cdevsw;
|
||||
/* call back funcion */
|
||||
typedef int kbd_callback_func_t(keyboard_t *kbd, int event,
|
||||
void *arg);
|
||||
|
||||
/* keyboard function table */
|
||||
typedef int kbd_probe_t(int unit, void *arg, int flags);
|
||||
typedef int kbd_init_t(int unit, keyboard_t **kbdp, void *arg,
|
||||
int flags);
|
||||
typedef int kbd_term_t(keyboard_t *kbd);
|
||||
typedef int kbd_intr_t(keyboard_t *kbd, void *arg);
|
||||
typedef int kbd_test_if_t(keyboard_t *kbd);
|
||||
typedef int kbd_enable_t(keyboard_t *kbd);
|
||||
typedef int kbd_disable_t(keyboard_t *kbd);
|
||||
typedef int kbd_read_t(keyboard_t *kbd, int wait);
|
||||
typedef int kbd_check_t(keyboard_t *kbd);
|
||||
typedef u_int kbd_read_char_t(keyboard_t *kbd, int wait);
|
||||
typedef int kbd_check_char_t(keyboard_t *kbd);
|
||||
typedef int kbd_ioctl_t(keyboard_t *kbd, u_long cmd, caddr_t data);
|
||||
typedef int kbd_lock_t(keyboard_t *kbd, int lock);
|
||||
typedef void kbd_clear_state_t(keyboard_t *kbd);
|
||||
typedef int kbd_get_state_t(keyboard_t *kbd, void *buf, size_t len);
|
||||
typedef int kbd_set_state_t(keyboard_t *kbd, void *buf, size_t len);
|
||||
typedef u_char *kbd_get_fkeystr_t(keyboard_t *kbd, int fkey,
|
||||
size_t *len);
|
||||
typedef int kbd_poll_mode_t(keyboard_t *kbd, int on);
|
||||
typedef void kbd_diag_t(keyboard_t *kbd, int level);
|
||||
|
||||
/* event types */
|
||||
#define KBDIO_KEYINPUT 0
|
||||
#define KBDIO_UNLOADING 1
|
||||
@ -50,6 +74,36 @@ typedef struct keyboard_callback {
|
||||
void *kc_arg;
|
||||
} keyboard_callback_t;
|
||||
|
||||
typedef struct keyboard_switch {
|
||||
kbd_probe_t *probe;
|
||||
kbd_init_t *init;
|
||||
kbd_term_t *term;
|
||||
kbd_intr_t *intr;
|
||||
kbd_test_if_t *test_if;
|
||||
kbd_enable_t *enable;
|
||||
kbd_disable_t *disable;
|
||||
kbd_read_t *read;
|
||||
kbd_check_t *check;
|
||||
kbd_read_char_t *read_char;
|
||||
kbd_check_char_t *check_char;
|
||||
kbd_ioctl_t *ioctl;
|
||||
kbd_lock_t *lock;
|
||||
kbd_clear_state_t *clear_state;
|
||||
kbd_get_state_t *get_state;
|
||||
kbd_set_state_t *set_state;
|
||||
kbd_get_fkeystr_t *get_fkeystr;
|
||||
kbd_poll_mode_t *poll;
|
||||
kbd_diag_t *diag;
|
||||
} keyboard_switch_t;
|
||||
|
||||
/* keyboard driver */
|
||||
typedef struct keyboard_driver {
|
||||
SLIST_ENTRY(keyboard_driver) link;
|
||||
char *name;
|
||||
keyboard_switch_t *kbdsw;
|
||||
int (*configure)(int); /* backdoor for the console driver */
|
||||
} keyboard_driver_t;
|
||||
|
||||
/* keyboard */
|
||||
struct keyboard {
|
||||
/* the following fields are managed by kbdio */
|
||||
@ -94,6 +148,7 @@ struct keyboard {
|
||||
unsigned long kb_count; /* # of processed key strokes */
|
||||
u_char kb_lastact[NUM_KEYS/2];
|
||||
struct cdev *kb_dev;
|
||||
const keyboard_driver_t *kb_drv;
|
||||
};
|
||||
|
||||
#define KBD_IS_VALID(k) ((k)->kb_flags & KB_VALID)
|
||||
@ -118,61 +173,6 @@ struct keyboard {
|
||||
#define KBD_DEACTIVATE(k) (--(k)->kb_active)
|
||||
#define KBD_LED_VAL(k) ((k)->kb_led)
|
||||
|
||||
/* keyboard function table */
|
||||
typedef int kbd_probe_t(int unit, void *arg, int flags);
|
||||
typedef int kbd_init_t(int unit, keyboard_t **kbdp, void *arg,
|
||||
int flags);
|
||||
typedef int kbd_term_t(keyboard_t *kbd);
|
||||
typedef int kbd_intr_t(keyboard_t *kbd, void *arg);
|
||||
typedef int kbd_test_if_t(keyboard_t *kbd);
|
||||
typedef int kbd_enable_t(keyboard_t *kbd);
|
||||
typedef int kbd_disable_t(keyboard_t *kbd);
|
||||
typedef int kbd_read_t(keyboard_t *kbd, int wait);
|
||||
typedef int kbd_check_t(keyboard_t *kbd);
|
||||
typedef u_int kbd_read_char_t(keyboard_t *kbd, int wait);
|
||||
typedef int kbd_check_char_t(keyboard_t *kbd);
|
||||
typedef int kbd_ioctl_t(keyboard_t *kbd, u_long cmd, caddr_t data);
|
||||
typedef int kbd_lock_t(keyboard_t *kbd, int lock);
|
||||
typedef void kbd_clear_state_t(keyboard_t *kbd);
|
||||
typedef int kbd_get_state_t(keyboard_t *kbd, void *buf, size_t len);
|
||||
typedef int kbd_set_state_t(keyboard_t *kbd, void *buf, size_t len);
|
||||
typedef u_char *kbd_get_fkeystr_t(keyboard_t *kbd, int fkey,
|
||||
size_t *len);
|
||||
typedef int kbd_poll_mode_t(keyboard_t *kbd, int on);
|
||||
typedef void kbd_diag_t(keyboard_t *kbd, int level);
|
||||
|
||||
typedef struct keyboard_switch {
|
||||
kbd_probe_t *probe;
|
||||
kbd_init_t *init;
|
||||
kbd_term_t *term;
|
||||
kbd_intr_t *intr;
|
||||
kbd_test_if_t *test_if;
|
||||
kbd_enable_t *enable;
|
||||
kbd_disable_t *disable;
|
||||
kbd_read_t *read;
|
||||
kbd_check_t *check;
|
||||
kbd_read_char_t *read_char;
|
||||
kbd_check_char_t *check_char;
|
||||
kbd_ioctl_t *ioctl;
|
||||
kbd_lock_t *lock;
|
||||
kbd_clear_state_t *clear_state;
|
||||
kbd_get_state_t *get_state;
|
||||
kbd_set_state_t *set_state;
|
||||
kbd_get_fkeystr_t *get_fkeystr;
|
||||
kbd_poll_mode_t *poll;
|
||||
kbd_diag_t *diag;
|
||||
} keyboard_switch_t;
|
||||
|
||||
/* keyboard driver */
|
||||
typedef struct keyboard_driver {
|
||||
SLIST_ENTRY(keyboard_driver) link;
|
||||
char *name;
|
||||
keyboard_switch_t *kbdsw;
|
||||
int (*configure)(int); /* backdoor for the console driver */
|
||||
} keyboard_driver_t;
|
||||
|
||||
extern keyboard_switch_t **kbdsw;
|
||||
|
||||
/*
|
||||
* Keyboard disciplines: call actual handlers via kbdsw[].
|
||||
*/
|
||||
@ -180,77 +180,77 @@ static __inline int
|
||||
kbdd_probe(keyboard_t *kbd, int unit, void *arg, int flags)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->probe)(unit, arg, flags));
|
||||
return ((*kbd->kb_drv->kbdsw->probe)(unit, arg, flags));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_init(keyboard_t *kbd, int unit, keyboard_t **kbdpp, void *arg, int flags)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->init)(unit, kbdpp, arg, flags));
|
||||
return ((*kbd->kb_drv->kbdsw->init)(unit, kbdpp, arg, flags));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_term(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->term)(kbd));
|
||||
return ((*kbd->kb_drv->kbdsw->term)(kbd));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_intr(keyboard_t *kbd, void *arg)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->intr)(kbd, arg));
|
||||
return ((*kbd->kb_drv->kbdsw->intr)(kbd, arg));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_test_if(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->test_if)(kbd));
|
||||
return ((*kbd->kb_drv->kbdsw->test_if)(kbd));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_enable(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->enable)(kbd));
|
||||
return ((*kbd->kb_drv->kbdsw->enable)(kbd));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_disable(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->disable)(kbd));
|
||||
return ((*kbd->kb_drv->kbdsw->disable)(kbd));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_read(keyboard_t *kbd, int wait)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->read)(kbd, wait));
|
||||
return ((*kbd->kb_drv->kbdsw->read)(kbd, wait));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_check(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->check)(kbd));
|
||||
return ((*kbd->kb_drv->kbdsw->check)(kbd));
|
||||
}
|
||||
|
||||
static __inline u_int
|
||||
kbdd_read_char(keyboard_t *kbd, int wait)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->read_char)(kbd, wait));
|
||||
return ((*kbd->kb_drv->kbdsw->read_char)(kbd, wait));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_check_char(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->check_char)(kbd));
|
||||
return ((*kbd->kb_drv->kbdsw->check_char)(kbd));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
@ -259,56 +259,56 @@ kbdd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
|
||||
|
||||
if (kbd == NULL)
|
||||
return (ENODEV);
|
||||
return ((*kbdsw[kbd->kb_index]->ioctl)(kbd, cmd, data));
|
||||
return ((*kbd->kb_drv->kbdsw->ioctl)(kbd, cmd, data));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_lock(keyboard_t *kbd, int lock)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->lock)(kbd, lock));
|
||||
return ((*kbd->kb_drv->kbdsw->lock)(kbd, lock));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
kbdd_clear_state(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
(*kbdsw[kbd->kb_index]->clear_state)(kbd);
|
||||
(*kbd->kb_drv->kbdsw->clear_state)(kbd);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_get_state(keyboard_t *kbd, void *buf, int len)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->get_state)(kbd, buf, len));
|
||||
return ((*kbd->kb_drv->kbdsw->get_state)(kbd, buf, len));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_set_state(keyboard_t *kbd, void *buf, int len)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->set_state)(kbd, buf, len));
|
||||
return ((*kbd->kb_drv->kbdsw->set_state)(kbd, buf, len));
|
||||
}
|
||||
|
||||
static __inline u_char *
|
||||
kbdd_get_fkeystr(keyboard_t *kbd, int fkey, size_t *len)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->get_fkeystr)(kbd, fkey, len));
|
||||
return ((*kbd->kb_drv->kbdsw->get_fkeystr)(kbd, fkey, len));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
kbdd_poll(keyboard_t *kbd, int on)
|
||||
{
|
||||
|
||||
return ((*kbdsw[kbd->kb_index]->poll)(kbd, on));
|
||||
return ((*kbd->kb_drv->kbdsw->poll)(kbd, on));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
kbdd_diag(keyboard_t *kbd, int level)
|
||||
{
|
||||
|
||||
(*kbdsw[kbd->kb_index]->diag)(kbd, level);
|
||||
(*kbd->kb_drv->kbdsw->diag)(kbd, level);
|
||||
}
|
||||
|
||||
#define KEYBOARD_DRIVER(name, sw, config) \
|
||||
|
@ -60,7 +60,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1300067 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1300068 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
Loading…
x
Reference in New Issue
Block a user