亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
国产精品乱码一区二区三区软件| 成人午夜看片网址| 欧美亚洲国产bt| 一区二区在线观看视频在线观看| 97se亚洲国产综合自在线观| 亚洲欧洲综合另类在线| 在线亚洲欧美专区二区| 午夜在线成人av| 日韩限制级电影在线观看| 蜜桃视频在线一区| 久久久久久免费| 波多野结衣一区二区三区| 亚洲视频一二区| 欧美艳星brazzers| 免费成人av在线播放| 久久久高清一区二区三区| 成人福利视频网站| 一区二区三区四区亚洲| 欧美日韩国产高清一区二区| 免费成人在线观看视频| 久久久久久毛片| 91豆麻精品91久久久久久| 日韩专区欧美专区| 久久久五月婷婷| 日本韩国视频一区二区| 日本三级亚洲精品| 国产欧美日韩精品一区| 欧美视频精品在线| 国内偷窥港台综合视频在线播放| 国产欧美1区2区3区| 欧美三级韩国三级日本三斤 | 国产女人水真多18毛片18精品视频| 成人黄动漫网站免费app| 亚洲国产一区二区三区青草影视| 欧美va亚洲va| 色999日韩国产欧美一区二区| 久久99精品国产麻豆婷婷| 亚洲色图丝袜美腿| 日韩精品一区二区三区在线| 99久久精品国产一区二区三区| 天天av天天翘天天综合网色鬼国产| 久久婷婷成人综合色| 91电影在线观看| 国产精品18久久久久久久网站| 亚洲欧美日韩国产一区二区三区| 欧美一二三区精品| 91亚洲国产成人精品一区二三| 天堂精品中文字幕在线| 国产精品国产三级国产专播品爱网| 欧美精选在线播放| 成人精品免费视频| 蜜臀av亚洲一区中文字幕| 成人欧美一区二区三区视频网页 | 色呦呦网站一区| 国产乱码精品1区2区3区| 天使萌一区二区三区免费观看| 国产精品国产馆在线真实露脸 | 日韩福利电影在线| 专区另类欧美日韩| 国产人成一区二区三区影院| 欧美一级欧美三级在线观看| 99精品欧美一区二区三区小说| 免费一级欧美片在线观看| 亚洲一区二区欧美日韩| 国产精品久久久久久久浪潮网站| 欧美成人官网二区| 欧美乱熟臀69xxxxxx| 色先锋资源久久综合| 不卡欧美aaaaa| 国产成人综合自拍| 国产在线精品一区二区| 秋霞影院一区二区| 午夜电影一区二区| 亚洲成av人片在线| 亚洲成人自拍偷拍| 亚洲国产精品欧美一二99| 亚洲精品国产a久久久久久| 中文字幕一区二区视频| 国产精品欧美极品| 中文字幕在线不卡视频| 亚洲欧美一区二区三区久本道91 | 欧美少妇xxx| 欧美综合久久久| 日本韩国一区二区| 在线精品视频一区二区| 91福利小视频| 欧美亚洲禁片免费| 欧美丝袜自拍制服另类| 91久久精品日日躁夜夜躁欧美| 色狠狠一区二区| 色偷偷一区二区三区| 欧美综合亚洲图片综合区| 欧美日韩中文一区| 7777精品伊人久久久大香线蕉的 | 手机精品视频在线观看| 日韩**一区毛片| 久久精品国产网站| 国产尤物一区二区在线| 国产999精品久久久久久绿帽| 国产另类ts人妖一区二区| 国产黄人亚洲片| 色综合天天天天做夜夜夜夜做| 色综合久久久久久久| 欧美色图天堂网| 日韩三级.com| 欧美激情一区在线| 亚洲最快最全在线视频| 亚洲成人黄色影院| 狠狠狠色丁香婷婷综合久久五月| 国产一区二区精品久久| jlzzjlzz亚洲女人18| 欧美性猛交xxxx乱大交退制版 | 精品国产伦一区二区三区免费| 久久免费美女视频| 亚洲欧洲精品成人久久奇米网| 一区二区三区中文字幕在线观看| 偷拍与自拍一区| 国产电影精品久久禁18| 91九色最新地址| 久久日一线二线三线suv| 亚洲免费毛片网站| 九九热在线视频观看这里只有精品| 成人免费看片app下载| 欧美色精品在线视频| 久久久久久夜精品精品免费| 一区二区三区精密机械公司| 久久99精品一区二区三区三区| 成人高清视频在线| 欧美日韩国产首页| 中国色在线观看另类| 亚洲成av人在线观看| 国产成人一级电影| 欧美日韩精品一区视频| 国产欧美日韩视频在线观看| 日本欧美韩国一区三区| hitomi一区二区三区精品| 欧美一区二区三区在| 综合欧美亚洲日本| 国产一区二区h| 欧美日韩成人激情| 自拍偷拍欧美激情| 国产自产2019最新不卡| 9191精品国产综合久久久久久| 国产精品不卡一区| 国产乱一区二区| 日韩一级大片在线观看| 亚洲国产中文字幕| 91啦中文在线观看| 亚洲国产精品精华液2区45| 麻豆久久一区二区| 欧美日韩国产大片| 一区二区三区精品在线观看| 成人黄色av电影| 中文无字幕一区二区三区| 国产真实乱偷精品视频免| 欧美日韩高清在线| 亚洲综合偷拍欧美一区色| 99在线精品一区二区三区| www成人在线观看| 青青青爽久久午夜综合久久午夜| 欧美伊人久久久久久久久影院| 综合久久久久久| 成人国产免费视频| 国产精品你懂的在线| 国产91高潮流白浆在线麻豆| 久久久蜜臀国产一区二区| 国产精品自拍毛片| 久久综合九色综合97婷婷 | 激情欧美日韩一区二区| 欧美美女一区二区| 日韩电影在线免费| 欧美日韩国产bt| 日本系列欧美系列| 日韩一级高清毛片| 国产一区二区毛片| 亚洲国产精品黑人久久久| 成人性生交大片免费看视频在线| 国产亚洲一本大道中文在线| 国产乱码字幕精品高清av| 亚洲国产精品黑人久久久| 99re在线视频这里只有精品| 亚洲男同1069视频| 欧美私模裸体表演在线观看| 日本视频免费一区| 精品999久久久| 成人亚洲精品久久久久软件| 中文字幕一区二| 欧美天堂亚洲电影院在线播放| 午夜精品久久久久久不卡8050| 欧美高清性hdvideosex| 蜜桃在线一区二区三区| 久久先锋资源网| 不卡在线视频中文字幕| 一区二区不卡在线视频 午夜欧美不卡在| 一本大道久久a久久综合| 日本亚洲一区二区| 国产欧美精品一区二区三区四区| 色综合中文综合网| 亚洲精品国产精华液| 777久久久精品|