⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datapkt.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
//===========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1996 - 2000  Microsoft Corporation.  All Rights Reserved.
//
//===========================================================================
/*++

Module Name:

    DataPkt.c

Abstract:

    Stream class based WDM driver for 1934 Desktop Camera.
    This file contains code to handle the stream class packets.

Author:

    Yee J. Wu 24-Jun-98

Environment:

    Kernel mode only

Revision History:


--*/


#include "strmini.h"
#include "ksmedia.h"
#include "1394.h"
#include "wdm.h"       // for DbgBreakPoint() defined in dbg.h
#include "dbg.h"
#include "dcamdef.h"
#include "dcampkt.h"
#include "sonydcam.h"

extern CAMERA_ISOCH_INFO IsochInfoTable[];



#ifdef ALLOC_PRAGMA
    #pragma alloc_text(PAGE, DCamSurpriseRemoval)
    #pragma alloc_text(PAGE, DCamReceiveDataPacket)
#endif



NTSTATUS
DCamCancelOnePacketCR(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp,
    PISOCH_DESCRIPTOR IsochDescriptor
    )
/*++

Routine Description:

    Completion routine for detach an isoch descriptor associate with a pending read SRB.
    Will cancel the pending SRB here if detaching descriptor has suceeded.

Arguments:

    DriverObject - Pointer to driver object created by system.
    pIrp - Allocated locally, need to be free here.
    IsochDescriptor - Isoch descriptor containing the SRB to be cancelled.

Return Value:

    None.

--*/
{
    PHW_STREAM_REQUEST_BLOCK pSrbToCancel;
    PISOCH_DESCRIPTOR_RESERVED IsochDescriptorReserved;
    PDCAM_EXTENSION pDevExt;


    if(STATUS_SUCCESS != pIrp->IoStatus.Status) {
        ERROR_LOG(("DCamCancelOnePacketCR: Detach buffer failed with pIrp->IoStatus.Status= %x (! STATUS_SUCCESS) \n", pIrp->IoStatus.Status));
        ASSERT(STATUS_SUCCESS == pIrp->IoStatus.Status);

    } else {
        IsochDescriptorReserved = (PISOCH_DESCRIPTOR_RESERVED) &IsochDescriptor->DeviceReserved[0];
        pSrbToCancel = IsochDescriptorReserved->Srb;
        pDevExt = (PDCAM_EXTENSION) pSrbToCancel->HwDeviceExtension;

        IsochDescriptorReserved->Flags |= STATE_SRB_IS_COMPLETE;

        pSrbToCancel->CommandData.DataBufferArray->DataUsed = 0;
        pSrbToCancel->ActualBytesTransferred = 0;
        pSrbToCancel->Status = pDevExt->bDevRemoved ? STATUS_DEVICE_REMOVED : STATUS_CANCELLED;

        DbgMsg2(("DCamCancelOnePacketCR: SRB %x, Status %x, IsochDesc %x, Reserved %x cancelled\n",
            pSrbToCancel, pSrbToCancel->Status, IsochDescriptor, IsochDescriptorReserved));

        StreamClassStreamNotification(
            StreamRequestComplete,
            pSrbToCancel->StreamObject,
            pSrbToCancel);

        ExFreePool(IsochDescriptor);
    }

    // Allocated locally so free it.
    IoFreeIrp(pIrp);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

VOID
DCamDetachAndCancelOnePacket(
    IN PHW_STREAM_REQUEST_BLOCK pSrbToCancel,
    PISOCH_DESCRIPTOR           IsochDescriptorToDetach,
    HANDLE                      hResource,
    PDEVICE_OBJECT              pBusDeviceObject
    )
/*++

Routine Description:

    Detach an isoch descriptor and then cancel pending SRB in the completion routine.

Arguments:

    pSrbToCancel - Pointer to SRB to cancel
    IsochDescriptorToDetach - Iosch descriptor to detach
    hResource - isoch resource allocated
    hBusDeviceObject - bus device object

Return Value:

    None.

--*/
{
    PDCAM_EXTENSION pDevExt;
    PIO_STACK_LOCATION NextIrpStack;
    NTSTATUS Status;
    PIRB     pIrb;
    PIRP     pIrp;


    DbgMsg2(("\'DCamDetachAndCancelOnePacket: pSrbTocancel %x, detaching IsochDescriptorToDetach %x\n", pSrbToCancel, IsochDescriptorToDetach));

    pDevExt = (PDCAM_EXTENSION) pSrbToCancel->HwDeviceExtension;

    // Reuse cached IRP
    pIrp = (PIRP) IsochDescriptorToDetach->DeviceReserved[5];

    pIrb = pSrbToCancel->SRBExtension;

    pIrb->Flags           = 0;
    pIrb->FunctionNumber  = REQUEST_ISOCH_DETACH_BUFFERS;
    pIrb->u.IsochDetachBuffers.hResource            = hResource;
    pIrb->u.IsochDetachBuffers.nNumberOfDescriptors = 1;
    pIrb->u.IsochDetachBuffers.pIsochDescriptor     = IsochDescriptorToDetach;

    NextIrpStack = IoGetNextIrpStackLocation(pIrp);
    NextIrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    NextIrpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_1394_CLASS;
    NextIrpStack->Parameters.Others.Argument1 = pIrb;

    IoSetCompletionRoutine(
        pIrp,
        DCamCancelOnePacketCR,
        IsochDescriptorToDetach,
        TRUE,
        TRUE,
        TRUE
        );

    Status =
        IoCallDriver(
            pBusDeviceObject,
            pIrp
            );

    ASSERT(Status == STATUS_SUCCESS || Status == STATUS_PENDING);
}

VOID
AbortWorkItem(
    IN DEVICE_OBJECT *DeviceObject,
    IN DCAM_EXTENSION *DevExt
    )
/*++

Routine Description:

    This work item routine aborts a stream at passive level.

Arguments:

    DeviceObject - Device object
    DevExt - Device extension 

Return Value:
    
    Success / failure

--*/
{
    ERROR_LOG( ( "[%s] abort starting...\n", __FUNCTION__ ) );

    DCamCancelAllPackets(
        DevExt,
        &DevExt->PendingReadCount );  
}


VOID
DCamCancelOnePacket(
    IN PHW_STREAM_REQUEST_BLOCK pSrbToCancel
    )
/*++

Routine Description:

    This routine is called to cancel a pending streaming SRB.  This is likely to
    happen when transitioning from PAUSE to STOP state.
    Note: This routine is called at DISPATCH_LEVEL !! so we queue a work item
    to cancel pending requests at the passive level.

Arguments:

    pSrbToCancel - Pointer to SRB to cancel

Return Value:

    None.

--*/
{
    PDCAM_EXTENSION pDevExt;
    PSTREAMEX       pStrmEx;
    PIO_WORKITEM pIOWorkItem;


    pDevExt = (PDCAM_EXTENSION) pSrbToCancel->HwDeviceExtension;
    ASSERT(pDevExt);
    pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;
    ASSERT(pStrmEx);

    // Nothing to cancel
    if(pStrmEx == NULL) {
        return;
    }


    //
    // Can cancel stream SRB as a result of aborting a stream.
    //
    if ( (pSrbToCancel->Flags & SRB_HW_FLAGS_STREAM_REQUEST) != SRB_HW_FLAGS_STREAM_REQUEST) {
        ERROR_LOG(("DCamCancelOnePacket: Cannot cancel Device SRB %x\n", pSrbToCancel));
        ASSERT( (pSrbToCancel->Flags & SRB_HW_FLAGS_STREAM_REQUEST) == SRB_HW_FLAGS_STREAM_REQUEST );
        return;
    }

    //
    // Abort only once so we must obtain the token first.
    //
    if( InterlockedExchange( &pStrmEx->CancelToken, 1 ) == 1 ) {
        // Already in cancelling state!
        ERROR_LOG( ( "Already cancelling...\n" ) );
        return;
    }

    //
    // Start a work item to cancel all pending request
    //
    pIOWorkItem = IoAllocateWorkItem( pDevExt ->PhysicalDeviceObject );

    if( !pIOWorkItem ) {
        // Could not do it, release the token.
        InterlockedExchange( &pStrmEx->CancelToken, 0 );
        return;
    }
    else {
        IoQueueWorkItem( pIOWorkItem, AbortWorkItem, DelayedWorkQueue, pDevExt );
    }
}

VOID
DCamCancelAllPackets(
    PDCAM_EXTENSION pDevExt,
    LONG *plPendingReadCount
    )
/*++

Routine Description:

    This routine is use to cancel all pending IRP.
    Can be called at DISPATCH_LEVEL.

Arguments:

    pSrbToCancel - Pointer to SRB to cancel
    pDevExt - Device's contect
    plPendingReadCount - Number of pending read

Return Value:

    None.

--*/
{
    HW_STREAM_REQUEST_BLOCK *pSrbToCancel;
    ISOCH_DESCRIPTOR *IsochDescriptorToDetach;
    LIST_ENTRY *pEntry;
    KIRQL oldIrql;
    STREAMEX *pStrmEx;

    PAGED_CODE();

    pStrmEx = pDevExt->pStrmEx;

    // Nothing to cancel
    if(pStrmEx == NULL) {
        return;
    }


    //
    // Sychronize with READ request so all request can be cancelled
    //
    KeWaitForSingleObject( &pStrmEx->hMutex, Executive, KernelMode, FALSE, 0 );

    //
    // Loop through the linked list from the beginning to end,
    // trying to find the SRB to cancel
    //
    KeAcquireSpinLock(&pDevExt->IsochDescriptorLock, &oldIrql);

    pEntry = pDevExt->IsochDescriptorList.Flink;

    while (pEntry != &pDevExt->IsochDescriptorList) {

        pSrbToCancel = ((PISOCH_DESCRIPTOR_RESERVED)pEntry)->Srb;
        IsochDescriptorToDetach = \
            (PISOCH_DESCRIPTOR) ( ((PUCHAR) pEntry) -
            FIELDOFFSET(ISOCH_DESCRIPTOR, DeviceReserved[0]));


        if(((PISOCH_DESCRIPTOR_RESERVED) pEntry)->Flags & (STATE_SRB_IS_COMPLETE | STATE_DETACHING_BUFFERS)) {
            // Skip this one since it is already in detaching phase or completed.
            ERROR_LOG(("DCamCancelAllPacket: pSrbToCancel %x, Descriptor %x,  Reserved %x already detaching or completed\n",
                pSrbToCancel, IsochDescriptorToDetach, pEntry));
            ASSERT( FALSE && "Not ready to be cancelled!!!" );

            pEntry = pEntry->Flink;  // next

        } else {
            ((PISOCH_DESCRIPTOR_RESERVED) pEntry)->Flags |= STATE_DETACHING_BUFFERS;
#if DBG
            // Should not have been detached.
            ASSERT((IsochDescriptorToDetach->DeviceReserved[7] == 0x87654321));
            IsochDescriptorToDetach->DeviceReserved[7]++;
#endif
            RemoveEntryList(pEntry);
            InterlockedDecrement(plPendingReadCount);
            DbgMsg2(("DCamCancelAllPackets: pSrbToCancel %x, Descriptor %x, Reserved %x\n",
                pSrbToCancel, IsochDescriptorToDetach, pEntry));

            pEntry = pEntry->Flink;  // pEntry is deleted in DCamDetachAndCancelOnePacket(); so get next here.

            DCamDetachAndCancelOnePacket(
                pSrbToCancel,
                IsochDescriptorToDetach,
                pDevExt->hResource,
                pDevExt->BusDeviceObject);
        }
    }

    KeReleaseSpinLock (&pDevExt->IsochDescriptorLock, oldIrql);

    KeReleaseMutex(&pStrmEx->hMutex, FALSE);
}



VOID
DCamSurpriseRemoval(
    IN PHW_STREAM_REQUEST_BLOCK pSrb
    )

/*++

Routine Description:

    Response to SRB_SURPRISE_REMOVAL.

Arguments:

    pSrb - Pointer to the stream request block


Return Value:

    None.

--*/

{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -