summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjoe <joe@FreeBSD.org>2002-01-26 12:04:22 +0000
committerjoe <joe@FreeBSD.org>2002-01-26 12:04:22 +0000
commit102fdc4f0a532992ab09937febc22df37cc7b579 (patch)
tree8222196b5e2a8f7ebfce2834d2eb9a1be1b2cbaf /sys
parentcc5a433a5e8a9fedce126874b6188478b8453575 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/dev/usb/ohci.c60
-rw-r--r--sys/dev/usb/ohcivar.h8
-rw-r--r--sys/dev/usb/uhci.c27
-rw-r--r--sys/dev/usb/usbdi.h3
-rw-r--r--sys/dev/usb/usbdivar.h5
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 \
OpenPOWER on IntegriCloud