From eb7e634f979cb8238a8140b9272a5a42876d3a14 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 28 Apr 2005 15:03:48 +0000 Subject: [PATCH] Finish support for wskbd @ kbd @ zs/sab for sparc64 consoles. Based on work from John Heasley and Michael Lorenz. --- sys/dev/sun/kbd.c | 110 ++++++++++++++++++++++++++++++------------- sys/dev/sun/kbd_zs.c | 10 +++- sys/dev/sun/kbdsun.c | 19 ++++---- sys/dev/sun/kbdvar.h | 3 +- 4 files changed, 98 insertions(+), 44 deletions(-) diff --git a/sys/dev/sun/kbd.c b/sys/dev/sun/kbd.c index e2996ce5d8d9..d8a67d165ca7 100644 --- a/sys/dev/sun/kbd.c +++ b/sys/dev/sun/kbd.c @@ -1,4 +1,4 @@ -/* $NetBSD: kbd.c,v 1.43 2005/02/27 00:27:49 perry Exp $ */ +/* $NetBSD: kbd.c,v 1.44 2005/04/28 15:03:48 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -47,7 +47,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.43 2005/02/27 00:27:49 perry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.44 2005/04/28 15:03:48 martin Exp $"); #include #include @@ -99,6 +99,7 @@ void sunkbd_wskbd_cngetc(void *, u_int *, int *); void sunkbd_wskbd_cnpollc(void *, int); void sunkbd_wskbd_cnbell(void *, u_int, u_int, u_int); static void sunkbd_bell_off(void *v); +void kbd_enable(struct device *); /* deferred keyboard initialization */ const struct wskbd_accessops sunkbd_wskbd_accessops = { wssunkbd_enable, @@ -188,6 +189,8 @@ kbdopen(dev, flags, mode, p) * events input, so we should probably just let the open to * always succeed regardless (e.g. Xsun opening /dev/kbd). */ + if (!k->k_wsenabled) + wssunkbd_enable(k, 1); /* exclusive open required for /dev/kbd */ if (k->k_events.ev_io) @@ -364,6 +367,7 @@ kbdioctl(dev, cmd, data, flag, p) break; default: + printf("kbd: returning ENOTTY\n"); error = ENOTTY; break; } @@ -683,7 +687,6 @@ kbd_input_keysym(k, keysym) { struct kbd_state *ks = &k->k_state; int data; - /* Check if a recipient has been configured */ if (k->k_cc == NULL || k->k_cc->cc_upstream == NULL) return (0); @@ -956,20 +959,20 @@ wssunkbd_enable(v, on) int on; { struct kbd_softc *k = v; - - k->k_wsenabled = on; - if (on) { - /* open actual underlying device */ - if (k->k_ops != NULL && k->k_ops->open != NULL) - (*k->k_ops->open)(k); - ev_init(&k->k_events); - k->k_evmode = 0; /* XXX: OK? */ - } else { - /* close underlying device */ - if (k->k_ops != NULL && k->k_ops->close != NULL) - (*k->k_ops->close)(k); + if (k->k_wsenabled != on) { + k->k_wsenabled = on; + if (on) { + /* open actual underlying device */ + if (k->k_ops != NULL && k->k_ops->open != NULL) + (*k->k_ops->open)(k); + ev_init(&k->k_events); + k->k_evmode = 0; /* XXX: OK? */ + } else { + /* close underlying device */ + if (k->k_ops != NULL && k->k_ops->close != NULL) + (*k->k_ops->close)(k); + } } - return 0; } @@ -991,6 +994,7 @@ wssunkbd_set_leds(v, leds) l |= LED_COMPOSE; if (k->k_ops != NULL && k->k_ops->setleds != NULL) (*k->k_ops->setleds)(k, l, 0); + k->k_leds=l; } int @@ -1001,9 +1005,31 @@ wssunkbd_ioctl(v, cmd, data, flag, p) int flag; struct proc *p; { + struct kbd_softc *k = v; + + switch (cmd) { + case WSKBDIO_GTYPE: + *(int *)data = WSKBD_TYPE_SUN5; + return (0); + case WSKBDIO_SETLEDS: + wssunkbd_set_leds(v, *(int *)data); + return (0); + case WSKBDIO_GETLEDS: + *(int *)data = k->k_leds; + return (0); +#ifdef WSDISPLAY_COMPAT_RAWKBD___ + case WSKBDIO_SETMODE: + DPRINTF(("wssunkbd_ioctl: set raw = %d\n", *(int *)data)); + sc->sc_rawkbd = *(int *)data == WSKBD_RAW; + usb_uncallout(sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc); + return (0); +#endif + } return EPASSTHROUGH; } +extern int prom_cngetc(dev_t); + void sunkbd_wskbd_cngetc(v, type, data) void *v; @@ -1011,6 +1037,8 @@ sunkbd_wskbd_cngetc(v, type, data) int *data; { /* struct kbd_sun_softc *k = v; */ + *data = prom_cngetc(0); + *type = WSCONS_EVENT_ASCII; } void @@ -1039,26 +1067,44 @@ sunkbd_wskbd_cnbell(v, pitch, period, volume) k->k_ops->docmd(k, KBD_CMD_BELL, 0); } +void +kbd_enable(dev) + struct device *dev; +{ + struct kbd_softc *k=(struct kbd_softc *)dev; + struct wskbddev_attach_args a; + + if (k->k_isconsole) + wskbd_cnattach(&sunkbd_wskbd_consops, k, + &sunkbd_wskbd_keymapdata); + + a.console = k->k_isconsole; + a.keymap = &sunkbd_wskbd_keymapdata; + a.accessops = &sunkbd_wskbd_accessops; + a.accesscookie = k; + + /* XXX why? */ + k->k_wsenabled = 0; + + /* Attach the wskbd */ + k->k_wskbd = config_found(&k->k_dev, &a, wskbddevprint); + + callout_init(&k->k_wsbell); + + wssunkbd_enable(k,1); + + wssunkbd_set_leds(k, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS); + delay(100000); + wssunkbd_set_leds(k, 0); +} + void kbd_wskbd_attach(k, isconsole) struct kbd_softc *k; int isconsole; { - struct wskbddev_attach_args a; - - a.console = isconsole; - - if (a.console) - wskbd_cnattach(&sunkbd_wskbd_consops, k, &sunkbd_wskbd_keymapdata); - - a.keymap = &sunkbd_wskbd_keymapdata; - - a.accessops = &sunkbd_wskbd_accessops; - a.accesscookie = k; - - /* Attach the wskbd */ - k->k_wskbd = config_found(&k->k_dev, &a, wskbddevprint); - k->k_wsenabled = 0; - callout_init(&k->k_wsbell); + k->k_isconsole=isconsole; + + config_interrupts(&k->k_dev,kbd_enable); } #endif diff --git a/sys/dev/sun/kbd_zs.c b/sys/dev/sun/kbd_zs.c index 8276714acb5e..93038cef91a6 100644 --- a/sys/dev/sun/kbd_zs.c +++ b/sys/dev/sun/kbd_zs.c @@ -1,4 +1,4 @@ -/* $NetBSD: kbd_zs.c,v 1.18 2005/02/27 00:27:49 perry Exp $ */ +/* $NetBSD: kbd_zs.c,v 1.19 2005/04/28 15:03:48 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -53,7 +53,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.18 2005/02/27 00:27:49 perry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.19 2005/04/28 15:03:48 martin Exp $"); #include #include @@ -77,6 +77,9 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.18 2005/02/27 00:27:49 perry Exp $"); #include #include +#if NWSKBD > 0 +void kbd_wskbd_attach(struct kbd_softc *k, int isconsole); +#endif /**************************************************************** * Interface to the lower layer (zscc) @@ -188,6 +191,9 @@ kbd_zs_attach(parent, self, aux) /* Magic sequence. */ k->k_magic1 = KBD_L1; k->k_magic2 = KBD_A; +#if NWSKBD > 0 + kbd_wskbd_attach(&k->k_kbd, k->k_kbd.k_isconsole); +#endif } /* diff --git a/sys/dev/sun/kbdsun.c b/sys/dev/sun/kbdsun.c index e173d02f4c63..2132b98bb71c 100644 --- a/sys/dev/sun/kbdsun.c +++ b/sys/dev/sun/kbdsun.c @@ -1,4 +1,4 @@ -/* $NetBSD: kbdsun.c,v 1.6 2005/02/21 03:46:38 heas Exp $ */ +/* $NetBSD: kbdsun.c,v 1.7 2005/04/28 15:03:48 martin Exp $ */ /* NetBSD: kbd.c,v 1.29 2001/11/13 06:54:32 lukem Exp */ /* @@ -47,7 +47,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.6 2005/02/21 03:46:38 heas Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.7 2005/04/28 15:03:48 martin Exp $"); #include #include @@ -135,12 +135,11 @@ kbd_sun_open(kbd) kbd_sun_drain_tx(k); /* the wakeup for this is in kbd_sun_was_reset(). */ - for (ntries = 200; ntries; ntries--) { + for (ntries = 30; ntries; ntries--) { error = tsleep((caddr_t)&ks->kbd_id, PZERO | PCATCH, devopn, - hz); + hz/10); if (ks->kbd_id) break; - DELAY(10000); } if (error == EWOULDBLOCK || ks->kbd_id == 0) { /* no response */ @@ -348,14 +347,16 @@ static int kbd_sun_drain_tx(k) struct kbd_sun_softc *k; { - int error = 0; + int error = 0, bail = 0; - while (k->k_txflags & K_TXBUSY && !error) { + while ((k->k_txflags & K_TXBUSY) && (!error) && (bail<1000)) { k->k_txflags |= K_TXWANT; error = tsleep((caddr_t)&k->k_txflags, - PZERO | PCATCH, "kbdout", 0); + PZERO | PCATCH, "kbdout", 1); + bail++; } - + if (bail==1000) + error=EIO; return (error); } diff --git a/sys/dev/sun/kbdvar.h b/sys/dev/sun/kbdvar.h index 849bf7df7e51..b2109e728ce7 100644 --- a/sys/dev/sun/kbdvar.h +++ b/sys/dev/sun/kbdvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: kbdvar.h,v 1.14 2005/02/20 20:32:45 heas Exp $ */ +/* $NetBSD: kbdvar.h,v 1.15 2005/04/28 15:03:49 martin Exp $ */ /* * Copyright (c) 1992, 1993 @@ -73,6 +73,7 @@ struct kbd_softc { int k_repeatsym; /* repeating symbol */ int k_repeating; /* callout is active (use callout_active?) */ struct callout k_repeat_ch; + int k_leds; };