Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Create a special kernel thread to run the usb sh...



details:   https://anonhg.NetBSD.org/src/rev/fd9919733a65
branches:  trunk
changeset: 517881:fd9919733a65
user:      augustss <augustss%NetBSD.org@localhost>
date:      Tue Nov 20 23:53:26 2001 +0000

description:
Create a special kernel thread to run the usb short lived tasks (instead
of using the device discovery threads).

diffstat:

 sys/dev/usb/usb.c |  94 +++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 61 insertions(+), 33 deletions(-)

diffs (204 lines):

diff -r 239518ca3536 -r fd9919733a65 sys/dev/usb/usb.c
--- a/sys/dev/usb/usb.c Tue Nov 20 23:09:45 2001 +0000
+++ b/sys/dev/usb/usb.c Tue Nov 20 23:53:26 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb.c,v 1.57 2001/11/20 13:48:04 augustss Exp $        */
+/*     $NetBSD: usb.c,v 1.58 2001/11/20 23:53:26 augustss Exp $        */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.57 2001/11/20 13:48:04 augustss Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.58 2001/11/20 23:53:26 augustss Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -96,19 +96,20 @@
        usbd_bus_handle sc_bus;         /* USB controller */
        struct usbd_port sc_port;       /* dummy port for root hub */
 
-       TAILQ_HEAD(, usb_task) sc_tasks;
        struct proc    *sc_event_thread;
 
-       struct usb_task sc_exp_task;
-
        char            sc_dying;
 };
 
+TAILQ_HEAD(, usb_task) usb_all_tasks;
+
 cdev_decl(usb);
 
 Static void    usb_discover(void *);
 Static void    usb_create_event_thread(void *);
 Static void    usb_event_thread(void *);
+Static void    usb_task_thread(void *);
+Static struct proc *usb_task_thread_proc = NULL;
 
 #define USB_MAX_EVENTS 100
 struct usb_event_q {
@@ -150,9 +151,6 @@
        sc->sc_bus = aux;
        sc->sc_bus->usbctl = sc;
        sc->sc_port.power = USB_MAX_POWER;
-       TAILQ_INIT(&sc->sc_tasks);
-
-       usb_init_task(&sc->sc_exp_task, usb_discover, sc);
 
        usbrev = sc->sc_bus->usbrev;
        printf(": USB revision %s", usbrev_str[usbrev]);
@@ -232,6 +230,7 @@
 usb_create_event_thread(void *arg)
 {
        struct usb_softc *sc = arg;
+       static int created = 0;
 
        if (usb_kthread_create1(usb_event_thread, sc, &sc->sc_event_thread,
                           "%s", sc->sc_dev.dv_xname)) {
@@ -239,6 +238,15 @@
                       sc->sc_dev.dv_xname);
                panic("usb_create_event_thread");
        }
+       if (!created) {
+               created = 1;
+               TAILQ_INIT(&usb_all_tasks);
+               if (usb_kthread_create1(usb_task_thread, NULL,
+                                       &usb_task_thread_proc, "usbtask")) {
+                       printf("unable to create task thread\n");
+                       panic("usb_create_event_thread task");
+               }
+       }
 }
 
 /*
@@ -249,29 +257,27 @@
 void
 usb_add_task(usbd_device_handle dev, struct usb_task *task)
 {
-       struct usb_softc *sc = dev->bus->usbctl;
        int s;
 
        s = splusb();
        if (!task->onqueue) {
-               DPRINTFN(2,("usb_add_task: sc=%p task=%p\n", sc, task));
-               TAILQ_INSERT_TAIL(&sc->sc_tasks, task, next);
+               DPRINTFN(2,("usb_add_task: task=%p\n", task));
+               TAILQ_INSERT_TAIL(&usb_all_tasks, task, next);
                task->onqueue = 1;
        } else
-               DPRINTFN(3,("usb_add_task: sc=%p task=%p on q\n", sc, task));
-       wakeup(&sc->sc_tasks);
+               DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
+       wakeup(&usb_all_tasks);
        splx(s);
 }
 
 void
 usb_rem_task(usbd_device_handle dev, struct usb_task *task)
 {
-       struct usb_softc *sc = dev->bus->usbctl;
        int s;
 
        s = splusb();
        if (task->onqueue) {
-               TAILQ_REMOVE(&sc->sc_tasks, task, next);
+               TAILQ_REMOVE(&usb_all_tasks, task, next);
                task->onqueue = 0;
        }
        splx(s);
@@ -281,8 +287,6 @@
 usb_event_thread(void *arg)
 {
        struct usb_softc *sc = arg;
-       struct usb_task *task;
-       int s;
 
        DPRINTF(("usb_event_thread: start\n"));
 
@@ -292,20 +296,18 @@
        config_pending_decr();
 
        while (!sc->sc_dying) {
-               s = splusb();
-               task = TAILQ_FIRST(&sc->sc_tasks);
-               if (task == NULL) {
-                       tsleep(&sc->sc_tasks, PWAIT, "usbevt", 0);
-                       task = TAILQ_FIRST(&sc->sc_tasks);
-               }
-               DPRINTFN(2,("usb_event_thread: woke up task=%p\n", task));
-               if (task != NULL && !sc->sc_dying) {
-                       TAILQ_REMOVE(&sc->sc_tasks, task, next);
-                       task->onqueue = 0;
-                       splx(s);
-                       task->fun(task->arg);
-               } else
-                       splx(s);
+#ifdef USB_DEBUG
+               if (usb_noexplore < 2)
+#endif
+               usb_discover(sc);
+#ifdef USB_DEBUG
+               (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
+                   usb_noexplore ? 0 : hz * 60);
+#else
+               (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
+                   hz * 60);
+#endif
+               DPRINTFN(2,("usb_event_thread: woke up\n"));
        }
        sc->sc_event_thread = NULL;
 
@@ -316,6 +318,32 @@
        kthread_exit(0);
 }
 
+void
+usb_task_thread(void *arg)
+{
+       struct usb_task *task;
+       int s;
+
+       DPRINTF(("usb_task_thread: start\n"));
+
+       s = splusb();
+       for (;;) {
+               task = TAILQ_FIRST(&usb_all_tasks);
+               if (task == NULL) {
+                       tsleep(&usb_all_tasks, PWAIT, "usbevt", 0);
+                       task = TAILQ_FIRST(&usb_all_tasks);
+               }
+               DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
+               if (task != NULL) {
+                       TAILQ_REMOVE(&usb_all_tasks, task, next);
+                       task->onqueue = 0;
+                       splx(s);
+                       task->fun(task->arg);
+                       s = splusb();
+               }
+       }
+}
+
 int
 usbctlprint(void *aux, const char *pnp)
 {
@@ -565,7 +593,7 @@
 {
        DPRINTFN(2,("usb_needs_explore\n"));
        dev->bus->needs_explore = 1;
-       usb_add_task(dev, &dev->bus->usbctl->sc_exp_task);
+       wakeup(&dev->bus->needs_explore);
 }
 
 /* Called at splusb() */
@@ -692,7 +720,7 @@
 
        /* Kill off event thread. */
        if (sc->sc_event_thread) {
-               wakeup(&sc->sc_tasks);
+               wakeup(&sc->sc_bus->needs_explore);
                if (tsleep(sc, PWAIT, "usbdet", hz * 60))
                        printf("%s: event thread didn't die\n",
                               USBDEVNAME(sc->sc_dev));



Home | Main Index | Thread Index | Old Index