From ba2c2e2ade784568c190e4658e2a6dd375ca8d89 Mon Sep 17 00:00:00 2001 From: augustss Date: Mon, 13 Sep 1999 21:33:25 +0000 Subject: [PATCH] * Make sure an aborted pipe is marked as not running. * Start queued request in the right order. * Insert some more DIAGNOSTIC sanity checks. --- sys/dev/usb/ohci.c | 45 +++++++++++++++++++++++++++++----------- sys/dev/usb/uhci.c | 47 ++++++++++++++++++++++++++++++------------ sys/dev/usb/usb.c | 7 ++++++- sys/dev/usb/usbdi.c | 29 +++++++++++++++++++------- sys/dev/usb/usbdivar.h | 12 ++++++++++- 5 files changed, 105 insertions(+), 35 deletions(-) diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 12ced6efc821..e7af10575805 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -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 diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 0780fb9ae7cf..ea89e3dc8e1f 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -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 */ diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c index 896882bd659b..957e5a59bb34 100644 --- a/sys/dev/usb/usb.c +++ b/sys/dev/usb/usb.c @@ -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); } diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index a5255a688cc3..651ce6f19f62 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -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 diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index e09c8ff9913e..40680dc7343c 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -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__)