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 my compiles-but-un-runtime-tested port ...
details: https://anonhg.NetBSD.org/src/rev/92c20e9b9f23
branches: jmcneill-usbmp
changeset: 771780:92c20e9b9f23
user: mrg <mrg%NetBSD.org@localhost>
date: Tue Dec 06 05:06:50 2011 +0000
description:
my compiles-but-un-runtime-tested port of uhci to usbmp branch.
based upon the ohci and ehci changes.
diffstat:
sys/dev/usb/uhci.c | 292 +++++++++++++++++++++++++++++++------------------
sys/dev/usb/uhcivar.h | 6 +-
2 files changed, 189 insertions(+), 109 deletions(-)
diffs (truncated from 1038 to 300 lines):
diff -r ebc84d7bd231 -r 92c20e9b9f23 sys/dev/usb/uhci.c
--- a/sys/dev/usb/uhci.c Tue Dec 06 05:05:30 2011 +0000
+++ b/sys/dev/usb/uhci.c Tue Dec 06 05:06:50 2011 +0000
@@ -1,13 +1,14 @@
-/* $NetBSD: uhci.c,v 1.240.6.1 2011/12/04 13:23:17 jmcneill Exp $ */
+/* $NetBSD: uhci.c,v 1.240.6.2 2011/12/06 05:06:50 mrg Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
- * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 2004, 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.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,14 +43,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.1 2011/12/04 13:23:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.2 2011/12/06 05:06:50 mrg Exp $");
#include "opt_usb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/malloc.h>
+#include <sys/kmem.h>
#include <sys/device.h>
#include <sys/select.h>
#include <sys/extent.h>
@@ -171,6 +172,8 @@
Static usbd_xfer_handle uhci_allocx(struct usbd_bus *);
Static void uhci_freex(struct usbd_bus *, usbd_xfer_handle);
+Static void uhci_get_locks(struct usbd_bus *, kmutex_t **,
+ kmutex_t **);
Static usbd_status uhci_device_ctrl_transfer(usbd_xfer_handle);
Static usbd_status uhci_device_ctrl_start(usbd_xfer_handle);
@@ -288,7 +291,7 @@
uhci_freem,
uhci_allocx,
uhci_freex,
- NULL, /* uhci_get_locks */
+ uhci_get_locks,
};
const struct usbd_pipe_methods uhci_root_ctrl_methods = {
@@ -523,7 +526,11 @@
SIMPLEQ_INIT(&sc->sc_free_xfers);
- callout_init(&sc->sc_poll_handle, 0);
+ callout_init(&sc->sc_poll_handle, 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, "uhciab");
/* Set up the bus struct. */
sc->sc_bus.methods = &uhci_bus_methods;
@@ -580,12 +587,17 @@
if (xfer == NULL)
break;
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
- free(xfer, M_USB);
+ kmem_free(xfer, sizeof(struct uhci_xfer));
}
callout_halt(&sc->sc_poll_handle, NULL);
callout_destroy(&sc->sc_poll_handle);
+ cv_destroy(&sc->sc_softwake_cv);
+
+ mutex_destroy(&sc->sc_lock);
+ mutex_destroy(&sc->sc_intr_lock);
+
/* XXX free other data structures XXX */
return (rv);
@@ -609,18 +621,19 @@
if (n > 16) {
u_int32_t i;
uhci_soft_td_t **stds;
+
DPRINTF(("uhci_allocm: get %d TDs\n", n));
- stds = malloc(sizeof(uhci_soft_td_t *) * n, M_TEMP,
- M_WAITOK|M_ZERO);
- for(i=0; i < n; i++)
+ stds = kmem_alloc(sizeof(uhci_soft_td_t *) * n, KM_SLEEP);
+ if (!stds)
+ return USBD_NOMEM;
+ for(i = 0; i < n; i++)
stds[i] = uhci_alloc_std(sc);
- for(i=0; i < n; i++)
+ for(i = 0; i < n; i++)
if (stds[i] != NULL)
uhci_free_std(sc, stds[i]);
- free(stds, M_TEMP);
+ kmem_free(stds, sizeof(uhci_soft_td_t *) * n);
}
-
status = usb_allocmem(&sc->sc_bus, size, 0, dma);
if (status == USBD_NOMEM)
status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size);
@@ -654,7 +667,7 @@
}
#endif
} else {
- xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT);
+ xfer = kmem_alloc(sizeof(struct uhci_xfer), KM_SLEEP);
}
if (xfer != NULL) {
memset(xfer, 0, sizeof (struct uhci_xfer));
@@ -685,6 +698,16 @@
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
+Static void
+uhci_get_locks(struct usbd_bus *bus, kmutex_t **intr, kmutex_t **thread)
+{
+ struct uhci_softc *sc = bus->hci_private;
+
+ *intr = &sc->sc_intr_lock;
+ *thread = &sc->sc_lock;
+}
+
+
/*
* Handle suspend/resume.
*
@@ -697,9 +720,8 @@
{
uhci_softc_t *sc = device_private(dv);
int cmd;
- int s;
-
- s = splhardusb();
+
+ mutex_spin_enter(&sc->sc_intr_lock);
cmd = UREAD2(sc, UHCI_CMD);
sc->sc_bus.use_polling++;
@@ -732,7 +754,7 @@
#endif
sc->sc_suspend = PWR_RESUME;
- splx(s);
+ mutex_spin_exit(&sc->sc_intr_lock);
return true;
}
@@ -742,9 +764,8 @@
{
uhci_softc_t *sc = device_private(dv);
int cmd;
- int s;
-
- s = splhardusb();
+
+ mutex_spin_enter(&sc->sc_intr_lock);
cmd = UREAD2(sc, UHCI_CMD);
@@ -770,7 +791,7 @@
usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
sc->sc_bus.use_polling--;
- splx(s);
+ mutex_spin_exit(&sc->sc_intr_lock);
return true;
}
@@ -992,7 +1013,6 @@
usbd_xfer_handle xfer = addr;
usbd_pipe_handle pipe = xfer->pipe;
uhci_softc_t *sc;
- int s;
u_char *p;
DPRINTFN(20, ("uhci_poll_hub\n"));
@@ -1014,11 +1034,11 @@
xfer->actlen = 1;
xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
+ mutex_enter(&sc->sc_lock);
xfer->device->bus->intr_context++;
usb_transfer_complete(xfer);
xfer->device->bus->intr_context--;
- splx(s);
+ mutex_exit(&sc->sc_lock);
}
void
@@ -1269,18 +1289,25 @@
uhci_intr(void *arg)
{
uhci_softc_t *sc = arg;
+ int ret = 0;
+
+ mutex_spin_enter(&sc->sc_intr_lock);
if (sc->sc_dying || !device_has_power(sc->sc_dev))
- return (0);
+ goto done;
if (sc->sc_bus.use_polling || UREAD2(sc, UHCI_INTR) == 0) {
#ifdef DIAGNOSTIC
DPRINTFN(16, ("uhci_intr: ignored interrupt while polling\n"));
#endif
- return (0);
+ goto done;
}
- return (uhci_intr1(sc));
+ ret = uhci_intr1(sc);
+
+ done:
+ mutex_spin_exit(&sc->sc_intr_lock);
+ return ret;
}
int
@@ -1296,6 +1323,8 @@
}
#endif
+ KASSERT(mutex_owned(&sc->sc_lock));
+
status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
if (status == 0) /* The interrupt was not for us. */
return (0);
@@ -1365,6 +1394,8 @@
DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_xname(sc->sc_dev),
sc->sc_bus.intr_context));
+ mutex_enter(&sc->sc_lock);
+
sc->sc_bus.intr_context++;
/*
@@ -1383,14 +1414,14 @@
uhci_check_intr(sc, ii);
}
-#ifdef USB_USE_SOFTINTR
if (sc->sc_softwake) {
sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
+ cv_broadcast(&sc->sc_softwake_cv);
}
-#endif /* USB_USE_SOFTINTR */
sc->sc_bus.intr_context--;
+
+ mutex_exit(&sc->sc_lock);
}
/* Check for an interrupt. */
@@ -1485,6 +1516,7 @@
DPRINTFN(12, ("uhci_idone: ii=%p\n", ii));
#ifdef DIAGNOSTIC
{
+ /* XXX SMP? */
int s = splhigh();
if (ii->isdone) {
splx(s);
@@ -1631,13 +1663,10 @@
uhci_timeout_task(void *addr)
{
usbd_xfer_handle xfer = addr;
- int s;
DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer));
- s = splusb();
uhci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
}
/*
@@ -1652,6 +1681,8 @@
int timo = xfer->timeout;
uhci_intr_info_t *ii;
+ mutex_enter(&sc->sc_lock);
+
DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
xfer->status = USBD_IN_PROGRESS;
Home |
Main Index |
Thread Index |
Old Index