📄 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
--*/
NTSTATUS
t1394_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 = NULL;
PIRP newIrp = NULL;
BOOLEAN allocNewIrp = FALSE;
KEVENT Event;
IO_STATUS_BLOCK ioStatus;
ENTER("t1394_IsochAllocateBandwidth");
TRACE(TL_TRACE, ("nMaxBytesPerFrameRequested = 0x%x\n", nMaxBytesPerFrameRequested));
TRACE(TL_TRACE, ("fulSpeed = 0x%x\n", fulSpeed));
//
// If this is a UserMode request create a newIrp so that the request
// will be issued from KernelMode
//
if (Irp->RequestorMode == UserMode) {
newIrp = IoBuildDeviceIoControlRequest (IOCTL_1394_CLASS, deviceExtension->StackDeviceObject,
NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);
if (!newIrp) {
TRACE(TL_ERROR, ("Failed to allocate newIrp!\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateBandwidth;
}
allocNewIrp = TRUE;
}
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateBandwidth;
} // if
RtlZeroMemory (pIrb, sizeof (IRB));
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_BANDWIDTH;
pIrb->Flags = 0;
pIrb->u.IsochAllocateBandwidth.nMaxBytesPerFrameRequested = nMaxBytesPerFrameRequested;
pIrb->u.IsochAllocateBandwidth.fulSpeed = fulSpeed;
//
// If we allocated this irp, submit it asynchronously and wait for its
// completion event to be signaled. Otherwise submit it synchronously
//
if (allocNewIrp) {
KeInitializeEvent (&Event, NotificationEvent, FALSE);
ntStatus = t1394_SubmitIrpAsync (deviceExtension->StackDeviceObject, newIrp, pIrb);
if (ntStatus == STATUS_PENDING) {
KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
ntStatus = ioStatus.Status;
}
}
else {
ntStatus = t1394_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));
}
Exit_IsochAllocateBandwidth:
if (pIrb)
{
ExFreePool(pIrb);
}
if (allocNewIrp)
{
Irp->IoStatus = ioStatus;
}
EXIT("t1394_IsochAllocateBandwidth", ntStatus);
return(ntStatus);
} // t1394_IsochAllocateBandwidth
NTSTATUS
t1394_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 = NULL;
PIRP newIrp = NULL;
BOOLEAN allocNewIrp = FALSE;
KEVENT Event;
IO_STATUS_BLOCK ioStatus;
ENTER("t1394_IsochAllocateChannel");
TRACE(TL_TRACE, ("nRequestedChannel = 0x%x\n", nRequestedChannel));
//
// If this is a UserMode request create a newIrp so that the request
// will be issued from KernelMode
//
if (Irp->RequestorMode == UserMode) {
newIrp = IoBuildDeviceIoControlRequest (IOCTL_1394_CLASS, deviceExtension->StackDeviceObject,
NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);
if (!newIrp) {
TRACE(TL_ERROR, ("Failed to allocate newIrp!\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateChannel;
}
allocNewIrp = TRUE;
}
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateChannel;
} // if
RtlZeroMemory (pIrb, sizeof (IRB));
pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_CHANNEL;
pIrb->Flags = 0;
pIrb->u.IsochAllocateChannel.nRequestedChannel = nRequestedChannel;
//
// If we allocated this irp, submit it asynchronously and wait for its
// completion event to be signaled. Otherwise submit it synchronously
//
if (allocNewIrp) {
KeInitializeEvent (&Event, NotificationEvent, FALSE);
ntStatus = t1394_SubmitIrpAsync (deviceExtension->StackDeviceObject, newIrp, pIrb);
if (ntStatus == STATUS_PENDING) {
KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
ntStatus = ioStatus.Status;
}
}
else {
ntStatus = t1394_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));
}
Exit_IsochAllocateChannel:
if (pIrb)
{
ExFreePool(pIrb);
}
if (allocNewIrp)
{
Irp->IoStatus = ioStatus;
}
EXIT("t1394_IsochAllocateChannel", ntStatus);
return(ntStatus);
} // t1394_IsochAllocateChannel
NTSTATUS
t1394_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 = NULL;
PIRP newIrp = NULL;
BOOLEAN allocNewIrp = FALSE;
KEVENT Event;
IO_STATUS_BLOCK ioStatus;
ENTER("t1394_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));
//
// If this is a UserMode request create a newIrp so that the request
// will be issued from KernelMode
//
if (Irp->RequestorMode == UserMode) {
newIrp = IoBuildDeviceIoControlRequest (IOCTL_1394_CLASS, deviceExtension->StackDeviceObject,
NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);
if (!newIrp) {
TRACE(TL_ERROR, ("Failed to allocate newIrp!\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateResources;
}
allocNewIrp = TRUE;
}
pIrb = ExAllocatePool(NonPagedPool, sizeof(IRB));
if (!pIrb) {
TRACE(TL_ERROR, ("Failed to allocate pIrb!\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Exit_IsochAllocateResources;
} // if
RtlZeroMemory (pIrb, sizeof (IRB));
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;
//
// If we allocated this irp, submit it asynchronously and wait for its
// completion event to be signaled. Otherwise submit it synchronously
//
if (allocNewIrp) {
KeInitializeEvent (&Event, NotificationEvent, FALSE);
ntStatus = t1394_SubmitIrpAsync (deviceExtension->StackDeviceObject, newIrp, pIrb);
if (ntStatus == STATUS_PENDING) {
KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
ntStatus = ioStatus.Status;
}
}
else {
ntStatus = t1394_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));
}
Exit_IsochAllocateResources:
if (pIrb)
{
ExFreePool(pIrb);
}
if (allocNewIrp)
{
Irp->IoStatus = ioStatus;
}
EXIT("t1394_IsochAllocateResources", ntStatus);
return(ntStatus);
} // t1394_IsochAllocateResources
NTSTATUS
t1394_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, j;
PISOCH_DETACH_DATA pIsochDetachData = NULL;
PRING3_ISOCH_DESCRIPTOR pR3TempDescriptor = NULL;
KIRQL Irql;
PIO_STACK_LOCATION NextIrpStack = NULL;
LARGE_INTEGER deltaTime;
PIRP newIrp = NULL;
CCHAR StackSize;
ENTER("t1394_IsochAttachBuffers");
TRACE(TL_TRACE, ("outputBufferLength = 0x%x\n", outputBufferLength));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -