intel_extreme: add MSI support

This commit is contained in:
Jerome Duval 2013-08-09 23:32:07 +02:00
parent 83ea4af492
commit c2cfbd70fe
4 changed files with 49 additions and 5 deletions

View File

@ -103,6 +103,7 @@ int32 api_version = B_CUR_DRIVER_API_VERSION;
char* gDeviceNames[MAX_CARDS + 1];
intel_info* gDeviceInfo[MAX_CARDS];
pci_module_info* gPCI;
pci_x86_module_info* gPCIx86Module = NULL;
agp_gart_module_info* gGART;
mutex gLock;
@ -185,6 +186,14 @@ init_driver(void)
mutex_init(&gLock, "intel extreme ksync");
// Try to get the PCI x86 module as well so we can enable possible MSIs.
if (get_module(B_PCI_X86_MODULE_NAME,
(module_info **)&gPCIx86Module) != B_OK) {
ERROR("failed to get pci x86 module\n");
gPCIx86Module = NULL;
}
// find devices
int32 found = 0;
@ -240,6 +249,10 @@ init_driver(void)
mutex_destroy(&gLock);
put_module(B_AGP_GART_MODULE_NAME);
put_module(B_PCI_MODULE_NAME);
if (gPCIx86Module != NULL) {
gPCIx86Module = NULL;
put_module(B_PCI_X86_MODULE_NAME);
}
return ENODEV;
}
@ -263,6 +276,10 @@ uninit_driver(void)
put_module(B_AGP_GART_MODULE_NAME);
put_module(B_PCI_MODULE_NAME);
if (gPCIx86Module != NULL) {
gPCIx86Module = NULL;
put_module(B_PCI_X86_MODULE_NAME);
}
}

View File

@ -20,6 +20,7 @@
extern char* gDeviceNames[];
extern intel_info* gDeviceInfo[];
extern pci_module_info* gPCI;
extern pci_x86_module_info* gPCIx86Module;
extern agp_gart_module_info* gGART;
extern mutex gLock;

View File

@ -131,13 +131,30 @@ init_interrupt_handler(intel_info &info)
status = B_ERROR;
}
if (status == B_OK && info.pci->u.h0.interrupt_pin != 0x00
&& info.pci->u.h0.interrupt_line != 0xff) {
// Find the right interrupt vector, using MSIs if available.
info.irq = 0xff;
info.use_msi = false;
if (info.pci->u.h0.interrupt_pin != 0x00)
info.irq = info.pci->u.h0.interrupt_line;
if (gPCIx86Module != NULL && gPCIx86Module->get_msi_count(info.pci->bus,
info.pci->device, info.pci->function) >= 1) {
uint8 msiVector = 0;
if (gPCIx86Module->configure_msi(info.pci->bus, info.pci->device,
info.pci->function, 1, &msiVector) == B_OK
&& gPCIx86Module->enable_msi(info.pci->bus, info.pci->device,
info.pci->function) == B_OK) {
ERROR("using message signaled interrupts\n");
info.irq = msiVector;
info.use_msi = true;
}
}
if (status == B_OK && info.irq != 0xff) {
// we've gotten an interrupt line for us to use
info.fake_interrupts = false;
status = install_io_interrupt_handler(info.pci->u.h0.interrupt_line,
status = install_io_interrupt_handler(info.irq,
&intel_interrupt_handler, (void*)&info, 0);
if (status == B_OK) {
write32(info, INTEL_DISPLAY_A_PIPE_STATUS,
@ -384,8 +401,14 @@ intel_extreme_uninit(intel_info &info)
write16(info, find_reg(info, INTEL_INTERRUPT_ENABLED), 0);
write16(info, find_reg(info, INTEL_INTERRUPT_MASK), ~0);
remove_io_interrupt_handler(info.pci->u.h0.interrupt_line,
intel_interrupt_handler, &info);
remove_io_interrupt_handler(info.irq, intel_interrupt_handler, &info);
if (info.use_msi && gPCIx86Module != NULL) {
gPCIx86Module->disable_msi(info.pci->bus,
info.pci->device, info.pci->function);
gPCIx86Module->unconfigure_msi(info.pci->bus,
info.pci->device, info.pci->function);
}
}
gGART->unmap_aperture(info.aperture);

View File

@ -12,6 +12,7 @@
#include <AGP.h>
#include <KernelExport.h>
#include <PCI.h>
#include <PCI_x86.h>
#include "intel_extreme.h"
#include "lock.h"
@ -34,6 +35,8 @@ struct intel_info {
struct overlay_registers* overlay_registers;
bool fake_interrupts;
uint8 irq;
bool use_msi;
const char* device_identifier;
DeviceType device_type;