temp
This commit is contained in:
1 parent
d36f19509c
commit
30d20457f0
309 files changed
+121746
-1963
No files matched your search
@@ -761,55 +761,17 @@ void XhciEventDpcRoutine(KDPC* dpc, void* context,
|
||||
}
|
||||
|
||||
#define XHCI_CONTROLLER_MAGIC 0x58484349u // XHCI
|
||||
#define XHCI_MAX_CONTROLLERS 8u
|
||||
|
||||
static XHCI_CONTROLLER* gXhciControllers[XHCI_MAX_CONTROLLERS];
|
||||
static uint32_t gXhciControllerCount;
|
||||
|
||||
// Registers controller.
|
||||
static KSTATUS XhciRegisterController(XHCI_CONTROLLER* xhci) {
|
||||
if (!xhci) return NTLSTATUS_INVALID_PARAMETER;
|
||||
for (uint32_t i = 0; i < gXhciControllerCount; i++) {
|
||||
if (gXhciControllers[i] == xhci)
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
if (gXhciControllerCount >= XHCI_MAX_CONTROLLERS)
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
gXhciControllers[gXhciControllerCount++] = xhci;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Removes a controller from the interrupt-dispatch registry.
|
||||
static void XhciUnregisterController(XHCI_CONTROLLER* xhci) {
|
||||
if (!xhci)
|
||||
return;
|
||||
for (uint32_t i = 0; i < gXhciControllerCount; i++) {
|
||||
if (gXhciControllers[i] != xhci)
|
||||
continue;
|
||||
for (uint32_t next = i + 1; next < gXhciControllerCount; next++)
|
||||
gXhciControllers[next - 1] = gXhciControllers[next];
|
||||
gXhciControllerCount--;
|
||||
gXhciControllers[gXhciControllerCount] = (XHCI_CONTROLLER*)0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the isr operation.
|
||||
void XhciIsr(void) {
|
||||
for (uint32_t i = 0; i < gXhciControllerCount; i++) {
|
||||
XHCI_CONTROLLER* xhci = gXhciControllers[i];
|
||||
if (!xhci || !xhci->Running || !xhci->Op || !xhci->Runtime)
|
||||
continue;
|
||||
|
||||
uint32_t status = XhciRead32(xhci->Op, XHCI_OP_USBSTS);
|
||||
if (!(status & (XHCI_USBSTS_EINT | XHCI_USBSTS_PCD | XHCI_USBSTS_HSE | XHCI_USBSTS_HCE)))
|
||||
continue;
|
||||
|
||||
xhci->InterruptCount++;
|
||||
XhciWrite32(xhci->Op, XHCI_OP_USBSTS, status & XHCI_USBSTS_CLEAR_MASK);
|
||||
XhciAckInterrupter0(xhci);
|
||||
KeInsertQueueDpc(&xhci->EventDpc, (void*)0, (void*)0);
|
||||
}
|
||||
void XhciIsr(void* context) {
|
||||
XHCI_CONTROLLER* xhci = (XHCI_CONTROLLER*)context;
|
||||
if (!xhci || !xhci->Running || !xhci->Op || !xhci->Runtime) return;
|
||||
uint32_t status = XhciRead32(xhci->Op, XHCI_OP_USBSTS);
|
||||
if (!(status & (XHCI_USBSTS_EINT | XHCI_USBSTS_PCD | XHCI_USBSTS_HSE | XHCI_USBSTS_HCE)))
|
||||
return;
|
||||
xhci->InterruptCount++;
|
||||
XhciWrite32(xhci->Op, XHCI_OP_USBSTS, status & XHCI_USBSTS_CLEAR_MASK);
|
||||
XhciAckInterrupter0(xhci);
|
||||
KeInsertQueueDpc(&xhci->EventDpc, (void*)0, (void*)0);
|
||||
}
|
||||
|
||||
// Implements the bios Handoff operation.
|
||||
@@ -2181,35 +2143,13 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) {
|
||||
return NTLSTATUS_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
xhci->Irq = 0xFFu;
|
||||
xhci->InterruptRequest.Routine = XhciIsr;
|
||||
xhci->InterruptRequest.Context = xhci;
|
||||
xhci->InterruptRequest.Affinity = 0;
|
||||
xhci->InterruptRequest.Interrupt = (KE_INTERRUPT*)0;
|
||||
xhci->UsingMsi = false;
|
||||
|
||||
st = PciEnableMsiAuto(xhci->Pdo, &xhci->Irq);
|
||||
if (KSUCCESS(st)) {
|
||||
xhci->UsingMsi = true;
|
||||
DbgPrint("usb: xHCI using MSI IRQ slot %u\n", xhci->Irq);
|
||||
} else {
|
||||
KSTATUS intxStatus = PciGetInterrupt(xhci->Pdo, &xhci->Irq);
|
||||
if (KSUCCESS(intxStatus) && xhci->Irq != 0xFFu) {
|
||||
DbgPrint("usb: xHCI using legacy INTx IRQ %u\n", xhci->Irq);
|
||||
} else {
|
||||
xhci->Irq = 0xFFu;
|
||||
DbgPrint("usb: xHCI no MSI/INTx interrupt available; using polled event-ring mode (msi=0x%x intx=0x%x)\n",
|
||||
st, intxStatus);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t enableFlags = PCI_ENABLE_MEMORY | PCI_ENABLE_BUSMASTER;
|
||||
if (xhci->UsingMsi || xhci->Irq == 0xFFu)
|
||||
enableFlags |= PCI_DISABLE_INTX;
|
||||
else
|
||||
enableFlags |= PCI_ENABLE_INTX;
|
||||
|
||||
st = PciEnableDevice(xhci->Pdo, enableFlags);
|
||||
if (!KSUCCESS(st)) {
|
||||
DbgPrint("usb: xHCI PciEnableDevice failed st=0x%x\n", st);
|
||||
return st;
|
||||
}
|
||||
st = PciEnableDevice(xhci->Pdo, PCI_ENABLE_MEMORY | PCI_ENABLE_BUSMASTER | PCI_DISABLE_INTX);
|
||||
if (!KSUCCESS(st)) return st;
|
||||
|
||||
xhci->MmioPhys = xhci->MmioBar.Base;
|
||||
|
||||
@@ -2266,10 +2206,9 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) {
|
||||
UsbInitializeHcd(&xhci->Hcd, &gXhciHcdOperations, xhci, 0, xhci->MaxPorts);
|
||||
xhci->Hcd.ControllerDevice = xhci->Fdo;
|
||||
|
||||
DbgPrint("usb: xHCI init %02x:%02x.%x vendor=%04x device=%04x irq=%u mmio=0x%016llX caplen=%u version=%04x\n",
|
||||
DbgPrint("usb: xHCI init %02x:%02x.%x vendor=%04x device=%04x mmio=0x%016llX caplen=%u version=%04x\n",
|
||||
xhci->Bus, xhci->Dev, xhci->Fn,
|
||||
xhci->PciInfo.VendorId, xhci->PciInfo.DeviceId,
|
||||
xhci->Irq,
|
||||
(unsigned long long)xhci->MmioPhys, xhci->CapLength, xhci->Version);
|
||||
DbgPrint("usb: xHCI caps slots=%u intrs=%u ports=%u ctx=%u scratchpads=%u hcs2=%08x hcc1=%08x dboff=0x%x rtsoff=0x%x pagesize=%08x\n",
|
||||
xhci->MaxSlots, xhci->MaxIntrs, xhci->MaxPorts, xhci->ContextBytes,
|
||||
@@ -2331,22 +2270,18 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) {
|
||||
goto failDma;
|
||||
}
|
||||
|
||||
st = XhciRegisterController(xhci);
|
||||
if (!KSUCCESS(st)) {
|
||||
DbgPrint("usb: xHCI controller registry full st=0x%x\n", st);
|
||||
goto failDma;
|
||||
}
|
||||
|
||||
if (xhci->Irq != 0xFFu) {
|
||||
KeIrqRegister(xhci->Irq, XhciIsr);
|
||||
st = PciConnectInterrupts(xhci->Pdo, &xhci->InterruptRequest, 1u, &xhci->UsingMsi);
|
||||
if (KSUCCESS(st)) {
|
||||
XhciEnableInterrupts(xhci);
|
||||
xhci->InterruptsEnabled = true;
|
||||
KeInsertQueueDpc(&xhci->EventDpc, (void*)0, (void*)0);
|
||||
DbgPrint("usb: xHCI ISR registered on IRQ %u (%s); event ring handled by DPC\n",
|
||||
xhci->Irq, xhci->UsingMsi ? "MSI" : "INTx");
|
||||
KE_INTERRUPT_INFO info;
|
||||
if (KSUCCESS(KeInterruptQuery(xhci->InterruptRequest.Interrupt, &info)))
|
||||
DbgPrint("usb: xHCI interrupt cpu=%u vector=0x%02x mode=%s\n",
|
||||
info.CpuIndex, info.Vector, xhci->UsingMsi ? "MSI/MSI-X" : "INTx");
|
||||
} else {
|
||||
xhci->InterruptsEnabled = false;
|
||||
DbgPrint("usb: xHCI started in polling mode; synchronous waits drain event ring\n");
|
||||
DbgPrint("usb: xHCI polling fallback status=0x%x\n", st);
|
||||
}
|
||||
xhci->Fdo->PnpState = DevicePnpStarted;
|
||||
|
||||
@@ -2362,7 +2297,8 @@ KSTATUS XhciStartController(XHCI_CONTROLLER* xhci) {
|
||||
|
||||
failDma:
|
||||
XhciHaltForDmaRelease(xhci);
|
||||
XhciUnregisterController(xhci);
|
||||
if (xhci->InterruptRequest.Interrupt)
|
||||
PciDisconnectInterrupts(xhci->Pdo, &xhci->InterruptRequest, 1u);
|
||||
if (xhci->Hcd.RootHubPdo) {
|
||||
(void)UsbRemovePdoSubtree(xhci->Hcd.RootHubPdo, true);
|
||||
xhci->Hcd.RootHubPdo = (DEVICE_OBJECT*)0;
|
||||
@@ -2400,6 +2336,8 @@ KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
|
||||
xhci->SurpriseRemoved = true;
|
||||
xhci->Running = false;
|
||||
xhci->InterruptsEnabled = false;
|
||||
if (xhci->InterruptRequest.Interrupt)
|
||||
PciDisconnectInterrupts(xhci->Pdo, &xhci->InterruptRequest, 1u);
|
||||
if (xhci->Hcd.RootHubPdo)
|
||||
(void)UsbRemovePdoSubtree(xhci->Hcd.RootHubPdo, true);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
@@ -2407,11 +2345,12 @@ KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
device->PnpState = DevicePnpDeleted;
|
||||
XhciHaltForDmaRelease(xhci);
|
||||
if (xhci->InterruptRequest.Interrupt)
|
||||
PciDisconnectInterrupts(xhci->Pdo, &xhci->InterruptRequest, 1u);
|
||||
if (xhci->Hcd.RootHubPdo) {
|
||||
(void)UsbRemovePdoSubtree(xhci->Hcd.RootHubPdo, true);
|
||||
xhci->Hcd.RootHubPdo = (DEVICE_OBJECT*)0;
|
||||
}
|
||||
XhciUnregisterController(xhci);
|
||||
XhciReleaseControllerDma(xhci);
|
||||
IoDetachDevice(device);
|
||||
IoDeleteDevice(device);
|
||||
@@ -2439,7 +2378,6 @@ KSTATUS XhciAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject
|
||||
|
||||
xhci->Fdo = fdo;
|
||||
xhci->Pdo = physicalDeviceObject;
|
||||
xhci->Irq = 0xFFu;
|
||||
KeInitializeDpc(&xhci->EventDpc, XhciEventDpcRoutine, xhci);
|
||||
|
||||
xhci->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject);
|
||||
|
||||
Reference in new issue
Block a user