diff options
author | yokota <yokota@FreeBSD.org> | 1999-08-22 09:52:33 +0000 |
---|---|---|
committer | yokota <yokota@FreeBSD.org> | 1999-08-22 09:52:33 +0000 |
commit | c9a6c5e45ee0200a3cfb5349733d904c3bb9339f (patch) | |
tree | c863c8a9db1db731c5f9cddf215957eab25b7c1f /sys/dev/kbd/kbd.c | |
parent | ae67da834bc3aff6bb01df8bccc2d8f0ff8b97c9 (diff) | |
download | FreeBSD-src-c9a6c5e45ee0200a3cfb5349733d904c3bb9339f.zip FreeBSD-src-c9a6c5e45ee0200a3cfb5349733d904c3bb9339f.tar.gz |
- Remove cdevsw entry points in individual keyboard drivers;
instead, use generic entry points for all drivers.
- Eliminate bogus makedev().
- Eliminate softc in the lower drivers, as it is no longer necessary.
Submitted (95%) by: phk
Diffstat (limited to 'sys/dev/kbd/kbd.c')
-rw-r--r-- | sys/dev/kbd/kbd.c | 301 |
1 files changed, 98 insertions, 203 deletions
diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c index e858975..869a8ff 100644 --- a/sys/dev/kbd/kbd.c +++ b/sys/dev/kbd/kbd.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: kbd.c,v 1.8 1999/05/30 16:51:31 phk Exp $ + * $Id: kbd.c,v 1.9 1999/05/31 11:24:48 phk Exp $ */ #include "kbd.h" @@ -44,6 +44,15 @@ #include <dev/kbd/kbdreg.h> +#define KBD_INDEX(dev) minor(dev) + +typedef struct genkbd_softc { + int gkb_flags; /* flag/status bits */ +#define KB_ASLEEP (1 << 0) + struct clist gkb_q; /* input queue */ + struct selinfo gkb_rsel; +} genkbd_softc_t; + /* local arrays */ /* @@ -58,11 +67,6 @@ static keyboard_t **keyboard = &kbd_ini; static keyboard_switch_t *kbdsw_ini; keyboard_switch_t **kbdsw = &kbdsw_ini; -#ifdef KBD_INSTALL_CDEV -static struct cdevsw *kbdcdevsw_ini; -static struct cdevsw **kbdcdevsw = &kbdcdevsw_ini; -#endif - #define ARRAY_DELTA 4 static int @@ -70,9 +74,6 @@ kbd_realloc_array(void) { keyboard_t **new_kbd; keyboard_switch_t **new_kbdsw; -#ifdef KBD_INSTALL_CDEV - struct cdevsw **new_cdevsw; -#endif int newsize; int s; @@ -89,35 +90,16 @@ kbd_realloc_array(void) splx(s); return ENOMEM; } -#ifdef KBD_INSTALL_CDEV - new_cdevsw = malloc(sizeof(*new_cdevsw)*newsize, M_DEVBUF, M_NOWAIT); - if (new_cdevsw == NULL) { - free(new_kbd, M_DEVBUF); - free(new_kbdsw, M_DEVBUF); - splx(s); - return ENOMEM; - } -#endif bzero(new_kbd, sizeof(*new_kbd)*newsize); bzero(new_kbdsw, sizeof(*new_kbdsw)*newsize); bcopy(keyboard, new_kbd, sizeof(*keyboard)*keyboards); bcopy(kbdsw, new_kbdsw, sizeof(*kbdsw)*keyboards); -#ifdef KBD_INSTALL_CDEV - bzero(new_cdevsw, sizeof(*new_cdevsw)*newsize); - bcopy(kbdcdevsw, new_cdevsw, sizeof(*kbdcdevsw)*keyboards); -#endif if (keyboards > 1) { free(keyboard, M_DEVBUF); free(kbdsw, M_DEVBUF); -#ifdef KBD_INSTALL_CDEV - free(kbdcdevsw, M_DEVBUF); -#endif } keyboard = new_kbd; kbdsw = new_kbdsw; -#ifdef KBD_INSTALL_CDEV - kbdcdevsw = new_cdevsw; -#endif keyboards = newsize; splx(s); @@ -358,6 +340,8 @@ keyboard_t { if ((index < 0) || (index >= keyboards)) return NULL; + if (keyboard[index] == NULL) + return NULL; if (!KBD_IS_VALID(keyboard[index])) return NULL; return keyboard[index]; @@ -394,28 +378,26 @@ kbd_configure(int flags) #define KBD_UNIT(dev) minor(dev) -static d_open_t kbdopen; -static d_close_t kbdclose; -static d_read_t kbdread; -static d_write_t kbdwrite; -static d_ioctl_t kbdioctl; -static d_devtotty_t kbddevtotty; -static d_poll_t kbdpoll; -static d_mmap_t kbdmmap; +static d_open_t genkbdopen; +static d_close_t genkbdclose; +static d_read_t genkbdread; +static d_write_t genkbdwrite; +static d_ioctl_t genkbdioctl; +static d_poll_t genkbdpoll; #define CDEV_MAJOR 112 static struct cdevsw kbd_cdevsw = { - /* open */ kbdopen, - /* close */ kbdclose, - /* read */ kbdread, - /* write */ kbdwrite, - /* ioctl */ kbdioctl, + /* open */ genkbdopen, + /* close */ genkbdclose, + /* read */ genkbdread, + /* write */ genkbdwrite, + /* ioctl */ genkbdioctl, /* stop */ nostop, /* reset */ noreset, - /* devtotty */ kbddevtotty, - /* poll */ kbdpoll, - /* mmap */ kbdmmap, + /* devtotty */ nodevtotty, + /* poll */ genkbdpoll, + /* mmap */ nommap, /* strategy */ nostrategy, /* name */ "kbd", /* parms */ noparms, @@ -427,157 +409,39 @@ static struct cdevsw kbd_cdevsw = { /* bmaj */ -1 }; -static void -vkbdattach(void *arg) -{ - static int kbd_devsw_installed = FALSE; - - if (!kbd_devsw_installed) { - cdevsw_add(&kbd_cdevsw); - kbd_devsw_installed = TRUE; - } -} - -PSEUDO_SET(vkbdattach, kbd); - int -kbd_attach(dev_t dev, keyboard_t *kbd, struct cdevsw *cdevsw) +kbd_attach(keyboard_t *kbd) { - int s; + dev_t dev; if (kbd->kb_index >= keyboards) return EINVAL; if (keyboard[kbd->kb_index] != kbd) return EINVAL; - s = spltty(); - kbd->kb_minor = minor(dev); - kbdcdevsw[kbd->kb_index] = cdevsw; - splx(s); - - /* XXX: DEVFS? */ + dev = make_dev(&kbd_cdevsw, kbd->kb_index, UID_ROOT, GID_WHEEL, 0600, + "kbd%r", kbd->kb_index); + if (dev->si_drv1 == NULL) + dev->si_drv1 = malloc(sizeof(genkbd_softc_t), M_DEVBUF, + M_WAITOK); + bzero(dev->si_drv1, sizeof(genkbd_softc_t)); printf("kbd%d at %s%d\n", kbd->kb_index, kbd->kb_name, kbd->kb_unit); return 0; } int -kbd_detach(dev_t dev, keyboard_t *kbd, struct cdevsw *cdevsw) +kbd_detach(keyboard_t *kbd) { - int s; - if (kbd->kb_index >= keyboards) return EINVAL; if (keyboard[kbd->kb_index] != kbd) return EINVAL; - if (kbdcdevsw[kbd->kb_index] != cdevsw) - return EINVAL; - s = spltty(); - kbdcdevsw[kbd->kb_index] = NULL; - splx(s); + /* XXX: unmake_dev() ? */ return 0; } -static int -kbdopen(dev_t dev, int flag, int mode, struct proc *p) -{ - int unit; - - unit = KBD_UNIT(dev); - if (unit >= keyboards) - return ENXIO; - if (kbdcdevsw[unit] == NULL) - return ENXIO; - if (KBD_IS_BUSY(keyboard[unit])) - return EBUSY; - return (*kbdcdevsw[unit]->d_open)(makedev(0, keyboard[unit]->kb_minor), - flag, mode, p); -} - -static int -kbdclose(dev_t dev, int flag, int mode, struct proc *p) -{ - int unit; - - unit = KBD_UNIT(dev); - if (kbdcdevsw[unit] == NULL) - return ENXIO; - return (*kbdcdevsw[unit]->d_close)(makedev(0, keyboard[unit]->kb_minor), - flag, mode, p); -} - -static int -kbdread(dev_t dev, struct uio *uio, int flag) -{ - int unit; - - unit = KBD_UNIT(dev); - if (kbdcdevsw[unit] == NULL) - return ENXIO; - return (*kbdcdevsw[unit]->d_read)(makedev(0, keyboard[unit]->kb_minor), - uio, flag); -} - -static int -kbdwrite(dev_t dev, struct uio *uio, int flag) -{ - int unit; - - unit = KBD_UNIT(dev); - if (kbdcdevsw[unit] == NULL) - return ENXIO; - return (*kbdcdevsw[unit]->d_write)(makedev(0, keyboard[unit]->kb_minor), - uio, flag); -} - -static int -kbdioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p) -{ - int unit; - - unit = KBD_UNIT(dev); - if (kbdcdevsw[unit] == NULL) - return ENXIO; - return (*kbdcdevsw[unit]->d_ioctl)(makedev(0, keyboard[unit]->kb_minor), - cmd, arg, flag, p); -} - -static struct tty -*kbddevtotty(dev_t dev) -{ - int unit; - - unit = KBD_UNIT(dev); - if (kbdcdevsw[unit] == NULL) - return NULL; - return (*kbdcdevsw[unit]->d_devtotty)(makedev(0, keyboard[unit]->kb_minor)); -} - -static int -kbdpoll(dev_t dev, int event, struct proc *p) -{ - int unit; - - unit = KBD_UNIT(dev); - if (kbdcdevsw[unit] == NULL) - return ENXIO; - return (*kbdcdevsw[unit]->d_poll)(makedev(0, keyboard[unit]->kb_minor), - event, p); -} - -static int -kbdmmap(dev_t dev, vm_offset_t offset, int nprot) -{ - int unit; - - unit = KBD_UNIT(dev); - if (kbdcdevsw[unit] == NULL) - return ENXIO; - return (*kbdcdevsw[unit]->d_mmap)(makedev(0, keyboard[unit]->kb_minor), - offset, nprot); -} - /* * Generic keyboard cdev driver functions * Keyboard subdrivers may call these functions to implement common @@ -589,15 +453,18 @@ kbdmmap(dev_t dev, vm_offset_t offset, int nprot) static kbd_callback_func_t genkbd_event; -int -genkbdopen(genkbd_softc_t *sc, keyboard_t *kbd, int mode, int flag, - struct proc *p) +static int +genkbdopen(dev_t dev, int mode, int flag, struct proc *p) { + keyboard_t *kbd; + genkbd_softc_t *sc; int s; int i; s = spltty(); - if (!KBD_IS_VALID(kbd)) { + sc = dev->si_drv1; + kbd = kbd_get_keyboard(KBD_INDEX(dev)); + if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { splx(s); return ENXIO; } @@ -626,29 +493,37 @@ genkbdopen(genkbd_softc_t *sc, keyboard_t *kbd, int mode, int flag, return 0; } -int -genkbdclose(genkbd_softc_t *sc, keyboard_t *kbd, int mode, int flag, - struct proc *p) +static int +genkbdclose(dev_t dev, int mode, int flag, struct proc *p) { + keyboard_t *kbd; + genkbd_softc_t *sc; int s; /* * NOTE: the device may have already become invalid. - * !KBD_IS_VALID(kbd) + * kbd == NULL || !KBD_IS_VALID(kbd) */ s = spltty(); - kbd_release(kbd, (void *)sc); + sc = dev->si_drv1; + kbd = kbd_get_keyboard(KBD_INDEX(dev)); + if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { + /* XXX: we shall be forgiving and don't report error... */ + } else { + kbd_release(kbd, (void *)sc); #if 0 - clist_free_cblocks(&sc->gkb_q); + clist_free_cblocks(&sc->gkb_q); #endif + } splx(s); - return 0; } -int -genkbdread(genkbd_softc_t *sc, keyboard_t *kbd, struct uio *uio, int flag) +static int +genkbdread(dev_t dev, struct uio *uio, int flag) { + keyboard_t *kbd; + genkbd_softc_t *sc; u_char buffer[KB_BUFSIZE]; int len; int error; @@ -656,17 +531,24 @@ genkbdread(genkbd_softc_t *sc, keyboard_t *kbd, struct uio *uio, int flag) /* wait for input */ s = spltty(); + sc = dev->si_drv1; + kbd = kbd_get_keyboard(KBD_INDEX(dev)); + if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { + splx(s); + return ENXIO; + } while (sc->gkb_q.c_cc == 0) { - if (!KBD_IS_VALID(kbd)) { - splx(s); - return EIO; - } if (flag & IO_NDELAY) { splx(s); return EWOULDBLOCK; } sc->gkb_flags |= KB_ASLEEP; error = tsleep((caddr_t)sc, PZERO | PCATCH, "kbdrea", 0); + kbd = kbd_get_keyboard(KBD_INDEX(dev)); + if ((kbd == NULL) || !KBD_IS_VALID(kbd)) { + splx(s); + return ENXIO; /* our keyboard has gone... */ + } if (error) { sc->gkb_flags &= ~KB_ASLEEP; splx(s); @@ -690,23 +572,25 @@ genkbdread(genkbd_softc_t *sc, keyboard_t *kbd, struct uio *uio, int flag) return error; } -int -genkbdwrite(genkbd_softc_t *sc, keyboard_t *kbd, struct uio *uio, int flag) +static int +genkbdwrite(dev_t dev, struct uio *uio, int flag) { - if (!KBD_IS_VALID(kbd)) + keyboard_t *kbd; + + kbd = kbd_get_keyboard(KBD_INDEX(dev)); + if ((kbd == NULL) || !KBD_IS_VALID(kbd)) return ENXIO; return ENODEV; } -int -genkbdioctl(genkbd_softc_t *sc, keyboard_t *kbd, u_long cmd, caddr_t arg, - int flag, struct proc *p) +static int +genkbdioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p) { + keyboard_t *kbd; int error; - if (kbd == NULL) /* XXX */ - return ENXIO; - if (!KBD_IS_VALID(kbd)) + kbd = kbd_get_keyboard(KBD_INDEX(dev)); + if ((kbd == NULL) || !KBD_IS_VALID(kbd)) return ENXIO; error = (*kbdsw[kbd->kb_index]->ioctl)(kbd, cmd, arg); if (error == ENOIOCTL) @@ -714,17 +598,23 @@ genkbdioctl(genkbd_softc_t *sc, keyboard_t *kbd, u_long cmd, caddr_t arg, return error; } -int -genkbdpoll(genkbd_softc_t *sc, keyboard_t *kbd, int events, struct proc *p) +static int +genkbdpoll(dev_t dev, int events, struct proc *p) { + keyboard_t *kbd; + genkbd_softc_t *sc; int revents; int s; revents = 0; s = spltty(); - if (events & (POLLIN | POLLRDNORM)) { - if ((sc->gkb_q.c_cc > 0) || !KBD_IS_VALID(kbd)) - revents |= (POLLIN | POLLRDNORM); + sc = dev->si_drv1; + kbd = kbd_get_keyboard(KBD_INDEX(dev)); + if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { + revents = POLLHUP; /* the keyboard has gone */ + } else if (events & (POLLIN | POLLRDNORM)) { + if (sc->gkb_q.c_cc > 0) + revents = events & (POLLIN | POLLRDNORM); else selrecord(p, &sc->gkb_rsel); } @@ -750,6 +640,11 @@ genkbd_event(keyboard_t *kbd, int event, void *arg) case KBDIO_UNLOADING: /* the keyboard is going... */ kbd_release(kbd, (void *)sc); + if (sc->gkb_flags & KB_ASLEEP) { + sc->gkb_flags &= ~KB_ASLEEP; + wakeup((caddr_t)sc); + } + selwakeup(&sc->gkb_rsel); return 0; default: return EINVAL; |