Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/jmcneill-usbmp]: src/sys/dev/usb convert usb event code to using a mutex...
details: https://anonhg.NetBSD.org/src/rev/c5bec3fc5601
branches: jmcneill-usbmp
changeset: 771796:c5bec3fc5601
user: mrg <mrg%NetBSD.org@localhost>
date: Mon Feb 20 03:27:07 2012 +0000
description:
convert usb event code to using a mutex and condvar.
diffstat:
sys/dev/usb/usb.c | 71 ++++++++++++++++++++++++++++++------------------------
1 files changed, 40 insertions(+), 31 deletions(-)
diffs (243 lines):
diff -r 85ed87585898 -r c5bec3fc5601 sys/dev/usb/usb.c
--- a/sys/dev/usb/usb.c Mon Feb 20 03:25:33 2012 +0000
+++ b/sys/dev/usb/usb.c Mon Feb 20 03:27:07 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: usb.c,v 1.125.6.6 2012/02/20 02:12:24 mrg Exp $ */
+/* $NetBSD: usb.c,v 1.125.6.7 2012/02/20 03:27:07 mrg Exp $ */
/*
* Copyright (c) 1998, 2002, 2008 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.6 2012/02/20 02:12:24 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.7 2012/02/20 03:27:07 mrg Exp $");
#include "opt_compat_netbsd.h"
#include "opt_usb.h"
@@ -57,19 +57,19 @@
#include <sys/signalvar.h>
#include <sys/intr.h>
#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+#include <sys/once.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_verbose.h>
+#include <dev/usb/usb_quirks.h>
#define USB_DEV_MINOR 255
-#include <sys/bus.h>
-
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_quirks.h>
-
#ifdef USB_DEBUG
#define DPRINTF(x) if (usbdebug) printf x
#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
@@ -135,6 +135,8 @@
SIMPLEQ_HEAD_INITIALIZER(usb_events);
Static int usb_nevents = 0;
Static struct selinfo usb_selevent;
+Static kmutex_t usb_event_lock;
+Static kcondvar_t usb_event_cv;
Static proc_t *usb_async_proc; /* process that wants USB SIGIO */
Static void *usb_async_sih;
Static int usb_dev_open = 0;
@@ -156,6 +158,7 @@
static int usb_detach(device_t, int);
static int usb_activate(device_t, enum devact);
static void usb_childdet(device_t, device_t);
+static int usb_once_init(void);
static void usb_doattach(device_t);
extern struct cfdriver usb_cd;
@@ -174,6 +177,7 @@
void
usb_attach(device_t parent, device_t self, void *aux)
{
+ static ONCE_DECL(init_control);
struct usb_softc *sc = device_private(self);
int usbrev;
@@ -194,13 +198,23 @@
}
aprint_normal("\n");
+ RUN_ONCE(&init_control, usb_once_init);
config_interrupts(self, usb_doattach);
}
+static int
+usb_once_init(void)
+{
+
+ selinit(&usb_selevent);
+ mutex_init(&usb_event_lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&usb_event_cv, "usbrea");
+ return 0;
+}
+
static void
usb_doattach(device_t self)
{
- static bool usb_selevent_init; /* XXX */
struct usb_softc *sc = device_private(self);
usbd_device_handle dev;
usbd_status err;
@@ -208,10 +222,6 @@
struct usb_event *ue;
bool mpsafe = sc->sc_bus->methods->get_locks ? true : false;
- if (!usb_selevent_init) {
- selinit(&usb_selevent);
- usb_selevent_init = true;
- }
DPRINTF(("usbd_doattach\n"));
sc->sc_bus->usbctl = self;
@@ -485,7 +495,7 @@
#ifdef COMPAT_30
struct usb_event_old *ueo = NULL; /* XXXGCC */
#endif
- int s, error, n, useold;
+ int error, n, useold;
if (minor(dev) != USB_DEV_MINOR)
return (ENXIO);
@@ -507,7 +517,7 @@
}
error = 0;
- s = splusb();
+ mutex_enter(&usb_event_lock);
for (;;) {
n = usb_get_next_event(ue);
if (n != 0)
@@ -516,11 +526,11 @@
error = EWOULDBLOCK;
break;
}
- error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
+ error = cv_wait_sig(&usb_event_cv, &usb_event_lock);
if (error)
break;
}
- splx(s);
+ mutex_exit(&usb_event_lock);
if (!error) {
#ifdef COMPAT_30
if (useold) { /* copy fields to old struct */
@@ -721,18 +731,18 @@
int
usbpoll(dev_t dev, int events, struct lwp *l)
{
- int revents, mask, s;
+ int revents, mask;
if (minor(dev) == USB_DEV_MINOR) {
revents = 0;
mask = POLLIN | POLLRDNORM;
- s = splusb();
+ mutex_enter(&usb_event_lock);
if (events & mask && usb_nevents > 0)
revents |= events & mask;
if (revents == 0 && events & mask)
selrecord(l, &usb_selevent);
- splx(s);
+ mutex_exit(&usb_event_lock);
return (revents);
} else {
@@ -743,11 +753,10 @@
static void
filt_usbrdetach(struct knote *kn)
{
- int s;
- s = splusb();
+ mutex_enter(&usb_event_lock);
SLIST_REMOVE(&usb_selevent.sel_klist, kn, knote, kn_selnext);
- splx(s);
+ mutex_exit(&usb_event_lock);
}
static int
@@ -768,7 +777,6 @@
usbkqfilter(dev_t dev, struct knote *kn)
{
struct klist *klist;
- int s;
switch (kn->kn_filter) {
case EVFILT_READ:
@@ -784,9 +792,9 @@
kn->kn_hook = NULL;
- s = splusb();
+ mutex_enter(&usb_event_lock);
SLIST_INSERT_HEAD(klist, kn, kn_selnext);
- splx(s);
+ mutex_exit(&usb_event_lock);
return (0);
}
@@ -847,12 +855,14 @@
wakeup(&dev->bus->needs_explore);
}
-/* Called at splusb() */
+/* Called at with usb_event_lock held. */
int
usb_get_next_event(struct usb_event *ue)
{
struct usb_event_q *ueq;
+ KASSERT(mutex_owned(&usb_event_lock));
+
if (usb_nevents <= 0)
return (0);
ueq = SIMPLEQ_FIRST(&usb_events);
@@ -909,30 +919,29 @@
{
struct usb_event_q *ueq;
struct timeval thetime;
- int s;
microtime(&thetime);
- /* Don't want to wait here inside splusb() */
+ /* Don't want to wait here with usb_event_lock held */
ueq = (struct usb_event_q *)(void *)uep;
ueq->ue = *uep;
ueq->ue.ue_type = type;
TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
- s = splusb();
+ mutex_enter(&usb_event_lock);
if (++usb_nevents >= USB_MAX_EVENTS) {
/* Too many queued events, drop an old one. */
DPRINTFN(-1,("usb: event dropped\n"));
(void)usb_get_next_event(0);
}
SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next);
- wakeup(&usb_events);
+ cv_signal(&usb_event_cv);
selnotify(&usb_selevent, 0, 0);
if (usb_async_proc != NULL) {
kpreempt_disable();
softint_schedule(usb_async_sih);
kpreempt_enable();
}
- splx(s);
+ mutex_exit(&usb_event_lock);
}
Static void
Home |
Main Index |
Thread Index |
Old Index