* Make sure an aborted pipe is marked as not running.

* Start queued request in the right order.
* Insert some more DIAGNOSTIC sanity checks.
This commit is contained in:
augustss 1999-09-13 21:33:25 +00:00
parent df6f3652dd
commit ba2c2e2ade
5 changed files with 105 additions and 35 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ohci.c,v 1.45 1999/09/13 19:49:41 augustss Exp $ */
/* $NetBSD: ohci.c,v 1.46 1999/09/13 21:33:25 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -1133,6 +1133,7 @@ ohci_add_ed(sed, head)
ohci_soft_ed_t *sed;
ohci_soft_ed_t *head;
{
SPLUSBCHECK;
sed->next = head->next;
sed->ed.ed_nexted = head->ed.ed_nexted;
head->next = sed;
@ -1149,6 +1150,8 @@ ohci_rem_ed(sed, head)
{
ohci_soft_ed_t *p;
SPLUSBCHECK;
/* XXX */
for (p = head; p && p->next != sed; p = p->next)
;
@ -1177,6 +1180,8 @@ ohci_hash_add_td(sc, std)
{
int h = HASH(std->physaddr);
SPLUSBCHECK;
LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
}
@ -1186,6 +1191,8 @@ ohci_hash_rem_td(sc, std)
ohci_softc_t *sc;
ohci_soft_td_t *std;
{
SPLUSBCHECK;
LIST_REMOVE(std, hnext);
}
@ -1404,6 +1411,8 @@ ohci_abort_req(reqh, status)
struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
ohci_soft_ed_t *sed;
SPLUSBCHECK;
DPRINTF(("ohci_abort_req: reqh=%p pipe=%p\n", reqh, opipe));
reqh->status = status;
@ -1549,11 +1558,13 @@ ohci_root_ctrl_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (ohci_root_ctrl_start(reqh));
/* Pipe isn't running, start first */
return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -1564,7 +1575,7 @@ ohci_root_ctrl_start(reqh)
usb_device_request_t *req;
void *buf;
int port, i;
int len, value, index, l, totlen = 0;
int s, len, value, index, l, totlen = 0;
usb_port_status_t ps;
usb_hub_descriptor_t hubd;
usbd_status r;
@ -1853,7 +1864,9 @@ ohci_root_ctrl_start(reqh)
r = USBD_NORMAL_COMPLETION;
ret:
reqh->status = r;
s = splusb();
usb_transfer_complete(reqh);
splx(s);
return (USBD_IN_PROGRESS);
}
@ -1880,11 +1893,13 @@ ohci_root_intr_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (ohci_root_intr_start(reqh));
/* Pipe isn't running, start first */
return (ohci_root_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -1927,11 +1942,13 @@ ohci_device_ctrl_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (ohci_device_ctrl_start(reqh));
/* Pipe isn't running, start first */
return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -2001,11 +2018,13 @@ ohci_device_bulk_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (ohci_device_bulk_start(reqh));
/* Pipe isn't running, start first */
return (ohci_device_bulk_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -2133,11 +2152,13 @@ ohci_device_intr_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (ohci_device_intr_start(reqh));
/* Pipe isn't running, start first */
return (ohci_device_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhci.c,v 1.51 1999/09/13 19:49:41 augustss Exp $ */
/* $NetBSD: uhci.c,v 1.52 1999/09/13 21:33:25 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -685,6 +685,8 @@ uhci_add_ctrl(sc, sqh)
{
uhci_soft_qh_t *eqh;
SPLUSBCHECK;
DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
eqh = sc->sc_ctl_end;
sqh->hlink = eqh->hlink;
@ -702,6 +704,8 @@ uhci_remove_ctrl(sc, sqh)
{
uhci_soft_qh_t *pqh;
SPLUSBCHECK;
DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh));
for (pqh = sc->sc_ctl_start; pqh->hlink != sqh; pqh=pqh->hlink)
#if defined(DIAGNOSTIC) || defined(USB_DEBUG)
@ -726,6 +730,8 @@ uhci_add_bulk(sc, sqh)
{
uhci_soft_qh_t *eqh;
SPLUSBCHECK;
DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
eqh = sc->sc_bulk_end;
sqh->hlink = eqh->hlink;
@ -743,6 +749,8 @@ uhci_remove_bulk(sc, sqh)
{
uhci_soft_qh_t *pqh;
SPLUSBCHECK;
DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
for (pqh = sc->sc_bulk_start; pqh->hlink != sqh; pqh = pqh->hlink)
#if defined(DIAGNOSTIC) || defined(USB_DEBUG)
@ -882,6 +890,7 @@ uhci_check_intr(sc, ii)
uhci_idone(ii);
}
/* Called at splusb() */
void
uhci_idone(ii)
uhci_intr_info_t *ii;
@ -1316,11 +1325,13 @@ uhci_device_bulk_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (uhci_device_bulk_start(reqh));
/* Pipe isn't running, start first */
return (uhci_device_bulk_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -1475,11 +1486,13 @@ uhci_device_ctrl_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (uhci_device_ctrl_start(reqh));
/* Pipe isn't running, start first */
return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -1509,11 +1522,13 @@ uhci_device_intr_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (uhci_device_intr_start(reqh));
/* Pipe isn't running, start first */
return (uhci_device_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -1796,7 +1811,7 @@ uhci_device_isoc_transfer(reqh)
/* and put on interrupt list if the pipe wasn't running */
if (r == USBD_NORMAL_COMPLETION)
uhci_device_isoc_start(reqh);
uhci_device_isoc_start(SIMPLEQ_FIRST(&reqh->pipe->queue));
return (r);
}
@ -2428,11 +2443,13 @@ uhci_root_ctrl_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (uhci_root_ctrl_start(reqh));
/* Pipe isn't running, start first */
return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
usbd_status
@ -2443,7 +2460,7 @@ uhci_root_ctrl_start(reqh)
usb_device_request_t *req;
void *buf;
int port, x;
int len, value, index, status, change, l, totlen = 0;
int s, len, value, index, status, change, l, totlen = 0;
usb_port_status_t ps;
usbd_status r;
@ -2762,7 +2779,9 @@ uhci_root_ctrl_start(reqh)
ret:
reqh->status = r;
reqh->hcpriv = 0;
s = splusb();
usb_transfer_complete(reqh);
splx(s);
return (USBD_IN_PROGRESS);
}
@ -2802,11 +2821,13 @@ uhci_root_intr_transfer(reqh)
{
usbd_status r;
/* Insert last in queue. */
r = usb_insert_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION)
return (r);
else
return (uhci_root_intr_start(reqh));
/* Pipe isn't running, start first */
return (uhci_root_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
}
/* Start a transfer on the root interrupt pipe */

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb.c,v 1.20 1999/09/13 19:18:17 augustss Exp $ */
/* $NetBSD: usb.c,v 1.21 1999/09/13 21:33:25 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -84,6 +84,7 @@ MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
int usbdebug = 0;
int uhcidebug;
int ohcidebug;
int usb_noexplore = 0;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@ -205,6 +206,10 @@ usb_event_thread(arg)
while (!sc->shutdown) {
(void)tsleep(&sc->sc_bus->needs_explore,
PWAIT, "usbevt", hz*30);
#ifdef USB_DEBUG
if (usb_noexplore)
continue;
#endif
DPRINTFN(2,("usb_event_thread: woke up\n"));
usb_discover(sc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi.c,v 1.39 1999/09/13 19:18:17 augustss Exp $ */
/* $NetBSD: usbdi.c,v 1.40 1999/09/13 21:33:25 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -681,6 +681,8 @@ usbd_ar_pipe(pipe)
{
usbd_request_handle reqh;
SPLUSBCHECK;
DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
#ifdef USB_DEBUG
if (usbdebug > 5)
@ -716,6 +718,7 @@ usbd_init()
}
}
/* Called at splusb() */
void
usb_transfer_complete(reqh)
usbd_request_handle reqh;
@ -724,8 +727,10 @@ usb_transfer_complete(reqh)
usb_dma_t *dmap = &reqh->dmabuf;
int polling;
DPRINTFN(5, ("usb_transfer_complete: pipe=%p reqh=%p actlen=%d\n",
pipe, reqh, reqh->actlen));
SPLUSBCHECK;
DPRINTFN(5, ("usb_transfer_complete: pipe=%p reqh=%p status=%d actlen=%d\n",
pipe, reqh, reqh->status, reqh->actlen));
#ifdef DIAGNOSTIC
if (!pipe) {
@ -776,9 +781,14 @@ usb_transfer_complete(reqh)
if ((reqh->flags & USBD_SYNCHRONOUS) && !polling)
wakeup(reqh);
if (!pipe->repeat &&
reqh->status != USBD_CANCELLED && reqh->status != USBD_TIMEOUT)
usbd_start_next(pipe);
if (!pipe->repeat) {
/* XXX should we stop the queue on all errors? */
if (reqh->status == USBD_CANCELLED ||
reqh->status == USBD_TIMEOUT)
pipe->running = 0;
else
usbd_start_next(pipe);
}
}
usbd_status
@ -789,8 +799,8 @@ usb_insert_transfer(reqh)
usbd_status r;
int s;
DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d\n", pipe,
pipe->running));
DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
pipe, pipe->running, reqh->timeout));
s = splusb();
SIMPLEQ_INSERT_TAIL(&pipe->queue, reqh, next);
if (pipe->running)
@ -803,6 +813,7 @@ usb_insert_transfer(reqh)
return (r);
}
/* Called at splusb() */
void
usbd_start_next(pipe)
usbd_pipe_handle pipe;
@ -810,6 +821,8 @@ usbd_start_next(pipe)
usbd_request_handle reqh;
usbd_status r;
SPLUSBCHECK;
DPRINTFN(10, ("usbd_start_next: pipe=%p\n", pipe));
#ifdef DIAGNOSTIC

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdivar.h,v 1.32 1999/09/13 19:49:41 augustss Exp $ */
/* $NetBSD: usbdivar.h,v 1.33 1999/09/13 21:33:25 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -221,6 +221,16 @@ void usb_transfer_complete __P((usbd_request_handle reqh));
int usb_bus_count __P((void));
void usb_needs_explore __P((usbd_bus_handle));
#ifdef DIAGNOSTIC
#define SPLUSBCHECK \
do { int _s = splusb(), _su = splusb(); \
if (_s != _su) printf("SPLUSBCHECK failed %d!=%d, %s:%d\n", \
_s, _su, __FILE__, __LINE__); \
} while (0)
#else
#define SPLUSBCHECK
#endif
/* Locator stuff. */
#if defined(__NetBSD__)