亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? read_write.c

?? PCI驅動代碼實例
?? C
?? 第 1 頁 / 共 2 頁
字號:
///////////////////////////////////////////////////////////////////////////////
//
//    (C) Copyright 1995 - 1997 OSR Open Systems Resources, Inc.
//    All Rights Reserved
//
//    This sofware is supplied for instructional purposes only.
//
//    OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
//    for this software.  THIS SOFTWARE IS PROVIDED  "AS IS" WITHOUT WARRANTY
//    OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
//    THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
//    PURPOSE.  THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
//    WITH YOU.  OSR's entire liability and your exclusive remedy shall not
//    exceed the price paid for this material.  In no event shall OSR or its
//    suppliers be liable for any damages whatsoever (including, without
//    limitation, damages for loss of business profit, business interruption,
//    loss of business information, or any other pecuniary loss) arising out
//    of the use or inability to use this software, even if OSR has been
//    advised of the possibility of such damages.  Because some states/
//    jurisdictions do not allow the exclusion or limitation of liability for
//    consequential or incidental damages, the above limitation may not apply
//    to you.
//
//    OSR Open Systems Resources, Inc.
//    105 Route 101A Suite 19
//    Amherst, NH 03031  (603) 595-6500 FAX: (603) 595-6503
//    email bugs to: bugs@osr.com
//
//                       
//    MODULE:
//
//        READ_WRITE.C
//
//    ABSTRACT:
//
//      This file contains read and write routines used by the
//      PCI Busmaster DMA device driver for the AMCC 5933 chip.
//
//    AUTHOR(S):
//
//        OSR Open Systems Resources, Inc.
// 
//    REVISION:   
//
//
///////////////////////////////////////////////////////////////////////////////

#include "osr-pci.h"

//
// forward declarations
//
BOOLEAN OsrStartReadOnDevice(IN PVOID SynchronizeContext);
BOOLEAN OsrStartWriteOnDevice(IN PVOID SynchronizeContext);

IO_ALLOCATION_ACTION  OsrAdapterControlRead(IN PDEVICE_OBJECT DeviceObject,
                                IN PIRP NotUsed, IN PVOID MapRegisterBase,
                                IN PVOID Context);
IO_ALLOCATION_ACTION  OsrAdapterControlWrite(IN PDEVICE_OBJECT DeviceObject,
                                IN PIRP NotUsed, IN PVOID MapRegisterBase,
                                IN PVOID Context);

///////////////////////////////////////////////////////////////////////////////
//
//  OsrWrite
//
//    This is the write dispatch entry point for the driver, called when the
//    I/O Manager has an IRP_MJ_WRITE request for the driver to process.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//    Irp - Address of the IRP representing the IRP_MJ_WRITE call.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//    STATUS_PENDING, since we are putting the IRP on our internal queue.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//    Since we set the DO_DIRECT_IO bit in the Device Object, all buffers
//    passed to us will have been probed and locked and described by an MDL.
//    The I/O manager will provides us the MDL address in Irp->MdlAddress.
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS OsrWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    POSR_DEVICE_EXT devExt = DeviceObject->DeviceExtension;
    KIRQL oldIrql;
    NTSTATUS code = STATUS_SUCCESS;
    BOOLEAN listWasEmpty;
    PIO_STACK_LOCATION ioStack;
    ULONG temp;
            
#if DBG
    DbgPrint("OsrWrite: entered\n");
#endif

    //
    // Validate the IRP we've received
    //
    ioStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // If the length of the requested transfer is either zero or too long,
    // we immediately compelte the IRP with an error status.
    //
    if (ioStack->Parameters.Write.Length == 0 ||
        ioStack->Parameters.Write.Length > OSR_PCI_MAX_TXFER)  {
            
        Irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return(STATUS_INVALID_USER_BUFFER);

    }
    
    // Take out the Write list lock, since we'll insert this IRP
    // onto the write queue
    //
    KeAcquireSpinLock(&devExt->WriteQueueLock, &oldIrql);

    //
    // Since we'll probably be queuing this request, set a routine 
    // to be called by the I/O Manager in case he needs to cancel
    // this IRP.
    //
    IoSetCancelRoutine(Irp, OsrCancelFromWriteQueue);

    //
    // Before we queue this request, has it been cancelled??
    //
    // What we're doing here is closing that tiny window between the time
    // the Dispatch routine is called and when we acquired the queue spin
    // lock.  Once the queue spin lock is held, and the IRP is queued, the
    // cancellation routine will deal with any requests to cancel the IRP.
    //
    if (Irp->Cancel)  {
        
        //
        // Can't complete a request with a valid cancel routine!
        //
        // TECHNICAL ERRATA: Page 466, Example 17.5 has the following
        // line, which is obviously in error:
        //
        // IoSetCancelRoutine(Irp, OsrCancelFromWriteQueue);
        // 
        // This line SHOULD READ:
        //
        IoSetCancelRoutine(Irp, NULL);
         
        KeReleaseSpinLock(&devExt->WriteQueueLock, oldIrql);

        Irp->IoStatus.Status = STATUS_CANCELLED;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return(STATUS_CANCELLED);
    }

    //
    // If we get this far, we will return with this request pending
    //
    IoMarkIrpPending(Irp);

    //
    // Do we need to start this request on the device?
    //
    // If there is no IRP currently in progress, we'll start the
    // one we've just received.
    //
    if (devExt->CurrentWriteIrp == NULL)  {
                
        //
        // No write presently active.  Start this request...
        // (Note that we're still holding the queue lock here)
        //
        OsrStartWriteIrp(DeviceObject,Irp);

    } else {

        //
        // Put this request on the end of the write queue
        //
        InsertTailList(&devExt->WriteQueue, &Irp->Tail.Overlay.ListEntry);

    }

    //
    // We're done playing with the write queue now
    //
    KeReleaseSpinLock(&devExt->WriteQueueLock, oldIrql);
    
