Ejemplo n.º 1
0
PUCHAR
SoundMapPortAddress(
    INTERFACE_TYPE BusType,
    ULONG BusNumber,
    ULONG PortBase,
    ULONG Length,
    PULONG MemType
)
/*++

Routine Description :

    Map a physical device port address to an address we can pass
    to READ/WRITE_PORT_UCHAR/USHORT etc

Arguments :
    BusType - type of bus
    BusNumber - bus number
    PortBase - The port start address
    Length - how many bytes of port space to map (needed by MmMapIoSpace)

Return Value :

    The virtual port address

--*/
{
    PHYSICAL_ADDRESS PortAddress;
    PHYSICAL_ADDRESS MappedAddress;

    *MemType = 1;                 // IO space
    PortAddress.LowPart = PortBase;
    PortAddress.HighPart = 0;
    HalTranslateBusAddress(
                BusType,
                BusNumber,
                PortAddress,
                MemType,
                &MappedAddress);

    if (*MemType == 0) {
        //
        // Map memory type IO space into our address space
        //
        return (PUCHAR)MmMapIoSpace(MappedAddress, Length, FALSE);
    } else {
        return (PUCHAR)MappedAddress.LowPart;
    }
}
Ejemplo n.º 2
0
Archivo: isa.c Proyecto: RPG-7/reactos
BOOLEAN NTAPI
HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
			   ULONG BusNumber,
			   PHYSICAL_ADDRESS BusAddress,
			   PULONG AddressSpace,
			   PPHYSICAL_ADDRESS TranslatedAddress)
{
   BOOLEAN Result;

   Result = HalTranslateBusAddress(PCIBus,
				   BusNumber,
				   BusAddress,
				   AddressSpace,
				   TranslatedAddress);
   if (Result != FALSE)
     return Result;

   Result = HalTranslateBusAddress(Internal,
				   BusNumber,
				   BusAddress,
				   AddressSpace,
				   TranslatedAddress);
   return Result;
}
Ejemplo n.º 3
0
Archivo: io.c Proyecto: GYGit/reactos
/*
 * @implemented
 */
NDIS_STATUS
EXPORT
NdisMMapIoSpace(
    OUT PVOID                   *VirtualAddress,
    IN  NDIS_HANDLE             MiniportAdapterHandle,
    IN  NDIS_PHYSICAL_ADDRESS   PhysicalAddress,
    IN  UINT                    Length)
/*
 * FUNCTION: Maps a bus-relative address to a system-wide virtual address
 * ARGUMENTS:
 *     VirtualAddress: receives virtual address of mapping
 *     MiniportAdapterHandle: Handle originally input to MiniportInitialize
 *     PhysicalAddress: bus-relative address to map
 *     Length: Number of bytes to map
 * RETURNS:
 *     NDIS_STATUS_SUCCESS: the operation completed successfully
 *     NDIS_STATUS_RESOURCE_CONFLICT: the physical address range is already claimed
 *     NDIS_STATUS_RESOURCES: insufficient resources to complete the mapping
 *     NDIS_STATUS_FAILURE: a general failure has occured
 * NOTES:
 *     - Must be called at IRQL = PASSIVE_LEVEL
 */
{
  PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle;
  ULONG AddressSpace = 0; /* Memory Space */
  NDIS_PHYSICAL_ADDRESS TranslatedAddress;

  PAGED_CODE();
  ASSERT(VirtualAddress && MiniportAdapterHandle);

  NDIS_DbgPrint(MAX_TRACE, ("Called\n"));

  if(!HalTranslateBusAddress(Adapter->NdisMiniportBlock.BusType, Adapter->NdisMiniportBlock.BusNumber,
                             PhysicalAddress, &AddressSpace, &TranslatedAddress))
  {
      NDIS_DbgPrint(MIN_TRACE, ("Unable to translate address\n"));
      return NDIS_STATUS_RESOURCES;
  }

  *VirtualAddress = MmMapIoSpace(TranslatedAddress, Length, MmNonCached);

  if(!*VirtualAddress) {
    NDIS_DbgPrint(MIN_TRACE, ("MmMapIoSpace failed\n"));
    return NDIS_STATUS_RESOURCES;
  }

  return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 4
0
Archivo: io.c Proyecto: GYGit/reactos
/*
 * @implemented
 */
VOID
EXPORT
NdisMDeregisterIoPortRange(IN  NDIS_HANDLE MiniportAdapterHandle,
                           IN  UINT        InitialPort,
                           IN  UINT        NumberOfPorts,
                           IN  PVOID       PortOffset)
/*
 * FUNCTION: Releases a register mapping to I/O ports
 * ARGUMENTS:
 *     MiniportAdapterHandle = Specifies handle input to MiniportInitialize
 *     InitialPort           = Bus-relative base port address of a range to be mapped
 *     NumberOfPorts         = Specifies number of ports to be mapped
 *     PortOffset            = Pointer to mapped base port address
 */
{
    PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
    PHYSICAL_ADDRESS PortAddress = RtlConvertUlongToLargeInteger(InitialPort);
    PHYSICAL_ADDRESS TranslatedAddress;
    ULONG AddressSpace = 1;

    NDIS_DbgPrint(MAX_TRACE, ("Called - InitialPort 0x%x, NumberOfPorts 0x%x, Port Offset 0x%x\n", InitialPort, NumberOfPorts, PortOffset));

    /* Translate the initial port again to find the address space of the translated address */
    if(!HalTranslateBusAddress(Adapter->NdisMiniportBlock.BusType, Adapter->NdisMiniportBlock.BusNumber,
                               PortAddress, &AddressSpace, &TranslatedAddress))
    {
        NDIS_DbgPrint(MIN_TRACE, ("Unable to translate address\n"));
        return;
    }

    /* Make sure we got the same translation as last time */
    ASSERT(TranslatedAddress.QuadPart == (ULONG_PTR)PortOffset);

    /* Check if we're in memory space */
    if (!AddressSpace)
    {
        NDIS_DbgPrint(MAX_TRACE, ("Calling MmUnmapIoSpace\n"));

        /* Unmap the memory */
        MmUnmapIoSpace(PortOffset, NumberOfPorts);
    }
}
Ejemplo n.º 5
0
NTSTATUS
AnajoystMapDevice(
    DWORD PortBase,
    DWORD NumberOfPorts,
    PJOY_EXTENSION pJoyExtension
)
{
    DWORD MemType;
    PHYSICAL_ADDRESS PortAddress;
    PHYSICAL_ADDRESS MappedAddress;


    MemType = 1;                 // IO space
    PortAddress.LowPart = PortBase;
    PortAddress.HighPart = 0;


    HalTranslateBusAddress(
        Isa,
        0,
        PortAddress,
        &MemType,
        &MappedAddress);

    if (MemType == 0) {
        //
        // Map memory type IO space into our address space
        //
        pJoyExtension->DeviceAddress = (PUCHAR) MmMapIoSpace(MappedAddress,
                                       NumberOfPorts,
                                       FALSE);
    }
    else
    {
        pJoyExtension->DeviceAddress  = (PUCHAR) MappedAddress.LowPart;
    }

    return STATUS_SUCCESS;

}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
PVOID
PipGetMappedAddress(
    IN  INTERFACE_TYPE BusType,
    IN  ULONG BusNumber,
    IN  PHYSICAL_ADDRESS IoAddress,
    IN  ULONG NumberOfBytes,
    IN  ULONG AddressSpace,
    OUT PBOOLEAN MappedAddress
    )

/*++

Routine Description:

    This routine maps an IO address to system address space.

Arguments:

    BusType - Supplies the type of bus - eisa, mca, isa...

    IoBusNumber - Supplies the bus number.

    IoAddress - Supplies the base device address to be mapped.

    NumberOfBytes - Supplies the number of bytes for which the address is
                    valid.

    AddressSpace - Supplies whether the address is in io space or memory.

    MappedAddress - Supplies whether the address was mapped. This only has
                      meaning if the address returned is non-null.

Return Value:

    The mapped address.

--*/

{
    PHYSICAL_ADDRESS cardAddress;
    PVOID address;

    HalTranslateBusAddress(BusType, BusNumber, IoAddress, &AddressSpace,
                           &cardAddress);

    //
    // Map the device base address into the virtual address space
    // if the address is in memory space.
    //

    if (!AddressSpace) {

        address = MmMapIoSpace(cardAddress, NumberOfBytes, FALSE);
        *MappedAddress = (address ? TRUE : FALSE);

    } else {

        address = (PVOID) cardAddress.LowPart;
        *MappedAddress = FALSE;
    }

    return address;
}
Ejemplo n.º 8
0
BOOLEAN
HalHandleNMI(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext
    )
/*++

Routine Description:

   This function is called when an EISA NMI occurs.  It prints the 
   appropriate status information and bugchecks.

Arguments:

   Interrupt - Supplies a pointer to the interrupt object

   ServiceContext - Bug number to call bugcheck with.

Return Value:

   Returns TRUE.

--*/
{
    UCHAR   StatusByte;
    UCHAR   EisaPort;
    ULONG   port;
    ULONG   AddressSpace = 1; // 1 = I/O address space
    BOOLEAN Status;
    PHYSICAL_ADDRESS BusAddress;
    PHYSICAL_ADDRESS TranslatedAddress;
    UCHAR Datum;
    
    NMIcount++;

    //
    // Set the Eisa NMI disable bit. We do this to mask further NMI 
    // interrupts while we're servicing this one.
    //
    Datum = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&Datum))->NmiDisable = 1;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, Datum);
