summaryrefslogtreecommitdiff
path: root/sys/dev/hil/hil.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-11-05 14:39:33 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-11-05 14:39:33 +0000
commit4947185b2e79d3035f39094f7759f956ce5230c4 (patch)
tree673ba15be18c04adfefeb1c5d127746bdcf9576b /sys/dev/hil/hil.c
parent7ce00e21ff6fb86cf4936fda8ea32f78f3364f6c (diff)
Handle loop reconfiguration in a kernel thread, instead of doing it from
interrupt context.
Diffstat (limited to 'sys/dev/hil/hil.c')
-rw-r--r--sys/dev/hil/hil.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/sys/dev/hil/hil.c b/sys/dev/hil/hil.c
index f9989d7c44c..16edb15dd05 100644
--- a/sys/dev/hil/hil.c
+++ b/sys/dev/hil/hil.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hil.c,v 1.21 2005/12/22 07:09:52 miod Exp $ */
+/* $OpenBSD: hil.c,v 1.22 2006/11/05 14:39:32 miod Exp $ */
/*
* Copyright (c) 2003, 2004, Miodrag Vallat.
* All rights reserved.
@@ -72,6 +72,7 @@
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
+#include <sys/kthread.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
@@ -98,8 +99,8 @@ void hilconfig(struct hil_softc *, u_int);
void hilempty(struct hil_softc *);
int hilsubmatch(struct device *, void *, void *);
void hil_process_int(struct hil_softc *, u_int8_t, u_int8_t);
-void hil_process_pending(struct hil_softc *);
int hil_process_poll(struct hil_softc *, u_int8_t, u_int8_t);
+void hil_thread(void *);
int send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd);
void polloff(struct hil_softc *);
void pollon(struct hil_softc *);
@@ -107,6 +108,8 @@ void pollon(struct hil_softc *);
static int hilwait(struct hil_softc *);
static int hildatawait(struct hil_softc *);
+#define hil_process_pending(sc) wakeup(&(sc)->sc_pending)
+
static __inline int
hilwait(struct hil_softc *sc)
{
@@ -246,6 +249,16 @@ hil_attach_deferred(void *v)
}
/*
+ * Create asynchronous loop event handler thread.
+ */
+ if (kthread_create(hil_thread, sc, &sc->sc_thread,
+ "%s", sc->sc_dev.dv_xname) != 0) {
+ printf("%s: unable to create event thread\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+
+ /*
* Enable loop interrupts.
*/
send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL);
@@ -420,17 +433,29 @@ hil_process_poll(struct hil_softc *sc, u_int8_t stat, u_int8_t c)
}
void
-hil_process_pending(struct hil_softc *sc)
+hil_thread(void *arg)
{
- switch (sc->sc_pending) {
- case HIL_PENDING_RECONFIG:
- sc->sc_pending = 0;
- hilconfig(sc, sc->sc_maxdev);
- break;
- case HIL_PENDING_UNPLUGGED:
- sc->sc_pending = 0;
- hilempty(sc);
- break;
+ struct hil_softc *sc = arg;
+ int s;
+
+ for (;;) {
+ s = splhil();
+ if (sc->sc_pending == 0) {
+ splx(s);
+ (void)tsleep(&sc->sc_pending, PWAIT, "hil_event", 0);
+ continue;
+ }
+
+ switch (sc->sc_pending) {
+ case HIL_PENDING_RECONFIG:
+ sc->sc_pending = 0;
+ hilconfig(sc, sc->sc_maxdev);
+ break;
+ case HIL_PENDING_UNPLUGGED:
+ sc->sc_pending = 0;
+ hilempty(sc);
+ break;
+ }
}
}