When a transfer is in progress and a STOP command is issued to xHC, xHC will generate 2 event TRBs on event ring: (1) Force Stopped Event TRB on successful completion of STOP cmd. (2) Transfer Event TRB for the TD which was in progress and stopped in the middle (with its Completion Code set to Stopped). Since the value of event->buffer is undefined and should be ignored, at this point the code should return after incrementing the dequeue pointer of event ring. Signed-off-by: Saurov Shyam <saurov.s@xxxxxxxxxxx> Signed-off-by: Manish Sharma <manish.s4@xxxxxxxxxxx> --- drivers/usb/host/xhci-ring.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7d34cbf..bfb3f20 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2245,6 +2245,17 @@ static int handle_tx_event(struct xhci_hcd *xhci, return -ENODEV; } + /* If a TD is in progress, FSE handled cleanly by incrementing event + * dequeue pointer. This should be handled before dereferencing + * event->buffer otherwise NULL value gets assigned to ep_ring. + **/ + trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); + if (trb_comp_code == COMP_STOP_INVAL) { + xhci_handle_cmd_stop_ep(xhci, slot_id, xhci->cmd_ring->dequeue, + (struct xhci_event_cmd *)event); + inc_deq(xhci, xhci->event_ring); + return 0; + } /* Endpoint ID is 1 based, our index is zero based */ ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; ep = &xdev->eps[ep_index]; -- 1.7.9.5��.n��������+%������w��{.n�����{���)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