AHCI: add MSI support.

This commit is contained in:
Jerome Duval
2013-07-31 00:39:59 +02:00
committed by Jérôme Duval
parent 656e05ec86
commit c01fadcadb
4 changed files with 38 additions and 0 deletions
@@ -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:
@@ -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
@@ -52,6 +52,7 @@ private:
int fPortCount;
uint32 fPortImplementedMask;
uint8 fIRQ;
bool fUseMSI;
AHCIPort * fPort[32];
// --- Instance check workaround begin
@@ -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)