MFNetBSD:

revision 1.116
    date: 2001/11/21 08:18:40;  author: augustss;  state: Exp;  lines: +30 -3
    Pay more attention to if the HC is being unplugged.
This commit is contained in:
Josef Karthauser 2002-04-07 15:07:23 +00:00
parent 8f3c17c9ba
commit daae4fc6d9

View file

@ -1,4 +1,4 @@
/* $NetBSD: ohci.c,v 1.114 2001/11/21 02:41:18 augustss Exp $ */
/* $NetBSD: ohci.c,v 1.116 2001/11/21 08:18:40 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -364,6 +364,9 @@ ohci_detach(struct ohci_softc *sc, int flags)
powerhook_disestablish(sc->sc_powerhook);
shutdownhook_disestablish(sc->sc_shutdownhook);
#endif
usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
/* free data structures XXX */
return (rv);
@ -1057,7 +1060,7 @@ ohci_intr(void *p)
{
ohci_softc_t *sc = p;
if (sc->sc_dying)
if (sc == NULL || sc->sc_dying)
return (0);
/* If we get an interrupt while polling, then just ignore it. */
@ -1548,6 +1551,8 @@ ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer)
xfer->status = USBD_IN_PROGRESS;
for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
usb_delay_ms(&sc->sc_bus, 1);
if (sc->sc_dying)
break;
intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
#ifdef OHCI_DEBUG
@ -1862,9 +1867,16 @@ void
ohci_timeout(void *addr)
{
struct ohci_xfer *oxfer = addr;
struct ohci_pipe *opipe = (struct ohci_pipe *)oxfer->xfer.pipe;
ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer));
if (sc->sc_dying) {
ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT);
return;
}
/* 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);
@ -1984,6 +1996,9 @@ ohci_open(usbd_pipe_handle pipe)
DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
pipe, addr, ed->bEndpointAddress, sc->sc_addr));
if (sc->sc_dying)
return (USBD_IOERROR);
std = NULL;
sed = NULL;
@ -2141,6 +2156,15 @@ ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed));
if (sc->sc_dying) {
/* If we're dying, just do the software part. */
s = splusb();
xfer->status = status; /* make software ignore it */
usb_uncallout(xfer->timeout_handle, ehci_timeout, xfer);
usb_transfer_complete(xfer);
splx(s);
}
if (xfer->device->bus->intr_context || !curproc)
panic("ohci_abort_xfer: not in process context\n");
@ -2589,6 +2613,10 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer)
for (i = 0; i < 5; i++) {
usb_delay_ms(&sc->sc_bus,
USB_PORT_ROOT_RESET_DELAY);
if (sc->sc_dying) {
err = USBD_IOERROR;
goto ret;
}
if ((OREAD4(sc, port) & UPS_RESET) == 0)
break;
}