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

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

?? read_write.c

?? PCI驅動代碼實例
?? C
?? 第 1 頁 / 共 2 頁
字號:
//
//  NOTES:
//      *** Called (and returns) with the WriteQueueLock held.
//
///////////////////////////////////////////////////////////////////////////////
VOID
OsrStartReadIrp(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("OsrRead: Transfer length %d.\n",
                                ioStack->Parameters.Read.Length);
#endif

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

    devExt->ReadTotalLength = ioStack->Parameters.Read.Length;

    devExt->ReadSoFar = 0;

    devExt->ReadStartingOffset = 0;

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

    //
    // Flush the requestor's buffer back from cache on non-dma coherent
    // machines.
    //
    KeFlushIoBuffers(Irp->MdlAddress, TRUE, TRUE);

    //
    // Determine number of map registers required by this read
    //
    mapRegsNeeded = 
        ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Irp->MdlAddress),
                                        ioStack->Parameters.Read.Length);
        
#if DBG
    DbgPrint("StartReadIrp: %d. map regs needed\n", mapRegsNeeded);
#endif

    //
    // Limit the number of map registers used to the maximum allowed by the
    // HAL.  We determined this max when we called HalGetAdapter() during
    // our DriverEntry processing.
    //
    devExt->MapRegsThisRead = ((mapRegsNeeded > devExt->ReadMapRegsGot) ? 
                              devExt->ReadMapRegsGot : mapRegsNeeded);

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

    IoAllocateAdapterChannel(devExt->ReadAdapter,
                             DeviceObject, 
                             devExt->MapRegsThisRead,
                             OsrAdapterControlRead,
                             Irp);
}

///////////////////////////////////////////////////////////////////////////////
//
//  OsrAdapterControlRead
//
//    This is routine is called by the I/O Manager when the Adapter resources
//    (such as map registers) requested by the OsrStartReadIrp function are
//    available for our use.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//      MapRegisterBase - Base address of the Map registers that have been
//                        reserved for us use.
//
//       Context - address of the Read Irp for the operation to be started
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//    DeallocateObjectKeepRegisters - indicates that the Mapping Registers that
//              were allocated to us should not be deallocated at this time.  We
//              will deallocate them from the DpcForIsr when the Read completes.
//
//  IRQL:
//
//    This routine is called at IRQL_DISPATCH_LEVEL.
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
IO_ALLOCATION_ACTION 
OsrAdapterControlRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP NotUsed, 
                                  IN PVOID MapRegisterBase, IN PVOID Context)
{
    PIRP irp = (PIRP) Context;
    PIO_STACK_LOCATION ioStack;
    POSR_DEVICE_EXT devExt;
    PUCHAR baseVa;

#if DBG
    DbgPrint("AdapterControlRead: Irp = 0x%0x\n", irp);
    DbgPrint("AdapterControlRead: Map Register Base = 0x%0x\n", MapRegisterBase);
#endif

    devExt = DeviceObject->DeviceExtension;
    
    ioStack = IoGetCurrentIrpStackLocation(irp);

    devExt->ReadLength = ioStack->Parameters.Read.Length - devExt->ReadSoFar;

#if DBG
    DbgPrint("AdapterControlRead: Length remaining = %d. \n", devExt->ReadLength);
#endif

    //
    // Get set-up for the transfer
    //
    devExt->ReadMapRegBase = MapRegisterBase;

    devExt->ReadStartingOffset =  devExt->ReadSoFar;

    //
    // Get requestor's virtual address of the buffer.  This is used by
    // IoMapTransfer() as an index into the buffer to track the progress
    // of the map operation.
    //
    baseVa = MmGetMdlVirtualAddress(irp->MdlAddress);

    //
    // Get the logical base address and length of a fragment of the 
    // requestor's buffer.
    //
    // Even though we are a Busmaster device, our device does not support
    // scatter/gather.  Thus, we can only use a single base address and length
    // at a time.  If the requestor's buffer has more fragments, we will
    // do additional DMA operations (one for each fragment) until the entire
    // transfer has been completed.
    //
    devExt->ReadPaToDevice = IoMapTransfer(NULL,
                                   irp->MdlAddress,
                                   MapRegisterBase,
                                   baseVa+(devExt->ReadSoFar),
                                   &devExt->ReadLength,
                                   FALSE);  // FALSE = READ from device


    //
    // Track the length of the requestor's buffer we've read so far.
    //
    devExt->ReadSoFar += devExt->ReadLength;

    //
    // Start the request on the device -- Base Address and Length
    // of this fragment are stored in the device extension
    //
    (VOID)KeSynchronizeExecution(devExt->InterruptObject,
                            OsrStartReadOnDevice,
                            DeviceObject);

    return(DeallocateObjectKeepRegisters);
}        


