@@ -277,6 +277,67 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
277277 }
278278}
279279
280+ /*
281+ * If the suspect DMA address is a TRB in this TD, this function returns that
282+ * TRB's segment. Otherwise it returns 0.
283+ */
284+ static struct xhci_segment * trb_in_td (struct xhci_hcd * xhci , struct xhci_td * td ,
285+ dma_addr_t suspect_dma , bool debug )
286+ {
287+ dma_addr_t start_dma ;
288+ dma_addr_t end_seg_dma ;
289+ dma_addr_t end_trb_dma ;
290+ struct xhci_segment * cur_seg ;
291+
292+ start_dma = xhci_trb_virt_to_dma (td -> start_seg , td -> start_trb );
293+ cur_seg = td -> start_seg ;
294+
295+ do {
296+ if (start_dma == 0 )
297+ return NULL ;
298+ /* We may get an event for a Link TRB in the middle of a TD */
299+ end_seg_dma = xhci_trb_virt_to_dma (cur_seg ,
300+ & cur_seg -> trbs [TRBS_PER_SEGMENT - 1 ]);
301+ /* If the end TRB isn't in this segment, this is set to 0 */
302+ end_trb_dma = xhci_trb_virt_to_dma (cur_seg , td -> end_trb );
303+
304+ if (debug )
305+ xhci_warn (xhci ,
306+ "Looking for event-dma %016llx trb-start %016llx trb-end %016llx seg-start %016llx seg-end %016llx\n" ,
307+ (unsigned long long )suspect_dma ,
308+ (unsigned long long )start_dma ,
309+ (unsigned long long )end_trb_dma ,
310+ (unsigned long long )cur_seg -> dma ,
311+ (unsigned long long )end_seg_dma );
312+
313+ if (end_trb_dma > 0 ) {
314+ /* The end TRB is in this segment, so suspect should be here */
315+ if (start_dma <= end_trb_dma ) {
316+ if (suspect_dma >= start_dma && suspect_dma <= end_trb_dma )
317+ return cur_seg ;
318+ } else {
319+ /* Case for one segment with
320+ * a TD wrapped around to the top
321+ */
322+ if ((suspect_dma >= start_dma &&
323+ suspect_dma <= end_seg_dma ) ||
324+ (suspect_dma >= cur_seg -> dma &&
325+ suspect_dma <= end_trb_dma ))
326+ return cur_seg ;
327+ }
328+ return NULL ;
329+ }
330+ /* Might still be somewhere in this segment */
331+ if (suspect_dma >= start_dma && suspect_dma <= end_seg_dma )
332+ return cur_seg ;
333+
334+ cur_seg = cur_seg -> next ;
335+ start_dma = xhci_trb_virt_to_dma (cur_seg , & cur_seg -> trbs [0 ]);
336+ } while (cur_seg != td -> start_seg );
337+
338+ return NULL ;
339+ }
340+
280341/*
281342 * Return number of free normal TRBs from enqueue to dequeue pointer on ring.
282343 * Not counting an assumed link TRB at end of each TRBS_PER_SEGMENT sized segment.
@@ -2079,67 +2140,6 @@ static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event)
20792140 spin_lock (& xhci -> lock );
20802141}
20812142
2082- /*
2083- * If the suspect DMA address is a TRB in this TD, this function returns that
2084- * TRB's segment. Otherwise it returns 0.
2085- */
2086- struct xhci_segment * trb_in_td (struct xhci_hcd * xhci , struct xhci_td * td , dma_addr_t suspect_dma ,
2087- bool debug )
2088- {
2089- dma_addr_t start_dma ;
2090- dma_addr_t end_seg_dma ;
2091- dma_addr_t end_trb_dma ;
2092- struct xhci_segment * cur_seg ;
2093-
2094- start_dma = xhci_trb_virt_to_dma (td -> start_seg , td -> start_trb );
2095- cur_seg = td -> start_seg ;
2096-
2097- do {
2098- if (start_dma == 0 )
2099- return NULL ;
2100- /* We may get an event for a Link TRB in the middle of a TD */
2101- end_seg_dma = xhci_trb_virt_to_dma (cur_seg ,
2102- & cur_seg -> trbs [TRBS_PER_SEGMENT - 1 ]);
2103- /* If the end TRB isn't in this segment, this is set to 0 */
2104- end_trb_dma = xhci_trb_virt_to_dma (cur_seg , td -> end_trb );
2105-
2106- if (debug )
2107- xhci_warn (xhci ,
2108- "Looking for event-dma %016llx trb-start %016llx trb-end %016llx seg-start %016llx seg-end %016llx\n" ,
2109- (unsigned long long )suspect_dma ,
2110- (unsigned long long )start_dma ,
2111- (unsigned long long )end_trb_dma ,
2112- (unsigned long long )cur_seg -> dma ,
2113- (unsigned long long )end_seg_dma );
2114-
2115- if (end_trb_dma > 0 ) {
2116- /* The end TRB is in this segment, so suspect should be here */
2117- if (start_dma <= end_trb_dma ) {
2118- if (suspect_dma >= start_dma && suspect_dma <= end_trb_dma )
2119- return cur_seg ;
2120- } else {
2121- /* Case for one segment with
2122- * a TD wrapped around to the top
2123- */
2124- if ((suspect_dma >= start_dma &&
2125- suspect_dma <= end_seg_dma ) ||
2126- (suspect_dma >= cur_seg -> dma &&
2127- suspect_dma <= end_trb_dma ))
2128- return cur_seg ;
2129- }
2130- return NULL ;
2131- } else {
2132- /* Might still be somewhere in this segment */
2133- if (suspect_dma >= start_dma && suspect_dma <= end_seg_dma )
2134- return cur_seg ;
2135- }
2136- cur_seg = cur_seg -> next ;
2137- start_dma = xhci_trb_virt_to_dma (cur_seg , & cur_seg -> trbs [0 ]);
2138- } while (cur_seg != td -> start_seg );
2139-
2140- return NULL ;
2141- }
2142-
21432143static void xhci_clear_hub_tt_buffer (struct xhci_hcd * xhci , struct xhci_td * td ,
21442144 struct xhci_virt_ep * ep )
21452145{
0 commit comments