Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/kbd/kbd.c
Show All 29 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_kbd.h" | #include "opt_kbd.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/lock.h> | |||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mutex.h> | |||||
#include <sys/conf.h> | #include <sys/conf.h> | ||||
#include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||
#include <sys/poll.h> | #include <sys/poll.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/selinfo.h> | #include <sys/selinfo.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
#define ARRAY_DELTA 4 | #define ARRAY_DELTA 4 | ||||
static int | static int | ||||
kbd_realloc_array(void) | kbd_realloc_array(void) | ||||
{ | { | ||||
keyboard_t **new_kbd; | keyboard_t **new_kbd; | ||||
int newsize; | int newsize; | ||||
int s; | |||||
s = spltty(); | GIANT_REQUIRED; | ||||
newsize = rounddown(keyboards + ARRAY_DELTA, ARRAY_DELTA); | newsize = rounddown(keyboards + ARRAY_DELTA, ARRAY_DELTA); | ||||
new_kbd = malloc(sizeof(*new_kbd)*newsize, M_DEVBUF, M_NOWAIT|M_ZERO); | new_kbd = malloc(sizeof(*new_kbd)*newsize, M_DEVBUF, M_NOWAIT|M_ZERO); | ||||
if (new_kbd == NULL) { | if (new_kbd == NULL) { | ||||
splx(s); | |||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
bcopy(keyboard, new_kbd, sizeof(*keyboard)*keyboards); | bcopy(keyboard, new_kbd, sizeof(*keyboard)*keyboards); | ||||
if (keyboards > 1) | if (keyboards > 1) | ||||
free(keyboard, M_DEVBUF); | free(keyboard, M_DEVBUF); | ||||
keyboard = new_kbd; | keyboard = new_kbd; | ||||
keyboards = newsize; | keyboards = newsize; | ||||
splx(s); | |||||
if (bootverbose) | if (bootverbose) | ||||
printf("kbd: new array size %d\n", keyboards); | printf("kbd: new array size %d\n", keyboards); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | kbd_register(keyboard_t *kbd) | ||||
return (-1); | return (-1); | ||||
} | } | ||||
int | int | ||||
kbd_unregister(keyboard_t *kbd) | kbd_unregister(keyboard_t *kbd) | ||||
{ | { | ||||
int error; | int error; | ||||
int s; | |||||
GIANT_REQUIRED; | |||||
if ((kbd->kb_index < 0) || (kbd->kb_index >= keyboards)) | if ((kbd->kb_index < 0) || (kbd->kb_index >= keyboards)) | ||||
return (ENOENT); | return (ENOENT); | ||||
if (keyboard[kbd->kb_index] != kbd) | if (keyboard[kbd->kb_index] != kbd) | ||||
return (ENOENT); | return (ENOENT); | ||||
s = spltty(); | |||||
if (KBD_IS_BUSY(kbd)) { | if (KBD_IS_BUSY(kbd)) { | ||||
error = (*kbd->kb_callback.kc_func)(kbd, KBDIO_UNLOADING, | error = (*kbd->kb_callback.kc_func)(kbd, KBDIO_UNLOADING, | ||||
kbd->kb_callback.kc_arg); | kbd->kb_callback.kc_arg); | ||||
if (error) { | if (error) { | ||||
splx(s); | |||||
return (error); | return (error); | ||||
} | } | ||||
if (KBD_IS_BUSY(kbd)) { | if (KBD_IS_BUSY(kbd)) { | ||||
splx(s); | |||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
} | } | ||||
KBD_INVALID(kbd); | KBD_INVALID(kbd); | ||||
keyboard[kbd->kb_index] = NULL; | keyboard[kbd->kb_index] = NULL; | ||||
splx(s); | |||||
return (0); | return (0); | ||||
} | } | ||||
/* find a function table by the driver name */ | /* find a function table by the driver name */ | ||||
keyboard_switch_t * | keyboard_switch_t * | ||||
kbd_get_switch(char *driver) | kbd_get_switch(char *driver) | ||||
{ | { | ||||
const keyboard_driver_t *p; | const keyboard_driver_t *p; | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* allocate a keyboard */ | /* allocate a keyboard */ | ||||
int | int | ||||
kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func, | kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func, | ||||
void *arg) | void *arg) | ||||
{ | { | ||||
int index; | int index; | ||||
int s; | |||||
GIANT_REQUIRED; | |||||
if (func == NULL) | if (func == NULL) | ||||
return (-1); | return (-1); | ||||
s = spltty(); | |||||
index = kbd_find_keyboard(driver, unit); | index = kbd_find_keyboard(driver, unit); | ||||
if (index >= 0) { | if (index >= 0) { | ||||
if (KBD_IS_BUSY(keyboard[index])) { | if (KBD_IS_BUSY(keyboard[index])) { | ||||
splx(s); | |||||
return (-1); | return (-1); | ||||
} | } | ||||
keyboard[index]->kb_token = id; | keyboard[index]->kb_token = id; | ||||
KBD_BUSY(keyboard[index]); | KBD_BUSY(keyboard[index]); | ||||
keyboard[index]->kb_callback.kc_func = func; | keyboard[index]->kb_callback.kc_func = func; | ||||
keyboard[index]->kb_callback.kc_arg = arg; | keyboard[index]->kb_callback.kc_arg = arg; | ||||
kbdd_clear_state(keyboard[index]); | kbdd_clear_state(keyboard[index]); | ||||
} | } | ||||
splx(s); | |||||
return (index); | return (index); | ||||
} | } | ||||
int | int | ||||
kbd_release(keyboard_t *kbd, void *id) | kbd_release(keyboard_t *kbd, void *id) | ||||
{ | { | ||||
int error; | int error; | ||||
int s; | |||||
s = spltty(); | GIANT_REQUIRED; | ||||
if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) { | if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) { | ||||
error = EINVAL; | error = EINVAL; | ||||
} else if (kbd->kb_token != id) { | } else if (kbd->kb_token != id) { | ||||
error = EPERM; | error = EPERM; | ||||
} else { | } else { | ||||
kbd->kb_token = NULL; | kbd->kb_token = NULL; | ||||
KBD_UNBUSY(kbd); | KBD_UNBUSY(kbd); | ||||
kbd->kb_callback.kc_func = NULL; | kbd->kb_callback.kc_func = NULL; | ||||
kbd->kb_callback.kc_arg = NULL; | kbd->kb_callback.kc_arg = NULL; | ||||
kbdd_clear_state(kbd); | kbdd_clear_state(kbd); | ||||
error = 0; | error = 0; | ||||
} | } | ||||
splx(s); | |||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
kbd_change_callback(keyboard_t *kbd, void *id, kbd_callback_func_t *func, | kbd_change_callback(keyboard_t *kbd, void *id, kbd_callback_func_t *func, | ||||
markj: I think this function is unused, BTW. Maybe better to leave it though. | |||||
Done Inline ActionsI am grepping through all commits now to confirm. emaste: I am grepping through all commits now to confirm. | |||||
Done Inline ActionsIndeed, the only commits referencing kbd_change_callback in the tree are: R10:617b90803690a7ece8e76a49803385516bac380b (introduction) emaste: Indeed, the only commits referencing `kbd_change_callback` in the tree are:
R10… | |||||
void *arg) | void *arg) | ||||
{ | { | ||||
int error; | int error; | ||||
int s; | |||||
s = spltty(); | GIANT_REQUIRED; | ||||
if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) { | if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) { | ||||
error = EINVAL; | error = EINVAL; | ||||
} else if (kbd->kb_token != id) { | } else if (kbd->kb_token != id) { | ||||
error = EPERM; | error = EPERM; | ||||
} else if (func == NULL) { | } else if (func == NULL) { | ||||
error = EINVAL; | error = EINVAL; | ||||
} else { | } else { | ||||
kbd->kb_callback.kc_func = func; | kbd->kb_callback.kc_func = func; | ||||
kbd->kb_callback.kc_arg = arg; | kbd->kb_callback.kc_arg = arg; | ||||
error = 0; | error = 0; | ||||
} | } | ||||
splx(s); | |||||
return (error); | return (error); | ||||
} | } | ||||
/* get a keyboard structure */ | /* get a keyboard structure */ | ||||
keyboard_t * | keyboard_t * | ||||
kbd_get_keyboard(int index) | kbd_get_keyboard(int index) | ||||
{ | { | ||||
if ((index < 0) || (index >= keyboards)) | if ((index < 0) || (index >= keyboards)) | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | |||||
static kbd_callback_func_t genkbd_event; | static kbd_callback_func_t genkbd_event; | ||||
static int | static int | ||||
genkbdopen(struct cdev *dev, int mode, int flag, struct thread *td) | genkbdopen(struct cdev *dev, int mode, int flag, struct thread *td) | ||||
{ | { | ||||
keyboard_t *kbd; | keyboard_t *kbd; | ||||
genkbd_softc_t *sc; | genkbd_softc_t *sc; | ||||
int s; | |||||
int i; | int i; | ||||
s = spltty(); | GIANT_REQUIRED; | ||||
sc = dev->si_drv1; | sc = dev->si_drv1; | ||||
kbd = kbd_get_keyboard(KBD_INDEX(dev)); | kbd = kbd_get_keyboard(KBD_INDEX(dev)); | ||||
if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | ||||
splx(s); | |||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
i = kbd_allocate(kbd->kb_name, kbd->kb_unit, sc, | i = kbd_allocate(kbd->kb_name, kbd->kb_unit, sc, | ||||
genkbd_event, (void *)sc); | genkbd_event, (void *)sc); | ||||
if (i < 0) { | if (i < 0) { | ||||
splx(s); | |||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
/* assert(i == kbd->kb_index) */ | /* assert(i == kbd->kb_index) */ | ||||
/* assert(kbd == kbd_get_keyboard(i)) */ | /* assert(kbd == kbd_get_keyboard(i)) */ | ||||
/* | /* | ||||
* NOTE: even when we have successfully claimed a keyboard, | * NOTE: even when we have successfully claimed a keyboard, | ||||
* the device may still be missing (!KBD_HAS_DEVICE(kbd)). | * the device may still be missing (!KBD_HAS_DEVICE(kbd)). | ||||
*/ | */ | ||||
sc->gkb_q_length = 0; | sc->gkb_q_length = 0; | ||||
splx(s); | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
genkbdclose(struct cdev *dev, int mode, int flag, struct thread *td) | genkbdclose(struct cdev *dev, int mode, int flag, struct thread *td) | ||||
{ | { | ||||
keyboard_t *kbd; | keyboard_t *kbd; | ||||
genkbd_softc_t *sc; | genkbd_softc_t *sc; | ||||
int s; | |||||
GIANT_REQUIRED; | |||||
/* | /* | ||||
* NOTE: the device may have already become invalid. | * NOTE: the device may have already become invalid. | ||||
* kbd == NULL || !KBD_IS_VALID(kbd) | * kbd == NULL || !KBD_IS_VALID(kbd) | ||||
*/ | */ | ||||
s = spltty(); | |||||
sc = dev->si_drv1; | sc = dev->si_drv1; | ||||
kbd = kbd_get_keyboard(KBD_INDEX(dev)); | kbd = kbd_get_keyboard(KBD_INDEX(dev)); | ||||
if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | ||||
/* XXX: we shall be forgiving and don't report error... */ | /* XXX: we shall be forgiving and don't report error... */ | ||||
} else { | } else { | ||||
kbd_release(kbd, (void *)sc); | kbd_release(kbd, (void *)sc); | ||||
} | } | ||||
splx(s); | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
genkbdread(struct cdev *dev, struct uio *uio, int flag) | genkbdread(struct cdev *dev, struct uio *uio, int flag) | ||||
{ | { | ||||
keyboard_t *kbd; | keyboard_t *kbd; | ||||
genkbd_softc_t *sc; | genkbd_softc_t *sc; | ||||
u_char buffer[KB_BUFSIZE]; | u_char buffer[KB_BUFSIZE]; | ||||
int len; | int len; | ||||
int error; | int error; | ||||
int s; | |||||
GIANT_REQUIRED; | |||||
/* wait for input */ | /* wait for input */ | ||||
s = spltty(); | |||||
sc = dev->si_drv1; | sc = dev->si_drv1; | ||||
kbd = kbd_get_keyboard(KBD_INDEX(dev)); | kbd = kbd_get_keyboard(KBD_INDEX(dev)); | ||||
if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | ||||
splx(s); | |||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
while (sc->gkb_q_length == 0) { | while (sc->gkb_q_length == 0) { | ||||
if (flag & O_NONBLOCK) { | if (flag & O_NONBLOCK) { | ||||
splx(s); | |||||
return (EWOULDBLOCK); | return (EWOULDBLOCK); | ||||
} | } | ||||
sc->gkb_flags |= KB_ASLEEP; | sc->gkb_flags |= KB_ASLEEP; | ||||
error = tsleep(sc, PZERO | PCATCH, "kbdrea", 0); | error = tsleep(sc, PZERO | PCATCH, "kbdrea", 0); | ||||
kbd = kbd_get_keyboard(KBD_INDEX(dev)); | kbd = kbd_get_keyboard(KBD_INDEX(dev)); | ||||
if ((kbd == NULL) || !KBD_IS_VALID(kbd)) { | if ((kbd == NULL) || !KBD_IS_VALID(kbd)) { | ||||
splx(s); | |||||
return (ENXIO); /* our keyboard has gone... */ | return (ENXIO); /* our keyboard has gone... */ | ||||
} | } | ||||
if (error) { | if (error) { | ||||
sc->gkb_flags &= ~KB_ASLEEP; | sc->gkb_flags &= ~KB_ASLEEP; | ||||
splx(s); | |||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
splx(s); | |||||
/* copy as much input as possible */ | /* copy as much input as possible */ | ||||
error = 0; | error = 0; | ||||
while (uio->uio_resid > 0) { | while (uio->uio_resid > 0) { | ||||
len = imin(uio->uio_resid, sizeof(buffer)); | len = imin(uio->uio_resid, sizeof(buffer)); | ||||
len = genkbd_getc(sc, buffer, len); | len = genkbd_getc(sc, buffer, len); | ||||
if (len <= 0) | if (len <= 0) | ||||
break; | break; | ||||
Show All 32 Lines | |||||
} | } | ||||
static int | static int | ||||
genkbdpoll(struct cdev *dev, int events, struct thread *td) | genkbdpoll(struct cdev *dev, int events, struct thread *td) | ||||
{ | { | ||||
keyboard_t *kbd; | keyboard_t *kbd; | ||||
genkbd_softc_t *sc; | genkbd_softc_t *sc; | ||||
int revents; | int revents; | ||||
int s; | |||||
GIANT_REQUIRED; | |||||
revents = 0; | revents = 0; | ||||
s = spltty(); | |||||
sc = dev->si_drv1; | sc = dev->si_drv1; | ||||
kbd = kbd_get_keyboard(KBD_INDEX(dev)); | kbd = kbd_get_keyboard(KBD_INDEX(dev)); | ||||
if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { | ||||
revents = POLLHUP; /* the keyboard has gone */ | revents = POLLHUP; /* the keyboard has gone */ | ||||
} else if (events & (POLLIN | POLLRDNORM)) { | } else if (events & (POLLIN | POLLRDNORM)) { | ||||
if (sc->gkb_q_length > 0) | if (sc->gkb_q_length > 0) | ||||
revents = events & (POLLIN | POLLRDNORM); | revents = events & (POLLIN | POLLRDNORM); | ||||
else | else | ||||
selrecord(td, &sc->gkb_rsel); | selrecord(td, &sc->gkb_rsel); | ||||
} | } | ||||
splx(s); | |||||
return (revents); | return (revents); | ||||
} | } | ||||
static int | static int | ||||
genkbd_event(keyboard_t *kbd, int event, void *arg) | genkbd_event(keyboard_t *kbd, int event, void *arg) | ||||
{ | { | ||||
genkbd_softc_t *sc; | genkbd_softc_t *sc; | ||||
size_t len; | size_t len; | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) | genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) | ||||
{ | { | ||||
keymap_t *mapp; | keymap_t *mapp; | ||||
okeymap_t *omapp; | okeymap_t *omapp; | ||||
keyarg_t *keyp; | keyarg_t *keyp; | ||||
fkeyarg_t *fkeyp; | fkeyarg_t *fkeyp; | ||||
int s; | |||||
int i, j; | int i, j; | ||||
int error; | int error; | ||||
s = spltty(); | GIANT_REQUIRED; | ||||
switch (cmd) { | switch (cmd) { | ||||
case KDGKBINFO: /* get keyboard information */ | case KDGKBINFO: /* get keyboard information */ | ||||
((keyboard_info_t *)arg)->kb_index = kbd->kb_index; | ((keyboard_info_t *)arg)->kb_index = kbd->kb_index; | ||||
i = imin(strlen(kbd->kb_name) + 1, | i = imin(strlen(kbd->kb_name) + 1, | ||||
sizeof(((keyboard_info_t *)arg)->kb_name)); | sizeof(((keyboard_info_t *)arg)->kb_name)); | ||||
bcopy(kbd->kb_name, ((keyboard_info_t *)arg)->kb_name, i); | bcopy(kbd->kb_name, ((keyboard_info_t *)arg)->kb_name, i); | ||||
((keyboard_info_t *)arg)->kb_unit = kbd->kb_unit; | ((keyboard_info_t *)arg)->kb_unit = kbd->kb_unit; | ||||
Show All 9 Lines | genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) | ||||
case KDGETREPEAT: /* get keyboard repeat rate */ | case KDGETREPEAT: /* get keyboard repeat rate */ | ||||
((int *)arg)[0] = kbd->kb_delay1; | ((int *)arg)[0] = kbd->kb_delay1; | ||||
((int *)arg)[1] = kbd->kb_delay2; | ((int *)arg)[1] = kbd->kb_delay2; | ||||
break; | break; | ||||
case GIO_KEYMAP: /* get keyboard translation table */ | case GIO_KEYMAP: /* get keyboard translation table */ | ||||
error = copyout(kbd->kb_keymap, *(void **)arg, | error = copyout(kbd->kb_keymap, *(void **)arg, | ||||
sizeof(keymap_t)); | sizeof(keymap_t)); | ||||
splx(s); | |||||
return (error); | return (error); | ||||
case OGIO_KEYMAP: /* get keyboard translation table (compat) */ | case OGIO_KEYMAP: /* get keyboard translation table (compat) */ | ||||
mapp = kbd->kb_keymap; | mapp = kbd->kb_keymap; | ||||
omapp = (okeymap_t *)arg; | omapp = (okeymap_t *)arg; | ||||
omapp->n_keys = mapp->n_keys; | omapp->n_keys = mapp->n_keys; | ||||
for (i = 0; i < NUM_KEYS; i++) { | for (i = 0; i < NUM_KEYS; i++) { | ||||
for (j = 0; j < NUM_STATES; j++) | for (j = 0; j < NUM_STATES; j++) | ||||
omapp->key[i].map[j] = | omapp->key[i].map[j] = | ||||
Show All 14 Lines | if (cmd == OPIO_KEYMAP) { | ||||
mapp->key[i].map[j] = | mapp->key[i].map[j] = | ||||
omapp->key[i].map[j]; | omapp->key[i].map[j]; | ||||
mapp->key[i].spcl = omapp->key[i].spcl; | mapp->key[i].spcl = omapp->key[i].spcl; | ||||
mapp->key[i].flgs = omapp->key[i].flgs; | mapp->key[i].flgs = omapp->key[i].flgs; | ||||
} | } | ||||
} else { | } else { | ||||
error = copyin(*(void **)arg, mapp, sizeof *mapp); | error = copyin(*(void **)arg, mapp, sizeof *mapp); | ||||
if (error != 0) { | if (error != 0) { | ||||
splx(s); | |||||
free(mapp, M_TEMP); | free(mapp, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
error = keymap_change_ok(kbd->kb_keymap, mapp, curthread); | error = keymap_change_ok(kbd->kb_keymap, mapp, curthread); | ||||
if (error != 0) { | if (error != 0) { | ||||
splx(s); | |||||
free(mapp, M_TEMP); | free(mapp, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
bzero(kbd->kb_accentmap, sizeof(*kbd->kb_accentmap)); | bzero(kbd->kb_accentmap, sizeof(*kbd->kb_accentmap)); | ||||
bcopy(mapp, kbd->kb_keymap, sizeof(*kbd->kb_keymap)); | bcopy(mapp, kbd->kb_keymap, sizeof(*kbd->kb_keymap)); | ||||
free(mapp, M_TEMP); | free(mapp, M_TEMP); | ||||
break; | break; | ||||
#else | #else | ||||
splx(s); | |||||
return (ENODEV); | return (ENODEV); | ||||
#endif | #endif | ||||
case GIO_KEYMAPENT: /* get keyboard translation table entry */ | case GIO_KEYMAPENT: /* get keyboard translation table entry */ | ||||
keyp = (keyarg_t *)arg; | keyp = (keyarg_t *)arg; | ||||
if (keyp->keynum >= sizeof(kbd->kb_keymap->key) / | if (keyp->keynum >= sizeof(kbd->kb_keymap->key) / | ||||
sizeof(kbd->kb_keymap->key[0])) { | sizeof(kbd->kb_keymap->key[0])) { | ||||
splx(s); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
bcopy(&kbd->kb_keymap->key[keyp->keynum], &keyp->key, | bcopy(&kbd->kb_keymap->key[keyp->keynum], &keyp->key, | ||||
sizeof(keyp->key)); | sizeof(keyp->key)); | ||||
break; | break; | ||||
case PIO_KEYMAPENT: /* set keyboard translation table entry */ | case PIO_KEYMAPENT: /* set keyboard translation table entry */ | ||||
#ifndef KBD_DISABLE_KEYMAP_LOAD | #ifndef KBD_DISABLE_KEYMAP_LOAD | ||||
keyp = (keyarg_t *)arg; | keyp = (keyarg_t *)arg; | ||||
if (keyp->keynum >= sizeof(kbd->kb_keymap->key) / | if (keyp->keynum >= sizeof(kbd->kb_keymap->key) / | ||||
sizeof(kbd->kb_keymap->key[0])) { | sizeof(kbd->kb_keymap->key[0])) { | ||||
splx(s); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
error = key_change_ok(&kbd->kb_keymap->key[keyp->keynum], | error = key_change_ok(&kbd->kb_keymap->key[keyp->keynum], | ||||
&keyp->key, curthread); | &keyp->key, curthread); | ||||
if (error != 0) { | if (error != 0) { | ||||
splx(s); | |||||
return (error); | return (error); | ||||
} | } | ||||
bcopy(&keyp->key, &kbd->kb_keymap->key[keyp->keynum], | bcopy(&keyp->key, &kbd->kb_keymap->key[keyp->keynum], | ||||
sizeof(keyp->key)); | sizeof(keyp->key)); | ||||
break; | break; | ||||
#else | #else | ||||
splx(s); | |||||
return (ENODEV); | return (ENODEV); | ||||
#endif | #endif | ||||
case GIO_DEADKEYMAP: /* get accent key translation table */ | case GIO_DEADKEYMAP: /* get accent key translation table */ | ||||
bcopy(kbd->kb_accentmap, arg, sizeof(*kbd->kb_accentmap)); | bcopy(kbd->kb_accentmap, arg, sizeof(*kbd->kb_accentmap)); | ||||
break; | break; | ||||
case PIO_DEADKEYMAP: /* set accent key translation table */ | case PIO_DEADKEYMAP: /* set accent key translation table */ | ||||
#ifndef KBD_DISABLE_KEYMAP_LOAD | #ifndef KBD_DISABLE_KEYMAP_LOAD | ||||
error = accent_change_ok(kbd->kb_accentmap, | error = accent_change_ok(kbd->kb_accentmap, | ||||
(accentmap_t *)arg, curthread); | (accentmap_t *)arg, curthread); | ||||
if (error != 0) { | if (error != 0) { | ||||
splx(s); | |||||
return (error); | return (error); | ||||
} | } | ||||
bcopy(arg, kbd->kb_accentmap, sizeof(*kbd->kb_accentmap)); | bcopy(arg, kbd->kb_accentmap, sizeof(*kbd->kb_accentmap)); | ||||
break; | break; | ||||
#else | #else | ||||
splx(s); | |||||
return (ENODEV); | return (ENODEV); | ||||
#endif | #endif | ||||
case GETFKEY: /* get functionkey string */ | case GETFKEY: /* get functionkey string */ | ||||
fkeyp = (fkeyarg_t *)arg; | fkeyp = (fkeyarg_t *)arg; | ||||
if (fkeyp->keynum >= kbd->kb_fkeytab_size) { | if (fkeyp->keynum >= kbd->kb_fkeytab_size) { | ||||
splx(s); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
bcopy(kbd->kb_fkeytab[fkeyp->keynum].str, fkeyp->keydef, | bcopy(kbd->kb_fkeytab[fkeyp->keynum].str, fkeyp->keydef, | ||||
kbd->kb_fkeytab[fkeyp->keynum].len); | kbd->kb_fkeytab[fkeyp->keynum].len); | ||||
fkeyp->flen = kbd->kb_fkeytab[fkeyp->keynum].len; | fkeyp->flen = kbd->kb_fkeytab[fkeyp->keynum].len; | ||||
break; | break; | ||||
case SETFKEY: /* set functionkey string */ | case SETFKEY: /* set functionkey string */ | ||||
#ifndef KBD_DISABLE_KEYMAP_LOAD | #ifndef KBD_DISABLE_KEYMAP_LOAD | ||||
fkeyp = (fkeyarg_t *)arg; | fkeyp = (fkeyarg_t *)arg; | ||||
if (fkeyp->keynum >= kbd->kb_fkeytab_size) { | if (fkeyp->keynum >= kbd->kb_fkeytab_size) { | ||||
splx(s); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
error = fkey_change_ok(&kbd->kb_fkeytab[fkeyp->keynum], | error = fkey_change_ok(&kbd->kb_fkeytab[fkeyp->keynum], | ||||
fkeyp, curthread); | fkeyp, curthread); | ||||
if (error != 0) { | if (error != 0) { | ||||
splx(s); | |||||
return (error); | return (error); | ||||
} | } | ||||
kbd->kb_fkeytab[fkeyp->keynum].len = min(fkeyp->flen, MAXFK); | kbd->kb_fkeytab[fkeyp->keynum].len = min(fkeyp->flen, MAXFK); | ||||
bcopy(fkeyp->keydef, kbd->kb_fkeytab[fkeyp->keynum].str, | bcopy(fkeyp->keydef, kbd->kb_fkeytab[fkeyp->keynum].str, | ||||
kbd->kb_fkeytab[fkeyp->keynum].len); | kbd->kb_fkeytab[fkeyp->keynum].len); | ||||
break; | break; | ||||
#else | #else | ||||
splx(s); | |||||
return (ENODEV); | return (ENODEV); | ||||
#endif | #endif | ||||
default: | default: | ||||
splx(s); | |||||
return (ENOIOCTL); | return (ENOIOCTL); | ||||
} | } | ||||
splx(s); | |||||
return (0); | return (0); | ||||
} | } | ||||
#ifndef KBD_DISABLE_KEYMAP_LOAD | #ifndef KBD_DISABLE_KEYMAP_LOAD | ||||
#define RESTRICTED_KEY(key, i) \ | #define RESTRICTED_KEY(key, i) \ | ||||
((key->spcl & (0x80 >> i)) && \ | ((key->spcl & (0x80 >> i)) && \ | ||||
(key->map[i] == RBT || key->map[i] == SUSP || \ | (key->map[i] == RBT || key->map[i] == SUSP || \ | ||||
key->map[i] == STBY || key->map[i] == DBG || \ | key->map[i] == STBY || key->map[i] == DBG || \ | ||||
▲ Show 20 Lines • Show All 517 Lines • Show Last 20 Lines |
I think this function is unused, BTW. Maybe better to leave it though.