Further modify bulk endpoint behavior to be able to tear down the
current transfer fully in the "purge" routine, and to actually finish kicking out any read()s in progress.
This commit is contained in:
parent
9bd82b5c5d
commit
00b5244e28
@ -776,14 +776,18 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
|
||||
sce->state |= UGEN_ASLP;
|
||||
error = tsleep(sce, PCATCH | PZERO,
|
||||
"ugenrd", 0);
|
||||
if (error) {
|
||||
if (sce->bulkreq.err || error) {
|
||||
sce->state &= ~UGEN_ASLP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tn = sce->bulkreq.len;
|
||||
err = sce->bulkreq.err;
|
||||
if (err == EIO) {
|
||||
error = ENXIO;
|
||||
break;
|
||||
}
|
||||
tn = sce->bulkreq.len;
|
||||
error = uiomove(sce->bulkreq.buf, tn, uio);
|
||||
|
||||
/* Set up a new transfer. */
|
||||
@ -982,12 +986,21 @@ void
|
||||
ugenpurge(struct cdev *dev)
|
||||
{
|
||||
int endpt = UGENENDPOINT(dev);
|
||||
struct ugen_endpoint *sce;
|
||||
struct ugen_softc *sc;
|
||||
|
||||
if (endpt == USB_CONTROL_ENDPOINT)
|
||||
return;
|
||||
USB_GET_SC(ugen, UGENUNIT(dev), sc);
|
||||
wakeup(&sc->sc_endpoints[endpt][IN]);
|
||||
sce = &sc->sc_endpoints[endpt][IN];
|
||||
if (sce->pipeh)
|
||||
usbd_abort_pipe(sce->pipeh);
|
||||
/* cancel async bulk transfer */
|
||||
if (sce->bulkreq.xfer != NULL) {
|
||||
ugen_rdcb(sce->bulkreq.xfer, sce, USBD_IOERROR);
|
||||
usbd_free_xfer(sce->bulkreq.xfer);
|
||||
sce->bulkreq.xfer = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1016,7 +1029,7 @@ USB_DETACH(ugen)
|
||||
/* cancel async bulk transfer */
|
||||
if (sce->bulkreq.xfer != NULL)
|
||||
ugen_rdcb(sce->bulkreq.xfer,
|
||||
sce, USBD_INTERRUPTED);
|
||||
sce, USBD_IOERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user