#if DBG
    DbgPrint("OsrWrite: exiting\n");
#endif

    return(STATUS_PENDING);
}

///////////////////////////////////////////////////////////////////////////////
//
//  OsrRead
//
//    This is the read dispatch entry point for the driver, called when the
//    I/O Manager has an IRP_MJ_READ request for the driver to process.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//    Irp - Address of the IRP representing the IRP_MJ_READ call.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//    STATUS_PENDING, since we are putting the IRP on our internal queue.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//    Since we set the DO_DIRECT_IO bit in the Device Object, all buffers
//    passed to us will have been probed and locked and described by an MDL.
//    The I/O manager will provides us the MDL address in Irp->MdlAddress.
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS OsrRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    POSR_DEVICE_EXT devExt = DeviceObject->DeviceExtension;
    KIRQL oldIrql;
    NTSTATUS code = STATUS_SUCCESS;
    BOOLEAN listWasEmpty;
    PIO_STACK_LOCATION ioStack;
    ULONG temp;
            
#if DBG
    DbgPrint("OsrRead: entered\n");
#endif

    //
    // Validate the IRP we've received
    //
    ioStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // If the length of the requested transfer is either zero or too long,
    // we immediately compelte the IRP with an error status.
    //
    if (ioStack->Parameters.Read.Length == 0 ||
        ioStack->Parameters.Read.Length > OSR_PCI_MAX_TXFER)  {
            
        Irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return(STATUS_INVALID_USER_BUFFER);

    }

    //
    // Get the Read Queue lock, so we can insert our IRP
    //
    KeAcquireSpinLock(&devExt->ReadQueueLock, &oldIrql);

    //
    // Since we'll probably be queuing this request, set a routine 
    // to be called by the I/O Manager in case he needs to cancel
    // this IRP.
    //
    IoSetCancelRoutine(Irp, OsrCancelFromReadQueue);

    //
    // Do we need to cancel this IRP, instead of queue it?
    //
    if (Irp->Cancel)  {
        
        //
        // Can't complete a request with a valid cancel routine!
        //
        IoSetCancelRoutine(Irp, NULL);
    
        KeReleaseSpinLock(&devExt->ReadQueueLock, oldIrql);

        Irp->IoStatus.Status = STATUS_CANCELLED;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return(STATUS_CANCELLED);
    }

    //
    // We'll be returning with this request pending
    //
    IoMarkIrpPending(Irp);

    //
    // Do we need to start this request on the device?
    //
    // If there is no IRP currently in progress, we'll start the
    // one we've just received.
    //
    if (devExt->CurrentReadIrp == NULL)  {
                
        //
        // No read operation presently active.  Start this request...
        // (Note that we're still holding the queue lock here)
        //
        OsrStartReadIrp(DeviceObject,Irp);

    } else {

        //
        // Put this request on the end of the write queue
        //
        InsertTailList(&devExt->ReadQueue, &Irp->Tail.Overlay.ListEntry);

    }

    //
    // We're done
    //
    KeReleaseSpinLock(&devExt->ReadQueueLock, oldIrql);
    
#if DBG
    DbgPrint("OsrRead: exiting\n");
#endif

      return(STATUS_PENDING);
}

