mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
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:
parent
6fedff6c32
commit
8eabf88dd3
1 changed files with 46 additions and 33 deletions
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Reference in a new issue