summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>1999-08-23 21:00:08 +0000
committern_hibma <n_hibma@FreeBSD.org>1999-08-23 21:00:08 +0000
commita9f46ba20de99dba4788fc06cb53f20217ad205f (patch)
treefad42e68251d78c562cc886c1e45c53f0c5aca60 /sys/dev
parent663cbe4fc26065f7af7d10faaee492a626156145 (diff)
downloadFreeBSD-src-a9f46ba20de99dba4788fc06cb53f20217ad205f.zip
FreeBSD-src-a9f46ba20de99dba4788fc06cb53f20217ad205f.tar.gz
Reset the UHCI controller when the device comes back from suspend.
This should be replaced by proper support for suspend one day (global suspend). Submitted-by: Christopher Masto <chris@netmonger.net>
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/uhci.c23
-rw-r--r--sys/dev/usb/uhci_pci.c39
-rw-r--r--sys/dev/usb/uhcivar.h6
3 files changed, 46 insertions, 22 deletions
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 5c333b8..dfedf52 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -305,8 +305,7 @@ uhci_init(uhci_softc_t *sc)
return(err);
sc->sc_pframes = KERNADDR(&dma);
- UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
- UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&dma)); /* set frame list address */
+ sc->sc_flbase = DMAADDR(&dma);
err = uhci_init_framelist(sc);
if (err) {
@@ -322,10 +321,7 @@ uhci_init(uhci_softc_t *sc)
sc->sc_bus.do_poll = uhci_poll;
DPRINTFN(1,("uhci_init: enabling\n"));
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
- UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
-
- return(uhci_run(sc, 1)); /* and here we go... */
+ return uhci_reset(sc);
}
usbd_status
@@ -424,12 +420,10 @@ uhci_busreset(sc)
UHCICMD(sc, 0); /* do nothing */
}
-#if 0
-void
-uhci_reset(priv)
- void *priv;
+usbd_status
+uhci_reset(sc)
+ uhci_softc_t *sc;
{
- uhci_softc_t *sc = priv;
int n;
/* Reset the host controller */
@@ -442,8 +436,13 @@ uhci_reset(priv)
if (n >= UHCI_RESET_TIMEOUT)
printf("%s: controller did not reset\n",
USBDEVNAME(sc->sc_bus.bdev));
+ UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
+ UWRITE4(sc, UHCI_FLBASEADDR, sc->sc_flbase); /* set frame list address */
+ UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
+ UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
+
+ return(uhci_run(sc, 1)); /* and here we go... */
}
-#endif
usbd_status
uhci_run(sc, run)
diff --git a/sys/dev/usb/uhci_pci.c b/sys/dev/usb/uhci_pci.c
index 3183eda..83bca9b 100644
--- a/sys/dev/usb/uhci_pci.c
+++ b/sys/dev/usb/uhci_pci.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -35,6 +33,8 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
*/
/* Universal Host Controller Interface
@@ -58,11 +58,12 @@
#include <sys/proc.h>
#include <sys/queue.h>
#if defined(__FreeBSD__)
-#include <machine/bus_pio.h>
-#endif
+#include <sys/bus.h>
+
#include <machine/bus.h>
-#include <sys/rman.h>
#include <machine/resource.h>
+#include <sys/rman.h>
+#endif
#include <pci/pcivar.h>
#include <pci/pcireg.h>
@@ -90,6 +91,29 @@ static const char *uhci_device_generic = "UHCI (generic) USB controller";
#define PCI_UHCI_BASE_REG 0x20
+static int
+uhci_pci_suspend(device_t self)
+{
+ uhci_softc_t *sc;
+
+ sc = device_get_softc(self);
+ bus_generic_suspend(self);
+
+ return 0;
+}
+
+static int
+uhci_pci_resume(device_t self)
+{
+ uhci_softc_t *sc;
+
+ sc = device_get_softc(self);
+ uhci_reset(sc);
+ bus_generic_resume(self);
+
+ return 0;
+}
+
static const char *
uhci_pci_match(device_t self)
{
@@ -148,7 +172,8 @@ uhci_pci_attach(device_t self)
sc->iot = rman_get_bustag(res);
sc->ioh = rman_get_bushandle(res);
- bus_space_write_2(sc->iot, sc->ioh, UHCI_INTR, 0); /* disable interrupts */
+ /* disable interrupts */
+ bus_space_write_2(sc->iot, sc->ioh, UHCI_INTR, 0);
rid = 0;
res = bus_alloc_resource(self, SYS_RES_IRQ, &rid, 0, ~0, 1,
@@ -247,6 +272,8 @@ static device_method_t uhci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uhci_pci_probe),
DEVMETHOD(device_attach, uhci_pci_attach),
+ DEVMETHOD(device_suspend, uhci_pci_suspend),
+ DEVMETHOD(device_resume, uhci_pci_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h
index 9af98b7..266bced 100644
--- a/sys/dev/usb/uhcivar.h
+++ b/sys/dev/usb/uhcivar.h
@@ -133,6 +133,7 @@ typedef struct uhci_softc {
#endif
uhci_physaddr_t *sc_pframes;
+ vm_offset_t sc_flbase;
struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT];
uhci_soft_qh_t *sc_ctl_start; /* dummy QH for control */
@@ -168,7 +169,4 @@ typedef struct uhci_softc {
usbd_status uhci_init __P((uhci_softc_t *));
int uhci_intr __P((void *));
-#if 0
-void uhci_reset __P((void *));
-#endif
-
+usbd_status uhci_reset __P((uhci_softc_t *));
OpenPOWER on IntegriCloud