Fix just the worst of the timeout race conditions that the previous
backed out commits were trying to address: when cancelling the timeout callout, also cancel the abort_task event, since it is possible that the timeout has already fired and set up an abort_task.
This commit is contained in:
parent
06281152f5
commit
2d37c72581
@ -755,6 +755,7 @@ ehci_check_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
|
||||
done:
|
||||
DPRINTFN(12, ("ehci_check_intr: ex=%p done\n", ex));
|
||||
usb_uncallout(ex->xfer.timeout_handle, ehci_timeout, ex);
|
||||
usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
|
||||
ehci_idone(ex);
|
||||
}
|
||||
|
||||
@ -1169,6 +1170,8 @@ ehci_allocx(struct usbd_bus *bus)
|
||||
}
|
||||
if (xfer != NULL) {
|
||||
memset(xfer, 0, sizeof(struct ehci_xfer));
|
||||
usb_init_task(&EXFER(xfer)->abort_task, ehci_timeout_task,
|
||||
xfer);
|
||||
#ifdef DIAGNOSTIC
|
||||
EXFER(xfer)->isdone = 1;
|
||||
xfer->busy_free = XFER_BUSY;
|
||||
@ -2496,6 +2499,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
|
||||
s = splusb();
|
||||
xfer->status = status; /* make software ignore it */
|
||||
usb_uncallout(xfer->timeout_handle, ehci_timeout, xfer);
|
||||
usb_rem_task(epipe->pipe.device, &exfer->abort_task);
|
||||
usb_transfer_complete(xfer);
|
||||
splx(s);
|
||||
return;
|
||||
@ -2510,6 +2514,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
|
||||
s = splusb();
|
||||
xfer->status = status; /* make software ignore it */
|
||||
usb_uncallout(xfer->timeout_handle, ehci_timeout, xfer);
|
||||
usb_rem_task(epipe->pipe.device, &exfer->abort_task);
|
||||
qhstatus = sqh->qh.qh_qtd.qtd_status;
|
||||
sqh->qh.qh_qtd.qtd_status = qhstatus | htole32(EHCI_QTD_HALTED);
|
||||
for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
|
||||
@ -2591,7 +2596,6 @@ ehci_timeout(void *addr)
|
||||
}
|
||||
|
||||
/* Execute the abort in a process context. */
|
||||
usb_init_task(&exfer->abort_task, ehci_timeout_task, addr);
|
||||
usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task);
|
||||
}
|
||||
|
||||
|
@ -998,6 +998,8 @@ ohci_allocx(struct usbd_bus *bus)
|
||||
}
|
||||
if (xfer != NULL) {
|
||||
memset(xfer, 0, sizeof (struct ohci_xfer));
|
||||
usb_init_task(&OXFER(xfer)->abort_task, ohci_timeout_task,
|
||||
xfer);
|
||||
#ifdef DIAGNOSTIC
|
||||
xfer->busy_free = XFER_BUSY;
|
||||
#endif
|
||||
@ -1405,6 +1407,8 @@ ohci_softintr(void *v)
|
||||
continue;
|
||||
}
|
||||
usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
|
||||
usb_rem_task(OXFER(xfer)->xfer.pipe->device,
|
||||
&OXFER(xfer)->abort_task);
|
||||
|
||||
len = std->len;
|
||||
if (std->td.td_cbp != 0)
|
||||
@ -1975,7 +1979,6 @@ ohci_timeout(void *addr)
|
||||
}
|
||||
|
||||
/* Execute the abort in a process context. */
|
||||
usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr);
|
||||
usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task);
|
||||
}
|
||||
|
||||
@ -2256,6 +2259,7 @@ ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
|
||||
s = splusb();
|
||||
xfer->status = status; /* make software ignore it */
|
||||
usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
|
||||
usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
|
||||
usb_transfer_complete(xfer);
|
||||
splx(s);
|
||||
}
|
||||
@ -2269,6 +2273,7 @@ ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
|
||||
s = splusb();
|
||||
xfer->status = status; /* make software ignore it */
|
||||
usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
|
||||
usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
|
||||
splx(s);
|
||||
DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
|
||||
sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
|
||||
|
@ -1370,6 +1370,7 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii)
|
||||
done:
|
||||
DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii));
|
||||
usb_uncallout(ii->xfer->timeout_handle, uhci_timeout, ii);
|
||||
usb_rem_task(ii->xfer->pipe->device, &UXFER(ii->xfer)->abort_task);
|
||||
uhci_idone(ii);
|
||||
}
|
||||
|
||||
@ -1945,8 +1946,8 @@ uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
|
||||
s = splusb();
|
||||
xfer->status = status; /* make software ignore it */
|
||||
usb_uncallout(xfer->timeout_handle, uhci_timeout, xfer);
|
||||
usb_transfer_complete(xfer);
|
||||
usb_rem_task(xfer->pipe->device, &UXFER(xfer)->abort_task);
|
||||
usb_transfer_complete(xfer);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user