Some undefined values, mostly null are coming in event->buffer in my case for
"stop,-invalid length” transfer event.
However, in the portion of the code you suggested does not increment the
dequeue pointer of transfer event ring, for trb_comp_code = COMP_STOP_INVAL.
In handle_tx_event() cleanup: does not increment the dequeue pointer of
transfer event ring.
In xhci_handle_event():
…
case TRB_TYPE(TRB_TRANSFER):
ret = handle_tx_event(xhci, &event->trans_event);
if (ret < 0)
xhci->error_bitmask |= 1 << 9;
else
update_ptrs = 0;
…
if (update_ptrs)
/* Update SW event ring dequeue pointer */
inc_deq(xhci, xhci->event_ring);
…
As update_ptrs=0, inc_deq(xhci, xhci->event_ring) won't run.
Regards,
-Saurov
------- Original Message -------
Sender : Mathias Nyman<[email protected]>
Date : Jul 01, 2015 17:35 (GMT+05:30)
Title : Re: [PATCH] xHCI: FSE handled cleanly by incrementing event dequeue
pointer
On 01.07.2015 13:13, SAUROV KANTI SHYAM wrote:
> 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.
>
The first event should be a "stop, invalid length" transfer event in case we
stop
in between TD's.
The event-> buffer should be valid and contain the current dequeue pointer
value
of the ring, see xhci 1.0 section 4.6.9.
It might still be part of the previous TD, but this is is already taken care of
in handle_tx_event():
/*
* Skip the Force Stopped Event. The event_trb(event_dma) of FSE
* is not in the current TD pointed by ep_ring->dequeue because
* that the hardware dequeue pointer still at the previous TRB
* of the current TD. The previous TRB maybe a Link TD or the
* last TRB of the previous TD. The command completion handle
* will take care the rest.
*/
if (!event_seg && (trb_comp_code == COMP_STOP ||
trb_comp_code == COMP_STOP_INVAL)) {
ret = 0;
goto cleanup;
}
The "stop,-invalid length" transfer event is followed by a command completion
event, which
we handle by calling xhci_handle_cmd_stop_ep(), so no point in calling it from
handle_tx_event()
Does this patch solve any issue in your case? there might be something else
going on.
If you have some custom solution using event data TRBs on the transfer ring
then it is
possible that it stops on an event data TRB, and the event->buffer is not a
pointer to the ring.
In that case the ED (Event Data) bit in the transfer event should first be
checked.
-Mathias