///////////////////////////////////////////////////////////////////////////////
//
//  OsrStartWriteIrp
//
//    This is routine is called by the OsrWrite and DpcForIsr routine to
//    start a new Write operation.  The request started is the IRP located
//    at the head of the write queue.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//      Irp - Address of the IRP representing the IRP_MJ_WRITE call.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//      This routine is called at IRQL_DISPATCH_LEVEL.
//
//  NOTES:
//      *** Called (and returns) with the WriteQueueLock held.
//
///////////////////////////////////////////////////////////////////////////////
VOID
OsrStartWriteIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    POSR_DEVICE_EXT devExt = DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION ioStack;
    ULONG mapRegsNeeded;
    
    ioStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // In progress IRPs cannot be cancelled
    //
    IoSetCancelRoutine(Irp, NULL);

#if DBG
    DbgPrint("OsrWrite: Transfer length %d.\n",
                                ioStack->Parameters.Write.Length);
#endif

    //
    // There is no in-progress request.  Start this request on the
    // device.
    //
    devExt->CurrentWriteIrp = Irp;

    devExt->WriteTotalLength = ioStack->Parameters.Write.Length;

    devExt->WriteSoFar = 0;

    devExt->WriteStartingOffset = 0;

    //
    // Start the watchdog timer on this IRP
    //
    (ULONG)Irp->Tail.Overlay.DriverContext[0] = OSR_WATCHDOG_INTERVAL;

    //
    // Since we're about to initiate a DMA operation, ensure the user's data
    // buffer is flushed from the cache back into memory, on processors that
    // are non-DMA cache coherent.
    //
    KeFlushIoBuffers(Irp->MdlAddress, FALSE, TRUE);

    //
    // Determine the number of map registers we'll need for this transfer
    //
    mapRegsNeeded = 
        ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
                                        ioStack->Parameters.Write.Length);
        
#if DBG
    DbgPrint("StartWrite: %d. map regs needed\n", mapRegsNeeded);
#endif

    //
    // If the number of map registers required for this transfer exceeds the
    // maximum we're allowed to use (as reported to us from HalGetAdapter() ),
    // we'll need to limit ourselves to the maximum we're allowed.
    //
    devExt->MapRegsThisWrite = ((mapRegsNeeded > devExt->WriteMapRegsGot) ? 
                              devExt->WriteMapRegsGot : mapRegsNeeded);

#if DBG
    DbgPrint("StartWrite: %d. map regs this xfer\n", devExt->MapRegsThisWrite);
#endif

    //
    // Ready to GO! Allocate the appropriate Adapter Object and map registers.
    //
    IoAllocateAdapterChannel(devExt->WriteAdapter,
                             DeviceObject, 
                             devExt->MapRegsThisWrite,
                             OsrAdapterControlWrite,
                             Irp);
}


