@@ -277,6 +277,67 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
277
277
}
278
278
}
279
279
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
+
280
341
/*
281
342
* Return number of free normal TRBs from enqueue to dequeue pointer on ring.
282
343
* 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)
2079
2140
spin_lock (& xhci -> lock );
2080
2141
}
2081
2142
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
-
2143
2143
static void xhci_clear_hub_tt_buffer (struct xhci_hcd * xhci , struct xhci_td * td ,
2144
2144
struct xhci_virt_ep * ep )
2145
2145
{
0 commit comments