#ifdef HALDBG
    DbgPrint("HalpIntializeNMI: wrote 0x%x to NmiEnable\n\r", Datum);
#endif

    StatusByte =
        READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);

    if (StatusByte & 0x80) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Parity Check / Parity Error\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
#else
        //
        // jwlfix - For the present, we're commenting out an NMI parity
        //          error bugcheck, until investigation into its causes
        //          yields a better solution.
        //
        //    HalDisplayString ("NMI: Parity Check / Parity Error\n");
        //    KeBugCheck(NMI_HARDWARE_FAILURE);
        //    return (TRUE);
#endif
    }

    Datum = READ_REGISTER_UCHAR((PUCHAR)HalpServerControlQva );
    if (((PMIKASA_SRV)(&Datum))->HaltIncoming == 0 ||
        ((PMIKASA_SRV)(&Datum))->TempFail == 1     ||
        ((PMIKASA_SRV)(&Datum))->Fan1Fault == 0    ||
        ((PMIKASA_SRV)(&Datum))->Fan2Fault == 0) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Server management NMI\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
        DbgPrint("HalHandleNMI:    Server Management Byte = 0x%x\r\n", Datum);
#else
        //
        // jwlfix - All the above conditions are for handling server 
        //          management features.  Implementing more than simple 
        //          dismissal waits upon definition of desired behavior 
        //          by platform designers or Microsoft Windows NT 
        //          requirements for server behavior.
#endif
    }

    if (StatusByte & 0x40) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Channel Check / IOCHK\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
#else
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
#endif
    }

#if 0
     // jwlfix - This code can be added in later, as we have need
     //          for it.  It's good to have it here, for when it
     //          might be of use.
     //
     // This is an Eisa machine, check for extnded nmi information...
     //

     StatusByte = READ_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl);

     if (StatusByte & 0x80) {
         HalDisplayString ("NMI: Fail-safe timer\n");
     }

     if (StatusByte & 0x40) {
         HalDisplayString ("NMI: Bus Timeout\n");
     }

     if (StatusByte & 0x20) {
         HalDisplayString ("NMI: Software NMI generated\n");
     }

     //
     // Look for any Eisa expansion board.  See if it asserted NMI.
     //
     // jwlfix - The following doesn't work, at this moment; it's 
     //          likey the 12-bit shift, which should be a 5-bit 
     //          shift on Mikasa.
     //

     BusAddress.HighPart = 0;

     for (EisaPort = 0; EisaPort <= 0xf; EisaPort++)
     {
         BusAddress.LowPart = (EisaPort << 12) + 0xC80;

         Status = HalTranslateBusAddress(Eisa,  // InterfaceType
                                         0,     // BusNumber
                                         BusAddress,
                                         &AddressSpace,  // 1=I/O address space
                                         &TranslatedAddress); // QVA
         if (Status == FALSE)
         {
             UCHAR pbuf[80];
             sprintf(pbuf,
                     "Unable to translate bus address %x for EISA slot %d\n",
                     BusAddress.LowPart, EisaPort);
             HalDisplayString(pbuf);
             KeBugCheck(NMI_HARDWARE_FAILURE);
         }

         port = TranslatedAddress.LowPart;

         WRITE_PORT_UCHAR ((PUCHAR) port, 0xff);
         StatusByte = READ_PORT_UCHAR ((PUCHAR) port);

         if ((StatusByte & 0x80) == 0) {
             //
             // Found valid Eisa board,  Check to see if its
             // IOCHKERR is asserted.
             //

             StatusByte = READ_PORT_UCHAR ((PUCHAR) port+4);
             if (StatusByte & 0x2) {
                 EisaNMIMsg[25] = (EisaPort > 9 ? 'A'-10 : '0') + EisaPort;
                 HalDisplayString (EisaNMIMsg);
                 KeBugCheck(NMI_HARDWARE_FAILURE);
             }
         }
     }
#ifdef HALDBG
    // Reset extended NMI interrupts (for debugging purposes only).
    WRITE_PORT_UCHAR(
      &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl, 0x00);
    WRITE_PORT_UCHAR(
      &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl, 0x02);
#endif
#endif

#ifdef HALDBG
    DbgPrint("HalHandleNMI: Resetting PERR#; NMI count = %d\r\n", NMIcount);
#endif

    //
    // Reset PERR# and disable it.
    //
    WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x04);

    //
    //   now enable it again.
    //
    WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);

    //
    // Clear the Eisa NMI disable bit. This re-enables NMI interrupts,
    // now that we're done servicing this one.
    //
    Datum = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&Datum))->NmiDisable = 0;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, Datum);
#ifdef HALDBG
    DbgPrint("HalpIntializeNMI: wrote 0x%x to NmiEnable\n\r", Datum);
#endif

    return(TRUE);
}
Ejemplo n.º 9
0
VOID
NdisMDeregisterIoPortRange(
	IN	NDIS_HANDLE				MiniportAdapterHandle,
	IN	UINT					InitialPort,
	IN	UINT					NumberOfPorts,
	IN	PVOID					PortOffset
	)

