diff options
author | joe <joe@FreeBSD.org> | 2002-01-26 12:04:22 +0000 |
---|---|---|
committer | joe <joe@FreeBSD.org> | 2002-01-26 12:04:22 +0000 |
commit | 102fdc4f0a532992ab09937febc22df37cc7b579 (patch) | |
tree | 8222196b5e2a8f7ebfce2834d2eb9a1be1b2cbaf /sys/dev | |
parent | cc5a433a5e8a9fedce126874b6188478b8453575 (diff) | |
download | FreeBSD-src-102fdc4f0a532992ab09937febc22df37cc7b579.zip FreeBSD-src-102fdc4f0a532992ab09937febc22df37cc7b579.tar.gz |
Merge from NetBSD:
ohci.c: revision 1.72 and 1.73
ohcivar.h: revision 1.19 and 1.20
uhci.c: revision 1.85
usbdi.h: a small part of revision 1.40
usbdivar.h: revision 1.47
Relevant commit messages from NetBSD are:
date: 2000/02/22 11:30:54; author: augustss; state: Exp;
Prepare a little for having USB interrupt processing done
outside the hard interrupt level (in a thread or a softintr).
No real soft processing done yet.
----------------------------
date: 2000/02/01 05:42:53; author: augustss; state: Exp;
Put some #ifdefs around power and shutdown hooks.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/ohci.c | 60 | ||||
-rw-r--r-- | sys/dev/usb/ohcivar.h | 8 | ||||
-rw-r--r-- | sys/dev/usb/uhci.c | 27 | ||||
-rw-r--r-- | sys/dev/usb/usbdi.h | 3 | ||||
-rw-r--r-- | sys/dev/usb/usbdivar.h | 5 |
5 files changed, 78 insertions, 25 deletions
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index f0ad030..84ec03c 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.71 2000/02/01 05:42:52 augustss Exp $ */ +/* $NetBSD: ohci.c,v 1.73 2000/02/22 22:59:49 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -135,11 +135,10 @@ Static void ohci_power(int, void *); #endif Static usbd_status ohci_open(usbd_pipe_handle); Static void ohci_poll(struct usbd_bus *); +Static void ohci_softintr __P((struct usbd_bus *)); Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle); Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle); -Static void ohci_process_done(ohci_softc_t *, - ohci_physaddr_t); Static usbd_status ohci_device_request(usbd_xfer_handle xfer); Static void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *); @@ -268,6 +267,7 @@ struct ohci_pipe { Static struct usbd_bus_methods ohci_bus_methods = { ohci_open, + ohci_softintr, ohci_poll, ohci_allocm, ohci_freem, @@ -669,6 +669,7 @@ ohci_init(sc) SIMPLEQ_INIT(&sc->sc_free_xfers); + /* XXX determine alignment by R/W */ /* Allocate the HCCA area. */ err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE, OHCI_HCCA_ALIGN, &sc->sc_hccadma); @@ -730,6 +731,17 @@ ohci_init(sc) sc->sc_hcca->hcca_interrupt_table[revbits[i]] = htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr); +#ifdef OHCI_DEBUG + if (ohcidebug > 15) { + for (i = 0; i < OHCI_NO_EDS; i++) { + printf("ed#%d ", i); + ohci_dump_ed(sc->sc_eds[i]); + } + printf("iso "); + ohci_dump_ed(sc->sc_isoc_head); + } +#endif + /* Determine in what context we are running. */ ctl = OREAD4(sc, OHCI_CONTROL); if (ctl & OHCI_IR) { @@ -1036,7 +1048,6 @@ ohci_intr1(sc) * HcInterruptStatus should be checked to determine its cause. */ if (done != 0) { - sc->sc_hcca->hcca_done_head = 0; if (done & ~OHCI_DONE_INTRS) intrs = OHCI_WDH; if (done & OHCI_DONE_INTRS) { @@ -1062,7 +1073,7 @@ ohci_intr1(sc) sc->sc_bus.intr_context++; sc->sc_bus.no_intrs++; - DPRINTFN(7, ("ohci_intr: sc=%p intrs=%x(%x) eintr=%x\n", + DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n", sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), (u_int)eintrs)); @@ -1072,7 +1083,21 @@ ohci_intr1(sc) intrs &= ~OHCI_SO; } if (eintrs & OHCI_WDH) { - ohci_process_done(sc, done); + done &= ~OHCI_DONE_INTRS; + if (sc->sc_done == 0) + sc->sc_done = done; + else { + /* Tack on at the end of sc_done. */ + ohci_physaddr_t ldone; + ohci_soft_td_t *std; + + for (ldone = sc->sc_done; ldone != 0; + ldone = le32toh(std->td.td_nexttd)) + std = ohci_hash_find_td(sc, ldone); + std->td.td_nexttd = le32toh(done); + } + sc->sc_hcca->hcca_done_head = 0; + usb_schedsoftintr(&sc->sc_bus); intrs &= ~OHCI_WDH; } if (eintrs & OHCI_RD) { @@ -1142,13 +1167,21 @@ char *ohci_cc_strs[] = { #endif void -ohci_process_done(sc, done) - ohci_softc_t *sc; - ohci_physaddr_t done; +ohci_softintr(bus) + struct usbd_bus *bus; { + ohci_softc_t *sc = (ohci_softc_t *)bus; + ohci_physaddr_t done; ohci_soft_td_t *std, *sdone, *stdnext; usbd_xfer_handle xfer; - int len, cc; + int len, cc, s; + + sc->sc_bus.intr_context++; + + s = splhardusb(); + done = sc->sc_done; + sc->sc_done = 0; + splx(s); DPRINTFN(10,("ohci_process_done: done=0x%08lx\n", (u_long)done)); @@ -1258,6 +1291,8 @@ ohci_process_done(sc, done) usb_transfer_complete(xfer); } } + + sc->sc_bus.intr_context--; } void @@ -1709,8 +1744,8 @@ void ohci_dump_ed(sed) ohci_soft_ed_t *sed; { - DPRINTF(("ED(%p) at %08lx: addr=%d endpt=%d maxp=%d %b\n" - "tailp=0x%8b headp=0x%8b nexted=0x%08lx\n", + DPRINTF(("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d %b\ntailp=0x%08lx " + "headflags=%b headp=0x%08lx nexted=0x%08lx\n", sed, (u_long)sed->physaddr, OHCI_ED_GET_FA(le32toh(sed->ed.ed_flags)), OHCI_ED_GET_EN(le32toh(sed->ed.ed_flags)), @@ -1721,6 +1756,7 @@ ohci_dump_ed(sed) "\20\1BIT1\2BIT2", (int)(uintptr_t)le32toh(sed->ed.ed_headp), "\20\1HALT\2CARRY", + (u_long)le32toh(sed->ed.ed_headp), (u_long)le32toh(sed->ed.ed_nexted))); } #endif diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index adf68a7..b72ccba 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ohcivar.h,v 1.18 2000/01/18 20:11:00 augustss Exp $ */ +/* $NetBSD: ohcivar.h,v 1.20 2000/02/22 11:30:55 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -111,11 +111,13 @@ typedef struct ohci_softc { usbd_xfer_handle sc_intrxfer; + ohci_physaddr_t sc_done; + char sc_vendor[16]; int sc_id_vendor; -#if defined(__NetBSD__) - void *sc_powerhook; +#if defined(__NetBSD__) || defined(__OpenBSD__) + void *sc_powerhook; /* cookie from power hook */ void *sc_shutdownhook; /* cookie from shutdown hook */ #endif diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index df19aac..06cbcec 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhci.c,v 1.84 2000/01/28 00:44:27 augustss Exp $ */ +/* $NetBSD: uhci.c,v 1.85 2000/02/22 11:30:55 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -243,6 +243,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 __P((struct usbd_bus *)); Static usbd_status uhci_device_request(usbd_xfer_handle xfer); @@ -287,6 +288,7 @@ void uhci_dump(void); struct usbd_bus_methods uhci_bus_methods = { uhci_open, + uhci_softintr, uhci_poll, uhci_allocm, uhci_freem, @@ -1077,7 +1079,6 @@ uhci_intr(void *arg) uhci_softc_t *sc = arg; int status; int ack; - uhci_intr_info_t *ii; /* * It can happen that an interrupt will be delivered to @@ -1146,8 +1147,24 @@ uhci_intr(void *arg) return (0); } - sc->sc_bus.intr_context++; sc->sc_bus.no_intrs++; + usb_schedsoftintr(&sc->sc_bus); + + DPRINTFN(10, ("%s: uhci_intr: exit\n", USBDEVNAME(sc->sc_bus.bdev))); + + return (1); +} + +void +uhci_softintr(bus) + struct usbd_bus *bus; +{ + uhci_softc_t *sc = (uhci_softc_t *)bus; + uhci_intr_info_t *ii; + + DPRINTFN(10,("%s: uhci_softintr\n", USBDEVNAME(sc->sc_bus.bdev))); + + sc->sc_bus.intr_context++; /* * Interrupts on UHCI really suck. When the host controller @@ -1163,11 +1180,7 @@ uhci_intr(void *arg) LIST_FOREACH(ii, &sc->sc_intrhead, list) uhci_check_intr(sc, ii); - DPRINTFN(10, ("%s: uhci_intr: exit\n", USBDEVNAME(sc->sc_bus.bdev))); - sc->sc_bus.intr_context--; - - return (1); } /* Check for an interrupt. */ diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index a66fec7..bb5bfbf 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.h,v 1.39 2000/01/19 00:23:59 augustss Exp $ */ +/* $NetBSD: usbdi.h,v 1.40 2000/02/02 07:34:00 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -256,5 +256,6 @@ int usbd_driver_load(module_t mod, int what, void *arg); */ /* XXX */ #define splusb splbio +#define splhardusb splbio #define IPL_USB IPL_BIO /* XXX */ diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index 9166d72..6057e19 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdivar.h,v 1.46 2000/01/19 01:16:40 augustss Exp $ */ +/* $NetBSD: usbdivar.h,v 1.47 2000/02/22 11:30:56 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -51,6 +51,7 @@ struct usbd_endpoint { struct usbd_bus_methods { usbd_status (*open_pipe)(struct usbd_pipe *pipe); + void (*soft_intr)__P((struct usbd_bus *)); void (*do_poll)(struct usbd_bus *); usbd_status (*allocm)(struct usbd_bus *, usb_dma_t *, u_int32_t bufsize); @@ -232,8 +233,8 @@ void usb_transfer_complete(usbd_xfer_handle xfer); void usb_disconnect_port(struct usbd_port *up, device_ptr_t); /* Routines from usb.c */ -int usb_bus_count(void); void usb_needs_explore(usbd_bus_handle); +void usb_schedsoftintr __P((struct usbd_bus *)); #ifdef DIAGNOSTIC #define SPLUSBCHECK \ |