mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
[ISAPNP] Read all resources when detecting devices
This commit is contained in:
parent
ca42de9c31
commit
b29a3ac524
4 changed files with 182 additions and 16 deletions
|
@ -83,6 +83,17 @@ ReadWord(
|
||||||
(ReadByte(ReadDataPort, Address + 1)));
|
(ReadByte(ReadDataPort, Address + 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
ULONG
|
||||||
|
ReadDoubleWord(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_In_ UCHAR Address)
|
||||||
|
{
|
||||||
|
return ((ReadWord(ReadDataPort, Address) << 8) |
|
||||||
|
(ReadWord(ReadDataPort, Address + 2)));
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
inline
|
inline
|
||||||
VOID
|
VOID
|
||||||
|
@ -198,7 +209,7 @@ ReadIrqNo(
|
||||||
_In_ PUCHAR ReadDataPort,
|
_In_ PUCHAR ReadDataPort,
|
||||||
_In_ UCHAR Index)
|
_In_ UCHAR Index)
|
||||||
{
|
{
|
||||||
return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index));
|
return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index)) & 0x0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -218,7 +229,67 @@ ReadDmaChannel(
|
||||||
_In_ PUCHAR ReadDataPort,
|
_In_ PUCHAR ReadDataPort,
|
||||||
_In_ UCHAR Index)
|
_In_ UCHAR Index)
|
||||||
{
|
{
|
||||||
return ReadByte(ReadDataPort, ISAPNP_DMACHANNEL(Index));
|
return ReadByte(ReadDataPort, ISAPNP_DMACHANNEL(Index)) & 0x07;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
ReadMemoryBase(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_In_ UCHAR Index)
|
||||||
|
{
|
||||||
|
return ReadWord(ReadDataPort, ISAPNP_MEMBASE(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
UCHAR
|
||||||
|
ReadMemoryControl(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_In_ UCHAR Index)
|
||||||
|
{
|
||||||
|
return ReadByte(ReadDataPort, ISAPNP_MEMCONTROL(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
ReadMemoryLimit(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_In_ UCHAR Index)
|
||||||
|
{
|
||||||
|
return ReadWord(ReadDataPort, ISAPNP_MEMLIMIT(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
ULONG
|
||||||
|
ReadMemoryBase32(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_In_ UCHAR Index)
|
||||||
|
{
|
||||||
|
return ReadDoubleWord(ReadDataPort, ISAPNP_MEMBASE32(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
UCHAR
|
||||||
|
ReadMemoryControl32(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_In_ UCHAR Index)
|
||||||
|
{
|
||||||
|
return ReadByte(ReadDataPort, ISAPNP_MEMCONTROL32(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
ULONG
|
||||||
|
ReadMemoryLimit32(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_In_ UCHAR Index)
|
||||||
|
{
|
||||||
|
return ReadDoubleWord(ReadDataPort, ISAPNP_MEMLIMIT32(Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -1016,6 +1087,95 @@ SkipTag:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
CODE_SEG("PAGE")
|
||||||
|
BOOLEAN
|
||||||
|
ReadCurrentResources(
|
||||||
|
_In_ PUCHAR ReadDataPort,
|
||||||
|
_Inout_ PISAPNP_LOGICAL_DEVICE LogDevice)
|
||||||
|
{
|
||||||
|
UCHAR i;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
DPRINT("%s for CSN %u, LDN %u\n", __FUNCTION__, LogDevice->CSN, LogDevice->LDN);
|
||||||
|
|
||||||
|
WriteLogicalDeviceNumber(LogDevice->LDN);
|
||||||
|
|
||||||
|
/* If the device is not activated by BIOS we just report a NULL resource list */
|
||||||
|
if (!(ReadByte(ReadDataPort, ISAPNP_ACTIVATE) & 1))
|
||||||
|
{
|
||||||
|
LogDevice->Flags &= ~ISAPNP_HAS_RESOURCES;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < RTL_NUMBER_OF(LogDevice->Io); i++)
|
||||||
|
{
|
||||||
|
LogDevice->Io[i].CurrentBase = ReadIoBase(ReadDataPort, i);
|
||||||
|
|
||||||
|
/* Skip empty descriptors */
|
||||||
|
if (!LogDevice->Io[i].CurrentBase)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0; i < RTL_NUMBER_OF(LogDevice->Irq); i++)
|
||||||
|
{
|
||||||
|
LogDevice->Irq[i].CurrentNo = ReadIrqNo(ReadDataPort, i);
|
||||||
|
|
||||||
|
if (!LogDevice->Irq[i].CurrentNo)
|
||||||
|
break;
|
||||||
|
|
||||||
|
LogDevice->Irq[i].CurrentType = ReadIrqType(ReadDataPort, i);
|
||||||
|
}
|
||||||
|
for (i = 0; i < RTL_NUMBER_OF(LogDevice->Dma); i++)
|
||||||
|
{
|
||||||
|
LogDevice->Dma[i].CurrentChannel = ReadDmaChannel(ReadDataPort, i);
|
||||||
|
|
||||||
|
if (LogDevice->Dma[i].CurrentChannel == 4)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange); i++)
|
||||||
|
{
|
||||||
|
LogDevice->MemRange[i].CurrentBase = ReadMemoryBase(ReadDataPort, i) << 8;
|
||||||
|
|
||||||
|
if (!LogDevice->MemRange[i].CurrentBase)
|
||||||
|
break;
|
||||||
|
|
||||||
|
LogDevice->MemRange[i].CurrentLength = ReadMemoryLimit(ReadDataPort, i) << 8;
|
||||||
|
|
||||||
|
if (ReadMemoryControl(ReadDataPort, i) & MEMORY_UPPER_LIMIT)
|
||||||
|
{
|
||||||
|
LogDevice->MemRange[i].CurrentLength -= LogDevice->MemRange[i].CurrentBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogDevice->MemRange[i].CurrentLength =
|
||||||
|
RANGE_LENGTH_TO_LENGTH(LogDevice->MemRange[i].CurrentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange32); i++)
|
||||||
|
{
|
||||||
|
LogDevice->MemRange32[i].CurrentBase = ReadMemoryBase32(ReadDataPort, i);
|
||||||
|
|
||||||
|
if (!LogDevice->MemRange32[i].CurrentBase)
|
||||||
|
break;
|
||||||
|
|
||||||
|
LogDevice->MemRange32[i].CurrentLength = ReadMemoryLimit32(ReadDataPort, i);
|
||||||
|
|
||||||
|
if (ReadMemoryControl32(ReadDataPort, i) & MEMORY_UPPER_LIMIT)
|
||||||
|
{
|
||||||
|
LogDevice->MemRange32[i].CurrentLength -= LogDevice->MemRange32[i].CurrentBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogDevice->MemRange32[i].CurrentLength =
|
||||||
|
RANGE_LENGTH_TO_LENGTH(LogDevice->MemRange32[i].CurrentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogDevice->Flags |= ISAPNP_HAS_RESOURCES;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
CODE_SEG("PAGE")
|
CODE_SEG("PAGE")
|
||||||
INT
|
INT
|
||||||
|
@ -1153,7 +1313,6 @@ IsaHwFillDeviceList(
|
||||||
{
|
{
|
||||||
PISAPNP_LOGICAL_DEVICE LogDevice;
|
PISAPNP_LOGICAL_DEVICE LogDevice;
|
||||||
UCHAR Csn;
|
UCHAR Csn;
|
||||||
ULONG i;
|
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
PUCHAR ResourceData;
|
PUCHAR ResourceData;
|
||||||
|
|
||||||
|
@ -1264,19 +1423,8 @@ IsaHwFillDeviceList(
|
||||||
goto Deactivate;
|
goto Deactivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteLogicalDeviceNumber(LogDev);
|
if (!ReadCurrentResources(FdoExt->ReadDataPort, LogDevice))
|
||||||
|
DPRINT("Unable to read boot resources\n");
|
||||||
for (i = 0; i < ARRAYSIZE(LogDevice->Io); i++)
|
|
||||||
LogDevice->Io[i].CurrentBase = ReadIoBase(FdoExt->ReadDataPort, i);
|
|
||||||
for (i = 0; i < ARRAYSIZE(LogDevice->Irq); i++)
|
|
||||||
{
|
|
||||||
LogDevice->Irq[i].CurrentNo = ReadIrqNo(FdoExt->ReadDataPort, i);
|
|
||||||
LogDevice->Irq[i].CurrentType = ReadIrqType(FdoExt->ReadDataPort, i);
|
|
||||||
}
|
|
||||||
for (i = 0; i < ARRAYSIZE(LogDevice->Dma); i++)
|
|
||||||
{
|
|
||||||
LogDevice->Dma[i].CurrentChannel = ReadDmaChannel(FdoExt->ReadDataPort, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
IsaPnpExtractAscii(LogDevice->VendorId, Identifier.VendorId);
|
IsaPnpExtractAscii(LogDevice->VendorId, Identifier.VendorId);
|
||||||
LogDevice->ProdId = Identifier.ProdId;
|
LogDevice->ProdId = Identifier.ProdId;
|
||||||
|
|
|
@ -133,6 +133,7 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
#define ISAPNP_PRESENT 0x00000001 /**< @brief Cleared when the device is physically removed. */
|
#define ISAPNP_PRESENT 0x00000001 /**< @brief Cleared when the device is physically removed. */
|
||||||
#define ISAPNP_HAS_MULTIPLE_LOGDEVS 0x00000002 /**< @brief Indicates if the parent card has multiple logical devices. */
|
#define ISAPNP_HAS_MULTIPLE_LOGDEVS 0x00000002 /**< @brief Indicates if the parent card has multiple logical devices. */
|
||||||
|
#define ISAPNP_HAS_RESOURCES 0x00000004 /**< @brief Cleared when the device has no boot resources. */
|
||||||
|
|
||||||
LIST_ENTRY DeviceLink;
|
LIST_ENTRY DeviceLink;
|
||||||
} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
|
} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
|
||||||
|
|
|
@ -28,10 +28,17 @@ extern "C" {
|
||||||
#define ISAPNP_ACTIVATE 0x30
|
#define ISAPNP_ACTIVATE 0x30
|
||||||
#define ISAPNP_IORANGECHECK 0x31
|
#define ISAPNP_IORANGECHECK 0x31
|
||||||
|
|
||||||
|
#define ISAPNP_MEMBASE(n) (0x40 + ((n) * 8))
|
||||||
|
#define ISAPNP_MEMCONTROL(n) (0x42 + ((n) * 8))
|
||||||
|
#define MEMORY_UPPER_LIMIT 0x01
|
||||||
|
#define ISAPNP_MEMLIMIT(n) (0x43 + ((n) * 8))
|
||||||
#define ISAPNP_IOBASE(n) (0x60 + ((n)*2))
|
#define ISAPNP_IOBASE(n) (0x60 + ((n)*2))
|
||||||
#define ISAPNP_IRQNO(n) (0x70 + ((n)*2))
|
#define ISAPNP_IRQNO(n) (0x70 + ((n)*2))
|
||||||
#define ISAPNP_IRQTYPE(n) (0x71 + ((n) * 2))
|
#define ISAPNP_IRQTYPE(n) (0x71 + ((n) * 2))
|
||||||
#define ISAPNP_DMACHANNEL(n) (0x74 + (n))
|
#define ISAPNP_DMACHANNEL(n) (0x74 + (n))
|
||||||
|
#define ISAPNP_MEMBASE32(n) ((n) == 0 ? 0x76 : (0x70 + (n) * 16))
|
||||||
|
#define ISAPNP_MEMCONTROL32(n) ((n) == 0 ? 0x7A : (0x74 + (n) * 16))
|
||||||
|
#define ISAPNP_MEMLIMIT32(n) ((n) == 0 ? 0x7B : (0x75 + (n) * 16))
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_RESET (1 << 0)
|
#define ISAPNP_CONFIG_RESET (1 << 0)
|
||||||
#define ISAPNP_CONFIG_WAIT_FOR_KEY (1 << 1)
|
#define ISAPNP_CONFIG_WAIT_FOR_KEY (1 << 1)
|
||||||
|
@ -61,6 +68,9 @@ extern "C" {
|
||||||
#define ISAPNP_TAG_MEM32RANGE 0x85
|
#define ISAPNP_TAG_MEM32RANGE 0x85
|
||||||
#define ISAPNP_TAG_FIXEDMEM32RANGE 0x86
|
#define ISAPNP_TAG_FIXEDMEM32RANGE 0x86
|
||||||
|
|
||||||
|
#define RANGE_LENGTH_TO_LENGTH(RangeLength) ((~(RangeLength) + 1) & 0xFFFFFF)
|
||||||
|
#define LENGTH_TO_RANGE_LENGTH(Length) (~(Length) + 1)
|
||||||
|
|
||||||
#include <pshpack1.h>
|
#include <pshpack1.h>
|
||||||
|
|
||||||
typedef struct _ISAPNP_IDENTIFIER
|
typedef struct _ISAPNP_IDENTIFIER
|
||||||
|
|
|
@ -478,6 +478,13 @@ IsaPdoQueryResources(
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (PdoExt->Common.Signature == IsaPnpLogicalDevice &&
|
||||||
|
!(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES))
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PdoExt->ResourceList)
|
if (!PdoExt->ResourceList)
|
||||||
return Irp->IoStatus.Status;
|
return Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue