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?

© 2011-2024 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS