hrev44542 adds 1 changeset to branch 'master' old head: c936a02360c7a18c49d2da5e8b8e38b6b666ead6 new head: a4bca8119323c016607b25c3d1dcec2f0d4b0010 ---------------------------------------------------------------------------- a4bca81: Add MSI support to OHCI. It looks like VirtualBox assumes MSIs when emulating a 64bit system so this gets OHCI working there. Shouldn't harm if it's used anywhere else either. [ Michael Lotz <mmlr@xxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev44542 Commit: a4bca8119323c016607b25c3d1dcec2f0d4b0010 URL: http://cgit.haiku-os.org/haiku/commit/?id=a4bca81 Author: Michael Lotz <mmlr@xxxxxxxx> Date: Wed Aug 15 19:30:08 2012 UTC ---------------------------------------------------------------------------- 2 files changed, 41 insertions(+), 2 deletions(-) src/add-ons/kernel/busses/usb/ohci.cpp | 40 ++++++++++++++++++++++++++-- src/add-ons/kernel/busses/usb/ohci.h | 3 +++ ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index c9f2c1a..df38174 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -10,6 +10,7 @@ #include <module.h> #include <PCI.h> +#include <PCI_x86.h> #include <USB3.h> #include <KernelExport.h> #include <util/AutoLock.h> @@ -19,6 +20,7 @@ #define USB_MODULE_NAME "ohci" pci_module_info *OHCI::sPCIModule = NULL; +pci_x86_module_info *OHCI::sPCIx86Module = NULL; static int32 @@ -309,10 +311,24 @@ OHCI::OHCI(pci_info *info, Stack *stack) B_URGENT_DISPLAY_PRIORITY, (void *)this); resume_thread(fFinishThread); + // Find the right interrupt vector, using MSIs if available. + uint8 interruptVector = fPCIInfo->u.h0.interrupt_line; + if (sPCIx86Module != NULL && sPCIx86Module->get_msi_count(fPCIInfo->bus, + fPCIInfo->device, fPCIInfo->function) >= 1) { + uint8 msiVector = 0; + if (sPCIx86Module->configure_msi(fPCIInfo->bus, fPCIInfo->device, + fPCIInfo->function, 1, &msiVector) == B_OK + && sPCIx86Module->enable_msi(fPCIInfo->bus, fPCIInfo->device, + fPCIInfo->function) == B_OK) { + TRACE_ALWAYS("using message signaled interrupts\n"); + interruptVector = msiVector; + } + } + // Install the interrupt handler TRACE("installing interrupt handler\n"); - install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line, - _InterruptHandler, (void *)this, 0); + install_io_interrupt_handler(interruptVector, _InterruptHandler, + (void *)this, 0); // Enable interesting interrupts now that the handler is in place _WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS @@ -538,6 +554,14 @@ OHCI::AddTo(Stack *stack) return B_NO_MEMORY; } + // Try to get the PCI x86 module as well so we can enable possible MSIs. + if (sPCIx86Module == NULL && get_module(B_PCI_X86_MODULE_NAME, + (module_info **)&sPCIx86Module) != B_OK) { + // If it isn't there, that's not critical though. + TRACE_MODULE_ERROR("failed to get pci x86 module\n"); + sPCIx86Module = NULL; + } + for (uint32 i = 0 ; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb && item->class_api == PCI_usb_ohci) { @@ -555,6 +579,12 @@ OHCI::AddTo(Stack *stack) delete item; sPCIModule = NULL; put_module(B_PCI_MODULE_NAME); + + if (sPCIx86Module != NULL) { + sPCIx86Module = NULL; + put_module(B_PCI_X86_MODULE_NAME); + } + return B_NO_MEMORY; } @@ -578,6 +608,12 @@ OHCI::AddTo(Stack *stack) delete item; sPCIModule = NULL; put_module(B_PCI_MODULE_NAME); + + if (sPCIx86Module != NULL) { + sPCIx86Module = NULL; + put_module(B_PCI_X86_MODULE_NAME); + } + return ENODEV; } diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index adf1031..fbe24c0 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -16,6 +16,7 @@ struct pci_info; struct pci_module_info; +struct pci_x86_module_info; class OHCIRootHub; typedef struct transfer_data { @@ -140,6 +141,8 @@ inline uint32 _ReadReg(uint32 reg); ohci_general_td *topDescriptor); static pci_module_info * sPCIModule; +static pci_x86_module_info * sPCIx86Module; + pci_info * fPCIInfo; Stack * fStack;