From 33d45f3f995e6e60aa55266a84b641abfbade498 Mon Sep 17 00:00:00 2001 From: Markus Pfeiffer Date: Thu, 2 Aug 2012 18:00:21 +0000 Subject: [PATCH] usb: fix ukbd --- sys/bus/usb/input/ukbd.c | 36 +++++++++++++++++++++++++++------- sys/bus/usb/usb_dev.c | 42 ++++++++++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/sys/bus/usb/input/ukbd.c b/sys/bus/usb/input/ukbd.c index 592ffead7f..90fe97aa28 100644 --- a/sys/bus/usb/input/ukbd.c +++ b/sys/bus/usb/input/ukbd.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -240,8 +241,8 @@ struct ukbd_softc { SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT) #define SCAN_CHAR(c) ((c) & 0x7f) -#define UKBD_LOCK() -#define UKBD_UNLOCK() +#define UKBD_LOCK(sc) lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE) +#define UKBD_UNLOCK(sc) lockmgr(&(sc)->sc_lock, LK_RELEASE) #ifdef INVARIANTS @@ -457,10 +458,10 @@ ukbd_get_key(struct ukbd_softc *sc, uint8_t wait) int32_t c; UKBD_CTX_LOCK_ASSERT(); - KASSERT( +/* KASSERT( (sc->sc_flags & UKBD_FLAG_POLLING) != 0, ("not polling in kdb or panic\n")); - +*/ if (sc->sc_inputs == 0) { /* start transfer, if not already started */ usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]); @@ -588,6 +589,9 @@ ukbd_event_keyinput(struct ukbd_softc *sc) if (sc->sc_inputs == 0) return; + kprintf("keyinput %x %x\n", KBD_IS_ACTIVE(&sc->sc_kbd), + KBD_IS_BUSY(&sc->sc_kbd)); + if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { /* let the callback function process the input */ @@ -1269,8 +1273,9 @@ ukbd_attach(device_t dev) } /* start the keyboard */ + UKBD_LOCK(sc); usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]); - + UKBD_UNLOCK(sc); return (0); /* success */ detach: @@ -1388,7 +1393,11 @@ ukbd_lock(keyboard_t *kbd, int lock) static int ukbd_enable(keyboard_t *kbd) { + struct ukbd_softc *sc = kbd->kb_data; + + UKBD_LOCK(sc); KBD_ACTIVATE(kbd); + UKBD_UNLOCK(sc); return (0); } @@ -1397,7 +1406,11 @@ ukbd_enable(keyboard_t *kbd) static int ukbd_disable(keyboard_t *kbd) { + struct ukbd_softc *sc = kbd->kb_data; + + UKBD_LOCK(sc); KBD_DEACTIVATE(kbd); + UKBD_UNLOCK(sc); return (0); } @@ -1446,8 +1459,11 @@ static int ukbd_check_char(keyboard_t *kbd) { int result; + struct ukbd_softc *sc = kbd->kb_data; + /*UKBD_LOCK(sc); */ result = ukbd_check_char_locked(kbd); + /*UKBD_UNLOCK(sc);*/ return (result); } @@ -1694,10 +1710,11 @@ static uint32_t ukbd_read_char(keyboard_t *kbd, int wait) { uint32_t keycode; + struct ukbd_softc *sc = kbd->kb_data; - UKBD_LOCK(); + /*UKBD_LOCK(sc);*/ keycode = ukbd_read_char_locked(kbd, wait); - UKBD_UNLOCK(); + /*UKBD_UNLOCK(sc);*/ return (keycode); } @@ -1843,6 +1860,7 @@ static int ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) { int result; + struct ukbd_softc *sc = kbd->kb_data; /* * XXX KDGKBSTATE, KDSKBSTATE and KDSETLED can be called from any @@ -1861,7 +1879,9 @@ ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) return (EDEADLK); /* best I could come up with */ /* FALLTHROUGH */ default: + UKBD_LOCK(sc); result = ukbd_ioctl_locked(kbd, cmd, arg); + UKBD_UNLOCK(sc); return (result); } } @@ -1906,6 +1926,7 @@ ukbd_poll(keyboard_t *kbd, int on) { struct ukbd_softc *sc = kbd->kb_data; + UKBD_LOCK(sc); if (on) { sc->sc_flags |= UKBD_FLAG_POLLING; sc->sc_poll_thread = curthread; @@ -1913,6 +1934,7 @@ ukbd_poll(keyboard_t *kbd, int on) sc->sc_flags &= ~UKBD_FLAG_POLLING; ukbd_start_timer(sc); /* start timer */ } + UKBD_UNLOCK(sc); return (0); } diff --git a/sys/bus/usb/usb_dev.c b/sys/bus/usb/usb_dev.c index dcfc68d801..c082ba4c78 100644 --- a/sys/bus/usb/usb_dev.c +++ b/sys/bus/usb/usb_dev.c @@ -155,6 +155,9 @@ static struct lock usb_sym_lock; struct lock usb_ref_lock; +static int usb_nevents = 0; +static struct kqinfo usb_kqevent; + /*------------------------------------------------------------------------* * usb_loc_fill * @@ -504,7 +507,7 @@ usb_fifo_create(struct usb_cdev_privdata *cpd, f->methods = &usb_ugen_methods; f->iface_index = ep->iface_index; f->udev = udev; - lockmgr(&usb_ref_lock, LK_EXCLUSIVE); + lockmgr(&usb_ref_lock, LK_EXCLUSIVE); udev->fifo[n + USB_FIFO_TX] = f; lockmgr(&usb_ref_lock, LK_RELEASE); } @@ -583,20 +586,20 @@ usb_fifo_free(struct usb_fifo *f) f->flag_iserror = 1; /* need to wait until all callers have exited */ while (f->refcount != 0) { - lockmgr(&usb_ref_lock, LK_RELEASE); /* avoid LOR */ - lockmgr(f->priv_lock, LK_EXCLUSIVE); + lockmgr(&usb_ref_lock, LK_RELEASE); /* avoid LOR */ + lockmgr(f->priv_lock, LK_EXCLUSIVE); /* get I/O thread out of any sleep state */ if (f->flag_sleeping) { f->flag_sleeping = 0; cv_broadcast(&f->cv_io); } - lockmgr(f->priv_lock, LK_RELEASE); - lockmgr(&usb_ref_lock, LK_EXCLUSIVE); + lockmgr(f->priv_lock, LK_RELEASE); + lockmgr(&usb_ref_lock, LK_EXCLUSIVE); /* wait for sync */ cv_wait(&f->cv_drain, &usb_ref_lock); } - lockmgr(&usb_ref_lock, LK_RELEASE); + lockmgr(&usb_ref_lock, LK_RELEASE); /* take care of closing the device here, if any */ usb_fifo_close(f, 0); @@ -1138,9 +1141,12 @@ done: return (err); } -static struct filterops usb_filtops = +static struct filterops usb_filtops_read = { FILTEROP_ISFD, NULL, usb_filter_detach, usb_filter_read }; +static struct filterops usb_filtops_write = + { FILTEROP_ISFD, NULL, usb_filter_detach, usb_filter_write }; + static int usb_kqfilter(struct dev_kqfilter_args *ap) { @@ -1151,7 +1157,11 @@ usb_kqfilter(struct dev_kqfilter_args *ap) switch(kn->kn_filter) { case EVFILT_READ: - kn->kn_fop = &usb_filtops; + kn->kn_fop = &usb_filtops_read; + kn->kn_hook = (caddr_t)dev; + break; + case EVFILT_WRITE: + kn->kn_fop = &usb_filtops_write; kn->kn_hook = (caddr_t)dev; break; default: @@ -1159,19 +1169,19 @@ usb_kqfilter(struct dev_kqfilter_args *ap) return(0); } -/* klist = &usb_kqevent.ki_note; + klist = &usb_kqevent.ki_note; knote_insert(klist, kn); -*/ + return(0); } static void usb_filter_detach(struct knote *kn) { - /* struct klist *klist; + struct klist *klist; klist = &usb_kqevent.ki_note; - knote_remove(klist, kn);*/ + knote_remove(klist, kn); } static int @@ -1188,6 +1198,14 @@ usb_filter_read(struct knote *kn, long hint) return(0); } +static int +usb_filter_write(struct knote *kn, long hint) +{ + + return(0); +} + + /* XXX implement using kqfilter */ #if XXXDF /* ARGSUSED */ -- 2.41.0