[PATCH] xHCI: FSE handled cleanly by incrementing event dequeue pointer

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

 



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�����٥




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

  Powered by Linux