UHCI USB: add MSI support
* similar to OHCI support by mmlr. * interrupt handler is removed on destruction.
This commit is contained in:
parent
b3dbb4d23b
commit
c45ac5ad59
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <module.h>
|
#include <module.h>
|
||||||
#include <PCI.h>
|
#include <PCI.h>
|
||||||
|
#include <PCI_x86.h>
|
||||||
#include <USB3.h>
|
#include <USB3.h>
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
@ -18,6 +19,7 @@
|
|||||||
#define USB_MODULE_NAME "uhci"
|
#define USB_MODULE_NAME "uhci"
|
||||||
|
|
||||||
pci_module_info *UHCI::sPCIModule = NULL;
|
pci_module_info *UHCI::sPCIModule = NULL;
|
||||||
|
pci_x86_module_info *UHCI::sPCIx86Module = NULL;
|
||||||
|
|
||||||
static int32 sDebuggerCommandAdded = 0;
|
static int32 sDebuggerCommandAdded = 0;
|
||||||
|
|
||||||
@ -404,7 +406,9 @@ UHCI::UHCI(pci_info *info, Stack *stack)
|
|||||||
fFinishIsochronousThread(-1),
|
fFinishIsochronousThread(-1),
|
||||||
fRootHub(NULL),
|
fRootHub(NULL),
|
||||||
fRootHubAddress(0),
|
fRootHubAddress(0),
|
||||||
fPortResetChange(0)
|
fPortResetChange(0),
|
||||||
|
fIRQ(0),
|
||||||
|
fUseMSI(false)
|
||||||
{
|
{
|
||||||
// Create a lock for the isochronous transfer list
|
// Create a lock for the isochronous transfer list
|
||||||
mutex_init(&fIsochronousLock, "UHCI isochronous lock");
|
mutex_init(&fIsochronousLock, "UHCI isochronous lock");
|
||||||
@ -557,10 +561,24 @@ UHCI::UHCI(pci_info *info, Stack *stack)
|
|||||||
(void *)this);
|
(void *)this);
|
||||||
resume_thread(fFinishIsochronousThread);
|
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
|
// Install the interrupt handler
|
||||||
TRACE("installing interrupt handler\n");
|
TRACE("installing interrupt handler\n");
|
||||||
install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line,
|
install_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this, 0);
|
||||||
InterruptHandler, (void *)this, 0);
|
|
||||||
|
|
||||||
// Enable interrupts
|
// Enable interrupts
|
||||||
fEnabledInterrupts = UHCI_USBSTS_USBINT | UHCI_USBSTS_ERRINT
|
fEnabledInterrupts = UHCI_USBSTS_USBINT | UHCI_USBSTS_ERRINT
|
||||||
@ -599,6 +617,8 @@ UHCI::~UHCI()
|
|||||||
wait_for_thread(fCleanupThread, &result);
|
wait_for_thread(fCleanupThread, &result);
|
||||||
wait_for_thread(fFinishIsochronousThread, &result);
|
wait_for_thread(fFinishIsochronousThread, &result);
|
||||||
|
|
||||||
|
remove_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this);
|
||||||
|
|
||||||
LockIsochronous();
|
LockIsochronous();
|
||||||
isochronous_transfer_data *isoTransfer = fFirstIsochronousTransfer;
|
isochronous_transfer_data *isoTransfer = fFirstIsochronousTransfer;
|
||||||
while (isoTransfer) {
|
while (isoTransfer) {
|
||||||
@ -629,7 +649,17 @@ UHCI::~UHCI()
|
|||||||
delete fRootHub;
|
delete fRootHub;
|
||||||
delete_area(fFrameArea);
|
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);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
|
if (sPCIx86Module != NULL) {
|
||||||
|
sPCIx86Module = NULL;
|
||||||
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
|
}
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
struct pci_info;
|
struct pci_info;
|
||||||
struct pci_module_info;
|
struct pci_module_info;
|
||||||
|
struct pci_x86_module_info;
|
||||||
class UHCIRootHub;
|
class UHCIRootHub;
|
||||||
class DebugTransfer;
|
class DebugTransfer;
|
||||||
|
|
||||||
@ -208,6 +209,7 @@ inline uint16 ReadReg16(uint32 reg);
|
|||||||
inline uint32 ReadReg32(uint32 reg);
|
inline uint32 ReadReg32(uint32 reg);
|
||||||
|
|
||||||
static pci_module_info * sPCIModule;
|
static pci_module_info * sPCIModule;
|
||||||
|
static pci_x86_module_info * sPCIx86Module;
|
||||||
|
|
||||||
uint32 fRegisterBase;
|
uint32 fRegisterBase;
|
||||||
pci_info * fPCIInfo;
|
pci_info * fPCIInfo;
|
||||||
@ -256,6 +258,9 @@ static pci_module_info * sPCIModule;
|
|||||||
UHCIRootHub * fRootHub;
|
UHCIRootHub * fRootHub;
|
||||||
uint8 fRootHubAddress;
|
uint8 fRootHubAddress;
|
||||||
uint8 fPortResetChange;
|
uint8 fPortResetChange;
|
||||||
|
|
||||||
|
uint8 fIRQ;
|
||||||
|
bool fUseMSI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user