Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #5
0
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(&parameters->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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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");

}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #11
0
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));
	}
}
Beispiel #12
0
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;	
}
Beispiel #13
0
/*
 * @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;
}
Beispiel #14
0
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;
}