Re: more usb detach love

2010-11-25 Thread Kevin Chadwick
On Wed, 24 Nov 2010 20:59:22 +
Jacob Meuser jake...@sdf.lonestar.org wrote:

 thoughts?

Probably not the thoughts your after especially on tech, but some of the
panics I was seeing a while back (keep meaning to run more recent and
proper tests with output, but time is short at the mo) would occur just
after device removal and only with certain usb readers. If I remember
right, usually after bb_reset messages. This along with other work on
usb I've seen definately seems to ring bells.

I'll try to find the time to see if my 4.8 snapshot can be paniced with
some troublesome readers, though I'm not sure if the ones that were
troublesome varied on 4.5/4.6? and 4.7. Anyway, If I can, I'll try
your patch



Re: more usb detach love

2010-11-25 Thread Jacob Meuser
On Thu, Nov 25, 2010 at 12:45:10PM +, Kevin Chadwick wrote:
 On Wed, 24 Nov 2010 20:59:22 +
 Jacob Meuser jake...@sdf.lonestar.org wrote:
 
  thoughts?
 
 Probably not the thoughts your after especially on tech, but some of the
 panics I was seeing a while back (keep meaning to run more recent and
 proper tests with output, but time is short at the mo) would occur just
 after device removal and only with certain usb readers. If I remember
 right, usually after bb_reset messages. This along with other work on
 usb I've seen definately seems to ring bells.
 
 I'll try to find the time to see if my 4.8 snapshot can be paniced with
 some troublesome readers, though I'm not sure if the ones that were
 troublesome varied on 4.5/4.6? and 4.7. Anyway, If I can, I'll try
 your patch

dlg@ fixed some panics that were caused by removing sd(4) devices not
so long ago, e.g. sys/scsi/sd.c r1.212.  anyway, this patch doesn't
touch umass(4), so it probably isn't a whole lot of help for that
particular case.

for people testing this, I'm more interested that it doesn't break
anything, than that it fixes some particular case, because I already
know that it does fix some particular cases.

-- 
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org



more usb detach love

2010-11-24 Thread Jacob Meuser
when a usb device is removed from a port, a hub interrupt is
generated.  this causes a hub explore task to be scheduled,
which will find that the device has been removed then detach
the driver via usb_disconnect_port().  so there is some time
between when the device is removed and the driver detachment.
if the kernel tries to access the device after it has been
removed but before the driver is detached, a kernel crash is
likely. also, the kernel does not know the device has been
removed until the driver is detached; config_deactivate() is
never called.

the following patch adds a 'dying' field to struct usbd_device,
and a couple functions, usbd_deactivate() and usbd_is_dying().
usbd_deactivate() sets the new dying field, and usbd_is_dying()
checks whether the dying field is set.  usb_disconnect_port()
is changed to call config_deactivate() for devices to be detached
before calling config_detach(), and usbd_deactivate() is added
to the DVACT_DEACTIVATE case for many devices' activate()
functions.  also, usbd_is_dying() is either added or replaces
driver specific state variables at places where it would be
good to know if the hardware is still usable.

the idea is to give drivers a chance to quit accessing the
hardware before the driver is detached, so we don't detach
the driver while a request is stalled trying to read/write
nonexistent hardware.

oh, usbd_is_dying() also checks if the underlying bus is
detached, because if the bus is detached, the device has
also been detached.  I think this will avoid the crash
described in
http://marc.info/?l=openbsd-bugsm=129050458925460w=2
it seems that that device generates a hub interrupt (the
only thing that causes uhub_explore() to be run) when
detached.  on the one hand this makes sense: hub interrupt
means the status of the hub changed.  on the other, it's
nonsensical: the hub is gone, we don't need an interrupt to
know that the hub state has changed.

the idea is really from yuo@, in some commit messages from
a couple months ago.

I've been running this diff for quite some time, and it was
actually in snapshots for some time in early October.

thoughts?

p.s. yes, this doesn't convert *all* drivers at this time.
that will happen, I promise.

-- 
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: if_atu.c
===
RCS file: /cvs/src/sys/dev/usb/if_atu.c,v
retrieving revision 1.96
diff -u -p -r1.96 if_atu.c
--- if_atu.c27 Oct 2010 17:51:11 -  1.96
+++ if_atu.c24 Nov 2010 19:53:58 -
@@ -902,7 +902,7 @@ atu_internal_firmware(void *arg)
if (err != 0) {
printf(%s: %s loadfirmware error %d\n,
sc-atu_dev.dv_xname, name, err);
-   return;
+   goto fail;
}
 
ptr = firm;
@@ -918,7 +918,7 @@ atu_internal_firmware(void *arg)
DPRINTF((%s: dfu_getstatus failed!\n,
sc-atu_dev.dv_xname));
free(firm, M_DEVBUF);
-   return;
+   goto fail;
}
/* success means state = DnLoadIdle */
state = DFUState_DnLoadIdle;
@@ -940,7 +940,7 @@ atu_internal_firmware(void *arg)
DPRINTF((%s: dfu_dnload failed\n,
sc-atu_dev.dv_xname));
free(firm, M_DEVBUF);
-   return;
+   goto fail;
}
 
ptr += block_size;
@@ -969,14 +969,14 @@ atu_internal_firmware(void *arg)
if (err) {
DPRINTF((%s: dfu_getstatus failed!\n,
sc-atu_dev.dv_xname));
-   return;
+   goto fail;
}
 
DPRINTFN(15, (%s: sending remap\n, sc-atu_dev.dv_xname));
err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL);
if ((err)  (!ISSET(sc-atu_quirk, ATU_QUIRK_NO_REMAP))) {
DPRINTF((%s: remap failed!\n, sc-atu_dev.dv_xname));
-   return;
+   goto fail;
}
 
/* after a lot of trying and measuring I found out the device needs
@@ -989,6 +989,9 @@ atu_internal_firmware(void *arg)
printf(%s: reattaching after firmware upload\n,
sc-atu_dev.dv_xname);
usb_needs_reattach(sc-atu_udev);
+
+fail:
+   usbd_deactivate(sc-atu_udev);
 }
 
 void
@@ -1169,7 +1172,7 @@ atu_task(void *arg)
 
DPRINTFN(10, (%s: atu_task\n, sc-atu_dev.dv_xname));
 
-   if (sc-sc_state != ATU_S_OK)
+   if (usbd_is_dying(sc-atu_udev))
return;
 
switch (sc-sc_cmd) {
@@ -1259,25 +1262,23 @@ atu_attach(struct device *parent, struct
u_int8_tmode, channel;
int i;
 
-   sc-sc_state = ATU_S_UNCONFIG;
+