[haiku-commits] haiku: hrev44542 - src/add-ons/kernel/busses/usb

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 16 Aug 2012 00:56:17 +0200 (CEST)

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;
 


Other related posts:

  • » [haiku-commits] haiku: hrev44542 - src/add-ons/kernel/busses/usb - mmlr