Rename and move around callout handles to make it more sane.

Add some DIAGNOSTIC.
Fix buglet in isoc abort on UHCI.
This commit is contained in:
augustss 2000-03-25 18:02:32 +00:00
parent b7eeb17414
commit 3fded57690
6 changed files with 81 additions and 61 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ohci.c,v 1.80 2000/03/24 22:03:30 augustss Exp $ */
/* $NetBSD: ohci.c,v 1.81 2000/03/25 18:02:32 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@ -1173,7 +1173,7 @@ ohci_softintr(bus)
continue;
}
cc = OHCI_TD_GET_CC(le32toh(std->td.td_flags));
usb_uncallout(xfer->timo_handle, ohci_timeout, xfer);
usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
if (xfer->status == USBD_CANCELLED ||
xfer->status == USBD_TIMEOUT) {
DPRINTF(("ohci_process_done: cancel/timeout %p\n",
@ -1498,7 +1498,7 @@ ohci_device_request(xfer)
opipe->tail.td = tail;
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
if (xfer->timeout && !sc->sc_bus.use_polling) {
usb_callout(xfer->timo_handle, MS_TO_TICKS(xfer->timeout),
usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
ohci_timeout, xfer);
}
splx(s);
@ -1693,6 +1693,7 @@ ohci_open(pipe)
DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
pipe, addr, ed->bEndpointAddress, sc->sc_addr));
if (addr == sc->sc_addr) {
switch (ed->bEndpointAddress) {
case USB_CONTROL_ENDPOINT:
@ -1840,7 +1841,7 @@ ohci_abort_xfer(xfer, status)
xfer->status = status;
usb_uncallout(xfer->timo_handle, ohci_timeout, xfer);
usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
sed = opipe->sed;
DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
@ -1849,8 +1850,8 @@ ohci_abort_xfer(xfer, status)
#if 1
if (xfer->device->bus->intr_context) {
/* We have no process context, so we can't use tsleep(). */
usb_callout(xfer->abort_handle, hz / USB_FRAMES_PER_SECOND,
ohci_abort_xfer_end, xfer);
usb_callout(xfer->pipe->abort_handle,
hz / USB_FRAMES_PER_SECOND, ohci_abort_xfer_end, xfer);
} else {
#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
KASSERT(intr_nesting_level == 0,
@ -2543,7 +2544,7 @@ ohci_device_bulk_start(xfer)
sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
if (xfer->timeout && !sc->sc_bus.use_polling) {
usb_callout(xfer->timo_handle, MS_TO_TICKS(xfer->timeout),
usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
ohci_timeout, xfer);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhci.c,v 1.95 2000/03/25 07:23:12 augustss Exp $ */
/* $NetBSD: uhci.c,v 1.96 2000/03/25 18:02:32 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@ -122,7 +122,6 @@ struct uhci_pipe {
u_char aborting;
usbd_xfer_handle abortstart, abortend;
usb_callout_t abort_timeout;
/* Info needed for different pipe kinds. */
union {
@ -171,7 +170,7 @@ static void uhci_free_std_chain __P((uhci_softc_t *,
static usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *,
uhci_softc_t *, int, int, u_int16_t, usb_dma_t *,
uhci_soft_td_t **, uhci_soft_td_t **));
static void uhci_timo __P((void *));
static void uhci_poll_hub __P((void *));
static void uhci_waitintr __P((uhci_softc_t *,
usbd_xfer_handle));
static void uhci_check_intr __P((uhci_softc_t *,
@ -458,6 +457,8 @@ uhci_init(sc)
SIMPLEQ_INIT(&sc->sc_free_xfers);
usb_callout_init(sc->sc_poll_handle);
/* Set up the bus struct. */
sc->sc_bus.methods = &uhci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
@ -571,7 +572,6 @@ uhci_allocx(bus)
if (xfer != NULL) {
memset(xfer, 0, sizeof (struct uhci_xfer));
UXFER(xfer)->iinfo.sc = sc;
usb_callout_init(UXFER(xfer)->iinfo.timeout_handle);
#ifdef DIAGNOSTIC
UXFER(xfer)->iinfo.isdone = 1;
#endif
@ -590,19 +590,14 @@ uhci_freex(bus, xfer)
struct uhci_softc *sc = (struct uhci_softc *)bus;
#ifdef DIAGNOSTIC
#ifdef __NetBSD__
if (callout_pending(&UXFER(xfer)->iinfo.timeout_handle)) {
printf("uhci_free_intr_info: pending callout");
return;
}
#endif
if (xfer->busy_free != XFER_BUSY) {
printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer,
xfer->busy_free);
return;
}
xfer->busy_free = XFER_FREE;
if (!UXFER(xfer)->iinfo.isdone)
printf("uhci_freex: !isdone\n");
#endif
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
@ -647,9 +642,9 @@ uhci_power(why, v)
if (uhcidebug > 2)
uhci_dumpregs(sc);
#endif
if (sc->sc_has_timo != NULL)
usb_uncallout(sc->sc_has_timo->timo_handle,
uhci_timo, sc->sc_has_timo);
if (sc->sc_intr_xfer != NULL)
usb_uncallout(sc->sc_poll_handle, uhci_poll_hub,
sc->sc_intr_xfer);
sc->sc_bus.use_polling++;
uhci_run(sc, 0); /* stop the controller */
@ -685,9 +680,9 @@ uhci_power(why, v)
uhci_run(sc, 1); /* and start traffic again */
usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
sc->sc_bus.use_polling--;
if (sc->sc_has_timo != NULL)
usb_callout(sc->sc_has_timo->timo_handle, sc->sc_ival,
uhci_timo, sc->sc_has_timo);
if (sc->sc_intr_xfer != NULL)
usb_callout(sc->sc_poll_handle, sc->sc_ival,
uhci_poll_hub, sc->sc_intr_xfer);
#ifdef UHCI_DEBUG
if (uhcidebug > 2)
uhci_dumpregs(sc);
@ -872,7 +867,7 @@ void iidump() { uhci_dump_iis(thesc); }
* from the root controller interrupt pipe for port status change.
*/
void
uhci_timo(addr)
uhci_poll_hub(addr)
void *addr;
{
usbd_xfer_handle xfer = addr;
@ -881,9 +876,9 @@ uhci_timo(addr)
int s;
u_char *p;
DPRINTFN(20, ("uhci_timo\n"));
DPRINTFN(20, ("uhci_poll_hub\n"));
usb_callout(xfer->timo_handle, sc->sc_ival, uhci_timo, xfer);
usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
p = KERNADDR(&xfer->dmabuf);
p[0] = 0;
@ -1136,7 +1131,7 @@ uhci_check_intr(sc, ii)
}
done:
DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii));
usb_uncallout(ii->timeout_handle, uhci_timeout, ii);
usb_uncallout(ii->xfer->timeout_handle, uhci_timeout, ii);
uhci_idone(ii);
}
@ -1643,7 +1638,6 @@ uhci_device_bulk_start(xfer)
ii->xfer = xfer;
ii->stdstart = data;
ii->stdend = dataend;
usb_callout_init(ii->timeout_handle);
#ifdef DIAGNOSTIC
if (!ii->isdone) {
printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii);
@ -1659,7 +1653,7 @@ uhci_device_bulk_start(xfer)
uhci_add_intr_info(sc, ii);
if (xfer->timeout && !sc->sc_bus.use_polling) {
usb_callout(ii->timeout_handle, MS_TO_TICKS(xfer->timeout),
usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
uhci_timeout, ii);
}
xfer->status = USBD_IN_PROGRESS;
@ -1802,14 +1796,17 @@ uhci_abort_xfer(xfer, status)
/* wait for HC to complete TDs */
delay(maxlen);
/* Don't timeout, */
usb_uncallout(xfer->timeout_handle, uhci_timeout, ii);
#ifdef DIAGNOSTIC
UXFER(xfer)->iinfo.isdone = 1;
#endif
/* Run callback and remove from interrupt list. */
usb_transfer_complete(xfer);
/* Don't timeout, */
usb_uncallout(ii->timeout_handle, uhci_timeout, ii);
/* Set up final processing. */
usb_callout(upipe->abort_timeout, hz / USB_FRAMES_PER_SECOND,
usb_callout(xfer->pipe->abort_handle, hz / USB_FRAMES_PER_SECOND,
uhci_abort_xfer_end, upipe);
/* And return. */
@ -1977,7 +1974,7 @@ uhci_cancel_abort(pipe)
s = splusb();
if (upipe->aborting) {
usb_uncallout(upipe->abort_timeout, uhci_abort_xfer_end, upipe);
usb_uncallout(pipe->abort_handle, uhci_abort_xfer_end, upipe);
upipe->aborting = 0;
}
splx(s);
@ -2100,7 +2097,6 @@ uhci_device_intr_start(xfer)
ii->xfer = xfer;
ii->stdstart = data;
ii->stdend = dataend;
usb_callout_init(ii->timeout_handle);
#ifdef DIAGNOSTIC
if (!ii->isdone) {
printf("uhci_device_intr_transfer: not done, ii=%p\n", ii);
@ -2269,7 +2265,6 @@ uhci_device_request(xfer)
ii->xfer = xfer;
ii->stdstart = setup;
ii->stdend = stat;
usb_callout_init(ii->timeout_handle);
#ifdef DIAGNOSTIC
if (!ii->isdone) {
printf("uhci_device_request: not done, ii=%p\n", ii);
@ -2311,7 +2306,7 @@ uhci_device_request(xfer)
}
#endif
if (xfer->timeout && !sc->sc_bus.use_polling) {
usb_callout(ii->timeout_handle, MS_TO_TICKS(xfer->timeout),
usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
uhci_timeout, ii);
}
xfer->status = USBD_IN_PROGRESS;
@ -2368,6 +2363,7 @@ uhci_device_isoc_enter(xfer)
if (xfer->status == USBD_IN_PROGRESS) {
/* This request has already been entered into the frame list */
printf("uhci_device_isoc_enter: xfer=%p in frame list\n", xfer);
/* XXX */
}
@ -2427,6 +2423,8 @@ uhci_device_isoc_start(xfer)
uhci_soft_td_t *end;
int s, i;
DPRINTFN(5,("uhci_device_isoc_start: xfer=%p\n", xfer));
if (sc->sc_dying)
return (USBD_IOERROR);
@ -2441,13 +2439,19 @@ uhci_device_isoc_start(xfer)
i -= UHCI_VFRAMELIST_COUNT;
end = upipe->u.iso.stds[i];
#ifdef DIAGNOSTIC
if (end == NULL) {
printf("uhci_device_isoc_start: end == NULL\n");
return (USBD_INVAL);
}
#endif
s = splusb();
/* Set up interrupt info. */
ii->xfer = xfer;
ii->stdstart = end;
ii->stdend = end;
usb_callout_init(ii->timeout_handle);
#ifdef DIAGNOSTIC
if (!ii->isdone) {
printf("uhci_device_isoc_start: not done, ii=%p\n", ii);
@ -2499,6 +2503,9 @@ uhci_device_isoc_abort(xfer)
/* and wait until we are sure the hardware has finished. */
delay(maxlen);
#ifdef DIAGNOSTIC
UXFER(xfer)->iinfo.isdone = 1;
#endif
/* Run callback and remove from interrupt list. */
usb_transfer_complete(xfer);
@ -2614,6 +2621,10 @@ uhci_device_isoc_done(xfer)
DPRINTFN(4, ("uhci_isoc_done: length=%d\n", xfer->actlen));
if (ii->xfer != xfer)
/* Not on interrupt list, ignore it. */
return;
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_BUSY) {
printf("uhci_device_isoc_done: xfer=%p not busy 0x%08x\n",
@ -2677,7 +2688,6 @@ uhci_device_intr_done(xfer)
ii->stdstart = data;
ii->stdend = dataend;
usb_callout_init(ii->timeout_handle);
#ifdef DIAGNOSTIC
if (!ii->isdone) {
printf("uhci_device_intr_done: not done, ii=%p\n", ii);
@ -2852,7 +2862,6 @@ uhci_open(pipe)
pipe, pipe->device->address,
ed->bEndpointAddress, sc->sc_addr));
usb_callout_init(upipe->abort_timeout);
upipe->aborting = 0;
upipe->nexttoggle = 0;
@ -3373,14 +3382,17 @@ uhci_root_intr_abort(xfer)
{
uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
usb_uncallout(xfer->timo_handle, uhci_timo, xfer);
sc->sc_has_timo = NULL;
usb_uncallout(sc->sc_poll_handle, uhci_poll_hub, xfer);
sc->sc_intr_xfer = NULL;
if (xfer->pipe->intrxfer == xfer) {
DPRINTF(("uhci_root_intr_abort: remove\n"));
xfer->pipe->intrxfer = 0;
}
xfer->status = USBD_CANCELLED;
#ifdef DIAGNOSTIC
UXFER(xfer)->iinfo.isdone = 1;
#endif
usb_transfer_complete(xfer);
}
@ -3416,8 +3428,8 @@ uhci_root_intr_start(xfer)
return (USBD_IOERROR);
sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
usb_callout(xfer->timo_handle, sc->sc_ival, uhci_timo, xfer);
sc->sc_has_timo = xfer;
usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
sc->sc_intr_xfer = xfer;
return (USBD_IN_PROGRESS);
}
@ -3428,7 +3440,7 @@ uhci_root_intr_close(pipe)
{
uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
usb_uncallout(pipe->intrxfer->timo_handle, uhci_timo, pipe->intrxfer);
sc->sc_has_timo = NULL;
usb_uncallout(sc->sc_poll_handle, uhci_poll_hub, sc->sc_intr_xfer);
sc->sc_intr_xfer = NULL;
DPRINTF(("uhci_root_intr_close\n"));
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhcivar.h,v 1.26 2000/03/24 22:57:58 augustss Exp $ */
/* $NetBSD: uhcivar.h,v 1.27 2000/03/25 18:02:33 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $ */
/*
@ -74,7 +74,6 @@ typedef struct uhci_intr_info {
uhci_soft_td_t *stdstart;
uhci_soft_td_t *stdend;
LIST_ENTRY(uhci_intr_info) list;
usb_callout_t timeout_handle;
#ifdef DIAGNOSTIC
int isdone;
#endif
@ -163,7 +162,8 @@ typedef struct uhci_softc {
/* Info for the root hub interrupt channel. */
int sc_ival; /* time between root hug intrs */
usbd_xfer_handle sc_has_timo; /* root hub interrupt transfer */
usbd_xfer_handle sc_intr_xfer; /* root hub interrupt transfer */
usb_callout_t sc_poll_handle;
char sc_vendor[16]; /* vendor string for root hub */
int sc_id_vendor; /* vendor ID for root hub */

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_subr.c,v 1.67 2000/03/13 23:52:37 soren Exp $ */
/* $NetBSD: usb_subr.c,v 1.68 2000/03/25 18:02:33 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@ -698,6 +698,7 @@ usbd_setup_pipe(dev, iface, ep, ival, pipe)
p->repeat = 0;
p->interval = ival;
SIMPLEQ_INIT(&p->queue);
usb_callout_init(p->abort_handle);
err = dev->bus->methods->open_pipe(p);
if (err) {
DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi.c,v 1.67 2000/03/24 22:03:32 augustss Exp $ */
/* $NetBSD: usbdi.c,v 1.68 2000/03/25 18:02:33 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@ -238,6 +238,12 @@ usbd_close_pipe(pipe)
LIST_REMOVE(pipe, next);
pipe->endpoint->refcnt--;
pipe->methods->close(pipe);
#if defined(__NetBSD__) && defined(DIAGNOSTIC)
if (callout_pending(&pipe->abort_handle)) {
callout_stop(&pipe->abort_handle);
printf("usbd_close_pipe: abort_handle pending");
}
#endif
if (pipe->intrxfer != NULL)
usbd_free_xfer(pipe->intrxfer);
free(pipe, M_USB);
@ -384,8 +390,7 @@ usbd_alloc_xfer(dev)
if (xfer == NULL)
return (NULL);
xfer->device = dev;
usb_callout_init(xfer->timo_handle);
usb_callout_init(xfer->abort_handle);
usb_callout_init(xfer->timeout_handle);
DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
return (xfer);
}
@ -398,10 +403,10 @@ usbd_free_xfer(xfer)
if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
usbd_free_buffer(xfer);
#if defined(__NetBSD__) && defined(DIAGNOSTIC)
if (callout_pending(&xfer->timo_handle))
panic("usbd_free_xfer: timo_handle pending");
if (callout_pending(&xfer->abort_handle))
panic("usbd_free_xfer: abort_handle pending");
if (callout_pending(&xfer->timeout_handle)) {
callout_stop(&xfer->timeout_handle);
printf("usbd_free_xfer: timout_handle pending");
}
#endif
xfer->device->bus->methods->freex(xfer->device->bus, xfer);
return (USBD_NORMAL_COMPLETION);

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdivar.h,v 1.51 2000/03/25 07:13:05 augustss Exp $ */
/* $NetBSD: usbdivar.h,v 1.52 2000/03/25 18:02:33 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
/*
@ -165,6 +165,8 @@ struct usbd_pipe {
char repeat;
int interval;
usb_callout_t abort_handle;
/* Filled by HC driver. */
struct usbd_pipe_methods *methods;
};
@ -206,8 +208,7 @@ struct usbd_xfer {
void *hcpriv; /* private use by the HC driver */
usb_callout_t timo_handle;
usb_callout_t abort_handle;
usb_callout_t timeout_handle;
};
void usbd_init __P((void));