VOID HalpInitializeProfiler( VOID ) /*++ Routine Description: Initialize the profiler by setting initial values and connecting the profile interrupt. Arguments: InterfaceType - Supplies the interface type of the bus on which the profiler will be connected. BusNumber - Supplies the number of the bus on which the profiler will be connected. BusInterruptLevel - Supplies the bus interrupt level to connect the profile interrupt. Return Value: None. --*/ { KAFFINITY Affinity; KIRQL Irql; ULONG Vector; // // Get the interrupt vector and synchronization Irql. // Vector = HalGetInterruptVector( Eisa, 0, 0, 0, &Irql, &Affinity ); IoConnectInterrupt( &HalpProfileInterruptObject, (PKSERVICE_ROUTINE)HalpProfileInterrupt, NULL, NULL, Vector, Irql, Irql, Latched, FALSE, Affinity, FALSE ); return; }
UINT32 AcpiOsInstallInterruptHandler ( UINT32 InterruptNumber, ACPI_OSD_HANDLER ServiceRoutine, void *Context) { ULONG Vector; KIRQL DIrql; KAFFINITY Affinity; NTSTATUS Status; if (AcpiInterruptHandlerRegistered) { DPRINT1("Reregister interrupt attempt failed\n"); return AE_ALREADY_EXISTS; } if (!ServiceRoutine) { DPRINT1("Bad parameter\n"); return AE_BAD_PARAMETER; } DPRINT("AcpiOsInstallInterruptHandler()\n"); Vector = HalGetInterruptVector( Internal, 0, InterruptNumber, InterruptNumber, &DIrql, &Affinity); AcpiIrqNumber = InterruptNumber; AcpiIrqHandler = ServiceRoutine; AcpiIrqContext = Context; AcpiInterruptHandlerRegistered = TRUE; Status = IoConnectInterrupt( &AcpiInterrupt, OslIsrStub, NULL, NULL, Vector, DIrql, DIrql, LevelSensitive, TRUE, Affinity, FALSE); if (!NT_SUCCESS(Status)) { DPRINT("Could not connect to interrupt %d\n", Vector); return AE_ERROR; } return AE_OK; }
static NTSTATUS i8042ConnectKeyboardInterrupt( IN PI8042_KEYBOARD_EXTENSION DeviceExtension) { PPORT_DEVICE_EXTENSION PortDeviceExtension; KIRQL DirqlMax; NTSTATUS Status; TRACE_(I8042PRT, "i8042ConnectKeyboardInterrupt()\n"); PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; DirqlMax = MAX( PortDeviceExtension->KeyboardInterrupt.Dirql, PortDeviceExtension->MouseInterrupt.Dirql); INFO_(I8042PRT, "KeyboardInterrupt.Vector %lu\n", PortDeviceExtension->KeyboardInterrupt.Vector); INFO_(I8042PRT, "KeyboardInterrupt.Dirql %lu\n", PortDeviceExtension->KeyboardInterrupt.Dirql); INFO_(I8042PRT, "KeyboardInterrupt.DirqlMax %lu\n", DirqlMax); INFO_(I8042PRT, "KeyboardInterrupt.InterruptMode %s\n", PortDeviceExtension->KeyboardInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"); INFO_(I8042PRT, "KeyboardInterrupt.ShareInterrupt %s\n", PortDeviceExtension->KeyboardInterrupt.ShareInterrupt ? "yes" : "no"); INFO_(I8042PRT, "KeyboardInterrupt.Affinity 0x%lx\n", PortDeviceExtension->KeyboardInterrupt.Affinity); Status = IoConnectInterrupt( &PortDeviceExtension->KeyboardInterrupt.Object, i8042KbdInterruptService, DeviceExtension, &PortDeviceExtension->SpinLock, PortDeviceExtension->KeyboardInterrupt.Vector, PortDeviceExtension->KeyboardInterrupt.Dirql, DirqlMax, PortDeviceExtension->KeyboardInterrupt.InterruptMode, PortDeviceExtension->KeyboardInterrupt.ShareInterrupt, PortDeviceExtension->KeyboardInterrupt.Affinity, FALSE); if (!NT_SUCCESS(Status)) { WARN_(I8042PRT, "IoConnectInterrupt() failed with status 0x%08x\n", Status); return Status; } if (DirqlMax == PortDeviceExtension->KeyboardInterrupt.Dirql) PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; PortDeviceExtension->Flags |= KEYBOARD_INITIALIZED; return STATUS_SUCCESS; }
NTSTATUS ConnectInterrupt(PDEVICE_OBJECT fdo) { PLOCAL_DEVICE_INFO pdx = (PLOCAL_DEVICE_INFO)fdo->DeviceExtension; NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; KeInitializeSpinLock(&pdx->InterruptSpinLock); //KdPrint(("InterruptVector = %d\r\n", pdx->InterruptVector)); //KdPrint(("InterruptLevel = %d\r\n", pdx->InterruptLevel)); //if (pdx->InterruptSharable) // KdPrint(("Interrupt is sharable\r\n")); //else // KdPrint(("Interrupt is not sharable\r\n")); //KdPrint(("InterruptAffinity = 0x%X\r\n", pdx->InterruptAffinity)); ntStatus = IoConnectInterrupt(&pdx->InterruptObject, // InterruptObject (PKSERVICE_ROUTINE)IRQISR, // ServiceRoutine pdx, // ServiceContext &pdx->InterruptSpinLock, // SpinLock pdx->InterruptVector, // Vector (KIRQL)pdx->InterruptLevel, // Irql (KIRQL)pdx->InterruptLevel, // SynchronizeIrql pdx->InterruptMode, // InterruptMode pdx->InterruptSharable, // ShareVector pdx->InterruptAffinity, // ProcessorEnableMask FALSE); // FloatingSave if (NT_SUCCESS(ntStatus)) { //if (gECDev.Flag & EC_F_CHIP_EXIST) //{ // // How to convert vector to IRQs in driver? // EC_SetWDogIRQ((uint8_t)pdx->InterruptLevel); //} DebugPrint(DBG_WDM | DBG_TRACE, " Connect Interrupt succeed\n"); } else { DebugPrint(DBG_WDM | DBG_ERROR, " Connect Interrupt failed\n"); } return ntStatus; }
NTSTATUS EnableIrq( PDEVICE_OBJECT DeviceObject) { PSOUND_BLASTER_PARAMETERS parameters = DeviceObject->DeviceExtension; ULONG vector; KIRQL irq_level; KAFFINITY affinity; NTSTATUS status = STATUS_SUCCESS; vector = HalGetInterruptVector(Isa, 0, parameters->irq, parameters->irq, &irq_level, &affinity); DPRINT("Vector is 0x%x\n", vector); status = IoConnectInterrupt(¶meters->interrupt, ServiceSoundBlasterInterrupt, DeviceObject, (PKSPIN_LOCK) NULL, vector, irq_level, irq_level, Latched, /* Latched / LevelSensitive */ FALSE, /* shareable */ affinity, FALSE); if ( status == STATUS_INVALID_PARAMETER ) status = STATUS_DEVICE_CONFIGURATION_ERROR; return status; }
static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject) /* * FUNCTION: Called on initialization to find our controllers and build device and controller objects for them * ARGUMENTS: * DriverObject: Our driver's DriverObject (so we can create devices against it) * RETURNS: * FALSE if we can't allocate a device, adapter, or interrupt object, or if we fail to find any controllers * TRUE otherwise (i.e. we have at least one fully-configured controller) * NOTES: * - Currently we only support ISA buses. * - BUG: Windows 2000 seems to clobber the response from the IoQueryDeviceDescription callback, so now we * just test a boolean value in the first object to see if it was completely populated. The same value * is tested for each controller before we build device objects for it. * TODO: * - Report resource usage to the HAL */ { INTERFACE_TYPE InterfaceType = Isa; CONFIGURATION_TYPE ControllerType = DiskController; CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral; KAFFINITY Affinity; DEVICE_DESCRIPTION DeviceDescription; UCHAR i; UCHAR j; PAGED_CODE(); /* Find our controllers on all ISA buses */ IoQueryDeviceDescription(&InterfaceType, 0, &ControllerType, 0, &PeripheralType, 0, ConfigCallback, 0); /* * w2k breaks the return val from ConfigCallback, so we have to hack around it, rather than just * looking for a return value from ConfigCallback. We expect at least one controller. */ if(!gControllerInfo[0].Populated) { WARN_(FLOPPY, "AddControllers: failed to get controller info from registry\n"); return FALSE; } /* Now that we have a controller, set it up with the system */ for(i = 0; i < gNumberOfControllers; i++) { /* 0: Report resource usage to the kernel, to make sure they aren't assigned to anyone else */ /* FIXME: Implement me. */ /* 1: Set up interrupt */ gControllerInfo[i].MappedVector = HalGetInterruptVector(gControllerInfo[i].InterfaceType, gControllerInfo[i].BusNumber, gControllerInfo[i].Level, gControllerInfo[i].Vector, &gControllerInfo[i].MappedLevel, &Affinity); /* Must set up the DPC before we connect the interrupt */ KeInitializeDpc(&gControllerInfo[i].Dpc, DpcForIsr, &gControllerInfo[i]); INFO_(FLOPPY, "Connecting interrupt %d to controller%d (object 0x%p)\n", gControllerInfo[i].MappedVector, i, &gControllerInfo[i]); /* NOTE: We cannot share our interrupt, even on level-triggered buses. See Isr() for details. */ if(IoConnectInterrupt(&gControllerInfo[i].InterruptObject, Isr, &gControllerInfo[i], 0, gControllerInfo[i].MappedVector, gControllerInfo[i].MappedLevel, gControllerInfo[i].MappedLevel, gControllerInfo[i].InterruptMode, FALSE, Affinity, 0) != STATUS_SUCCESS) { WARN_(FLOPPY, "AddControllers: unable to connect interrupt\n"); continue; } /* 2: Set up DMA */ memset(&DeviceDescription, 0, sizeof(DeviceDescription)); DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; DeviceDescription.DmaChannel = gControllerInfo[i].Dma; DeviceDescription.InterfaceType = gControllerInfo[i].InterfaceType; DeviceDescription.BusNumber = gControllerInfo[i].BusNumber; DeviceDescription.MaximumLength = 2*18*512; /* based on a 1.44MB floppy */ /* DMA 0,1,2,3 are 8-bit; 4,5,6,7 are 16-bit (4 is chain i think) */ DeviceDescription.DmaWidth = gControllerInfo[i].Dma > 3 ? Width16Bits: Width8Bits; gControllerInfo[i].AdapterObject = HalGetAdapter(&DeviceDescription, &gControllerInfo[i].MapRegisters); if(!gControllerInfo[i].AdapterObject) { WARN_(FLOPPY, "AddControllers: unable to allocate an adapter object\n"); IoDisconnectInterrupt(gControllerInfo[i].InterruptObject); continue; } /* 2b: Initialize the new controller */ if(InitController(&gControllerInfo[i]) != STATUS_SUCCESS) { WARN_(FLOPPY, "AddControllers(): Unable to set up controller %d - initialization failed\n", i); IoDisconnectInterrupt(gControllerInfo[i].InterruptObject); continue; } /* 2c: Set the controller's initlized flag so we know to release stuff in Unload */ gControllerInfo[i].Initialized = TRUE; /* 3: per-drive setup */ for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++) { WCHAR DeviceNameBuf[MAX_DEVICE_NAME]; UNICODE_STRING DeviceName; UNICODE_STRING LinkName; UNICODE_STRING ArcPath; UCHAR DriveNumber; INFO_(FLOPPY, "AddControllers(): Configuring drive %d on controller %d\n", i, j); /* * 3a: create a device object for the drive * Controllers and drives are 0-based, so the combos are: * 0: 0,0 * 1: 0,1 * 2: 0,2 * 3: 0,3 * 4: 1,0 * 5: 1,1 * ... * 14: 3,2 * 15: 3,3 */ DriveNumber = (UCHAR)(i*4 + j); /* loss of precision is OK; there are only 16 of 'em */ RtlZeroMemory(&DeviceNameBuf, MAX_DEVICE_NAME * sizeof(WCHAR)); swprintf(DeviceNameBuf, L"\\Device\\Floppy%d", DriveNumber); RtlInitUnicodeString(&DeviceName, DeviceNameBuf); if(IoCreateDevice(DriverObject, sizeof(PVOID), &DeviceName, FILE_DEVICE_DISK, FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE, FALSE, &gControllerInfo[i].DriveInfo[j].DeviceObject) != STATUS_SUCCESS) { WARN_(FLOPPY, "AddControllers: unable to register a Device object\n"); IoDisconnectInterrupt(gControllerInfo[i].InterruptObject); continue; /* continue on to next drive */ } INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n", DeviceNameBuf, gControllerInfo[i].DriveInfo[j].DeviceObject); /* 3b.5: Create an ARC path in case we're booting from this drive */ swprintf(gControllerInfo[i].DriveInfo[j].ArcPathBuffer, L"\\ArcName\\multi(%d)disk(%d)fdisk(%d)", gControllerInfo[i].BusNumber, i, DriveNumber); RtlInitUnicodeString(&ArcPath, gControllerInfo[i].DriveInfo[j].ArcPathBuffer); IoAssignArcName(&ArcPath, &DeviceName); /* 3c: Set flags up */ gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO; /* 3d: Create a symlink */ swprintf(gControllerInfo[i].DriveInfo[j].SymLinkBuffer, L"\\DosDevices\\%c:", DriveNumber + 'A'); RtlInitUnicodeString(&LinkName, gControllerInfo[i].DriveInfo[j].SymLinkBuffer); if(IoCreateSymbolicLink(&LinkName, &DeviceName) != STATUS_SUCCESS) { WARN_(FLOPPY, "AddControllers: Unable to create a symlink for drive %d\n", DriveNumber); IoDisconnectInterrupt(gControllerInfo[i].InterruptObject); IoDeassignArcName(&ArcPath); continue; /* continue to next drive */ } /* 3e: Increase global floppy drives count */ IoGetConfigurationInformation()->FloppyCount++; /* 3f: Set up the DPC */ IoInitializeDpcRequest(gControllerInfo[i].DriveInfo[j].DeviceObject, (PIO_DPC_ROUTINE)DpcForIsr); /* 3g: Point the device extension at our DriveInfo struct */ gControllerInfo[i].DriveInfo[j].DeviceObject->DeviceExtension = &gControllerInfo[i].DriveInfo[j]; /* 3h: neat comic strip */ /* 3i: set the initial media type to unknown */ memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY)); gControllerInfo[i].DriveInfo[j].DiskGeometry.MediaType = Unknown; /* 3j: Now that we're done, set the Initialized flag so we know to free this in Unload */ gControllerInfo[i].DriveInfo[j].Initialized = TRUE; /* 3k: Clear the DO_DEVICE_INITIALIZING flag */ gControllerInfo[i].DriveInfo[j].DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; } } INFO_(FLOPPY, "AddControllers: --------------------------------------------> finished adding controllers\n"); return TRUE; }
void sb16_play(WAVE_HDR* wave) { ULONG MappedIrq; KIRQL Dirql; KAFFINITY Affinity; PKINTERRUPT IrqObject; unsigned int newmask; unsigned int i; unsigned int tmp[255]; i=0; dump_wav(wave); do { // tmp[i++]=get_dma_page(0x0fffff); // DPRINT1("0x%x ",tmp[i-1]); } while((tmp[i-1]&0xffff)!=0); // free_page((tmp[0]),i-1); sb16.buffer=((unsigned char*)tmp[i-1]); /* * Because this is used by alomost every subsystem including irqs it * must be atomic. The following code sequence disables interrupts after * saving the previous state of the interrupt flag */ _disable(); memcpy(sb16.buffer,(&wave->data),wave->dLen); MappedIrq = HalGetInterruptVector(Internal,0,0,8+sb16.irq,&Dirql,&Affinity); IoConnectInterrupt(&IrqObject,DMAOutputISR,0,NULL,MappedIrq,Dirql,Dirql,0,FALSE,Affinity,FALSE); // mask=inb(0x21); newmask=((int)1<<sb16.irq); // outb(0x21,(mask&~newmask)); // Restore the interrupt flag _enable(); // disable_dma(sb16.dma8); //outb(0x0a,5); // clear_dma_ff(1); //outb(0xc,0); // set_dma_count(1,wave->dLen); //set_dma_mode(1,DMA_MODE_WRITE); //outb(0xb,0x49); //outb(0x3,(wave->dLen)&0xff); //outb(0x3,((unsigned int)(wave->dLen)>>8)&0xff); //set_dma_addr(sb16.dma8,(unsigned int)sb16.buffer); //outb(0x83,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>16))&0xf); //outb(0x2,((unsigned int)sb16.buffer&0xff)); //outb(0x2,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>8))&0xff); //enable_dma(sb16.dma8); //outb(0xa,1); write_dsp(sb16.base,0x00D1); write_dsp(sb16.base,0x40); write_dsp(sb16.base,((unsigned char)256-(1000000/wave->nSamplesPerSec))); // outb(sb16.base + 4, (int) 0xa); // outb(sb16.base + 5, (int) 0x00); // outb(sb16.base + 4, (int) 4); // outb(sb16.base + 5, (int) 0xFF); // outb(sb16.base + 4, (int) 0x22); // outb(sb16.base + 5, (int) 0xFF); write_dsp(sb16.base,0x14); write_dsp(sb16.base,(wave->dLen&0x00ff)); write_dsp(sb16.base,((wave->dLen)&0xff00)>>8); // write_dsp(sb16.base,0xc0); // write_dsp(sb16.base,0x0); // OldIRQ=HalGetInterruptVector(Internal,0,0,irq+8,&irql,&affinity); // DPRINT1("OldIRQ: 0x%x\n",OldIRQ); // status=IoConnectInterrupt(&IrqObject,playRoutine,0,NULL,OldIRQ,irql,irql,0,FALSE,affinity,FALSE); // if(status!=STATUS_SUCCESS) DPRINT1("Couldn't set irq\n"); // else DPRINT1("IRQ set\n"); }
NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated) { PFDO_DEVICE_EXTENSION FdoDeviceExtension; PCM_PARTIAL_RESOURCE_DESCRIPTOR resource; DEVICE_DESCRIPTION DeviceDescription; PEHCI_HOST_CONTROLLER hcd; ULONG NumberResources; ULONG iCount; ULONG DeviceAddress; ULONG PropertySize; ULONG BusNumber; NTSTATUS Status; FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; hcd = &FdoDeviceExtension->hcd; /* Sanity Checks */ Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice, DevicePropertyAddress, sizeof(ULONG), &DeviceAddress, &PropertySize); Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice, DevicePropertyBusNumber, sizeof(ULONG), &BusNumber, &PropertySize); /* Get the resources the PNP Manager gave */ NumberResources = translated->Count; DPRINT("NumberResources %d\n", NumberResources); for (iCount = 0; iCount < NumberResources; iCount++) { DPRINT("Resource Info %d:\n", iCount); resource = &translated->PartialDescriptors[iCount]; switch(resource->Type) { case CmResourceTypePort: { DPRINT("Port Start: %x\n", resource->u.Port.Start); DPRINT("Port Length %d\n", resource->u.Port.Length); /* FIXME: Handle Ports */ break; } case CmResourceTypeInterrupt: { DPRINT("Interrupt Vector: %x\n", resource->u.Interrupt.Vector); FdoDeviceExtension->Vector = resource->u.Interrupt.Vector; FdoDeviceExtension->Irql = resource->u.Interrupt.Level; FdoDeviceExtension->Affinity = resource->u.Interrupt.Affinity; FdoDeviceExtension->Mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive; FdoDeviceExtension->IrqShared = resource->ShareDisposition == CmResourceShareShared; break; } case CmResourceTypeMemory: { PVOID ResourceBase = 0; DPRINT("Mem Start: %x\n", resource->u.Memory.Start); DPRINT("Mem Length: %d\n", resource->u.Memory.Length); ResourceBase = MmMapIoSpace(resource->u.Memory.Start, resource->u.Memory.Length, FALSE); DPRINT("ResourceBase %x\n", ResourceBase); if (ResourceBase == NULL) { DPRINT1("MmMapIoSpace failed!!!!!!!!!\n"); } GetCapabilities(&FdoDeviceExtension->hcd.ECHICaps, (ULONG)ResourceBase); DPRINT1("hcd.ECHICaps.Length %x\n", FdoDeviceExtension->hcd.ECHICaps.Length); FdoDeviceExtension->hcd.OpRegisters = (ULONG)((ULONG)ResourceBase + FdoDeviceExtension->hcd.ECHICaps.Length); break; } case CmResourceTypeDma: { DPRINT("Dma Channel: %x\n", resource->u.Dma.Channel); DPRINT("Dma Port: %d\n", resource->u.Dma.Port); break; } case CmResourceTypeDevicePrivate: { /* Windows does this. */ DPRINT1("CmResourceTypeDevicePrivate not handled\n"); break; } default: { DPRINT1("PNP Manager gave resource type not handled!! Notify Developers!\n"); break; } } } for (iCount = 0; iCount < hcd->ECHICaps.HCSParams.PortCount; iCount++) { hcd->Ports[iCount].PortStatus = 0x8000; hcd->Ports[iCount].PortChange = 0; if (hcd->ECHICaps.HCSParams.PortPowerControl) hcd->Ports[iCount].PortStatus |= USB_PORT_STATUS_POWER; } KeInitializeDpc(&FdoDeviceExtension->DpcObject, EhciDefferedRoutine, FdoDeviceExtension); RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION)); DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; DeviceDescription.Master = TRUE; DeviceDescription.ScatterGather = TRUE; DeviceDescription.Dma32BitAddresses = TRUE; DeviceDescription.DmaWidth = 2; DeviceDescription.InterfaceType = PCIBus; DeviceDescription.MaximumLength = EHCI_MAX_SIZE_TRANSFER; hcd->pDmaAdapter = IoGetDmaAdapter(FdoDeviceExtension->LowerDevice, &DeviceDescription, &hcd->MapRegisters); if (hcd->pDmaAdapter == NULL) { DPRINT1("Ehci: IoGetDmaAdapter failed!\n"); ASSERT(FALSE); } DPRINT1("MapRegisters %x\n", hcd->MapRegisters); /* Allocate Common Buffer for Periodic Frame List */ FdoDeviceExtension->PeriodicFrameList.VirtualAddr = hcd->pDmaAdapter->DmaOperations->AllocateCommonBuffer(hcd->pDmaAdapter, sizeof(ULONG) * 1024, &FdoDeviceExtension->PeriodicFrameList.PhysicalAddr, FALSE); if (FdoDeviceExtension->PeriodicFrameList.VirtualAddr == NULL) { DPRINT1("Ehci: FdoDeviceExtension->PeriodicFramList is null\n"); return STATUS_UNSUCCESSFUL; } /* Zeroize it */ RtlZeroMemory(FdoDeviceExtension->PeriodicFrameList.VirtualAddr, sizeof(ULONG) * 1024); ExInitializeFastMutex(&FdoDeviceExtension->FrameListMutex); /* Allocate initial page for queueheads and descriptors */ FdoDeviceExtension->hcd.CommonBufferVA[0] = hcd->pDmaAdapter->DmaOperations->AllocateCommonBuffer(hcd->pDmaAdapter, PAGE_SIZE, &FdoDeviceExtension->hcd.CommonBufferPA[0], FALSE); if (FdoDeviceExtension->hcd.CommonBufferVA[0] == 0) { DPRINT1("Ehci: Failed to allocate common buffer!\n"); return STATUS_UNSUCCESSFUL; } hcd->CommonBufferSize = PAGE_SIZE * 16; /* Zeroize it */ RtlZeroMemory(FdoDeviceExtension->hcd.CommonBufferVA[0], PAGE_SIZE); /* Init SpinLock for host controller device lock */ KeInitializeSpinLock(&hcd->Lock); /* Reserved a Queue Head that will always be in the AsyncList Address Register. By setting it as the Head of Reclamation the controller can know when it has reached the end of the QueueHead list */ hcd->AsyncListQueue = CreateQueueHead(hcd); hcd->AsyncListQueue->HorizontalLinkPointer = hcd->AsyncListQueue->PhysicalAddr | QH_TYPE_QH; hcd->AsyncListQueue->EndPointCharacteristics.QEDTDataToggleControl = FALSE; hcd->AsyncListQueue->Token.Bits.InterruptOnComplete = FALSE; hcd->AsyncListQueue->EndPointCharacteristics.HeadOfReclamation = TRUE; hcd->AsyncListQueue->Token.Bits.Halted = TRUE; hcd->AsyncListQueue->NextQueueHead = hcd->AsyncListQueue; hcd->AsyncListQueue->PreviousQueueHead = hcd->AsyncListQueue; /* Reserve a Queue Head thats only purpose is for linking completed Queue Heads. Completed QueueHeads are moved to this temporary. As the memory must still be valid up until the controllers doorbell is rang to let it know info has been removed from QueueHead list */ hcd->CompletedListQueue = CreateQueueHead(hcd); hcd->CompletedListQueue->NextQueueHead = hcd->CompletedListQueue; hcd->CompletedListQueue->PreviousQueueHead = hcd->CompletedListQueue; /* Ensure the controller is stopped */ StopEhci(hcd); SetAsyncListQueueRegister(hcd, hcd->AsyncListQueue->PhysicalAddr); /* FIXME: Implement Periodic Frame List */ Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt, InterruptService, FdoDeviceExtension->DeviceObject, NULL, FdoDeviceExtension->Vector, FdoDeviceExtension->Irql, FdoDeviceExtension->Irql, FdoDeviceExtension->Mode, FdoDeviceExtension->IrqShared, FdoDeviceExtension->Affinity, FALSE); StartEhci(hcd); FdoDeviceExtension->DeviceState = DEVICESTARTED; return STATUS_SUCCESS; }
NTSTATUS SoundConnectInterrupt( IN ULONG InterruptNumber, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN PKSERVICE_ROUTINE Isr, IN PVOID ServiceContext, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, OUT PKINTERRUPT *Interrupt ) /*++ Routine Description : Connect to an interrupt. From this point on our interrupt service routine can receive interrupts We assume that floating point arithmetic will not be used in the service routine. Arguments : InterruptNumber - the interrupt number we're using BusType - Our bus type BusNumber - the number of our buse (of type BusType) Isr - the interrupt service routine ServiceContext - a value passed to the interrupt service routine InterruptMode - whether it's latched or level sensitive ShareVector - whether the interrupt can be shared Interrupt - Returns the pointer to the interrupt object Return Value : An NTSTATUS return value - STATUS_SUCCESS if OK. --*/ { KAFFINITY Affinity; KIRQL InterruptRequestLevel; ULONG InterruptVector; NTSTATUS Status; // // Call HalGetInterruptVector to get the interrupt vector, // processor affinity and request level to pass to IoConnectInterrupt // InterruptVector = HalGetInterruptVector(BusType, BusNumber, InterruptNumber, InterruptNumber, &InterruptRequestLevel, &Affinity); Status = IoConnectInterrupt( Interrupt, Isr, ServiceContext, (PKSPIN_LOCK)NULL, InterruptVector, InterruptRequestLevel, InterruptRequestLevel, InterruptMode, ShareVector, Affinity, FALSE // No floating point save ); return Status == STATUS_INVALID_PARAMETER ? STATUS_DEVICE_CONFIGURATION_ERROR : Status; }
NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath) #endif { PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension; #ifndef TARGET_NT4 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp); #endif Log(("VBoxGuest::vboxguestwinInit\n")); int rc = STATUS_SUCCESS; #ifdef TARGET_NT4 /* * Let's have a look at what our PCI adapter offers. */ Log(("VBoxGuest::vboxguestwinInit: Starting to scan PCI resources of VBoxGuest ...\n")); /* Assign the PCI resources. */ PCM_RESOURCE_LIST pResourceList = NULL; UNICODE_STRING classNameString; RtlInitUnicodeString(&classNameString, L"VBoxGuestAdapter"); rc = HalAssignSlotResources(pRegPath, &classNameString, pDrvObj, pDevObj, PCIBus, pDevExt->win.s.busNumber, pDevExt->win.s.slotNumber, &pResourceList); if (pResourceList && pResourceList->Count > 0) vboxguestwinShowDeviceResources(&pResourceList->List[0].PartialResourceList); if (NT_SUCCESS(rc)) rc = vboxguestwinScanPCIResourceList(pResourceList, pDevExt); #else if (pStack->Parameters.StartDevice.AllocatedResources->Count > 0) vboxguestwinShowDeviceResources(&pStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList); if (NT_SUCCESS(rc)) rc = vboxguestwinScanPCIResourceList(pStack->Parameters.StartDevice.AllocatedResourcesTranslated, pDevExt); #endif if (NT_SUCCESS(rc)) { /* * Map physical address of VMMDev memory into MMIO region * and init the common device extension bits. */ void *pvMMIOBase = NULL; uint32_t cbMMIO = 0; rc = vboxguestwinMapVMMDevMemory(pDevExt, pDevExt->win.s.vmmDevPhysMemoryAddress, pDevExt->win.s.vmmDevPhysMemoryLength, &pvMMIOBase, &cbMMIO); if (NT_SUCCESS(rc)) { pDevExt->pVMMDevMemory = (VMMDevMemory *)pvMMIOBase; Log(("VBoxGuest::vboxguestwinInit: pvMMIOBase = 0x%p, pDevExt = 0x%p, pDevExt->pVMMDevMemory = 0x%p\n", pvMMIOBase, pDevExt, pDevExt ? pDevExt->pVMMDevMemory : NULL)); int vrc = VBoxGuestInitDevExt(pDevExt, pDevExt->IOPortBase, pvMMIOBase, cbMMIO, vboxguestwinVersionToOSType(g_winVersion), VMMDEV_EVENT_MOUSE_POSITION_CHANGED); if (RT_FAILURE(vrc)) { Log(("VBoxGuest::vboxguestwinInit: Could not init device extension, rc = %Rrc!\n", vrc)); rc = STATUS_DEVICE_CONFIGURATION_ERROR; } } else Log(("VBoxGuest::vboxguestwinInit: Could not map physical address of VMMDev, rc = 0x%x!\n", rc)); } if (NT_SUCCESS(rc)) { int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pDevExt->win.s.pPowerStateRequest, sizeof (VMMDevPowerStateRequest), VMMDevReq_SetPowerStatus); if (RT_FAILURE(vrc)) { Log(("VBoxGuest::vboxguestwinInit: Alloc for pPowerStateRequest failed, rc = %Rrc\n", vrc)); rc = STATUS_UNSUCCESSFUL; } } if (NT_SUCCESS(rc)) { /* * Register DPC and ISR. */ Log(("VBoxGuest::vboxguestwinInit: Initializing DPC/ISR ...\n")); IoInitializeDpcRequest(pDevExt->win.s.pDeviceObject, vboxguestwinDpcHandler); #ifdef TARGET_NT4 ULONG uInterruptVector; KIRQL irqLevel; /* Get an interrupt vector. */ /* Only proceed if the device provides an interrupt. */ if ( pDevExt->win.s.interruptLevel || pDevExt->win.s.interruptVector) { Log(("VBoxGuest::vboxguestwinInit: Getting interrupt vector (HAL): Bus: %u, IRQL: %u, Vector: %u\n", pDevExt->win.s.busNumber, pDevExt->win.s.interruptLevel, pDevExt->win.s.interruptVector)); uInterruptVector = HalGetInterruptVector(PCIBus, pDevExt->win.s.busNumber, pDevExt->win.s.interruptLevel, pDevExt->win.s.interruptVector, &irqLevel, &pDevExt->win.s.interruptAffinity); Log(("VBoxGuest::vboxguestwinInit: HalGetInterruptVector returns vector %u\n", uInterruptVector)); if (uInterruptVector == 0) Log(("VBoxGuest::vboxguestwinInit: No interrupt vector found!\n")); } else Log(("VBoxGuest::vboxguestwinInit: Device does not provide an interrupt!\n")); #endif if (pDevExt->win.s.interruptVector) { Log(("VBoxGuest::vboxguestwinInit: Connecting interrupt ...\n")); rc = IoConnectInterrupt(&pDevExt->win.s.pInterruptObject, /* Out: interrupt object. */ (PKSERVICE_ROUTINE)vboxguestwinIsrHandler, /* Our ISR handler. */ pDevExt, /* Device context. */ NULL, /* Optional spinlock. */ #ifdef TARGET_NT4 uInterruptVector, /* Interrupt vector. */ irqLevel, /* Interrupt level. */ irqLevel, /* Interrupt level. */ #else pDevExt->win.s.interruptVector, /* Interrupt vector. */ (KIRQL)pDevExt->win.s.interruptLevel, /* Interrupt level. */ (KIRQL)pDevExt->win.s.interruptLevel, /* Interrupt level. */ #endif pDevExt->win.s.interruptMode, /* LevelSensitive or Latched. */ TRUE, /* Shareable interrupt. */ pDevExt->win.s.interruptAffinity, /* CPU affinity. */ FALSE); /* Don't save FPU stack. */ if (NT_ERROR(rc)) Log(("VBoxGuest::vboxguestwinInit: Could not connect interrupt, rc = 0x%x\n", rc)); } else Log(("VBoxGuest::vboxguestwinInit: No interrupt vector found!\n")); } #ifdef VBOX_WITH_HGCM Log(("VBoxGuest::vboxguestwinInit: Allocating kernel session data ...\n")); int vrc = VBoxGuestCreateKernelSession(pDevExt, &pDevExt->win.s.pKernelSession); if (RT_FAILURE(vrc)) { Log(("VBoxGuest::vboxguestwinInit: Failed to allocated kernel session data! rc = %Rrc\n", rc)); rc = STATUS_UNSUCCESSFUL; } #endif if (RT_SUCCESS(rc)) { ULONG ulValue = 0; NTSTATUS s = vboxguestwinRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled", &ulValue); if (NT_SUCCESS(s)) { pDevExt->fLoggingEnabled = ulValue >= 0xFF; if (pDevExt->fLoggingEnabled) Log(("Logging to release log enabled (0x%x)", ulValue)); } /* Ready to rumble! */ Log(("VBoxGuest::vboxguestwinInit: Device is ready!\n")); VBOXGUEST_UPDATE_DEVSTATE(pDevExt, WORKING); } else { pDevExt->win.s.pInterruptObject = NULL; } Log(("VBoxGuest::vboxguestwinInit: Returned with rc = 0x%x\n", rc)); return rc; }
VOID SetIpiHandlerRoutine( IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ) /*++ Routine Description CALLBACK This is a deferred routine for DPC, which is delivered for each processor in MP system to initialize IPI support. This routine connects an IPI interrupt handler Arguments Dpc, DeferredContext, SystemArgument1, SystemArgument2 Normal parameters of CustomDpc routine, see CustomDpc,KeInitializeDpc,KeInsertQueueDpc in MSDN. Return Value None --*/ { IDTR Idtr; __asm { sidt fword ptr [Idtr] } ULONG Proc = KeGetCurrentProcessorNumber(); KdPrint(("[%d] IDT = %x\n", Proc, Idtr.Table)); if (DeferredContext == NULL) { NTSTATUS Status; Status = IoConnectInterrupt ( &IntObjs[Proc], IpiService, NULL, NULL, IpiVector, Irql, Irql, Latched, TRUE, Affinity, FALSE ); KdPrint(("[%d] IoConnectInterrupt: %x\n", Proc, Status)); if (!NT_SUCCESS(Status)) IntObjs[Proc] = NULL; } else { if (IntObjs[Proc]) IoDisconnectInterrupt (IntObjs[Proc]); KdPrint(("[%d] Interrupt disconnected\n", Proc)); } }
NTSTATUS InitMyPCI(IN PDEVICE_EXTENSION pdx,IN PCM_PARTIAL_RESOURCE_LIST list) { PDEVICE_OBJECT fdo = pdx->fdo; ULONG vector; KIRQL irql; KINTERRUPT_MODE mode; KAFFINITY affinity; BOOLEAN irqshare; BOOLEAN gotinterrupt = FALSE; PHYSICAL_ADDRESS portbase; BOOLEAN gotport = FALSE; PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = &list->PartialDescriptors[0]; ULONG nres = list->Count; BOOLEAN IsMem0 = TRUE; for (ULONG i = 0; i < nres; ++i, ++resource) { // for each resource switch (resource->Type) { // switch on resource type case CmResourceTypePort: portbase = resource->u.Port.Start; pdx->nports = resource->u.Port.Length; pdx->mappedport = (resource->Flags & CM_RESOURCE_PORT_IO) == 0; gotport = TRUE; break; case CmResourceTypeMemory: if (IsMem0) { pdx->MemBar0 = (PUCHAR)MmMapIoSpace(resource->u.Memory.Start, resource->u.Memory.Length, MmNonCached); pdx->nMem0 = resource->u.Memory.Length; IsMem0 = FALSE; }else { pdx->MemBar1 = (PUCHAR)MmMapIoSpace(resource->u.Memory.Start, resource->u.Memory.Length, MmNonCached); pdx->nMem1 = resource->u.Memory.Length; } break; case CmResourceTypeInterrupt: irql = (KIRQL) resource->u.Interrupt.Level; vector = resource->u.Interrupt.Vector; affinity = resource->u.Interrupt.Affinity; mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive; irqshare = resource->ShareDisposition == CmResourceShareShared; gotinterrupt = TRUE; break; default: KdPrint(("Unexpected I/O resource type %d\n", resource->Type)); break; } // switch on resource type } // for each resource if (!(TRUE&& gotport&& gotinterrupt )) { KdPrint((" Didn't get expected I/O resources\n")); return STATUS_DEVICE_CONFIGURATION_ERROR; } if (pdx->mappedport) { // map port address for RISC platform pdx->portbase = (PUCHAR) MmMapIoSpace(portbase, pdx->nports, MmNonCached); if (!pdx->mappedport) { KdPrint(("Unable to map port range %I64X, length %X\n", portbase, pdx->nports)); return STATUS_INSUFFICIENT_RESOURCES; } } // map port address for RISC platform else pdx->portbase = (PUCHAR) portbase.QuadPart; NTSTATUS status = IoConnectInterrupt(&pdx->InterruptObject, (PKSERVICE_ROUTINE) OnInterrupt, (PVOID) pdx, NULL, vector, irql, irql, LevelSensitive, TRUE, affinity, FALSE); if (!NT_SUCCESS(status)) { KdPrint(("IoConnectInterrupt failed - %X\n", status)); if (pdx->portbase && pdx->mappedport) MmUnmapIoSpace(pdx->portbase, pdx->nports); pdx->portbase = NULL; return status; } #define IMAGE_LENGTH (640*480) //申请一段连续物理地址来读取图像 PHYSICAL_ADDRESS maxAddress; maxAddress.u.LowPart = 0xFFFFFFFF; maxAddress.u.HighPart = 0; pdx->MemForImage = MmAllocateContiguousMemory(IMAGE_LENGTH,maxAddress); PHYSICAL_ADDRESS pycialAddressForImage = MmGetPhysicalAddress(pdx->MemForImage); WRITE_REGISTER_BUFFER_UCHAR((PUCHAR)pdx->MemBar0+0x10000, (PUCHAR)&pycialAddressForImage.u.LowPart,4); return STATUS_SUCCESS; }
/* * @implemented */ NDIS_STATUS EXPORT NdisMRegisterInterrupt( OUT PNDIS_MINIPORT_INTERRUPT Interrupt, IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InterruptVector, IN UINT InterruptLevel, IN BOOLEAN RequestIsr, IN BOOLEAN SharedInterrupt, IN NDIS_INTERRUPT_MODE InterruptMode) /* * FUNCTION: Claims access to an interrupt vector * ARGUMENTS: * Interrupt = Address of interrupt object to initialize * MiniportAdapterHandle = Specifies handle input to MiniportInitialize * InterruptVector = Specifies bus-relative vector to register * InterruptLevel = Specifies bus-relative DIRQL vector for interrupt * RequestIsr = TRUE if MiniportISR should always be called * SharedInterrupt = TRUE if other devices may use the same interrupt * InterruptMode = Specifies type of interrupt * RETURNS: * Status of operation */ { NTSTATUS Status; ULONG MappedIRQ; KIRQL DIrql; KAFFINITY Affinity; PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; NDIS_DbgPrint(MAX_TRACE, ("Called. InterruptVector (0x%X) InterruptLevel (0x%X) " "SharedInterrupt (%d) InterruptMode (0x%X)\n", InterruptVector, InterruptLevel, SharedInterrupt, InterruptMode)); RtlZeroMemory(Interrupt, sizeof(NDIS_MINIPORT_INTERRUPT)); KeInitializeSpinLock(&Interrupt->DpcCountLock); KeInitializeDpc(&Interrupt->InterruptDpc, HandleDeferredProcessing, Adapter); KeInitializeEvent(&Interrupt->DpcsCompletedEvent, NotificationEvent, FALSE); Interrupt->SharedInterrupt = SharedInterrupt; Interrupt->IsrRequested = RequestIsr; Interrupt->Miniport = &Adapter->NdisMiniportBlock; MappedIRQ = HalGetInterruptVector(Adapter->NdisMiniportBlock.BusType, Adapter->NdisMiniportBlock.BusNumber, InterruptLevel, InterruptVector, &DIrql, &Affinity); NDIS_DbgPrint(MAX_TRACE, ("Connecting to interrupt vector (0x%X) Affinity (0x%X).\n", MappedIRQ, Affinity)); Status = IoConnectInterrupt(&Interrupt->InterruptObject, ServiceRoutine, Interrupt, &Interrupt->DpcCountLock, MappedIRQ, DIrql, DIrql, InterruptMode, SharedInterrupt, Affinity, FALSE); NDIS_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status)); if (NT_SUCCESS(Status)) { Adapter->NdisMiniportBlock.Interrupt = Interrupt; Adapter->NdisMiniportBlock.RegisteredInterrupts++; return NDIS_STATUS_SUCCESS; } if (Status == STATUS_INSUFFICIENT_RESOURCES) { /* FIXME: Log error */ NDIS_DbgPrint(MIN_TRACE, ("Resource conflict!\n")); return NDIS_STATUS_RESOURCE_CONFLICT; } NDIS_DbgPrint(MIN_TRACE, ("Function failed. Status (0x%X).\n", Status)); return NDIS_STATUS_FAILURE; }
BOOLEAN NTAPI IntVideoPortSetupInterrupt( IN PDEVICE_OBJECT DeviceObject, IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, IN PVIDEO_PORT_CONFIG_INFO ConfigInfo) { NTSTATUS Status; PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension; /* * MSDN documentation for VIDEO_PORT_CONFIG_INFO states: "If a miniport driver's * HwVidFindAdapter function finds that the video adapter does not generate * interrupts or that it cannot determine a valid interrupt vector/level for * the adapter, HwVidFindAdapter should set both BusInterruptVector and * BusInterruptLevel to zero. */ if (DriverExtension->InitializationData.HwInterrupt != NULL && (ConfigInfo->BusInterruptLevel != 0 || ConfigInfo->BusInterruptVector != 0)) { ULONG InterruptVector; KIRQL Irql; KAFFINITY Affinity; InterruptVector = HalGetInterruptVector( ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, ConfigInfo->BusInterruptLevel, ConfigInfo->BusInterruptVector, &Irql, &Affinity); if (InterruptVector == 0) { WARN_(VIDEOPRT, "HalGetInterruptVector failed\n"); return FALSE; } KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock); Status = IoConnectInterrupt( &DeviceExtension->InterruptObject, IntVideoPortInterruptRoutine, DeviceExtension, &DeviceExtension->InterruptSpinLock, InterruptVector, Irql, Irql, ConfigInfo->InterruptMode, DeviceExtension->InterruptShared, Affinity, FALSE); if (!NT_SUCCESS(Status)) { WARN_(VIDEOPRT, "IoConnectInterrupt failed with status 0x%08x\n", Status); return FALSE; } } return TRUE; }