///////////////////////////////////////////////////////////////////////////////
//
//  OsrAdapterControlWrite
//
//    This is routine is called by the I/O Manager when the Adapter resources
//    (such as map registers) requested by the OsrStartWriteIrp function are
//    available for our use.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//      MapRegisterBase - Base address of the Map registers that have been
//                      reserved by the I/O Manager and HAL for our use.
//
//      Context - address of the Write Irp for the operation to be started on the 
//              device.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//    DeallocateObjectKeepRegisters - indicates that the map registers that
//            were allocated to us should not be deallocated at this time.
//            We will deallocate them with the Read operation completes.
//
//  IRQL:
//
//    This routine is called at IRQL_DISPATCH_LEVEL.
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
IO_ALLOCATION_ACTION 
OsrAdapterControlWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP NotUsed, 
                                  IN PVOID MapRegisterBase, IN PVOID Context)
{
    PIRP irp = (PIRP) Context;
    PIO_STACK_LOCATION ioStack;
    POSR_DEVICE_EXT devExt;
    PUCHAR baseVa;

#if DBG
    DbgPrint("AdapterControlWrite: Irp = 0x%0x\n", irp);
#endif

    devExt = DeviceObject->DeviceExtension;

    ioStack = IoGetCurrentIrpStackLocation(irp);

    devExt->WriteLength = ioStack->Parameters.Write.Length - devExt->WriteSoFar;

#if DBG
    DbgPrint("AdapterControlWrite: Length remaining = %d. \n", devExt->WriteLength);
#endif

    //
    // Get set-up for the transfer
    //
    devExt->WriteMapRegBase = MapRegisterBase;

    baseVa = MmGetMdlVirtualAddress(irp->MdlAddress);

    devExt->WriteStartingOffset =  devExt->WriteSoFar;

    //
    // Get the base address and length of the segment to write.
    //
    devExt->WritePaToDevice = IoMapTransfer(NULL,
                                   irp->MdlAddress,
                                   MapRegisterBase,
                                   baseVa+(devExt->WriteSoFar),
                                   &devExt->WriteLength,
                                   TRUE);      // WriteToDevice

    //
    // Update the length transfered so far
    //
    devExt->WriteSoFar += devExt->WriteLength;

    //
    // Put the request on the device
    //
    (VOID)KeSynchronizeExecution(devExt->InterruptObject,
                            OsrStartWriteOnDevice,
                            DeviceObject);

    return(DeallocateObjectKeepRegisters);
}        


