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

📄 isr_dpc.c

📁 PCI驱动程序开发示例。是我从OSR网站下载的
💻 C
📖 第 1 页 / 共 2 页
字号:
        //
        // Get the address of the in-progress request
        //
        irp = devExt->CurrentWriteIrp;

        //
        // See if there's an entry on the Write queue that needs to be
        // completed or continued.
        //
        if (irp)  {
            
            //
            // There is an IRP currently in progress.
            //
            baseVa = (PUCHAR)MmGetMdlVirtualAddress(irp->MdlAddress)+
                                    devExt->WriteStartingOffset;

            IoFlushAdapterBuffers(devExt->WriteAdapter,
                                 irp->MdlAddress,
                                 devExt->WriteMapRegBase,
                                 baseVa,
                                 devExt->WriteSoFar-devExt->WriteStartingOffset,
                                 TRUE);     // writeToDevice == TRUE

            //
            // Tell the HAL the map registers we were using are free
            //
            IoFreeMapRegisters(devExt->WriteAdapter,
                               devExt->WriteMapRegBase,
                               devExt->MapRegsThisWrite);

            //
            // See if there's more of the user's buffer left for us to DMA.
            // Be sure the request was not cancelled whilst in progress.
            //
            if( (devExt->WriteTotalLength - devExt->WriteSoFar) &&
                (!irp->Cancel) )  {
#if DBG
                DbgPrint("---CONTINUING:\n");
#endif
                //
                // The user buffer has NOT been completely DMA'ed.
                // How many map regs can we use this time?
                //
                mapRegsNeeded = 
                    ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(irp->MdlAddress)+
                                 devExt->WriteSoFar,
                                 devExt->WriteTotalLength-devExt->WriteSoFar);
                    
                devExt->MapRegsThisWrite = ((mapRegsNeeded > devExt->WriteMapRegsGot) ? 
                                          devExt->WriteMapRegsGot : mapRegsNeeded);

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

                IoAllocateAdapterChannel(devExt->WriteAdapter,
                                         DeviceObject, 
                                         devExt->MapRegsThisWrite,
                                         OsrAdapterControlWrite,
                                         irp);
            } else  {

                //
                // We're going to complete this request
                //

                //
                // Information field contains number of bytes written
                //
                irp->IoStatus.Information = devExt->WriteTotalLength;

                // and all requests are completed with success...
                //
                irp->IoStatus.Status = STATUS_SUCCESS;


                //
                //
                // ...unless the in-progress I/O operation is cancelled.
                //
                if(irp->Cancel == TRUE)  {

#if DBG
                    DbgPrint("---CANCEL flag set in WRITE IRP to be completed!\n");
#endif
                    irp->IoStatus.Status = STATUS_CANCELLED;
                    irp->IoStatus.Information = 0;

                }

#if DBG
                DbgPrint("---Completing Write IRP 0x%0x\n",irp);
#endif
                //
                // Complete the request now
                //
                IoCompleteRequest(irp, IO_NO_INCREMENT);    

                //
                // N.B.  We're STILL HOLDING the write queue lock.
                //

                //
                // No write in progress right now
                //
                devExt->CurrentWriteIrp = NULL;

                //
                // Keep removing entries until we start one.
                //
                while ( !devExt->CurrentWriteIrp &&
                        !IsListEmpty(&devExt->WriteQueue) ) {

                    entry = RemoveHeadList(&devExt->WriteQueue);

                    irp =  CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
#if DBG
                    DbgPrint("---IRP removed from queue in DpcForIsr = 0x%0x\n",irp);
#endif
                    //
                    // If this IRP is cancelled, cancel it now, without
                    // initiating it on the device
                    //
                    if (irp->Cancel) {
#if DBG
                        DbgPrint("---CANCEL flag set in IRP removed from queue 0x%0x\n",irp);
#endif
                        irp->IoStatus.Status = STATUS_CANCELLED;
                        irp->IoStatus.Information = 0;

                        //
                        // Complete the request now
                        //
                        IoCompleteRequest(irp, IO_NO_INCREMENT);    

                    } else {

                        //
                        // Since we do not cancel in-progress requests
                        // on this device, we will reset the cancel
                        // routine in the IRP to NULL.
                        //
                        IoSetCancelRoutine(irp, NULL);

                        //
                        // Make this IRP the current write IRP, and
                        // start the request on the device.  This routine
                        // sets devExt->CurrentWriteIrp
                        //
                        OsrStartWriteIrp(DeviceObject, irp);                
                    }

                }   // while (!devExt->CurrentWriteIrp && 
                    //        !IsListEmpty(devExt->WriteQueue) )
            }
        }                              

        //
        // Drop the lock
        //
        KeReleaseSpinLockFromDpcLevel(&devExt->WriteQueueLock);

    }

    //
    // Read Complete??
    //
    if( KeSynchronizeExecution(devExt->InterruptObject,
                                ReadIsDone,
                                devExt) )  {

#if DBG
        DbgPrint("---Read Done\n");
#endif

        //
        // Get the read queue lock.  We'll hold it throughout the entire
        // process.
        //
        KeAcquireSpinLockAtDpcLevel(&devExt->ReadQueueLock);

        //
        // Get the address of the in-progress request
        //
        irp = devExt->CurrentReadIrp;

        //
        // See if there's an entry on the Read queue that needs to be
        // completed or continued.
        //
        if (irp)  {
            
            //
            // There is an IRP currently in progress.
            //
            baseVa = (PUCHAR)MmGetMdlVirtualAddress(irp->MdlAddress)+
                                    devExt->ReadStartingOffset;

            IoFlushAdapterBuffers(devExt->ReadAdapter,
                                 irp->MdlAddress,
                                 devExt->ReadMapRegBase,
                                 baseVa,
                                 devExt->ReadSoFar-devExt->ReadStartingOffset,
                                 FALSE);     // read == FALSE

            //
            // Tell the HAL the map registers we were using are free
            //
            IoFreeMapRegisters(devExt->ReadAdapter,
                               devExt->ReadMapRegBase,
                               devExt->MapRegsThisRead);

            //
            // See if there's more of the user's buffer left for us to DMA.
            // Be sure the request was not cancelled whilst in progress.
            //
            if( (devExt->ReadTotalLength - devExt->ReadSoFar) &&
                (!irp->Cancel) )  {
#if DBG
                DbgPrint("---CONTINUING:\n");
#endif
                //
                // The user buffer has NOT been completely DMA'ed.
                // How many map regs can we use this time?
                //
                mapRegsNeeded = 
                    ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(irp->MdlAddress)+
                                 devExt->ReadSoFar,
                                 devExt->ReadTotalLength-devExt->ReadSoFar);
                    
                devExt->MapRegsThisRead = ((mapRegsNeeded > devExt->ReadMapRegsGot) ? 
                                          devExt->ReadMapRegsGot : mapRegsNeeded);

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

                IoAllocateAdapterChannel(devExt->ReadAdapter,
                                         DeviceObject, 
                                         devExt->MapRegsThisRead,
                                         OsrAdapterControlRead,
                                         irp);
            } else  {

                //
                // We're going to complete this request
                //

                //
                // Information field contains number of bytes written
                //
                irp->IoStatus.Information = devExt->ReadTotalLength;

                // and all requests are completed with success...
                //
                irp->IoStatus.Status = STATUS_SUCCESS;


                //
                //
                // ...unless the in-progress I/O operation is cancelled.
                //
                if(irp->Cancel == TRUE)  {

#if DBG
                    DbgPrint("---CANCEL flag set in READ IRP to be completed!\n");
#endif
                    irp->IoStatus.Status = STATUS_CANCELLED;
                    irp->IoStatus.Information = 0;

                }

#if DBG
                DbgPrint("---Completing Read IRP 0x%0x\n",irp);
#endif
                //
                // Complete the request now
                //
                IoCompleteRequest(irp, IO_NO_INCREMENT);    

                //
                // N.B.  We're STILL HOLDING the read queue lock.
                //

                //
                // No read in progress right now
                //
                devExt->CurrentReadIrp = NULL;

                //
                // Keep removing entries until we start one.
                //
                while ( !devExt->CurrentReadIrp &&
                        !IsListEmpty(&devExt->ReadQueue) ) {

                    entry = RemoveHeadList(&devExt->ReadQueue);

                    irp =  CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
#if DBG
                    DbgPrint("---IRP removed from queue in DpcForIsr = 0x%0x\n",irp);
#endif
                    //
                    // If this IRP is cancelled, cancel it now, without
                    // initiating it on the device
                    //
                    if (irp->Cancel) {
#if DBG
                        DbgPrint("---CANCEL flag set in IRP removed from queue 0x%0x\n",irp);
#endif
                        irp->IoStatus.Status = STATUS_CANCELLED;
                        irp->IoStatus.Information = 0;

                        //
                        // Complete the request now
                        //
                        IoCompleteRequest(irp, IO_NO_INCREMENT);    

                    } else {

                        //
                        // Since we do not cancel in-progress requests
                        // on this device, we will reset the cancel
                        // routine in the IRP to NULL.
                        //
                        IoSetCancelRoutine(irp, NULL);

                        //
                        // Make this IRP the current read IRP, and
                        // start the request on the device.  This routine
                        // sets devExt->CurrentReadIrp
                        //
                        OsrStartReadIrp(DeviceObject, irp);                
                    }

                }   // while (!devExt->CurrentReadIrp && 
                    //        !IsListEmpty(devExt->ReadQueue) )
            }
        }                              

        //
        // Drop the read queue lock
        //
        KeReleaseSpinLockFromDpcLevel(&devExt->ReadQueueLock);
    }
    
    //
    // We're outa here...
    //
    return;
}

⌨️ 快捷键说明

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