* Fix the check after waiting for owner change to happen and don't reset if the
handover indeed worked. Doesn't really matter though, as we reset anyway, just not twice in the success case. * Disable all interrupts and clear any pending active interrupts just after taking over the controller. This might fix bug #2361. * Also trace output when the ownership change is successful. * Don't disable interrupts during reset. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25915 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -204,7 +204,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
// Determine in what context we are running (Kindly copied from FreeBSD)
|
||||
uint32 control = _ReadReg(OHCI_CONTROL);
|
||||
if (control & OHCI_INTERRUPT_ROUTING) {
|
||||
TRACE(("usb_ohci: SMM is in control of the host controller\n"));
|
||||
TRACE(("usb_ohci: smm is in control of the host controller\n"));
|
||||
uint32 status = _ReadReg(OHCI_COMMAND_STATUS);
|
||||
_WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST);
|
||||
for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) {
|
||||
@@ -212,16 +212,22 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
control = _ReadReg(OHCI_CONTROL);
|
||||
}
|
||||
|
||||
if (!(control & OHCI_INTERRUPT_ROUTING)) {
|
||||
TRACE(("usb_ohci: SMM does not respond. Resetting...\n"));
|
||||
if ((control & OHCI_INTERRUPT_ROUTING) != 0) {
|
||||
TRACE_ERROR(("usb_ohci: smm does not respond. resetting...\n"));
|
||||
_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||
snooze(USB_DELAY_BUS_RESET);
|
||||
}
|
||||
} else
|
||||
TRACE(("usb_ohci: ownership change successful\n"));
|
||||
} else {
|
||||
TRACE(("usb_ohci: cold started\n"));
|
||||
snooze(USB_DELAY_BUS_RESET);
|
||||
}
|
||||
|
||||
// Disable all interrupts and clear any current interrupt status
|
||||
_WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS
|
||||
| OHCI_MASTER_INTERRUPT_ENABLE);
|
||||
_WriteReg(OHCI_INTERRUPT_STATUS, OHCI_ALL_INTERRUPTS);
|
||||
|
||||
// This reset should not be necessary according to the OHCI spec, but
|
||||
// without it some controllers do not start.
|
||||
_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
|
||||
@@ -232,7 +238,6 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval);
|
||||
|
||||
// Disable interrupts right before we reset
|
||||
cpu_status former = disable_interrupts();
|
||||
_WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET);
|
||||
// Nominal time for a reset is 10 us
|
||||
uint32 reset = 0;
|
||||
@@ -244,7 +249,6 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
}
|
||||
|
||||
if (reset) {
|
||||
restore_interrupts(former);
|
||||
TRACE_ERROR(("usb_ohci: Error resetting the host controller (timeout)\n"));
|
||||
return;
|
||||
}
|
||||
@@ -267,8 +271,6 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
// And finally start the controller
|
||||
_WriteReg(OHCI_CONTROL, control);
|
||||
|
||||
restore_interrupts(former);
|
||||
|
||||
// The controller is now OPERATIONAL.
|
||||
frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE)
|
||||
^ OHCI_FRAME_INTERVAL_TOGGLE;
|
||||
|
||||
Reference in New Issue
Block a user