summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2011-12-14 00:28:54 +0000
committerhselasky <hselasky@FreeBSD.org>2011-12-14 00:28:54 +0000
commit7076389cec83009f9046b6c6e2695fe340a63802 (patch)
tree56520f5d0635d8db6259b372fff280b4e6288da5 /sys
parent145914e3e7153161b6dd67fdcd58c7a8201845bc (diff)
downloadFreeBSD-src-7076389cec83009f9046b6c6e2695fe340a63802.zip
FreeBSD-src-7076389cec83009f9046b6c6e2695fe340a63802.tar.gz
Implement better support for USB controller suspend and resume.
This patch should remove the need for kldunload of USB controller drivers at suspend and kldload of USB controller drivers at resume. This patch also fixes some build issues in avr32dci.c MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/econa/ehci_ebus.c55
-rw-r--r--sys/arm/econa/ohci_ec.c8
-rw-r--r--sys/dev/usb/controller/at91dci.c29
-rw-r--r--sys/dev/usb/controller/at91dci.h2
-rw-r--r--sys/dev/usb/controller/at91dci_atmelarm.c26
-rw-r--r--sys/dev/usb/controller/atmegadci.c29
-rw-r--r--sys/dev/usb/controller/atmegadci.h2
-rw-r--r--sys/dev/usb/controller/atmegadci_atmelarm.c26
-rw-r--r--sys/dev/usb/controller/avr32dci.c86
-rw-r--r--sys/dev/usb/controller/avr32dci.h3
-rw-r--r--sys/dev/usb/controller/ehci.c252
-rw-r--r--sys/dev/usb/controller/ehci.h5
-rw-r--r--sys/dev/usb/controller/ehci_ixp4xx.c48
-rw-r--r--sys/dev/usb/controller/ehci_mv.c48
-rw-r--r--sys/dev/usb/controller/ehci_pci.c82
-rw-r--r--sys/dev/usb/controller/musb_otg.c29
-rw-r--r--sys/dev/usb/controller/musb_otg.h2
-rw-r--r--sys/dev/usb/controller/musb_otg_atmelarm.c26
-rw-r--r--sys/dev/usb/controller/ohci.c100
-rw-r--r--sys/dev/usb/controller/ohci.h4
-rw-r--r--sys/dev/usb/controller/ohci_atmelarm.c8
-rw-r--r--sys/dev/usb/controller/ohci_pci.c55
-rw-r--r--sys/dev/usb/controller/ohci_s3c24x0.c8
-rw-r--r--sys/dev/usb/controller/uhci.c56
-rw-r--r--sys/dev/usb/controller/uhci.h4
-rw-r--r--sys/dev/usb/controller/uhci_pci.c54
-rw-r--r--sys/dev/usb/controller/usb_controller.c247
-rw-r--r--sys/dev/usb/controller/uss820dci.c29
-rw-r--r--sys/dev/usb/controller/uss820dci.h2
-rw-r--r--sys/dev/usb/controller/uss820dci_atmelarm.c50
-rw-r--r--sys/dev/usb/controller/xhci_pci.c59
-rw-r--r--sys/dev/usb/usb_bus.h6
-rw-r--r--sys/dev/usb/usb_controller.h14
-rw-r--r--sys/dev/usb/usb_if.m10
-rw-r--r--sys/mips/atheros/ar71xx_ehci.c54
-rw-r--r--sys/mips/atheros/ar71xx_ohci.c8
-rw-r--r--sys/mips/cavium/usb/octusb.c29
-rw-r--r--sys/mips/cavium/usb/octusb.h2
-rw-r--r--sys/mips/cavium/usb/octusb_octeon.c25
-rw-r--r--sys/mips/rmi/xls_ehci.c58
-rw-r--r--sys/mips/rt305x/rt305x_dotg.c26
-rw-r--r--sys/modules/usb/Makefile6
-rw-r--r--sys/modules/usb/avr32dci/Makefile38
-rw-r--r--sys/powerpc/ps3/ehci_ps3.c9
-rw-r--r--sys/powerpc/ps3/ohci_ps3.c9
45 files changed, 796 insertions, 932 deletions
diff --git a/sys/arm/econa/ehci_ebus.c b/sys/arm/econa/ehci_ebus.c
index ee20148..4b72b7f 100644
--- a/sys/arm/econa/ehci_ebus.c
+++ b/sys/arm/econa/ehci_ebus.c
@@ -75,10 +75,6 @@ __FBSDID("$FreeBSD$");
static device_attach_t ehci_ebus_attach;
static device_detach_t ehci_ebus_detach;
-static device_shutdown_t ehci_ebus_shutdown;
-static device_suspend_t ehci_ebus_suspend;
-static device_resume_t ehci_ebus_resume;
-
static void *ih_err;
@@ -86,45 +82,6 @@ static void *ih_err;
#define USB_BRIDGE_INTR_MASK 0x214
static int
-ehci_ebus_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-ehci_ebus_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_ebus_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
-
- return (0);
-}
-
-static int
ehci_ebus_probe(device_t self)
{
@@ -277,17 +234,17 @@ static device_method_t ehci_methods[] = {
DEVMETHOD(device_probe, ehci_ebus_probe),
DEVMETHOD(device_attach, ehci_ebus_attach),
DEVMETHOD(device_detach, ehci_ebus_detach),
- DEVMETHOD(device_suspend, ehci_ebus_suspend),
- DEVMETHOD(device_resume, ehci_ebus_resume),
- DEVMETHOD(device_shutdown, ehci_ebus_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(ehci_softc_t),
+ .name = "ehci",
+ .methods = ehci_methods,
+ .size = sizeof(ehci_softc_t),
};
static devclass_t ehci_devclass;
diff --git a/sys/arm/econa/ohci_ec.c b/sys/arm/econa/ohci_ec.c
index ee44960..543aae1 100644
--- a/sys/arm/econa/ohci_ec.c
+++ b/sys/arm/econa/ohci_ec.c
@@ -220,15 +220,17 @@ static device_method_t ohci_methods[] = {
DEVMETHOD(device_probe, ohci_ec_probe),
DEVMETHOD(device_attach, ohci_ec_attach),
DEVMETHOD(device_detach, ohci_ec_detach),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_driver = {
- "ohci",
- ohci_methods,
- sizeof(struct ec_ohci_softc),
+ .name = "ohci",
+ .methods = ohci_methods,
+ .size = sizeof(struct ec_ohci_softc),
};
static devclass_t ohci_devclass;
diff --git a/sys/dev/usb/controller/at91dci.c b/sys/dev/usb/controller/at91dci.c
index f831115..d325812 100644
--- a/sys/dev/usb/controller/at91dci.c
+++ b/sys/dev/usb/controller/at91dci.c
@@ -1461,16 +1461,16 @@ at91dci_uninit(struct at91dci_softc *sc)
USB_BUS_UNLOCK(&sc->sc_bus);
}
-void
+static void
at91dci_suspend(struct at91dci_softc *sc)
{
- return;
+ /* TODO */
}
-void
+static void
at91dci_resume(struct at91dci_softc *sc)
{
- return;
+ /* TODO */
}
static void
@@ -2306,6 +2306,26 @@ at91dci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
}
}
+static void
+at91dci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct at91dci_softc *sc = AT9100_DCI_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ at91dci_suspend(sc);
+ break;
+ case USB_HW_POWER_SHUTDOWN:
+ at91dci_uninit(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ at91dci_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
struct usb_bus_methods at91dci_bus_methods =
{
.endpoint_init = &at91dci_ep_init,
@@ -2316,4 +2336,5 @@ struct usb_bus_methods at91dci_bus_methods =
.clear_stall = &at91dci_clear_stall,
.roothub_exec = &at91dci_roothub_exec,
.xfer_poll = &at91dci_do_poll,
+ .set_hw_power_sleep = &at91dci_set_hw_power_sleep,
};
diff --git a/sys/dev/usb/controller/at91dci.h b/sys/dev/usb/controller/at91dci.h
index a1603aa..b079eb5 100644
--- a/sys/dev/usb/controller/at91dci.h
+++ b/sys/dev/usb/controller/at91dci.h
@@ -235,8 +235,6 @@ struct at91dci_softc {
usb_error_t at91dci_init(struct at91dci_softc *sc);
void at91dci_uninit(struct at91dci_softc *sc);
-void at91dci_suspend(struct at91dci_softc *sc);
-void at91dci_resume(struct at91dci_softc *sc);
void at91dci_interrupt(struct at91dci_softc *sc);
void at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on);
diff --git a/sys/dev/usb/controller/at91dci_atmelarm.c b/sys/dev/usb/controller/at91dci_atmelarm.c
index 1e8e394..da9ba36 100644
--- a/sys/dev/usb/controller/at91dci_atmelarm.c
+++ b/sys/dev/usb/controller/at91dci_atmelarm.c
@@ -77,7 +77,6 @@ __FBSDID("$FreeBSD$");
static device_probe_t at91_udp_probe;
static device_attach_t at91_udp_attach;
static device_detach_t at91_udp_detach;
-static device_shutdown_t at91_udp_shutdown;
struct at91_udp_softc {
struct at91dci_softc sc_dci; /* must be first */
@@ -324,35 +323,22 @@ at91_udp_detach(device_t dev)
return (0);
}
-static int
-at91_udp_shutdown(device_t dev)
-{
- struct at91_udp_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- at91dci_uninit(&sc->sc_dci);
-
- return (0);
-}
-
static device_method_t at91_udp_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at91_udp_probe),
DEVMETHOD(device_attach, at91_udp_attach),
DEVMETHOD(device_detach, at91_udp_detach),
- DEVMETHOD(device_shutdown, at91_udp_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t at91_udp_driver = {
- "at91_udp",
- at91_udp_methods,
- sizeof(struct at91_udp_softc),
+ .name = "at91_udp",
+ .methods = at91_udp_methods,
+ .size = sizeof(struct at91_udp_softc),
};
static devclass_t at91_udp_devclass;
diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c
index ad53fc3..7db3bdb 100644
--- a/sys/dev/usb/controller/atmegadci.c
+++ b/sys/dev/usb/controller/atmegadci.c
@@ -1352,16 +1352,16 @@ atmegadci_uninit(struct atmegadci_softc *sc)
USB_BUS_UNLOCK(&sc->sc_bus);
}
-void
+static void
atmegadci_suspend(struct atmegadci_softc *sc)
{
- return;
+ /* TODO */
}
-void
+static void
atmegadci_resume(struct atmegadci_softc *sc)
{
- return;
+ /* TODO */
}
static void
@@ -2126,6 +2126,26 @@ atmegadci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc
}
}
+static void
+atmegadci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct atmegadci_softc *sc = ATMEGA_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ atmegadci_suspend(sc);
+ break;
+ case USB_HW_POWER_SHUTDOWN:
+ atmegadci_uninit(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ atmegadci_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
struct usb_bus_methods atmegadci_bus_methods =
{
.endpoint_init = &atmegadci_ep_init,
@@ -2136,4 +2156,5 @@ struct usb_bus_methods atmegadci_bus_methods =
.clear_stall = &atmegadci_clear_stall,
.roothub_exec = &atmegadci_roothub_exec,
.xfer_poll = &atmegadci_do_poll,
+ .set_hw_power_sleep = &atmegadci_set_hw_power_sleep,
};
diff --git a/sys/dev/usb/controller/atmegadci.h b/sys/dev/usb/controller/atmegadci.h
index 68613af..91ba030 100644
--- a/sys/dev/usb/controller/atmegadci.h
+++ b/sys/dev/usb/controller/atmegadci.h
@@ -278,8 +278,6 @@ struct atmegadci_softc {
usb_error_t atmegadci_init(struct atmegadci_softc *sc);
void atmegadci_uninit(struct atmegadci_softc *sc);
-void atmegadci_suspend(struct atmegadci_softc *sc);
-void atmegadci_resume(struct atmegadci_softc *sc);
void atmegadci_interrupt(struct atmegadci_softc *sc);
#endif /* _ATMEGADCI_H_ */
diff --git a/sys/dev/usb/controller/atmegadci_atmelarm.c b/sys/dev/usb/controller/atmegadci_atmelarm.c
index c68101c..6c380b6 100644
--- a/sys/dev/usb/controller/atmegadci_atmelarm.c
+++ b/sys/dev/usb/controller/atmegadci_atmelarm.c
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
static device_probe_t atmegadci_probe;
static device_attach_t atmegadci_attach;
static device_detach_t atmegadci_detach;
-static device_shutdown_t atmegadci_shutdown;
struct atmegadci_super_softc {
struct atmegadci_softc sc_otg; /* must be first */
@@ -193,35 +192,22 @@ atmegadci_detach(device_t dev)
return (0);
}
-static int
-atmegadci_shutdown(device_t dev)
-{
- struct atmegadci_super_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- atmegadci_uninit(&sc->sc_otg);
-
- return (0);
-}
-
static device_method_t atmegadci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, atmegadci_probe),
DEVMETHOD(device_attach, atmegadci_attach),
DEVMETHOD(device_detach, atmegadci_detach),
- DEVMETHOD(device_shutdown, atmegadci_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t atmegadci_driver = {
- "atmegadci",
- atmegadci_methods,
- sizeof(struct atmegadci_super_softc),
+ .name = "atmegadci",
+ .methods = atmegadci_methods,
+ .size = sizeof(struct atmegadci_super_softc),
};
static devclass_t atmegadci_devclass;
diff --git a/sys/dev/usb/controller/avr32dci.c b/sys/dev/usb/controller/avr32dci.c
index 26785a3..9494c30 100644
--- a/sys/dev/usb/controller/avr32dci.c
+++ b/sys/dev/usb/controller/avr32dci.c
@@ -265,7 +265,7 @@ avr32dci_set_address(struct avr32dci_softc *sc, uint8_t addr)
{
DPRINTFN(5, "addr=%d\n", addr);
- avr32dci_mod_ctrl(sc, AVR32_UDADDR_ADDEN | addr, 0);
+ avr32dci_mod_ctrl(sc, AVR32_CTRL_DEV_FADDR_EN | addr, 0);
}
static uint8_t
@@ -501,7 +501,7 @@ repeat:
}
/* allocate FIFO bank */
- AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(td->ep_no), AVR32_EPTSTA_TX_BK_RDY);
+ AVR32_WRITE_4(sc, AVR32_EPTCTL(td->ep_no), AVR32_EPTCTL_TX_PK_RDY);
/* check remainder */
if (td->remainder == 0) {
@@ -754,7 +754,7 @@ avr32dci_setup_standard_chain(struct usb_xfer *xfer)
uint8_t need_sync;
DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
- xfer->address, UE_GET_ADDR(xfer->endpoint),
+ xfer->address, UE_GET_ADDR(xfer->endpointno),
xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
temp.max_frame_size = xfer->max_frame_size;
@@ -773,7 +773,7 @@ avr32dci_setup_standard_chain(struct usb_xfer *xfer)
temp.did_stall = !xfer->flags_int.control_stall;
sc = AVR32_BUS2SC(xfer->xroot->bus);
- ep_no = (xfer->endpoint & UE_ADDR);
+ ep_no = (xfer->endpointno & UE_ADDR);
/* check if we should prepend a setup message */
@@ -798,7 +798,7 @@ avr32dci_setup_standard_chain(struct usb_xfer *xfer)
}
if (x != xfer->nframes) {
- if (xfer->endpoint & UE_DIR_IN) {
+ if (xfer->endpointno & UE_DIR_IN) {
temp.func = &avr32dci_data_tx;
need_sync = 1;
} else {
@@ -872,7 +872,7 @@ avr32dci_setup_standard_chain(struct usb_xfer *xfer)
* Send a DATA1 message and invert the current
* endpoint direction.
*/
- if (xfer->endpoint & UE_DIR_IN) {
+ if (xfer->endpointno & UE_DIR_IN) {
temp.func = &avr32dci_data_rx;
need_sync = 0;
} else {
@@ -913,7 +913,8 @@ avr32dci_start_standard_chain(struct usb_xfer *xfer)
/* poll one time - will turn on interrupts */
if (avr32dci_xfer_do_fifo(xfer)) {
- uint8_t ep_no = xfer->endpoint & UE_ADDR_MASK;
+ uint8_t ep_no = xfer->endpointno & UE_ADDR;
+ struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus);
avr32dci_mod_ien(sc, AVR32_INT_EPT_INT(ep_no), 0);
@@ -1012,7 +1013,7 @@ avr32dci_standard_done(struct usb_xfer *xfer)
usb_error_t err = 0;
DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
- xfer, xfer->pipe);
+ xfer, xfer->endpoint);
/* reset scanner */
@@ -1064,10 +1065,10 @@ avr32dci_device_done(struct usb_xfer *xfer, usb_error_t error)
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
DPRINTFN(9, "xfer=%p, pipe=%p, error=%d\n",
- xfer, xfer->pipe, error);
+ xfer, xfer->endpoint, error);
if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
- ep_no = (xfer->endpoint & UE_ADDR);
+ ep_no = (xfer->endpointno & UE_ADDR);
/* disable endpoint interrupt */
avr32dci_mod_ien(sc, 0, AVR32_INT_EPT_INT(ep_no));
@@ -1080,7 +1081,7 @@ avr32dci_device_done(struct usb_xfer *xfer, usb_error_t error)
static void
avr32dci_set_stall(struct usb_device *udev, struct usb_xfer *xfer,
- struct usb_endpoint *ep, uint8_t *did_stall)
+ struct usb_endpoint *pipe, uint8_t *did_stall)
{
struct avr32dci_softc *sc;
uint8_t ep_no;
@@ -1166,7 +1167,7 @@ avr32dci_clear_stall_sub(struct avr32dci_softc *sc, uint8_t ep_no,
}
static void
-avr32dci_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
+avr32dci_clear_stall(struct usb_device *udev, struct usb_endpoint *pipe)
{
struct avr32dci_softc *sc;
struct usb_endpoint_descriptor *ed;
@@ -1226,8 +1227,7 @@ avr32dci_init(struct avr32dci_softc *sc)
AVR32_INT_ENDRESET, 0);
/* reset all endpoints */
-/**INDENT** Warning@1207: Extra ) */
- AVR32_WRITE_4(sc, AVR32_EPTRST, (1 << AVR32_EP_MAX) - 1));
+ AVR32_WRITE_4(sc, AVR32_EPTRST, (1 << AVR32_EP_MAX) - 1);
/* disable all endpoints */
for (n = 0; n != AVR32_EP_MAX; n++) {
@@ -1262,8 +1262,7 @@ avr32dci_uninit(struct avr32dci_softc *sc)
avr32dci_mod_ien(sc, 0, 0xFFFFFFFF);
/* reset all endpoints */
-/**INDENT** Warning@1242: Extra ) */
- AVR32_WRITE_4(sc, AVR32_EPTRST, (1 << AVR32_EP_MAX) - 1));
+ AVR32_WRITE_4(sc, AVR32_EPTRST, (1 << AVR32_EP_MAX) - 1);
/* disable all endpoints */
for (n = 0; n != AVR32_EP_MAX; n++) {
@@ -1284,16 +1283,16 @@ avr32dci_uninit(struct avr32dci_softc *sc)
USB_BUS_UNLOCK(&sc->sc_bus);
}
-void
+static void
avr32dci_suspend(struct avr32dci_softc *sc)
{
- return;
+ /* TODO */
}
-void
+static void
avr32dci_resume(struct avr32dci_softc *sc)
{
- return;
+ /* TODO */
}
static void
@@ -1369,10 +1368,10 @@ avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
uint8_t ep_no;
DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
- xfer, xfer->pipe->isoc_next, xfer->nframes);
+ xfer, xfer->endpoint->isoc_next, xfer->nframes);
/* get the current frame index */
- ep_no = xfer->endpoint & UE_ADDR_MASK;
+ ep_no = xfer->endpointno & UE_ADDR;
nframes = (AVR32_READ_4(sc, AVR32_FNUM) / 8);
nframes &= AVR32_FRAME_MASK;
@@ -1381,9 +1380,9 @@ avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
* check if the frame index is within the window where the frames
* will be inserted
*/
- temp = (nframes - xfer->pipe->isoc_next) & AVR32_FRAME_MASK;
+ temp = (nframes - xfer->endpoint->isoc_next) & AVR32_FRAME_MASK;
- if ((xfer->pipe->is_synced == 0) ||
+ if ((xfer->endpoint->is_synced == 0) ||
(temp < xfer->nframes)) {
/*
* If there is data underflow or the pipe queue is
@@ -1391,15 +1390,15 @@ avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
* of the current frame position. Else two isochronous
* transfers might overlap.
*/
- xfer->pipe->isoc_next = (nframes + 3) & AVR32_FRAME_MASK;
- xfer->pipe->is_synced = 1;
- DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
+ xfer->endpoint->isoc_next = (nframes + 3) & AVR32_FRAME_MASK;
+ xfer->endpoint->is_synced = 1;
+ DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
}
/*
* compute how many milliseconds the insertion is ahead of the
* current frame position:
*/
- temp = (xfer->pipe->isoc_next - nframes) & AVR32_FRAME_MASK;
+ temp = (xfer->endpoint->isoc_next - nframes) & AVR32_FRAME_MASK;
/*
* pre-compute when the isochronous transfer will be finished:
@@ -1409,7 +1408,7 @@ avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
xfer->nframes;
/* compute frame number for next insertion */
- xfer->pipe->isoc_next += xfer->nframes;
+ xfer->endpoint->isoc_next += xfer->nframes;
/* setup TDs */
avr32dci_setup_standard_chain(xfer);
@@ -1832,7 +1831,7 @@ tr_handle_clear_port_feature:
AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(0), AVR32_EPTSTA_FRCESTALL);
/* configure */
- AVR32_WRITE_4(sc, AVR32_EPTCFG(0), AVR32_EPTCFG_TYPE_CONTROL |
+ AVR32_WRITE_4(sc, AVR32_EPTCFG(0), AVR32_EPTCFG_TYPE_CTRL |
AVR32_EPTCFG_NBANK(1) | AVR32_EPTCFG_EPSIZE(6));
temp = AVR32_READ_4(sc, AVR32_EPTCFG(0));
@@ -1974,7 +1973,7 @@ avr32dci_xfer_setup(struct usb_setup_params *parm)
/*
* compute maximum number of TDs
*/
- if ((xfer->pipe->edesc->bmAttributes & UE_XFERTYPE) == UE_CONTROL) {
+ if ((xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) == UE_CONTROL) {
ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC 1 */
+ 1 /* SYNC 2 */ ;
@@ -1997,7 +1996,7 @@ avr32dci_xfer_setup(struct usb_setup_params *parm)
/*
* get profile stuff
*/
- ep_no = xfer->endpoint & UE_ADDR;
+ ep_no = xfer->endpointno & UE_ADDR;
avr32dci_get_hw_ep_profile(parm->udev, &pf, ep_no);
if (pf == NULL) {
@@ -2045,7 +2044,7 @@ avr32dci_xfer_unsetup(struct usb_xfer *xfer)
static void
avr32dci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
- struct usb_endpoint *ep)
+ struct usb_endpoint *pipe)
{
struct avr32dci_softc *sc = AVR32_BUS2SC(udev->bus);
@@ -2072,6 +2071,26 @@ avr32dci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
}
}
+static void
+avr32dci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct avr32dci_softc *sc = AVR32_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ avr32dci_suspend(sc);
+ break;
+ case USB_HW_POWER_SHUTDOWN:
+ avr32dci_uninit(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ avr32dci_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
struct usb_bus_methods avr32dci_bus_methods =
{
.endpoint_init = &avr32dci_ep_init,
@@ -2082,4 +2101,5 @@ struct usb_bus_methods avr32dci_bus_methods =
.clear_stall = &avr32dci_clear_stall,
.roothub_exec = &avr32dci_roothub_exec,
.xfer_poll = &avr32dci_do_poll,
+ .set_hw_power_sleep = &avr32dci_set_hw_power_sleep,
};
diff --git a/sys/dev/usb/controller/avr32dci.h b/sys/dev/usb/controller/avr32dci.h
index 6672fa7..2d80344 100644
--- a/sys/dev/usb/controller/avr32dci.h
+++ b/sys/dev/usb/controller/avr32dci.h
@@ -166,6 +166,7 @@ struct avr32dci_td {
uint32_t offset;
uint32_t remainder;
uint16_t max_packet_size;
+ uint8_t bank_shift;
uint8_t error:1;
uint8_t alt_next:1;
uint8_t short_pkt:1;
@@ -246,8 +247,6 @@ struct avr32dci_softc {
usb_error_t avr32dci_init(struct avr32dci_softc *sc);
void avr32dci_uninit(struct avr32dci_softc *sc);
-void avr32dci_suspend(struct avr32dci_softc *sc);
-void avr32dci_resume(struct avr32dci_softc *sc);
void avr32dci_interrupt(struct avr32dci_softc *sc);
void avr32dci_vbus_interrupt(struct avr32dci_softc *sc, uint8_t is_on);
diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
index 7e682f4..f59c801 100644
--- a/sys/dev/usb/controller/ehci.c
+++ b/sys/dev/usb/controller/ehci.c
@@ -188,7 +188,7 @@ ehci_reset(ehci_softc_t *sc)
EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
for (i = 0; i < 100; i++) {
- usb_pause_mtx(NULL, hz / 1000);
+ usb_pause_mtx(NULL, hz / 128);
hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
if (!hcr) {
if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGEMMIO)) {
@@ -212,7 +212,7 @@ ehci_reset(ehci_softc_t *sc)
return (0);
}
}
- device_printf(sc->sc_bus.bdev, "reset timeout\n");
+ device_printf(sc->sc_bus.bdev, "Reset timeout\n");
return (USB_ERR_IOERROR);
}
@@ -224,7 +224,7 @@ ehci_hcreset(ehci_softc_t *sc)
EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
for (i = 0; i < 100; i++) {
- usb_pause_mtx(NULL, hz / 1000);
+ usb_pause_mtx(NULL, hz / 128);
hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
if (hcr)
break;
@@ -237,7 +237,60 @@ ehci_hcreset(ehci_softc_t *sc)
*/
device_printf(sc->sc_bus.bdev, "stop timeout\n");
- return ehci_reset(sc);
+ return (ehci_reset(sc));
+}
+
+static int
+ehci_init_sub(struct ehci_softc *sc)
+{
+ struct usb_page_search buf_res;
+ uint32_t cparams;
+ uint32_t hcr;
+ uint8_t i;
+
+ cparams = EREAD4(sc, EHCI_HCCPARAMS);
+
+ DPRINTF("cparams=0x%x\n", cparams);
+
+ if (EHCI_HCC_64BIT(cparams)) {
+ DPRINTF("HCC uses 64-bit structures\n");
+
+ /* MUST clear segment register if 64 bit capable */
+ EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
+ }
+
+ usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
+ EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
+
+ usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
+ EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
+
+ /* enable interrupts */
+ EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
+
+ /* turn on controller */
+ EOWRITE4(sc, EHCI_USBCMD,
+ EHCI_CMD_ITC_1 | /* 1 microframes interrupt delay */
+ (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
+ EHCI_CMD_ASE |
+ EHCI_CMD_PSE |
+ EHCI_CMD_RS);
+
+ /* Take over port ownership */
+ EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
+
+ for (i = 0; i < 100; i++) {
+ usb_pause_mtx(NULL, hz / 128);
+ hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
+ if (!hcr) {
+ break;
+ }
+ }
+ if (hcr) {
+ device_printf(sc->sc_bus.bdev, "Run timeout\n");
+ return (USB_ERR_IOERROR);
+ }
+ return (USB_ERR_NORMAL_COMPLETION);
}
usb_error_t
@@ -246,8 +299,6 @@ ehci_init(ehci_softc_t *sc)
struct usb_page_search buf_res;
uint32_t version;
uint32_t sparams;
- uint32_t cparams;
- uint32_t hcr;
uint16_t i;
uint16_t x;
uint16_t y;
@@ -279,15 +330,6 @@ ehci_init(ehci_softc_t *sc)
DPRINTF("sparams=0x%x\n", sparams);
sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
- DPRINTF("cparams=0x%x\n", cparams);
-
- if (EHCI_HCC_64BIT(cparams)) {
- DPRINTF("HCC uses 64-bit structures\n");
-
- /* MUST clear segment register if 64 bit capable */
- EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
- }
sc->sc_bus.usbrev = USB_REV_2_0;
/* Reset the controller */
@@ -464,9 +506,6 @@ ehci_init(ehci_softc_t *sc)
[i & (EHCI_VIRTUAL_FRAMELIST_COUNT - 1)]->itd_self;
}
}
- /* setup sync list pointer */
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
-
usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
if (1) {
@@ -511,35 +550,8 @@ ehci_init(ehci_softc_t *sc)
}
#endif
- /* setup async list pointer */
- EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
-
-
- /* enable interrupts */
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- /* turn on controller */
- EOWRITE4(sc, EHCI_USBCMD,
- EHCI_CMD_ITC_1 | /* 1 microframes interrupt delay */
- (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
- EHCI_CMD_ASE |
- EHCI_CMD_PSE |
- EHCI_CMD_RS);
-
- /* Take over port ownership */
- EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
-
- for (i = 0; i < 100; i++) {
- usb_pause_mtx(NULL, hz / 1000);
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (!hcr) {
- break;
- }
- }
- if (hcr) {
- device_printf(sc->sc_bus.bdev, "run timeout\n");
- return (USB_ERR_IOERROR);
- }
+ /* finial setup */
+ err = ehci_init_sub(sc);
if (!err) {
/* catch any lost interrupts */
@@ -573,137 +585,28 @@ ehci_detach(ehci_softc_t *sc)
usb_callout_drain(&sc->sc_tmo_poll);
}
-void
+static void
ehci_suspend(ehci_softc_t *sc)
{
- uint32_t cmd;
- uint32_t hcr;
- uint8_t i;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if (((cmd & EHCI_PS_PO) == 0) &&
- ((cmd & EHCI_PS_PE) == EHCI_PS_PE)) {
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd | EHCI_PS_SUSP);
- }
- }
-
- sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
-
- cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
- EOWRITE4(sc, EHCI_USBCMD, cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) &
- (EHCI_STS_ASS | EHCI_STS_PSS);
-
- if (hcr == 0) {
- break;
- }
- usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- }
-
- if (hcr != 0) {
- device_printf(sc->sc_bus.bdev, "reset timeout\n");
- }
- cmd &= ~EHCI_CMD_RS;
- EOWRITE4(sc, EHCI_USBCMD, cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr == EHCI_STS_HCH) {
- break;
- }
- usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- }
+ DPRINTF("stopping the HC\n");
- if (hcr != EHCI_STS_HCH) {
- device_printf(sc->sc_bus.bdev,
- "config timeout\n");
- }
- USB_BUS_UNLOCK(&sc->sc_bus);
+ /* reset HC */
+ ehci_hcreset(sc);
}
-void
+static void
ehci_resume(ehci_softc_t *sc)
{
- struct usb_page_search buf_res;
- uint32_t cmd;
- uint32_t hcr;
- uint8_t i;
-
- USB_BUS_LOCK(&sc->sc_bus);
-
- /* restore things in case the bios doesn't */
- EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
-
- usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
+ /* reset HC */
+ ehci_hcreset(sc);
- usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
- EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
-
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- hcr = 0;
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if (((cmd & EHCI_PS_PO) == 0) &&
- ((cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)) {
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd | EHCI_PS_FPR);
- hcr = 1;
- }
- }
-
- if (hcr) {
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
-
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if (((cmd & EHCI_PS_PO) == 0) &&
- ((cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)) {
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd & ~EHCI_PS_FPR);
- }
- }
- }
- EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr != EHCI_STS_HCH) {
- break;
- }
- usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
- }
- if (hcr == EHCI_STS_HCH) {
- device_printf(sc->sc_bus.bdev, "config timeout\n");
- }
-
- USB_BUS_UNLOCK(&sc->sc_bus);
-
- usb_pause_mtx(NULL,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
+ /* setup HC */
+ ehci_init_sub(sc);
/* catch any lost interrupts */
ehci_do_poll(&sc->sc_bus);
}
-void
-ehci_shutdown(ehci_softc_t *sc)
-{
- DPRINTF("stopping the HC\n");
-
- if (ehci_hcreset(sc)) {
- DPRINTF("reset failed!\n");
- }
-}
-
#ifdef USB_DEBUG
static void
ehci_dump_regs(ehci_softc_t *sc)
@@ -3908,8 +3811,24 @@ ehci_device_suspend(struct usb_device *udev)
}
USB_BUS_UNLOCK(udev->bus);
+}
- return;
+static void
+ehci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct ehci_softc *sc = EHCI_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ case USB_HW_POWER_SHUTDOWN:
+ ehci_suspend(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ ehci_resume(sc);
+ break;
+ default:
+ break;
+ }
}
static void
@@ -3955,6 +3874,7 @@ struct usb_bus_methods ehci_bus_methods =
.device_resume = ehci_device_resume,
.device_suspend = ehci_device_suspend,
.set_hw_power = ehci_set_hw_power,
+ .set_hw_power_sleep = ehci_set_hw_power_sleep,
.roothub_exec = ehci_roothub_exec,
.xfer_poll = ehci_do_poll,
};
diff --git a/sys/dev/usb/controller/ehci.h b/sys/dev/usb/controller/ehci.h
index a8aa514..b8b6985 100644
--- a/sys/dev/usb/controller/ehci.h
+++ b/sys/dev/usb/controller/ehci.h
@@ -333,8 +333,6 @@ typedef struct ehci_softc {
uint32_t sc_terminate_self; /* TD short packet termination pointer */
uint32_t sc_eintrs;
- uint32_t sc_cmd; /* shadow of cmd register during
- * suspend */
uint16_t sc_intr_stat[EHCI_VIRTUAL_FRAMELIST_COUNT];
uint16_t sc_id_vendor; /* vendor ID for root hub */
@@ -445,9 +443,6 @@ usb_bus_mem_cb_t ehci_iterate_hw_softc;
usb_error_t ehci_reset(ehci_softc_t *sc);
usb_error_t ehci_init(ehci_softc_t *sc);
void ehci_detach(struct ehci_softc *sc);
-void ehci_suspend(struct ehci_softc *sc);
-void ehci_resume(struct ehci_softc *sc);
-void ehci_shutdown(ehci_softc_t *sc);
void ehci_interrupt(ehci_softc_t *sc);
#endif /* _EHCI_H_ */
diff --git a/sys/dev/usb/controller/ehci_ixp4xx.c b/sys/dev/usb/controller/ehci_ixp4xx.c
index 7327fde..45113d9 100644
--- a/sys/dev/usb/controller/ehci_ixp4xx.c
+++ b/sys/dev/usb/controller/ehci_ixp4xx.c
@@ -78,9 +78,6 @@ struct ixp_ehci_softc {
static device_attach_t ehci_ixp_attach;
static device_detach_t ehci_ixp_detach;
-static device_shutdown_t ehci_ixp_shutdown;
-static device_suspend_t ehci_ixp_suspend;
-static device_resume_t ehci_ixp_resume;
static uint8_t ehci_bs_r_1(void *, bus_space_handle_t, bus_size_t);
static void ehci_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
@@ -90,45 +87,6 @@ static uint32_t ehci_bs_r_4(void *, bus_space_handle_t, bus_size_t);
static void ehci_bs_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
static int
-ehci_ixp_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-ehci_ixp_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_ixp_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
-
- return (0);
-}
-
-static int
ehci_ixp_probe(device_t self)
{
@@ -335,9 +293,9 @@ static device_method_t ehci_methods[] = {
DEVMETHOD(device_probe, ehci_ixp_probe),
DEVMETHOD(device_attach, ehci_ixp_attach),
DEVMETHOD(device_detach, ehci_ixp_detach),
- DEVMETHOD(device_suspend, ehci_ixp_suspend),
- DEVMETHOD(device_resume, ehci_ixp_resume),
- DEVMETHOD(device_shutdown, ehci_ixp_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
diff --git a/sys/dev/usb/controller/ehci_mv.c b/sys/dev/usb/controller/ehci_mv.c
index f12cb14..a47e253 100644
--- a/sys/dev/usb/controller/ehci_mv.c
+++ b/sys/dev/usb/controller/ehci_mv.c
@@ -81,9 +81,6 @@ __FBSDID("$FreeBSD$");
static device_attach_t mv_ehci_attach;
static device_detach_t mv_ehci_detach;
-static device_shutdown_t mv_ehci_shutdown;
-static device_suspend_t mv_ehci_suspend;
-static device_resume_t mv_ehci_resume;
static int err_intr(void *arg);
@@ -103,45 +100,6 @@ static void *ih_err;
#define MV_USB_DEVICE_UNDERFLOW (1 << 3)
static int
-mv_ehci_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-mv_ehci_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-mv_ehci_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
-
- return (0);
-}
-
-static int
mv_ehci_probe(device_t self)
{
@@ -372,9 +330,9 @@ static device_method_t ehci_methods[] = {
DEVMETHOD(device_probe, mv_ehci_probe),
DEVMETHOD(device_attach, mv_ehci_attach),
DEVMETHOD(device_detach, mv_ehci_detach),
- DEVMETHOD(device_suspend, mv_ehci_suspend),
- DEVMETHOD(device_resume, mv_ehci_resume),
- DEVMETHOD(device_shutdown, mv_ehci_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
diff --git a/sys/dev/usb/controller/ehci_pci.c b/sys/dev/usb/controller/ehci_pci.c
index 8c19b2a..e293ec8 100644
--- a/sys/dev/usb/controller/ehci_pci.c
+++ b/sys/dev/usb/controller/ehci_pci.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_pci.h>
#include <dev/usb/controller/ehci.h>
#include <dev/usb/controller/ehcireg.h>
+#include "usb_if.h"
#define PCI_EHCI_VENDORID_ACERLABS 0x10b9
#define PCI_EHCI_VENDORID_AMD 0x1022
@@ -92,54 +93,10 @@ __FBSDID("$FreeBSD$");
#define PCI_EHCI_VENDORID_NVIDIA2 0x10DE
#define PCI_EHCI_VENDORID_VIA 0x1106
-static void ehci_pci_takecontroller(device_t self);
-
static device_probe_t ehci_pci_probe;
static device_attach_t ehci_pci_attach;
static device_detach_t ehci_pci_detach;
-static device_suspend_t ehci_pci_suspend;
-static device_resume_t ehci_pci_resume;
-static device_shutdown_t ehci_pci_shutdown;
-
-static int
-ehci_pci_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-ehci_pci_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_pci_takecontroller(self);
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_pci_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
-
- return (0);
-}
+static usb_take_controller_t ehci_pci_take_controller;
static const char *
ehci_pci_match(device_t self)
@@ -418,7 +375,7 @@ ehci_pci_attach(device_t self)
sc->sc_intr_hdl = NULL;
goto error;
}
- ehci_pci_takecontroller(self);
+ ehci_pci_take_controller(self);
/* Undocumented quirks taken from Linux */
@@ -530,8 +487,8 @@ ehci_pci_detach(device_t self)
return (0);
}
-static void
-ehci_pci_takecontroller(device_t self)
+static int
+ehci_pci_take_controller(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
uint32_t cparams;
@@ -573,22 +530,25 @@ ehci_pci_takecontroller(device_t self)
usb_pause_mtx(NULL, hz / 100); /* wait 10ms */
}
}
+ return (0);
}
-static driver_t ehci_driver =
-{
+static device_method_t ehci_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ehci_pci_probe),
+ DEVMETHOD(device_attach, ehci_pci_attach),
+ DEVMETHOD(device_detach, ehci_pci_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(usb_take_controller, ehci_pci_take_controller),
+
+ DEVMETHOD_END
+};
+
+static driver_t ehci_driver = {
.name = "ehci",
- .methods = (device_method_t[]){
- /* device interface */
- DEVMETHOD(device_probe, ehci_pci_probe),
- DEVMETHOD(device_attach, ehci_pci_attach),
- DEVMETHOD(device_detach, ehci_pci_detach),
- DEVMETHOD(device_suspend, ehci_pci_suspend),
- DEVMETHOD(device_resume, ehci_pci_resume),
- DEVMETHOD(device_shutdown, ehci_pci_shutdown),
-
- DEVMETHOD_END
- },
+ .methods = ehci_pci_methods,
.size = sizeof(struct ehci_softc),
};
diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c
index be32b2b..d463052 100644
--- a/sys/dev/usb/controller/musb_otg.c
+++ b/sys/dev/usb/controller/musb_otg.c
@@ -1910,16 +1910,16 @@ musbotg_uninit(struct musbotg_softc *sc)
USB_BUS_UNLOCK(&sc->sc_bus);
}
-void
+static void
musbotg_suspend(struct musbotg_softc *sc)
{
- return;
+ /* TODO */
}
-void
+static void
musbotg_resume(struct musbotg_softc *sc)
{
- return;
+ /* TODO */
}
static void
@@ -2776,6 +2776,26 @@ musbotg_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
}
}
+static void
+musbotg_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ musbotg_suspend(sc);
+ break;
+ case USB_HW_POWER_SHUTDOWN:
+ musbotg_uninit(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ musbotg_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
struct usb_bus_methods musbotg_bus_methods =
{
.endpoint_init = &musbotg_ep_init,
@@ -2786,4 +2806,5 @@ struct usb_bus_methods musbotg_bus_methods =
.clear_stall = &musbotg_clear_stall,
.roothub_exec = &musbotg_roothub_exec,
.xfer_poll = &musbotg_do_poll,
+ .set_hw_power_sleep = &musbotg_set_hw_power_sleep,
};
diff --git a/sys/dev/usb/controller/musb_otg.h b/sys/dev/usb/controller/musb_otg.h
index e8eafca..3b889a9 100644
--- a/sys/dev/usb/controller/musb_otg.h
+++ b/sys/dev/usb/controller/musb_otg.h
@@ -398,8 +398,6 @@ struct musbotg_softc {
usb_error_t musbotg_init(struct musbotg_softc *sc);
void musbotg_uninit(struct musbotg_softc *sc);
-void musbotg_suspend(struct musbotg_softc *sc);
-void musbotg_resume(struct musbotg_softc *sc);
void musbotg_interrupt(struct musbotg_softc *sc);
void musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on);
diff --git a/sys/dev/usb/controller/musb_otg_atmelarm.c b/sys/dev/usb/controller/musb_otg_atmelarm.c
index b301e09..bb3e60a 100644
--- a/sys/dev/usb/controller/musb_otg_atmelarm.c
+++ b/sys/dev/usb/controller/musb_otg_atmelarm.c
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
static device_probe_t musbotg_probe;
static device_attach_t musbotg_attach;
static device_detach_t musbotg_detach;
-static device_shutdown_t musbotg_shutdown;
struct musbotg_super_softc {
struct musbotg_softc sc_otg; /* must be first */
@@ -218,35 +217,22 @@ musbotg_detach(device_t dev)
return (0);
}
-static int
-musbotg_shutdown(device_t dev)
-{
- struct musbotg_super_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- musbotg_uninit(&sc->sc_otg);
-
- return (0);
-}
-
static device_method_t musbotg_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, musbotg_probe),
DEVMETHOD(device_attach, musbotg_attach),
DEVMETHOD(device_detach, musbotg_detach),
- DEVMETHOD(device_shutdown, musbotg_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t musbotg_driver = {
- "musbotg",
- musbotg_methods,
- sizeof(struct musbotg_super_softc),
+ .name = "musbotg",
+ .methods = musbotg_methods,
+ .size = sizeof(struct musbotg_super_softc),
};
static devclass_t musbotg_devclass;
diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c
index fa2d607..93c2bb2 100644
--- a/sys/dev/usb/controller/ohci.c
+++ b/sys/dev/usb/controller/ohci.c
@@ -166,7 +166,7 @@ ohci_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb)
}
static usb_error_t
-ohci_controller_init(ohci_softc_t *sc)
+ohci_controller_init(ohci_softc_t *sc, int do_suspend)
{
struct usb_page_search buf_res;
uint32_t i;
@@ -233,6 +233,11 @@ reset:
}
#endif
+ if (do_suspend) {
+ OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_SUSPEND);
+ return (USB_ERR_NORMAL_COMPLETION);
+ }
+
/* The controller is now in SUSPEND state, we have 2ms to finish. */
/* set up HC registers */
@@ -415,13 +420,12 @@ ohci_init(ohci_softc_t *sc)
sc->sc_bus.usbrev = USB_REV_1_0;
- if (ohci_controller_init(sc)) {
+ if (ohci_controller_init(sc, 0) != 0)
return (USB_ERR_INVAL);
- } else {
- /* catch any lost interrupts */
- ohci_do_poll(&sc->sc_bus);
- return (USB_ERR_NORMAL_COMPLETION);
- }
+
+ /* catch any lost interrupts */
+ ohci_do_poll(&sc->sc_bus);
+ return (USB_ERR_NORMAL_COMPLETION);
}
/*
@@ -445,75 +449,32 @@ ohci_detach(struct ohci_softc *sc)
usb_callout_drain(&sc->sc_tmo_rhsc);
}
-/* NOTE: suspend/resume is called from
- * interrupt context and cannot sleep!
- */
-void
+static void
ohci_suspend(ohci_softc_t *sc)
{
- uint32_t ctl;
-
- USB_BUS_LOCK(&sc->sc_bus);
+ DPRINTF("\n");
#ifdef USB_DEBUG
- DPRINTF("\n");
- if (ohcidebug > 2) {
+ if (ohcidebug > 2)
ohci_dumpregs(sc);
- }
#endif
- ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
- if (sc->sc_control == 0) {
- /*
- * Preserve register values, in case that APM BIOS
- * does not recover them.
- */
- sc->sc_control = ctl;
- sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
- }
- ctl |= OHCI_HCFS_SUSPEND;
- OWRITE4(sc, OHCI_CONTROL, ctl);
-
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
-
- USB_BUS_UNLOCK(&sc->sc_bus);
+ /* reset HC and leave it suspended */
+ ohci_controller_init(sc, 1);
}
-void
+static void
ohci_resume(ohci_softc_t *sc)
{
- uint32_t ctl;
+ DPRINTF("\n");
#ifdef USB_DEBUG
- DPRINTF("\n");
- if (ohcidebug > 2) {
+ if (ohcidebug > 2)
ohci_dumpregs(sc);
- }
#endif
- /* some broken BIOSes never initialize the Controller chip */
- ohci_controller_init(sc);
-
- USB_BUS_LOCK(&sc->sc_bus);
- if (sc->sc_intre) {
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
- sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
- }
- if (sc->sc_control)
- ctl = sc->sc_control;
- else
- ctl = OREAD4(sc, OHCI_CONTROL);
- ctl |= OHCI_HCFS_RESUME;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_DELAY));
- ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_RECOVERY));
- sc->sc_control = sc->sc_intre = 0;
- USB_BUS_UNLOCK(&sc->sc_bus);
+ /* some broken BIOSes never initialize the Controller chip */
+ ohci_controller_init(sc, 0);
/* catch any lost interrupts */
ohci_do_poll(&sc->sc_bus);
@@ -2713,6 +2674,24 @@ ohci_device_suspend(struct usb_device *udev)
}
static void
+ohci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct ohci_softc *sc = OHCI_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ case USB_HW_POWER_SHUTDOWN:
+ ohci_suspend(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ ohci_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
ohci_set_hw_power(struct usb_bus *bus)
{
struct ohci_softc *sc = OHCI_BUS2SC(bus);
@@ -2756,6 +2735,7 @@ struct usb_bus_methods ohci_bus_methods =
.device_resume = ohci_device_resume,
.device_suspend = ohci_device_suspend,
.set_hw_power = ohci_set_hw_power,
+ .set_hw_power_sleep = ohci_set_hw_power_sleep,
.roothub_exec = ohci_roothub_exec,
.xfer_poll = ohci_do_poll,
};
diff --git a/sys/dev/usb/controller/ohci.h b/sys/dev/usb/controller/ohci.h
index d85c2c9..9d8ac7d 100644
--- a/sys/dev/usb/controller/ohci.h
+++ b/sys/dev/usb/controller/ohci.h
@@ -241,8 +241,6 @@ typedef struct ohci_softc {
bus_space_handle_t sc_io_hdl;
uint32_t sc_eintrs; /* enabled interrupts */
- uint32_t sc_control; /* Preserved during suspend/standby */
- uint32_t sc_intre;
uint16_t sc_intr_stat[OHCI_NO_EDS];
uint16_t sc_id_vendor;
@@ -260,8 +258,6 @@ usb_bus_mem_cb_t ohci_iterate_hw_softc;
usb_error_t ohci_init(ohci_softc_t *sc);
void ohci_detach(struct ohci_softc *sc);
-void ohci_suspend(ohci_softc_t *sc);
-void ohci_resume(ohci_softc_t *sc);
void ohci_interrupt(ohci_softc_t *sc);
#endif /* _OHCI_H_ */
diff --git a/sys/dev/usb/controller/ohci_atmelarm.c b/sys/dev/usb/controller/ohci_atmelarm.c
index 177c926..643b4d1 100644
--- a/sys/dev/usb/controller/ohci_atmelarm.c
+++ b/sys/dev/usb/controller/ohci_atmelarm.c
@@ -221,15 +221,17 @@ static device_method_t ohci_methods[] = {
DEVMETHOD(device_probe, ohci_atmelarm_probe),
DEVMETHOD(device_attach, ohci_atmelarm_attach),
DEVMETHOD(device_detach, ohci_atmelarm_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_driver = {
- "ohci",
- ohci_methods,
- sizeof(struct at91_ohci_softc),
+ .name = "ohci",
+ .methods = ohci_methods,
+ .size = sizeof(struct at91_ohci_softc),
};
static devclass_t ohci_devclass;
diff --git a/sys/dev/usb/controller/ohci_pci.c b/sys/dev/usb/controller/ohci_pci.c
index c8690c9..864376b 100644
--- a/sys/dev/usb/controller/ohci_pci.c
+++ b/sys/dev/usb/controller/ohci_pci.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_pci.h>
#include <dev/usb/controller/ohci.h>
#include <dev/usb/controller/ohcireg.h>
+#include "usb_if.h"
#define PCI_OHCI_VENDORID_ACERLABS 0x10b9
#define PCI_OHCI_VENDORID_AMD 0x1022
@@ -92,28 +93,13 @@ __FBSDID("$FreeBSD$");
static device_probe_t ohci_pci_probe;
static device_attach_t ohci_pci_attach;
static device_detach_t ohci_pci_detach;
-static device_suspend_t ohci_pci_suspend;
-static device_resume_t ohci_pci_resume;
+static usb_take_controller_t ohci_pci_take_controller;
static int
-ohci_pci_suspend(device_t self)
+ohci_pci_take_controller(device_t self)
{
- ohci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err) {
- return (err);
- }
- ohci_suspend(sc);
- return (0);
-}
-
-static int
-ohci_pci_resume(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- uint32_t reg, int_line;
+ uint32_t reg;
+ uint32_t int_line;
if (pci_get_powerstate(self) != PCI_POWERSTATE_D0) {
device_printf(self, "chip is in D%d mode "
@@ -124,9 +110,6 @@ ohci_pci_resume(device_t self)
pci_write_config(self, PCI_CBMEM, reg, 4);
pci_write_config(self, PCIR_INTLINE, int_line, 4);
}
- ohci_resume(sc);
-
- bus_generic_resume(self);
return (0);
}
@@ -381,20 +364,22 @@ ohci_pci_detach(device_t self)
return (0);
}
-static driver_t ohci_driver =
-{
+static device_method_t ohci_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ohci_pci_probe),
+ DEVMETHOD(device_attach, ohci_pci_attach),
+ DEVMETHOD(device_detach, ohci_pci_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(usb_take_controller, ohci_pci_take_controller),
+
+ DEVMETHOD_END
+};
+
+static driver_t ohci_driver = {
.name = "ohci",
- .methods = (device_method_t[]){
- /* device interface */
- DEVMETHOD(device_probe, ohci_pci_probe),
- DEVMETHOD(device_attach, ohci_pci_attach),
- DEVMETHOD(device_detach, ohci_pci_detach),
- DEVMETHOD(device_suspend, ohci_pci_suspend),
- DEVMETHOD(device_resume, ohci_pci_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- DEVMETHOD_END
- },
+ .methods = ohci_pci_methods,
.size = sizeof(struct ohci_softc),
};
diff --git a/sys/dev/usb/controller/ohci_s3c24x0.c b/sys/dev/usb/controller/ohci_s3c24x0.c
index b0907ad..225a2d2 100644
--- a/sys/dev/usb/controller/ohci_s3c24x0.c
+++ b/sys/dev/usb/controller/ohci_s3c24x0.c
@@ -198,15 +198,17 @@ static device_method_t ohci_methods[] = {
DEVMETHOD(device_probe, ohci_s3c24x0_probe),
DEVMETHOD(device_attach, ohci_s3c24x0_attach),
DEVMETHOD(device_detach, ohci_s3c24x0_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_driver = {
- "ohci",
- ohci_methods,
- sizeof(struct ohci_softc),
+ .name = "ohci",
+ .methods = ohci_methods,
+ .size = sizeof(struct ohci_softc),
};
static devclass_t ohci_devclass;
diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c
index c365e01..d9091c9 100644
--- a/sys/dev/usb/controller/uhci.c
+++ b/sys/dev/usb/controller/uhci.c
@@ -373,9 +373,10 @@ done_1:
done_2:
- /* reload the configuration */
- UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
- UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
+ /* reset frame number */
+ UWRITE2(sc, UHCI_FRNUM, 0);
+ /* set default SOF value */
+ UWRITE1(sc, UHCI_SOF, 0x40);
USB_BUS_UNLOCK(&sc->sc_bus);
@@ -463,9 +464,6 @@ uhci_init(uhci_softc_t *sc)
uhci_dumpregs(sc);
}
#endif
- sc->sc_saved_sof = 0x40; /* default value */
- sc->sc_saved_frnum = 0; /* default frame number */
-
/*
* Setup QH's
*/
@@ -658,24 +656,16 @@ uhci_init(uhci_softc_t *sc)
return (0);
}
-/* NOTE: suspend/resume is called from
- * interrupt context and cannot sleep!
- */
-
-void
+static void
uhci_suspend(uhci_softc_t *sc)
{
- USB_BUS_LOCK(&sc->sc_bus);
-
#ifdef USB_DEBUG
if (uhcidebug > 2) {
uhci_dumpregs(sc);
}
#endif
- /* save some state if BIOS doesn't */
- sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
- sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
+ USB_BUS_LOCK(&sc->sc_bus);
/* stop the controller */
@@ -685,13 +675,10 @@ uhci_suspend(uhci_softc_t *sc)
UHCICMD(sc, UHCI_CMD_EGSM);
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_WAIT));
-
USB_BUS_UNLOCK(&sc->sc_bus);
}
-void
+static void
uhci_resume(uhci_softc_t *sc)
{
USB_BUS_LOCK(&sc->sc_bus);
@@ -704,21 +691,17 @@ uhci_resume(uhci_softc_t *sc)
UHCICMD(sc, UHCI_CMD_FGR);
- usb_pause_mtx(&sc->sc_bus.bus_mtx,
- USB_MS_TO_TICKS(USB_RESUME_DELAY));
-
/* and start traffic again */
uhci_start(sc);
+ USB_BUS_UNLOCK(&sc->sc_bus);
+
#ifdef USB_DEBUG
- if (uhcidebug > 2) {
+ if (uhcidebug > 2)
uhci_dumpregs(sc);
- }
#endif
- USB_BUS_UNLOCK(&sc->sc_bus);
-
/* catch lost interrupts */
uhci_do_poll(&sc->sc_bus);
}
@@ -3179,6 +3162,24 @@ uhci_device_suspend(struct usb_device *udev)
}
static void
+uhci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct uhci_softc *sc = UHCI_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ case USB_HW_POWER_SHUTDOWN:
+ uhci_suspend(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ uhci_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
uhci_set_hw_power(struct usb_bus *bus)
{
struct uhci_softc *sc = UHCI_BUS2SC(bus);
@@ -3225,6 +3226,7 @@ struct usb_bus_methods uhci_bus_methods =
.device_resume = uhci_device_resume,
.device_suspend = uhci_device_suspend,
.set_hw_power = uhci_set_hw_power,
+ .set_hw_power_sleep = uhci_set_hw_power_sleep,
.roothub_exec = uhci_roothub_exec,
.xfer_poll = uhci_do_poll,
};
diff --git a/sys/dev/usb/controller/uhci.h b/sys/dev/usb/controller/uhci.h
index 0878e79..8a6ce44 100644
--- a/sys/dev/usb/controller/uhci.h
+++ b/sys/dev/usb/controller/uhci.h
@@ -230,13 +230,11 @@ typedef struct uhci_softc {
uint32_t sc_loops; /* number of QHs that wants looping */
uint16_t sc_intr_stat[UHCI_IFRAMELIST_COUNT];
- uint16_t sc_saved_frnum;
uint8_t sc_addr; /* device address */
uint8_t sc_conf; /* device configuration */
uint8_t sc_isreset; /* bits set if a root hub is reset */
uint8_t sc_isresumed; /* bits set if a port was resumed */
- uint8_t sc_saved_sof;
uint8_t sc_hub_idata[1];
char sc_vendor[16]; /* vendor string for root hub */
@@ -245,8 +243,6 @@ typedef struct uhci_softc {
usb_bus_mem_cb_t uhci_iterate_hw_softc;
usb_error_t uhci_init(uhci_softc_t *sc);
-void uhci_suspend(uhci_softc_t *sc);
-void uhci_resume(uhci_softc_t *sc);
void uhci_reset(uhci_softc_t *sc);
void uhci_interrupt(uhci_softc_t *sc);
diff --git a/sys/dev/usb/controller/uhci_pci.c b/sys/dev/usb/controller/uhci_pci.c
index 4b04f25..454b904 100644
--- a/sys/dev/usb/controller/uhci_pci.c
+++ b/sys/dev/usb/controller/uhci_pci.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_pci.h>
#include <dev/usb/controller/uhci.h>
#include <dev/usb/controller/uhcireg.h>
+#include "usb_if.h"
#define PCI_UHCI_VENDORID_INTEL 0x8086
#define PCI_UHCI_VENDORID_VIA 0x1106
@@ -83,33 +84,13 @@ __FBSDID("$FreeBSD$");
static device_probe_t uhci_pci_probe;
static device_attach_t uhci_pci_attach;
static device_detach_t uhci_pci_detach;
-static device_suspend_t uhci_pci_suspend;
-static device_resume_t uhci_pci_resume;
+static usb_take_controller_t uhci_pci_take_controller;
static int
-uhci_pci_suspend(device_t self)
+uhci_pci_take_controller(device_t self)
{
- uhci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err) {
- return (err);
- }
- uhci_suspend(sc);
- return (0);
-}
-
-static int
-uhci_pci_resume(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
-
pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
- uhci_resume(sc);
-
- bus_generic_resume(self);
return (0);
}
@@ -446,21 +427,22 @@ uhci_pci_detach(device_t self)
return (0);
}
-static driver_t uhci_driver =
-{
+static device_method_t uhci_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, uhci_pci_probe),
+ DEVMETHOD(device_attach, uhci_pci_attach),
+ DEVMETHOD(device_detach, uhci_pci_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(usb_take_controller, uhci_pci_take_controller),
+
+ DEVMETHOD_END
+};
+
+static driver_t uhci_driver = {
.name = "uhci",
- .methods = (device_method_t[]){
- /* device interface */
- DEVMETHOD(device_probe, uhci_pci_probe),
- DEVMETHOD(device_attach, uhci_pci_attach),
- DEVMETHOD(device_detach, uhci_pci_detach),
-
- DEVMETHOD(device_suspend, uhci_pci_suspend),
- DEVMETHOD(device_resume, uhci_pci_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- DEVMETHOD_END
- },
+ .methods = uhci_pci_methods,
.size = sizeof(struct uhci_softc),
};
diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
index 7ff0bc0..f31ab5b 100644
--- a/sys/dev/usb/controller/usb_controller.c
+++ b/sys/dev/usb/controller/usb_controller.c
@@ -61,12 +61,16 @@
#include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h>
#include <dev/usb/usb_pf.h>
+#include "usb_if.h"
/* function prototypes */
static device_probe_t usb_probe;
static device_attach_t usb_attach;
static device_detach_t usb_detach;
+static device_suspend_t usb_suspend;
+static device_resume_t usb_resume;
+static device_shutdown_t usb_shutdown;
static void usb_attach_sub(device_t, struct usb_bus *);
@@ -91,9 +95,9 @@ static device_method_t usb_methods[] = {
DEVMETHOD(device_probe, usb_probe),
DEVMETHOD(device_attach, usb_attach),
DEVMETHOD(device_detach, usb_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, usb_suspend),
+ DEVMETHOD(device_resume, usb_resume),
+ DEVMETHOD(device_shutdown, usb_shutdown),
{0, 0}
};
@@ -182,12 +186,12 @@ usb_detach(device_t dev)
usb_root_mount_rel(bus);
USB_BUS_LOCK(bus);
- if (usb_proc_msignal(&bus->explore_proc,
- &bus->detach_msg[0], &bus->detach_msg[1])) {
- /* ignore */
- }
- /* Wait for detach to complete */
+ /* Queue detach job */
+ usb_proc_msignal(&bus->explore_proc,
+ &bus->detach_msg[0], &bus->detach_msg[1]);
+
+ /* Wait for detach to complete */
usb_proc_mwait(&bus->explore_proc,
&bus->detach_msg[0], &bus->detach_msg[1]);
@@ -213,6 +217,75 @@ usb_detach(device_t dev)
}
/*------------------------------------------------------------------------*
+ * usb_suspend
+ *------------------------------------------------------------------------*/
+static int
+usb_suspend(device_t dev)
+{
+ struct usb_bus *bus = device_get_softc(dev);
+
+ DPRINTF("\n");
+
+ if (bus == NULL) {
+ /* was never setup properly */
+ return (0);
+ }
+
+ USB_BUS_LOCK(bus);
+ usb_proc_msignal(&bus->explore_proc,
+ &bus->suspend_msg[0], &bus->suspend_msg[1]);
+ USB_BUS_UNLOCK(bus);
+
+ return (0);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_resume
+ *------------------------------------------------------------------------*/
+static int
+usb_resume(device_t dev)
+{
+ struct usb_bus *bus = device_get_softc(dev);
+
+ DPRINTF("\n");
+
+ if (bus == NULL) {
+ /* was never setup properly */
+ return (0);
+ }
+
+ USB_BUS_LOCK(bus);
+ usb_proc_msignal(&bus->explore_proc,
+ &bus->resume_msg[0], &bus->resume_msg[1]);
+ USB_BUS_UNLOCK(bus);
+
+ return (0);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_shutdown
+ *------------------------------------------------------------------------*/
+static int
+usb_shutdown(device_t dev)
+{
+ struct usb_bus *bus = device_get_softc(dev);
+
+ DPRINTF("\n");
+
+ if (bus == NULL) {
+ /* was never setup properly */
+ return (0);
+ }
+
+ USB_BUS_LOCK(bus);
+ usb_proc_msignal(&bus->explore_proc,
+ &bus->shutdown_msg[0], &bus->shutdown_msg[1]);
+ USB_BUS_UNLOCK(bus);
+
+ return (0);
+}
+
+/*------------------------------------------------------------------------*
* usb_bus_explore
*
* This function is used to explore the device tree from the root.
@@ -226,6 +299,9 @@ usb_bus_explore(struct usb_proc_msg *pm)
bus = ((struct usb_bus_msg *)pm)->bus;
udev = bus->devices[USB_ROOT_HUB_ADDR];
+ if (bus->no_explore != 0)
+ return;
+
if (udev && udev->hub) {
if (bus->do_probe) {
@@ -296,6 +372,133 @@ usb_bus_detach(struct usb_proc_msg *pm)
bus->bdev = NULL;
}
+/*------------------------------------------------------------------------*
+ * usb_bus_suspend
+ *
+ * This function is used to suspend the USB contoller.
+ *------------------------------------------------------------------------*/
+static void
+usb_bus_suspend(struct usb_proc_msg *pm)
+{
+ struct usb_bus *bus;
+ struct usb_device *udev;
+ usb_error_t err;
+
+ bus = ((struct usb_bus_msg *)pm)->bus;
+ udev = bus->devices[USB_ROOT_HUB_ADDR];
+
+ if (udev == NULL || bus->bdev == NULL)
+ return;
+
+ bus_generic_shutdown(bus->bdev);
+
+ usbd_enum_lock(udev);
+
+ err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
+ if (err)
+ device_printf(bus->bdev, "Could not unconfigure root HUB\n");
+
+ USB_BUS_LOCK(bus);
+ bus->hw_power_state = 0;
+ bus->no_explore = 1;
+ USB_BUS_UNLOCK(bus);
+
+ if (bus->methods->set_hw_power != NULL)
+ (bus->methods->set_hw_power) (bus);
+
+ if (bus->methods->set_hw_power_sleep != NULL)
+ (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SUSPEND);
+
+ usbd_enum_unlock(udev);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bus_resume
+ *
+ * This function is used to resume the USB contoller.
+ *------------------------------------------------------------------------*/
+static void
+usb_bus_resume(struct usb_proc_msg *pm)
+{
+ struct usb_bus *bus;
+ struct usb_device *udev;
+ usb_error_t err;
+
+ bus = ((struct usb_bus_msg *)pm)->bus;
+ udev = bus->devices[USB_ROOT_HUB_ADDR];
+
+ if (udev == NULL || bus->bdev == NULL)
+ return;
+
+ usbd_enum_lock(udev);
+#if 0
+ DEVMETHOD(usb_take_controller, NULL); /* dummy */
+#endif
+ USB_TAKE_CONTROLLER(device_get_parent(bus->bdev));
+
+ USB_BUS_LOCK(bus);
+ bus->hw_power_state =
+ USB_HW_POWER_CONTROL |
+ USB_HW_POWER_BULK |
+ USB_HW_POWER_INTERRUPT |
+ USB_HW_POWER_ISOC |
+ USB_HW_POWER_NON_ROOT_HUB;
+ bus->no_explore = 0;
+ USB_BUS_UNLOCK(bus);
+
+ if (bus->methods->set_hw_power_sleep != NULL)
+ (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_RESUME);
+
+ if (bus->methods->set_hw_power != NULL)
+ (bus->methods->set_hw_power) (bus);
+
+ err = usbd_set_config_index(udev, 0);
+ if (err)
+ device_printf(bus->bdev, "Could not configure root HUB\n");
+
+ usbd_enum_unlock(udev);
+}
+
+/*------------------------------------------------------------------------*
+ * usb_bus_shutdown
+ *
+ * This function is used to shutdown the USB contoller.
+ *------------------------------------------------------------------------*/
+static void
+usb_bus_shutdown(struct usb_proc_msg *pm)
+{
+ struct usb_bus *bus;
+ struct usb_device *udev;
+ usb_error_t err;
+
+ bus = ((struct usb_bus_msg *)pm)->bus;
+ udev = bus->devices[USB_ROOT_HUB_ADDR];
+
+ if (udev == NULL || bus->bdev == NULL)
+ return;
+
+ bus_generic_shutdown(bus->bdev);
+
+ usbd_enum_lock(udev);
+
+ err = usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
+ if (err)
+ device_printf(bus->bdev, "Could not unconfigure root HUB\n");
+
+ USB_BUS_LOCK(bus);
+ bus->hw_power_state = 0;
+ bus->no_explore = 1;
+ USB_BUS_UNLOCK(bus);
+
+ if (bus->methods->set_hw_power != NULL)
+ (bus->methods->set_hw_power) (bus);
+
+ if (bus->methods->set_hw_power_sleep != NULL)
+ (bus->methods->set_hw_power_sleep) (bus, USB_HW_POWER_SHUTDOWN);
+
+ usbd_enum_unlock(udev);
+}
+
static void
usb_power_wdog(void *arg)
{
@@ -374,8 +577,6 @@ usb_bus_attach(struct usb_proc_msg *pm)
return;
}
- USB_BUS_UNLOCK(bus);
-
/* default power_mask value */
bus->hw_power_state =
USB_HW_POWER_CONTROL |
@@ -384,13 +585,15 @@ usb_bus_attach(struct usb_proc_msg *pm)
USB_HW_POWER_ISOC |
USB_HW_POWER_NON_ROOT_HUB;
+ USB_BUS_UNLOCK(bus);
+
/* make sure power is set at least once */
if (bus->methods->set_hw_power != NULL) {
(bus->methods->set_hw_power) (bus);
}
- /* Allocate the Root USB device */
+ /* allocate the Root USB device */
child = usb_alloc_device(bus->bdev, bus, NULL, 0, 0, 1,
speed, USB_MODE_HOST);
@@ -456,6 +659,21 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
bus->attach_msg[1].hdr.pm_callback = &usb_bus_attach;
bus->attach_msg[1].bus = bus;
+ bus->suspend_msg[0].hdr.pm_callback = &usb_bus_suspend;
+ bus->suspend_msg[0].bus = bus;
+ bus->suspend_msg[1].hdr.pm_callback = &usb_bus_suspend;
+ bus->suspend_msg[1].bus = bus;
+
+ bus->resume_msg[0].hdr.pm_callback = &usb_bus_resume;
+ bus->resume_msg[0].bus = bus;
+ bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume;
+ bus->resume_msg[1].bus = bus;
+
+ bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown;
+ bus->shutdown_msg[0].bus = bus;
+ bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;
+ bus->shutdown_msg[1].bus = bus;
+
/* Create USB explore and callback processes */
if (usb_proc_create(&bus->giant_callback_proc,
@@ -477,10 +695,8 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
} else {
/* Get final attach going */
USB_BUS_LOCK(bus);
- if (usb_proc_msignal(&bus->explore_proc,
- &bus->attach_msg[0], &bus->attach_msg[1])) {
- /* ignore */
- }
+ usb_proc_msignal(&bus->explore_proc,
+ &bus->attach_msg[0], &bus->attach_msg[1]);
USB_BUS_UNLOCK(bus);
/* Do initial explore */
@@ -602,4 +818,3 @@ usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
mtx_destroy(&bus->bus_mtx);
}
-
diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c
index b98043e..612bc81 100644
--- a/sys/dev/usb/controller/uss820dci.c
+++ b/sys/dev/usb/controller/uss820dci.c
@@ -1513,16 +1513,16 @@ uss820dci_uninit(struct uss820dci_softc *sc)
USB_BUS_UNLOCK(&sc->sc_bus);
}
-void
+static void
uss820dci_suspend(struct uss820dci_softc *sc)
{
- return;
+ /* TODO */
}
-void
+static void
uss820dci_resume(struct uss820dci_softc *sc)
{
- return;
+ /* TODO */
}
static void
@@ -2360,6 +2360,26 @@ uss820dci_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc
}
}
+static void
+uss820dci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct uss820dci_softc *sc = USS820_DCI_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ uss820dci_suspend(sc);
+ break;
+ case USB_HW_POWER_SHUTDOWN:
+ uss820dci_uninit(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ uss820dci_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
struct usb_bus_methods uss820dci_bus_methods =
{
.endpoint_init = &uss820dci_ep_init,
@@ -2370,4 +2390,5 @@ struct usb_bus_methods uss820dci_bus_methods =
.clear_stall = &uss820dci_clear_stall,
.roothub_exec = &uss820dci_roothub_exec,
.xfer_poll = &uss820dci_do_poll,
+ .set_hw_power_sleep = uss820dci_set_hw_power_sleep,
};
diff --git a/sys/dev/usb/controller/uss820dci.h b/sys/dev/usb/controller/uss820dci.h
index e158c1c..8a27f15 100644
--- a/sys/dev/usb/controller/uss820dci.h
+++ b/sys/dev/usb/controller/uss820dci.h
@@ -349,8 +349,6 @@ struct uss820dci_softc {
usb_error_t uss820dci_init(struct uss820dci_softc *sc);
void uss820dci_uninit(struct uss820dci_softc *sc);
-void uss820dci_suspend(struct uss820dci_softc *sc);
-void uss820dci_resume(struct uss820dci_softc *sc);
void uss820dci_interrupt(struct uss820dci_softc *sc);
#endif /* _USS820_DCI_H_ */
diff --git a/sys/dev/usb/controller/uss820dci_atmelarm.c b/sys/dev/usb/controller/uss820dci_atmelarm.c
index e3742b8..7fd83a2 100644
--- a/sys/dev/usb/controller/uss820dci_atmelarm.c
+++ b/sys/dev/usb/controller/uss820dci_atmelarm.c
@@ -63,18 +63,15 @@ __FBSDID("$FreeBSD$");
static device_probe_t uss820_atmelarm_probe;
static device_attach_t uss820_atmelarm_attach;
static device_detach_t uss820_atmelarm_detach;
-static device_suspend_t uss820_atmelarm_suspend;
-static device_resume_t uss820_atmelarm_resume;
-static device_shutdown_t uss820_atmelarm_shutdown;
static device_method_t uss820dci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uss820_atmelarm_probe),
DEVMETHOD(device_attach, uss820_atmelarm_attach),
DEVMETHOD(device_detach, uss820_atmelarm_detach),
- DEVMETHOD(device_suspend, uss820_atmelarm_suspend),
- DEVMETHOD(device_resume, uss820_atmelarm_resume),
- DEVMETHOD(device_shutdown, uss820_atmelarm_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
@@ -93,47 +90,6 @@ MODULE_DEPEND(uss820, usb, 1, 1, 1);
static const char *const uss820_desc = "USS820 USB Device Controller";
static int
-uss820_atmelarm_suspend(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_suspend(dev);
- if (err == 0) {
- uss820dci_suspend(sc);
- }
- return (err);
-}
-
-static int
-uss820_atmelarm_resume(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- int err;
-
- uss820dci_resume(sc);
-
- err = bus_generic_resume(dev);
-
- return (err);
-}
-
-static int
-uss820_atmelarm_shutdown(device_t dev)
-{
- struct uss820dci_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- uss820dci_uninit(sc);
-
- return (0);
-}
-
-static int
uss820_atmelarm_probe(device_t dev)
{
device_set_desc(dev, uss820_desc);
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index 75b3af8..80877ac 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -58,23 +58,22 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_pci.h>
#include <dev/usb/controller/xhci.h>
#include <dev/usb/controller/xhcireg.h>
+#include "usb_if.h"
static device_probe_t xhci_pci_probe;
static device_attach_t xhci_pci_attach;
static device_detach_t xhci_pci_detach;
-static device_suspend_t xhci_pci_suspend;
-static device_resume_t xhci_pci_resume;
-static device_shutdown_t xhci_pci_shutdown;
-static void xhci_pci_takecontroller(device_t);
+static usb_take_controller_t xhci_pci_take_controller;
static device_method_t xhci_device_methods[] = {
/* device interface */
DEVMETHOD(device_probe, xhci_pci_probe),
DEVMETHOD(device_attach, xhci_pci_attach),
DEVMETHOD(device_detach, xhci_pci_detach),
- DEVMETHOD(device_suspend, xhci_pci_suspend),
- DEVMETHOD(device_resume, xhci_pci_resume),
- DEVMETHOD(device_shutdown, xhci_pci_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(usb_take_controller, xhci_pci_take_controller),
DEVMETHOD_END
};
@@ -90,45 +89,6 @@ static devclass_t xhci_devclass;
DRIVER_MODULE(xhci, pci, xhci_driver, xhci_devclass, 0, 0);
MODULE_DEPEND(xhci, usb, 1, 1, 1);
-static int
-xhci_pci_suspend(device_t self)
-{
- struct xhci_softc *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- xhci_suspend(sc);
- return (0);
-}
-
-static int
-xhci_pci_resume(device_t self)
-{
- struct xhci_softc *sc = device_get_softc(self);
-
- xhci_pci_takecontroller(self);
- xhci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-xhci_pci_shutdown(device_t self)
-{
- struct xhci_softc *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- xhci_shutdown(sc);
-
- return (0);
-}
static const char *
xhci_pci_match(device_t self)
@@ -209,7 +169,7 @@ xhci_pci_attach(device_t self)
sc->sc_intr_hdl = NULL;
goto error;
}
- xhci_pci_takecontroller(self);
+ xhci_pci_take_controller(self);
err = xhci_halt_controller(sc);
@@ -268,8 +228,8 @@ xhci_pci_detach(device_t self)
return (0);
}
-static void
-xhci_pci_takecontroller(device_t self)
+static int
+xhci_pci_take_controller(device_t self)
{
struct xhci_softc *sc = device_get_softc(self);
uint32_t cparams;
@@ -312,4 +272,5 @@ xhci_pci_takecontroller(device_t self)
usb_pause_mtx(NULL, hz / 100); /* wait 10ms */
}
}
+ return (0);
}
diff --git a/sys/dev/usb/usb_bus.h b/sys/dev/usb/usb_bus.h
index 1dd9d6a..07207cf 100644
--- a/sys/dev/usb/usb_bus.h
+++ b/sys/dev/usb/usb_bus.h
@@ -69,6 +69,9 @@ struct usb_bus {
struct usb_bus_msg explore_msg[2];
struct usb_bus_msg detach_msg[2];
struct usb_bus_msg attach_msg[2];
+ struct usb_bus_msg suspend_msg[2];
+ struct usb_bus_msg resume_msg[2];
+ struct usb_bus_msg shutdown_msg[2];
/*
* This mutex protects the USB hardware:
*/
@@ -98,7 +101,8 @@ struct usb_bus {
enum usb_revision usbrev; /* USB revision. See "USB_REV_XXX". */
uint8_t devices_max; /* maximum number of USB devices */
- uint8_t do_probe; /* set if USB BUS should be re-probed */
+ uint8_t do_probe; /* set if USB should be re-probed */
+ uint8_t no_explore; /* don't explore USB ports */
/*
* The scratch area can only be used inside the explore thread
diff --git a/sys/dev/usb/usb_controller.h b/sys/dev/usb/usb_controller.h
index 6b15dab..4ffc041 100644
--- a/sys/dev/usb/usb_controller.h
+++ b/sys/dev/usb/usb_controller.h
@@ -66,7 +66,7 @@ struct usb_bus_methods {
void (*device_suspend) (struct usb_device *);
void (*device_resume) (struct usb_device *);
void (*set_hw_power) (struct usb_bus *);
-
+ void (*set_hw_power_sleep) (struct usb_bus *, uint32_t);
/*
* The following flag is set if one or more control transfers are
* active:
@@ -92,6 +92,18 @@ struct usb_bus_methods {
* are present on the given USB bus:
*/
#define USB_HW_POWER_NON_ROOT_HUB 0x10
+ /*
+ * The following flag is set if we are suspending
+ */
+#define USB_HW_POWER_SUSPEND 0x20
+ /*
+ * The following flag is set if we are resuming
+ */
+#define USB_HW_POWER_RESUME 0x40
+ /*
+ * The following flag is set if we are shutting down
+ */
+#define USB_HW_POWER_SHUTDOWN 0x60
/* USB Device mode only - Mandatory */
diff --git a/sys/dev/usb/usb_if.m b/sys/dev/usb/usb_if.m
index 926a237..b24fc2b 100644
--- a/sys/dev/usb/usb_if.m
+++ b/sys/dev/usb/usb_if.m
@@ -54,3 +54,13 @@ METHOD int handle_request {
uint16_t offset; /* data offset */
uint8_t *pstate; /* set if transfer is complete, see USB_HR_XXX */
};
+
+# Take controller from BIOS
+#
+# Return values:
+# 0: Success
+# Else: Failure
+#
+METHOD int take_controller {
+ device_t dev;
+};
diff --git a/sys/mips/atheros/ar71xx_ehci.c b/sys/mips/atheros/ar71xx_ehci.c
index 1f24d7c..c04e069 100644
--- a/sys/mips/atheros/ar71xx_ehci.c
+++ b/sys/mips/atheros/ar71xx_ehci.c
@@ -65,53 +65,11 @@ struct ar71xx_ehci_softc {
static device_attach_t ar71xx_ehci_attach;
static device_detach_t ar71xx_ehci_detach;
-static device_shutdown_t ar71xx_ehci_shutdown;
-static device_suspend_t ar71xx_ehci_suspend;
-static device_resume_t ar71xx_ehci_resume;
bs_r_1_proto(reversed);
bs_w_1_proto(reversed);
static int
-ar71xx_ehci_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-ar71xx_ehci_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ar71xx_ehci_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
-
- return (0);
-}
-
-static int
ar71xx_ehci_probe(device_t self)
{
@@ -280,17 +238,17 @@ static device_method_t ehci_methods[] = {
DEVMETHOD(device_probe, ar71xx_ehci_probe),
DEVMETHOD(device_attach, ar71xx_ehci_attach),
DEVMETHOD(device_detach, ar71xx_ehci_detach),
- DEVMETHOD(device_suspend, ar71xx_ehci_suspend),
- DEVMETHOD(device_resume, ar71xx_ehci_resume),
- DEVMETHOD(device_shutdown, ar71xx_ehci_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(struct ar71xx_ehci_softc),
+ .name = "ehci",
+ .methods = ehci_methods,
+ .size = sizeof(struct ar71xx_ehci_softc),
};
static devclass_t ehci_devclass;
diff --git a/sys/mips/atheros/ar71xx_ohci.c b/sys/mips/atheros/ar71xx_ohci.c
index 9e0a63f..6292372 100644
--- a/sys/mips/atheros/ar71xx_ohci.c
+++ b/sys/mips/atheros/ar71xx_ohci.c
@@ -194,15 +194,17 @@ static device_method_t ohci_methods[] = {
DEVMETHOD(device_probe, ar71xx_ohci_probe),
DEVMETHOD(device_attach, ar71xx_ohci_attach),
DEVMETHOD(device_detach, ar71xx_ohci_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_driver = {
- "ohci",
- ohci_methods,
- sizeof(struct ar71xx_ohci_softc),
+ .name = "ohci",
+ .methods = ohci_methods,
+ .size = sizeof(struct ar71xx_ohci_softc),
};
static devclass_t ohci_devclass;
diff --git a/sys/mips/cavium/usb/octusb.c b/sys/mips/cavium/usb/octusb.c
index d8ea9fb..9d6884b 100644
--- a/sys/mips/cavium/usb/octusb.c
+++ b/sys/mips/cavium/usb/octusb.c
@@ -913,16 +913,16 @@ octusb_uninit(struct octusb_softc *sc)
}
-void
+static void
octusb_suspend(struct octusb_softc *sc)
{
-
+ /* TODO */
}
-void
+static void
octusb_resume(struct octusb_softc *sc)
{
-
+ /* TODO */
}
/*------------------------------------------------------------------------*
@@ -1908,6 +1908,26 @@ octusb_set_hw_power(struct usb_bus *bus)
DPRINTF("Nothing to do.\n");
}
+static void
+octusb_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
+{
+ struct octusb_softc *sc = OCTUSB_BUS2SC(bus);
+
+ switch (state) {
+ case USB_HW_POWER_SUSPEND:
+ octusb_suspend(sc);
+ break;
+ case USB_HW_POWER_SHUTDOWN:
+ octusb_uninit(sc);
+ break;
+ case USB_HW_POWER_RESUME:
+ octusb_resume(sc);
+ break;
+ default:
+ break;
+ }
+}
+
struct usb_bus_methods octusb_bus_methods = {
.endpoint_init = octusb_ep_init,
.xfer_setup = octusb_xfer_setup,
@@ -1916,6 +1936,7 @@ struct usb_bus_methods octusb_bus_methods = {
.device_resume = octusb_device_resume,
.device_suspend = octusb_device_suspend,
.set_hw_power = octusb_set_hw_power,
+ .set_hw_power_sleep = octusb_set_hw_power_sleep,
.roothub_exec = octusb_roothub_exec,
.xfer_poll = octusb_do_poll,
};
diff --git a/sys/mips/cavium/usb/octusb.h b/sys/mips/cavium/usb/octusb.h
index 31f4fc0..41320ef 100644
--- a/sys/mips/cavium/usb/octusb.h
+++ b/sys/mips/cavium/usb/octusb.h
@@ -140,8 +140,6 @@ struct octusb_softc {
usb_bus_mem_cb_t octusb_iterate_hw_softc;
usb_error_t octusb_init(struct octusb_softc *);
usb_error_t octusb_uninit(struct octusb_softc *);
-void octusb_suspend(struct octusb_softc *);
-void octusb_resume(struct octusb_softc *);
void octusb_interrupt(struct octusb_softc *);
#endif /* _OCTUSB_H_ */
diff --git a/sys/mips/cavium/usb/octusb_octeon.c b/sys/mips/cavium/usb/octusb_octeon.c
index d160eda..4448f4e 100644
--- a/sys/mips/cavium/usb/octusb_octeon.c
+++ b/sys/mips/cavium/usb/octusb_octeon.c
@@ -182,36 +182,23 @@ octusb_octeon_detach(device_t dev)
return (0);
}
-static int
-octusb_octeon_shutdown(device_t dev)
-{
- struct octusb_octeon_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- octusb_uninit(&sc->sc_dci);
-
- return (0);
-}
-
static device_method_t octusb_octeon_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, octusb_octeon_identify),
DEVMETHOD(device_probe, octusb_octeon_probe),
DEVMETHOD(device_attach, octusb_octeon_attach),
DEVMETHOD(device_detach, octusb_octeon_detach),
- DEVMETHOD(device_shutdown, octusb_octeon_shutdown),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t octusb_octeon_driver = {
- "octusb",
- octusb_octeon_methods,
- sizeof(struct octusb_octeon_softc),
+ .name = "octusb",
+ .methods = octusb_octeon_methods,
+ .size = sizeof(struct octusb_octeon_softc),
};
static devclass_t octusb_octeon_devclass;
diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c
index 4870872..c4ae065 100644
--- a/sys/mips/rmi/xls_ehci.c
+++ b/sys/mips/rmi/xls_ehci.c
@@ -69,50 +69,8 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/controller/ehcireg.h>
#include <mips/rmi/pic.h>
-static int ehci_xls_attach(device_t self);
-static int ehci_xls_detach(device_t self);
-static int ehci_xls_shutdown(device_t self);
-static int ehci_xls_suspend(device_t self);
-static int ehci_xls_resume(device_t self);
-
-static int
-ehci_xls_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_suspend(sc);
- return (0);
-}
-
-static int
-ehci_xls_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_resume(sc);
-
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_xls_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
-
- return (0);
-}
+static device_attach_t ehci_xls_attach;
+static device_detach_t ehci_xls_detach;
static const char *xlr_usb_dev_desc = "RMI XLR USB 2.0 controller";
static const char *xlr_vendor_desc = "RMI Corp";
@@ -248,17 +206,17 @@ static device_method_t ehci_methods[] = {
DEVMETHOD(device_probe, ehci_xls_probe),
DEVMETHOD(device_attach, ehci_xls_attach),
DEVMETHOD(device_detach, ehci_xls_detach),
- DEVMETHOD(device_suspend, ehci_xls_suspend),
- DEVMETHOD(device_resume, ehci_xls_resume),
- DEVMETHOD(device_shutdown, ehci_xls_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(struct ehci_softc),
+ .name = "ehci",
+ .methods = ehci_methods,
+ .size = sizeof(struct ehci_softc),
};
static devclass_t ehci_devclass;
diff --git a/sys/mips/rt305x/rt305x_dotg.c b/sys/mips/rt305x/rt305x_dotg.c
index 67666f7..89b4933 100644
--- a/sys/mips/rt305x/rt305x_dotg.c
+++ b/sys/mips/rt305x/rt305x_dotg.c
@@ -67,7 +67,6 @@ __FBSDID("$FreeBSD$");
static device_probe_t dotg_obio_probe;
static device_attach_t dotg_obio_attach;
static device_detach_t dotg_obio_detach;
-static device_shutdown_t dotg_obio_shutdown;
struct dotg_obio_softc {
struct dotg_softc sc_dci; /* must be first */
@@ -208,35 +207,22 @@ dotg_obio_detach(device_t dev)
return (0);
}
-static int
-dotg_obio_shutdown(device_t dev)
-{
- struct dotg_obio_softc *sc = device_get_softc(dev);
- int err;
-
- err = bus_generic_shutdown(dev);
- if (err)
- return (err);
-
- dotg_uninit(&sc->sc_dci);
-
- return (0);
-}
-
static device_method_t dotg_obio_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, dotg_obio_probe),
DEVMETHOD(device_attach, dotg_obio_attach),
DEVMETHOD(device_detach, dotg_obio_detach),
- DEVMETHOD(device_shutdown, dotg_obio_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t dotg_obio_driver = {
- "dotg",
- dotg_obio_methods,
- sizeof(struct dotg_obio_softc),
+ .name = "dotg",
+ .methods = dotg_obio_methods,
+ .size = sizeof(struct dotg_obio_softc),
};
static devclass_t dotg_obio_devclass;
diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile
index abcfcbe..3df35bc 100644
--- a/sys/modules/usb/Makefile
+++ b/sys/modules/usb/Makefile
@@ -26,7 +26,7 @@
#
SUBDIR = usb
-SUBDIR += ehci musb ohci uhci xhci uss820dci ${_at91dci} ${_atmegadci}
+SUBDIR += ehci musb ohci uhci xhci uss820dci ${_at91dci} ${_atmegadci} ${_avr32dci}
SUBDIR += rum run uath upgt usie ural zyd ${_urtw}
SUBDIR += atp uhid ukbd ums udbp ufm uep
SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \
@@ -48,4 +48,8 @@ _atmegadci= atmegadci
_urtw= urtw
.endif
+.if ${MACHINE_CPUARCH} == "avr32"
+_avr32dci= avr32dci
+.endif
+
.include <bsd.subdir.mk>
diff --git a/sys/modules/usb/avr32dci/Makefile b/sys/modules/usb/avr32dci/Makefile
new file mode 100644
index 0000000..ea7d9c2
--- /dev/null
+++ b/sys/modules/usb/avr32dci/Makefile
@@ -0,0 +1,38 @@
+#
+# $FreeBSD$
+#
+# Copyright (c) 2011 Hans Petter Selasky. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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.
+#
+
+S= ${.CURDIR}/../../..
+
+.PATH: $S/dev/usb/controller
+
+KMOD= avr32dci
+SRCS= bus_if.h device_if.h usb_if.h \
+ opt_bus.h opt_usb.h \
+ avr32dci.c \
+ pci_if.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/powerpc/ps3/ehci_ps3.c b/sys/powerpc/ps3/ehci_ps3.c
index c85c9bb..d516160 100644
--- a/sys/powerpc/ps3/ehci_ps3.c
+++ b/sys/powerpc/ps3/ehci_ps3.c
@@ -152,14 +152,17 @@ static device_method_t ehci_ps3_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ehci_ps3_probe),
DEVMETHOD(device_attach, ehci_ps3_attach),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ehci_ps3_driver = {
- "ehci",
- ehci_ps3_methods,
- sizeof(ehci_softc_t),
+ .name = "ehci",
+ .methods = ehci_ps3_methods,
+ .size = sizeof(ehci_softc_t),
};
static devclass_t ehci_ps3_devclass;
diff --git a/sys/powerpc/ps3/ohci_ps3.c b/sys/powerpc/ps3/ohci_ps3.c
index c16daba..a047617 100644
--- a/sys/powerpc/ps3/ohci_ps3.c
+++ b/sys/powerpc/ps3/ohci_ps3.c
@@ -150,14 +150,17 @@ static device_method_t ohci_ps3_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ohci_ps3_probe),
DEVMETHOD(device_attach, ohci_ps3_attach),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD_END
};
static driver_t ohci_ps3_driver = {
- "ohci",
- ohci_ps3_methods,
- sizeof(ohci_softc_t),
+ .name = "ohci",
+ .methods = ohci_ps3_methods,
+ .size = sizeof(ohci_softc_t),
};
static devclass_t ohci_ps3_devclass;
OpenPOWER on IntegriCloud