Fixed incomplete initialization in some ohci controllers with

broken BIOS. Separate ohci_controller_init() from ohci_init(),
and call ohci_controller_init() at resume process once more.

Discussed on [bsd-nomads:16737] - [bsd-nomads:16746].

Submitted by Hiroyuki Aizu <eyes@navi.org> [bsd-nomads:16741]
This commit is contained in:
Takeshi Shibagaki 2003-12-22 15:40:10 +00:00
parent 6fedff6c32
commit 8eabf88dd3

View file

@ -229,6 +229,8 @@ Static void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
Static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
Static void ohci_noop(usbd_pipe_handle pipe);
Static usbd_status ohci_controller_init(ohci_softc_t *sc);
#ifdef USB_DEBUG
Static void ohci_dumpregs(ohci_softc_t *);
Static void ohci_dump_tds(ohci_soft_td_t *);
@ -697,7 +699,7 @@ ohci_init(ohci_softc_t *sc)
ohci_soft_ed_t *sed, *psed;
usbd_status err;
int i;
u_int32_t s, ctl, ival, hcr, fm, per, rev, desca;
u_int32_t rev;
DPRINTF(("ohci_init: start\n"));
#if defined(__OpenBSD__)
@ -797,6 +799,44 @@ ohci_init(ohci_softc_t *sc)
}
#endif
err = ohci_controller_init(sc);
if (err != USBD_NORMAL_COMPLETION)
goto bad5;
/* Set up the bus struct. */
sc->sc_bus.methods = &ohci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
#if defined(__NetBSD__) || defined(__OpenBSD__)
sc->sc_control = sc->sc_intre = 0;
sc->sc_powerhook = powerhook_establish(ohci_power, sc);
sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
#endif
usb_callout_init(sc->sc_tmo_rhsc);
return (USBD_NORMAL_COMPLETION);
bad5:
for (i = 0; i < OHCI_NO_EDS; i++)
ohci_free_sed(sc, sc->sc_eds[i]);
bad4:
ohci_free_sed(sc, sc->sc_isoc_head);
bad3:
ohci_free_sed(sc, sc->sc_ctrl_head);
bad2:
ohci_free_sed(sc, sc->sc_bulk_head);
bad1:
usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
return (err);
}
Static usbd_status
ohci_controller_init(ohci_softc_t *sc)
{
int i;
u_int32_t s, ctl, ival, hcr, fm, per, desca;
/* Determine in what context we are running. */
ctl = OREAD4(sc, OHCI_CONTROL);
if (ctl & OHCI_IR) {
@ -852,8 +892,7 @@ ohci_init(ohci_softc_t *sc)
}
if (hcr) {
printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev));
err = USBD_IOERROR;
goto bad5;
return (USBD_IOERROR);
}
#ifdef USB_DEBUG
if (ohcidebug > 15)
@ -906,33 +945,7 @@ ohci_init(ohci_softc_t *sc)
if (ohcidebug > 5)
ohci_dumpregs(sc);
#endif
/* Set up the bus struct. */
sc->sc_bus.methods = &ohci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
#if defined(__NetBSD__) || defined(__OpenBSD__)
sc->sc_control = sc->sc_intre = 0;
sc->sc_powerhook = powerhook_establish(ohci_power, sc);
sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
#endif
usb_callout_init(sc->sc_tmo_rhsc);
return (USBD_NORMAL_COMPLETION);
bad5:
for (i = 0; i < OHCI_NO_EDS; i++)
ohci_free_sed(sc, sc->sc_eds[i]);
bad4:
ohci_free_sed(sc, sc->sc_isoc_head);
bad3:
ohci_free_sed(sc, sc->sc_ctrl_head);
bad2:
ohci_free_sed(sc, sc->sc_bulk_head);
bad1:
usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
return (err);
}
usbd_status
@ -1047,10 +1060,10 @@ ohci_power(int why, void *v)
sc->sc_bus.use_polling--;
} else {
sc->sc_bus.use_polling++;
/* Some broken BIOSes do not recover these values */
OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
/* Some broken BIOSes never initialize Controller chip */
ohci_controller_init(sc);
if (sc->sc_intre)
OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));