From e8db6294949a5531c82c39d5924913a97a558285 Mon Sep 17 00:00:00 2001 From: augustss Date: Sun, 21 Jan 2001 02:39:52 +0000 Subject: [PATCH] Add code to use soft interrupt to handle USB interrupt processing. Don't enable the code since it doesn't work with the kludgy Ethernet drivers. --- sys/dev/usb/ohci.c | 8 ++++---- sys/dev/usb/uhci.c | 8 ++++---- sys/dev/usb/usb.c | 43 ++++++++++++++++++++++++++++++++++++++++-- sys/dev/usb/usb_port.h | 9 ++++++++- sys/dev/usb/usbdi.c | 5 ++++- sys/dev/usb/usbdi.h | 15 ++++++--------- sys/dev/usb/usbdivar.h | 14 +++++++++++--- 7 files changed, 78 insertions(+), 24 deletions(-) diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index afe125539d6c..99334de1a53a 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.98 2001/01/20 23:36:03 augustss Exp $ */ +/* $NetBSD: ohci.c,v 1.99 2001/01/21 02:39:52 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ /* @@ -137,7 +137,7 @@ Static void ohci_shutdown(void *v); Static void ohci_power(int, void *); Static usbd_status ohci_open(usbd_pipe_handle); Static void ohci_poll(struct usbd_bus *); -Static void ohci_softintr(struct usbd_bus *); +Static void ohci_softintr(void *); Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle); Static void ohci_add_done(ohci_softc_t *, ohci_physaddr_t); Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle); @@ -1189,9 +1189,9 @@ ohci_add_done(ohci_softc_t *sc, ohci_physaddr_t done) } void -ohci_softintr(struct usbd_bus *bus) +ohci_softintr(void *v) { - ohci_softc_t *sc = (ohci_softc_t *)bus; + ohci_softc_t *sc = v; ohci_soft_itd_t *sitd, *sidone, *sitdnext; ohci_soft_td_t *std, *sdone, *stdnext; usbd_xfer_handle xfer; diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index da3b8316fafe..cc49942a3c5d 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhci.c,v 1.132 2001/01/20 23:36:02 augustss Exp $ */ +/* $NetBSD: uhci.c,v 1.133 2001/01/21 02:39:52 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ /* @@ -242,7 +242,7 @@ Static void uhci_root_intr_done(usbd_xfer_handle); Static usbd_status uhci_open(usbd_pipe_handle); Static void uhci_poll(struct usbd_bus *); -Static void uhci_softintr(struct usbd_bus *); +Static void uhci_softintr(void *); Static usbd_status uhci_device_request(usbd_xfer_handle xfer); @@ -1220,9 +1220,9 @@ uhci_intr(void *arg) } void -uhci_softintr(struct usbd_bus *bus) +uhci_softintr(void *v) { - uhci_softc_t *sc = (uhci_softc_t *)bus; + uhci_softc_t *sc = v; uhci_intr_info_t *ii; DPRINTFN(10,("%s: uhci_softintr\n", USBDEVNAME(sc->sc_bus.bdev))); diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c index 9ee9c6fe3407..de47295fc009 100644 --- a/sys/dev/usb/usb.c +++ b/sys/dev/usb/usb.c @@ -1,4 +1,4 @@ -/* $NetBSD: usb.c,v 1.48 2000/12/13 04:05:14 augustss Exp $ */ +/* $NetBSD: usb.c,v 1.49 2001/01/21 02:39:53 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb.c,v 1.20 1999/11/17 22:33:46 n_hibma Exp $ */ /* @@ -215,6 +215,20 @@ USB_ATTACH(usb) ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue); +#ifdef USB_USE_SOFTINTR +#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS + /* XXX we should have our own level */ + sc->sc_bus->soft = softintr_establish(IPL_SOFTNET, + sc->sc_bus->methods->soft_intr, sc->sc_bus); + if (sc->sc_bus->soft == NULL) { + printf("%s: can't register softintr\n", USBDEVNAME(sc->sc_dev)); + sc->sc_dying = 1; + } +#else + callout_init(&sc->sc_bus->softi); +#endif +#endif + err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0, &sc->sc_port); if (!err) { @@ -664,9 +678,23 @@ usb_add_event(int type, struct usb_event *uep) splx(s); } void -usb_schedsoftintr(struct usbd_bus *bus) +usb_schedsoftintr(usbd_bus_handle bus) { +#ifdef USB_USE_SOFTINTR + if (bus->use_polling) { + bus->methods->soft_intr(bus); + } else { +#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS + softintr_schedule(bus->soft); +#else + if (!callout_pending(&bus->softi)) + callout_reset(&bus->softi, 0, bus->methods->soft_intr, + bus); +#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */ + } +#else bus->methods->soft_intr(bus); +#endif } #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -718,6 +746,17 @@ usb_detach(device_ptr_t self, int flags) usbd_finish(); +#ifdef USB_USE_SOFTINTR +#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS + if (sc->sc_bus->soft != NULL) { + softintr_disestablish(sc->sc_bus->soft); + sc->sc_bus->soft = NULL; + } +#else + callout_stop(&sc->sc_bus->softi); +#endif +#endif + ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev); usb_add_event(USB_EVENT_CTRLR_DETACH, &ue); diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h index da94b47259a0..8ba6286e4965 100644 --- a/sys/dev/usb/usb_port.h +++ b/sys/dev/usb/usb_port.h @@ -1,5 +1,5 @@ /* $OpenBSD: usb_port.h,v 1.18 2000/09/06 22:42:10 rahnds Exp $ */ -/* $NetBSD: usb_port.h,v 1.38 2001/01/11 06:33:51 augustss Exp $ */ +/* $NetBSD: usb_port.h,v 1.39 2001/01/21 02:39:53 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.21 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -39,6 +39,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _USB_PORT_H +#define _USB_PORT_H /* * Macro's to cope with the differences between operating systems. @@ -51,6 +53,8 @@ #include "opt_usbverbose.h" +/*#define USB_USE_SOFTINTR */ + #ifdef USB_DEBUG #define UKBD_DEBUG 1 #define UHID_DEBUG 1 @@ -499,3 +503,6 @@ __CONCAT(dname,_detach)(device_t self) #define logprintf printf #endif /* __FreeBSD__ */ + +#endif /* _USB_PORT_H */ + diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 20cdccac8c51..185fa2f82282 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.c,v 1.78 2001/01/19 04:01:10 augustss Exp $ */ +/* $NetBSD: usbdi.c,v 1.79 2001/01/21 02:39:53 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */ /* @@ -299,12 +299,15 @@ usbd_transfer(usbd_xfer_handle xfer) int i; usbd_bus_handle bus = pipe->device->bus; int to = xfer->timeout * 1000; + DPRINTFN(2,("usbd_transfer: polling\n")); for (i = 0; i < to; i += 10) { delay(10); bus->methods->do_poll(bus); if (xfer->done) break; } + DPRINTFN(2,("usbd_transfer: polling done =\n", + xfer->done)); /* XXX Is this right, what about the HC timeout? */ if (!xfer->done) { pipe->methods->abort(xfer); diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index e4884dc2d8a8..00212b79f42e 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.h,v 1.46 2001/01/18 20:28:23 jdolecek Exp $ */ +/* $NetBSD: usbdi.h,v 1.47 2001/01/21 02:39:53 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */ /* @@ -241,14 +241,11 @@ struct usb_attach_arg { int usbd_driver_load(module_t mod, int what, void *arg); #endif -/* - * XXX - * splusb MUST be the lowest level interrupt so that within USB callbacks - * the level can be raised the appropriate level. - * XXX Should probably use a softsplusb. - */ -/* XXX */ +/* XXX Perhaps USB should have its own levels? */ +#ifdef USB_USE_SOFTINTR +#define splusb splsoftnet +#else #define splusb splbio +#endif #define splhardusb splbio #define IPL_USB IPL_BIO -/* XXX */ diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index bcb7898944cb..92767018561f 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdivar.h,v 1.61 2001/01/18 20:28:23 jdolecek Exp $ */ +/* $NetBSD: usbdivar.h,v 1.62 2001/01/21 02:39:53 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */ /* @@ -55,7 +55,7 @@ struct usbd_endpoint { struct usbd_bus_methods { usbd_status (*open_pipe)(struct usbd_pipe *pipe); - void (*soft_intr)(struct usbd_bus *); + void (*soft_intr)(void *); void (*do_poll)(struct usbd_bus *); usbd_status (*allocm)(struct usbd_bus *, usb_dma_t *, u_int32_t bufsize); @@ -114,7 +114,15 @@ struct usbd_bus { #define USBREV_1_0 2 #define USBREV_1_1 3 #define USBREV_2_0 4 -#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1" } +#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" } + +#ifdef USB_USE_SOFTINTR +#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS + void *soft; /* soft interrupt cookie */ +#else + struct callout softi; +#endif +#endif #if defined(__NetBSD__) || defined(__OpenBSD__) bus_dma_tag_t dmatag; /* DMA tag */