Skip to content

Commit

Permalink
Fix BSOD with HDA devices accessing bus while it's powered off
Browse files Browse the repository at this point in the history
  • Loading branch information
coolstar committed Mar 1, 2023
1 parent f350ae9 commit a81b1f6
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions sklhdaudbus/hdaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ NTSTATUS HDA_TransferCodecVerbs(

PFDO_CONTEXT fdoCtx = devData->FdoContext;

status = SendHDACmds(fdoCtx, Count, CodecTransfer);
status = WdfDeviceStopIdle(devData->FdoContext->WdfDevice, TRUE);
if (!NT_SUCCESS(status)) {
return status;
}

status = SendHDACmds(fdoCtx, Count, CodecTransfer);
if (!NT_SUCCESS(status)) {
goto out;
}

UINT16 codecAddr = (UINT16)devData->CodecIds.CodecAddress;

int timeout_ms = 1000;
Expand All @@ -50,7 +55,8 @@ NTSTATUS HDA_TransferCodecVerbs(
InterlockedAdd(&fdoCtx->rirb.cmds[codecAddr], Count - TransferredCount);

SklHdAudBusPrint(DEBUG_LEVEL_VERBOSE, DBG_IOCTL, "%s timeout (Count: %d, transferred %d)!\n", __func__, Count, TransferredCount);
return STATUS_IO_TIMEOUT;
status = STATUS_IO_TIMEOUT;
goto out;
}

LARGE_INTEGER Timeout;
Expand All @@ -64,7 +70,12 @@ NTSTATUS HDA_TransferCodecVerbs(
DbgPrint("Got Callback\n");
Callback(CodecTransfer, Context);
}
return STATUS_SUCCESS;

status = STATUS_SUCCESS;

out:
WdfDeviceResumeIdle(fdoCtx->WdfDevice);
return status;
}

NTSTATUS HDA_AllocateCaptureDmaEngine(
Expand All @@ -87,6 +98,11 @@ NTSTATUS HDA_AllocateCaptureDmaEngine(

PFDO_CONTEXT fdoContext = devData->FdoContext;

NTSTATUS status = WdfDeviceStopIdle(devData->FdoContext->WdfDevice, TRUE);
if (!NT_SUCCESS(status)) {
return status;
}

WdfInterruptAcquireLock(devData->FdoContext->Interrupt);
for (UINT32 i = 0; i < fdoContext->captureStreams; i++) {
int tag = fdoContext->captureIndexOff + i;
Expand All @@ -109,6 +125,7 @@ NTSTATUS HDA_AllocateCaptureDmaEngine(
}

WdfInterruptReleaseLock(devData->FdoContext->Interrupt);
WdfDeviceResumeIdle(devData->FdoContext->WdfDevice);
return STATUS_INSUFFICIENT_RESOURCES;
}

Expand All @@ -130,6 +147,11 @@ NTSTATUS HDA_AllocateRenderDmaEngine(

PFDO_CONTEXT fdoContext = devData->FdoContext;

NTSTATUS status = WdfDeviceStopIdle(devData->FdoContext->WdfDevice, TRUE);
if (!NT_SUCCESS(status)) {
return status;
}

WdfInterruptAcquireLock(devData->FdoContext->Interrupt);
for (UINT32 i = 0; i < fdoContext->playbackStreams; i++) {
int tag = fdoContext->playbackIndexOff + i;
Expand All @@ -153,6 +175,7 @@ NTSTATUS HDA_AllocateRenderDmaEngine(
}

WdfInterruptReleaseLock(devData->FdoContext->Interrupt);
WdfDeviceResumeIdle(devData->FdoContext->WdfDevice);
return STATUS_INSUFFICIENT_RESOURCES;
}

Expand Down Expand Up @@ -223,6 +246,8 @@ NTSTATUS HDA_FreeDmaEngine(
stream->PdoContext = NULL;
WdfInterruptReleaseLock(devData->FdoContext->Interrupt);

WdfDeviceResumeIdle(devData->FdoContext->WdfDevice);

return STATUS_SUCCESS;
}

Expand Down

0 comments on commit a81b1f6

Please sign in to comment.