Ticket #8085: usbOHCIStartupV1.diff

File usbOHCIStartupV1.diff, 3.1 KB (added by kallisti5, 8 years ago)
  • src/add-ons/kernel/busses/usb/ohci.cpp

    diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp
    index c9f2c1a..c61f631 100644
    a b OHCI::OHCI(pci_info *info, Stack *stack)  
    204204    fInterruptEndpoints[0]->next_physical_endpoint
    205205        = fDummyIsochronous->physical_address;
    206206
    207     // Disable all interrupts before handoff/reset
    208     _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
    209 
    210207    // Determine in what context we are running (Kindly copied from FreeBSD)
    211208    uint32 control = _ReadReg(OHCI_CONTROL);
    212     if (control & OHCI_INTERRUPT_ROUTING) {
     209    if ((control & OHCI_INTERRUPT_ROUTING) != 0) {
     210        // SMM in control, ask for control of USB
    213211        TRACE_ALWAYS("smm is in control of the host controller\n");
    214212        uint32 status = _ReadReg(OHCI_COMMAND_STATUS);
    215213        _WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST);
    OHCI::OHCI(pci_info *info, Stack *stack)  
    219217        }
    220218
    221219        if ((control & OHCI_INTERRUPT_ROUTING) != 0) {
    222             TRACE_ERROR("smm does not respond. resetting...\n");
     220            TRACE_ERROR("smm is not responding. Resetting...\n");
     221            // Last resort
    223222            _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
    224223            snooze(USB_DELAY_BUS_RESET);
    225         } else
     224        } else {
    226225            TRACE_ALWAYS("ownership change successful\n");
     226            // Disable all interrupts
     227            _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
     228        }
    227229    } else {
    228         TRACE("cold started\n");
    229         snooze(USB_DELAY_BUS_RESET);
     230        // SMM *not* in control, resume or reset USB bus
     231        // Disable all interrupts
     232        _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS);
     233        control = _ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_MASK;
     234        if ((control & OHCI_HC_FUNCTIONAL_STATE_RESET) == 0) {
     235            TRACE("no smm, BIOS active. Attempting resume...\n");
     236            if ((control & OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) == 0) {
     237                _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESUME);
     238                for (uint32 i = 0; i < 100
     239                    && !(control & OHCI_HC_FUNCTIONAL_STATE_RESUME); i++) {
     240                    snooze(1000);
     241                    control = _ReadReg(OHCI_CONTROL)
     242                        & OHCI_HC_FUNCTIONAL_STATE_MASK;
     243                }
     244                if ((control & OHCI_HC_FUNCTIONAL_STATE_RESUME) == 0)
     245                    TRACE_ALWAYS("failed to resume controller\n");
     246            } else {
     247                TRACE_ALWAYS("bus not reset, and not operational?\n");
     248            }
     249        } else {
     250            TRACE("no smm, no BIOS. Attempting reset...\n");
     251
     252            _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
     253            snooze(USB_DELAY_BUS_RESET);
     254            for (uint32 i = 0; i < 100
     255                && !(control & OHCI_HC_FUNCTIONAL_STATE_RESET); i++) {
     256                snooze(1000);
     257                control = _ReadReg(OHCI_CONTROL)
     258                    & OHCI_HC_FUNCTIONAL_STATE_MASK;
     259            }
     260            if ((control & OHCI_HC_FUNCTIONAL_STATE_RESET) == 0)
     261                TRACE_ALWAYS("failed to reset controller\n");
     262        }
    230263    }
    231264
     265    #if 0
    232266    // This reset should not be necessary according to the OHCI spec, but
    233267    // without it some controllers do not start.
    234268    _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET);
    235269    snooze(USB_DELAY_BUS_RESET);
     270    #endif
    236271
    237272    // We now own the host controller and the bus has been reset
    238273    uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL);