Example #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;
}
Example #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;
}
Example #3
0
VOID
DbgHalInitializeMP(
	)

/*++

Routine Description

	This routine initializes an IPI support in MultiProcessor system

Arguments

	None

Return Value

	None

--*/

{
	if (KeNumberProcessors > MAX_PROCESSORS)
	{
		KdPrint(("Number of processors (%d) is greater that maximum supported number %d\n",
			KeNumberProcessors,
			MAX_PROCESSORS
			));

		ASSERT (FALSE);
	}

	if (KeNumberProcessors > 1)
	{
		KdPrint(("Initializing IPIs for MP system\n"));

		// Get free interrupt vector for IPI service
		IpiVector = HalGetInterruptVector (Internal, 0, 0, 0, &Irql, &Affinity);
		KdPrint(("Allocated vector %x\n", IpiVector));

		// Set IPI handlers
		KdPrint(("Setting up handlers\n"));
		SendEachProcessorDpc (SetIpiHandlerRoutine, NULL, NULL, NULL);
	}
	else
	{
		KdPrint(("DbgHalInitializeMP: nothing to initialize on UP system\n"));
	}
}
Example #4
0
ULONG
NTAPI
HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler,
                      IN PBUS_HANDLER RootHandler,
                      IN ULONG BusInterruptLevel,
                      IN ULONG BusInterruptVector,
                      OUT PKIRQL Irql,
                      OUT PKAFFINITY Affinity)
{
    /* Validate the level first */
    if (BusInterruptLevel < 1) return 0;

    /* PCI has its IRQs on top of ISA IRQs, so pass it on to the ISA handler */
    return HalGetInterruptVector(Isa,
                                 0,
                                 BusInterruptLevel,
                                 0,
                                 Irql,
                                 Affinity);
}
Example #5
0
ULONG
HalpGetPCIIntOnISABus (
    IN PBUS_HANDLER BusHandler,
    IN PBUS_HANDLER RootHandler,
    IN ULONG BusInterruptLevel,
    IN ULONG BusInterruptVector,
    OUT PKIRQL Irql,
    OUT PKAFFINITY Affinity
    )
{
    if (BusInterruptLevel < 1) {
        // bogus bus level
        return 0;
    }


    //
    // Current PCI buses just map their IRQs ontop of the ISA space,
    // so foreward this to the isa handler for the isa vector
    // (the isa vector was saved away at either HalSetBusData or
    // IoAssignReosurces time - if someone is trying to connect a
    // PCI interrupt without performing one of those operations first,
    // they are broken).
    //

    return HalGetInterruptVector (
#ifndef MCA
                Isa, 0,
#else
                MicroChannel, 0,
#endif
                BusInterruptLevel ^ IRQXOR,
                0,
                Irql,
                Affinity
            );
}
Example #6
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;
}
Example #7
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;
}
Example #8
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");

}
Example #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;
}
Example #10
0
NTSTATUS SoundReportResourceUsage(
    IN PDEVICE_OBJECT DeviceObject,
    IN INTERFACE_TYPE BusType,
    IN ULONG BusNumber,
    IN PULONG InterruptNumber OPTIONAL,
    IN KINTERRUPT_MODE InterruptMode,
    IN BOOLEAN InterruptShareDisposition,
    IN PULONG DmaChannel OPTIONAL,
    IN PULONG FirstIoPort OPTIONAL,
    IN ULONG IoPortLength
)
/*++

Routine Description :

    Calls IoReportResourceUsage for the device and resources
    passed in.  NOTE that this supercedes previous resources
    declared for this device.

    It is assumed that all resources owned by the device cannot
    be shared, except for level-sensitive interrupts which can be
    shared.

Arguments :

    DeviceObject - The device which 'owns' the resources
                   This can also be a pointer to a driver object
    BusType      - The type of bus on which the device lives
    BusNumber    - The bus number (of type BusType) where the device is
    InterruptNumber - The interrupt the devices uses (if any)
    DmaChannel   - The DMA channel the device uses
    FirstIoPort  - The start Io port for the device
    IoPortLength - The number of bytes of IO space the device uses
                   (starting at FirstIoPort)

Return Value :

    STATUS_SUCCESS if no problems
    The return from IoReportResourceUsage if this fails
    STATUS_DEVICE_CONFIGURATION_ERROR is IoReportResourceUsage reports
        a conflict

--*/

{
    NTSTATUS Status;

    //
    // Our resource list to report back to the system
    //

    /*

     Compiler rejects this

    UCHAR ResBuffer[FIELD_OFFSET(
                       CM_RESOURCE_LIST,
                       List[0].PartialResourceList.PartialDescriptors[3].Type)];

     */

    UCHAR ResBuffer[3 * sizeof(CM_RESOURCE_LIST)];

    BOOLEAN ResourceConflict;

    PCM_RESOURCE_LIST ResourceList;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;

    ResourceList = (PCM_RESOURCE_LIST)ResBuffer;
    Descriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
    ResourceConflict = FALSE;

    //
    // Zero out any unused data
    //

    RtlZeroMemory(ResBuffer, sizeof(ResBuffer));

    //
    // We assume there's only 1 bus so we only need one list.
    // Fill in the bus description
    //

    ResourceList->Count = 1;
    ResourceList->List[0].InterfaceType = BusType;
    ResourceList->List[0].BusNumber = BusNumber;

    //
    // If the device is using IO Ports add this to the list
    //

    if (ARGUMENT_PRESENT(FirstIoPort)) {
        PHYSICAL_ADDRESS PortAddress;
        ULONG MemType;
        PHYSICAL_ADDRESS MappedAddress;

        PortAddress.LowPart = *FirstIoPort;
        PortAddress.HighPart = 0;
        MemType = 1;

        HalTranslateBusAddress(
                    BusType,
                    BusNumber,
                    PortAddress,
                    &MemType,
                    &MappedAddress);


        ResourceList->List[0].PartialResourceList.Count++;

        Descriptor->Type = CmResourceTypePort;

        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;

        Descriptor->u.Port.Start.LowPart = *FirstIoPort;

        Descriptor->u.Port.Length = IoPortLength;

        Descriptor->Flags = MemType == 0 ? CM_RESOURCE_PORT_MEMORY :
                                           CM_RESOURCE_PORT_IO;

        //
        // Move on to next resource descriptor entry
        //

        Descriptor++;
    }

    //
    // Add interrupt information (if any) to the list
    //

    if (ARGUMENT_PRESENT(InterruptNumber)) {

        KAFFINITY Affinity;
        KIRQL InterruptRequestLevel;
        ULONG InterruptVector;

        //
        // Get the processor affinity and vector
        //


        InterruptVector = HalGetInterruptVector(BusType,
                                                BusNumber,
                                                *InterruptNumber,
                                                *InterruptNumber,
                                                &InterruptRequestLevel,
                                                &Affinity);



        ResourceList->List[0].PartialResourceList.Count++;

        Descriptor->Type = CmResourceTypeInterrupt;

        Descriptor->ShareDisposition = (UCHAR)(InterruptShareDisposition ?
                                               CmResourceShareShared :
                                               CmResourceShareDeviceExclusive);

        Descriptor->Flags =
           InterruptMode == Latched ? CM_RESOURCE_INTERRUPT_LATCHED :
                                      CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;

        Descriptor->u.Interrupt.Level = *InterruptNumber;

        Descriptor->u.Interrupt.Vector = InterruptVector;

        Descriptor->u.Interrupt.Affinity = (ULONG)Affinity;

        //
        // Move on to next resource descriptor entry
        //

        Descriptor++;
    }

    //
    // Add DMA description if any
    //

    if (ARGUMENT_PRESENT(DmaChannel)) {
        ResourceList->List[0].PartialResourceList.Count++;

        Descriptor->Type = CmResourceTypeDma;

        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;

        Descriptor->u.Dma.Channel = *DmaChannel;

        Descriptor->u.Dma.Port = 0;  // ???

        //
        // Move on to next resource descriptor entry
        //

        Descriptor++;
    }

    //
    // Report our resource usage and detect conflicts
    //

    switch (DeviceObject->Type) {
    case IO_TYPE_DEVICE:
        Status = IoReportResourceUsage(NULL,
                                       DeviceObject->DriverObject,
                                       NULL,
                                       0,
                                       DeviceObject,
                                       ResourceList,
                                       (PUCHAR)Descriptor - (PUCHAR)ResourceList,
                                       FALSE,
                                       &ResourceConflict);
        break;
    case IO_TYPE_DRIVER:
        Status = IoReportResourceUsage(NULL,
                                       (PDRIVER_OBJECT)DeviceObject,
                                       ResourceList,
                                       (PUCHAR)Descriptor - (PUCHAR)ResourceList,
                                       NULL,
                                       NULL,
                                       0,
                                       FALSE,
                                       &ResourceConflict);
        break;

    default:
        ASSERTMSG("SoundReportResourceUsage - invalid object", FALSE);
    }

    if (ResourceConflict) {
        dprintf1(("Resource conflict reported"));
        Status = STATUS_DEVICE_CONFIGURATION_ERROR;
    }

    return 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;
}
Example #12
0
static
NTSTATUS
IopTranslateDeviceResources(
   IN PDEVICE_NODE DeviceNode)
{
   PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
   PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
   ULONG i, j, ListSize;
   NTSTATUS Status;

   if (!DeviceNode->ResourceList)
   {
      DeviceNode->ResourceListTranslated = NULL;
      return STATUS_SUCCESS;
   }

   /* That's easy to translate a resource list. Just copy the
    * untranslated one and change few fields in the copy
    */
   ListSize = PnpDetermineResourceListSize(DeviceNode->ResourceList);

   DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize);
   if (!DeviceNode->ResourceListTranslated)
   {
      Status = STATUS_NO_MEMORY;
      goto cleanup;
   }
   RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize);

   for (i = 0; i < DeviceNode->ResourceList->Count; i++)
   {
      pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList;
      for (j = 0; j < pPartialResourceList->Count; j++)
      {
         DescriptorRaw = &pPartialResourceList->PartialDescriptors[j];
         DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j];
         switch (DescriptorRaw->Type)
         {
            case CmResourceTypePort:
            {
               ULONG AddressSpace = 1; /* IO space */
               if (!HalTranslateBusAddress(
                  DeviceNode->ResourceList->List[i].InterfaceType,
                  DeviceNode->ResourceList->List[i].BusNumber,
                  DescriptorRaw->u.Port.Start,
                  &AddressSpace,
                  &DescriptorTranslated->u.Port.Start))
               {
                  Status = STATUS_UNSUCCESSFUL;
                  DPRINT1("Failed to translate port resource (Start: 0x%I64x)\n", DescriptorRaw->u.Port.Start.QuadPart);
                  goto cleanup;
               }
                
               if (AddressSpace == 0)
               {
                   DPRINT1("Guessed incorrect address space: 1 -> 0\n");

                   /* FIXME: I think all other CM_RESOURCE_PORT_XXX flags are 
                    * invalid for this state but I'm not 100% sure */
                   DescriptorRaw->Flags =
                   DescriptorTranslated->Flags = CM_RESOURCE_PORT_MEMORY;
               }
               break;
            }
            case CmResourceTypeInterrupt:
            {
               DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
                  DeviceNode->ResourceList->List[i].InterfaceType,
                  DeviceNode->ResourceList->List[i].BusNumber,
                  DescriptorRaw->u.Interrupt.Level,
                  DescriptorRaw->u.Interrupt.Vector,
                  (PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
                  &DescriptorTranslated->u.Interrupt.Affinity);
                
               if (!DescriptorTranslated->u.Interrupt.Vector)
               {
                   Status = STATUS_UNSUCCESSFUL;
                   DPRINT1("Failed to translate interrupt resource (Vector: 0x%x | Level: 0x%x)\n", DescriptorRaw->u.Interrupt.Vector,
                                                                                                   DescriptorRaw->u.Interrupt.Level);
                   goto cleanup;
               }
               break;
            }
            case CmResourceTypeMemory:
            {
               ULONG AddressSpace = 0; /* Memory space */
               if (!HalTranslateBusAddress(
                  DeviceNode->ResourceList->List[i].InterfaceType,
                  DeviceNode->ResourceList->List[i].BusNumber,
                  DescriptorRaw->u.Memory.Start,
                  &AddressSpace,
                  &DescriptorTranslated->u.Memory.Start))
               {
                  Status = STATUS_UNSUCCESSFUL;
                  DPRINT1("Failed to translate memory resource (Start: 0x%I64x)\n", DescriptorRaw->u.Memory.Start.QuadPart);
                  goto cleanup;
               }

               if (AddressSpace != 0)
               {
                   DPRINT1("Guessed incorrect address space: 0 -> 1\n");

                   /* This should never happen for memory space */
                   ASSERT(FALSE);
               }
            }

            case CmResourceTypeDma:
            case CmResourceTypeBusNumber:
            case CmResourceTypeDeviceSpecific:
               /* Nothing to do */
               break;
            default:
               DPRINT1("Unknown resource descriptor type 0x%x\n", DescriptorRaw->Type);
               Status = STATUS_NOT_IMPLEMENTED;
               goto cleanup;
         }
      }
   }
   return STATUS_SUCCESS;

cleanup:
   /* Yes! Also delete ResourceList because ResourceList and
    * ResourceListTranslated should be a pair! */
   ExFreePool(DeviceNode->ResourceList);
   DeviceNode->ResourceList = NULL;
   if (DeviceNode->ResourceListTranslated)
   {
      ExFreePool(DeviceNode->ResourceListTranslated);
      DeviceNode->ResourceList = NULL;
   }
   return Status;
}
Example #13
0
NTSTATUS
IopIrqTranslateOrdering(
    OUT PIO_RESOURCE_DESCRIPTOR Target,
    IN PIO_RESOURCE_DESCRIPTOR Source
    )

/*

Routine Description:

    This routine is called during arbiter initialization to translate the
    orderings.

Parameters:

    Target - Place to put the translated descriptor

    Source - Descriptor to translate

Return Value:

    Status code

*/

{

    KIRQL level;
    KAFFINITY affinity;

    PAGED_CODE();

    //
    // Copy the source to the target
    //

    *Target = *Source;

    if (Source->Type != CmResourceTypeInterrupt) {
        return STATUS_SUCCESS;
    }

    //
    // Translate the vector
    //


    ARB_PRINT(
        2,
        ("Translating Vector 0x%x-0x%x =>",
        Source->u.Interrupt.MinimumVector,
        Source->u.Interrupt.MaximumVector
        ));

    Target->u.Interrupt.MinimumVector =
        HalGetInterruptVector(Isa,
                              0,
                              Source->u.Interrupt.MinimumVector,
                              Source->u.Interrupt.MinimumVector,
                              &level,
                              &affinity
                              );

    if (affinity == 0) {
        ARB_PRINT(2,("Translation failed\n"));
        *Target = *Source;
        return STATUS_SUCCESS;
    }

    Target->u.Interrupt.MaximumVector =
        HalGetInterruptVector(Isa,
                              0,
                              Source->u.Interrupt.MaximumVector,
                              Source->u.Interrupt.MaximumVector,
                              &level,
                              &affinity
                              );

    if (affinity == 0) {
        ARB_PRINT(2,("Translation failed\n"));
        *Target = *Source;
        return STATUS_SUCCESS;
    }

    ARB_PRINT(
        2,
        ("0x%x-0x%x\n",
        Target->u.Interrupt.MinimumVector,
        Target->u.Interrupt.MaximumVector
        ));


    return STATUS_SUCCESS;
}
Example #14
0
File: io.c Project: GYGit/reactos
/*
 * @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;
}
Example #15
0
NTSTATUS kdi_ConfigCallBack
(
/* INPUT PARAMETERS:  */

    dVoidPtr context,
    PUNICODE_STRING path_name,
    INTERFACE_TYPE bus_type,
    dUDWord bus_number,
    PKEY_VALUE_FULL_INFORMATION *bus_information,
    CONFIGURATION_TYPE controller_type,
    dUDWord controller_number,
    PKEY_VALUE_FULL_INFORMATION *controller_information,
    CONFIGURATION_TYPE peripheral_type,
    dUDWord peripheral_number,
    PKEY_VALUE_FULL_INFORMATION *peripheral_information

