// usb.c - USB bus driver entry point and PCI controller discovery. #include "usb.h" XHCI_CONTROLLER gXhci; bool gHaveXhci = false; const char* UsbControllerName(uint8_t progIf) { switch (progIf) { case 0x00: return "UHCI"; case 0x10: return "OHCI"; case 0x20: return "EHCI"; case 0x30: return "xHCI"; default: return "USB"; } } void UsbDiscoverControllers(const HAL_API* hal) { uint32_t found = 0; uint32_t xhciOk = 0; for (uint16_t bus = 0; bus < 256; bus++) { for (uint8_t dev = 0; dev < 32; dev++) { for (uint8_t fn = 0; fn < 8; fn++) { uint32_t vd = hal->Pci.Read32((uint8_t)bus, dev, fn, PCI_REG_VENDOR_DEVICE); if ((vd & 0xFFFFu) == PCI_VENDOR_INVALID) continue; uint32_t classReg = hal->Pci.Read32((uint8_t)bus, dev, fn, PCI_REG_CLASS); uint8_t classCode = (uint8_t)(classReg >> 24); uint8_t subclass = (uint8_t)(classReg >> 16); uint8_t progIf = (uint8_t)(classReg >> 8); if (classCode != PCI_CLASS_SERIAL_BUS || subclass != PCI_SUBCLASS_USB) continue; USB_BAR bar0; bool hasBar0 = UsbReadBar(hal, (uint8_t)bus, dev, fn, 0, &bar0); uint32_t rawBar0 = hal->Pci.Read32((uint8_t)bus, dev, fn, PCI_REG_BAR0); uint32_t rawBar1 = hal->Pci.Read32((uint8_t)bus, dev, fn, PCI_REG_BAR0 + 4u); uint8_t irq = hal->Pci.GetIrqLine((uint8_t)bus, dev, fn); DbgPrint("usb: found %s controller at %u:%u.%u vendor=%04x device=%04x irq=%u bar0raw=%08x bar1raw=%08x", UsbControllerName(progIf), bus, dev, fn, vd & 0xFFFFu, vd >> 16, irq, rawBar0, rawBar1); if (hasBar0 && bar0.Kind == UsbBarMmio) { DbgPrint(" mmio=0x%016llX\n", (unsigned long long)bar0.Base); } else if (hasBar0 && bar0.Kind == UsbBarIo) { DbgPrint(" io=0x%016llX\n", (unsigned long long)bar0.Base); } else { DbgPrint(" no-bar0\n"); } if (progIf == PCI_PROGIF_XHCI) { KSTATUS st = XhciInitialise(hal, (uint8_t)bus, dev, fn, (uint16_t)(vd & 0xFFFFu), (uint16_t)(vd >> 16)); if (KSUCCESS(st) || st == STATUS_ALREADY_EXISTS) xhciOk++; else DbgPrint("usb: xHCI init failed st=0x%x\n", st); } found++; } } } if (!found) DbgPrint("usb: no PCI USB controllers discovered\n"); else DbgPrint("usb: discovery complete; controllers=%u xhci_initialised=%u\n", found, xhciOk); } KSTATUS DriverEntry(const HAL_API* hal) { if (!hal) return STATUS_INVALID_PARAMETER; DbgPrint("usb: discovery starting\n"); KSTATUS st = UsbInitializeBusModel(); if (!KSUCCESS(st)) { DbgPrint("usb: bus model initialisation failed st=0x%x\n", st); return st; } st = UsbInitializeCompositeDriver(); if (!KSUCCESS(st)) { DbgPrint("usb: composite driver initialisation failed st=0x%x\n", st); return st; } st = UsbInitializeHidDriver(); if (!KSUCCESS(st)) { DbgPrint("usb: HID driver initialisation failed st=0x%x\n", st); return st; } st = UsbInitializeStorageDriver(); if (!KSUCCESS(st)) { DbgPrint("usb: storage driver initialisation failed st=0x%x\n", st); return st; } st = UsbInitializeHubDriver(); if (!KSUCCESS(st)) { DbgPrint("usb: hub driver initialisation failed st=0x%x\n", st); return st; } UsbDiscoverControllers(hal); return STATUS_SUCCESS; }