|
@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|
|
* qtd is updated in qh_completions(). Update the QH
|
|
|
* overlay here.
|
|
|
*/
|
|
|
- if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
|
|
|
+ if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
|
|
|
qh->hw->hw_qtd_next = qtd->hw_next;
|
|
|
qtd = NULL;
|
|
|
}
|
|
@@ -449,11 +449,19 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
|
|
else if (last_status == -EINPROGRESS && !urb->unlinked)
|
|
|
continue;
|
|
|
|
|
|
- /* qh unlinked; token in overlay may be most current */
|
|
|
- if (state == QH_STATE_IDLE
|
|
|
- && cpu_to_hc32(ehci, qtd->qtd_dma)
|
|
|
- == hw->hw_current) {
|
|
|
+ /*
|
|
|
+ * If this was the active qtd when the qh was unlinked
|
|
|
+ * and the overlay's token is active, then the overlay
|
|
|
+ * hasn't been written back to the qtd yet so use its
|
|
|
+ * token instead of the qtd's. After the qtd is
|
|
|
+ * processed and removed, the overlay won't be valid
|
|
|
+ * any more.
|
|
|
+ */
|
|
|
+ if (state == QH_STATE_IDLE &&
|
|
|
+ qh->qtd_list.next == &qtd->qtd_list &&
|
|
|
+ (hw->hw_token & ACTIVE_BIT(ehci))) {
|
|
|
token = hc32_to_cpu(ehci, hw->hw_token);
|
|
|
+ hw->hw_token &= ~ACTIVE_BIT(ehci);
|
|
|
|
|
|
/* An unlink may leave an incomplete
|
|
|
* async transaction in the TT buffer.
|