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>