Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/jmcneill-usbmp]: src/sys/dev/usb adapt ohci, from mrg with some changes ...
details: https://anonhg.NetBSD.org/src/rev/e58c7e324bef
branches: jmcneill-usbmp
changeset: 771766:e58c7e324bef
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Dec 04 21:02:27 2011 +0000
description:
adapt ohci, from mrg with some changes by me
diffstat:
sys/dev/usb/ohci.c | 355 ++++++++++++++++++++++++++++++-------------------
sys/dev/usb/ohcivar.h | 9 +-
2 files changed, 225 insertions(+), 139 deletions(-)
diffs (truncated from 1224 to 300 lines):
diff -r b2fe66350ed9 -r e58c7e324bef sys/dev/usb/ohci.c
--- a/sys/dev/usb/ohci.c Sun Dec 04 19:22:56 2011 +0000
+++ b/sys/dev/usb/ohci.c Sun Dec 04 21:02:27 2011 +0000
@@ -1,13 +1,14 @@
-/* $NetBSD: ohci.c,v 1.218.6.1 2011/12/04 13:23:16 jmcneill Exp $ */
+/* $NetBSD: ohci.c,v 1.218.6.2 2011/12/04 21:02:27 jmcneill Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
- * Copyright (c) 1998, 2004, 2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 2004, 2005, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Lennart Augustsson (lennart%augustsson.net@localhost) at
- * Carlstedt Research & Technology.
+ * Carlstedt Research & Technology, Jared D. McNeill (jmcneill%invisible.ca@localhost)
+ * and Matthew R. Green.
* This code is derived from software contributed to The NetBSD Foundation
* by Charles M. Hannum.
*
@@ -41,13 +42,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.1 2011/12/04 13:23:16 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.2 2011/12/04 21:02:27 jmcneill Exp $");
#include "opt_usb.h"
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/malloc.h>
+#include <sys/kmem.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/select.h>
@@ -113,6 +114,7 @@
Static void ohci_softintr(void *);
Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
+Static void ohci_rhsc_softint(void *arg);
Static usbd_status ohci_device_request(usbd_xfer_handle xfer);
Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *,
@@ -134,6 +136,8 @@
Static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
+Static void ohci_get_locks(struct usbd_bus *, kmutex_t **,
+ kmutex_t **);
Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
@@ -274,7 +278,7 @@
ohci_freem,
ohci_allocx,
ohci_freex,
- NULL, /* ohci_get_locks */
+ ohci_get_locks,
};
Static const struct usbd_pipe_methods ohci_root_ctrl_methods = {
@@ -371,11 +375,18 @@
usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
callout_destroy(&sc->sc_tmo_rhsc);
+ softint_disestablish(sc->sc_rhsc_si);
+
+ cv_destroy(&sc->sc_softwake_cv);
+
+ mutex_destroy(&sc->sc_lock);
+ mutex_destroy(&sc->sc_intr_lock);
+
if (sc->sc_hcca != NULL)
usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
while((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) {
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
- free(xfer, M_USB);
+ kmem_free(xfer, sizeof(struct ohci_xfer));
}
return (rv);
@@ -426,7 +437,6 @@
usbd_status err;
int i, offs;
usb_dma_t dma;
- int s;
if (sc->sc_freetds == NULL) {
DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
@@ -434,7 +444,6 @@
OHCI_TD_ALIGN, &dma);
if (err)
return (NULL);
- s = splusb();
for(i = 0; i < OHCI_STD_CHUNK; i++) {
offs = i * OHCI_STD_SIZE;
std = KERNADDR(&dma, offs);
@@ -444,17 +453,14 @@
std->nexttd = sc->sc_freetds;
sc->sc_freetds = std;
}
- splx(s);
}
- s = splusb();
std = sc->sc_freetds;
sc->sc_freetds = std->nexttd;
memset(&std->td, 0, sizeof(ohci_td_t));
std->nexttd = NULL;
std->xfer = NULL;
ohci_hash_add_td(sc, std);
- splx(s);
return (std);
}
@@ -462,13 +468,10 @@
void
ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std)
{
- int s;
-
- s = splusb();
+
ohci_hash_rem_td(sc, std);
std->nexttd = sc->sc_freetds;
sc->sc_freetds = std;
- splx(s);
}
usbd_status
@@ -485,6 +488,8 @@
DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
+ KASSERT(mutex_owned(&sc->sc_lock));
+
len = alen;
cur = sp;
dataphys = DMAADDR(dma, 0);
@@ -590,7 +595,7 @@
{
ohci_soft_itd_t *sitd;
usbd_status err;
- int i, s, offs;
+ int i, offs;
usb_dma_t dma;
if (sc->sc_freeitds == NULL) {
@@ -599,7 +604,6 @@
OHCI_ITD_ALIGN, &dma);
if (err)
return (NULL);
- s = splusb();
for(i = 0; i < OHCI_SITD_CHUNK; i++) {
offs = i * OHCI_SITD_SIZE;
sitd = KERNADDR(&dma, offs);
@@ -609,17 +613,14 @@
sitd->nextitd = sc->sc_freeitds;
sc->sc_freeitds = sitd;
}
- splx(s);
}
- s = splusb();
sitd = sc->sc_freeitds;
sc->sc_freeitds = sitd->nextitd;
memset(&sitd->itd, 0, sizeof(ohci_itd_t));
sitd->nextitd = NULL;
sitd->xfer = NULL;
ohci_hash_add_itd(sc, sitd);
- splx(s);
#ifdef DIAGNOSTIC
sitd->isdone = 0;
@@ -631,7 +632,6 @@
void
ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
{
- int s;
DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
@@ -644,11 +644,9 @@
sitd->isdone = 0;
#endif
- s = splusb();
ohci_hash_rem_itd(sc, sitd);
sitd->nextitd = sc->sc_freeitds;
sc->sc_freeitds = sitd;
- splx(s);
}
usbd_status
@@ -663,7 +661,14 @@
aprint_normal_dev(sc->sc_dev, "");
sc->sc_hcca = NULL;
- callout_init(&sc->sc_tmo_rhsc, 0);
+ callout_init(&sc->sc_tmo_rhsc, CALLOUT_MPSAFE);
+
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
+ mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
+ cv_init(&sc->sc_softwake_cv, "ohciab");
+
+ sc->sc_rhsc_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
+ ohci_rhsc_softint, sc);
for (i = 0; i < OHCI_HASH_SIZE; i++)
LIST_INIT(&sc->sc_hash_tds[i]);
@@ -959,7 +964,7 @@
}
#endif
} else {
- xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT);
+ xfer = kmem_alloc(sizeof(struct ohci_xfer), KM_SLEEP);
}
if (xfer != NULL) {
memset(xfer, 0, sizeof (struct ohci_xfer));
@@ -985,6 +990,15 @@
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
+Static void
+ohci_get_locks(struct usbd_bus *bus, kmutex_t **intr, kmutex_t **thread)
+{
+ struct ohci_softc *sc = bus->hci_private;
+
+ *intr = &sc->sc_intr_lock;
+ *thread = &sc->sc_lock;
+}
+
/*
* Shut down the controller when the system is going down.
*/
@@ -1003,10 +1017,11 @@
{
ohci_softc_t *sc = device_private(dv);
uint32_t ctl;
- int s;
-
- s = splhardusb();
+
+ mutex_spin_enter(&sc->sc_intr_lock);
sc->sc_bus.use_polling++;
+ mutex_spin_exit(&sc->sc_intr_lock);
+
/* Some broken BIOSes do not recover these values */
OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
OWRITE4(sc, OHCI_CONTROL_HEAD_ED,
@@ -1027,8 +1042,10 @@
OWRITE4(sc, OHCI_CONTROL, ctl);
usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
sc->sc_control = sc->sc_intre = 0;
+
+ mutex_spin_enter(&sc->sc_intr_lock);
sc->sc_bus.use_polling--;
- splx(s);
+ mutex_spin_exit(&sc->sc_intr_lock);
return true;
}
@@ -1038,10 +1055,11 @@
{
ohci_softc_t *sc = device_private(dv);
uint32_t ctl;
- int s;
-
- s = splhardusb();
+
+ mutex_spin_enter(&sc->sc_intr_lock);
sc->sc_bus.use_polling++;
+ mutex_spin_exit(&sc->sc_intr_lock);
+
ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
if (sc->sc_control == 0) {
/*
@@ -1055,8 +1073,10 @@
ctl |= OHCI_HCFS_SUSPEND;
OWRITE4(sc, OHCI_CONTROL, ctl);
usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
+
+ mutex_spin_enter(&sc->sc_intr_lock);
sc->sc_bus.use_polling--;
- splx(s);
+ mutex_spin_exit(&sc->sc_intr_lock);
return true;
}
@@ -1108,10 +1128,16 @@
ohci_intr(void *p)
{
ohci_softc_t *sc = p;
-
- if (sc == NULL || sc->sc_dying || !device_has_power(sc->sc_dev))
+ int ret = 0;
+
+ if (sc == NULL)
Home |
Main Index |
Thread Index |
Old Index