📄 isochapi.c
字号:
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
isochapi.c
Abstract
Author:
Peter Binder (pbinder) 7/26/97
Revision History:
Date Who What
-------- --------- ------------------------------------------------------------
7/26/97 pbinder birth
4/14/98 pbinder taken from 1394diag
--*/
#include "pch.h"
NTSTATUS
t1394Diag_IsochAllocateBandwidth(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG nMaxBytesPerFrameRequested,
IN ULONG fulSpeed,
OUT PHANDLE phBandwidth,
OUT PULONG pBytesPerFrameAvailable,
OUT PULONG pSpeedSelected
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIRB pIrb;
ENTER("t1394Diag_IsochAllocateBandwidth");
TRACE(TL_TRACE, ("nMaxBytesPerFrameRequested = 0x%x\n", nMaxBytesPerFrameRequested));
TRACE(TL_TRACE, ("fulSpeed = 0x%x\n", fulSpeed));
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
TRAP;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateBandwidth;
} // if
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_BANDWIDTH;
pIrb->Flags = 0;
pIrb->u.IsochAllocateBandwidth.nMaxBytesPerFrameRequested = nMaxBytesPerFrameRequested;
pIrb->u.IsochAllocateBandwidth.fulSpeed = fulSpeed;
ntStatus = t1394Diag_SubmitIrpSynch(deviceExtension->StackDeviceObject, Irp, pIrb);
if (NT_SUCCESS(ntStatus)) {
*phBandwidth = pIrb->u.IsochAllocateBandwidth.hBandwidth;
*pBytesPerFrameAvailable = pIrb->u.IsochAllocateBandwidth.BytesPerFrameAvailable;
*pSpeedSelected = pIrb->u.IsochAllocateBandwidth.SpeedSelected;
TRACE(TL_TRACE, ("hBandwidth = 0x%x\n", *phBandwidth));
TRACE(TL_TRACE, ("BytesPerFrameAvailable = 0x%x\n", *pBytesPerFrameAvailable));
// lets see if we got the speed we wanted
if (fulSpeed != pIrb->u.IsochAllocateBandwidth.SpeedSelected) {
TRACE(TL_TRACE, ("Different bandwidth speed selected.\n"));
}
TRACE(TL_TRACE, ("SpeedSelected = 0x%x\n", *pSpeedSelected));
}
else {
TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
TRAP;
}
ExFreePool(pIrb);
Exit_IsochAllocateBandwidth:
EXIT("t1394Diag_IsochAllocateBandwidth", ntStatus);
return(ntStatus);
} // t1394Diag_IsochAllocateBandwidth
NTSTATUS
t1394Diag_IsochAllocateChannel(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG nRequestedChannel,
OUT PULONG pChannel,
OUT PLARGE_INTEGER pChannelsAvailable
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIRB pIrb;
ENTER("t1394Diag_IsochAllocateChannel");
TRACE(TL_TRACE, ("nRequestedChannel = 0x%x\n", nRequestedChannel));
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
TRAP;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateChannel;
} // if
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_CHANNEL;
pIrb->Flags = 0;
pIrb->u.IsochAllocateChannel.nRequestedChannel = nRequestedChannel;
ntStatus = t1394Diag_SubmitIrpSynch(deviceExtension->StackDeviceObject, Irp, pIrb);
if (NT_SUCCESS(ntStatus)) {
*pChannel = pIrb->u.IsochAllocateChannel.Channel;
*pChannelsAvailable = pIrb->u.IsochAllocateChannel.ChannelsAvailable;
TRACE(TL_TRACE, ("Channel = 0x%x\n", *pChannel));
TRACE(TL_TRACE, ("ChannelsAvailable.LowPart = 0x%x\n", pChannelsAvailable->LowPart));
TRACE(TL_TRACE, ("ChannelsAvailable.HighPart = 0x%x\n", pChannelsAvailable->HighPart));
}
else {
TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
TRAP;
}
ExFreePool(pIrb);
Exit_IsochAllocateChannel:
EXIT("t1394Diag_IsochAllocateChannel", ntStatus);
return(ntStatus);
} // t1394Diag_IsochAllocateChannel
NTSTATUS
t1394Diag_IsochAllocateResources(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG fulSpeed,
IN ULONG fulFlags,
IN ULONG nChannel,
IN ULONG nMaxBytesPerFrame,
IN ULONG nNumberOfBuffers,
IN ULONG nMaxBufferSize,
IN ULONG nQuadletsToStrip,
OUT PHANDLE phResource
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIRB pIrb;
ENTER("t1394Diag_IsochAllocateResources");
TRACE(TL_TRACE, ("fulSpeed = 0x%x\n", fulSpeed));
TRACE(TL_TRACE, ("fulFlags = 0x%x\n", fulFlags));
TRACE(TL_TRACE, ("nChannel = 0x%x\n", nChannel));
TRACE(TL_TRACE, ("nMaxBytesPerFrame = 0x%x\n", nMaxBytesPerFrame));
TRACE(TL_TRACE, ("nNumberOfBuffers = 0x%x\n", nNumberOfBuffers));
TRACE(TL_TRACE, ("nMaxBufferSize = 0x%x\n", nMaxBufferSize));
TRACE(TL_TRACE, ("nQuadletsToStrip = 0x%x\n", nQuadletsToStrip));
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
TRAP;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateResources;
} // if
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_RESOURCES;
pIrb->Flags = 0;
pIrb->u.IsochAllocateResources.fulSpeed = fulSpeed;
pIrb->u.IsochAllocateResources.fulFlags = fulFlags;
pIrb->u.IsochAllocateResources.nChannel = nChannel;
pIrb->u.IsochAllocateResources.nMaxBytesPerFrame = nMaxBytesPerFrame;
pIrb->u.IsochAllocateResources.nNumberOfBuffers = nNumberOfBuffers;
pIrb->u.IsochAllocateResources.nMaxBufferSize = nMaxBufferSize;
pIrb->u.IsochAllocateResources.nQuadletsToStrip = nQuadletsToStrip;
ntStatus = t1394Diag_SubmitIrpSynch(deviceExtension->StackDeviceObject, Irp, pIrb);
if (NT_SUCCESS(ntStatus)) {
PISOCH_RESOURCE_DATA IsochResourceData;
KIRQL Irql;
*phResource = pIrb->u.IsochAllocateResources.hResource;
TRACE(TL_TRACE, ("hResource = 0x%x\n", *phResource));
// need to add to our list...
IsochResourceData = ExAllocatePool(NonPagedPool, sizeof(ISOCH_RESOURCE_DATA));
if (IsochResourceData) {
IsochResourceData->hResource = pIrb->u.IsochAllocateResources.hResource;
KeAcquireSpinLock(&deviceExtension->IsochResourceSpinLock, &Irql);
InsertHeadList(&deviceExtension->IsochResourceData, &IsochResourceData->IsochResourceList);
KeReleaseSpinLock(&deviceExtension->IsochResourceSpinLock, Irql);
}
else {
TRACE(TL_WARNING, ("Failed to allocate IsochResourceData!\n"));
}
}
else {
TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus));
TRAP;
}
ExFreePool(pIrb);
Exit_IsochAllocateResources:
EXIT("t1394Diag_IsochAllocateResources", ntStatus);
return(ntStatus);
} // t1394Diag_IsochAllocateResources
NTSTATUS
t1394Diag_IsochAttachBuffers(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG outputBufferLength,
IN HANDLE hResource,
IN ULONG nNumberOfDescriptors,
OUT PISOCH_DESCRIPTOR pIsochDescriptor,
IN OUT PRING3_ISOCH_DESCRIPTOR R3_IsochDescriptor
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIRB pIrb;
ULONG i;
PISOCH_DETACH_DATA pIsochDetachData;
PRING3_ISOCH_DESCRIPTOR pR3TempDescriptor;
KIRQL Irql;
PIO_STACK_LOCATION NextIrpStack;
LARGE_INTEGER deltaTime;
ENTER("t1394Diag_IsochAttachBuffers");
TRACE(TL_TRACE, ("outputBufferLength = 0x%x\n", outputBufferLength));
TRACE(TL_TRACE, ("hResource = 0x%x\n", hResource));
TRACE(TL_TRACE, ("nNumberOfDescriptors = 0x%x\n", nNumberOfDescriptors));
TRACE(TL_TRACE, ("R3_IsochDescriptor = 0x%x\n", R3_IsochDescriptor));
//
// allocate the irb
//
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
TRAP;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAttachBuffers;
} // if
//
// allocate our isoch descriptors
//
pIsochDescriptor = ExAllocatePool(NonPagedPool, sizeof(ISOCH_DESCRIPTOR)*nNumberOfDescriptors);
if (!pIsochDescriptor) {
TRACE(TL_ERROR, ("Failed to allocate pIsochDescriptor!\n"));
TRAP;
if (pIrb)
ExFreePool(pIrb);
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAttachBuffers;
}
KeAcquireSpinLock(&deviceExtension->IsochSpinLock, &Irql);
pR3TempDescriptor = R3_IsochDescriptor;
for (i=0;i < nNumberOfDescriptors; i++) {
TRACE(TL_TRACE, ("pR3TempDescriptor = 0x%x\n", pR3TempDescriptor));
TRACE(TL_TRACE, ("pR3TempDescriptor->fulFlags = 0x%x\n", pR3TempDescriptor->fulFlags));
TRACE(TL_TRACE, ("pR3TempDescriptor->ulLength = 0x%x\n", pR3TempDescriptor->ulLength));
TRACE(TL_TRACE, ("pR3TempDescriptor->nMaxBytesPerFrame = 0x%x\n", pR3TempDescriptor->nMaxBytesPerFrame));
TRACE(TL_TRACE, ("pR3TempDescriptor->ulSynch = 0x%x\n", pR3TempDescriptor->ulSynch));
TRACE(TL_TRACE, ("pR3TempDescriptor->ulTag = 0x%x\n", pR3TempDescriptor->ulTag));
TRACE(TL_TRACE, ("pR3TempDescriptor->CycleTime.CL_CycleOffset = 0x%x\n", pR3TempDescriptor->CycleTime.CL_CycleOffset));
TRACE(TL_TRACE, ("pR3TempDescriptor->CycleTime.CL_CycleCount = 0x%x\n", pR3TempDescriptor->CycleTime.CL_CycleCount));
TRACE(TL_TRACE, ("pR3TempDescriptor->CycleTime.CL_SecondCount = 0x%x\n", pR3TempDescriptor->CycleTime.CL_SecondCount));
TRACE(TL_TRACE, ("pR3TempDescriptor->Data = 0x%x\n", &pR3TempDescriptor->Data));
TRACE(TL_TRACE, ("pIsochDescriptor[%x] = 0x%x\n", i, &pIsochDescriptor[i]));
pIsochDescriptor[i].Mdl = MmCreateMdl(NULL, pR3TempDescriptor->Data, pR3TempDescriptor->ulLength);
MmBuildMdlForNonPagedPool(pIsochDescriptor[i].Mdl);
pIsochDescriptor[i].fulFlags = pR3TempDescriptor->fulFlags;
pIsochDescriptor[i].ulLength = MmGetMdlByteCount(pIsochDescriptor[i].Mdl);
pIsochDescriptor[i].nMaxBytesPerFrame = pR3TempDescriptor->nMaxBytesPerFrame;
pIsochDescriptor[i].ulSynch = pR3TempDescriptor->ulSynch;
pIsochDescriptor[i].ulTag = pR3TempDescriptor->ulTag;
pIsochDescriptor[i].CycleTime = pR3TempDescriptor->CycleTime;
if (pR3TempDescriptor->bUseCallback) {
//
// i'm hoping this is the last descriptor. they should have only set this in the
// last descriptor, since elsewhere it's not supported.
//
if (i != nNumberOfDescriptors-1) {
TRACE(TL_TRACE, ("Callback on descriptor prior to last!\n"));
// setting callback to NULL
pIsochDescriptor[i].Callback = NULL;
}
else {
// need to save hResource, numDescriptors and Irp to use when detaching.
// this needs to be done before we submit the irp, since the isoch callback
// can be called before the submitirpsynch call completes.
pIsochDetachData = ExAllocatePool(NonPagedPool, sizeof(ISOCH_DETACH_DATA));
if (!pIsochDetachData) {
TRACE(TL_ERROR, ("Failed to allocate pIsochDetachData!\n"));
TRAP;
if (pIsochDescriptor) {
ExFreePool(pIsochDescriptor);
}
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAttachBuffers;
}
pIsochDetachData->Tag = ISOCH_DETACH_TAG;
pIsochDetachData->AttachIrb = pIrb;
InsertHeadList(&deviceExtension->IsochDetachData, &pIsochDetachData->IsochDetachList);
KeInitializeTimer(&pIsochDetachData->Timer);
KeInitializeDpc(&pIsochDetachData->TimerDpc, t1394Diag_IsochTimeout, pIsochDetachData);
#define REQUEST_BUSY_RETRY_VALUE (ULONG)(-100 * 100 * 100 * 100) //80 msecs in units of 100nsecs
deltaTime.LowPart = REQUEST_BUSY_RETRY_VALUE;
deltaTime.HighPart = -1;
KeSetTimer(&pIsochDetachData->Timer, deltaTime, &pIsochDetachData->TimerDpc);
pIsochDetachData->outputBufferLength = outputBufferLength;
pIsochDetachData->DeviceExtension = deviceExtension;
pIsochDetachData->hResource = hResource;
pIsochDetachData->numIsochDescriptors = nNumberOfDescriptors;
pIsochDetachData->IsochDescriptor = pIsochDescriptor;
pIsochDetachData->Irp = Irp;
pIsochDetachData->bDetach = pR3TempDescriptor->bAutoDetach;
pIsochDescriptor[i].Callback = t1394Diag_IsochCallback;
pIsochDescriptor[i].Context1 = deviceExtension;
pIsochDescriptor[i].Context2 = pIsochDetachData;
TRACE(TL_TRACE, ("IsochAttachBuffers: pIsochDetachData = 0x%x\n", pIsochDetachData));
TRACE(TL_TRACE, ("IsochAttachBuffers: pIsochDetachData->Irp = 0x%x\n", pIsochDetachData->Irp));
}
}
else {
pIsochDescriptor[i].Callback = NULL;
}
TRACE(TL_TRACE, ("pIsochDescriptor[%x].fulFlags = 0x%x\n", i, pIsochDescriptor[i].fulFlags));
TRACE(TL_TRACE, ("pIsochDescriptor[%x].ulLength = 0x%x\n", i, pIsochDescriptor[i].ulLength));
TRACE(TL_TRACE, ("pIsochDescriptor[%x].nMaxBytesPerFrame = 0x%x\n", i, pIsochDescriptor[i].nMaxBytesPerFrame));
TRACE(TL_TRACE, ("pIsochDescriptor[%x].ulSynch = 0x%x\n", i, pIsochDescriptor[i].ulSynch));
TRACE(TL_TRACE, ("pIsochDescriptor[%x].ulTag = 0x%x\n", i, pIsochDescriptor[i].ulTag));
TRACE(TL_TRACE, ("pIsochDescriptor[%x].CycleTime.CL_CycleOffset = 0x%x\n", i, pIsochDescriptor[i].CycleTime.CL_CycleOffset));
TRACE(TL_TRACE, ("pIsochDescriptor[%x].CycleTime.CL_CycleCount = 0x%x\n", i, pIsochDescriptor[i].CycleTime.CL_CycleCount));
TRACE(TL_TRACE, ("pIsochDescriptor[%x].CycleTime.CL_SecondCount = 0x%x\n", i, pIsochDescriptor[i].CycleTime.CL_SecondCount));
pR3TempDescriptor =
(PRING3_ISOCH_DESCRIPTOR)((ULONG_PTR)pR3TempDescriptor +
pIsochDescriptor[i].ulLength +
sizeof(RING3_ISOCH_DESCRIPTOR));
} // for
KeReleaseSpinLock(&deviceExtension->IsochSpinLock, Irql);
// lets make sure the device is still around
// if it isn't, we free the irb and return, our pnp
// cleanup will take care of everything else
if (deviceExtension->bShutdown) {
TRACE(TL_TRACE, ("Shutdown!\n"));
ntStatus = STATUS_NO_SUCH_DEVICE;
goto Exit_IsochAttachBuffers;
}
pIrb->FunctionNumber = REQUEST_ISOCH_ATTACH_BUFFERS;
pIrb->Flags = 0;
pIrb->u.IsochAttachBuffers.hResource = hResource;
pIrb->u.IsochAttachBuffers.nNumberOfDescriptors = nNumberOfDescriptors;
pIrb->u.IsochAttachBuffers.pIsochDescriptor = pIsochDescriptor;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -