On 06/03/15(Fri) 22:06, Remi Locherer wrote:
> On Fri, Mar 06, 2015 at 09:15:23AM +0100, Stefan Sperling wrote:
> > On Fri, Mar 06, 2015 at 08:45:20AM +0100, Remi Locherer wrote:
> > > Hi,
> > > 
> > > Since about fall 2014 I see "urtwn0 timeout" every now an then like 
> > > others that reported it. An unplug and replut of the urtwn device
> > > usually helped.
> > > 
> > > But with the snapshots from March 1st and 3rd the system just freezes
> > > when I unplug the urtwn device after I see the timeout message in
> > > xconsole. The system just freezes and does not drop to ddb.
> > > 
> > > With the snapshot from February 20 I did not observe these freezes.
> > > 
> > > Outputs of lsusb -v and dmesg below.
> > > 
> > > Remi
> > > 
> > 
> > Hi Remi,
> > 
> > I've discussed this with mpi. We're unsure what's going on exactly. 
> > 
> > Can you please really make sure you're not dropping into ddb (i.e.
> > don't detach the device while in X, but when on console)?
> 
> Your assumption is right! Switching from X to console _before_ unplugging
> the urtwn device gives me an ddb promt. I made photos from trace and ps:
> 
> * page fault trap: https://relo.ch/urtwn_freeze/IMG_20150306_184105.jpg
> * trace cpu 0 - 3: https://relo.ch/urtwn_freeze/IMG_20150306_192412.jpg
> * ps part 1: https://relo.ch/urtwn_freeze/IMG_20150306_192537.jpg
> * ps part 2: https://relo.ch/urtwn_freeze/IMG_20150306_192708.jpg

It looks like we're trying to remove a transfer from the list of pending
xfers when it has not yet been added to it.

Could you tell me if the diff below fixes your issue?

Index: ehci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ehci.c,v
retrieving revision 1.175
diff -u -p -r1.175 ehci.c
--- ehci.c      28 Feb 2015 09:22:59 -0000      1.175
+++ ehci.c      6 Mar 2015 22:21:28 -0000
@@ -2716,7 +2716,7 @@ ehci_abort_xfer(struct usbd_xfer *xfer, 
 
        DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p\n", xfer, epipe));
 
-       if (sc->sc_bus.dying) {
+       if (sc->sc_bus.dying || xfer->status == USBD_NOT_STARTED) {
                /* If we're dying, just do the software part. */
                s = splusb();
                xfer->status = status;  /* make software ignore it */
@@ -2728,6 +2728,12 @@ ehci_abort_xfer(struct usbd_xfer *xfer, 
 #endif
                usb_transfer_complete(xfer);
                splx(s);
+               return;
+       }
+
+       /* Transfer is already done. */
+       if (xfer->status != USBD_IN_PROGRESS) {
+               DPRINTF(("%s: already done \n", __func__));
                return;
        }
 

Reply via email to