/*++

Routine Description:

	Sets up an IO port for operations.

Arguments:

	MiniportAdapterHandle - Handle passed to Miniport Initialize.

	InitialPort - Physical address of the starting port number.

	NumberOfPorts - Number of ports to map.

	PortOffset - The mapped port address the Miniport uses for NdisRaw functions.

Return Value:

	None.

--*/
{
	PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)(MiniportAdapterHandle);
	PHYSICAL_ADDRESS PortAddress;
	PHYSICAL_ADDRESS InitialPortAddress;
	ULONG addressSpace;
	CM_PARTIAL_RESOURCE_DESCRIPTOR	Resource;
	NDIS_STATUS	Status;

	//
	// Get the system physical address for this card.  The card uses
	// I/O space, except for "internal" Jazz devices which use
	// memory space.
	//
	addressSpace = (Miniport->AdapterType == NdisInterfaceInternal) ? 0 : 1;

	InitialPortAddress.LowPart = InitialPort;
	InitialPortAddress.HighPart = 0;

	HalTranslateBusAddress(Miniport->BusType,		// InterfaceType
						   Miniport->BusNumber,		// BusNumber
                           InitialPortAddress,		// Bus Address
						   &addressSpace,			// AddressSpace
						   &PortAddress);			// Translated address
	if (addressSpace == 0)
	{
		//
		// memory space
		//
		MmUnmapIoSpace(PortOffset, NumberOfPorts);
	}

	//
	//	Build the resource to remove.
	//
	Resource.Type = CmResourceTypePort;
	Resource.ShareDisposition = CmResourceShareDeviceExclusive;
	Resource.Flags = (Miniport->AdapterType == NdisInterfaceInternal) ?
						CM_RESOURCE_PORT_MEMORY : CM_RESOURCE_PORT_IO;
	Resource.u.Port.Start.QuadPart = InitialPort;
	Resource.u.Port.Length = NumberOfPorts;

	//
	//	Remove the resource.
	//
	Status = ndisRemoveResource(
				&Miniport->Resources,
				&Resource,
				Miniport->DriverHandle->NdisDriverInfo->NdisWrapperDriver,
				Miniport->DeviceObject,
				&Miniport->MiniportName);

	if (Status != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT(DBG_COMP_UNLOAD, DBG_LEVEL_INFO,
			("NdisMDeregisterIoPortRange failed to remove the resource\n"));
	}
}
Ejemplo n.º 10
0
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,
                                        ULONG PhysMemSizeInBytes,
                                        PVOID *ppPhysMemLin,
                                        HANDLE *pPhysicalMemoryHandle)
{
  UNICODE_STRING     PhysicalMemoryUnicodeString;
  PVOID              PhysicalMemorySection = NULL;
  OBJECT_ATTRIBUTES  ObjectAttributes;
  PHYSICAL_ADDRESS   ViewBase;
  NTSTATUS           ntStatus;
  PHYSICAL_ADDRESS   pStartPhysAddress;
  PHYSICAL_ADDRESS   pEndPhysAddress;
  PHYSICAL_ADDRESS   MappingLength;
  BOOLEAN            Result1, Result2;
  ULONG              IsIOSpace;
  unsigned char     *pbPhysMemLin = NULL;

  OutputDebugString ("Entering MapPhysicalMemoryToLinearSpace");

  RtlInitUnicodeString (&PhysicalMemoryUnicodeString,
                        L"\\Device\\PhysicalMemory");

  InitializeObjectAttributes (&ObjectAttributes,
                              &PhysicalMemoryUnicodeString,
                              OBJ_CASE_INSENSITIVE,
                              (HANDLE) NULL,
                              (PSECURITY_DESCRIPTOR) NULL);

  *pPhysicalMemoryHandle = NULL;

  ntStatus = ZwOpenSection (pPhysicalMemoryHandle,
                            SECTION_ALL_ACCESS,
                            &ObjectAttributes);

  if (NT_SUCCESS(ntStatus))
  {

    ntStatus = ObReferenceObjectByHandle (*pPhysicalMemoryHandle,
                                          SECTION_ALL_ACCESS,
                                          (POBJECT_TYPE) NULL,
                                          KernelMode,
                                          &PhysicalMemorySection,
                                          (POBJECT_HANDLE_INFORMATION) NULL);

    if (NT_SUCCESS(ntStatus))
    {

      pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress;

      pEndPhysAddress = RtlLargeIntegerAdd (pStartPhysAddress,
                                            RtlConvertUlongToLargeInteger(PhysMemSizeInBytes));

      IsIOSpace = 0;

      Result1 = HalTranslateBusAddress (1, 0, pStartPhysAddress, &IsIOSpace, &pStartPhysAddress);

      IsIOSpace = 0;

      Result2 = HalTranslateBusAddress (1, 0, pEndPhysAddress, &IsIOSpace, &pEndPhysAddress);

      if (Result1 && Result2)
      {

        MappingLength = RtlLargeIntegerSubtract (pEndPhysAddress, pStartPhysAddress);

        if (MappingLength.LowPart)
        {
        
          // Let ZwMapViewOfSection pick a linear address

          PhysMemSizeInBytes = MappingLength.LowPart;

          ViewBase = pStartPhysAddress;

          ntStatus = ZwMapViewOfSection (*pPhysicalMemoryHandle,
                                         (HANDLE) -1,
                                         &pbPhysMemLin,
                                         0L,
                                         PhysMemSizeInBytes,
                                         &ViewBase,
                                         &PhysMemSizeInBytes,
                                         ViewShare,
                                         0,
                                         PAGE_READWRITE | PAGE_NOCACHE);

          if (!NT_SUCCESS(ntStatus))
            OutputDebugString ("ERROR: ZwMapViewOfSection failed");
          else
          {
            pbPhysMemLin += (ULONG)pStartPhysAddress.LowPart - (ULONG)ViewBase.LowPart;
            *ppPhysMemLin = pbPhysMemLin;
          }  
        }
        else
          OutputDebugString ("ERROR: RtlLargeIntegerSubtract failed");
      }
      else
        OutputDebugString ("ERROR: MappingLength = 0");
    }
    else
      OutputDebugString ("ERROR: ObReferenceObjectByHandle failed");
  }
  else
    OutputDebugString ("ERROR: ZwOpenSection failed");
    
  if (!NT_SUCCESS(ntStatus))
    ZwClose(*pPhysicalMemoryHandle);
  
  OutputDebugString ("Leaving MapPhysicalMemoryToLinearSpace");

  return ntStatus;
}
Ejemplo n.º 11
0
Archivo: io.c Proyecto: GYGit/reactos
/*
 * @implemented
 */
NDIS_STATUS
EXPORT
NdisMRegisterIoPortRange(
    OUT PVOID       *PortOffset,
    IN  NDIS_HANDLE MiniportAdapterHandle,
    IN  UINT        InitialPort,
    IN  UINT        NumberOfPorts)
/*
 * FUNCTION: Sets up driver access to device I/O ports
 * ARGUMENTS:
 *     PortOffset            = Address of buffer to place mapped base port address
 *     MiniportAdapterHandle = Specifies handle input to MiniportInitialize
 *     InitialPort           = Bus-relative base port address of a range to be mapped
 *     NumberOfPorts         = Specifies number of ports to be mapped
 * RETURNS:
 *     Status of operation
 */
{
  PHYSICAL_ADDRESS     PortAddress, TranslatedAddress;
  PLOGICAL_ADAPTER Adapter  = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
  ULONG                AddressSpace = 1;    /* FIXME The HAL handles this wrong atm */

  *PortOffset = 0;

  NDIS_DbgPrint(MAX_TRACE, ("Called - InitialPort 0x%x, NumberOfPorts 0x%x\n", InitialPort, NumberOfPorts));

  memset(&PortAddress, 0, sizeof(PortAddress));

  /*
   * FIXME: NDIS 5+ completely ignores the InitialPort parameter, but
   * we don't have a way to get the I/O base address yet (see
   * NDIS_MINIPORT_BLOCK->AllocatedResources and
   * NDIS_MINIPORT_BLOCK->AllocatedResourcesTranslated).
   */
  if(InitialPort)
      PortAddress = RtlConvertUlongToLargeInteger(InitialPort);
  else
      ASSERT(FALSE);

  NDIS_DbgPrint(MAX_TRACE, ("Translating address 0x%x 0x%x\n", PortAddress.u.HighPart, PortAddress.u.LowPart));

  if(!HalTranslateBusAddress(Adapter->NdisMiniportBlock.BusType, Adapter->NdisMiniportBlock.BusNumber,
                             PortAddress, &AddressSpace, &TranslatedAddress))
    {
      NDIS_DbgPrint(MIN_TRACE, ("Unable to translate address\n"));
      return NDIS_STATUS_RESOURCES;
    }

  NDIS_DbgPrint(MAX_TRACE, ("Hal returned AddressSpace=0x%x TranslatedAddress=0x%x 0x%x\n",
                            AddressSpace, TranslatedAddress.u.HighPart, TranslatedAddress.u.LowPart));

  if(AddressSpace)
    {
      ASSERT(TranslatedAddress.u.HighPart == 0);
      *PortOffset = (PVOID)(ULONG_PTR)TranslatedAddress.QuadPart;
      NDIS_DbgPrint(MAX_TRACE, ("Returning 0x%x\n", *PortOffset));
      return NDIS_STATUS_SUCCESS;
    }

  NDIS_DbgPrint(MAX_TRACE, ("calling MmMapIoSpace\n"));

  *PortOffset = MmMapIoSpace(TranslatedAddress, NumberOfPorts, MmNonCached);
  NDIS_DbgPrint(MAX_TRACE, ("Returning 0x%x for port range\n", *PortOffset));

  if(!*PortOffset) {
    NDIS_DbgPrint(MIN_TRACE, ("MmMapIoSpace failed\n"));
    return NDIS_STATUS_RESOURCES;
  }

  return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 12
0
VOID
KdpWriteIoSpaceExtended (
    IN PDBGKD_MANIPULATE_STATE64 m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a read io space extended state
    manipulation message.  Its function is to read system io
    locations.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_WRITE_IO_EXTENDED64 a = &m->u.ReadWriteIoExtended;
    ULONG Length;
    STRING MessageHeader;
    PUCHAR b;
    PUSHORT s;
    PULONG l;
    ULONG BusNumber;
    ULONG AddressSpace;
    ULONG SavedAddressSpace;
    PHYSICAL_ADDRESS IoAddress;
    ULONG DataSize;
    PHYSICAL_ADDRESS TranslatedAddress;
    INTERFACE_TYPE InterfaceType;
    ULONG Value;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    ASSERT(AdditionalData->Length == 0);

    m->ReturnStatus = STATUS_SUCCESS;

    InterfaceType = a->InterfaceType;
    BusNumber = a->BusNumber;
    AddressSpace = SavedAddressSpace = a->AddressSpace;
    IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    DataSize = a->DataSize;
    Value = a->DataValue;

    //
    // Translate the bus address to the physical system address
    // or QVA.
    //

    if( !HalTranslateBusAddress( InterfaceType,
                                 BusNumber,
                                 IoAddress,
                                 &AddressSpace,
                                 &TranslatedAddress ) ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendWriteIoSpaceExtendedResponse;
    }

    //
    // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    //        is one.  It may be in later systems that we will have to
    //        check the address space, map it, perform the virtual read
    //        unmap, and then return the data - only we will have to be
    //        careful about what Irql we are to make sure the memory mgmt
    //        stuff will all work
    //

    if( !AddressSpace ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendWriteIoSpaceExtendedResponse;
    }

    //
    // Do the IO space read using the appropriate HAL routines based upon
    // the original address space and the data size requested.
    //

    if( !SavedAddressSpace ){

        //
        // Memory (buffer) space on the bus
        //

        switch( DataSize ){

        case 1:
            WRITE_REGISTER_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value );
            break;

        case 2:
            WRITE_REGISTER_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value );
            break;

        case 4:
            WRITE_REGISTER_ULONG( (PULONG)TranslatedAddress.QuadPart, Value );
            break;

        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
        }

    } else {

        //
        // I/O space on the bus
        //

        switch( DataSize ){

        case 1:
            WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value );
            break;

        case 2:
            WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value);
            break;

        case 4:
            WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value );
            break;

        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
        }
    }



