On Mon, 7 Oct 2013, Sarah Sharp wrote: > > i am using 3.10 kernel. Also i looked at tip i see same implementation for > > process_ctrl_td() > > > > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/host/xhci-ring.c > > Yeah, the implementation has always been this way. I've known since the > beginning of writing the xHCI driver that it needs to handle zero-length > data phases, but hadn't had ever had a report that it was required by a > device under Linux. This code, near the end of process_ctrl_td(), looks a little strange: /* * 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) { /* Don't overwrite a previously set error code */ if ((*status == -EINPROGRESS || *status == 0) && (td->urb->transfer_flags & URB_SHORT_NOT_OK)) /* Did we already see a short data * stage? */ *status = -EREMOTEIO; If you already saw a short data stage, why isn't the status already set to -EREMOTEIO? Also what's the reason for the test "td->urb->actual_length != 0"? What does this have to do with getting a short data stage? Are you assuming that at this point, actual_length will be nonzero if and only if there was a short data stage? } else { td->urb->actual_length = td->urb->transfer_buffer_length; } What's the purpose of this clause? It looks like the driver is confusing "actual_length == 0" with "actual_length was never set". What if actual_length _was_ previously set, but it was set to 0? Alan Stern -- 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