/** * ISR handler. * * @return BOOLEAN Indicates whether the IRQ came from us (TRUE) or not (FALSE). * @param pInterrupt Interrupt that was triggered. * @param pServiceContext Context specific pointer. */ BOOLEAN vboxguestwinIsrHandler(PKINTERRUPT pInterrupt, PVOID pServiceContext) { PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pServiceContext; if (pDevExt == NULL) return FALSE; /*Log(("VBoxGuest::vboxguestwinGuestIsrHandler: pDevExt = 0x%p, pVMMDevMemory = 0x%p\n", pDevExt, pDevExt ? pDevExt->pVMMDevMemory : NULL));*/ /* Enter the common ISR routine and do the actual work. */ BOOLEAN fIRQTaken = VBoxGuestCommonISR(pDevExt); /* If we need to wake up some events we do that in a DPC to make * sure we're called at the right IRQL. */ if (fIRQTaken) { Log(("VBoxGuest::vboxguestwinGuestIsrHandler: IRQ was taken! pInterrupt = 0x%p, pDevExt = 0x%p\n", pInterrupt, pDevExt)); if (ASMAtomicUoReadU32(&pDevExt->u32MousePosChangedSeq) || !RTListIsEmpty(&pDevExt->WakeUpList)) { Log(("VBoxGuest::vboxguestwinGuestIsrHandler: Requesting DPC ...\n")); IoRequestDpc(pDevExt->win.s.pDeviceObject, pDevExt->win.s.pCurrentIrp, NULL); } } return fIRQTaken; }
uint8_t IRQISR(PKINTERRUPT Interrupt, PVOID ServiceContext) { PLOCAL_DEVICE_INFO pdx = (PLOCAL_DEVICE_INFO)ServiceContext; DebugPrint(DBG_WDM | DBG_TRACE, " --> "__FUNCTION__"\n"); // We should check if the interrupt comes from us and return IoRequestDpc(pdx->DeviceObject, 0, pdx); DebugPrint(DBG_WDM | DBG_TRACE, " <-- "__FUNCTION__"\n"); return 1; }
BOOLEAN OnInterrupt(PKINTERRUPT InterruptObject, PDEVICE_EXTENSION pdx) { // OnInterrupt //关中断 UCHAR HSR = READ_PORT_UCHAR(pdx->portbase); HSR = HSR | 0x4; WRITE_PORT_UCHAR(pdx->portbase,HSR); KdPrint(("==============interrupt!!!\n")); //恢复中断信号电平 WRITE_REGISTER_UCHAR((PUCHAR)pdx->MemBar1+0x400000,0x10); IoRequestDpc(pdx->fdo, NULL, pdx); return TRUE; }
dBoolean kdi_Hardware ( /* INPUT PARAMETERS: */ PKINTERRUPT interrupt, dVoidPtr context /* UPDATE PARAMETERS: */ /* OUTPUT PARAMETERS: */ ) /* COMMENTS: ***************************************************************** * * Routine Description: * * This routine is called at DIRQL by the system when the controller * interrupts. * * Arguments: * * Interrupt - a pointer to the interrupt object. * * Context - a pointer to our controller data area for the controller * that interrupted. (This was set up by the call to * IoConnectInterrupt). * * Return Value: * * Normally returns TRUE, but will return FALSE if this interrupt was * not expected. * * DEFINITIONS: *************************************************************/ { /* DATA: ********************************************************************/ dBoolean no_chain = dFALSE; KdiContextPtr kdi_context; /* CODE: ********************************************************************/ UNREFERENCED_PARAMETER( interrupt ); kdi_context = context; if (kdi_context->current_interrupt && kdi_context->interrupt_pending) { // // Check to see if the interrupt is ours // kdi_context->interrupt_status = cqd_ClearInterrupt( kdi_context->cqd_context, kdi_context->interrupt_pending ); if (kdi_context->interrupt_status == DONT_PANIC) { // // We found a valid interrupt from the floppy, so // Reset interrupt pending flag and schedule a DPC to process // the interrupt // kdi_context->interrupt_pending = dFALSE; IoRequestDpc( kdi_context->device_object, kdi_context->device_object->CurrentIrp, (dVoidPtr) dNULL_PTR ); no_chain = dTRUE; } else { kdi_CheckedDump( QIC117INFO, "Q117i: Unexpected IRQ processed\n", 0l); } } return no_chain; }
BOOLEAN SoundISR( IN PKINTERRUPT pInterrupt, IN PVOID Context ) /*++ Routine Description: Interrupt service routine for the soundblaster card. Arguments: pInterrupt - our interrupt Contest - Pointer to our global device info Return Value: TRUE if we handled the interrupt --*/ { PGLOBAL_DEVICE_INFO pGDI; BOOLEAN Result; UCHAR oldval; // pGDI = (PGLOBAL_DEVICE_INFO)Context; ASSERT(pGDI->Key == GDI_KEY); // dprintf1(( "I-1" )); dprintf5(("<")); // // Acknowledge the interrupt // HwInterruptAcknowledge(&pGDI->Hw); // Interrupt pin inactive if( pGDI->WaveInfo.Direction ){ if( pGDI->WaveInfo.MapOn ){ SoundFlushDMA( &pGDI->WaveInfo ); SoundMapDMA( &pGDI->WaveInfo ); } } // // See who the interrupt is for and request the // appropriate deferred routine // Result = TRUE; // // It is valid to test DMABusy because it is set ON before we start // interrupts if (pGDI->WaveInfo.DMABusy) { dprintf5((pGDI->WaveInfo.Direction ? "o" : "i")); // // Check to see if we're overrunning, don't queue a Dpc if // we are. // if (!pGDI->WaveInfo.DpcQueued) { pGDI->WaveInfo.DpcQueued = TRUE; // ASSERTMSG("Overrun count not zeroed by Dpc routine", // pGDI->WaveInfo.Overrun == 0); IoRequestDpc(pGDI->WaveInfo.DeviceObject, NULL, NULL); } else { // // Overrun ! // if (pGDI->WaveInfo.Overrun == 0) { dprintf2(("Wave overrun")); } pGDI->WaveInfo.Overrun++; } } else { #if DBG // We only get 10 valid interrupts when we test the interrupt // for validity in init.c. If we get lots more here there // may be a problem. sndBogusInterrupts++; if ((sndBogusInterrupts % 20) == 0) { dprintf(("%u bogus interrupts so far", sndBogusInterrupts - 10)); } #endif // DBG // // Set the return value to FALSE to say we didn't // handle the interrupt. // Result = FALSE; } dprintf5((">")); return Result; }
BOOLEAN VideoPortDoDma( IN PVOID HwDeviceExtension, IN PVIDEO_REQUEST_PACKET pVrp ) { PDEVICE_EXTENSION deviceExtension = ((PDEVICE_EXTENSION) HwDeviceExtension) - 1; PPUBLIC_VIDEO_REQUEST_BLOCK pPVRB; PDMA_PARAMETERS pIoVrb; PIRP pIrp; GET_PVRB_FROM_PVRP(pPVRB, pVrp); pIoVrb = pVideoPortGetDmaParameters(deviceExtension, pPVRB); if (!pIoVrb) { // // Can't get DmaParameter storage. set flag and return // deviceExtension->VRBFlags |= INSUFFICIENT_DMA_RESOURCES; return FALSE; } pIrp = pPVRB->pIrp; deviceExtension->MapDmaParameters = pIoVrb; // // Get Mdl for user buffer. // if (!pPVRB || !IoAllocateMdl(pPVRB->vrp.InputBuffer, pPVRB->vrp.InputBufferLength, FALSE, FALSE, pIrp)) { VideoPortDebugPrint(0, "VideoPortIoStartRequest: Can't allocate Mdl\n"); pPVRB->vrp.StatusBlock->Status = VRB_STATUS_INVALID_REQUEST; VideoPortNotification(RequestComplete, deviceExtension, pIoVrb); VideoPortNotification(NextRequest, deviceExtension); // // Queue a DPC to process the work that was just indicated. // IoRequestDpc(deviceExtension->DeviceObject, NULL, NULL); return FALSE; } // // Save the Mdl virtual address // pIoVrb->DataOffset = MmGetMdlVirtualAddress(pIrp->MdlAddress); // // Determine if the device needs mapped memory. // if (deviceExtension->bMapBuffers) { if (pIrp->MdlAddress) { pIoVrb->DataOffset = MmGetSystemAddressForMdl(pIrp->MdlAddress); pPVRB->vrp.InputBuffer = ((PUCHAR)pIoVrb->DataOffset) + (ULONG)(((PUCHAR)pPVRB->vrp.InputBuffer) - ((PUCHAR)MmGetMdlVirtualAddress(pIrp->MdlAddress))); } } if (deviceExtension->DmaAdapterObject) { // // If the buffer is not mapped then the I/O buffer must be flushed // to aid in cache coherency. // KeFlushIoBuffers(pIrp->MdlAddress, TRUE, TRUE); } // // Determine if this adapter needs map registers // if (deviceExtension->bMasterWithAdapter) { // // Calculate the number of map registers needed for this transfer. // Note that this may be recalculated if the miniport really wants // to do DMA // pIoVrb->NumberOfMapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES( pPVRB->vrp.InputBuffer, pPVRB->vrp.InputBufferLength ); } // // The miniport may have requested too big of a buffer, so iteratively // chop it in half until we find one we can do. This changes the // vrp.InputBufferLength, which the miniport must check to see how much // is actually sent and queue up the remainder. // while (pIoVrb->NumberOfMapRegisters > deviceExtension->Capabilities.MaximumPhysicalPages) { pPVRB->vrp.InputBufferLength /= 2; pIoVrb->NumberOfMapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES( pPVRB->vrp.InputBuffer, pPVRB->vrp.InputBufferLength ); } // // Allocate the adapter channel with sufficient map registers // for the transfer. // IoAllocateAdapterChannel( deviceExtension->DmaAdapterObject, // AdapterObject deviceExtension->DeviceObject, // DeviceObject pIoVrb->NumberOfMapRegisters, // NumberOfMapRegisters pVideoPortBuildScatterGather, // ExecutionRoutine (Must return DeallocateObjectKeepRegisters) pIoVrb); // Context // // The execution routine called via IoAllocateChannel will do the // rest of the work so just return. // return TRUE; }
BOOLEAN pVideoPortStartIoSynchronized ( PVOID ServiceContext ) /*++ Routine Description: This routine calls the dependent driver start io routine. It also starts the request timer for the logical unit if necesary and inserts the PPUBLIC_VIDEO_REQUEST_BLOCK data structure in to the request list. Arguments: ServiceContext - Supplies the pointer to the device object. Return Value: Returns the value returned by the dependent start I/O routine. Notes: The port driver spinlock must be held when this routine is called. --*/ { PDEVICE_OBJECT deviceObject = ServiceContext; PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension; PIO_STACK_LOCATION irpStack; PPUBLIC_VIDEO_REQUEST_BLOCK pPVRB; PDMA_PARAMETERS pIoVrb; BOOLEAN timerStarted; BOOLEAN returnValue; VideoPortDebugPrint(3, "pVideoPortStartIoSynchronized: Enter routine\n"); irpStack = IoGetCurrentIrpStackLocation(deviceObject->CurrentIrp); pPVRB = irpStack->Parameters.Others.Argument1; // // Mark the pPVRB as active. // pPVRB->VRBFlags |= VRB_FLAGS_IS_ACTIVE; returnValue = deviceExtension->HwStartIO(deviceExtension->HwDeviceExtension, &(pPVRB->vrp)); // // Check for miniport work requests. // if (deviceExtension->pInterruptContext->InterruptFlags & NOTIFY_REQUIRED) { IoRequestDpc(deviceExtension->DeviceObject, NULL, NULL); } return returnValue; } // end pVideoPortStartIoSynchronized()