SendWriteIoSpaceExtendedResponse:

    KdpSendPacket(
        PACKET_TYPE_KD_STATE_MANIPULATE,
        &MessageHeader,
        NULL
        );
}
Ejemplo n.º 13
0
VOID
KdpReadIoSpace (
    IN PDBGKD_MANIPULATE_STATE64 m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a read io space state
    manipulation message.  Its function is to read system io
    locations.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_WRITE_IO64 a = &m->u.ReadWriteIo;
    STRING MessageHeader;
    INTERFACE_TYPE InterfaceType;
    ULONG BusNumber;
    PHYSICAL_ADDRESS IoAddress;
    PHYSICAL_ADDRESS TranslatedAddress;
    ULONG AddressSpace;
    ULONG DataSize;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    ASSERT(AdditionalData->Length == 0);

    m->ReturnStatus = STATUS_SUCCESS;

    //
    // Capture the input parameters and use the default values for those
    // parameters not specified in the Api.
    //

    InterfaceType = Isa;
    BusNumber = 0;
    AddressSpace = 1;
    IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    DataSize = a->DataSize;

    //
    // Zero the return data value.
    //

    a->DataValue = 0;

    //
    // Translate the bus address to the physical system address
    // or QVA.
    //

    if( !HalTranslateBusAddress( InterfaceType,
                                 BusNumber,
                                 IoAddress,
                                 &AddressSpace,
                                 &TranslatedAddress ) ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendReadIoSpaceResponse;
    }

    //
    // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    //        is one.  It may be in later systems that we will have to
    //        check the address space, map it, perform the virtual read
    //        unmap, and then return the data - only we will have to be
    //        careful about what Irql we are to make sure the memory mgmt
    //        stuff will all work
    //

    if( !AddressSpace ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendReadIoSpaceResponse;
    }

    //
    // Do the IO space read using the appropriate HAL routines based upon
    // the default address space (io) and the data size requested.
    //

    switch( DataSize ){

    case 1:
        a->DataValue = READ_PORT_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart );
        break;

    case 2:
        a->DataValue = READ_PORT_USHORT( (PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart );
        break;

    case 4:
        a->DataValue = READ_PORT_ULONG((PULONG)(ULONG_PTR) TranslatedAddress.QuadPart );
        break;

    default:
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
    }


SendReadIoSpaceResponse:

    KdpSendPacket(
        PACKET_TYPE_KD_STATE_MANIPULATE,
        &MessageHeader,
        NULL
        );
}
Ejemplo n.º 14
0
BOOLEAN
HalInitSystem (
    IN ULONG Phase,
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This function initializes the Hardware Architecture Layer (HAL) for a
    MIPS R3000 or R4000 system.

Arguments:

    Phase - Supplies the initialization phase (zero or one).

    LoaderBlock - Supplies a pointer to a loader parameter block.

Return Value:

    A value of TRUE is returned is the initialization was successfully
    complete. Otherwise a value of FALSE is returend.

--*/

{

    ULONG FailedAddress;
    PKPRCB Prcb;
    PHYSICAL_ADDRESS PhysicalAddress;
    PHYSICAL_ADDRESS ZeroAddress;
    ULONG AddressSpace;

    //
    // Initialize the HAL components based on the phase of initialization
    // and the processor number.
    //

    Prcb = PCR->Prcb;
    PCR->DataBusError = HalpBusError;
    PCR->InstructionBusError = HalpBusError;
    if ((Phase == 0) || (Prcb->Number != 0)) {

        //
        // Phase 0 initialization.
        //
        // N.B. Phase 0 initialization is executed on all processors.
        //
        // Verify that the processor block major version number conform
        // to the system that is being loaded.
        //

        if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) {
            KeBugCheck(MISMATCHED_HAL);
        }

        //
        // Map the fixed TB entries.
        //

        HalpMapFixedTbEntries();

        //
        // If processor 0 is being initialized, then initialize various
        // variables, spin locks, and the display adapter.
        //

        if (Prcb->Number == 0) {

            //
            // Set the number of process id's and TB entries.
            //

            **((PULONG *)(&KeNumberProcessIds)) = 256;
            **((PULONG *)(&KeNumberTbEntries)) = 48;

            //
            // Set the interval clock increment value.
            //

            HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
            HalpNextTimeIncrement = MAXIMUM_INCREMENT;
            HalpNextIntervalCount = 0;
            KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT);

            //
            // Initialize all spin locks.
            //

#if defined(_DUO_)

            KeInitializeSpinLock(&HalpBeepLock);
            KeInitializeSpinLock(&HalpDisplayAdapterLock);
            KeInitializeSpinLock(&HalpSystemInterruptLock);

#endif

            //
            // Set address of cache error routine.
            //

            KeSetCacheErrorRoutine(HalpCacheErrorRoutine);

            //
            // Initialize the display adapter.
            //

            HalpInitializeDisplay0(LoaderBlock);

            //
            // Allocate map register memory.
            //

            HalpAllocateMapRegisters(LoaderBlock);

            //
            // Initialize and register a bug check callback record.
            //

            KeInitializeCallbackRecord(&HalpCallbackRecord);
            KeRegisterBugCheckCallback(&HalpCallbackRecord,
                                       HalpBugCheckCallback,
                                       &HalpBugCheckBuffer,
                                       sizeof(HALP_BUGCHECK_BUFFER),
                                       &HalpComponentId[0]);
        }

        //
        // Clear memory address error registers.
        //

#if defined(_DUO_)

        FailedAddress = ((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress.Long;

#endif

        FailedAddress = ((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long;

        //
        // Initialize interrupts
        //

        HalpInitializeInterrupts();
        return TRUE;

    } else {

        //
        // Phase 1 initialization.
        //
        // N.B. Phase 1 initialization is only executed on processor 0.
        //
        // Complete initialization of the display adapter.
        //

        if (HalpInitializeDisplay1(LoaderBlock) == FALSE) {
            return FALSE;

        } else {

            //
            // Map I/O space, calibrate the stall execution scale factor,
            // and create DMA data structures.
            //

            HalpMapIoSpace();
            HalpCalibrateStall();
            HalpCreateDmaStructures();

            //
            // Map EISA memory space so the x86 bios emulator emulator can
            // initialze a video adapter in an EISA slot.
            //

            ZeroAddress.QuadPart = 0;
            AddressSpace = 0;
            HalTranslateBusAddress(Isa,
                                   0,
                                   ZeroAddress,
                                   &AddressSpace,
                                   &PhysicalAddress);

            HalpEisaMemoryBase = MmMapIoSpace(PhysicalAddress,
                                              PAGE_SIZE * 256,
                                              FALSE);

            HalpInitializeX86DisplayAdapter();
            return TRUE;
        }
    }
}
Ejemplo n.º 15
0
VOID
DumpT2(
    VOID
    )
/*++

Routine Description:

    Read the interesting T2 registers and print them to the debug port.

Arguments:

    None.

Return Value:

    None.

--*/
{
    PVOID RegisterQva;
    PVOID TestQva;
    ULONGLONG Value;
    ULONG LongValue;
    T2_TDR Tdr;

//    DbgPrint( "Dumping the T2 registers, " );

#if 0
//
// This code tests whether the windows and holes allow access to
// the address in I/O memory space set in PhysicalAddress.
// See also the companion code at the end of this routine.
//
    {
    ULONG AddressSpace;
    PHYSICAL_ADDRESS PhysicalAddress;

    AddressSpace = 0;
    PhysicalAddress.LowPart = 0xD0000;    // DE422
//    PhysicalAddress.LowPart = 0x2200000;    // 34Mbytes
//    PhysicalAddress.LowPart = 0x0400000;    // 4Mbytes
    PhysicalAddress.HighPart = 0;
    HalTranslateBusAddress( Isa, 0, PhysicalAddress, &AddressSpace, &TestQva );

    LongValue = READ_REGISTER_ULONG( TestQva );
    DbgPrint( "TestQva = %lx, Value = %x, writing 0xa5a5a5a5..\n",
	      TestQva, LongValue );
    LongValue = 0xa5a5a5a5;
    WRITE_REGISTER_ULONG( TestQva, LongValue );
    LongValue = READ_REGISTER_ULONG( TestQva );
    DbgPrint( "TestQva = %lx, Value = %x\n", TestQva, LongValue );
    }
#endif // 0
 
#if 0   
    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Iocsr;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Iocsr = %Lx, ", Value );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Ivrpr;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Ivrpr = %Lx\n",  Value );
      
    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Hae0_1;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Hae0_1 = %Lx, ",  Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Hae0_2;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Hae0_2 = %Lx, ",  Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Hbase;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Hbase = %Lx\n",  Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Wbase1;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Wbase1 = %Lx, ", Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Wmask1;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Wmask1 = %Lx, ", Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tbase1;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Tbase1 = %Lx\n", Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Wbase2;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Wbase2 = %Lx, ", Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Wmask2;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Wmask2 = %Lx, ", Value ); 

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tbase2;
    Value = READ_T2_REGISTER( RegisterQva );
    DbgPrint( "Tbase2 = %Lx\n", Value ); 

#endif // 0

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr0;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr0 PFN=%x, V=%x, Tag=%x, ",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr1;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr1 PFN=%x, V=%x, Tag=%x\n",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr2;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr2 PFN=%x, V=%x, Tag=%x, ",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr3;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr3 PFN=%x, V=%x, Tag=%x\n",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr4;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr4 PFN=%x, V=%x, Tag=%x, ",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr5;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr5 PFN=%x, V=%x, Tag=%x\n",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr6;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr6 PFN=%x, V=%x, Tag=%x, ",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

    RegisterQva = &((PT2_CSRS)(T2_CSRS_QVA))->Tdr7;
    Value = READ_T2_REGISTER( RegisterQva );
    Tdr = *(PT2_TDR)&Value;
    DbgPrint( "Tdr7 PFN=%x, V=%x, Tag=%x\n",  Tdr.Pfn, Tdr.Valid, Tdr.Tag );

#if 0
    LongValue = READ_REGISTER_ULONG( TestQva );
    DbgPrint( "TestQva = %lx, Value = %x, writing 0xc3c3c3c3..\n",
	      TestQva, LongValue );
    LongValue = 0xc3c3c3c3;
    WRITE_REGISTER_ULONG( TestQva, LongValue );
    LongValue = READ_REGISTER_ULONG( TestQva );
    DbgPrint( "TestQva = %lx, Value = %x\n", TestQva, LongValue );
#endif // 0

//    DbgPrint( "--end T2 dump\n\n" );

    return;

}
Ejemplo n.º 16
0
NDIS_STATUS
NdisMRegisterIoPortRange(
	OUT	PVOID	*				PortOffset,
	IN	NDIS_HANDLE				MiniportAdapterHandle,
	IN	UINT					InitialPort,
	IN	UINT					NumberOfPorts
	)

/*++

Routine Description:

	Sets up an IO port for operations.

Arguments:

	PortOffset - The mapped port address the Miniport uses for NdisRaw functions.

	MiniportAdapterHandle - Handle passed to Miniport Initialize.

	InitialPort - Physical address of the starting port number.

	NumberOfPorts - Number of ports to map.

Return Value:

	None.

--*/
{
	PNDIS_MINIPORT_BLOCK	Miniport = (PNDIS_MINIPORT_BLOCK)(MiniportAdapterHandle);
	PHYSICAL_ADDRESS		PortAddress;
	PHYSICAL_ADDRESS		InitialPortAddress;
	ULONG 					addressSpace;
	NDIS_STATUS				Status;

	CM_PARTIAL_RESOURCE_DESCRIPTOR	Resource;

	//
	// First check if any bus access is allowed
	//
	if ((Miniport->BusType == (NDIS_INTERFACE_TYPE)-1) ||
		(Miniport->BusNumber == (ULONG)-1))
	{
		return(NDIS_STATUS_FAILURE);
	}

	//
	// Setup port
	//
	Resource.Type = CmResourceTypePort;
	Resource.ShareDisposition = CmResourceShareDeviceExclusive;
	Resource.Flags = (Miniport->AdapterType == NdisInterfaceInternal) ?
						CM_RESOURCE_PORT_MEMORY : CM_RESOURCE_PORT_IO;
	Resource.u.Port.Start.QuadPart = InitialPort;
	Resource.u.Port.Length = NumberOfPorts;

	//
	//	Add the new resource.
	//
	Status = ndisAddResource(
				&Miniport->Resources,
				&Resource,
				Miniport->AdapterType,
				Miniport->BusNumber,
				Miniport->DriverHandle->NdisDriverInfo->NdisWrapperDriver,
				Miniport->DeviceObject,
				&Miniport->MiniportName);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		return(Status);
	}

	//
	// Now Map the ports
	//

	//
	// Get the system physical address for this card.  The card uses
	// I/O space, except for "internal" Jazz devices which use
	// memory space.
	//
	addressSpace = (Miniport->AdapterType == NdisInterfaceInternal) ? 0 : 1;

	InitialPortAddress.LowPart = InitialPort;
	InitialPortAddress.HighPart = 0;

	if (!HalTranslateBusAddress(Miniport->BusType,			// InterfaceType
								Miniport->BusNumber,		// BusNumber
								InitialPortAddress,			// Bus Address
								&addressSpace,				// AddressSpace
								&PortAddress))				// Translated address
	{
		//
		// It would be nice to return a better status here, but we only get
		// TRUE/FALSE back from HalTranslateBusAddress.
		//

		return NDIS_STATUS_FAILURE;
	}

	if (addressSpace == 0)
	{
		//
		// memory space
		//

		*(PortOffset) = (PULONG)MmMapIoSpace(PortAddress,
											 NumberOfPorts,
											 FALSE);

		if (*(PortOffset) == (PULONG)NULL)
		{
			return NDIS_STATUS_RESOURCES;
		}
	}
	else
	{
		//
		// I/O space
		//

		*(PortOffset) = (PULONG)PortAddress.LowPart;
	}

	return(NDIS_STATUS_SUCCESS);
}
Ejemplo n.º 17
0
VOID
HalpReportResourceUsage (
    IN PUNICODE_STRING  HalName,
    IN INTERFACE_TYPE   DeviceInterfaceToUse
    )
