Enable support for DEVICE_SUSPEND, DEVICE_RESUME and DEVICE_SHUTDOWN
methods for USB devices in the same way of uhci driver. But this change is not complete because some ohci controlers are not initialized completely. So "kernel: usb0: 1 scheduling overruns" interrupt will generate many times. This change will be same one in PR kern/60099. Discussed on [bsd-nomads:16737] - [bsd-nomads:16746].
This commit is contained in:
parent
64493776c7
commit
8eac066005
@ -1001,7 +1001,6 @@ ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
|
||||
/*
|
||||
* Shut down the controller when the system is going down.
|
||||
*/
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
void
|
||||
ohci_shutdown(void *v)
|
||||
{
|
||||
@ -1031,9 +1030,7 @@ ohci_power(int why, void *v)
|
||||
#endif
|
||||
|
||||
s = splhardusb();
|
||||
switch (why) {
|
||||
case PWR_SUSPEND:
|
||||
case PWR_STANDBY:
|
||||
if (why != PWR_RESUME) {
|
||||
sc->sc_bus.use_polling++;
|
||||
ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
|
||||
if (sc->sc_control == 0) {
|
||||
@ -1048,8 +1045,7 @@ ohci_power(int why, void *v)
|
||||
OWRITE4(sc, OHCI_CONTROL, ctl);
|
||||
usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
|
||||
sc->sc_bus.use_polling--;
|
||||
break;
|
||||
case PWR_RESUME:
|
||||
} else {
|
||||
sc->sc_bus.use_polling++;
|
||||
/* Some broken BIOSes do not recover these values */
|
||||
OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
|
||||
@ -1070,15 +1066,9 @@ ohci_power(int why, void *v)
|
||||
usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
|
||||
sc->sc_control = sc->sc_intre = 0;
|
||||
sc->sc_bus.use_polling--;
|
||||
break;
|
||||
case PWR_SOFTSUSPEND:
|
||||
case PWR_SOFTSTANDBY:
|
||||
case PWR_SOFTRESUME:
|
||||
break;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
void
|
||||
|
@ -119,6 +119,44 @@ static const char *ohci_device_generic = "OHCI (generic) USB controller";
|
||||
|
||||
static int ohci_pci_attach(device_t self);
|
||||
static int ohci_pci_detach(device_t self);
|
||||
static int ohci_pci_suspend(device_t self);
|
||||
static int ohci_pci_resume(device_t self);
|
||||
|
||||
static int
|
||||
ohci_pci_suspend(device_t self)
|
||||
{
|
||||
ohci_softc_t *sc = device_get_softc(self);
|
||||
int err;
|
||||
|
||||
err = bus_generic_suspend(self);
|
||||
if (err)
|
||||
return err;
|
||||
ohci_power(PWR_SUSPEND, sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ohci_pci_resume(device_t self)
|
||||
{
|
||||
ohci_softc_t *sc = device_get_softc(self);
|
||||
u_int32_t reg, int_line;
|
||||
|
||||
if (pci_get_powerstate(self) != PCI_POWERSTATE_D0) {
|
||||
device_printf(self, "chip is in D%d mode "
|
||||
"-- setting to D0\n", pci_get_powerstate(self));
|
||||
reg = pci_read_config(self, PCI_CBMEM, 4);
|
||||
int_line = pci_read_config(self, PCIR_INTLINE, 4);
|
||||
pci_set_powerstate(self, PCI_POWERSTATE_D0);
|
||||
pci_write_config(self, PCI_CBMEM, reg, 4);
|
||||
pci_write_config(self, PCIR_INTLINE, int_line, 4);
|
||||
}
|
||||
|
||||
ohci_power(PWR_RESUME, sc);
|
||||
bus_generic_resume(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
ohci_pci_match(device_t self)
|
||||
@ -310,6 +348,8 @@ static device_method_t ohci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, ohci_pci_probe),
|
||||
DEVMETHOD(device_attach, ohci_pci_attach),
|
||||
DEVMETHOD(device_suspend, ohci_pci_suspend),
|
||||
DEVMETHOD(device_resume, ohci_pci_resume),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
|
||||
/* Bus interface */
|
||||
|
@ -165,3 +165,6 @@ int ohci_activate(device_ptr_t, enum devact);
|
||||
#endif
|
||||
|
||||
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
|
||||
|
||||
void ohci_shutdown(void *v);
|
||||
void ohci_power(int state, void *priv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user