Source-Changes-HG archive

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

[src/trunk]: src/sys/rump/dev/lib/libugenhc Change match to be based on the e...



details:   https://anonhg.NetBSD.org/src/rev/2502f176d452
branches:  trunk
changeset: 752191:2502f176d452
user:      pooka <pooka%NetBSD.org@localhost>
date:      Thu Feb 18 15:25:13 2010 +0000

description:
Change match to be based on the existence of the ugen device node
and signal the root hub interrupt only once we are succesfully able
to open the device node.  This makes it possible to insert a device
after the rump kernel was booted and have it succesfully attach
(does not make detach possible yet, though, as there are some
ugen and host kernel uhci/ohci/ehci evil crashies with that).

XXX: optimally, match would fail if there is a permanent error in
opening.  However, it is difficult to figure out the difference
between the device backing ugen not being present, a transient
error in opening and a permanent error in opening.  For example,
which of the latter two would EPERM be?  And, ugen returns ENXIO
if the device is not present, but how would be know that's really
the case and not some other ENXIO from elsewhere in the stack?

diffstat:

 sys/rump/dev/lib/libugenhc/ugenhc.c |  91 ++++++++++++++++++------------------
 1 files changed, 45 insertions(+), 46 deletions(-)

diffs (168 lines):

diff -r ca5ee4bbe5f2 -r 2502f176d452 sys/rump/dev/lib/libugenhc/ugenhc.c
--- a/sys/rump/dev/lib/libugenhc/ugenhc.c       Thu Feb 18 14:57:01 2010 +0000
+++ b/sys/rump/dev/lib/libugenhc/ugenhc.c       Thu Feb 18 15:25:13 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ugenhc.c,v 1.2 2010/02/17 20:39:53 pooka Exp $ */
+/*     $NetBSD: ugenhc.c,v 1.3 2010/02/18 15:25:13 pooka Exp $ */
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.2 2010/02/17 20:39:53 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.3 2010/02/18 15:25:13 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -98,6 +98,9 @@
        int sc_port_change;
        int sc_addr;
        int sc_conf;
+
+       struct lwp *sc_rhintr;
+       usbd_xfer_handle sc_intrxfer;
 };
 
 static int     ugenhc_probe(struct device *, struct cfdata *, void *);
@@ -382,8 +385,10 @@
                        totlen = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
                        memset(buf, 0, totlen);
                        if (rumpuser_ioctl(sc->sc_ugenfd[UGEN_EPT_CTRL],
-                           USB_GET_DEVICE_DESC, &uddesc, &ru_error) == -1)
-                               panic("%d", ru_error);
+                           USB_GET_DEVICE_DESC, &uddesc, &ru_error) == -1) {
+                               err = EIO;
+                               goto ret;
+                       }
                        memcpy(buf, &uddesc, totlen);
                        }
 
@@ -570,39 +575,49 @@
        .done =         rumpusb_device_ctrl_done,
 };
 
-struct intrent {
-       usbd_xfer_handle xfer;
-       LIST_ENTRY(intrent) entries;
-};
-
-static LIST_HEAD(, intrent) intrlist = LIST_HEAD_INITIALIZER(intrlist);
-
 static void
-rhscintr(void)
+rhscintr(void *arg)
 {
-       struct intrent *ie, *ie_next;
+       char buf[UGENDEV_BUFSIZE];
+       struct ugenhc_softc *sc = arg;
        usbd_xfer_handle xfer;
+       int fd, error;
 
-       for (ie = LIST_FIRST(&intrlist); ie; ie = ie_next) {
-               xfer = ie->xfer;
-               xfer->actlen = xfer->length;
-               xfer->status = USBD_NORMAL_COMPLETION;
-               usb_transfer_complete(xfer);
+       makeugendevstr(sc->sc_devnum, 0, buf);
+       for (;;) {
+               fd = rumpuser_open(buf, O_RDWR, &error);
+               if (fd != -1)
+                       break;
+               kpause("ugwait", false, hz/4, NULL);
+       }
+
+       sc->sc_ugenfd[UGEN_EPT_CTRL] = fd;
 
-               ie_next = LIST_NEXT(ie, entries);
-               LIST_REMOVE(ie, entries);
-               kmem_free(ie, sizeof(*ie));
-       }
+       sc->sc_port_status = UPS_CURRENT_CONNECT_STATUS
+           | UPS_PORT_ENABLED | UPS_PORT_POWER;
+       sc->sc_port_change = UPS_C_CONNECT_STATUS;
+
+       xfer = sc->sc_intrxfer;;
+       xfer->actlen = 0;
+       xfer->status = USBD_NORMAL_COMPLETION;
+       usb_transfer_complete(xfer);
+
+       kthread_exit(0);
 }
 
 static usbd_status
 rumpusb_root_intr_start(usbd_xfer_handle xfer)
 {
-       struct intrent *ie;
+       struct ugenhc_softc *sc = xfer->pipe->device->bus->hci_private;
+       int error;
 
-       ie = kmem_alloc(sizeof(*ie), KM_SLEEP);
-       ie->xfer = xfer;
-       LIST_INSERT_HEAD(&intrlist, ie, entries);
+       sc->sc_intrxfer = xfer;
+       if (!sc->sc_rhintr) {
+               error = kthread_create(PRI_NONE, 0, NULL,
+                   rhscintr, sc, &sc->sc_rhintr, "ugenrhi");
+               if (error)
+                       xfer->status = error;
+       }
 
        return (USBD_IN_PROGRESS);
 }
@@ -831,10 +846,6 @@
        int endpt, oflags, error;
        int fd, val;
 
-       sc->sc_port_status = UPS_CURRENT_CONNECT_STATUS
-           | UPS_PORT_ENABLED | UPS_PORT_POWER;
-       sc->sc_port_change = UPS_C_CONNECT_STATUS;
-
        if (addr == sc->sc_addr) {
                switch (xfertype) {
                case UE_CONTROL:
@@ -955,14 +966,14 @@
 ugenhc_probe(struct device *parent, struct cfdata *match, void *aux)
 {
        char buf[UGENDEV_BUFSIZE];
-       int fd, error;
+       int error;
 
        makeugendevstr(match->cf_unit, 0, buf);
-       fd = rumpuser_open(buf, O_RDWR, &error);
-       if (fd == -1)
+       if (rumpuser_getfileinfo(buf, NULL, NULL, &error) == -1) {
+               printf("match error %d\n", error);
                return 0;
+       }
 
-       rumpuser_close(fd, &error);
        return 1;
 }
 
@@ -971,8 +982,6 @@
 {
        struct mainbus_attach_args *maa = aux;
        struct ugenhc_softc *sc = device_private(self);
-       char buf[UGENDEV_BUFSIZE];
-       int error;
 
        aprint_normal("\n");
 
@@ -986,15 +995,5 @@
        sc->sc_bus.pipe_size = sizeof(struct ugenhc_pipe);
        sc->sc_devnum = maa->maa_unit;
 
-       makeugendevstr(sc->sc_devnum, 0, buf);
-       sc->sc_ugenfd[UGEN_EPT_CTRL] = rumpuser_open(buf, O_RDWR, &error);
-       if (error)
-               panic("ugenhc_attach: failed to open ctrl ept %s\n", buf);
-
        config_found(self, &sc->sc_bus, usbctlprint);
-
-       /* whoah, like extreme XXX, bro */
-       rhscintr();
-       if (!rump_threads)
-               config_pending_decr();
 }



Home | Main Index | Thread Index | Old Index