/*++

Routine Description:

Arguments:

Return Value:

--*/
{
    PCM_RESOURCE_LIST               RawResourceList, TranslatedResourceList;
    PCM_FULL_RESOURCE_DESCRIPTOR    pRFullDesc,      pTFullDesc;
    PCM_PARTIAL_RESOURCE_LIST       pRPartList,      pTPartList;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,        pTCurLoc;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR pRSortLoc,       pTSortLoc;
    CM_PARTIAL_RESOURCE_DESCRIPTOR  RPartialDesc,    TPartialDesc;
    ULONG   i, j, k, ListSize, Count;
    ULONG   curscale, sortscale;
    UCHAR   pass, reporton;
    INTERFACE_TYPE  interfacetype;
    ULONG           CurrentIDT, CurrentElement;
    ADDRESS_USAGE   *CurrentAddress;
    LARGE_INTEGER   curvalue, sortvalue;


    //
    // Allocate some space to build the resource structure
    //

    RawResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (NonPagedPool, PAGE_SIZE*2);
    TranslatedResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (NonPagedPool, PAGE_SIZE*2);

    // This functions assumes unset fields are zero
    RtlZeroMemory (RawResourceList, PAGE_SIZE*2);
    RtlZeroMemory (TranslatedResourceList, PAGE_SIZE*2);

    //
    // Initialize the lists
    //

    RawResourceList->List[0].InterfaceType = (INTERFACE_TYPE) -1;

    pRFullDesc = RawResourceList->List;
    pRCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) RawResourceList->List;
    pTCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) TranslatedResourceList->List;

    //
    // Make sure all vectors 00-2f are reserved
    // 00-1E reserved by Intel
    // 1F    reserved by Intel for APIC (apc priority level)
    // 20-2e reserved by Microsoft
    // 2f    reserved by Microsoft for APIC (dpc priority level)
    //

#if defined(_R98_)	// CHG001
    for(i=0; i < DEVICE_VECTORS; i++) {			// ADD001
             HalpIDTUsage[i].Flags = InternalUsage | InterruptLatched;
             HalpIDTUsage[i].BusReleativeVector = (UCHAR) i;
    }
#else
    for(i=0; i < PRIMARY_VECTOR_BASE; i++) {
        if (!(HalpIDTUsage[i].Flags & IDTOwned)) {
             HalpIDTUsage[i].Flags = InternalUsage;
             HalpIDTUsage[i].BusReleativeVector = (UCHAR) i;
        }
    }
