[prev in list] [next in list] [prev in thread] [next in thread]
List: haiku-commits
Subject: [haiku-commits] haiku: hrev45932 - in src: add-ons/kernel/busses/usb libs/compat/freebsd_network add
From: korli () users ! berlios ! de
Date: 2013-07-30 22:53:32
Message-ID: 20130730225332.90B945C0BEA () vmrepo ! haiku-os ! org
[Download RAW message or body]
hrev45932 adds 6 changesets to branch 'master'
old head: cdbf478fbf2aa409e060bfb273e239b07389ccbe
new head: 96adf3ffad2c81bd60876fff16f8768e2c035c9f
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=96adf3f+%5Ecdbf478
----------------------------------------------------------------------------
656e05e: FreeBSD compat layer: implement MSI-X support.
[ Jérôme Duval <jerome.duval@gmail.com> ]
c01fadc: AHCI: add MSI support.
[ Jerome Duval <jerome.duval@gmail.com> ]
010b06a: EHCI USB: add MSI support
* similar to OHCI support by mmlr.
* interrupt handler is removed on destruction.
[ Jerome Duval <jerome.duval@gmail.com> ]
b3dbb4d: OHCI USB: disable MSI on destruction
* also remove interrupt handler and put the PCI x86 module.
[ Jerome Duval <jerome.duval@gmail.com> ]
c45ac5a: UHCI USB: add MSI support
* similar to OHCI support by mmlr.
* interrupt handler is removed on destruction.
[ Jerome Duval <jerome.duval@gmail.com> ]
96adf3f: XHCI USB: add MSI support
* similar to OHCI support by mmlr.
* interrupt handler is removed on destruction.
[ Jerome Duval <jerome.duval@gmail.com> ]
----------------------------------------------------------------------------
14 files changed, 241 insertions(+), 35 deletions(-)
src/add-ons/kernel/busses/scsi/ahci/ahci.c | 11 ++++
.../kernel/busses/scsi/ahci/ahci_controller.cpp | 24 ++++++++
.../kernel/busses/scsi/ahci/ahci_controller.h | 1 +
src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h | 2 +
src/add-ons/kernel/busses/usb/ehci.cpp | 59 +++++++++++++++++--
src/add-ons/kernel/busses/usb/ehci.h | 4 ++
src/add-ons/kernel/busses/usb/ohci.cpp | 24 ++++++--
src/add-ons/kernel/busses/usb/ohci.h | 3 +
src/add-ons/kernel/busses/usb/uhci.cpp | 36 +++++++++++-
src/add-ons/kernel/busses/usb/uhci.h | 5 ++
src/add-ons/kernel/busses/usb/xhci.cpp | 40 +++++++++++--
src/add-ons/kernel/busses/usb/xhci.h | 4 ++
src/libs/compat/freebsd_network/bus.cpp | 61 ++++++++++++++------
src/libs/compat/freebsd_network/device.h | 2 +
############################################################################
Commit: 656e05ec86375a592c360f7f4d2ea321e74cd8ff
URL: http://cgit.haiku-os.org/haiku/commit/?id=656e05e
Author: Jérôme Duval <jerome.duval@gmail.com>
Date: Mon Jul 29 21:04:45 2013 UTC
FreeBSD compat layer: implement MSI-X support.
----------------------------------------------------------------------------
diff --git a/src/libs/compat/freebsd_network/bus.cpp \
b/src/libs/compat/freebsd_network/bus.cpp index 22aed56..3353471 100644
--- a/src/libs/compat/freebsd_network/bus.cpp
+++ b/src/libs/compat/freebsd_network/bus.cpp
@@ -56,7 +56,6 @@ struct internal_intr {
void *arg;
int irq;
uint32 flags;
- bool is_msi;
thread_id thread;
sem_id sem;
@@ -170,8 +169,6 @@ bus_alloc_resource(device_t dev, int type, int *rid, unsigned \
long start, res->r_bustag = 1;
res->r_bushandle = info->u.h0.interrupt_line + *rid - 1;
result = 0;
-
- // TODO: msi-x interrupts
}
} else if (type == SYS_RES_MEMORY)
result = bus_alloc_mem_resource(dev, res, *rid);
@@ -349,7 +346,6 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
intr->arg = arg;
intr->irq = res->r_bushandle;
intr->flags = flags;
- intr->is_msi = false;
intr->sem = -1;
intr->thread = -1;
@@ -386,14 +382,21 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
// this is an msi, enable it
pci_info *info
= &((struct root_device_softc *)dev->root->softc)->pci_info;
- if (gPCIx86->enable_msi(info->bus, info->device,
- info->function) != B_OK) {
- device_printf(dev, "enabling msi failed\n");
- bus_teardown_intr(dev, res, intr);
- return ENODEV;
+ if (&((struct root_device_softc *)dev->root->softc)->is_msi) {
+ if (gPCIx86->enable_msi(info->bus, info->device,
+ info->function) != B_OK) {
+ device_printf(dev, "enabling msi failed\n");
+ bus_teardown_intr(dev, res, intr);
+ return ENODEV;
+ }
+ } else if (&((struct root_device_softc *)dev->root->softc)->is_msix) {
+ if (gPCIx86->enable_msix(info->bus, info->device,
+ info->function) != B_OK) {
+ device_printf(dev, "enabling msix failed\n");
+ bus_teardown_intr(dev, res, intr);
+ return ENODEV;
+ }
}
-
- intr->is_msi = true;
}
if (status < B_OK) {
@@ -412,11 +415,11 @@ int
bus_teardown_intr(device_t dev, struct resource *res, void *arg)
{
struct internal_intr *intr = (struct internal_intr *)arg;
+ struct root_device_softc *root = (struct root_device_softc *)dev->root->softc;
- if (intr->is_msi && gPCIx86 != NULL) {
+ if ((root->is_msi || root->is_msix) && gPCIx86 != NULL) {
// disable msi generation
- pci_info *info
- = &((struct root_device_softc *)dev->root->softc)->pci_info;
+ pci_info *info = &root->pci_info;
gPCIx86->disable_msi(info->bus, info->device, info->function);
}
@@ -613,14 +616,14 @@ pci_get_domain(device_t dev)
return 0;
}
-uint32_t
+uint32_t
pci_get_devid(device_t dev)
{
return pci_read_config(dev, PCI_device_id, 2) << 16 |
pci_read_config(dev, PCI_vendor_id, 2);
}
-uint8_t
+uint8_t
pci_get_cachelnsz(device_t dev)
{
return pci_read_config(dev, PCI_line_size, 1);
@@ -787,6 +790,7 @@ pci_alloc_msi(device_t dev, int *count)
return ENODEV;
}
+ ((struct root_device_softc *)dev->root->softc)->is_msi = true;
info->u.h0.interrupt_line = startVector;
return EOK;
}
@@ -801,6 +805,8 @@ pci_release_msi(device_t dev)
info = &((struct root_device_softc *)dev->root->softc)->pci_info;
gPCIx86->unconfigure_msi(info->bus, info->device, info->function);
+ ((struct root_device_softc *)dev->root->softc)->is_msi = false;
+ ((struct root_device_softc *)dev->root->softc)->is_msix = false;
return EOK;
}
@@ -808,14 +814,33 @@ pci_release_msi(device_t dev)
int
pci_msix_count(device_t dev)
{
- return 0;
+ pci_info *info;
+ if (gPCIx86 == NULL)
+ return 0;
+
+ info = &((struct root_device_softc *)dev->root->softc)->pci_info;
+ return gPCIx86->get_msix_count(info->bus, info->device, info->function);
}
int
pci_alloc_msix(device_t dev, int *count)
{
- return ENODEV;
+ pci_info *info;
+ uint8 startVector = 0;
+ if (gPCIx86 == NULL)
+ return ENODEV;
+
+ info = &((struct root_device_softc *)dev->root->softc)->pci_info;
+
+ if (gPCIx86->configure_msix(info->bus, info->device, info->function, *count,
+ &startVector) != B_OK) {
+ return ENODEV;
+ }
+
+ ((struct root_device_softc *)dev->root->softc)->is_msix = true;
+ info->u.h0.interrupt_line = startVector;
+ return EOK;
}
diff --git a/src/libs/compat/freebsd_network/device.h \
b/src/libs/compat/freebsd_network/device.h index 481d4d4..9a63201 100644
--- a/src/libs/compat/freebsd_network/device.h
+++ b/src/libs/compat/freebsd_network/device.h
@@ -30,6 +30,8 @@ extern "C" {
struct root_device_softc {
struct pci_info pci_info;
+ bool is_msi;
+ bool is_msix;
};
enum {
############################################################################
Commit: c01fadcadb0f00bfeac3e7c5572f9ebdd8301799
URL: http://cgit.haiku-os.org/haiku/commit/?id=c01fadc
Author: Jerome Duval <jerome.duval@gmail.com>
Date: Tue Jul 30 21:00:41 2013 UTC
Committer: Jérôme Duval <jerome.duval@gmail.com>
Commit-Date: Tue Jul 30 22:39:59 2013 UTC
AHCI: add MSI support.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci.c \
b/src/add-ons/kernel/busses/scsi/ahci/ahci.c index 761355b..89327a3 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci.c
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci.c
@@ -142,6 +142,7 @@ const device_info kSupportedDevices[] = {
device_manager_info *gDeviceManager;
scsi_for_sim_interface *gSCSI;
+pci_x86_module_info* gPCIx86Module;
status_t
@@ -328,7 +329,17 @@ std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
+ if (get_module(B_PCI_X86_MODULE_NAME,
+ (module_info**)&gPCIx86Module) != B_OK) {
+ TRACE("failed to get pci x86 module\n");
+ gPCIx86Module = NULL;
+ }
+ return B_OK;
case B_MODULE_UNINIT:
+ if (gPCIx86Module != NULL) {
+ put_module(B_PCI_X86_MODULE_NAME);
+ gPCIx86Module = NULL;
+ }
return B_OK;
default:
diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp \
b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp index b5ed575..c7295f9 \
100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.cpp
@@ -29,6 +29,7 @@ AHCIController::AHCIController(device_node *node,
fPortCount(0),
fPortImplementedMask(0),
fIRQ(0),
+ fUseMSI(false),
fInstanceCheck(-1)
{
memset(fPort, 0, sizeof(fPort));
@@ -101,6 +102,20 @@ AHCIController::Init()
}
fIRQ = pciInfo.u.h0.interrupt_line;
+ if (gPCIx86Module != NULL && gPCIx86Module->get_msi_count(
+ pciInfo.bus, pciInfo.device, pciInfo.function) >= 1) {
+ uint8 vector;
+ if (gPCIx86Module->configure_msi(pciInfo.bus, pciInfo.device,
+ pciInfo.function, 1, &vector) == B_OK
+ && gPCIx86Module->enable_msi(pciInfo.bus, pciInfo.device,
+ pciInfo.function) == B_OK) {
+ TRACE("using MSI vector %u\n", vector);
+ fIRQ = vector;
+ fUseMSI = true;
+ } else {
+ TRACE("couldn't use MSI\n");
+ }
+ }
if (fIRQ == 0 || fIRQ == 0xff) {
TRACE("Error: PCI IRQ not assigned\n");
return B_ERROR;
@@ -250,6 +265,15 @@ AHCIController::Uninit()
// well...
remove_io_interrupt_handler(fIRQ, Interrupt, this);
+ if (fUseMSI && gPCIx86Module != NULL) {
+ pci_info pciInfo;
+ fPCI->get_pci_info(fPCIDevice, &pciInfo);
+ gPCIx86Module->disable_msi(pciInfo.bus,
+ pciInfo.device, pciInfo.function);
+ gPCIx86Module->unconfigure_msi(pciInfo.bus,
+ pciInfo.device, pciInfo.function);
+ }
+
delete_area(fRegsArea);
// --- Instance check workaround begin
diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h \
b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h index c973d41..ccbba64 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_controller.h
@@ -52,6 +52,7 @@ private:
int fPortCount;
uint32 fPortImplementedMask;
uint8 fIRQ;
+ bool fUseMSI;
AHCIPort * fPort[32];
// --- Instance check workaround begin
diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h \
b/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h index ebe1757..7599abd 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h
@@ -7,6 +7,7 @@
#include <bus/PCI.h>
#include <bus/SCSI.h>
+#include <PCI_x86.h>
#ifdef __cplusplus
extern "C" {
@@ -259,6 +260,7 @@ status_t get_device_info(uint16 vendorID, uint16 deviceID, const \
char **name, extern scsi_sim_interface gAHCISimInterface;
extern device_manager_info *gDeviceManager;
extern scsi_for_sim_interface *gSCSI;
+extern pci_x86_module_info* gPCIx86Module;
#define MAX_SECTOR_LBA_28 ((1ull << 28) - 1)
############################################################################
Commit: 010b06a16e6bb1c84a92ed34dd410b5769a0b430
URL: http://cgit.haiku-os.org/haiku/commit/?id=010b06a
Author: Jerome Duval <jerome.duval@gmail.com>
Date: Tue Jul 30 21:36:47 2013 UTC
Committer: Jérôme Duval <jerome.duval@gmail.com>
Commit-Date: Tue Jul 30 22:40:11 2013 UTC
EHCI USB: add MSI support
* similar to OHCI support by mmlr.
* interrupt handler is removed on destruction.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp \
b/src/add-ons/kernel/busses/usb/ehci.cpp index 2c6b79b..c6b7bbd 100644
--- a/src/add-ons/kernel/busses/usb/ehci.cpp
+++ b/src/add-ons/kernel/busses/usb/ehci.cpp
@@ -11,6 +11,7 @@
#include <driver_settings.h>
#include <module.h>
#include <PCI.h>
+#include <PCI_x86.h>
#include <USB3.h>
#include <KernelExport.h>
@@ -19,6 +20,7 @@
#define USB_MODULE_NAME "ehci"
pci_module_info *EHCI::sPCIModule = NULL;
+pci_x86_module_info *EHCI::sPCIx86Module = NULL;
static int32
@@ -142,7 +144,9 @@ EHCI::EHCI(pci_info *info, Stack *stack)
fPortCount(0),
fPortResetChange(0),
fPortSuspendChange(0),
- fInterruptPollThread(-1)
+ fInterruptPollThread(-1),
+ fIRQ(0),
+ fUseMSI(false)
{
// Create a lock for the isochronous transfer list
mutex_init(&fIsochronousLock, "EHCI isochronous lock");
@@ -352,16 +356,31 @@ EHCI::EHCI(pci_info *info, Stack *stack)
"ehci interrupt poll thread", B_NORMAL_PRIORITY, (void *)this);
resume_thread(fInterruptPollThread);
} else {
+ // Find the right interrupt vector, using MSIs if available.
+ fIRQ = 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");
+ fIRQ = msiVector;
+ fUseMSI = true;
+ }
+ }
+
// install the interrupt handler and enable interrupts
- install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line,
- InterruptHandler, (void *)this, 0);
+ install_io_interrupt_handler(fIRQ, InterruptHandler,
+ (void *)this, 0);
}
// ensure that interrupts are en-/disabled on the PCI device
command = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device,
fPCIInfo->function, PCI_command, 2);
- if (polling == ((command & PCI_command_int_disable) == 0)) {
- if (polling)
+ if ((polling || fUseMSI) == ((command & PCI_command_int_disable) == 0)) {
+ if (polling || fUseMSI)
command &= ~PCI_command_int_disable;
else
command |= PCI_command_int_disable;
@@ -548,6 +567,8 @@ EHCI::~EHCI()
if (fInterruptPollThread >= 0)
wait_for_thread(fInterruptPollThread, &result);
+ else
+ remove_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this);
LockIsochronous();
isochronous_transfer_data *isoTransfer = fFirstIsochronousTransfer;
@@ -564,7 +585,19 @@ EHCI::~EHCI()
delete [] fSitdEntries;
delete_area(fPeriodicFrameListArea);
delete_area(fRegisterArea);
+
+ if (fUseMSI && sPCIx86Module != NULL) {
+ sPCIx86Module->disable_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ }
put_module(B_PCI_MODULE_NAME);
+
+ if (sPCIx86Module != NULL) {
+ sPCIx86Module = NULL;
+ put_module(B_PCI_X86_MODULE_NAME);
+ }
}
@@ -941,6 +974,14 @@ EHCI::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 (int32 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_ehci) {
@@ -956,6 +997,10 @@ EHCI::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;
}
@@ -979,6 +1024,10 @@ EHCI::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/ehci.h \
b/src/add-ons/kernel/busses/usb/ehci.h index 4680e2b..deec069 100644
--- a/src/add-ons/kernel/busses/usb/ehci.h
+++ b/src/add-ons/kernel/busses/usb/ehci.h
@@ -14,6 +14,7 @@
struct pci_info;
struct pci_module_info;
+struct pci_x86_module_info;
class EHCIRootHub;
@@ -188,6 +189,7 @@ inline uint16 ReadCapReg16(uint32 reg);
inline uint32 ReadCapReg32(uint32 reg);
static pci_module_info * sPCIModule;
+static pci_x86_module_info * sPCIx86Module;
uint8 * fCapabilityRegisters;
uint8 * fOperationalRegisters;
@@ -243,6 +245,8 @@ static pci_module_info * sPCIModule;
// Interrupt polling
thread_id fInterruptPollThread;
+ uint8 fIRQ;
+ bool fUseMSI;
};
############################################################################
Commit: b3dbb4d23b2c740eeabb928ae18eee3486246849
URL: http://cgit.haiku-os.org/haiku/commit/?id=b3dbb4d
Author: Jerome Duval <jerome.duval@gmail.com>
Date: Tue Jul 30 22:02:41 2013 UTC
Committer: Jérôme Duval <jerome.duval@gmail.com>
Commit-Date: Tue Jul 30 22:40:16 2013 UTC
OHCI USB: disable MSI on destruction
* also remove interrupt handler and put the PCI x86 module.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp \
b/src/add-ons/kernel/busses/usb/ohci.cpp index 670192e..3a28a49 100644
--- a/src/add-ons/kernel/busses/usb/ohci.cpp
+++ b/src/add-ons/kernel/busses/usb/ohci.cpp
@@ -76,7 +76,9 @@ OHCI::OHCI(pci_info *info, Stack *stack)
fProcessingPipe(NULL),
fRootHub(NULL),
fRootHubAddress(0),
- fPortCount(0)
+ fPortCount(0),
+ fIRQ(0),
+ fUseMSI(false)
{
if (!fInitOK) {
TRACE_ERROR("bus manager failed to init\n");
@@ -323,7 +325,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
resume_thread(fFinishThread);
// Find the right interrupt vector, using MSIs if available.
- uint8 interruptVector = fPCIInfo->u.h0.interrupt_line;
+ fIRQ = fPCIInfo->u.h0.interrupt_line;
if (sPCIx86Module != NULL && sPCIx86Module->get_msi_count(fPCIInfo->bus,
fPCIInfo->device, fPCIInfo->function) >= 1) {
uint8 msiVector = 0;
@@ -332,14 +334,14 @@ OHCI::OHCI(pci_info *info, Stack *stack)
&& sPCIx86Module->enable_msi(fPCIInfo->bus, fPCIInfo->device,
fPCIInfo->function) == B_OK) {
TRACE_ALWAYS("using message signaled interrupts\n");
- interruptVector = msiVector;
+ fIRQ = msiVector;
+ fUseMSI = true;
}
}
// Install the interrupt handler
TRACE("installing interrupt handler\n");
- install_io_interrupt_handler(interruptVector, _InterruptHandler,
- (void *)this, 0);
+ install_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this, 0);
// Enable interesting interrupts now that the handler is in place
_WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS
@@ -357,6 +359,8 @@ OHCI::~OHCI()
delete_sem(fFinishTransfersSem);
wait_for_thread(fFinishThread, &result);
+ remove_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this);
+
_LockEndpoints();
mutex_destroy(&fEndpointLock);
@@ -377,7 +381,17 @@ OHCI::~OHCI()
delete [] fInterruptEndpoints;
delete fRootHub;
+ if (fUseMSI && sPCIx86Module != NULL) {
+ sPCIx86Module->disable_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ }
put_module(B_PCI_MODULE_NAME);
+ if (sPCIx86Module != NULL) {
+ sPCIx86Module = NULL;
+ put_module(B_PCI_X86_MODULE_NAME);
+ }
}
diff --git a/src/add-ons/kernel/busses/usb/ohci.h \
b/src/add-ons/kernel/busses/usb/ohci.h index fbe24c0..341e8a4 100644
--- a/src/add-ons/kernel/busses/usb/ohci.h
+++ b/src/add-ons/kernel/busses/usb/ohci.h
@@ -174,6 +174,9 @@ static pci_x86_module_info * sPCIx86Module;
// Port management
uint8 fPortCount;
+
+ uint8 fIRQ;
+ bool fUseMSI;
};
############################################################################
Commit: c45ac5ad59cf7fea1595e471f46e8e5400e69cec
URL: http://cgit.haiku-os.org/haiku/commit/?id=c45ac5a
Author: Jerome Duval <jerome.duval@gmail.com>
Date: Tue Jul 30 22:12:23 2013 UTC
Committer: Jérôme Duval <jerome.duval@gmail.com>
Commit-Date: Tue Jul 30 22:40:23 2013 UTC
UHCI USB: add MSI support
* similar to OHCI support by mmlr.
* interrupt handler is removed on destruction.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp \
b/src/add-ons/kernel/busses/usb/uhci.cpp index 7463fb5..42b898a 100644
--- a/src/add-ons/kernel/busses/usb/uhci.cpp
+++ b/src/add-ons/kernel/busses/usb/uhci.cpp
@@ -10,6 +10,7 @@
#include <module.h>
#include <PCI.h>
+#include <PCI_x86.h>
#include <USB3.h>
#include <KernelExport.h>
@@ -18,6 +19,7 @@
#define USB_MODULE_NAME "uhci"
pci_module_info *UHCI::sPCIModule = NULL;
+pci_x86_module_info *UHCI::sPCIx86Module = NULL;
static int32 sDebuggerCommandAdded = 0;
@@ -404,7 +406,9 @@ UHCI::UHCI(pci_info *info, Stack *stack)
fFinishIsochronousThread(-1),
fRootHub(NULL),
fRootHubAddress(0),
- fPortResetChange(0)
+ fPortResetChange(0),
+ fIRQ(0),
+ fUseMSI(false)
{
// Create a lock for the isochronous transfer list
mutex_init(&fIsochronousLock, "UHCI isochronous lock");
@@ -557,10 +561,24 @@ UHCI::UHCI(pci_info *info, Stack *stack)
(void *)this);
resume_thread(fFinishIsochronousThread);
+ // Find the right interrupt vector, using MSIs if available.
+ fIRQ = 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");
+ fIRQ = msiVector;
+ fUseMSI = true;
+ }
+ }
+
// 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(fIRQ, InterruptHandler, (void *)this, 0);
// Enable interrupts
fEnabledInterrupts = UHCI_USBSTS_USBINT | UHCI_USBSTS_ERRINT
@@ -599,6 +617,8 @@ UHCI::~UHCI()
wait_for_thread(fCleanupThread, &result);
wait_for_thread(fFinishIsochronousThread, &result);
+ remove_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this);
+
LockIsochronous();
isochronous_transfer_data *isoTransfer = fFirstIsochronousTransfer;
while (isoTransfer) {
@@ -629,7 +649,17 @@ UHCI::~UHCI()
delete fRootHub;
delete_area(fFrameArea);
+ if (fUseMSI && sPCIx86Module != NULL) {
+ sPCIx86Module->disable_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ }
put_module(B_PCI_MODULE_NAME);
+ if (sPCIx86Module != NULL) {
+ sPCIx86Module = NULL;
+ put_module(B_PCI_X86_MODULE_NAME);
+ }
Unlock();
}
diff --git a/src/add-ons/kernel/busses/usb/uhci.h \
b/src/add-ons/kernel/busses/usb/uhci.h index a0c2b89..f5fbb78 100644
--- a/src/add-ons/kernel/busses/usb/uhci.h
+++ b/src/add-ons/kernel/busses/usb/uhci.h
@@ -23,6 +23,7 @@
struct pci_info;
struct pci_module_info;
+struct pci_x86_module_info;
class UHCIRootHub;
class DebugTransfer;
@@ -208,6 +209,7 @@ inline uint16 ReadReg16(uint32 reg);
inline uint32 ReadReg32(uint32 reg);
static pci_module_info * sPCIModule;
+static pci_x86_module_info * sPCIx86Module;
uint32 fRegisterBase;
pci_info * fPCIInfo;
@@ -256,6 +258,9 @@ static pci_module_info * sPCIModule;
UHCIRootHub * fRootHub;
uint8 fRootHubAddress;
uint8 fPortResetChange;
+
+ uint8 fIRQ;
+ bool fUseMSI;
};
############################################################################
Revision: hrev45932
Commit: 96adf3ffad2c81bd60876fff16f8768e2c035c9f
URL: http://cgit.haiku-os.org/haiku/commit/?id=96adf3f
Author: Jerome Duval <jerome.duval@gmail.com>
Date: Tue Jul 30 22:21:23 2013 UTC
Committer: Jérôme Duval <jerome.duval@gmail.com>
Commit-Date: Tue Jul 30 22:40:33 2013 UTC
XHCI USB: add MSI support
* similar to OHCI support by mmlr.
* interrupt handler is removed on destruction.
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp \
b/src/add-ons/kernel/busses/usb/xhci.cpp index f7e3a97..72edc44 100644
--- a/src/add-ons/kernel/busses/usb/xhci.cpp
+++ b/src/add-ons/kernel/busses/usb/xhci.cpp
@@ -13,6 +13,7 @@
#include <module.h>
#include <PCI.h>
+#include <PCI_x86.h>
#include <USB3.h>
#include <KernelExport.h>
@@ -24,6 +25,7 @@
#define USB_MODULE_NAME "xhci"
pci_module_info *XHCI::sPCIModule = NULL;
+pci_x86_module_info *XHCI::sPCIx86Module = NULL;
static int32
@@ -111,6 +113,8 @@ XHCI::XHCI(pci_info *info, Stack *stack)
fRegisterArea(-1),
fPCIInfo(info),
fStack(stack),
+ fIRQ(0),
+ fUseMSI(false),
fErstArea(-1),
fDcbaArea(-1),
fSpinlock(B_SPINLOCK_INITIALIZER),
@@ -256,10 +260,24 @@ XHCI::XHCI(pci_info *info, Stack *stack)
B_NORMAL_PRIORITY, (void *)this);
resume_thread(fEventThread);
+ // Find the right interrupt vector, using MSIs if available.
+ fIRQ = 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");
+ fIRQ = msiVector;
+ fUseMSI = true;
+ }
+ }
+
// 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(fIRQ, InterruptHandler, (void *)this, 0);
memset(fPortSpeeds, 0, sizeof(fPortSpeeds));
memset(fPortSlots, 0, sizeof(fPortSlots));
@@ -281,14 +299,28 @@ XHCI::~XHCI()
delete_sem(fCmdCompSem);
delete_sem(fFinishTransfersSem);
delete_sem(fEventSem);
+ wait_for_thread(fFinishThread, &result);
+ wait_for_thread(fEventThread, &result);
+
+ remove_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this);
+
delete_area(fRegisterArea);
delete_area(fErstArea);
for (uint32 i = 0; i < fScratchpadCount; i++)
delete_area(fScratchpadArea[i]);
delete_area(fDcbaArea);
- wait_for_thread(fFinishThread, &result);
- wait_for_thread(fEventThread, &result);
+
+ if (fUseMSI && sPCIx86Module != NULL) {
+ sPCIx86Module->disable_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
+ fPCIInfo->device, fPCIInfo->function);
+ }
put_module(B_PCI_MODULE_NAME);
+ if (sPCIx86Module != NULL) {
+ sPCIx86Module = NULL;
+ put_module(B_PCI_X86_MODULE_NAME);
+ }
}
diff --git a/src/add-ons/kernel/busses/usb/xhci.h \
b/src/add-ons/kernel/busses/usb/xhci.h index 8c35c34..df4a597 100644
--- a/src/add-ons/kernel/busses/usb/xhci.h
+++ b/src/add-ons/kernel/busses/usb/xhci.h
@@ -17,6 +17,7 @@
struct pci_info;
struct pci_module_info;
+struct pci_x86_module_info;
struct xhci_td;
struct xhci_device;
struct xhci_endpoint;
@@ -194,6 +195,7 @@ private:
inline void WriteDoorReg32(uint32 reg, uint32 value);
static pci_module_info * sPCIModule;
+ static pci_x86_module_info *sPCIx86Module;
uint8 * fCapabilityRegisters;
uint32 fCapabilityLength;
@@ -205,6 +207,8 @@ private:
area_id fRegisterArea;
pci_info * fPCIInfo;
Stack * fStack;
+ uint8 fIRQ;
+ bool fUseMSI;
area_id fErstArea;
xhci_erst_element * fErst;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic