Re: Tx transfer not triggering corresponding Rx interrupt
- Reply: Hans Petter Selasky : "Re: Tx transfer not triggering corresponding Rx interrupt"
- Reply: Hans Petter Selasky : "Re: Tx transfer not triggering corresponding Rx interrupt"
- In reply to: Hans Petter Selasky : "Re: Tx transfer not triggering corresponding Rx interrupt"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 17 May 2022 06:18:08 UTC
On Monday, May 16, 2022 9:52:14 AM EDT Hans Petter Selasky wrote: > On 5/15/22 04:41, Farhan Khan wrote: > > Hi all, > > > > I am trying to understand why a USB Rx interrupt callback is not > > triggering. I am sending a USB Tx interrupt packet. The immediate next > > step is that the function will msleep(). The corresponding wakeup() > > occurs after an Rx interrupt. > > > > There is no explicit usbd_transfer_start() on the Rx interrupt. Elsewhere > > in the code there is an instance where an Tx interrupt should eventually > > result in a corresponding Rx interrupt that results in a wakeup(). That > > does not occurs here and I do not understand why not. > > Hi Farhan, > > OpenBSD and NetBSD it is simply different than in FreeBSD, so you need > to start all transfers that should receive or transmit data. I did this. No change in behavior. > > Problem: > Can you use these terms instead: > > IN packet (from device to host) > OUT packet (from host to device) > > Else I get confused what direction traffic is flowing. > > RX/TX terms are always relative to the local code. > > IN / OUT is fixed. Pardon, I will use IN/OUT. But you are correct, I intended Tx and Rx to be relative to the host. So Tx means OUT (from Host to device) and Rx means IN (from device to host). > > The msleep() located on line 1314 fails with EWOULDBLOCK. > > This sleep seems to be the equivalent of the acknowledgement that the Tx > > interrupt packet was received. > > > > ----------- > > Expected: > > > > I expect this to somehow result in the Rx interrupt, which runs the > > corresponding handler athn_usb_intr(). This function contains the wakeup() > > line on line 2556 (the AR_HTC_MSG_CONN_SVC case). > > > > ----------- > > This happens elsewhere: > > > > In athn_usb_load_firmware(), line 1011, there is a usbd_do_request(), > > followed by an msleep(). The wait_msg_id is AR_HTC_MSG_READY. The wakeup > > for this occurs only after an Rx interrupt is called on line 2538. > > > > ----------- > > Question rephrased: > > > > Why is a USB transfer resulting in an Rx interrupt in one place, even > > though a usbd_transfer_start() is not called on the Rx interrupt, but not > > for athn_usb_htc_connect_svc()/athn_usb_htc_msg()? > > > > How do I make this Tx transfer result in an Rx interrupt without having to > > manually call usbd_transfer_start() (OpenBSD does not appear to do this?) > > Because the USB stack is not the same! You need to study FreeBSD's USB > stack a bit more and you'll figure out. I have been reading example code and documentation for weeks now. This behavior is not documented anywhere. > > I do not understand the differences between usbd_do_request, > > usb_transfer_start and usbd_setup_xfer/usbd_transfer that might be > > resulting in different behavior, so any light on that would also help. > > usbd_do_request() is only for synchronous transfers on endpoint zero, > the control endpoint. It is a handy function to avoid allocating and > freeing USB transfers over and over again. Does this also result in automatic Rx/IN interrupt callbacks? If not, why is this happening? > > Function names might be similar, but the behaviour is very different! > > > ----------- > > Been stuck for some time, so any assistance is appreciated. > > Thank you! > : > :-) > > --HPS Do you have office hours during which we can speak? Perhaps IRC? I have asked this question a few times and I'm not getting it sufficiently answered. I suspect it is due to us getting lost in the details rather than focusing on the question. I apologize, my emails have been very verbose and perhaps unfocused. I'll try to keep this simple: In my driver I call usbd_do_transfer() followed by a msleep() **WITHOUT** calling usbd_transfer_start on the Rx/IN interrupt. The Rx/IN interrupt is necessary to run the associated wakeup(). This suggests the Rx/IN callback is happening, yet I see the callback for the Rx/IN interrupt happening. This is what I want to occur, but why is this happening **WITHOUT** being called? Similarly, is there a way to have an Rx/IN interrupt trigger after receiving a USB packet **WITHOUT** manually calling usbd_transfer_start() the way it is done with usbd_transfer_start()? The `interval` parameter, which seems like it should execute the callback on a regular interval, does not do anything at all. If I can get this question explained, I can hopefully make progress. Otherwise, I'm stuck and this seems like undocumented or inconsistent behavior. Failed strategies so far: * Manually calling the Rx/IN interrupt, changing msleep time to 10 seconds - Rx/IN callback happening late for some reason. And this just seems wrong. * Calling Rx/IN from within the Tx/OUT callback - Not possible due to mutex. Just to confirm, the device is sending the host an Rx/IN packet, I confirmed this with wireshark. Very stuck and confused :( - Farhan