///////////////////////////////////////////////////////////////////////////////
//
//  OsrStartReadOnDevice
//
//      This function performs all the actual hardware manipulation to initiate
//      a new read request on the AMCC device.  When called, all resources
//      (mapping registers) have been allocated for the operation, and we have
//      a base address and length of a buffer fragment to be DMA'ed.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//      BaseAddress  - Logical base address of the requestor's buffer fragment
//                      to be used as the base address of the transfer
//
//      Length - Length in bytes of this fragment to be transfered.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//      This routine is called at IRQL_DISPATCH_LEVEL.
//
//  NOTES:
//
//      When this routine is called, no other Read operations are in progress on
//      the device.
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN
OsrStartReadOnDevice(IN PVOID SynchronizeContext)
{
    ULONG temp;
    PDEVICE_OBJECT deviceObject = (PDEVICE_OBJECT)SynchronizeContext;
    PHYSICAL_ADDRESS baseAddress;
    ULONG length;
    POSR_DEVICE_EXT devExt = deviceObject->DeviceExtension;

    baseAddress = devExt->ReadPaToDevice;
    length = devExt->ReadLength;

#if DBG
    DbgPrint("StartReadOnDev: Reading BA = 0x%0x, Length = %d.\n",
                        baseAddress.LowPart, length);
#endif

    //
    // Pass the device the Physical Base Address of the buffer
    //
    ASSERT(!baseAddress.HighPart);

    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MWAR_OFF,
                     baseAddress.LowPart);

    //
    // ...and the length of the read
    //
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MWTC_OFF, length);

    //
    // Tell the device to interrupt when the read is complete.
    //
    // NOTE: In this particular device, "read" operations from the
    // device are called "WRITE" operations... since they write to
    // MEMORY.  Thus, we set the INT_ON_WRITE bit in the Interrupt
    // CSR.
    //
    temp = READ_PORT_ULONG(devExt->AmccBaseRegisterAddress+ICSR_OFF);

#if DBG
    DbgPrint("StartDmaRead: Current INTCSR State:\n");
    OsrPrintIntcsr(temp);
#endif

    temp &= ~AMCC_INT_ACK_BITS;
    temp |= AMCC_INT_INT_ON_WRITE;
    
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+ICSR_OFF, temp);

    //
    // Yeeeeha!  Start the request by settting the "Write Enable"
    // bit in the master CSR
    //
    temp = READ_PORT_ULONG(devExt->AmccBaseRegisterAddress+MCSR_OFF);
    temp &= (AMCC_MCSR_READ_ENABLE        |
                AMCC_MCSR_READ_FIFO_MGMT  |
                AMCC_MCSR_READ_PRIORITY   |
                AMCC_MCSR_WRITE_ENABLE    |
                AMCC_MCSR_WRITE_FIFO_MGMT |
                AMCC_MCSR_WRITE_PRIORITY);

    temp |= AMCC_MCSR_WRITE_ENABLE;

    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MCSR_OFF, temp); 

    return(TRUE);
}    

///////////////////////////////////////////////////////////////////////////////
//
//  OsrStartWriteOnDevice
//
//      This function performs all the actual hardware manipulation to initiate
//      a new read request on the AMCC device.  When called, all resources
//      (mapping registers) have been allocated for the operation, and we have
//      a base address and length of a buffer fragment to be DMA'ed.
//
//  INPUTS:
//
//      DeviceObject - Address of the DEVICE_OBJECT for our device.
//  
//      BaseAddress  - Logical base address of the requestor's buffer fragment
//                      to be used as the base address of the transfer
//
//      Length - Length in bytes of this fragment to be transfered.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//    None.
//
//  IRQL:
//
//    This routine is called at IRQL_DISPATCH_LEVEL.
//
//  NOTES:
//
//    When this routine is called, no other Write operations are in progress on
//    the device.
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN
OsrStartWriteOnDevice(IN PVOID SynchronizeContext)
{
    ULONG temp;
    PDEVICE_OBJECT deviceObject = (PDEVICE_OBJECT)SynchronizeContext;
    PHYSICAL_ADDRESS baseAddress;
    ULONG length;
    POSR_DEVICE_EXT devExt = deviceObject->DeviceExtension;

    baseAddress = devExt->WritePaToDevice;
    length = devExt->WriteLength;

#if DBG
    DbgPrint("StartWriteOnDev: Writing BA = 0x%0x, Length = %d.\n",
                        baseAddress.LowPart, length);
#endif

    //
    // Pass the device the Physical Base Address of the buffer...
    //
    ASSERT(!baseAddress.HighPart);

    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MRAR_OFF,
                     baseAddress.LowPart);

    //
    // ...and the length of the write operation
    //
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MRTC_OFF, length);

    //
    // Request the device interrupt when the write operation is complete
    //
    temp = READ_PORT_ULONG(devExt->AmccBaseRegisterAddress+ICSR_OFF);

