USB OHCI: Fix ownership handover from SMM to OS.
* Disabling all interrupts prior to ownership handover from SMM to OS can prevent propper OHCI and PS/2 functionality as described in #8987 and #8984. In that case SMM does not respond to the ownership change request. On the other hand not disabling the interrupts can lead to interrupt storms (discussed in #8085) since no interrupt handler is installed at that moment. As suggested by mmlr this patch attempts to address both issues by keeping the ownership change request interrupt enabled. * Removed an unnecessary reset upon non-responding SMM for now, since we reset a few lines later anyway and added TODOs respectively. That should safe a bit boot time. Signed-off-by: Michael Lotz <mmlr@mlotz.ch>
This commit is contained in:
parent
c530d46cca
commit
3b98be3cc4
@ -206,8 +206,15 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
fInterruptEndpoints[0]->next_physical_endpoint
|
||||
= fDummyIsochronous->physical_address;
|
||||
|
||||
// Disable all interrupts before handoff/reset
|
||||
_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
|
||||
// When the handover from SMM takes place, all interrupts are routed to the
|
||||
// OS. As we don't yet have an interrupt handler installed at this point,
|
||||
// this may cause interrupt storms if the firmware does not disable the
|
||||
// interrupts during handover. Therefore we disable interrupts before
|
||||
// requesting ownership. We have to keep the ownership change interrupt
|
||||
// enabled though, as otherwise the SMM will not be notified of the
|
||||
// ownership change request we trigger below.
|
||||
_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS &
|
||||
~OHCI_OWNERSHIP_CHANGE) ;
|
||||
|
||||
// Determine in what context we are running (Kindly copied from FreeBSD)
|
||||
uint32 control = _ReadReg(OHCI_CONTROL);
|
||||
@ -221,9 +228,12 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
}
|
||||
|
||||
if ((control & OHCI_INTERRUPT_ROUTING) != 0) {
|
||||
TRACE_ERROR("smm does not respond. resetting...\n");
|
||||
_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||
snooze(USB_DELAY_BUS_RESET);
|
||||
TRACE_ERROR("smm does not respond.\n");
|
||||
|
||||
// TODO: Enable this reset as soon as the non-specified
|
||||
// reset a few lines later is replaced by a better solution.
|
||||
//_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||
//snooze(USB_DELAY_BUS_RESET);
|
||||
} else
|
||||
TRACE_ALWAYS("ownership change successful\n");
|
||||
} else {
|
||||
@ -231,8 +241,8 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
snooze(USB_DELAY_BUS_RESET);
|
||||
}
|
||||
|
||||
// This reset should not be necessary according to the OHCI spec, but
|
||||
// without it some controllers do not start.
|
||||
// TODO: This reset delays system boot time. It should not be necessary
|
||||
// according to the OHCI spec, but without it some controllers don't start.
|
||||
_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||
snooze(USB_DELAY_BUS_RESET);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user