Hackers,

please find attached patch for UHCI that fixes bus hanging
after a device has been unplugged. i can not provide a patch
for OHCI because i do not have hardware to test.

after looking into this in more detail i found a somewhat
similar patch in PR "kern/37928".

also if someone can comment on
http://mail-index.netbsd.org/current-users/2001/04/13/0022.html
regarding to FreeBSD.

another problems i'm having with USB are

1) when i put my laptop into docking station it somewhat hard
   to attach USB device. i'm getting "device problem" errors
   (see attached usb.errors file). however if i try to plug/
   unplug device several times then it works. perhaps something
   is wrong with USB hub in docking station? there is no such
   problem when i connect device directly to the laptop, i.e.
   no docking station.

2) there is bug somewhere which i can reproduce at will with
   my hardware. it seems that USB stack missing one interrupt
   transfer from the device. in only happens when driver re-opens
   USB pipes, i.e.

        1) Device plugged
        2) Driver open USB pipe
        3) Driver sends control request
        4) Device sends interrupt transfer 1
        5) Device sends interrupt transfer 2

        6) Driver closes USB pipe
        7) Driver opens USB pipe
        8) Driver sends control request
        9) ??? no interrupt transfer 1 ???
        10) Device sends interrupt transfer 2

if i re-plug device than everything works again. i can
reproduce it with both my driver and "ugen" driver.

any clues?

thanks,
max

Josef Karthauser wrote:
> 
> On Tue, Aug 27, 2002 at 01:46:25PM -0700, Maksim Yevmenkin wrote:
> > Hackers,
> >
> > Replying to myself and -current. Strange, but commenting out
> >
> > #define USB_USE_SOFTINTR
> >
> > in /sys/dev/usb_ports.h fixed my problem. USB device back to
> > full speed and now i'm getting solid ~60 KBytes/sec.
> >
> > Note: this is _the_only_ change i made. the rest of the
> > code has not been changed.
> >
> > Hmmm.... Anyone care to comment?
> 
> That's interesting and was going to be my suggestion.
> Unfortunately there's a nasty bug in there without that defined, which
> I've not managed to track down yet.  If you come across it please let
> me know privately and we'll try and nail it.  It manifests itself as the
> bus hanging after a device has been unplugged.
> 
> Joe
> --
> "As far as the laws of mathematics refer to reality, they are not certain;
> and as far as they are certain, they do not refer to reality." - Albert
> Einstein, 1921
Aug 30 11:34:22 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:23 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:23 beetle kernel: uhub1: device problem, disabling port 1
Aug 30 11:34:27 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:27 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:27 beetle kernel: uhub1: device problem, disabling port 2
Aug 30 11:34:30 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:30 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:30 beetle kernel: uhub1: device problem, disabling port 2
Aug 30 11:34:33 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:33 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:33 beetle kernel: uhub1: device problem, disabling port 1
Aug 30 11:34:36 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:36 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:36 beetle kernel: uhub1: device problem, disabling port 2
Aug 30 11:34:38 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:38 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:38 beetle kernel: uhub1: device problem, disabling port 1
Aug 30 11:34:41 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:41 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:41 beetle kernel: uhub1: device problem, disabling port 2
Aug 30 11:34:44 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:44 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:44 beetle kernel: uhub1: device problem, disabling port 1
Aug 30 11:34:46 beetle kernel: usbd_new_device: addr=3, getting first desc failed
Aug 30 11:34:46 beetle kernel: uhub_explore: usb_new_device failed, error=IOERROR
Aug 30 11:34:46 beetle kernel: uhub1: device problem, disabling port 1
Aug 30 11:34:49 beetle kernel: ubt0: 3Com product 0x00a0, rev 1.10/1.15, addr 3
Aug 30 11:34:49 beetle kernel: ubt0: Interface 0 endpoints: interrupt=0x81, 
bulk-in=0x82, bulk-out=0x2
Aug 30 11:34:49 beetle kernel: ubt0: Interface 1 (alt.config 5) endpoints: 
isoc-in=0x83, isoc-out=0x3; wMaxPacketSize=49; nframes=6, buffer size=294
--- uhci.c.orig Thu Aug 29 09:30:08 2002
+++ uhci.c      Fri Aug 30 10:24:57 2002
@@ -1264,18 +1264,20 @@
         * output on a slow console).
         * We scan all interrupt descriptors to see if any have
         * completed.
         */
        LIST_FOREACH(ii, &sc->sc_intrhead, list)
                uhci_check_intr(sc, ii);
 
+#ifdef USB_USE_SOFTINTR
        if (sc->sc_softwake) {
                sc->sc_softwake = 0;
                wakeup(&sc->sc_softwake);
        }
+#endif /* USB_USE_SOFTINTR */
 
        sc->sc_bus.intr_context--;
 }
 
 /* Check for an interrupt. */
 void
 uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii)
@@ -1923,18 +1925,22 @@
        /* 
         * Step 2: Wait until we know hardware has finished any possible
         * use of the xfer.  Also make sure the soft interrupt routine
         * has run.
         */
        usb_delay_ms(upipe->pipe.device->bus, 2); /* Hardware finishes in 1ms */
        s = splusb();
+#ifdef USB_USE_SOFTINTR
        sc->sc_softwake = 1;
+#endif /* USB_USE_SOFTINTR */
        usb_schedsoftintr(&sc->sc_bus);
+#ifdef USB_USE_SOFTINTR 
        DPRINTFN(1,("uhci_abort_xfer: tsleep\n"));
        tsleep(&sc->sc_softwake, PZERO, "uhciab", 0);
+#endif /* USB_USE_SOFTINTR */
        splx(s);
                
        /*
         * Step 3: Execute callback.
         */
        xfer->hcpriv = ii;
 
--- uhcivar.h.orig      Thu Aug 29 09:29:58 2002
+++ uhcivar.h   Thu Aug 29 09:31:08 2002
@@ -163,15 +163,18 @@
 
        u_int8_t sc_addr;               /* device address */
        u_int8_t sc_conf;               /* device configuration */
 
        u_int8_t sc_saved_sof;
        u_int16_t sc_saved_frnum;
 
+#ifdef USB_USE_SOFTINTR
        char sc_softwake;
+#endif /* USB_USE_SOFTINTR */
+
        char sc_isreset;
        char sc_suspend;
        char sc_dying;
 
        LIST_HEAD(, uhci_intr_info) sc_intrhead;
 
        /* Info for the root hub interrupt channel. */
--- usb_port.h.orig     Tue Aug 27 13:06:39 2002
+++ usb_port.h  Fri Aug 30 11:08:42 2002
@@ -335,15 +335,15 @@
 MALLOC_DECLARE(M_USBDEV);
 MALLOC_DECLARE(M_USBHC);
 
 #endif
 
 #define USBVERBOSE
 
-#define USB_USE_SOFTINTR
+/* #define USB_USE_SOFTINTR */
 
 #define Static static
 
 #define device_ptr_t device_t
 #define USBBASEDEVICE device_t
 #define USBDEV(bdev) (bdev)
 #define USBDEVNAME(bdev) device_get_nameunit(bdev)

Reply via email to