#if DBG
    DbgPrint("StartWriteOnDev: Current INTCSR State:\n");
    OsrPrintIntcsr(temp);
#endif

    temp &= ~AMCC_INT_ACK_BITS;
    temp |= AMCC_INT_INT_ON_READ;
    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+ICSR_OFF, temp);

    //
    // Yeeeeha!  Start the request by setting the appropriate enable bit.
    //
    temp = READ_PORT_ULONG(devExt->AmccBaseRegisterAddress+MCSR_OFF);
    temp &= (AMCC_MCSR_READ_ENABLE|
                AMCC_MCSR_READ_FIFO_MGMT|
                AMCC_MCSR_READ_PRIORITY|
                AMCC_MCSR_WRITE_ENABLE|
                AMCC_MCSR_WRITE_FIFO_MGMT|
                AMCC_MCSR_WRITE_PRIORITY);

    temp |= AMCC_MCSR_READ_ENABLE;

    WRITE_PORT_ULONG(devExt->AmccBaseRegisterAddress+MCSR_OFF, temp); 

    return(TRUE);
}    

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美一区二区三区喷汁尤物| 久久99精品久久只有精品| 精品少妇一区二区三区| 不卡的看片网站| 日日夜夜免费精品视频| 国产精品午夜春色av| 日本道在线观看一区二区| 国产成人高清视频| 另类成人小视频在线| 天堂影院一区二区| 亚洲美女屁股眼交| 中文字幕亚洲电影| 久久久久国产精品免费免费搜索| 色哟哟欧美精品| 91麻豆国产福利在线观看| 国产精品77777| 韩国av一区二区三区在线观看| 久久毛片高清国产| 国产亚洲欧美激情| 精品国产91洋老外米糕| 91精品国产综合久久久久久 | 色综合久久久久网| 国产成人精品亚洲午夜麻豆| 午夜影院久久久| 亚洲影视在线播放| 亚洲精选在线视频| 欧美人牲a欧美精品| 在线观看视频一区| 国内成人精品2018免费看| 日韩国产欧美一区二区三区| 亚洲超碰97人人做人人爱| 亚洲综合一二区| 亚洲午夜久久久久中文字幕久| 久久尤物电影视频在线观看| 精品久久久久久综合日本欧美| 欧美精品v日韩精品v韩国精品v| 欧美精品久久久久久久多人混战 | 成人精品鲁一区一区二区| 久久久国产一区二区三区四区小说| 欧美一区二区三区成人| 久久天天做天天爱综合色| 色狠狠桃花综合| 欧美久久久久久久久| 在线播放91灌醉迷j高跟美女| 欧美卡1卡2卡| 久久久久久久久久久黄色| 在线精品国精品国产尤物884a| 亚洲视频在线一区| 亚洲国产你懂的| 青青草97国产精品免费观看 | 色婷婷久久综合| 六月丁香婷婷久久| 粉嫩绯色av一区二区在线观看 | 欧美激情中文字幕一区二区| 欧美日韩一区二区在线观看视频 | 亚洲成精国产精品女| 日日夜夜精品免费视频| 国内精品视频一区二区三区八戒 | 久久免费视频色| 亚洲三级电影全部在线观看高清| 一区二区三区在线视频观看| 麻豆一区二区三| heyzo一本久久综合| 北条麻妃国产九九精品视频| 欧美猛男超大videosgay| 久久精品人人爽人人爽| 精品国产乱子伦一区| 日韩一区日韩二区| 奇米色一区二区| 色综合天天性综合| 亚洲精品一区二区三区蜜桃下载| 国产精品色一区二区三区| 美国十次综合导航| 欧美日韩在线精品一区二区三区激情| 欧美xxxxx牲另类人与| 一区二区三区欧美在线观看| 日本不卡中文字幕| 国产精品乡下勾搭老头1| 成人性生交大合| 久久久久久99久久久精品网站| 久久久久久久久久美女| 欧美96一区二区免费视频| 91麻豆自制传媒国产之光| 337p日本欧洲亚洲大胆色噜噜| 亚洲男同性视频| 国产成人免费视频网站| 欧美一级高清大全免费观看| 一区二区三区鲁丝不卡| 国产一区二区三区在线观看精品| 色天使色偷偷av一区二区| 88在线观看91蜜桃国自产| 亚洲妇女屁股眼交7| 美女视频网站黄色亚洲| 日韩午夜电影av| 免费成人小视频| 精品久久久久久综合日本欧美| 午夜电影网一区| 欧美日韩高清在线播放| 久久精品亚洲麻豆av一区二区 | 美国十次综合导航| 欧美精品在线一区二区| 亚洲一二三四在线| 色偷偷成人一区二区三区91| 亚洲黄色小视频| 在线精品亚洲一区二区不卡| 精品国产凹凸成av人网站| 麻豆精品在线看| 亚洲精品一区二区三区在线观看| 国产综合成人久久大片91| 精品免费国产二区三区| 国产精品每日更新在线播放网址| 成人天堂资源www在线| 91精品1区2区| 亚洲妇女屁股眼交7| 欧美精品自拍偷拍| 麻豆成人91精品二区三区| 日韩免费高清av| 亚洲黄色性网站| 欧美二区乱c少妇| 国产一区三区三区| 欧美国产乱子伦| 一本大道久久精品懂色aⅴ| 欧美极品另类videosde| 成人精品小蝌蚪| 国产精品色婷婷| 91女人视频在线观看| 亚洲激情一二三区| 成人精品国产免费网站| 一区二区激情小说| 欧美日韩国产成人在线91| 久久国产视频网| 亚洲免费资源在线播放| 8x8x8国产精品| 国产电影一区在线| 亚洲乱码国产乱码精品精98午夜| av动漫一区二区| 日韩黄色免费网站| 久久久久久亚洲综合影院红桃| 91搞黄在线观看| 国产精品亚洲一区二区三区妖精| 亚洲精品菠萝久久久久久久| 欧美不卡一区二区三区四区| 成人ar影院免费观看视频| 亚洲.国产.中文慕字在线| 欧美日韩国产大片| 国产精品一二三区在线| 亚洲激情网站免费观看| 久久久久99精品一区| 成人av电影观看| 久久国产乱子精品免费女| 国产精品拍天天在线| 日韩三级高清在线| 六月丁香综合在线视频| 一区二区三区四区在线播放| 91精品国产综合久久精品麻豆| 99久久久久免费精品国产| 肉肉av福利一精品导航| 亚洲激情自拍视频| 26uuu色噜噜精品一区| 久久综合av免费| 国产精品欧美经典| 一区二区三区久久| 日韩精品一二三四| 狠狠色丁香婷婷综合久久片| 国产福利一区二区三区视频| av在线综合网| 欧美日韩成人在线一区| 精品区一区二区| 国产精品久久久久久久久久免费看| 18欧美亚洲精品| 亚洲综合区在线| 免费观看日韩av| 成人综合在线观看| 欧美午夜精品免费| 日韩一区二区免费高清| 久久久不卡影院| 亚洲精品日产精品乱码不卡| 亚洲成人精品一区| 国产美女精品在线| 色综合av在线| 精品日产卡一卡二卡麻豆| 中文字幕一区二区三区在线播放| 亚洲自拍偷拍欧美| 韩国成人在线视频| 在线免费观看一区| 国产色91在线| 亚洲国产日韩在线一区模特 | 国产精品国模大尺度视频| 午夜电影网一区| 9i看片成人免费高清| 91精品啪在线观看国产60岁| 中文字幕av一区二区三区| 午夜av电影一区| 成人av在线资源| 日韩免费观看2025年上映的电影| 亚洲精品免费在线播放| 国产综合色视频| 日韩一二三四区| 尤物在线观看一区| 懂色av一区二区三区蜜臀|