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:
shiba 2003-12-22 15:18:46 +00:00
parent 64493776c7
commit 8eac066005
3 changed files with 45 additions and 12 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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);