///////////////////////////////////////////////////////////////////////////////
//
//  OsrStartReadIrp
//
//    This is routine is called by the OsrRead and Dpc routine in order to
//    begin a new Read operation.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//      Irp - Address of the IRP representing the IRP_MJ_READ call.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//      This routine is called at IRQL_DISPATCH_LEVEL.

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人黄色在线看| 精品区一区二区| 日韩欧美电影一二三| 国产精品欧美久久久久无广告 | 麻豆91精品视频| 91色porny在线视频| 久久久久综合网| 麻豆精品视频在线观看| 欧美日韩综合在线| 中文字幕综合网| 成人在线综合网| 久久久午夜精品| 久草这里只有精品视频| 3d动漫精品啪啪1区2区免费 | 欧美性生活一区| 1024精品合集| 99这里只有久久精品视频| 国产亚洲精品超碰| 国产综合色精品一区二区三区| 7777女厕盗摄久久久| 亚洲高清不卡在线观看| 色88888久久久久久影院按摩 | 久久久亚洲精品一区二区三区| 日韩电影在线免费| 欧美一区二区美女| 日韩精品一二三区| 91精品国产综合久久精品图片| 一区二区三区高清在线| 一本久久综合亚洲鲁鲁五月天 | 国产精品美女久久久久aⅴ国产馆| 国产一区二区三区高清播放| 欧美大片日本大片免费观看| 奇米影视一区二区三区小说| 欧美一级日韩免费不卡| 美女www一区二区| 久久亚洲一区二区三区明星换脸| 精品在线一区二区| 精品国产伦一区二区三区观看体验 | 国产福利电影一区二区三区| 久久久久久97三级| 成人激情免费电影网址| 亚洲激情自拍偷拍| 欧美亚洲一区二区三区四区| 日韩和欧美一区二区三区| 制服丝袜av成人在线看| 九九精品一区二区| 欧美激情中文字幕| 色先锋久久av资源部| 首页综合国产亚洲丝袜| 久久综合九色综合欧美就去吻| 国产精品中文字幕日韩精品| 国产精品高清亚洲| 欧美日韩精品电影| 国产一区在线观看视频| 国产精品欧美久久久久无广告 | 久久久久久毛片| 不卡一区二区在线| 天天综合天天综合色| 日韩一级片网址| 粉嫩一区二区三区在线看| 亚洲自拍另类综合| 久久众筹精品私拍模特| 91社区在线播放| 久久丁香综合五月国产三级网站 | 日韩福利视频导航| 亚洲国产精品成人综合| 一本久久精品一区二区| 久久国产精品99久久人人澡| 中文字幕人成不卡一区| 日韩精品在线一区二区| 日本韩国一区二区| 国产成人免费视| 偷拍日韩校园综合在线| 国产精品久久久久久一区二区三区| 色哟哟国产精品| 岛国精品一区二区| 奇米影视一区二区三区| 亚洲黄色av一区| 国产欧美精品区一区二区三区| 欧美视频一区二区在线观看| 国产jizzjizz一区二区| 免费成人av在线播放| 亚洲色图制服诱惑| 久久久欧美精品sm网站| 91精品国产aⅴ一区二区| 色综合久久久久综合99| 国产黄人亚洲片| 久久av中文字幕片| 日韩高清在线观看| 午夜一区二区三区视频| 自拍av一区二区三区| 欧美国产日韩精品免费观看| 欧美大片一区二区三区| 欧美年轻男男videosbes| 色婷婷精品久久二区二区蜜臀av | 成人精品视频网站| 国模冰冰炮一区二区| 青青草成人在线观看| 亚洲v精品v日韩v欧美v专区| 亚洲人一二三区| 国产精品久久久久久久久果冻传媒| 日韩一区二区精品葵司在线| 欧美日韩中文字幕一区二区| 在线亚洲一区二区| 91免费国产视频网站| 成人深夜福利app| 豆国产96在线|亚洲| 懂色av一区二区夜夜嗨| 国产精品亚洲а∨天堂免在线| 久久国产精品无码网站| 狠狠色综合日日| 激情综合色播激情啊| 久久91精品国产91久久小草| 九色|91porny| 国产盗摄一区二区| 成人一二三区视频| www.亚洲在线| 91久久精品一区二区三区| 91色视频在线| 欧美日韩一二三区| 制服丝袜av成人在线看| 欧美mv日韩mv| 久久久91精品国产一区二区三区| 国产欧美精品一区| 亚洲日本一区二区| 天天综合色天天综合色h| 久久国产夜色精品鲁鲁99| 国产a级毛片一区| 一本到一区二区三区| 91麻豆精品国产自产在线| 日韩欧美激情四射| 国产精品三级在线观看| 亚洲成人免费在线观看| 蜜臀99久久精品久久久久久软件| 国产精品一区三区| 色综合天天在线| 欧美人xxxx| 国产日韩欧美精品综合| 亚洲已满18点击进入久久| 日本伊人色综合网| 成人在线综合网| 欧美日韩一区二区欧美激情| 久久综合色天天久久综合图片| 最新高清无码专区| 男男gaygay亚洲| 成人国产精品视频| 欧美一级生活片| 亚洲精品一卡二卡| 美日韩一区二区三区| 成人动漫中文字幕| 日韩精品一区二区三区中文精品| 国产精品国产精品国产专区不片| 午夜视频在线观看一区二区 | 激情综合网激情| 91蝌蚪porny成人天涯| 日韩小视频在线观看专区| 国产精品美女一区二区三区| 婷婷中文字幕一区三区| 国产成人精品一区二区三区网站观看| 日本精品一级二级| 欧美极品xxx| 麻豆成人av在线| 欧美在线色视频| 国产精品私人自拍| 另类欧美日韩国产在线| 在线视频欧美区| 亚洲欧洲成人精品av97| 精品午夜久久福利影院| 欧美日韩成人在线一区| 中文字幕中文在线不卡住| 九色porny丨国产精品| 777午夜精品免费视频| 一区二区高清免费观看影视大全| 国精产品一区一区三区mba视频 | 一二三区精品福利视频| 国产精品一区二区在线看| 日韩一二三区不卡| 亚洲成人精品一区二区| 91丨九色丨黑人外教| 中文字幕av在线一区二区三区| 六月丁香婷婷久久| 欧美一区永久视频免费观看| 一区二区三区电影在线播| 91视频一区二区三区| 欧美韩国一区二区| 国产福利一区二区| 久久久久9999亚洲精品| 精品影视av免费| 2024国产精品视频| 久久99深爱久久99精品| 日韩一级免费一区| 久久精品国产一区二区三区免费看 | 美腿丝袜在线亚洲一区| 日韩一区二区三区av| 日韩在线a电影| 日韩视频一区二区在线观看| 日韩av成人高清| 精品日韩一区二区三区免费视频| 成人高清伦理免费影院在线观看| 久久综合久久综合久久综合|