ehci vs xhci: zero-length packet received in control endpoint handled differently?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey,

I've been trying to debug the issue I have with my Option Globetrotter
modem, handled by the 'hso' driver.

One thing the driver does is to re-submit the RX urb in the control
endpoint if the urb->actual_length is > 0:

put_rxbuf_data_and_resubmit_ctrl_urb ()
{
        ...
        /* Re issue a read as long as we receive data. */
        if (count == 0 && ((urb->actual_length != 0) ||
            (serial->rx_state == RX_PENDING))) {
                serial->rx_state = RX_SENT;
                hso_mux_serial_read(serial);
        } else
                serial->rx_state = RX_IDLE;
}

The thing is that (urb->actual_length == 0) never seems to happen with
the xhci driver.

When using the ehci driver, we do get that condition, see hso debug
logs when the modem sends back two characters ("AT" echo in the TTY):
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 0
After the last urb, rx_state would go to RX_IDLE.

When using the xhci driver,  we never get the actual_length set to 0,
instead, it is reset to transfer_buffer_length (1024 here) before it
reaches the hso driver. Equivalent logs would be:
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1024
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1024
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1024
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1024
  [  +0,000005] [1995:ctrl_callback]: Actual length of urb = 1024
  ....
And it goes like that forever.

The issue is not only that the hso driver ends up getting in a loop
where the RX urb is continuously resubmitted, but also, the hso driver
will actually take all those 1024 bytes as data, and feed them as
output of the TTY (which is what e.g. ModemManager sees, a bunch of
NUL bytes interleaved with AT responses).

Looking at the xhci code, and after adding some additional debug logs,
the urb->actual_length is reset to transfer_buffer_length in the
following place:

process_ctrl_td()
{
        ...
        /*
         * Did we transfer any data, despite the errors that might have
         * happened?  I.e. did we get past the setup stage?
         */
        if (event_trb != ep_ring->dequeue) {
                /* The event was for the status stage */
                if (event_trb == td->last_trb) {
                        if (td->urb->actual_length != 0) {
                                ...
                        } else {
                                td->urb->actual_length =
td->urb->transfer_buffer_length;
                        }
                }
                ...
        }
        ...
}

actual_length passes from being 0 to transfer_buffer_length, which is
what I see in the hso driver logs.

Now, what would be the thing to fix? Shouldn't ehci and xhci behave in
the same way w.r.t. this zero-length packet? Or is it the hso driver
the one needing a fix?

Cheers,

-- 
Aleksander
https://aleksander.es
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux