Clearing stalls: usbd_xfer_set_stall vs usbd_do_clear_stall_callback

Hans Petter Selasky hselasky at c2i.net
Thu May 5 06:41:18 UTC 2011


On Thursday 05 May 2011 03:16:14 Trevor Blackwell wrote:
> We have a system that experiences occasional stalls due to ESD strikes in
> the cable between the host & hub. So I've been extensively testing the
> clear stall logic.
> 

Hi,

> It's done two different ways in the standard drivers. In if_cdce it's:
> 
> if (error != USB_ERR_CANCELLED) {
>                         usbd_xfer_set_stall(xfer);

In this case you need to either set the number of frames equal to zero, or 
setup a valid data chain!

> usbd_transfer_submit(xfer);
> }
> 
> In the midi part of uaudio it's done by setting up special control
> transfers and keeping state in the driver:
> 
>  if (error != USB_ERR_CANCELLED) {
> /* try to clear stall first */
> chan->flags |= UMIDI_FLAG_READ_STALL;
> usbd_transfer_start(chan->xfer[3]);
> }
> ...
> static void
> umidi_read_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error)
> {
> struct umidi_chan *chan = usbd_xfer_softc(xfer);
> struct usb_xfer *xfer_other = chan->xfer[1];
> 
> if (usbd_clear_stall_callback(xfer, xfer_other)) {
> DPRINTF("stall cleared\n");
> chan->flags &= ~UMIDI_FLAG_READ_STALL;
> usbd_transfer_start(xfer_other);
> }
> }

This way is depreciated, and has been changed into the above method which 
should work exactly the same.

> 
> The first sure is simpler, but it doesn't seem to work. Stalls never get
> cleared. Tracing through the code, it's not clear how the clear stall
> request is supposed to get filled in. I can see that usb_xfer_set_stall
> ultimately leads to a call to usbd_clear_stall_proc, but I can't find where
> udev->ctrl_xfer[1] gets set up with the right endpoint values.

Look in usb_device.c and the function:

usb_do_clear_stall_callback()

The way it works, is that this function scans the USB device for stalled 
endpoints, and then clear one and one of them in turn.

--HPS


More information about the freebsd-usb mailing list