Re: Understanding USB callback events and sequence

From: Hans Petter Selasky <hps_at_selasky.org>
Date: Tue, 22 Mar 2022 18:28:24 UTC
On 3/22/22 19:05, Farhan Khan wrote:
> Hi all,
> 
> I am trying to understand how the structure of the USB callback and have a few questions. The relevant manual page is usbdi(9).
> 
> The manual talks about the 3 states of the callback: USB_ST_SETUP, USB_ST_TRANSFERRED, and default (error). I am not clear on the difference between USB_ST_SETUP and USB_ST_TRANSFERRED. The manual seems to suggest that USB_ST_SETUP is where the USB packet is sent, which leads me to think USB_ST_TRANSFERRED is cleanup? From looking at examples, this appears to be how thinks are done.

Hi Faran,

The USB callback function is like an event loop. After a USB transfer 
was submitted and completed you get a callback one time in state 
ST_TRANSFERRED. If you then don't submit another job, you will go back 
to ST_SETUP.

> What triggers the event? From testing, it seems that usbd_transfer_start(9) triggers the callback with USB_ST_SETUP. If so, what triggers USB_ST_TRANSFERRED. Why is it necessary?

usbd_transfer_start() triggers the initial USB_ST_SETUP. Nothing else. 
If you call usbd_transfer_start() while the USB transfer is pending, 
nothing happens!

This was part of the design, because for example with ethernet, one 
thread may feed data, while another may process data.

To simplify implementations, the feed loop just calls 
usbd_transfer_start(), and then the callback will process data as needed.

> Also, when I read examples I see that in some places the expected `break` in the `select` is removed with a note saying "fall through". Wouldn't this double-send the USB packet, or at least sent another packet during the USB_ST_TRANSFERRED stage? 

No, this is normal. All USB transfer callbacks are sequential. 
usbd_transfer_start() does not directly call the USB transfer callback.

> For example here:
> https://github.com/freebsd/freebsd-src/blob/9a6695532b3997e4e2bc3fe57481cc49be5e9e93/sys/dev/usb/wlan/if_rsu.c#L2671

This just means that the driver wants to check if it can send more 
packets after the current job completed (USB_ST_TRANSFERRED).

> 
> Finally, I have been looking at USB traffic under wireshark (interpreted from usbdump -w file.pcap) and I see that every USB packet has a response from the device. Is this response packet handled by one of the RX callbacks? Or is this the same as TX's USB_ST_TRANSFERRED?

The "DONE" callback is either USB_ST_TRANSFERRED or USB_ST_CANCELLED / 
default.

> Thank you and pardon the multiple questions!

You are welcome, hope it makes sense to you.

--HPS