replace ad hoc driver loading with a proper driver manager, new DDK, new PnP manager with device matching, asynchronous startup, resource ownership and removal, add shared PCI capability helpers, replace typed, rigid services with a proper service manager, implement proper system shutdown and restart, shutting down unloads drivers and shuts down services, add simple power button, remove heavyweight boot self-tests and SMP stress runs, add monotonic timestamps to kernel debug output, fruitless USB and PS/2 fixes, make test builds opt in.
This commit is contained in:
1 parent
c0ad63c27f
commit
d36f19509c
160 files changed
+6563
-7366
No files matched your search
+8
-135
@@ -11,72 +11,7 @@
|
||||
#include <kernel/ke_debug.h>
|
||||
#include <kernel/ob_object.h>
|
||||
#include <kernel/ke_sched.h>
|
||||
|
||||
#define MAX_DRIVER_OBJECTS 64
|
||||
#define MAX_PDO_OBJECTS 128
|
||||
|
||||
// Implements the sv Or Unnamed operation.
|
||||
static SYS_STRING_VIEW IoSvOrUnnamed(SYS_STRING_VIEW name) {
|
||||
return SysSvIsEmpty(name) ? SYS_SV_LITERAL("<unnamed>") : name;
|
||||
}
|
||||
|
||||
// Implements the bus Type Name operation.
|
||||
static const char* IoBusTypeName(IO_BUS_TYPE busType) {
|
||||
switch (busType) {
|
||||
case IoBusPci: return "pci";
|
||||
case IoBusUsb: return "usb";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// Driver object registry / PDO AddDevice binding.
|
||||
|
||||
static DRIVER_OBJECT* gDriverObjects[MAX_DRIVER_OBJECTS];
|
||||
static uint32_t gDriverObjectCount;
|
||||
static DEVICE_OBJECT* gPhysicalDevices[MAX_PDO_OBJECTS];
|
||||
static uint32_t gPhysicalDeviceCount;
|
||||
|
||||
// Implements the driver Matches Pdo operation.
|
||||
static bool IoDriverMatchesPdo(const DRIVER_OBJECT* driver, const DEVICE_OBJECT* pdo) {
|
||||
if (!driver || !driver->IdTable || !pdo || pdo->Type != DeviceObjectPhysical)
|
||||
return false;
|
||||
|
||||
for (size_t d = 0; d < driver->IdTable->Count; d++) {
|
||||
const IO_DEVICE_ID* want = &driver->IdTable->Ids[d];
|
||||
if (want->BusType != IoBusUnknown && want->BusType != pdo->u.Pdo.BusType)
|
||||
continue;
|
||||
for (uint8_t p = 0; p < pdo->u.Pdo.IdCount; p++) {
|
||||
if (SysSvEqual(want->Id, pdo->u.Pdo.Ids[p].Id))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implements the try Add Device For Driver operation.
|
||||
static bool IoTryAddDeviceForDriver(DRIVER_OBJECT* driver, DEVICE_OBJECT* pdo) {
|
||||
if (!driver || !pdo || !driver->DriverAddDevice)
|
||||
return false;
|
||||
if (!IoDriverMatchesPdo(driver, pdo))
|
||||
return false;
|
||||
|
||||
KSTATUS st = driver->DriverAddDevice(driver, pdo);
|
||||
if (KSUCCESS(st)) {
|
||||
DbgPrint("io: AddDevice driver=%v pdo=%v bus=%s\n",
|
||||
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), IoBusTypeName(pdo->u.Pdo.BusType));
|
||||
|
||||
KSTATUS start = IoSendPnpIrpSync(pdo, IRP_MN_START_DEVICE);
|
||||
if (!KSUCCESS(start) && start != NTLSTATUS_NOT_SUPPORTED) {
|
||||
DbgPrint("io: START_DEVICE failed driver=%v pdo=%v st=0x%x\n",
|
||||
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), start);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
DbgPrint("io: AddDevice failed driver=%v pdo=%v st=0x%x\n",
|
||||
IoSvOrUnnamed(driver->Name), IoSvOrUnnamed(pdo->Name), st);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#include <kernel/io_pnp.h>
|
||||
|
||||
__declspec(dllexport) void IoInitializeDriverObject(DRIVER_OBJECT* driver,
|
||||
SYS_STRING_VIEW name) {
|
||||
@@ -86,42 +21,12 @@ __declspec(dllexport) void IoInitializeDriverObject(DRIVER_OBJECT* driver,
|
||||
driver->Name = name;
|
||||
}
|
||||
|
||||
// Registers driver Object.
|
||||
__declspec(dllexport) KSTATUS IoRegisterDriverObject(DRIVER_OBJECT* driver) {
|
||||
if (!driver) return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (!SysSvIsUtf8Text(driver->Name)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (gDriverObjectCount >= MAX_DRIVER_OBJECTS)
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
|
||||
if (driver->Header.Type != ObjectTypeDriver ||
|
||||
driver->Header.LifetimeState != ObjectAlive) {
|
||||
ObInitializeObjectHeader(&driver->Header, ObjectTypeDriver);
|
||||
}
|
||||
|
||||
gDriverObjects[gDriverObjectCount++] = driver;
|
||||
DbgPrint("io: registered driver object %v\n", IoSvOrUnnamed(driver->Name));
|
||||
|
||||
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++)
|
||||
(void)IoTryAddDeviceForDriver(driver, gPhysicalDevices[i]);
|
||||
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Device object lifetime.
|
||||
|
||||
static void IoDeviceDestroy(OBJECT* object) {
|
||||
DEVICE_OBJECT* dev = (DEVICE_OBJECT*)object;
|
||||
IoDmaDetachDevice(dev);
|
||||
|
||||
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) {
|
||||
if (gPhysicalDevices[i] == dev) {
|
||||
gPhysicalDevices[i] = gPhysicalDevices[gPhysicalDeviceCount - 1u];
|
||||
gPhysicalDevices[gPhysicalDeviceCount - 1u] = (DEVICE_OBJECT*)0;
|
||||
gPhysicalDeviceCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->LowerDevice)
|
||||
IoDetachDevice(dev);
|
||||
|
||||
@@ -232,27 +137,11 @@ __declspec(dllexport) KSTATUS IoRegisterPhysicalDevice(DEVICE_OBJECT* pdo) {
|
||||
if (!pdo || pdo->Type != DeviceObjectPhysical)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) {
|
||||
if (gPhysicalDevices[i] == pdo)
|
||||
return NTLSTATUS_ALREADY_EXISTS;
|
||||
}
|
||||
KSTATUS status = IoPnpPhysicalDeviceArrived(pdo);
|
||||
if (!KSUCCESS(status)) return status;
|
||||
|
||||
if (gPhysicalDeviceCount >= MAX_PDO_OBJECTS)
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
IoPnpPhysicalDevicePublished(pdo);
|
||||
|
||||
gPhysicalDevices[gPhysicalDeviceCount++] = pdo;
|
||||
|
||||
bool anyMatched = false;
|
||||
for (uint32_t i = 0; i < gDriverObjectCount; i++) {
|
||||
if (IoTryAddDeviceForDriver(gDriverObjects[i], pdo))
|
||||
anyMatched = true;
|
||||
}
|
||||
|
||||
if (!anyMatched && pdo->u.Pdo.BusType == IoBusUsb) {
|
||||
SYS_STRING_VIEW id = pdo->u.Pdo.IdCount ? pdo->u.Pdo.Ids[0].Id : SYS_SV_LITERAL("<no-id>");
|
||||
DbgPrint("io: no function driver for pdo=%v id=%v bus=%s\n",
|
||||
IoSvOrUnnamed(pdo->Name), id, IoBusTypeName(pdo->u.Pdo.BusType));
|
||||
}
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -280,24 +169,6 @@ __declspec(dllexport) void IoDereferenceDeviceObject(DEVICE_OBJECT* device) {
|
||||
if (device) ObDereferenceObject(&device->Header);
|
||||
}
|
||||
|
||||
// Releases physical Device Registry Entry.
|
||||
static void IoRemovePhysicalDeviceRegistryEntry(DEVICE_OBJECT* device) {
|
||||
if (!device || device->Type != DeviceObjectPhysical)
|
||||
return;
|
||||
|
||||
for (uint32_t i = 0; i < gPhysicalDeviceCount; i++) {
|
||||
if (gPhysicalDevices[i] == device) {
|
||||
for (uint32_t j = i + 1; j < gPhysicalDeviceCount; j++)
|
||||
gPhysicalDevices[j - 1] = gPhysicalDevices[j];
|
||||
gPhysicalDeviceCount--;
|
||||
if (gPhysicalDeviceCount < MAX_PDO_OBJECTS)
|
||||
gPhysicalDevices[gPhysicalDeviceCount] = (DEVICE_OBJECT*)0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the unlink Device From Parent operation.
|
||||
static void IoUnlinkDeviceFromParent(DEVICE_OBJECT* device) {
|
||||
if (!device || !device->Parent)
|
||||
return;
|
||||
@@ -333,9 +204,11 @@ __declspec(dllexport) void IoDeleteDevice(DEVICE_OBJECT* device) {
|
||||
device->PnpState = DevicePnpDeleted;
|
||||
KeReleaseSpinlock(&device->Lock, flags);
|
||||
|
||||
IoDmaDetachDevice(device);
|
||||
if (device->Type == DeviceObjectPhysical)
|
||||
IoPnpPhysicalDeviceRemoved(device);
|
||||
else
|
||||
IoDmaDetachDevice(device);
|
||||
IoUnlinkDeviceFromParent(device);
|
||||
IoRemovePhysicalDeviceRegistryEntry(device);
|
||||
IoDereferenceDeviceObject(device);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user