/* UPDATE PARAMETERS: */

/* OUTPUT PARAMETERS: */

)
/* COMMENTS: *****************************************************************
 *
 * Routine Description:
 *
 *    This routine is used to acquire all of the configuration
 *    information for each floppy disk controller and the
 *    peripheral driver attached to that controller.
 *
 * Arguments:
 *
 *    context - Pointer to the confuration information we are building
 *                    up.
 *
 *    path_name - unicode registry path.    Not Used.
 *
 *    bus_type - Internal, Isa, ...
 *
 *    bus_number - Which bus if we are on a multibus system.
 *
 *    bus_information - Configuration information about the bus. Not Used.
 *
 *    controller_type - Should always be DiskController.
 *
 *    controller_number - Which controller if there is more than one
 *                                controller in the system.
 *
 *    controller_information - Array of pointers to the three pieces of
 *                                    registry information.
 *
 *    peripheral_type - Should always be FloppyDiskPeripheral.
 *
 *    peripheral_number - Which floppy if this controller is maintaining
 *                                more than one.
 *
 *    peripheral_information - Array of pointers to the three pieces of
 *                                    registry information.
 *
 * Return Value:
 *
 *    STATUS_SUCCESS if everything went ok, or STATUS_INSUFFICIENT_RESOURCES
 *    if it couldn't map the base csr or acquire the adapter object, or
 *    all of the resource information couldn't be acquired.
 *
 * DEFINITIONS: *************************************************************/
{

/* DATA: ********************************************************************/

    /* So we don't have to typecast the context. */
    ConfigDataPtr config = context;

    /* Simple iteration variable. */
    dUDWord i;

    /* This boolean will be used to denote whether we've seen this */
    /* controller before. */
    dBoolean new_controller;

    /* This will be used to denote whether we even have room */
    /* for a new controller. */
    dBoolean out_of_room;

    /* Iteration variable that will end up indexing to where */
    /* the controller information should be placed. */
    dUDWord controller_slot;

    /* Short hand for referencing the particular controller config */
    /* information that we are building up. */
    ConfigControllerDataPtr controller;

#if !MULTI_CONTROLLER
    PCM_FULL_RESOURCE_DESCRIPTOR peripheral_data_ptr = (PCM_FULL_RESOURCE_DESCRIPTOR)
        (((dUBytePtr)peripheral_information[IoQueryDeviceConfigurationData]) +
        peripheral_information[IoQueryDeviceConfigurationData]->DataOffset);
#endif

    /* These three boolean will tell us whether we got all the */
    /* information that we needed. */
    dBoolean found_port = FALSE;
    dBoolean found_interrupt = FALSE;
    dBoolean found_dma = FALSE;

/* CODE: ********************************************************************/

    ASSERT(controller_type == DiskController);
#if !MULTI_CONTROLLER
    ASSERT(peripheral_type == FloppyDiskPeripheral);
#endif

    /* Loop through the "slots" that we have for a new controller. */
    /* Determine if this is a controller that we've already seen, */
    /* or a new controller. */

    out_of_room = dTRUE;
    for (
        controller_slot = 0;
        controller_slot < MAXIMUM_CONTROLLERS_PER_MACHINE;
        controller_slot++
        ) {

        if (config->controller[controller_slot].actual_controller_number == -1) {

            new_controller = dTRUE;
            out_of_room = dFALSE;
            config->controller[controller_slot].actual_controller_number =
            controller_number;
            config->number_of_controllers++;
            break;

        } else if (config->controller[controller_slot].actual_controller_number
                        == (LONG)controller_number) {

            new_controller = dFALSE;
            out_of_room = dFALSE;
            break;

        }

    }

    if (out_of_room) {

        /* Just return and ignore the controller. */

        return STATUS_SUCCESS;

    }

    controller = &config->controller[controller_slot];

    if (new_controller) {

        PCM_FULL_RESOURCE_DESCRIPTOR controller_data =
                (PCM_FULL_RESOURCE_DESCRIPTOR)
                (((dUBytePtr)controller_information[IoQueryDeviceConfigurationData]) +
                controller_information[IoQueryDeviceConfigurationData]->DataOffset);

        /* We have the pointer. Save off the interface type and */
        /* the busnumber for use when we call the Hal and the */
        /* Io System. */

        controller->interface_type = bus_type;
        controller->bus_number = bus_number;
        controller->sharable_vector = dTRUE;
        controller->save_float_state = dFALSE;

        /* We need to get the following information out of the partial */
        /* resource descriptors. */

        /* The irql and vector. */

        /* The dma channel. */

        /* The base address and span covered by the floppy controllers */
        /* registers. */

        /* It is not defined how these appear in the partial resource */
        /* lists, so we will just loop over all of them.    If we find */
        /* something we don't recognize, we drop that information on */
        /* the floor.    When we have finished going through all the */
        /* partial information, we validate that we got the above */
        /* three. */

        kdi_CheckedDump(QIC117INFO,
                        "Q117i: path: %ls\n",
                        (ULONG)path_name->Buffer);
        kdi_CheckedDump(QIC117INFO,
                        "Q117i: adding controller: %08x\n",
                        controller_number);
        kdi_CheckedDump(QIC117INFO,
                        "Q117i: adding controller slot: %08x\n",
                        controller_slot);

        for (
            i = 0;
            i < controller_data->PartialResourceList.Count;
            i++
            ) {

            PCM_PARTIAL_RESOURCE_DESCRIPTOR partial =
                &controller_data->PartialResourceList.PartialDescriptors[i];

            switch (partial->Type) {

                case CmResourceTypePort: {

                    dBoolean in_io_space = !!partial->Flags;
                    found_port = dTRUE;

                    /* Save of the pointer to the partial so */
                    /* that we can later use it to report resources */
                    /* and we can also use this later in the routine */
                    /* to make sure that we got all of our resources. */

                    controller->span_of_controller_address =
                            partial->u.Port.Length;
                    controller->original_base_address =
                            partial->u.Port.Start;
                    controller->controller_base_address =
                            kdi_GetControllerBase(
                                bus_type,
                                bus_number,
                                partial->u.Port.Start,
                                controller->span_of_controller_address,
                                in_io_space,
                                &controller->mapped_address
                                );

                    if (!controller->controller_base_address) {

                            return STATUS_INSUFFICIENT_RESOURCES;

                    }

                    break;
                }
                case CmResourceTypeInterrupt: {

                    found_interrupt = dTRUE;

                    if (partial->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {

                        controller->interrupt_mode = Latched;

                    } else {

                        controller->interrupt_mode = LevelSensitive;

                    }

                    controller->original_irql =  partial->u.Interrupt.Level;
                    controller->original_vector = partial->u.Interrupt.Vector;
                    controller->controller_vector =
                            HalGetInterruptVector(
                                bus_type,
                                bus_number,
                                partial->u.Interrupt.Level,
                                partial->u.Interrupt.Vector,
                                &controller->controller_irql,
                                &controller->processor_mask
                                );

                    break;
                }
                case CmResourceTypeDma: {

                    DEVICE_DESCRIPTION device_desc;

                    RtlZeroMemory(&device_desc,sizeof(device_desc));
                    found_dma = dTRUE;

                    controller->original_dma_channel = partial->u.Dma.Channel;

                    device_desc.Version = DEVICE_DESCRIPTION_VERSION;
                    if (partial->u.Dma.Channel > 3) {
                        device_desc.DmaWidth = Width16Bits;
                    } else {
                        device_desc.DmaWidth = Width8Bits;
                    }
                    device_desc.DemandMode = dTRUE;
                    device_desc.MaximumLength = 32l*1024l;
                    device_desc.AutoInitialize = dFALSE;
                    device_desc.ScatterGather = dFALSE;
                    device_desc.DmaChannel = partial->u.Dma.Channel;
                    device_desc.InterfaceType = bus_type;
                    device_desc.DmaSpeed = TypeA;
                    controller->number_of_map_registers = BYTES_TO_PAGES(32l*1024l);
                    controller->adapter_object =
                            HalGetAdapter(
                                &device_desc,
                                &controller->number_of_map_registers
                                );

                    kdi_CheckedDump(QIC117INFO,
                                    "Q117i: Bus Type = %08x\n",
                                    bus_type);

                    kdi_CheckedDump(QIC117INFO,
                                    "Q117i: Number of map registers = %08x\n",
                                    controller->number_of_map_registers );

                    if (!controller->adapter_object) {

                            return STATUS_INSUFFICIENT_RESOURCES;

                    }

                    break;

                }
                default: {

                    break;

                }

            }

        }

        /* If we didn't get all the information then we return */
        /* insufficient resources. */

        if ((!found_port) ||
            (!found_interrupt) ||
            (!found_dma)) {

            return STATUS_INSUFFICIENT_RESOURCES;

        }
        controller->number_of_tape_drives++;
        controller->ok_to_use_this_controller = dTRUE;

        {
            //
            // Get extra information about the floppy controller
            //

            RTL_QUERY_REGISTRY_TABLE    paramTable[2];
            ULONG apiSupported;
            WCHAR idstr[200];
            UNICODE_STRING str;

            str.Length = 0;
            str.MaximumLength = 200;
            str.Buffer = idstr;

            RtlZeroMemory(&paramTable[0], sizeof(paramTable));

            paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
            paramTable[0].Name = L"APISupported";
            paramTable[0].EntryContext = &str;
            paramTable[0].DefaultType = REG_SZ;
            paramTable[0].DefaultData = L"";
            paramTable[0].DefaultLength = sizeof(WCHAR);


            if (!NT_SUCCESS(RtlQueryRegistryValues(
                RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
                path_name->Buffer, &paramTable[0], NULL, NULL)))
            {
                str.Buffer[0] = 0;
            }

            controller->controller_data.clk_48mhz = FALSE;
            controller->controller_data.floppyEnablerApiSupported = FALSE;

            if (str.Buffer[0] != 0) {
                NTSTATUS ntStatus;
                PFILE_OBJECT file;      // file object is not needed,  but returned by API

                kdi_CheckedDump(QIC117INFO,
                       "Q117i: Got registry setting for EnablerAPI = %ls\n",
                        (ULONG)str.Buffer );

                ntStatus = IoGetDeviceObjectPointer(
                                &str,
                                FILE_READ_ACCESS,
                                &file,
                                &controller->controller_data.apiDeviceObject);

                if (NT_SUCCESS(ntStatus)) {
                    FDC_INFORMATION info;

                    controller->controller_data.floppyEnablerApiSupported = TRUE;

                    //
                    // set the DMA direction to unknown,  thereby forcing a
                    // call to set the direction
                    //
                    controller->controller_data.dmaDirection = 0xff;

                    ntStatus = kdi_FloppyEnabler(
                                    controller->controller_data.apiDeviceObject,
                                    IOCTL_GET_FDC_INFO, &info);

                    //
                    //  We got the info for the FDC,  now check for a 48MHz clock
                    //
                    if (NT_SUCCESS(ntStatus)) {
                        controller->controller_data.clk_48mhz =
                            (info.ClockRatesSupported == FDC_CLOCK_48MHZ);
                    }


                } else {
                    kdi_CheckedDump(QIC117DBGP,
                       "Q117i: Got registry setting for EnablerAPI = %ls but failed to open channel to device\n",
                        (ULONG)str.Buffer );
                }
            }

        }

    }

    kdi_CheckedDump(QIC117INFO,
            "Q117i: Got setting for 48mhz clock setting = %x\n",
            controller->controller_data.clk_48mhz );



    return STATUS_SUCCESS;
}
Example #16
0
File: init.c Project: GYGit/reactos
//*************************************************************************
// InitPICE()
//
//*************************************************************************
BOOLEAN InitPICE(void)
{
    ULONG ulHandleScancode=0,ulHandleKbdEvent=0;
	ARGS Args;
    KIRQL Dirql;
    KAFFINITY Affinity;
	ULONG ulAddr;

    ENTER_FUNC();

	DPRINT((0,"InitPICE(): trace step 0.5\n"));
    KeyboardIRQL = HalGetInterruptVector(Internal,
				     0,
				     0,
				     KEYBOARD_IRQ,
				     &Dirql,
				     &Affinity);
	DPRINT((0,"KeyboardIRQL: %x\n", KeyboardIRQL));

    DPRINT((0,"InitPICE(): trace step 1\n"));
    // enable monochrome passthrough on BX type chipset
    EnablePassThrough();

    DPRINT((0,"InitPICE(): trace step 2\n"));
    // now load all symbol files described in /etc/pice.conf
    if(!LoadSymbolsFromConfig(FALSE))
    {
        DPRINT((0,"InitPICE: LoadSymbolsFromConfig() failed\n"));
        LEAVE_FUNC();
        return FALSE;
    }

    DPRINT((0,"InitPICE(): trace step 3\n"));
    // init the output console
	// this might be one of the following depending setup
	// a) monochrome card
	// b) serial terminal (TODO)
    if(!ConsoleInit())
    {
        DPRINT((0,"InitPICE: ConsoleInit() failed\n"));
        UnloadSymbols();
        LEAVE_FUNC();
        return FALSE;
    }

    DPRINT((0,"InitPICE(): trace step 4\n"));
    // print the initial screen template
    PrintTemplate();
/*
    DPRINT((0,"InitPICE(): trace step 5\n"));
	// ask the user if he wants to abort the debugger load
    if(!CheckLoadAbort())
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (abort by user)\n");
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}
*/

    DPRINT((0,"InitPICE(): trace step 6\n"));
    // load the file /boot/System.map.
    // !!! It must be consistent with the current kernel at all cost!!!
    if(!LoadExports())
    {
		Print(OUTPUT_WINDOW,"pICE: failed to load exports\n");
        Print(OUTPUT_WINDOW,"press any key to continue...\n");
        while(!GetKeyPolled());
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
    }

    DPRINT((0,"InitPICE(): trace step 7\n"));
	ScanExports("_KernelAddressSpace", &ulAddr);
	my_init_mm = (PMADDRESS_SPACE) ulAddr;
	DPRINT((0,"init_mm %x @ %x\n",&my_init_mm,my_init_mm));
	if(!my_init_mm)
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (initial memory map not found)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
		DbgPrint("pICE: ABORT (initial memory map not found)\n");
		DbgPrint("pICE: press any key to continue...\n");
        while(!GetKeyPolled());
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}

	DPRINT((0,"InitPICE(): trace step 7.1\n"));
	ScanExports("_ModuleListHead",&ulAddr);
	pModuleListHead = (LIST_ENTRY*)ulAddr;
    DPRINT((0,"pModuleListHead @ %X\n",pModuleListHead));
	if(!pModuleListHead)
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (pModuleListHead not found)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
        while(!GetKeyPolled());
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}

	DPRINT((0,"InitPICE(): trace step 7.2\n"));
	ScanExports("_PsProcessListHead",&ulAddr);
	pPsProcessListHead = (LIST_ENTRY*)ulAddr;
    DPRINT((0,"pPsProcessListHead @ %X\n",pPsProcessListHead));
	if(!pPsProcessListHead)
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (PsProcessListHead not found)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
        while(!GetKeyPolled());
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}

    DPRINT((0,"InitPICE(): trace step 8\n"));
    // end of the kernel
	/*
	ScanExports("_end",(PULONG)&kernel_end);
    if(!kernel_end)
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (kernel size is unknown)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
        while(!GetKeyPolled());
		UnloadExports();
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}
	*/

    DPRINT((0,"InitPICE(): trace step 9\n"));

	// the loaded module list
	ScanExports("_NameSpaceRoot", &ulAddr);
	pNameSpaceRoot = (PDIRECTORY_OBJECT *)ulAddr;
	DPRINT((0,"pNameSpaceRoot @ %X\n",pNameSpaceRoot));
    if(!pNameSpaceRoot)
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (couldn't retreive name space root)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
        while(!GetKeyPolled());
		UnloadExports();
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}

    DPRINT((0,"InitPICE(): trace step 10\n"));
    // setup a linked list for use in module parsing routines.
	if(!InitModuleList(&pdebug_module_head, 100))
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (couldn't initialize kernel module list)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
		FreeModuleList( pdebug_module_head );
        while(!GetKeyPolled());
		UnloadExports();
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}
	pdebug_module_tail = pdebug_module_head;

    DPRINT((0,"InitPICE(): trace step 11\n"));
    // do a sanity check on exports
    if(!SanityCheckExports())
    {
		Print(OUTPUT_WINDOW,"pICE: ABORT (exports are conflicting with kernel symbols)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
        while(!GetKeyPolled());
		UnloadExports();
        UnloadSymbols();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
    }

    DPRINT((0,"InitPICE(): trace step 12\n"));


    DPRINT((0,"InitPICE(): trace step 13\n"));
    // patch the keyboard driver

	if(!PatchKeyboardDriver())
	{
		Print(OUTPUT_WINDOW,"pICE: ABORT (couldn't patch keyboard driver)\n");
		Print(OUTPUT_WINDOW,"pICE: press any key to continue...\n");
        while(!GetKeyPolled());
		UnloadSymbols();
		UnloadExports();
		ConsoleShutdown();
        LEAVE_FUNC();
		return FALSE;
	}

    DPRINT((0,"InitPICE(): trace step 14\n"));
    // partial init of shadow registers
    CurrentCS = GLOBAL_CODE_SEGMENT;
    CurrentEIP = (ULONG)RealIsr;

    CurrentDS = CurrentSS = GLOBAL_DATA_SEGMENT;
    __asm__("\n\t \
            mov %%esp,%%eax\n\t \
            mov %%eax,_CurrentESP\n\t \
            ":::"eax");


    // display version and symbol information
    Ver(NULL);

    // disable HW breakpoints
	__asm__("\n\t \
		xorl %%eax,%%eax\n\t \
		mov %%eax,%%dr6\n\t \
		mov %%eax,%%dr7\n\t \
        mov %%dr0,%%eax\n\t \
        mov %%dr1,%%eax\n\t \
        mov %%dr2,%%eax\n\t \
        mov %%dr3,%%eax"
		:::"eax"
		);

    DPRINT((0,"InitPICE(): trace step 15\n"));
    TakeIdtSnapshot();

    DPRINT((0,"InitPICE(): trace step 16\n"));
    // install all hooks
    InstallTraceHook();
    InstallGlobalKeyboardHook();
    InstallSyscallHook();
    InstallInt3Hook();
    InstallDblFltHook();
    InstallGPFaultHook();
    InstallIntEHook();
    InstallPrintkHook();

    DPRINT((0,"InitPICE(): trace step 16\n"));
    if(ulDoInitialBreak)
    {
        DPRINT((0,"about to do initial break...\n"));

        // simulate an initial break
        __asm__("\n\t \
            pushfl\n\t \
            pushl %cs\n\t \
            pushl $initialreturnpoint\n\t \
            pushl $" STR(REASON_CTRLF) "\n\t \
            jmp NewInt31Handler\n\t \
initialreturnpoint:");
    }
    else
    {
Example #17
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;
}