Sample Code
Windows Driver Samples/ WDF Hybrid 1394 Virtual Device Sample Driver/ C++/ kmdf/ kmdf_vdev_isoch.c/
/*++ Copyright (c) Microsoft Corporation Module Name: kmdf_vdev_isoch.c Abstract --*/ #include "kmdf_vdev.h" #include "kmdf_vdev_isoch.tmh" // autogenerated for WPP tracing NTSTATUS kmdf1394_IsochAllocateBandwidth ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN OUT PISOCH_ALLOCATE_BANDWIDTH IsochAllocateBandwidth) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); PIRB pIrb = NULL; Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "nMaxBytesPerFrameRequested = 0x%X\n", IsochAllocateBandwidth->nMaxBytesPerFrameRequested); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "fulSpeed = 0x%X\n", IsochAllocateBandwidth->fulSpeed); pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_BANDWIDTH; pIrb->Flags = 0; pIrb->u.IsochAllocateBandwidth.nMaxBytesPerFrameRequested = \ IsochAllocateBandwidth->nMaxBytesPerFrameRequested; pIrb->u.IsochAllocateBandwidth.fulSpeed = IsochAllocateBandwidth->fulSpeed; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (NT_SUCCESS (ntStatus)) { IsochAllocateBandwidth->hBandwidth = \ pIrb->u.IsochAllocateBandwidth.hBandwidth; IsochAllocateBandwidth->BytesPerFrameAvailable= \ pIrb->u.IsochAllocateBandwidth.BytesPerFrameAvailable; IsochAllocateBandwidth->SpeedSelected = \ pIrb->u.IsochAllocateBandwidth.SpeedSelected; DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "hBandwidth = 0x%p\n", IsochAllocateBandwidth->hBandwidth); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "BytesPerFrameAvailable = 0x%X\n", IsochAllocateBandwidth->BytesPerFrameAvailable); // // lets see if we got the speed we wanted // if (IsochAllocateBandwidth->fulSpeed != \ pIrb->u.IsochAllocateBandwidth.SpeedSelected) { DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "Different bandwidth speed selected.\n"); } DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "SpeedSelected = 0x%X\n", IsochAllocateBandwidth->SpeedSelected); } else { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochAllocateBandwidth NTSTATUS kmdf1394_IsochAllocateChannel ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN OUT PISOCH_ALLOCATE_CHANNEL IsochAllocateChannel) { NTSTATUS ntStatus = STATUS_SUCCESS; PIRB pIrb = NULL; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "nRequestedChannel = 0x%X\n", IsochAllocateChannel->nRequestedChannel); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_CHANNEL; pIrb->Flags = 0; pIrb->u.IsochAllocateChannel.nRequestedChannel = \ IsochAllocateChannel->nRequestedChannel; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (NT_SUCCESS (ntStatus)) { IsochAllocateChannel->Channel = pIrb->u.IsochAllocateChannel.Channel; IsochAllocateChannel->ChannelsAvailable = \ pIrb->u.IsochAllocateChannel.ChannelsAvailable; DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "Channel = 0x%X\n", IsochAllocateChannel->Channel); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "ChannelsAvailable.LowPart = 0x%X\n", IsochAllocateChannel->ChannelsAvailable.LowPart); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "ChannelsAvailable.HighPart = 0x%X\n", IsochAllocateChannel->ChannelsAvailable.HighPart); } else { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochAllocateChannel NTSTATUS kmdf1394_IsochAllocateResources ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN OUT PISOCH_ALLOCATE_RESOURCES IsochAllocateResources) { NTSTATUS ntStatus = STATUS_SUCCESS; PIRB pIrb = NULL; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); Enter(); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_ALLOCATE_RESOURCES; pIrb->Flags = 0; pIrb->u.IsochAllocateResources.fulSpeed = IsochAllocateResources->fulSpeed; pIrb->u.IsochAllocateResources.fulFlags = IsochAllocateResources->fulFlags; pIrb->u.IsochAllocateResources.nChannel = IsochAllocateResources->nChannel; pIrb->u.IsochAllocateResources.nMaxBytesPerFrame = \ IsochAllocateResources->nMaxBytesPerFrame; pIrb->u.IsochAllocateResources.nNumberOfBuffers = \ IsochAllocateResources->nNumberOfBuffers; pIrb->u.IsochAllocateResources.nMaxBufferSize = \ IsochAllocateResources->nMaxBufferSize; pIrb->u.IsochAllocateResources.nQuadletsToStrip = \ IsochAllocateResources->nQuadletsToStrip; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (NT_SUCCESS (ntStatus)) { PISOCH_RESOURCE_DATA IsochResourceData; IsochAllocateResources->hResource = \ pIrb->u.IsochAllocateResources.hResource; DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "hResource = 0x%p\n", IsochAllocateResources->hResource); // // need to add to our list... // IsochResourceData = ExAllocatePoolWithTag ( NonPagedPool, sizeof(ISOCH_RESOURCE_DATA), POOLTAG_KMDF_VDEV); if (IsochResourceData) { IsochResourceData->hResource = \ pIrb->u.IsochAllocateResources.hResource; WdfSpinLockAcquire (deviceExtension->IsochResourceSpinLock); InsertHeadList (&deviceExtension->IsochResourceData, &IsochResourceData->IsochResourceList); WdfSpinLockRelease (deviceExtension->IsochResourceSpinLock); } else { DoTraceLevelMessage(TRACE_LEVEL_WARNING, TRACE_FLAG_ISOCH, "Failed to allocate IsochResourceData!\n"); } } else { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return(ntStatus); } // kmdf1394_IsochAllocateResources NTSTATUS kmdf1394_IsochAttachBuffers ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN PISOCH_ATTACH_BUFFERS IsochAttachBuffers) { NTSTATUS ntStatus = STATUS_SUCCESS; Enter(); UNREFERENCED_PARAMETER (Device); UNREFERENCED_PARAMETER (Request); UNREFERENCED_PARAMETER (IsochAttachBuffers); // // TODO: Put the appropriate code to attach buffers back in // ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochAttachBuffers NTSTATUS kmdf1394_IsochDetachBuffers( IN WDFDEVICE Device, IN WDFREQUEST Request, IN PISOCH_DETACH_BUFFERS IsochDetachBuffers) { NTSTATUS ntStatus = STATUS_SUCCESS; Enter(); UNREFERENCED_PARAMETER (Device); UNREFERENCED_PARAMETER (Request); UNREFERENCED_PARAMETER (IsochDetachBuffers); // // TODO: Put the appropriate code to detach buffers back in // ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochDetachBuffers NTSTATUS kmdf1394_IsochFreeBandwidth ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN HANDLE hBandwidth) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext (Device); PIRB pIrb = NULL; Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "hBandwidth = 0x%p\n", hBandwidth); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_FREE_BANDWIDTH; pIrb->Flags = 0; pIrb->u.IsochFreeBandwidth.hBandwidth = hBandwidth; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochFreeBandwidth NTSTATUS kmdf1394_IsochFreeChannel ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN ULONG nChannel) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext (Device); PIRB pIrb = NULL; Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "nChannel = 0x%X\n", nChannel); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL; pIrb->Flags = 0; pIrb->u.IsochFreeChannel.nChannel = nChannel; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochFreeChannel NTSTATUS kmdf1394_IsochFreeResources ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN HANDLE hResource) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext (Device); PIRB pIrb = NULL; PISOCH_RESOURCE_DATA IsochResourceData = NULL; PLIST_ENTRY listHead, thisEntry; Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "hResource = 0x%p\n", hResource); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } // // remove this one from our list... // WdfSpinLockAcquire (deviceExtension->IsochResourceSpinLock); listHead = &deviceExtension->IsochResourceData; for (thisEntry = listHead->Flink; thisEntry != listHead; IsochResourceData = NULL, thisEntry = thisEntry->Flink) { IsochResourceData = CONTAINING_RECORD ( thisEntry, ISOCH_RESOURCE_DATA, IsochResourceList); if (IsochResourceData->hResource == hResource) { DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "Removing hResource = 0x%p\n", hResource); RemoveEntryList(&IsochResourceData->IsochResourceList); ExFreePoolWithTag(IsochResourceData, POOLTAG_KMDF_VDEV); break; } } WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock); RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES; pIrb->Flags = 0; pIrb->u.IsochFreeResources.hResource = hResource; ntStatus = kmdf1394_SubmitIrpSynch (deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochFreeResources NTSTATUS kmdf1394_IsochListen ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN PISOCH_LISTEN IsochListen) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); PIRB pIrb = NULL; Enter(); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_LISTEN; pIrb->Flags = 0; pIrb->u.IsochListen.hResource = IsochListen->hResource; pIrb->u.IsochListen.fulFlags = IsochListen->fulFlags; pIrb->u.IsochListen.StartTime = IsochListen->StartTime; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochListen NTSTATUS kmdf1394_IsochQueryCurrentCycleTime ( IN WDFDEVICE Device, IN WDFREQUEST Request, OUT PCYCLE_TIME pCurrentCycleTime) { NTSTATUS ntStatus = STATUS_SUCCESS; PIRB pIrb = NULL; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); Enter(); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_QUERY_CYCLE_TIME; pIrb->Flags = 0; ntStatus = kmdf1394_SubmitIrpSynch( deviceExtension->StackIoTarget, Request, pIrb); if (NT_SUCCESS (ntStatus)) { *pCurrentCycleTime = pIrb->u.IsochQueryCurrentCycleTime.CycleTime; DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "CurrentCycleTime.CL_CycleOffset = 0x%X\n", pCurrentCycleTime->CL_CycleOffset); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "CurrentCycleTime.CL_CycleCount = 0x%X\n", pCurrentCycleTime->CL_CycleCount); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "CurrentCycleTime.CL_SecondCount = 0x%X\n", pCurrentCycleTime->CL_SecondCount); } else { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return(ntStatus); } // kmdf1394_IsochQueryCurrentCycleTime NTSTATUS kmdf1394_IsochQueryResources ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN OUT PISOCH_QUERY_RESOURCES IsochQueryResources) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext (Device); PIRB pIrb = NULL; Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "fulSpeed = 0x%X\n", IsochQueryResources->fulSpeed); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_QUERY_RESOURCES; pIrb->Flags = 0; pIrb->u.IsochQueryResources.fulSpeed = IsochQueryResources->fulSpeed; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (NT_SUCCESS(ntStatus)) { IsochQueryResources->BytesPerFrameAvailable = \ pIrb->u.IsochQueryResources.BytesPerFrameAvailable; IsochQueryResources->ChannelsAvailable = \ pIrb->u.IsochQueryResources.ChannelsAvailable; DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "BytesPerFrameAvailable = 0x%X\n", IsochQueryResources->BytesPerFrameAvailable); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "ChannelsAvailable.LowPart = 0x%X\n", IsochQueryResources->ChannelsAvailable.LowPart); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "ChannelsAvailable.HighPart = 0x%X\n", IsochQueryResources->ChannelsAvailable.HighPart); } else { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return(ntStatus); } //kmdf1394_IsochQueryResources NTSTATUS kmdf1394_IsochSetChannelBandwidth ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN PISOCH_SET_CHANNEL_BANDWIDTH IsochSetChannelBandwidth) { NTSTATUS ntStatus = STATUS_SUCCESS; PIRB pIrb = NULL; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "hBandwidth = 0x%p\n", IsochSetChannelBandwidth->hBandwidth); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "nMaxBytesPerFrame = 0x%X\n", IsochSetChannelBandwidth->nMaxBytesPerFrame); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_SET_CHANNEL_BANDWIDTH; pIrb->Flags = 0; pIrb->u.IsochSetChannelBandwidth.hBandwidth = \ IsochSetChannelBandwidth->hBandwidth; pIrb->u.IsochSetChannelBandwidth.nMaxBytesPerFrame = \ IsochSetChannelBandwidth->nMaxBytesPerFrame; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS(ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return(ntStatus); } // kmdf1394_IsochSetChannelBandwidth NTSTATUS kmdf1394_IsochModifyStreamProperties ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN PISOCH_MODIFY_STREAM_PROPERTIES IsochModifyStreamProperties) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); PIRB pIrb = NULL; Enter(); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_MODIFY_STREAM_PROPERTIES; pIrb->Flags = 0; pIrb->u.IsochModifyStreamProperties.hResource = \ IsochModifyStreamProperties->hResource; pIrb->u.IsochModifyStreamProperties.ChannelMask = \ IsochModifyStreamProperties->ChannelMask; pIrb->u.IsochModifyStreamProperties.fulSpeed = \ IsochModifyStreamProperties->fulSpeed; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } NTSTATUS kmdf1394_IsochStop ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN PISOCH_STOP IsochStop) { NTSTATUS ntStatus = STATUS_SUCCESS; PIRB pIrb = NULL; PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); Enter(); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "hResource = 0x%p\n", IsochStop->hResource); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "fulFlags = 0x%X\n", IsochStop->fulFlags); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_STOP; pIrb->Flags = 0; pIrb->u.IsochStop.hResource = IsochStop->hResource; pIrb->u.IsochStop.fulFlags = IsochStop->fulFlags; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag(pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } //kmdf1394_IsochStop NTSTATUS kmdf1394_IsochTalk ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN PISOCH_TALK IsochTalk) { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = GetDeviceContext (Device); PIRB pIrb = NULL; Enter(); pIrb = ExAllocatePoolWithTag (NonPagedPool, sizeof(IRB), POOLTAG_KMDF_VDEV); if (!pIrb) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "Failed to allocate pIrb!\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory (pIrb, sizeof (IRB)); pIrb->FunctionNumber = REQUEST_ISOCH_TALK; pIrb->Flags = 0; pIrb->u.IsochTalk.hResource = IsochTalk->hResource; pIrb->u.IsochTalk.fulFlags = IsochTalk->fulFlags; pIrb->u.IsochTalk.StartTime = IsochTalk->StartTime; ntStatus = kmdf1394_SubmitIrpSynch ( deviceExtension->StackIoTarget, Request, pIrb); if (!NT_SUCCESS(ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_ISOCH, "SubmitIrpSync failed = %!STATUS!\n", ntStatus); } ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV); ExitS(ntStatus); return ntStatus; } // kmdf1394_IsochTalk void kmdf1394_IsochCallback ( IN PDEVICE_EXTENSION DeviceExtension, IN PISOCH_DETACH_DATA IsochDetachData) { Enter(); if (!IsochDetachData) { goto Exit_IsochCallback; } // // make sure somebody else isn't already handling cleaning up for this request // WdfSpinLockAcquire (DeviceExtension->IsochSpinLock); if (kmdf1394_IsOnList ( &IsochDetachData->IsochDetachList, &DeviceExtension->IsochDetachData)) { RemoveEntryList (&IsochDetachData->IsochDetachList); WdfSpinLockRelease (DeviceExtension->IsochSpinLock); KeCancelTimer (&IsochDetachData->Timer); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "IsochCallback: IsochDetachData = 0x%p\n", IsochDetachData); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "IsochCallback: IsochDetachData->Request = 0x%p\n", IsochDetachData->Request); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "IsochCallback: IsochDetachData->newIrp = 0x%p\n", IsochDetachData->newIrp); // // need to save the status of the attach // we'll clean up in the same spot for success's and timeout's // TODO: IsochDetachData->AttachStatus = IsochDetachData->Irp->IoStatus.Status; // kmdf1394_IsochCleanup (IsochDetachData); } else { DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "IsochCallback: Entry 0x%p not on List 0x%p\n", IsochDetachData, &(DeviceExtension->IsochDetachData)); WdfSpinLockRelease (DeviceExtension->IsochSpinLock); } Exit_IsochCallback: Exit(); } // kmdf1394_IsochCallback void kmdf1394_IsochTimeout ( IN PKDPC Dpc, IN PISOCH_DETACH_DATA IsochDetachData, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PDEVICE_EXTENSION DeviceExtension; UNREFERENCED_PARAMETER (Dpc); UNREFERENCED_PARAMETER (SystemArgument1); UNREFERENCED_PARAMETER (SystemArgument2); Enter(); DoTraceLevelMessage(TRACE_LEVEL_WARNING, TRACE_FLAG_ISOCH, "Isoch Timeout!\n"); // // ISSUE: the device extension we are referencing comes from the IsochDetachData // but it is possible this memory has been freed before we enter this function. // The only way to check is to validate against our DeviceExtension->IsochDetachList // but if the IsochDetachData has been freed then that won't be accessible // DeviceExtension = IsochDetachData->DeviceExtension; if (DeviceExtension) { // // make sure nobody else has already handled this request yet // WdfSpinLockAcquire (DeviceExtension->IsochSpinLock); if (kmdf1394_IsOnList ( &IsochDetachData->IsochDetachList, &DeviceExtension->IsochDetachData)) { RemoveEntryList (&IsochDetachData->IsochDetachList); WdfSpinLockRelease (DeviceExtension->IsochSpinLock); if(KeCancelTimer (&IsochDetachData->Timer)) { DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "IsochTimeout: IsochDetachData = 0x%p\n", IsochDetachData); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "IsochTimeout: IsochDetachData->Irp = 0x%p\n", IsochDetachData->Request); DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_ISOCH, "IsochTimeout: IsochDetachData->newIrp = 0x%p\n", IsochDetachData->newIrp); // // need to save the status of the attach // we'll clean up in the same spot for success's and timeout's // IsochDetachData->AttachStatus = STATUS_TIMEOUT; kmdf1394_IsochCleanup(IsochDetachData); } } else { WdfSpinLockRelease(DeviceExtension->IsochSpinLock); } } Exit(); } // kmdf1394_IsochTimeout // // TODO: These last functions are here as place holders for when the // attach / detach buffers routines are implemented. // void kmdf1394_IsochCleanup ( IN PISOCH_DETACH_DATA IsochDetachData) { UNREFERENCED_PARAMETER(IsochDetachData); Enter(); Exit(); } //kmdf1394_IsochCleanup NTSTATUS kmdf1394_IsochDetachCompletionRoutine ( IN PDEVICE_OBJECT Device, IN PIRP Irp, IN PISOCH_DETACH_DATA IsochDetachData) { UNREFERENCED_PARAMETER(Device); UNREFERENCED_PARAMETER(Irp); UNREFERENCED_PARAMETER(IsochDetachData); Enter(); ExitS(STATUS_MORE_PROCESSING_REQUIRED); return STATUS_MORE_PROCESSING_REQUIRED; } // kmdf1394_IsochDetachCompletionRoutine
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials