On Wed, 2010-04-28 at 09:50 -0700, Sarah Sharp wrote: > > > I'm also wondering about this line: > > > > > > Apr 27 13:42:09 xanatos kernel: [12044.124863] xhci_hcd 0000:05:00.0: WARN Event TRB for slot 1 ep 2 with no TDs queued? > > > > > This line is strange to be here. A missed service error indicates the > > xHC was unable to complete the data transfer associated with an Isoch > > TRB within the ESIT. but if an endpoint has no tds queued, what does the > > xHC has to process? > > If the driver got stuck on one isoc TD, and the host processed all the > TDs after that one, then there will still be TDs in the endpoint's TD > list. So this code will never run: > > > if (list_empty(&ep_ring->td_list)) { > /* When the Isoch ring is empty, the xHC will generate > * a Ring Overrun Event for IN Isoch endpoint or Ring > * Underrun Event for OUT Isoch endpoint. > */ > switch (trb_comp_code) { > case COMP_UNDERRUN: > xhci_dbg(xhci, "underrun event on endpoint\n"); > urb = NULL; > goto cleanup; > case COMP_OVERRUN: > xhci_dbg(xhci, "overrun event on endpoint\n"); > urb = NULL; > goto cleanup; > default: > break; > } > xhci_warn(xhci, "WARN Event TRB for slot %d ep %d " > "with no TDs queued?\n", > TRB_TO_SLOT_ID(event->flags), ep_index); > xhci_warn(xhci, "Event TRB with TRB type ID %u\n", > (unsigned int) > (event->flags & TRB_TYPE_BITMASK)>>10); > xhci_print_trb_offsets(xhci, (union xhci_trb *) event); > urb = NULL; > goto cleanup; > } > > You may want to move the checking for COMP_UNDERRUN and COMP_OVERRUN > outside that if statement. > The symptom driver got stuck on one isoc TD should not happen but yes, you got a point. xHCI spec 4.11.2.3 says, "A Ring Underrun or Ring overrun Event is only generated the first interval that an empty Transfer Ring is detected." So if encounter a Ring Underrun or Ring overrun Event but the ep_ring->td_list is not empty, it means something is wrong. That case should be handled and reported. > > When the xHC continues to process, you can see two valid isoc tds > > @21cb2420 and 21cb2430 have no corresponding events in the event ring. > > The next event is for td @21cb2440. The td @21cb2420 is stucked and many > > "ERROR Transfer event TRB DMA ptr not part of current TD" messages burst > > out. > > > > Now that's the trick part. When submit one missed service error event, > > the xHC actually missed two isoc tds. (According to the spec, in this > > case there should be two missed service error events here - correct me > > if I'm wrong.) > > I'll ask Steve about that. It's not clear to me from the spec. In > fact, section 4.11.2.3 says: > > "The xHC may not generate a Missed Service Error for each Isochronous > deadline missed, e.g. if the Event Ring is full." > > I would read that to mean that the xHC can skip arbitrary numbers of > isoc TDs and only generate one Missed Service Error, but I'll ask Steve > for clarification. > Probably you are right. The xHC may not generate a Missed Service Error for every isoc TD it missed. It's the driver's responsibility to check and handle the missed TDs. > > Even if advance to next td when encounter missed service > > error event, in this case it will go to td @21cb2430 - unfortunately > > still stucked. I'll do more tests to see if this is always what happens > > and what should do about this. You can check your log and see if this is > > what happening at your side. > > Hmm, maybe when we get a missed service event, we need to set a flag in > the endpoint. On the next transfer event with a non-zero DMA pointer, > we search for the TD that corresponds to the DMA pointer, and mark all > isoc buffers that are before that TD with a short packet status (and > giveback any URBs that we complete in the process). > It sounds feasible. I'll try this proposal. Thanks. Andiry Xu -- 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