usb hubs, hotplug support, unplug support, saving log files to disk, smt

This commit is contained in:
maksw committed 2026-06-09 09:14:24 +02:00
1 parent b838f8d83d
commit 27b31f62b6
39 files changed
+6294 -735

No files matched your search

+104 -17
View File
@@ -21,6 +21,9 @@ IRP_QUEUE gIrpQueue;
SEMAPHORE *gIrpSemaphore = NULL;
EVENT *gDmaEvent = NULL; // auto-reset; DPC signals after each xfer
KDPC gDmaDpc; // bottom half for DMA completion
IO_REMOVE_LOCK gRemoveLock;
bool gSurpriseRemoved = false;
bool gRemoved = false;
// ---------------------------------------------------------------------------
// Bus Master I/O helpers
@@ -307,6 +310,28 @@ static KSTATUS IdeDmaRw(uint64_t lba, uint32_t count, void *buf, bool write) {
return STATUS_SUCCESS;
}
static KSTATUS IdeGetIrpReadWrite(IRP* irp, bool* outWrite, uint64_t* outLba,
uint32_t* outSectors, void** outBuffer) {
if (!irp || !outWrite || !outLba || !outSectors || !outBuffer)
return STATUS_INVALID_PARAMETER;
IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp);
if (!ios) return STATUS_INVALID_PARAMETER;
if (ios->MajorFunction != IRP_MJ_READ && ios->MajorFunction != IRP_MJ_WRITE)
return STATUS_INVALID_PARAMETER;
if ((ios->Parameters.ReadWrite.ByteOffset & 511ull) ||
(ios->Parameters.ReadWrite.Length & 511u))
return STATUS_INVALID_PARAMETER;
if (!irp->UserBuffer || ios->Parameters.ReadWrite.Length == 0)
return STATUS_INVALID_PARAMETER;
*outWrite = (ios->MajorFunction == IRP_MJ_WRITE);
*outLba = ios->Parameters.ReadWrite.ByteOffset >> 9;
*outSectors = ios->Parameters.ReadWrite.Length >> 9;
*outBuffer = irp->UserBuffer;
return STATUS_SUCCESS;
}
// ---------------------------------------------------------------------------
// IdeWorker — kernel thread, one per IDE controller.
//
@@ -320,17 +345,22 @@ void IdeWorker(uintptr_t arg) {
IRP *irp = IrpQueueDequeue(&gIrpQueue);
if (!irp)
KePanic(KE_PANIC_CODE_DRIVER, "IdeWorker: semaphore fired but IRP queue is empty — accounting bug\n");
continue;
KSTATUS st;
if (irp->Lba + irp->SectorCount > gSectorCount) {
st = STATUS_INVALID_PARAMETER;
} else {
bool write = !!(irp->Flags & IRP_FLAG_WRITE);
st = IdeDmaRw(irp->Lba, irp->SectorCount, irp->Buffer, write);
bool write = false;
uint64_t lba = 0;
uint32_t sectors = 0;
void* buffer = (void*)0;
KSTATUS st = IdeGetIrpReadWrite(irp, &write, &lba, &sectors, &buffer);
if (KSUCCESS(st)) {
if (lba + sectors > gSectorCount)
st = STATUS_INVALID_PARAMETER;
else
st = IdeDmaRw(lba, sectors, buffer, write);
}
IoCompleteRequest(irp, st, KSUCCESS(st) ? ((size_t)irp->SectorCount * 512u) : 0);
IoReleaseRemoveLock(&gRemoveLock, irp);
IoCompleteRequest(irp, st, KSUCCESS(st) ? ((size_t)sectors * 512u) : 0);
}
}
@@ -344,8 +374,20 @@ void IdeWorker(uintptr_t arg) {
// ---------------------------------------------------------------------------
static KSTATUS IdeDispatchReadWrite(DEVICE_OBJECT *device, IRP *irp) {
(void)device;
if (!irp || !irp->Buffer || irp->SectorCount == 0) return STATUS_INVALID_PARAMETER;
if (irp->Lba + irp->SectorCount > gSectorCount) return STATUS_INVALID_PARAMETER;
KSTATUS st = IoAcquireRemoveLock(&gRemoveLock, irp);
if (!KSUCCESS(st))
return st;
bool write = false;
uint64_t lba = 0;
uint32_t sectors = 0;
void* buffer = (void*)0;
st = IdeGetIrpReadWrite(irp, &write, &lba, &sectors, &buffer);
if (!KSUCCESS(st) || lba + sectors > gSectorCount) {
IoReleaseRemoveLock(&gRemoveLock, irp);
return KSUCCESS(st) ? STATUS_INVALID_PARAMETER : st;
}
irp->Status = STATUS_FAILURE;
irp->Information = 0;
@@ -355,13 +397,53 @@ static KSTATUS IdeDispatchReadWrite(DEVICE_OBJECT *device, IRP *irp) {
return STATUS_PENDING;
}
bool write = !!(irp->Flags & IRP_FLAG_WRITE);
KSTATUS st = write ? IdeWrite(NULL, irp->Lba, irp->SectorCount, irp->Buffer)
: IdeRead (NULL, irp->Lba, irp->SectorCount, irp->Buffer);
IoCompleteRequest(irp, st, KSUCCESS(st) ? ((size_t)irp->SectorCount * 512u) : 0);
st = write ? IdeWrite(NULL, lba, sectors, buffer)
: IdeRead (NULL, lba, sectors, buffer);
IoReleaseRemoveLock(&gRemoveLock, irp);
IoCompleteRequest(irp, st, KSUCCESS(st) ? ((size_t)sectors * 512u) : 0);
return STATUS_PENDING;
}
static void IdeCancelReleaseRemoveLock(IRP* irp, void* context) {
(void)context;
IoReleaseRemoveLock(&gRemoveLock, irp);
}
static KSTATUS IdeDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
if (!device || !irp) return STATUS_INVALID_PARAMETER;
IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp);
if (!ios || ios->MajorFunction != IRP_MJ_PNP)
return STATUS_INVALID_PARAMETER;
switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) {
case IRP_MN_START_DEVICE:
device->PnpState = DevicePnpStarted;
return STATUS_SUCCESS;
case IRP_MN_QUERY_REMOVE_DEVICE:
device->PnpState = DevicePnpRemovePending;
return STATUS_SUCCESS;
case IRP_MN_CANCEL_REMOVE_DEVICE:
device->PnpState = DevicePnpStarted;
return STATUS_SUCCESS;
case IRP_MN_SURPRISE_REMOVAL:
gSurpriseRemoved = true;
device->PnpState = DevicePnpSurpriseRemoved;
IrpQueueCancelAllEx(&gIrpQueue, STATUS_OBJECT_DEAD, IdeCancelReleaseRemoveLock, (void*)0);
return STATUS_SUCCESS;
case IRP_MN_REMOVE_DEVICE:
gRemoved = true;
device->PnpState = DevicePnpDeleted;
IrpQueueCancelAllEx(&gIrpQueue, STATUS_OBJECT_DEAD, IdeCancelReleaseRemoveLock, (void*)0);
IoReleaseRemoveLockAndWait(&gRemoveLock, irp);
IoDeleteDevice(device);
gDevice = (DEVICE_OBJECT*)0;
return STATUS_SUCCESS;
default:
return STATUS_NOT_SUPPORTED;
}
}
// ---------------------------------------------------------------------------
// IdeDmaInit — locate the PCI IDE controller, grab BAR4, allocate the PRDT,
// create sync objects, and register IRQ 14.
@@ -427,13 +509,18 @@ KSTATUS DriverEntry(const HAL_API *hal) {
// ---- Register definitive DEVICE_OBJECT --------------------------------
memset(&gDriver, 0, sizeof(gDriver));
gDriver.Name = "ide";
IoInitializeDriverObject(&gDriver, SYS_SV_LITERAL("ide"));
gDriver.MajorFunction[IRP_MJ_READ] = IdeDispatchReadWrite;
gDriver.MajorFunction[IRP_MJ_WRITE] = IdeDispatchReadWrite;
gDriver.MajorFunction[IRP_MJ_PNP] = IdeDispatchPnp;
KSTATUS st = IoCreateDevice(&gDriver, 0, &gDevice);
KSTATUS st = IoInitializeRemoveLock(&gRemoveLock);
if (!KSUCCESS(st)) return st;
gDevice->SectorCount = gSectorCount;
st = IoCreateDevice(&gDriver, 0, &gDevice);
if (!KSUCCESS(st)) return st;
gDevice->u.Disk.SectorCount = gSectorCount;
gDevice->u.Disk.SectorSize = 512;
gDevice->AlignmentRequirement = 512;
// ---- Try to initialise Bus Master DMA ---------------------------------