Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 May 2011 18:16:14 -0700
From:      Trevor Blackwell <trevor@anybots.com>
To:        freebsd-usb@freebsd.org
Subject:   Clearing stalls: usbd_xfer_set_stall vs usbd_do_clear_stall_callback
Message-ID:  <BANLkTik9MDy_tS3s78xG9VtbTaW%2BnCoM9A@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
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.

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);
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);
}
}

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.



-- 
Trevor Blackwell    trevor@anybots.com    650 776 7870



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?BANLkTik9MDy_tS3s78xG9VtbTaW%2BnCoM9A>