Pay more attention to if the HC is being unplugged.
This commit is contained in:
parent
f8e9dbe7d3
commit
1029005107
@ -1,7 +1,7 @@
|
||||
/* TODO
|
||||
Add intrinfo.
|
||||
*/
|
||||
/* $NetBSD: ehci.c,v 1.16 2001/11/21 02:47:07 augustss Exp $ */
|
||||
/* $NetBSD: ehci.c,v 1.17 2001/11/21 08:18:39 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -50,7 +50,7 @@ Add intrinfo.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.16 2001/11/21 02:47:07 augustss Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.17 2001/11/21 08:18:39 augustss Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -273,8 +273,6 @@ Static struct usbd_pipe_methods ehci_device_isoc_methods = {
|
||||
ehci_device_isoc_done,
|
||||
};
|
||||
|
||||
int ehcidisable = 0;
|
||||
|
||||
usbd_status
|
||||
ehci_init(ehci_softc_t *sc)
|
||||
{
|
||||
@ -283,9 +281,6 @@ ehci_init(ehci_softc_t *sc)
|
||||
usbd_status err;
|
||||
ehci_soft_qh_t *sqh;
|
||||
|
||||
if (ehcidisable)
|
||||
return (USBD_INVAL);
|
||||
|
||||
DPRINTF(("ehci_init: start\n"));
|
||||
#ifdef EHCI_DEBUG
|
||||
theehci = sc;
|
||||
@ -433,7 +428,7 @@ ehci_intr(void *v)
|
||||
{
|
||||
ehci_softc_t *sc = v;
|
||||
|
||||
if (sc == NULL || sc->sc_dying || ehcidisable)
|
||||
if (sc == NULL || sc->sc_dying)
|
||||
return (0);
|
||||
|
||||
/* If we get an interrupt while polling, then just ignore it. */
|
||||
@ -591,6 +586,8 @@ ehci_waitintr(ehci_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 = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)) &
|
||||
sc->sc_eintrs;
|
||||
DPRINTFN(15,("ehci_waitintr: 0x%04x\n", intrs));
|
||||
@ -648,7 +645,7 @@ ehci_detach(struct ehci_softc *sc, int flags)
|
||||
if (sc->sc_shutdownhook != NULL)
|
||||
shutdownhook_disestablish(sc->sc_shutdownhook);
|
||||
|
||||
usb_delay_ms(&sc->sc_bus, 1000); /* XXX let stray task complete */
|
||||
usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
|
||||
|
||||
/* XXX free other data structures XXX */
|
||||
|
||||
@ -955,6 +952,9 @@ ehci_open(usbd_pipe_handle pipe)
|
||||
DPRINTFN(1, ("ehci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
|
||||
pipe, addr, ed->bEndpointAddress, sc->sc_addr));
|
||||
|
||||
if (sc->sc_dying)
|
||||
return (USBD_IOERROR);
|
||||
|
||||
if (addr == sc->sc_addr) {
|
||||
switch (ed->bEndpointAddress) {
|
||||
case USB_CONTROL_ENDPOINT:
|
||||
@ -1537,10 +1537,18 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer)
|
||||
EOWRITE4(sc, port, v | EHCI_PS_PR);
|
||||
/* Wait for reset to complete. */
|
||||
usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
|
||||
if (sc->sc_dying) {
|
||||
err = USBD_IOERROR;
|
||||
goto ret;
|
||||
}
|
||||
/* Terminate reset sequence. */
|
||||
EOWRITE4(sc, port, v);
|
||||
/* Wait for HC to complete reset. */
|
||||
usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE);
|
||||
if (sc->sc_dying) {
|
||||
err = USBD_IOERROR;
|
||||
goto ret;
|
||||
}
|
||||
v = EOREAD4(sc, port);
|
||||
DPRINTF(("ehci after reset, status=0x%08x\n", v));
|
||||
if (v & EHCI_PS_PR) {
|
||||
@ -1924,8 +1932,8 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
|
||||
{
|
||||
struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
|
||||
ehci_soft_qh_t *sqh = epipe->sqh;
|
||||
#if 0
|
||||
ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
|
||||
#if 0
|
||||
ehci_soft_td_t *p, *n;
|
||||
ehci_physaddr_t headp;
|
||||
int hit;
|
||||
@ -1934,6 +1942,16 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
|
||||
|
||||
DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p sqh=%p\n", xfer, epipe,sqh));
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
if (xfer->device->bus->intr_context || !curproc)
|
||||
panic("ehci_abort_xfer: not in process context\n");
|
||||
|
||||
@ -1983,9 +2001,16 @@ void
|
||||
ehci_timeout(void *addr)
|
||||
{
|
||||
struct ehci_xfer *exfer = addr;
|
||||
struct ehci_pipe *epipe = (struct ehci_pipe *)exfer->xfer.pipe;
|
||||
ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
|
||||
|
||||
DPRINTF(("ehci_timeout: exfer=%p\n", exfer));
|
||||
|
||||
if (sc->sc_dying) {
|
||||
ehci_abort_xfer(&exfer->xfer, USBD_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
@ -2198,7 +2223,7 @@ ehci_device_request(usbd_xfer_handle xfer)
|
||||
}
|
||||
splx(s);
|
||||
|
||||
#if 1
|
||||
#ifdef EHCI_DEBUG
|
||||
if (ehcidebug > 10) {
|
||||
delay(10000);
|
||||
DPRINTF(("ehci_device_request: status=%x\n",
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ohci.c,v 1.115 2001/11/21 05:52:50 itojun Exp $ */
|
||||
/* $NetBSD: ohci.c,v 1.116 2001/11/21 08:18:40 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
@ -46,7 +46,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.115 2001/11/21 05:52:50 itojun Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.116 2001/11/21 08:18:40 augustss Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -381,6 +381,8 @@ ohci_detach(struct ohci_softc *sc, int flags)
|
||||
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 +1059,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. */
|
||||
@ -1516,6 +1518,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
|
||||
@ -1808,9 +1812,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);
|
||||
@ -1929,6 +1940,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;
|
||||
|
||||
@ -2086,6 +2100,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");
|
||||
|
||||
@ -2531,6 +2554,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user