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<mathias.ny...@linux.intel.com>
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

Reply via email to