#endif

    for(pass=0; pass < 2; pass++) {
        if (pass == 0) {
            //
            // First pass - build resource lists for resources reported
            // reported against device usage.
            //

            reporton = DeviceUsage & ~IDTOwned;
            interfacetype = DeviceInterfaceToUse;
        } else {

            //
            // Second pass = build reousce lists for resources reported
            // as internal usage.
            //

            reporton = InternalUsage & ~IDTOwned;
            interfacetype = Internal;
        }

        CurrentIDT = 0;
        CurrentElement = 0;
        CurrentAddress = HalpAddressUsageList;

        for (; ;) {
            if (CurrentIDT <= MAXIMUM_VECTOR) {	// CHG001
                //
                // Check to see if CurrentIDT needs to be reported
                //

                if (!(HalpIDTUsage[CurrentIDT].Flags & reporton)) {
                    // Don't report on this one
                    CurrentIDT++;
                    continue;
                }

                //
                // Report CurrentIDT resource
                //

                RPartialDesc.Type = CmResourceTypeInterrupt;
                RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
                RPartialDesc.Flags =
                    HalpIDTUsage[CurrentIDT].Flags & InterruptLatched ?
                    CM_RESOURCE_INTERRUPT_LATCHED :
                    CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
                RPartialDesc.u.Interrupt.Vector = HalpIDTUsage[CurrentIDT].BusReleativeVector;
                RPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].BusReleativeVector;
                RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors;

                RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc);
                TPartialDesc.u.Interrupt.Vector = CurrentIDT;
                TPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].Irql;

                CurrentIDT++;

            } else {
                //
                // Check to see if CurrentAddress needs to be reported
                //

                if (!CurrentAddress) {
                    break;                  // No addresses left
                }

                if (!(CurrentAddress->Flags & reporton)) {
                    // Don't report on this list
                    CurrentElement = 0;
                    CurrentAddress = CurrentAddress->Next;
                    continue;
                }

                if (!CurrentAddress->Element[CurrentElement].Length) {
                    // End of current list, go to next list
                    CurrentElement = 0;
                    CurrentAddress = CurrentAddress->Next;
                    continue;
                }

                //
                // Report CurrentAddress
                //

                RPartialDesc.Type = (UCHAR) CurrentAddress->Type;
                RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;

                if (RPartialDesc.Type == CmResourceTypePort) {
                    i = 1;              // address space port
                    RPartialDesc.Flags = CM_RESOURCE_PORT_IO;
                } else {
                    i = 0;              // address space memory
                    RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
                }

                // Notice: assuming u.Memory and u.Port have the same layout
                RPartialDesc.u.Memory.Start.HighPart = 0;
                RPartialDesc.u.Memory.Start.LowPart =
                    CurrentAddress->Element[CurrentElement].Start;

                RPartialDesc.u.Memory.Length =
                    CurrentAddress->Element[CurrentElement].Length;

                // translated address = Raw address
                RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc);
                HalTranslateBusAddress (
                    interfacetype,                  // device bus or internal
                    0,                              // bus number
                    RPartialDesc.u.Memory.Start,    // source address
                    &i,                             // address space
                    &TPartialDesc.u.Memory.Start ); // translated address

                if (RPartialDesc.Type == CmResourceTypePort  &&  i == 0) {
                    TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY;
                }

                CurrentElement++;
            }

            //
            // Include the current resource in the HALs list
            //

            if (pRFullDesc->InterfaceType != interfacetype) {
                //
                // Interface type changed, add another full section
                //

                RawResourceList->Count++;
                TranslatedResourceList->Count++;

                pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc;
                pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc;

                pRFullDesc->InterfaceType = interfacetype;
                pTFullDesc->InterfaceType = interfacetype;

                pRPartList = &pRFullDesc->PartialResourceList;
                pTPartList = &pTFullDesc->PartialResourceList;

                //
                // Bump current location pointers up
                //
                pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
                pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
            }


            pRPartList->Count++;
            pTPartList->Count++;
            RtlCopyMemory (pRCurLoc, &RPartialDesc, sizeof RPartialDesc);
            RtlCopyMemory (pTCurLoc, &TPartialDesc, sizeof TPartialDesc);

            pRCurLoc++;
            pTCurLoc++;
        }
    }

    ListSize = (ULONG) ( ((PUCHAR) pRCurLoc) - ((PUCHAR) RawResourceList) );

    //
    // The HAL's resource usage structures have been built
    // Sort the partial lists based on the Raw resource values
    //

    pRFullDesc = RawResourceList->List;
    pTFullDesc = TranslatedResourceList->List;

    for (i=0; i < RawResourceList->Count; i++) {

        pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
        pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
        Count = pRFullDesc->PartialResourceList.Count;

        for (j=0; j < Count; j++) {
            HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);

            pRSortLoc = pRCurLoc;
            pTSortLoc = pTCurLoc;

            for (k=j; k < Count; k++) {
                HalpGetResourceSortValue (pRSortLoc, &sortscale, &sortvalue);

                if (sortscale < curscale ||
                    (sortscale == curscale &&
                     RtlLargeIntegerLessThan (sortvalue, curvalue)) ) {

                    //
                    // Swap the elements..
                    //

                    RtlCopyMemory (&RPartialDesc, pRCurLoc, sizeof RPartialDesc);
                    RtlCopyMemory (pRCurLoc, pRSortLoc, sizeof RPartialDesc);
                    RtlCopyMemory (pRSortLoc, &RPartialDesc, sizeof RPartialDesc);

                    // swap translated descriptor as well
                    RtlCopyMemory (&TPartialDesc, pTCurLoc, sizeof TPartialDesc);
                    RtlCopyMemory (pTCurLoc, pTSortLoc, sizeof TPartialDesc);
                    RtlCopyMemory (pTSortLoc, &TPartialDesc, sizeof TPartialDesc);

                    // get new curscale & curvalue
                    HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);
                }

                pRSortLoc++;
                pTSortLoc++;
            }

            pRCurLoc++;
            pTCurLoc++;
        }

        pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc;
        pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc;
    }


    //
    // Inform the IO system of our resources..
    //

    IoReportHalResourceUsage (
        HalName,
        RawResourceList,
        TranslatedResourceList,
        ListSize
    );

    ExFreePool (RawResourceList);
    ExFreePool (TranslatedResourceList);
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
static NTSTATUS NTAPI
ConfigCallback(PVOID Context,
               PUNICODE_STRING PathName,
               INTERFACE_TYPE BusType,
               ULONG BusNumber,
               PKEY_VALUE_FULL_INFORMATION *BusInformation,
               CONFIGURATION_TYPE ControllerType,
               ULONG ControllerNumber,
               PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
               CONFIGURATION_TYPE PeripheralType,
               ULONG PeripheralNumber,
               PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
/*
 * FUNCTION: Callback to IoQueryDeviceDescription, which tells us about our controllers
 * ARGUMENTS:
 *     Context: Unused
 *     PathName: Unused
 *     BusType: Type of the bus that our controller is on
 *     BusNumber: Number of the bus that our controller is on
 *     BusInformation: Unused
 *     ControllerType: Unused
 *     ControllerNumber: Number of the controller that we're adding
 *     ControllerInformation: Full configuration information for our controller
 *     PeripheralType: Unused
 *     PeripheralNumber: Unused
 *     PeripheralInformation: Full configuration information for each drive on our controller
 * RETURNS:
 *     STATUS_SUCCESS in all cases
 * NOTES:
 *     - The only documentation I've found about the contents of these structures is
 *       from the various Microsoft floppy samples and from the DDK headers.  They're
 *       very vague, though, so I'm only mostly sure that this stuff is correct, as
 *       the MS samples do things completely differently than I have done them.  Seems
 *       to work in my VMWare, though.
 *     - Basically, the function gets all of the information (port, dma, irq) about the
 *       controller, and then loops through all of the drives presented in PeripheralInformation.
 *     - Each controller has a CONTROLLER_INFO created for it, and each drive has a DRIVE_INFO.
 *     - Device objects are created for each drive (not controller), as that's the targeted
 *       device in the eyes of the rest of the OS.  Each DRIVE_INFO points to a single CONTROLLER_INFO.
 *     - We only support up to four controllers in the whole system, each of which supports up to four
 *       drives.
 */
{
    PKEY_VALUE_FULL_INFORMATION ControllerFullDescriptor = ControllerInformation[IoQueryDeviceConfigurationData];
    PCM_FULL_RESOURCE_DESCRIPTOR ControllerResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)ControllerFullDescriptor +
            ControllerFullDescriptor->DataOffset);

    PKEY_VALUE_FULL_INFORMATION PeripheralFullDescriptor = PeripheralInformation[IoQueryDeviceConfigurationData];
    PCM_FULL_RESOURCE_DESCRIPTOR PeripheralResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PCHAR)PeripheralFullDescriptor +
            PeripheralFullDescriptor->DataOffset);

    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
    PCM_FLOPPY_DEVICE_DATA FloppyDeviceData;
    UCHAR i;

    PAGED_CODE();
    UNREFERENCED_PARAMETER(PeripheralType);
    UNREFERENCED_PARAMETER(PeripheralNumber);
    UNREFERENCED_PARAMETER(BusInformation);
    UNREFERENCED_PARAMETER(Context);
    UNREFERENCED_PARAMETER(ControllerType);
    UNREFERENCED_PARAMETER(PathName);


    TRACE_(FLOPPY, "ConfigCallback called with ControllerNumber %d\n", ControllerNumber);

    gControllerInfo[gNumberOfControllers].ControllerNumber = ControllerNumber;
    gControllerInfo[gNumberOfControllers].InterfaceType = BusType;
    gControllerInfo[gNumberOfControllers].BusNumber = BusNumber;

    /* Get controller interrupt level/vector, dma channel, and port base */
    for(i = 0; i < ControllerResourceDescriptor->PartialResourceList.Count; i++)
    {
        KeInitializeEvent(&gControllerInfo[gNumberOfControllers].SynchEvent, NotificationEvent, FALSE);

        PartialDescriptor = &ControllerResourceDescriptor->PartialResourceList.PartialDescriptors[i];

        if(PartialDescriptor->Type == CmResourceTypeInterrupt)
        {
            gControllerInfo[gNumberOfControllers].Level = PartialDescriptor->u.Interrupt.Level;
            gControllerInfo[gNumberOfControllers].Vector = PartialDescriptor->u.Interrupt.Vector;

            if(PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
                gControllerInfo[gNumberOfControllers].InterruptMode = Latched;
            else
                gControllerInfo[gNumberOfControllers].InterruptMode = LevelSensitive;
        }

        else if(PartialDescriptor->Type == CmResourceTypePort)
        {
            PHYSICAL_ADDRESS TranslatedAddress;
            ULONG AddressSpace = 0x1; /* I/O Port Range */

            if(!HalTranslateBusAddress(BusType, BusNumber, PartialDescriptor->u.Port.Start, &AddressSpace, &TranslatedAddress))
            {
                WARN_(FLOPPY, "HalTranslateBusAddress failed; returning\n");
                return STATUS_IO_DEVICE_ERROR;
            }

            if(AddressSpace == 0)
                gControllerInfo[gNumberOfControllers].BaseAddress = MmMapIoSpace(TranslatedAddress, FDC_PORT_BYTES, MmNonCached);
            else
                gControllerInfo[gNumberOfControllers].BaseAddress = (PUCHAR)(ULONG_PTR)TranslatedAddress.QuadPart;
        }

        else if(PartialDescriptor->Type == CmResourceTypeDma)
            gControllerInfo[gNumberOfControllers].Dma = PartialDescriptor->u.Dma.Channel;
    }

    /* Start with 0 drives, then go looking */
    gControllerInfo[gNumberOfControllers].NumberOfDrives = 0;

    /* learn about drives attached to controller */
    for(i = 0; i < PeripheralResourceDescriptor->PartialResourceList.Count; i++)
    {
        PDRIVE_INFO DriveInfo = &gControllerInfo[gNumberOfControllers].DriveInfo[i];

        PartialDescriptor = &PeripheralResourceDescriptor->PartialResourceList.PartialDescriptors[i];

        if(PartialDescriptor->Type != CmResourceTypeDeviceSpecific)
            continue;

        FloppyDeviceData = (PCM_FLOPPY_DEVICE_DATA)(PartialDescriptor + 1);

        DriveInfo->ControllerInfo = &gControllerInfo[gNumberOfControllers];
        DriveInfo->UnitNumber = i;

        DriveInfo->FloppyDeviceData.MaxDensity = FloppyDeviceData->MaxDensity;
        DriveInfo->FloppyDeviceData.MountDensity = FloppyDeviceData->MountDensity;
        DriveInfo->FloppyDeviceData.StepRateHeadUnloadTime = FloppyDeviceData->StepRateHeadUnloadTime;
        DriveInfo->FloppyDeviceData.HeadLoadTime = FloppyDeviceData->HeadLoadTime;
        DriveInfo->FloppyDeviceData.MotorOffTime = FloppyDeviceData->MotorOffTime;
        DriveInfo->FloppyDeviceData.SectorLengthCode = FloppyDeviceData->SectorLengthCode;
        DriveInfo->FloppyDeviceData.SectorPerTrack = FloppyDeviceData->SectorPerTrack;
        DriveInfo->FloppyDeviceData.ReadWriteGapLength = FloppyDeviceData->ReadWriteGapLength;
        DriveInfo->FloppyDeviceData.FormatGapLength = FloppyDeviceData->FormatGapLength;
        DriveInfo->FloppyDeviceData.FormatFillCharacter = FloppyDeviceData->FormatFillCharacter;
        DriveInfo->FloppyDeviceData.HeadSettleTime = FloppyDeviceData->HeadSettleTime;
        DriveInfo->FloppyDeviceData.MotorSettleTime = FloppyDeviceData->MotorSettleTime;
        DriveInfo->FloppyDeviceData.MaximumTrackValue = FloppyDeviceData->MaximumTrackValue;
        DriveInfo->FloppyDeviceData.DataTransferLength = FloppyDeviceData->DataTransferLength;

        /* Once it's all set up, acknowledge its existance in the controller info object */
        gControllerInfo[gNumberOfControllers].NumberOfDrives++;
    }

    gControllerInfo[gNumberOfControllers].Populated = TRUE;
    gNumberOfControllers++;

    return STATUS_SUCCESS;
}
Ejemplo n.º 20
0
BOOLEAN
NTAPI
HaliFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress,
                              IN OUT PULONG AddressSpace,
                              OUT PPHYSICAL_ADDRESS TranslatedAddress,
                              IN OUT PULONG_PTR Context,
                              IN BOOLEAN NextBus)
{
    PHAL_BUS_HANDLER BusHandler;
    PBUS_HANDLER Handler;
    PLIST_ENTRY NextEntry;
    ULONG ContextValue;

    /* Make sure we have a context */
    if (!Context) return FALSE;
    ASSERT((*Context) || (NextBus == TRUE));

    /* Read the context */
    ContextValue = *Context;

    /* Find the bus handler */
    Handler = HalpContextToBusHandler(ContextValue);
    if (!Handler) return FALSE;

    /* Check if this is an ongoing lookup */
    if (NextBus)
    {
        /* Get the HAL bus handler */
        BusHandler = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler);
        NextEntry = &BusHandler->AllHandlers;

        /* Get the next one if we were already with one */
        if (ContextValue) NextEntry = NextEntry->Flink;

        /* Start scanning */
        while (TRUE)
        {
            /* Check if this is the last one */
            if (NextEntry == &HalpAllBusHandlers)
            {
                /* Quit */
                *Context = 1;
                return FALSE;
            }

            /* Call this translator */
            BusHandler = CONTAINING_RECORD(NextEntry, HAL_BUS_HANDLER, AllHandlers);
            if (HalTranslateBusAddress(BusHandler->Handler.InterfaceType,
                                       BusHandler->Handler.BusNumber,
                                       BusAddress,
                                       AddressSpace,
                                       TranslatedAddress)) break;

            /* Try the next one */
            NextEntry = NextEntry->Flink;
        }

        /* If we made it, we're done */
        *Context = (ULONG_PTR)Handler;
        return TRUE;
    }

    /* Try the first one through */
    if (!HalTranslateBusAddress(Handler->InterfaceType,
                                Handler->BusNumber,
                                BusAddress,
                                AddressSpace,
                                TranslatedAddress)) return FALSE;

    /* Remember for next time */
    *Context = (ULONG_PTR)Handler;
    return TRUE;
}