diff --git a/sys/arm/econa/ehci_ebus.c b/sys/arm/econa/ehci_ebus.c index ee201485f0c9..4b72b7f6caec 100644 --- a/sys/arm/econa/ehci_ebus.c +++ b/sys/arm/econa/ehci_ebus.c @@ -75,55 +75,12 @@ __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; #define EHCI_HC_DEVSTR "CNS11XX USB EHCI" #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 ee449602ade4..543aae138154 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 f831115b6cfd..d3258127dc17 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 a1603aa660ad..b079eb5b272c 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 1e8e39494b9f..da9ba36e639f 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 ad53fc328a96..7db3bdbb44d1 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 68613af3e5e5..91ba030661f9 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 c68101ca2b0d..6c380b6076d0 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 26785a3542a5..9494c3016408 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 @@ avr32dci_data_tx(struct avr32dci_td *td) } /* 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 @@ avr32dci_roothub_exec(struct usb_device *udev, 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 6672fa76afb3..2d80344fd485 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 7e682f4fcbb1..f59c801dacdc 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,135 +585,26 @@ 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); - } - - if (hcr != EHCI_STS_HCH) { - device_printf(sc->sc_bus.bdev, - "config timeout\n"); - } - USB_BUS_UNLOCK(&sc->sc_bus); -} - -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); - - 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)); - - /* 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"); - } + /* reset HC */ + ehci_hcreset(sc); +} + +static void +ehci_resume(ehci_softc_t *sc) +{ + /* reset HC */ + ehci_hcreset(sc); + + /* setup HC */ + ehci_init_sub(sc); + + /* catch any lost interrupts */ + ehci_do_poll(&sc->sc_bus); } #ifdef USB_DEBUG @@ -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 a8aa514a006b..b8b6985df74a 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 7327fdefa122..45113d9f4e26 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); @@ -89,45 +86,6 @@ static void ehci_bs_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t); 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 f12cb14ce5cb..a47e253841c6 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); @@ -102,45 +99,6 @@ static void *ih_err; #define MV_USB_HOST_OVERFLOW (1 << 2) #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 8c19b2a1f9de..e293ec8d2c2a 100644 --- a/sys/dev/usb/controller/ehci_pci.c +++ b/sys/dev/usb/controller/ehci_pci.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#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 = -{ - .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), +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 - }, + DEVMETHOD_END +}; + +static driver_t ehci_driver = { + .name = "ehci", + .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 be32b2b5feb9..d463052d0eff 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 e8eafca6fb1d..3b889a9dfe1f 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 b301e09d48a8..bb3e60a6d455 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 fa2d60707986..93c2bb220910 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 @@ ohci_controller_init(ohci_softc_t *sc) } #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); + ohci_controller_init(sc, 0); /* catch any lost interrupts */ ohci_do_poll(&sc->sc_bus); @@ -2712,6 +2673,24 @@ ohci_device_suspend(struct usb_device *udev) return; } +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) { @@ -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 d85c2c940e1a..9d8ac7dc8321 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 177c926c01c2..643b4d17bc45 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 c8690c99f413..864376b9204d 100644 --- a/sys/dev/usb/controller/ohci_pci.c +++ b/sys/dev/usb/controller/ohci_pci.c @@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#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 = -{ - .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), +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 - }, + DEVMETHOD_END +}; + +static driver_t ohci_driver = { + .name = "ohci", + .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 b0907ad80069..225a2d201e33 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 c365e01c30a6..d9091c98e485 100644 --- a/sys/dev/usb/controller/uhci.c +++ b/sys/dev/usb/controller/uhci.c @@ -373,9 +373,10 @@ uhci_reset(uhci_softc_t *sc) 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); -#ifdef USB_DEBUG - if (uhcidebug > 2) { - uhci_dumpregs(sc); - } -#endif - USB_BUS_UNLOCK(&sc->sc_bus); +#ifdef USB_DEBUG + if (uhcidebug > 2) + uhci_dumpregs(sc); +#endif + /* catch lost interrupts */ uhci_do_poll(&sc->sc_bus); } @@ -3178,6 +3161,24 @@ uhci_device_suspend(struct usb_device *udev) return; } +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) { @@ -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 0878e798e749..8a6ce4470310 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 4b04f255a546..454b904de81a 100644 --- a/sys/dev/usb/controller/uhci_pci.c +++ b/sys/dev/usb/controller/uhci_pci.c @@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#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 7ff0bc0faf31..f31ab5b49ab5 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -61,12 +61,16 @@ #include #include #include +#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]); @@ -212,6 +216,75 @@ usb_detach(device_t dev) return (0); } +/*------------------------------------------------------------------------* + * 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 * @@ -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 b98043e5155b..612bc81bb209 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 e158c1c10f9d..8a27f15144d0 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 e3742b85fb53..7fd83a229ccd 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 }; @@ -92,47 +89,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) { diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c index 75b3af82833a..80877acabd57 100644 --- a/sys/dev/usb/controller/xhci_pci.c +++ b/sys/dev/usb/controller/xhci_pci.c @@ -58,23 +58,22 @@ __FBSDID("$FreeBSD$"); #include #include #include +#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 1dd9d6a1f8c0..07207cf6190c 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 6b15dab993d5..4ffc041ebb4d 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 926a23770060..b24fc2b386a4 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 1f24d7cc949a..c04e069b83ae 100644 --- a/sys/mips/atheros/ar71xx_ehci.c +++ b/sys/mips/atheros/ar71xx_ehci.c @@ -65,52 +65,10 @@ 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 9e0a63f075e4..629237211f5c 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 d8ea9fbce75c..9d6884bea1be 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 31f4fc0835bd..41320ef1d1a3 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 d160eda9a5f6..4448f4e5090b 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 48708722819e..c4ae06562ad9 100644 --- a/sys/mips/rmi/xls_ehci.c +++ b/sys/mips/rmi/xls_ehci.c @@ -69,50 +69,8 @@ __FBSDID("$FreeBSD$"); #include #include -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 67666f70aae1..89b493321da4 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 abcfcbebc257..3df35bc79857 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 diff --git a/sys/modules/usb/avr32dci/Makefile b/sys/modules/usb/avr32dci/Makefile new file mode 100644 index 000000000000..ea7d9c280ec4 --- /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 diff --git a/sys/powerpc/ps3/ehci_ps3.c b/sys/powerpc/ps3/ehci_ps3.c index c85c9bb4d1a2..d5161609cc91 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 c16daba13335..a047617c56ad 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;