On 24.11.2016 15:33, Felipe Balbi wrote:
Stop Endpoint command can come at any point and we have no control of that. We should make sure to handle COMP_STOP on SETUP phase as well, otherwise urb->actual_lenght might be set to negative values in some occasions such as below: urb->length = 4; build_control_transfer_td_for(urb, ep); stop_endpoint(ep); COMP_STOP: [...] urb->actual_length = urb->length - trb->length; trb->length is 8 for SETUP stage (8 control request bytes), so actual_length would be set to -4 in this case. While doing that, also make sure to use TRB_TYPE field of the actual TRB instead of matching pointers to figure out in which stage of the control transfer we got our completion event. Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> ---
This is awsome. This probably fixes tons of issues related to failing getting port status and other control transfers. Looking at it now it turns out that in COMP_STOP case we can't rely on endpoint ring dequeue pointer to be correct, and still we used it to determine the control transfer stage. (setup, data, status). No wonder there has been issues related to control transfers. Using the TRB_TYPE of the actual TRB on the endpoint ring is definitely the way to go Thanks -Mathias -- 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