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>