Date: Thu, 5 May 2011 08:40:07 +0200 From: Hans Petter Selasky <hselasky@c2i.net> To: freebsd-usb@freebsd.org Cc: Trevor Blackwell <trevor@anybots.com> Subject: Re: Clearing stalls: usbd_xfer_set_stall vs usbd_do_clear_stall_callback Message-ID: <201105050840.07361.hselasky@c2i.net> In-Reply-To: <BANLkTik9MDy_tS3s78xG9VtbTaW%2BnCoM9A@mail.gmail.com> References: <BANLkTik9MDy_tS3s78xG9VtbTaW%2BnCoM9A@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105050840.07361.hselasky>
