1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS ISA PnP Bus driver
38f44930fSDmitry Borisov * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4c2c66affSColin Finck * PURPOSE: Driver entry
58f44930fSDmitry Borisov * COPYRIGHT: Copyright 2010 Cameron Gutman <cameron.gutman@reactos.org>
68f44930fSDmitry Borisov * Copyright 2020 Hervé Poussineau <hpoussin@reactos.org>
7f15de155SDmitry Borisov * Copyright 2021 Dmitry Borisov <di.sean@protonmail.com>
8c2c66affSColin Finck */
9c2c66affSColin Finck
10f15de155SDmitry Borisov /* INCLUDES *******************************************************************/
11f15de155SDmitry Borisov
12b36d9bd9SDmitry Borisov #ifndef UNIT_TEST
1376ec8411SDmitry Borisov
148f44930fSDmitry Borisov #include "isapnp.h"
15b36d9bd9SDmitry Borisov
16c2c66affSColin Finck #define NDEBUG
17c2c66affSColin Finck #include <debug.h>
18c2c66affSColin Finck
19f15de155SDmitry Borisov /* GLOBALS ********************************************************************/
20f15de155SDmitry Borisov
21f15de155SDmitry Borisov KEVENT BusSyncEvent;
22f15de155SDmitry Borisov
23f15de155SDmitry Borisov _Guarded_by_(BusSyncEvent)
2421514e47SDmitry Borisov BOOLEAN ReadPortCreated = FALSE;
2521514e47SDmitry Borisov
26f15de155SDmitry Borisov _Guarded_by_(BusSyncEvent)
27f15de155SDmitry Borisov LIST_ENTRY BusListHead;
28f15de155SDmitry Borisov
29b36d9bd9SDmitry Borisov #endif /* UNIT_TEST */
30b36d9bd9SDmitry Borisov
31*10b08aa2SDmitry Borisov extern ULONG IsaConfigPorts[2];
32*10b08aa2SDmitry Borisov
33f15de155SDmitry Borisov /* FUNCTIONS ******************************************************************/
34f15de155SDmitry Borisov
3567141abeSHervé Poussineau static
3670ba96f1SDmitry Borisov CODE_SEG("PAGE")
378ed43b69SDmitry Borisov VOID
IsaConvertIoRequirement(_Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,_In_ PISAPNP_IO_DESCRIPTION Description)388ed43b69SDmitry Borisov IsaConvertIoRequirement(
398ed43b69SDmitry Borisov _Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,
408ed43b69SDmitry Borisov _In_ PISAPNP_IO_DESCRIPTION Description)
418ed43b69SDmitry Borisov {
428ed43b69SDmitry Borisov PAGED_CODE();
438ed43b69SDmitry Borisov
448ed43b69SDmitry Borisov Descriptor->Type = CmResourceTypePort;
458ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
468ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_PORT_IO;
478ed43b69SDmitry Borisov if (Description->Information & 0x1)
488ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
498ed43b69SDmitry Borisov else
508ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE;
518ed43b69SDmitry Borisov Descriptor->u.Port.Length = Description->Length;
528ed43b69SDmitry Borisov Descriptor->u.Port.Alignment = Description->Alignment;
538ed43b69SDmitry Borisov Descriptor->u.Port.MinimumAddress.LowPart = Description->Minimum;
548ed43b69SDmitry Borisov Descriptor->u.Port.MaximumAddress.LowPart = Description->Maximum +
558ed43b69SDmitry Borisov Description->Length - 1;
568ed43b69SDmitry Borisov }
578ed43b69SDmitry Borisov
588ed43b69SDmitry Borisov static
598ed43b69SDmitry Borisov CODE_SEG("PAGE")
608ed43b69SDmitry Borisov VOID
IsaConvertIrqRequirement(_Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,_In_ PISAPNP_IRQ_DESCRIPTION Description,_In_ ULONG Vector,_In_ BOOLEAN FirstDescriptor)618ed43b69SDmitry Borisov IsaConvertIrqRequirement(
628ed43b69SDmitry Borisov _Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,
638ed43b69SDmitry Borisov _In_ PISAPNP_IRQ_DESCRIPTION Description,
648ed43b69SDmitry Borisov _In_ ULONG Vector,
658ed43b69SDmitry Borisov _In_ BOOLEAN FirstDescriptor)
668ed43b69SDmitry Borisov {
678ed43b69SDmitry Borisov PAGED_CODE();
688ed43b69SDmitry Borisov
698ed43b69SDmitry Borisov if (!FirstDescriptor)
708ed43b69SDmitry Borisov Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
718ed43b69SDmitry Borisov Descriptor->Type = CmResourceTypeInterrupt;
728ed43b69SDmitry Borisov if (Description->Information & 0xC)
738ed43b69SDmitry Borisov {
748ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
758ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareShared;
768ed43b69SDmitry Borisov }
778ed43b69SDmitry Borisov else
788ed43b69SDmitry Borisov {
798ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
808ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
818ed43b69SDmitry Borisov }
828ed43b69SDmitry Borisov Descriptor->u.Interrupt.MinimumVector =
838ed43b69SDmitry Borisov Descriptor->u.Interrupt.MaximumVector = Vector;
848ed43b69SDmitry Borisov }
858ed43b69SDmitry Borisov
868ed43b69SDmitry Borisov static
878ed43b69SDmitry Borisov CODE_SEG("PAGE")
888ed43b69SDmitry Borisov VOID
IsaConvertDmaRequirement(_Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,_In_ PISAPNP_DMA_DESCRIPTION Description,_In_ ULONG Channel,_In_ BOOLEAN FirstDescriptor)898ed43b69SDmitry Borisov IsaConvertDmaRequirement(
908ed43b69SDmitry Borisov _Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,
918ed43b69SDmitry Borisov _In_ PISAPNP_DMA_DESCRIPTION Description,
928ed43b69SDmitry Borisov _In_ ULONG Channel,
938ed43b69SDmitry Borisov _In_ BOOLEAN FirstDescriptor)
948ed43b69SDmitry Borisov {
958ed43b69SDmitry Borisov UNREFERENCED_PARAMETER(Description);
968ed43b69SDmitry Borisov
978ed43b69SDmitry Borisov PAGED_CODE();
988ed43b69SDmitry Borisov
998ed43b69SDmitry Borisov if (!FirstDescriptor)
1008ed43b69SDmitry Borisov Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
1018ed43b69SDmitry Borisov Descriptor->Type = CmResourceTypeDma;
1028ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareUndetermined;
1038ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_DMA_8; /* Ignore information byte for compatibility */
1048ed43b69SDmitry Borisov Descriptor->u.Dma.MinimumChannel =
1058ed43b69SDmitry Borisov Descriptor->u.Dma.MaximumChannel = Channel;
1068ed43b69SDmitry Borisov }
1078ed43b69SDmitry Borisov
1088ed43b69SDmitry Borisov static
1098ed43b69SDmitry Borisov CODE_SEG("PAGE")
1108ed43b69SDmitry Borisov VOID
IsaConvertMemRangeRequirement(_Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,_In_ PISAPNP_MEMRANGE_DESCRIPTION Description)1118ed43b69SDmitry Borisov IsaConvertMemRangeRequirement(
1128ed43b69SDmitry Borisov _Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,
1138ed43b69SDmitry Borisov _In_ PISAPNP_MEMRANGE_DESCRIPTION Description)
1148ed43b69SDmitry Borisov {
1158ed43b69SDmitry Borisov PAGED_CODE();
1168ed43b69SDmitry Borisov
1178ed43b69SDmitry Borisov Descriptor->Type = CmResourceTypeMemory;
1188ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1198ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_MEMORY_24;
1208ed43b69SDmitry Borisov if ((Description->Information & 0x40) || !(Description->Information & 0x01))
1218ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1228ed43b69SDmitry Borisov else
1238ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1248ed43b69SDmitry Borisov Descriptor->u.Memory.Length = Description->Length << 8;
1258ed43b69SDmitry Borisov if (Description->Alignment == 0)
1268ed43b69SDmitry Borisov Descriptor->u.Memory.Alignment = 0x10000;
1278ed43b69SDmitry Borisov else
1288ed43b69SDmitry Borisov Descriptor->u.Memory.Alignment = Description->Alignment;
1298ed43b69SDmitry Borisov Descriptor->u.Memory.MinimumAddress.LowPart = Description->Minimum << 8;
1308ed43b69SDmitry Borisov Descriptor->u.Memory.MaximumAddress.LowPart = (Description->Maximum << 8) +
1318ed43b69SDmitry Borisov (Description->Length << 8) - 1;
1328ed43b69SDmitry Borisov }
1338ed43b69SDmitry Borisov
1348ed43b69SDmitry Borisov static
1358ed43b69SDmitry Borisov CODE_SEG("PAGE")
1368ed43b69SDmitry Borisov VOID
IsaConvertMemRange32Requirement(_Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,_In_ PISAPNP_MEMRANGE32_DESCRIPTION Description)1378ed43b69SDmitry Borisov IsaConvertMemRange32Requirement(
1388ed43b69SDmitry Borisov _Out_ PIO_RESOURCE_DESCRIPTOR Descriptor,
1398ed43b69SDmitry Borisov _In_ PISAPNP_MEMRANGE32_DESCRIPTION Description)
1408ed43b69SDmitry Borisov {
1418ed43b69SDmitry Borisov PAGED_CODE();
1428ed43b69SDmitry Borisov
1438ed43b69SDmitry Borisov Descriptor->Type = CmResourceTypeMemory;
1448ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1458ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_MEMORY_24;
1468ed43b69SDmitry Borisov if ((Description->Information & 0x40) || !(Description->Information & 0x01))
1478ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1488ed43b69SDmitry Borisov else
1498ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1508ed43b69SDmitry Borisov Descriptor->u.Memory.Length = Description->Length;
1518ed43b69SDmitry Borisov Descriptor->u.Memory.Alignment = Description->Alignment;
1528ed43b69SDmitry Borisov Descriptor->u.Memory.MinimumAddress.LowPart = Description->Minimum;
1538ed43b69SDmitry Borisov Descriptor->u.Memory.MaximumAddress.LowPart = Description->Maximum +
1548ed43b69SDmitry Borisov Description->Length - 1;
1558ed43b69SDmitry Borisov }
1568ed43b69SDmitry Borisov
15776ec8411SDmitry Borisov /*
15876ec8411SDmitry Borisov * For example, the PnP ROM
15976ec8411SDmitry Borisov * 0x15, 0x04, ... // Logical device ID
16076ec8411SDmitry Borisov * 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x04, 0x04, // IO 330, len 4, align 4
16176ec8411SDmitry Borisov * 0x30, // **** Start DF ****
16276ec8411SDmitry Borisov * 0x22, 0x04, 0x00, // IRQ 2
16376ec8411SDmitry Borisov * 0x31, 0x02, // **** Start DF ****
16476ec8411SDmitry Borisov * 0x22, 0xC0, 0x00, // IRQ 6 or 7
16576ec8411SDmitry Borisov * 0x38, // **** End DF ******
16676ec8411SDmitry Borisov * 0x2A, 0x20, 0x3A, // DMA 5
16776ec8411SDmitry Borisov * 0x22, 0x00, 0x08, // IRQ 12
16876ec8411SDmitry Borisov * 0x79, 0x00, // END
16976ec8411SDmitry Borisov *
17076ec8411SDmitry Borisov * becomes the following resource requirements list:
17176ec8411SDmitry Borisov * Interface 1 Bus 0 Slot 0 AlternativeLists 2
17276ec8411SDmitry Borisov *
17376ec8411SDmitry Borisov * AltList #0, AltList->Count 4
17476ec8411SDmitry Borisov * [Option 0, ShareDisposition 1, Flags 11] IO: Min 0:330, Max 0:333, Align 4 Len 4
17576ec8411SDmitry Borisov * [Option 0, ShareDisposition 1, Flags 1] INT: Min 2 Max 2
17676ec8411SDmitry Borisov * [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
17776ec8411SDmitry Borisov * [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
17876ec8411SDmitry Borisov *
17976ec8411SDmitry Borisov * AltList #1, AltList->Count 5
18076ec8411SDmitry Borisov * [Option 0, ShareDisposition 1, Flags 11] IO: Min 0:330, Max 0:333, Align 4 Len 4
18176ec8411SDmitry Borisov * [Option 0, ShareDisposition 1, Flags 1] INT: Min 6 Max 6
18276ec8411SDmitry Borisov * [Option 8, ShareDisposition 1, Flags 1] INT: Min 7 Max 7
18376ec8411SDmitry Borisov * [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
18476ec8411SDmitry Borisov * [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
18576ec8411SDmitry Borisov */
1868ed43b69SDmitry Borisov static
1878ed43b69SDmitry Borisov CODE_SEG("PAGE")
18867141abeSHervé Poussineau NTSTATUS
IsaPnpCreateLogicalDeviceRequirements(_In_ PISAPNP_PDO_EXTENSION PdoExt)1898f44930fSDmitry Borisov IsaPnpCreateLogicalDeviceRequirements(
1908f44930fSDmitry Borisov _In_ PISAPNP_PDO_EXTENSION PdoExt)
19167141abeSHervé Poussineau {
19267141abeSHervé Poussineau PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
19367141abeSHervé Poussineau PIO_RESOURCE_DESCRIPTOR Descriptor;
19476ec8411SDmitry Borisov ISAPNP_DEPENDENT_FUNCTION_STATE DfState;
19576ec8411SDmitry Borisov ULONG FirstFixedDescriptors, LastFixedDescriptors;
19676ec8411SDmitry Borisov ULONG ResourceCount, AltListCount, ListSize, i;
19776ec8411SDmitry Borisov BOOLEAN IsFirstAltList, IsFirstDescriptor;
19876ec8411SDmitry Borisov PIO_RESOURCE_LIST AltList;
19976ec8411SDmitry Borisov PISAPNP_RESOURCE Resource;
20067141abeSHervé Poussineau
20170ba96f1SDmitry Borisov PAGED_CODE();
20270ba96f1SDmitry Borisov
20376ec8411SDmitry Borisov /* Count the number of requirements */
20476ec8411SDmitry Borisov DfState = dfNotStarted;
20576ec8411SDmitry Borisov FirstFixedDescriptors = 0;
20676ec8411SDmitry Borisov LastFixedDescriptors = 0;
20776ec8411SDmitry Borisov ResourceCount = 0;
20876ec8411SDmitry Borisov AltListCount = 1;
20976ec8411SDmitry Borisov Resource = PdoExt->IsaPnpDevice->Resources;
21076ec8411SDmitry Borisov while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
21167141abeSHervé Poussineau {
21276ec8411SDmitry Borisov switch (Resource->Type)
21376ec8411SDmitry Borisov {
21476ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_START_DEPENDENT:
21576ec8411SDmitry Borisov {
21676ec8411SDmitry Borisov if (DfState == dfStarted)
21776ec8411SDmitry Borisov ++AltListCount;
2188f44930fSDmitry Borisov
21976ec8411SDmitry Borisov DfState = dfStarted;
22076ec8411SDmitry Borisov break;
22167141abeSHervé Poussineau }
2228f44930fSDmitry Borisov
22376ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_END_DEPENDENT:
22467141abeSHervé Poussineau {
22576ec8411SDmitry Borisov DfState = dfDone;
22676ec8411SDmitry Borisov break;
22776ec8411SDmitry Borisov }
2288ed43b69SDmitry Borisov
22976ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_IRQ:
23076ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_DMA:
2318ed43b69SDmitry Borisov {
23276ec8411SDmitry Borisov RTL_BITMAP ResourceBitmap;
23376ec8411SDmitry Borisov ULONG BitmapSize, BitmapBuffer, BitCount;
2348ed43b69SDmitry Borisov
23576ec8411SDmitry Borisov if (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ)
2368ed43b69SDmitry Borisov {
23776ec8411SDmitry Borisov BitmapSize = RTL_BITS_OF(Resource->IrqDescription.Mask);
23876ec8411SDmitry Borisov BitmapBuffer = Resource->IrqDescription.Mask;
2398ed43b69SDmitry Borisov }
2408ed43b69SDmitry Borisov else
2418ed43b69SDmitry Borisov {
24276ec8411SDmitry Borisov BitmapSize = RTL_BITS_OF(Resource->DmaDescription.Mask);
24376ec8411SDmitry Borisov BitmapBuffer = Resource->DmaDescription.Mask;
2448ed43b69SDmitry Borisov }
24576ec8411SDmitry Borisov RtlInitializeBitMap(&ResourceBitmap, &BitmapBuffer, BitmapSize);
24676ec8411SDmitry Borisov
24776ec8411SDmitry Borisov BitCount = RtlNumberOfSetBits(&ResourceBitmap);
24876ec8411SDmitry Borisov switch (DfState)
24976ec8411SDmitry Borisov {
25076ec8411SDmitry Borisov case dfNotStarted:
25176ec8411SDmitry Borisov FirstFixedDescriptors += BitCount;
25276ec8411SDmitry Borisov break;
25376ec8411SDmitry Borisov
25476ec8411SDmitry Borisov case dfStarted:
25576ec8411SDmitry Borisov ResourceCount += BitCount;
25676ec8411SDmitry Borisov break;
25776ec8411SDmitry Borisov
25876ec8411SDmitry Borisov case dfDone:
25976ec8411SDmitry Borisov LastFixedDescriptors += BitCount;
26076ec8411SDmitry Borisov break;
26176ec8411SDmitry Borisov
26276ec8411SDmitry Borisov DEFAULT_UNREACHABLE;
26376ec8411SDmitry Borisov }
26476ec8411SDmitry Borisov
26576ec8411SDmitry Borisov break;
26676ec8411SDmitry Borisov }
26776ec8411SDmitry Borisov
26876ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_IO:
26976ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_MEMRANGE:
27076ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
27176ec8411SDmitry Borisov {
27276ec8411SDmitry Borisov switch (DfState)
27376ec8411SDmitry Borisov {
27476ec8411SDmitry Borisov case dfNotStarted:
27576ec8411SDmitry Borisov ++FirstFixedDescriptors;
27676ec8411SDmitry Borisov break;
27776ec8411SDmitry Borisov
27876ec8411SDmitry Borisov case dfStarted:
27976ec8411SDmitry Borisov ++ResourceCount;
28076ec8411SDmitry Borisov break;
28176ec8411SDmitry Borisov
28276ec8411SDmitry Borisov case dfDone:
28376ec8411SDmitry Borisov ++LastFixedDescriptors;
28476ec8411SDmitry Borisov break;
28576ec8411SDmitry Borisov
28676ec8411SDmitry Borisov DEFAULT_UNREACHABLE;
28776ec8411SDmitry Borisov }
28876ec8411SDmitry Borisov break;
28976ec8411SDmitry Borisov }
29076ec8411SDmitry Borisov
29176ec8411SDmitry Borisov default:
29276ec8411SDmitry Borisov ASSERT(FALSE);
29376ec8411SDmitry Borisov UNREACHABLE;
29476ec8411SDmitry Borisov break;
29576ec8411SDmitry Borisov }
29676ec8411SDmitry Borisov
29776ec8411SDmitry Borisov ++Resource;
29876ec8411SDmitry Borisov }
29976ec8411SDmitry Borisov
30076ec8411SDmitry Borisov /* This logical device has no resource requirements */
30176ec8411SDmitry Borisov if ((ResourceCount == 0) && (FirstFixedDescriptors == 0) && (LastFixedDescriptors == 0))
30276ec8411SDmitry Borisov return STATUS_SUCCESS;
30376ec8411SDmitry Borisov
30476ec8411SDmitry Borisov /* Allocate memory to store requirements */
30576ec8411SDmitry Borisov ListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
30676ec8411SDmitry Borisov FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) * AltListCount +
30776ec8411SDmitry Borisov sizeof(IO_RESOURCE_DESCRIPTOR) * ResourceCount +
30876ec8411SDmitry Borisov sizeof(IO_RESOURCE_DESCRIPTOR) * AltListCount *
30976ec8411SDmitry Borisov (FirstFixedDescriptors + LastFixedDescriptors);
31066c19575SDmitry Borisov RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
31167141abeSHervé Poussineau if (!RequirementsList)
31267141abeSHervé Poussineau return STATUS_NO_MEMORY;
31367141abeSHervé Poussineau
31467141abeSHervé Poussineau RequirementsList->ListSize = ListSize;
31567141abeSHervé Poussineau RequirementsList->InterfaceType = Isa;
31676ec8411SDmitry Borisov RequirementsList->AlternativeLists = AltListCount;
31767141abeSHervé Poussineau
31867141abeSHervé Poussineau RequirementsList->List[0].Version = 1;
31967141abeSHervé Poussineau RequirementsList->List[0].Revision = 1;
32067141abeSHervé Poussineau
32167141abeSHervé Poussineau /* Store requirements */
32276ec8411SDmitry Borisov IsFirstAltList = TRUE;
32376ec8411SDmitry Borisov AltList = &RequirementsList->List[0];
32476ec8411SDmitry Borisov Descriptor = &RequirementsList->List[0].Descriptors[0];
32576ec8411SDmitry Borisov Resource = PdoExt->IsaPnpDevice->Resources;
32676ec8411SDmitry Borisov while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
32767141abeSHervé Poussineau {
32876ec8411SDmitry Borisov switch (Resource->Type)
32967141abeSHervé Poussineau {
33076ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_START_DEPENDENT:
33167141abeSHervé Poussineau {
33276ec8411SDmitry Borisov if (!IsFirstAltList)
3337cda1ed2SHervé Poussineau {
33476ec8411SDmitry Borisov /* Add room for the fixed descriptors */
33576ec8411SDmitry Borisov AltList->Count += LastFixedDescriptors;
3368f44930fSDmitry Borisov
33776ec8411SDmitry Borisov /* Move on to the next list */
33876ec8411SDmitry Borisov AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count);
33976ec8411SDmitry Borisov AltList->Version = 1;
34076ec8411SDmitry Borisov AltList->Revision = 1;
3418ed43b69SDmitry Borisov
3428ed43b69SDmitry Borisov /* Propagate the fixed resources to our new list */
34376ec8411SDmitry Borisov RtlCopyMemory(&AltList->Descriptors,
34476ec8411SDmitry Borisov RequirementsList->List[0].Descriptors,
34576ec8411SDmitry Borisov sizeof(IO_RESOURCE_DESCRIPTOR) * FirstFixedDescriptors);
34676ec8411SDmitry Borisov AltList->Count += FirstFixedDescriptors;
34776ec8411SDmitry Borisov
34876ec8411SDmitry Borisov Descriptor = &AltList->Descriptors[FirstFixedDescriptors];
3498ed43b69SDmitry Borisov }
3508ed43b69SDmitry Borisov
35176ec8411SDmitry Borisov IsFirstAltList = FALSE;
35276ec8411SDmitry Borisov break;
3538ed43b69SDmitry Borisov }
3548ed43b69SDmitry Borisov
35576ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_END_DEPENDENT:
35676ec8411SDmitry Borisov break;
35776ec8411SDmitry Borisov
35876ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_IO:
3598ed43b69SDmitry Borisov {
36076ec8411SDmitry Borisov IsaConvertIoRequirement(Descriptor++, &Resource->IoDescription);
36176ec8411SDmitry Borisov
36276ec8411SDmitry Borisov ++AltList->Count;
36376ec8411SDmitry Borisov break;
36476ec8411SDmitry Borisov }
36576ec8411SDmitry Borisov
36676ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_IRQ:
36776ec8411SDmitry Borisov {
36876ec8411SDmitry Borisov IsFirstDescriptor = TRUE;
36976ec8411SDmitry Borisov
37076ec8411SDmitry Borisov for (i = 0; i < RTL_BITS_OF(Resource->IrqDescription.Mask); i++)
37176ec8411SDmitry Borisov {
37276ec8411SDmitry Borisov if (!(Resource->IrqDescription.Mask & (1 << i)))
3738ed43b69SDmitry Borisov continue;
3748ed43b69SDmitry Borisov
3758ed43b69SDmitry Borisov IsaConvertIrqRequirement(Descriptor++,
37676ec8411SDmitry Borisov &Resource->IrqDescription,
37776ec8411SDmitry Borisov i,
37876ec8411SDmitry Borisov IsFirstDescriptor);
37976ec8411SDmitry Borisov ++AltList->Count;
3808ed43b69SDmitry Borisov
38176ec8411SDmitry Borisov IsFirstDescriptor = FALSE;
3827cda1ed2SHervé Poussineau }
3838ed43b69SDmitry Borisov
38476ec8411SDmitry Borisov break;
38576ec8411SDmitry Borisov }
38676ec8411SDmitry Borisov
38776ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_DMA:
3888ed43b69SDmitry Borisov {
38976ec8411SDmitry Borisov IsFirstDescriptor = TRUE;
39076ec8411SDmitry Borisov
39176ec8411SDmitry Borisov for (i = 0; i < RTL_BITS_OF(Resource->DmaDescription.Mask); i++)
39276ec8411SDmitry Borisov {
39376ec8411SDmitry Borisov if (!(Resource->DmaDescription.Mask & (1 << i)))
3948ed43b69SDmitry Borisov continue;
3958ed43b69SDmitry Borisov
3968ed43b69SDmitry Borisov IsaConvertDmaRequirement(Descriptor++,
39776ec8411SDmitry Borisov &Resource->DmaDescription,
39876ec8411SDmitry Borisov i,
39976ec8411SDmitry Borisov IsFirstDescriptor);
40076ec8411SDmitry Borisov ++AltList->Count;
4018ed43b69SDmitry Borisov
40276ec8411SDmitry Borisov IsFirstDescriptor = FALSE;
4038ed43b69SDmitry Borisov }
40476ec8411SDmitry Borisov
40576ec8411SDmitry Borisov break;
4068ed43b69SDmitry Borisov }
40776ec8411SDmitry Borisov
40876ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_MEMRANGE:
4098ed43b69SDmitry Borisov {
41076ec8411SDmitry Borisov IsaConvertMemRangeRequirement(Descriptor++, &Resource->MemRangeDescription);
41176ec8411SDmitry Borisov
41276ec8411SDmitry Borisov ++AltList->Count;
41376ec8411SDmitry Borisov break;
4148ed43b69SDmitry Borisov }
41576ec8411SDmitry Borisov
41676ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
4178ed43b69SDmitry Borisov {
41876ec8411SDmitry Borisov IsaConvertMemRange32Requirement(Descriptor++, &Resource->MemRange32Description);
41976ec8411SDmitry Borisov
42076ec8411SDmitry Borisov ++AltList->Count;
42176ec8411SDmitry Borisov break;
4228ed43b69SDmitry Borisov }
4238ed43b69SDmitry Borisov
42476ec8411SDmitry Borisov default:
42576ec8411SDmitry Borisov ASSERT(FALSE);
42676ec8411SDmitry Borisov UNREACHABLE;
42776ec8411SDmitry Borisov break;
42876ec8411SDmitry Borisov }
42976ec8411SDmitry Borisov
43076ec8411SDmitry Borisov ++Resource;
43176ec8411SDmitry Borisov }
43276ec8411SDmitry Borisov
43376ec8411SDmitry Borisov /* Append the fixed resources */
43476ec8411SDmitry Borisov if (LastFixedDescriptors)
43576ec8411SDmitry Borisov {
43676ec8411SDmitry Borisov PIO_RESOURCE_LIST NextList = &RequirementsList->List[0];
43776ec8411SDmitry Borisov
43876ec8411SDmitry Borisov /* Make the descriptor point to the fixed resources */
43976ec8411SDmitry Borisov Descriptor -= LastFixedDescriptors;
44076ec8411SDmitry Borisov
44176ec8411SDmitry Borisov /* Propagate the fixed resources onto previous lists */
44276ec8411SDmitry Borisov AltListCount = RequirementsList->AlternativeLists - 1;
44376ec8411SDmitry Borisov for (i = 0; i < AltListCount; i++)
44476ec8411SDmitry Borisov {
44576ec8411SDmitry Borisov RtlCopyMemory(&NextList->Descriptors[NextList->Count - LastFixedDescriptors],
44676ec8411SDmitry Borisov Descriptor,
44776ec8411SDmitry Borisov sizeof(IO_RESOURCE_DESCRIPTOR) * LastFixedDescriptors);
44876ec8411SDmitry Borisov
4498ed43b69SDmitry Borisov NextList = (PIO_RESOURCE_LIST)(NextList->Descriptors + NextList->Count);
4507cda1ed2SHervé Poussineau }
4517cda1ed2SHervé Poussineau }
45267141abeSHervé Poussineau
45367141abeSHervé Poussineau PdoExt->RequirementsList = RequirementsList;
45467141abeSHervé Poussineau return STATUS_SUCCESS;
45567141abeSHervé Poussineau }
45667141abeSHervé Poussineau
4578ed43b69SDmitry Borisov CODE_SEG("PAGE")
4588ed43b69SDmitry Borisov BOOLEAN
FindIoDescriptor(_In_ PISAPNP_LOGICAL_DEVICE LogDevice,_In_opt_ ULONG Base,_In_ ULONG RangeStart,_In_ ULONG RangeEnd,_Out_opt_ PUCHAR Information,_Out_opt_ PULONG Length)4598ed43b69SDmitry Borisov FindIoDescriptor(
4608ed43b69SDmitry Borisov _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
4618ed43b69SDmitry Borisov _In_opt_ ULONG Base,
4628ed43b69SDmitry Borisov _In_ ULONG RangeStart,
4638ed43b69SDmitry Borisov _In_ ULONG RangeEnd,
4648ed43b69SDmitry Borisov _Out_opt_ PUCHAR Information,
46576ec8411SDmitry Borisov _Out_opt_ PULONG Length)
4668ed43b69SDmitry Borisov {
46776ec8411SDmitry Borisov PISAPNP_RESOURCE Resource;
4688ed43b69SDmitry Borisov
4698ed43b69SDmitry Borisov PAGED_CODE();
4708ed43b69SDmitry Borisov
47176ec8411SDmitry Borisov Resource = LogDevice->Resources;
47276ec8411SDmitry Borisov while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
4738ed43b69SDmitry Borisov {
47476ec8411SDmitry Borisov if (Resource->Type == ISAPNP_RESOURCE_TYPE_IO)
47576ec8411SDmitry Borisov {
47676ec8411SDmitry Borisov PISAPNP_IO_DESCRIPTION Description = &Resource->IoDescription;
47776ec8411SDmitry Borisov BOOLEAN Match;
4788ed43b69SDmitry Borisov
47976ec8411SDmitry Borisov if (Base)
48076ec8411SDmitry Borisov {
48176ec8411SDmitry Borisov Match = (Base >= Description->Minimum) && (Base <= Description->Maximum);
48276ec8411SDmitry Borisov }
48376ec8411SDmitry Borisov else
48476ec8411SDmitry Borisov {
48576ec8411SDmitry Borisov Match = (RangeStart >= Description->Minimum) &&
4868ed43b69SDmitry Borisov (RangeEnd <= (ULONG)(Description->Maximum + Description->Length - 1));
48776ec8411SDmitry Borisov }
4888ed43b69SDmitry Borisov
4898ed43b69SDmitry Borisov if (Match)
4908ed43b69SDmitry Borisov {
4918ed43b69SDmitry Borisov if (Information)
4928ed43b69SDmitry Borisov *Information = Description->Information;
4938ed43b69SDmitry Borisov if (Length)
4948ed43b69SDmitry Borisov *Length = Description->Length;
4958ed43b69SDmitry Borisov
4968ed43b69SDmitry Borisov return TRUE;
4978ed43b69SDmitry Borisov }
4988ed43b69SDmitry Borisov }
4998ed43b69SDmitry Borisov
50076ec8411SDmitry Borisov ++Resource;
5018ed43b69SDmitry Borisov }
5028ed43b69SDmitry Borisov
5038ed43b69SDmitry Borisov return FALSE;
5048ed43b69SDmitry Borisov }
5058ed43b69SDmitry Borisov
5068ed43b69SDmitry Borisov CODE_SEG("PAGE")
5078ed43b69SDmitry Borisov BOOLEAN
FindIrqDescriptor(_In_ PISAPNP_LOGICAL_DEVICE LogDevice,_In_ ULONG Vector)5088ed43b69SDmitry Borisov FindIrqDescriptor(
5098ed43b69SDmitry Borisov _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
51076ec8411SDmitry Borisov _In_ ULONG Vector)
5118ed43b69SDmitry Borisov {
51276ec8411SDmitry Borisov PISAPNP_RESOURCE Resource;
5138ed43b69SDmitry Borisov
5148ed43b69SDmitry Borisov PAGED_CODE();
5158ed43b69SDmitry Borisov
51676ec8411SDmitry Borisov Resource = LogDevice->Resources;
51776ec8411SDmitry Borisov while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
5188ed43b69SDmitry Borisov {
51976ec8411SDmitry Borisov if (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ)
52076ec8411SDmitry Borisov {
52176ec8411SDmitry Borisov PISAPNP_IRQ_DESCRIPTION Description = &Resource->IrqDescription;
5228ed43b69SDmitry Borisov
52376ec8411SDmitry Borisov if (Description->Mask & (1 << Vector))
5248ed43b69SDmitry Borisov return TRUE;
5258ed43b69SDmitry Borisov }
5268ed43b69SDmitry Borisov
52776ec8411SDmitry Borisov ++Resource;
5288ed43b69SDmitry Borisov }
5298ed43b69SDmitry Borisov
5308ed43b69SDmitry Borisov return FALSE;
5318ed43b69SDmitry Borisov }
5328ed43b69SDmitry Borisov
5338ed43b69SDmitry Borisov CODE_SEG("PAGE")
5348ed43b69SDmitry Borisov BOOLEAN
FindDmaDescriptor(_In_ PISAPNP_LOGICAL_DEVICE LogDevice,_In_ ULONG Channel)5358ed43b69SDmitry Borisov FindDmaDescriptor(
5368ed43b69SDmitry Borisov _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
53776ec8411SDmitry Borisov _In_ ULONG Channel)
5388ed43b69SDmitry Borisov {
53976ec8411SDmitry Borisov PISAPNP_RESOURCE Resource;
5408ed43b69SDmitry Borisov
5418ed43b69SDmitry Borisov PAGED_CODE();
5428ed43b69SDmitry Borisov
54376ec8411SDmitry Borisov Resource = LogDevice->Resources;
54476ec8411SDmitry Borisov while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
5458ed43b69SDmitry Borisov {
54676ec8411SDmitry Borisov if (Resource->Type == ISAPNP_RESOURCE_TYPE_DMA)
54776ec8411SDmitry Borisov {
54876ec8411SDmitry Borisov PISAPNP_DMA_DESCRIPTION Description = &Resource->DmaDescription;
5498ed43b69SDmitry Borisov
55076ec8411SDmitry Borisov if (Description->Mask & (1 << Channel))
5518ed43b69SDmitry Borisov return TRUE;
5528ed43b69SDmitry Borisov }
5538ed43b69SDmitry Borisov
55476ec8411SDmitry Borisov ++Resource;
5558ed43b69SDmitry Borisov }
5568ed43b69SDmitry Borisov
5578ed43b69SDmitry Borisov return FALSE;
5588ed43b69SDmitry Borisov }
5598ed43b69SDmitry Borisov
5608ed43b69SDmitry Borisov CODE_SEG("PAGE")
5618ed43b69SDmitry Borisov BOOLEAN
FindMemoryDescriptor(_In_ PISAPNP_LOGICAL_DEVICE LogDevice,_In_ ULONG RangeStart,_In_ ULONG RangeEnd,_Out_opt_ PUCHAR Information)5628ed43b69SDmitry Borisov FindMemoryDescriptor(
5638ed43b69SDmitry Borisov _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
5648ed43b69SDmitry Borisov _In_ ULONG RangeStart,
5658ed43b69SDmitry Borisov _In_ ULONG RangeEnd,
56676ec8411SDmitry Borisov _Out_opt_ PUCHAR Information)
5678ed43b69SDmitry Borisov {
56876ec8411SDmitry Borisov PISAPNP_RESOURCE Resource;
5698ed43b69SDmitry Borisov
5708ed43b69SDmitry Borisov PAGED_CODE();
5718ed43b69SDmitry Borisov
57276ec8411SDmitry Borisov Resource = LogDevice->Resources;
57376ec8411SDmitry Borisov while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
5748ed43b69SDmitry Borisov {
57576ec8411SDmitry Borisov switch (Resource->Type)
57676ec8411SDmitry Borisov {
57776ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_MEMRANGE:
57876ec8411SDmitry Borisov {
57976ec8411SDmitry Borisov PISAPNP_MEMRANGE_DESCRIPTION Description;
58076ec8411SDmitry Borisov
58176ec8411SDmitry Borisov Description = &Resource->MemRangeDescription;
5828ed43b69SDmitry Borisov
5838ed43b69SDmitry Borisov if ((RangeStart >= (ULONG)(Description->Minimum << 8)) &&
58476ec8411SDmitry Borisov (RangeEnd <= (ULONG)((Description->Maximum << 8) +
58576ec8411SDmitry Borisov (Description->Length << 8) - 1)))
5868ed43b69SDmitry Borisov {
5878ed43b69SDmitry Borisov if (Information)
5888ed43b69SDmitry Borisov *Information = Description->Information;
5898ed43b69SDmitry Borisov
5908ed43b69SDmitry Borisov return TRUE;
5918ed43b69SDmitry Borisov }
59276ec8411SDmitry Borisov break;
5938ed43b69SDmitry Borisov }
59476ec8411SDmitry Borisov
59576ec8411SDmitry Borisov case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
5968ed43b69SDmitry Borisov {
59776ec8411SDmitry Borisov PISAPNP_MEMRANGE32_DESCRIPTION Description32;
59876ec8411SDmitry Borisov
59976ec8411SDmitry Borisov Description32 = &Resource->MemRange32Description;
6008ed43b69SDmitry Borisov
6018ed43b69SDmitry Borisov if ((RangeStart >= Description32->Minimum) &&
6028ed43b69SDmitry Borisov (RangeEnd <= (Description32->Maximum + Description32->Length - 1)))
6038ed43b69SDmitry Borisov {
6048ed43b69SDmitry Borisov if (Information)
6058ed43b69SDmitry Borisov *Information = Description32->Information;
6068ed43b69SDmitry Borisov
6078ed43b69SDmitry Borisov return TRUE;
6088ed43b69SDmitry Borisov }
60976ec8411SDmitry Borisov break;
6108ed43b69SDmitry Borisov }
6118ed43b69SDmitry Borisov
61276ec8411SDmitry Borisov default:
61376ec8411SDmitry Borisov break;
6148ed43b69SDmitry Borisov }
6158ed43b69SDmitry Borisov
61676ec8411SDmitry Borisov ++Resource;
6178ed43b69SDmitry Borisov }
6188ed43b69SDmitry Borisov
6198ed43b69SDmitry Borisov return FALSE;
6208ed43b69SDmitry Borisov }
6218ed43b69SDmitry Borisov
62267141abeSHervé Poussineau static
62370ba96f1SDmitry Borisov CODE_SEG("PAGE")
62467141abeSHervé Poussineau NTSTATUS
IsaPnpCreateLogicalDeviceResources(_In_ PISAPNP_PDO_EXTENSION PdoExt)6258f44930fSDmitry Borisov IsaPnpCreateLogicalDeviceResources(
6268f44930fSDmitry Borisov _In_ PISAPNP_PDO_EXTENSION PdoExt)
62767141abeSHervé Poussineau {
62867141abeSHervé Poussineau PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
62967141abeSHervé Poussineau ULONG ResourceCount = 0;
6308ed43b69SDmitry Borisov UCHAR Information;
63167141abeSHervé Poussineau ULONG ListSize, i;
63267141abeSHervé Poussineau PCM_RESOURCE_LIST ResourceList;
63367141abeSHervé Poussineau PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
63467141abeSHervé Poussineau
63570ba96f1SDmitry Borisov PAGED_CODE();
63670ba96f1SDmitry Borisov
6378ed43b69SDmitry Borisov if (!(LogDev->Flags & ISAPNP_HAS_RESOURCES))
6388ed43b69SDmitry Borisov return STATUS_SUCCESS;
6398ed43b69SDmitry Borisov
64067141abeSHervé Poussineau /* Count number of required resources */
6418f44930fSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
64267141abeSHervé Poussineau {
64367141abeSHervé Poussineau if (LogDev->Io[i].CurrentBase)
64467141abeSHervé Poussineau ResourceCount++;
64567141abeSHervé Poussineau else
64667141abeSHervé Poussineau break;
64767141abeSHervé Poussineau }
6488f44930fSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->Irq); i++)
64967141abeSHervé Poussineau {
65067141abeSHervé Poussineau if (LogDev->Irq[i].CurrentNo)
65167141abeSHervé Poussineau ResourceCount++;
65267141abeSHervé Poussineau else
65367141abeSHervé Poussineau break;
65467141abeSHervé Poussineau }
6558f44930fSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
6567cda1ed2SHervé Poussineau {
6572981e63aSDmitry Borisov if (LogDev->Dma[i].CurrentChannel != DMACHANNEL_NONE)
6587cda1ed2SHervé Poussineau ResourceCount++;
6597cda1ed2SHervé Poussineau else
6607cda1ed2SHervé Poussineau break;
6617cda1ed2SHervé Poussineau }
6628ed43b69SDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange); i++)
6638ed43b69SDmitry Borisov {
6648ed43b69SDmitry Borisov if (LogDev->MemRange[i].CurrentBase)
6658ed43b69SDmitry Borisov ResourceCount++;
6668ed43b69SDmitry Borisov else
6678ed43b69SDmitry Borisov break;
6688ed43b69SDmitry Borisov }
6698ed43b69SDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++)
6708ed43b69SDmitry Borisov {
6718ed43b69SDmitry Borisov if (LogDev->MemRange32[i].CurrentBase)
6728ed43b69SDmitry Borisov ResourceCount++;
6738ed43b69SDmitry Borisov else
6748ed43b69SDmitry Borisov break;
6758ed43b69SDmitry Borisov }
67667141abeSHervé Poussineau if (ResourceCount == 0)
67767141abeSHervé Poussineau return STATUS_SUCCESS;
67867141abeSHervé Poussineau
67967141abeSHervé Poussineau /* Allocate memory to store resources */
68067141abeSHervé Poussineau ListSize = sizeof(CM_RESOURCE_LIST)
68167141abeSHervé Poussineau + (ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
68266c19575SDmitry Borisov ResourceList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
68367141abeSHervé Poussineau if (!ResourceList)
68467141abeSHervé Poussineau return STATUS_NO_MEMORY;
68567141abeSHervé Poussineau
68667141abeSHervé Poussineau ResourceList->Count = 1;
68767141abeSHervé Poussineau ResourceList->List[0].InterfaceType = Isa;
68867141abeSHervé Poussineau ResourceList->List[0].PartialResourceList.Version = 1;
68967141abeSHervé Poussineau ResourceList->List[0].PartialResourceList.Revision = 1;
69067141abeSHervé Poussineau ResourceList->List[0].PartialResourceList.Count = ResourceCount;
69167141abeSHervé Poussineau
69267141abeSHervé Poussineau /* Store resources */
69367141abeSHervé Poussineau ResourceCount = 0;
6948f44930fSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
69567141abeSHervé Poussineau {
6968ed43b69SDmitry Borisov ULONG CurrentLength;
6978ed43b69SDmitry Borisov
69867141abeSHervé Poussineau if (!LogDev->Io[i].CurrentBase)
6998f36dee6SDmitry Borisov break;
7008f44930fSDmitry Borisov
7018ed43b69SDmitry Borisov if (!FindIoDescriptor(LogDev,
7028ed43b69SDmitry Borisov LogDev->Io[i].CurrentBase,
7038ed43b69SDmitry Borisov 0,
7048ed43b69SDmitry Borisov 0,
7058ed43b69SDmitry Borisov &Information,
70676ec8411SDmitry Borisov &CurrentLength))
7078ed43b69SDmitry Borisov {
70876ec8411SDmitry Borisov DPRINT1("I/O entry #%lu %x not found\n", i, LogDev->Io[i].CurrentBase);
7098ed43b69SDmitry Borisov goto InvalidBiosResources;
7108ed43b69SDmitry Borisov }
7118ed43b69SDmitry Borisov
71267141abeSHervé Poussineau Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
71367141abeSHervé Poussineau Descriptor->Type = CmResourceTypePort;
71467141abeSHervé Poussineau Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
7158ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_PORT_IO;
7168ed43b69SDmitry Borisov if (Information & 0x1)
7178ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
71867141abeSHervé Poussineau else
7198ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE;
7208ed43b69SDmitry Borisov Descriptor->u.Port.Length = CurrentLength;
72167141abeSHervé Poussineau Descriptor->u.Port.Start.LowPart = LogDev->Io[i].CurrentBase;
72267141abeSHervé Poussineau }
7238f44930fSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->Irq); i++)
72467141abeSHervé Poussineau {
72567141abeSHervé Poussineau if (!LogDev->Irq[i].CurrentNo)
7268f36dee6SDmitry Borisov break;
7278f44930fSDmitry Borisov
72867141abeSHervé Poussineau Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
72967141abeSHervé Poussineau Descriptor->Type = CmResourceTypeInterrupt;
73067141abeSHervé Poussineau Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
73167141abeSHervé Poussineau if (LogDev->Irq[i].CurrentType & 0x01)
73267141abeSHervé Poussineau Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
73367141abeSHervé Poussineau else
73467141abeSHervé Poussineau Descriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
73567141abeSHervé Poussineau Descriptor->u.Interrupt.Level = LogDev->Irq[i].CurrentNo;
73667141abeSHervé Poussineau Descriptor->u.Interrupt.Vector = LogDev->Irq[i].CurrentNo;
73776ec8411SDmitry Borisov Descriptor->u.Interrupt.Affinity = (KAFFINITY)-1;
73867141abeSHervé Poussineau }
7398f44930fSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
7407cda1ed2SHervé Poussineau {
7412981e63aSDmitry Borisov if (LogDev->Dma[i].CurrentChannel == DMACHANNEL_NONE)
7428f36dee6SDmitry Borisov break;
7438f44930fSDmitry Borisov
7447cda1ed2SHervé Poussineau Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
7457cda1ed2SHervé Poussineau Descriptor->Type = CmResourceTypeDma;
7467cda1ed2SHervé Poussineau Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
7478ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_DMA_8; /* Ignore information byte for compatibility */
7487cda1ed2SHervé Poussineau Descriptor->u.Dma.Channel = LogDev->Dma[i].CurrentChannel;
7497cda1ed2SHervé Poussineau }
7508ed43b69SDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange); i++)
7518ed43b69SDmitry Borisov {
7528ed43b69SDmitry Borisov if (!LogDev->MemRange[i].CurrentBase)
7538ed43b69SDmitry Borisov break;
7548ed43b69SDmitry Borisov
7558ed43b69SDmitry Borisov if (!FindMemoryDescriptor(LogDev,
7568ed43b69SDmitry Borisov LogDev->MemRange[i].CurrentBase,
7578ed43b69SDmitry Borisov LogDev->MemRange[i].CurrentLength,
75876ec8411SDmitry Borisov &Information))
7598ed43b69SDmitry Borisov {
76076ec8411SDmitry Borisov DPRINT1("MEM entry #%lu %lx %lx not found\n",
76176ec8411SDmitry Borisov i,
76276ec8411SDmitry Borisov LogDev->MemRange[i].CurrentBase,
76376ec8411SDmitry Borisov LogDev->MemRange[i].CurrentLength);
7648ed43b69SDmitry Borisov goto InvalidBiosResources;
7658ed43b69SDmitry Borisov }
7668ed43b69SDmitry Borisov
7678ed43b69SDmitry Borisov Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
7688ed43b69SDmitry Borisov Descriptor->Type = CmResourceTypeMemory;
7698ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
7708ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_MEMORY_24;
7718ed43b69SDmitry Borisov if ((Information & 0x40) || !(Information & 0x01))
7728ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
7738ed43b69SDmitry Borisov else
7748ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
775c1d70873SDmitry Borisov Descriptor->u.Memory.Length = LogDev->MemRange[i].CurrentLength;
7768ed43b69SDmitry Borisov Descriptor->u.Memory.Start.QuadPart = LogDev->MemRange[i].CurrentBase;
7778ed43b69SDmitry Borisov }
7788ed43b69SDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++)
7798ed43b69SDmitry Borisov {
7808ed43b69SDmitry Borisov if (!LogDev->MemRange32[i].CurrentBase)
7818ed43b69SDmitry Borisov break;
7828ed43b69SDmitry Borisov
7838ed43b69SDmitry Borisov if (!FindMemoryDescriptor(LogDev,
7848ed43b69SDmitry Borisov LogDev->MemRange32[i].CurrentBase,
7858ed43b69SDmitry Borisov LogDev->MemRange32[i].CurrentLength,
78676ec8411SDmitry Borisov &Information))
7878ed43b69SDmitry Borisov {
78876ec8411SDmitry Borisov DPRINT1("MEM32 entry #%lu %lx %lx not found\n",
78976ec8411SDmitry Borisov i,
79076ec8411SDmitry Borisov LogDev->MemRange32[i].CurrentBase,
79176ec8411SDmitry Borisov LogDev->MemRange32[i].CurrentLength);
7928ed43b69SDmitry Borisov goto InvalidBiosResources;
7938ed43b69SDmitry Borisov }
7948ed43b69SDmitry Borisov
7958ed43b69SDmitry Borisov Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
7968ed43b69SDmitry Borisov Descriptor->Type = CmResourceTypeMemory;
7978ed43b69SDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
7988ed43b69SDmitry Borisov Descriptor->Flags = CM_RESOURCE_MEMORY_24;
7998ed43b69SDmitry Borisov if ((Information & 0x40) || !(Information & 0x01))
8008ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
8018ed43b69SDmitry Borisov else
8028ed43b69SDmitry Borisov Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
803c1d70873SDmitry Borisov Descriptor->u.Memory.Length = LogDev->MemRange32[i].CurrentLength;
8048ed43b69SDmitry Borisov Descriptor->u.Memory.Start.QuadPart = LogDev->MemRange32[i].CurrentBase;
8058ed43b69SDmitry Borisov }
80667141abeSHervé Poussineau
80767141abeSHervé Poussineau PdoExt->ResourceList = ResourceList;
80867141abeSHervé Poussineau PdoExt->ResourceListSize = ListSize;
80967141abeSHervé Poussineau return STATUS_SUCCESS;
8108ed43b69SDmitry Borisov
8118ed43b69SDmitry Borisov InvalidBiosResources:
81276ec8411SDmitry Borisov DPRINT1("Invalid boot resources! (CSN %u, LDN %u)\n", LogDev->CSN, LogDev->LDN);
8138ed43b69SDmitry Borisov
8148ed43b69SDmitry Borisov LogDev->Flags &= ~ISAPNP_HAS_RESOURCES;
8158ed43b69SDmitry Borisov ExFreePoolWithTag(ResourceList, TAG_ISAPNP);
8168ed43b69SDmitry Borisov return STATUS_SUCCESS;
81767141abeSHervé Poussineau }
81867141abeSHervé Poussineau
81970ba96f1SDmitry Borisov CODE_SEG("PAGE")
8204ba8a8b5SDmitry Borisov PIO_RESOURCE_REQUIREMENTS_LIST
IsaPnpCreateReadPortDORequirements(_In_opt_ ULONG SelectedReadPort)821debec8c9SHervé Poussineau IsaPnpCreateReadPortDORequirements(
822c4b6330bSDmitry Borisov _In_opt_ ULONG SelectedReadPort)
823debec8c9SHervé Poussineau {
824c4b6330bSDmitry Borisov ULONG ResourceCount, ListSize, i;
825debec8c9SHervé Poussineau PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
826debec8c9SHervé Poussineau PIO_RESOURCE_DESCRIPTOR Descriptor;
827c4b6330bSDmitry Borisov const ULONG ReadPorts[] = { 0x274, 0x3E4, 0x204, 0x2E4, 0x354, 0x2F4 };
828debec8c9SHervé Poussineau
82970ba96f1SDmitry Borisov PAGED_CODE();
83070ba96f1SDmitry Borisov
831c4b6330bSDmitry Borisov if (SelectedReadPort)
832c4b6330bSDmitry Borisov {
833c4b6330bSDmitry Borisov /*
834c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_WRITE_DATA, required]
835c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_WRITE_DATA, optional]
836c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_ADDRESS, required]
837c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_ADDRESS, optional]
838c4b6330bSDmitry Borisov * [IO descriptor: Selected Read Port, required]
839c4b6330bSDmitry Borisov * [IO descriptor: Read Port 1, optional]
840c4b6330bSDmitry Borisov * [IO descriptor: Read Port 2, optional]
841c4b6330bSDmitry Borisov * [...]
842c4b6330bSDmitry Borisov * [IO descriptor: Read Port X - 1, optional]
843c4b6330bSDmitry Borisov */
844*10b08aa2SDmitry Borisov ResourceCount = RTL_NUMBER_OF(IsaConfigPorts) * 2 + RTL_NUMBER_OF(ReadPorts);
845c4b6330bSDmitry Borisov }
846c4b6330bSDmitry Borisov else
847c4b6330bSDmitry Borisov {
848c4b6330bSDmitry Borisov /*
849c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_WRITE_DATA, required]
850c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_WRITE_DATA, optional]
851c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_ADDRESS, required]
852c4b6330bSDmitry Borisov * [IO descriptor: ISAPNP_ADDRESS, optional]
853c4b6330bSDmitry Borisov * [IO descriptor: Read Port 1, required]
854c4b6330bSDmitry Borisov * [IO descriptor: Read Port 1, optional]
855c4b6330bSDmitry Borisov * [IO descriptor: Read Port 2, required]
856c4b6330bSDmitry Borisov * [IO descriptor: Read Port 2, optional]
857c4b6330bSDmitry Borisov * [...]
858c4b6330bSDmitry Borisov * [IO descriptor: Read Port X, required]
859c4b6330bSDmitry Borisov * [IO descriptor: Read Port X, optional]
860c4b6330bSDmitry Borisov */
861*10b08aa2SDmitry Borisov ResourceCount = (RTL_NUMBER_OF(IsaConfigPorts) + RTL_NUMBER_OF(ReadPorts)) * 2;
862c4b6330bSDmitry Borisov }
863c4b6330bSDmitry Borisov ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) +
864c4b6330bSDmitry Borisov sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1);
86566c19575SDmitry Borisov RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
866debec8c9SHervé Poussineau if (!RequirementsList)
8674ba8a8b5SDmitry Borisov return NULL;
868debec8c9SHervé Poussineau
869debec8c9SHervé Poussineau RequirementsList->ListSize = ListSize;
870debec8c9SHervé Poussineau RequirementsList->AlternativeLists = 1;
871debec8c9SHervé Poussineau
872debec8c9SHervé Poussineau RequirementsList->List[0].Version = 1;
873debec8c9SHervé Poussineau RequirementsList->List[0].Revision = 1;
874c4b6330bSDmitry Borisov RequirementsList->List[0].Count = ResourceCount;
875debec8c9SHervé Poussineau
876c4b6330bSDmitry Borisov Descriptor = &RequirementsList->List[0].Descriptors[0];
877c4b6330bSDmitry Borisov
878c4b6330bSDmitry Borisov /* Store the Data port and the Address port */
879*10b08aa2SDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(IsaConfigPorts) * 2; i++)
880debec8c9SHervé Poussineau {
881c4b6330bSDmitry Borisov if ((i % 2) == 0)
882c4b6330bSDmitry Borisov {
883debec8c9SHervé Poussineau /* Expected port */
884c4b6330bSDmitry Borisov Descriptor->Type = CmResourceTypePort;
885c4b6330bSDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
886c4b6330bSDmitry Borisov Descriptor->Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
887c4b6330bSDmitry Borisov Descriptor->u.Port.Length = 0x01;
888c4b6330bSDmitry Borisov Descriptor->u.Port.Alignment = 0x01;
889c4b6330bSDmitry Borisov Descriptor->u.Port.MinimumAddress.LowPart =
890*10b08aa2SDmitry Borisov Descriptor->u.Port.MaximumAddress.LowPart = IsaConfigPorts[i / 2];
891c4b6330bSDmitry Borisov }
892c4b6330bSDmitry Borisov else
893c4b6330bSDmitry Borisov {
894debec8c9SHervé Poussineau /* ... but mark it as optional */
895c4b6330bSDmitry Borisov Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
896c4b6330bSDmitry Borisov Descriptor->Type = CmResourceTypePort;
897c4b6330bSDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
898c4b6330bSDmitry Borisov Descriptor->Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
899c4b6330bSDmitry Borisov Descriptor->u.Port.Alignment = 0x01;
900c4b6330bSDmitry Borisov }
901c4b6330bSDmitry Borisov
902c4b6330bSDmitry Borisov Descriptor++;
903c4b6330bSDmitry Borisov }
904c4b6330bSDmitry Borisov
905c4b6330bSDmitry Borisov /* Store the Read Ports */
906c4b6330bSDmitry Borisov if (SelectedReadPort)
907c4b6330bSDmitry Borisov {
908c4b6330bSDmitry Borisov BOOLEAN Selected = FALSE;
909c4b6330bSDmitry Borisov
910c4b6330bSDmitry Borisov DBG_UNREFERENCED_LOCAL_VARIABLE(Selected);
911c4b6330bSDmitry Borisov
912c4b6330bSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(ReadPorts); i++)
913c4b6330bSDmitry Borisov {
914c4b6330bSDmitry Borisov if (ReadPorts[i] != SelectedReadPort)
915c4b6330bSDmitry Borisov Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
916c4b6330bSDmitry Borisov else
917c4b6330bSDmitry Borisov Selected = TRUE;
918c4b6330bSDmitry Borisov Descriptor->Type = CmResourceTypePort;
919c4b6330bSDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
920c4b6330bSDmitry Borisov Descriptor->Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
921c4b6330bSDmitry Borisov Descriptor->u.Port.Length = 0x04;
922c4b6330bSDmitry Borisov Descriptor->u.Port.Alignment = 0x01;
923c4b6330bSDmitry Borisov Descriptor->u.Port.MinimumAddress.LowPart = ReadPorts[i];
924c4b6330bSDmitry Borisov Descriptor->u.Port.MaximumAddress.LowPart = ReadPorts[i] +
925c4b6330bSDmitry Borisov Descriptor->u.Port.Length - 1;
926c4b6330bSDmitry Borisov
927c4b6330bSDmitry Borisov Descriptor++;
928c4b6330bSDmitry Borisov }
929c4b6330bSDmitry Borisov
930c4b6330bSDmitry Borisov ASSERT(Selected == TRUE);
931c4b6330bSDmitry Borisov }
932c4b6330bSDmitry Borisov else
933c4b6330bSDmitry Borisov {
934c4b6330bSDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(ReadPorts) * 2; i++)
935c4b6330bSDmitry Borisov {
936c4b6330bSDmitry Borisov if ((i % 2) == 0)
937c4b6330bSDmitry Borisov {
938c4b6330bSDmitry Borisov /* Expected port */
939c4b6330bSDmitry Borisov Descriptor->Type = CmResourceTypePort;
940c4b6330bSDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
941c4b6330bSDmitry Borisov Descriptor->Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
942c4b6330bSDmitry Borisov Descriptor->u.Port.Length = 0x04;
943c4b6330bSDmitry Borisov Descriptor->u.Port.Alignment = 0x01;
944c4b6330bSDmitry Borisov Descriptor->u.Port.MinimumAddress.LowPart = ReadPorts[i / 2];
945c4b6330bSDmitry Borisov Descriptor->u.Port.MaximumAddress.LowPart = ReadPorts[i / 2] +
946c4b6330bSDmitry Borisov Descriptor->u.Port.Length - 1;
947c4b6330bSDmitry Borisov }
948c4b6330bSDmitry Borisov else
949c4b6330bSDmitry Borisov {
950c4b6330bSDmitry Borisov /* ... but mark it as optional */
951c4b6330bSDmitry Borisov Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
952c4b6330bSDmitry Borisov Descriptor->Type = CmResourceTypePort;
953c4b6330bSDmitry Borisov Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
954c4b6330bSDmitry Borisov Descriptor->Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
955c4b6330bSDmitry Borisov Descriptor->u.Port.Alignment = 0x01;
956c4b6330bSDmitry Borisov }
957c4b6330bSDmitry Borisov
958c4b6330bSDmitry Borisov Descriptor++;
959c4b6330bSDmitry Borisov }
960debec8c9SHervé Poussineau }
961debec8c9SHervé Poussineau
9624ba8a8b5SDmitry Borisov return RequirementsList;
963debec8c9SHervé Poussineau }
964debec8c9SHervé Poussineau
96570ba96f1SDmitry Borisov CODE_SEG("PAGE")
9664ba8a8b5SDmitry Borisov PCM_RESOURCE_LIST
IsaPnpCreateReadPortDOResources(VOID)9674ba8a8b5SDmitry Borisov IsaPnpCreateReadPortDOResources(VOID)
96861c1079aSHervé Poussineau {
96961c1079aSHervé Poussineau ULONG ListSize, i;
97061c1079aSHervé Poussineau PCM_RESOURCE_LIST ResourceList;
97161c1079aSHervé Poussineau PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
97261c1079aSHervé Poussineau
97370ba96f1SDmitry Borisov PAGED_CODE();
97470ba96f1SDmitry Borisov
9758f44930fSDmitry Borisov ListSize = sizeof(CM_RESOURCE_LIST) +
976*10b08aa2SDmitry Borisov sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (RTL_NUMBER_OF(IsaConfigPorts) - 1);
97766c19575SDmitry Borisov ResourceList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
97861c1079aSHervé Poussineau if (!ResourceList)
9794ba8a8b5SDmitry Borisov return NULL;
98061c1079aSHervé Poussineau
98161c1079aSHervé Poussineau ResourceList->Count = 1;
98261c1079aSHervé Poussineau ResourceList->List[0].InterfaceType = Internal;
98361c1079aSHervé Poussineau ResourceList->List[0].PartialResourceList.Version = 1;
98461c1079aSHervé Poussineau ResourceList->List[0].PartialResourceList.Revision = 1;
985*10b08aa2SDmitry Borisov ResourceList->List[0].PartialResourceList.Count = RTL_NUMBER_OF(IsaConfigPorts);
98661c1079aSHervé Poussineau
9878ed43b69SDmitry Borisov Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
988*10b08aa2SDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(IsaConfigPorts); i++)
98961c1079aSHervé Poussineau {
99061c1079aSHervé Poussineau Descriptor->Type = CmResourceTypePort;
99161c1079aSHervé Poussineau Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
99261c1079aSHervé Poussineau Descriptor->Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
99361c1079aSHervé Poussineau Descriptor->u.Port.Length = 0x01;
994*10b08aa2SDmitry Borisov Descriptor->u.Port.Start.LowPart = IsaConfigPorts[i];
9958ed43b69SDmitry Borisov
9968ed43b69SDmitry Borisov Descriptor++;
99761c1079aSHervé Poussineau }
99861c1079aSHervé Poussineau
9994ba8a8b5SDmitry Borisov return ResourceList;
100061c1079aSHervé Poussineau }
100161c1079aSHervé Poussineau
1002b36d9bd9SDmitry Borisov #ifndef UNIT_TEST
1003b36d9bd9SDmitry Borisov
100461c1079aSHervé Poussineau static
100570ba96f1SDmitry Borisov CODE_SEG("PAGE")
100661c1079aSHervé Poussineau NTSTATUS
IsaPnpCreateReadPortDO(_In_ PISAPNP_FDO_EXTENSION FdoExt)10078f44930fSDmitry Borisov IsaPnpCreateReadPortDO(
10088f44930fSDmitry Borisov _In_ PISAPNP_FDO_EXTENSION FdoExt)
1009c4813f73SHervé Poussineau {
1010c4813f73SHervé Poussineau PISAPNP_PDO_EXTENSION PdoExt;
1011c4813f73SHervé Poussineau NTSTATUS Status;
10128f44930fSDmitry Borisov
101370ba96f1SDmitry Borisov PAGED_CODE();
101421514e47SDmitry Borisov ASSERT(ReadPortCreated == FALSE);
101521514e47SDmitry Borisov
101621514e47SDmitry Borisov DPRINT("Creating Read Port\n");
101770ba96f1SDmitry Borisov
1018c4813f73SHervé Poussineau Status = IoCreateDevice(FdoExt->DriverObject,
1019c4813f73SHervé Poussineau sizeof(ISAPNP_PDO_EXTENSION),
1020c4813f73SHervé Poussineau NULL,
1021c4813f73SHervé Poussineau FILE_DEVICE_CONTROLLER,
1022ac13f37dSHervé Poussineau FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
1023c4813f73SHervé Poussineau FALSE,
10248f44930fSDmitry Borisov &FdoExt->ReadPortPdo);
1025c4813f73SHervé Poussineau if (!NT_SUCCESS(Status))
1026c4813f73SHervé Poussineau return Status;
10278f44930fSDmitry Borisov
10288f44930fSDmitry Borisov PdoExt = FdoExt->ReadPortPdo->DeviceExtension;
1029c4813f73SHervé Poussineau RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION));
1030f15de155SDmitry Borisov PdoExt->Common.Signature = IsaPnpReadDataPort;
10318f44930fSDmitry Borisov PdoExt->Common.Self = FdoExt->ReadPortPdo;
1032c4813f73SHervé Poussineau PdoExt->Common.State = dsStopped;
10332fe644dcSHervé Poussineau PdoExt->FdoExt = FdoExt;
1034c4813f73SHervé Poussineau
103521514e47SDmitry Borisov FdoExt->ReadPortPdo->Flags &= ~DO_DEVICE_INITIALIZING;
103621514e47SDmitry Borisov
103761c1079aSHervé Poussineau return Status;
103821514e47SDmitry Borisov }
103921514e47SDmitry Borisov
104021514e47SDmitry Borisov CODE_SEG("PAGE")
1041f15de155SDmitry Borisov VOID
IsaPnpRemoveReadPortDO(_In_ PDEVICE_OBJECT Pdo)1042f15de155SDmitry Borisov IsaPnpRemoveReadPortDO(
1043f15de155SDmitry Borisov _In_ PDEVICE_OBJECT Pdo)
1044f15de155SDmitry Borisov {
1045f15de155SDmitry Borisov PAGED_CODE();
1046f15de155SDmitry Borisov
1047f15de155SDmitry Borisov DPRINT("Removing Read Port\n");
1048f15de155SDmitry Borisov
1049f15de155SDmitry Borisov IoDeleteDevice(Pdo);
1050f15de155SDmitry Borisov }
1051f15de155SDmitry Borisov
1052f15de155SDmitry Borisov CODE_SEG("PAGE")
105321514e47SDmitry Borisov NTSTATUS
IsaPnpFillDeviceRelations(_In_ PISAPNP_FDO_EXTENSION FdoExt,_Inout_ PIRP Irp,_In_ BOOLEAN IncludeDataPort)105421514e47SDmitry Borisov IsaPnpFillDeviceRelations(
105521514e47SDmitry Borisov _In_ PISAPNP_FDO_EXTENSION FdoExt,
105621514e47SDmitry Borisov _Inout_ PIRP Irp,
105721514e47SDmitry Borisov _In_ BOOLEAN IncludeDataPort)
105821514e47SDmitry Borisov {
105921514e47SDmitry Borisov NTSTATUS Status = STATUS_SUCCESS;
106021514e47SDmitry Borisov PLIST_ENTRY CurrentEntry;
106121514e47SDmitry Borisov PISAPNP_LOGICAL_DEVICE IsaDevice;
106221514e47SDmitry Borisov PDEVICE_RELATIONS DeviceRelations;
106321514e47SDmitry Borisov ULONG PdoCount, i = 0;
106421514e47SDmitry Borisov
106521514e47SDmitry Borisov PAGED_CODE();
106621514e47SDmitry Borisov
1067f15de155SDmitry Borisov IsaPnpAcquireBusDataLock();
1068f15de155SDmitry Borisov
106921514e47SDmitry Borisov /* Try to claim the Read Port for our FDO */
107021514e47SDmitry Borisov if (!ReadPortCreated)
107121514e47SDmitry Borisov {
107221514e47SDmitry Borisov Status = IsaPnpCreateReadPortDO(FdoExt);
107321514e47SDmitry Borisov if (!NT_SUCCESS(Status))
107421514e47SDmitry Borisov return Status;
107521514e47SDmitry Borisov
107621514e47SDmitry Borisov ReadPortCreated = TRUE;
107721514e47SDmitry Borisov }
107821514e47SDmitry Borisov
1079f15de155SDmitry Borisov IsaPnpReleaseBusDataLock();
1080f15de155SDmitry Borisov
108121514e47SDmitry Borisov /* Inactive ISA bus */
108221514e47SDmitry Borisov if (!FdoExt->ReadPortPdo)
108321514e47SDmitry Borisov IncludeDataPort = FALSE;
108421514e47SDmitry Borisov
1085f15de155SDmitry Borisov IsaPnpAcquireDeviceDataLock(FdoExt);
1086f15de155SDmitry Borisov
1087f15de155SDmitry Borisov /* If called from the FDO dispatch routine && Active bus */
1088f15de155SDmitry Borisov if (IncludeDataPort && FdoExt->ReadPortPdo)
1089f15de155SDmitry Borisov {
1090f15de155SDmitry Borisov PISAPNP_PDO_EXTENSION ReadPortExt = FdoExt->ReadPortPdo->DeviceExtension;
1091f15de155SDmitry Borisov
1092f15de155SDmitry Borisov if ((ReadPortExt->Flags & ISAPNP_READ_PORT_ALLOW_FDO_SCAN) &&
1093f15de155SDmitry Borisov !(ReadPortExt->Flags & ISAPNP_SCANNED_BY_READ_PORT))
1094f15de155SDmitry Borisov {
1095f15de155SDmitry Borisov DPRINT("Rescan ISA PnP bus\n");
1096f15de155SDmitry Borisov
1097f15de155SDmitry Borisov /* Run the isolation protocol */
1098ca42de9cSDmitry Borisov FdoExt->Cards = IsaHwTryReadDataPort(FdoExt->ReadDataPort);
1099ca42de9cSDmitry Borisov
1100f15de155SDmitry Borisov /* Card identification */
1101ca42de9cSDmitry Borisov if (FdoExt->Cards > 0)
1102f15de155SDmitry Borisov (VOID)IsaHwFillDeviceList(FdoExt);
1103367f4b15SDmitry Borisov
1104367f4b15SDmitry Borisov IsaHwWaitForKey();
1105f15de155SDmitry Borisov }
1106f15de155SDmitry Borisov
1107f15de155SDmitry Borisov ReadPortExt->Flags &= ~ISAPNP_SCANNED_BY_READ_PORT;
1108f15de155SDmitry Borisov }
1109f15de155SDmitry Borisov
111021514e47SDmitry Borisov PdoCount = FdoExt->DeviceCount;
111121514e47SDmitry Borisov if (IncludeDataPort)
111221514e47SDmitry Borisov ++PdoCount;
111321514e47SDmitry Borisov
1114f15de155SDmitry Borisov CurrentEntry = FdoExt->DeviceListHead.Flink;
1115f15de155SDmitry Borisov while (CurrentEntry != &FdoExt->DeviceListHead)
1116f15de155SDmitry Borisov {
1117f15de155SDmitry Borisov IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceLink);
1118f15de155SDmitry Borisov
1119f15de155SDmitry Borisov if (!(IsaDevice->Flags & ISAPNP_PRESENT))
1120f15de155SDmitry Borisov --PdoCount;
1121f15de155SDmitry Borisov
1122f15de155SDmitry Borisov CurrentEntry = CurrentEntry->Flink;
1123f15de155SDmitry Borisov }
1124f15de155SDmitry Borisov
112521514e47SDmitry Borisov DeviceRelations = ExAllocatePoolWithTag(PagedPool,
112621514e47SDmitry Borisov FIELD_OFFSET(DEVICE_RELATIONS, Objects[PdoCount]),
112721514e47SDmitry Borisov TAG_ISAPNP);
112821514e47SDmitry Borisov if (!DeviceRelations)
112921514e47SDmitry Borisov {
1130f15de155SDmitry Borisov IsaPnpReleaseDeviceDataLock(FdoExt);
113121514e47SDmitry Borisov return STATUS_NO_MEMORY;
113221514e47SDmitry Borisov }
113321514e47SDmitry Borisov
113421514e47SDmitry Borisov if (IncludeDataPort)
113521514e47SDmitry Borisov {
1136f15de155SDmitry Borisov PISAPNP_PDO_EXTENSION ReadPortExt = FdoExt->ReadPortPdo->DeviceExtension;
1137f15de155SDmitry Borisov
113821514e47SDmitry Borisov DeviceRelations->Objects[i++] = FdoExt->ReadPortPdo;
113921514e47SDmitry Borisov ObReferenceObject(FdoExt->ReadPortPdo);
1140f15de155SDmitry Borisov
1141f15de155SDmitry Borisov /* The Read Port PDO can only be removed by FDO */
1142f15de155SDmitry Borisov ReadPortExt->Flags |= ISAPNP_ENUMERATED;
114321514e47SDmitry Borisov }
114421514e47SDmitry Borisov
114521514e47SDmitry Borisov CurrentEntry = FdoExt->DeviceListHead.Flink;
114621514e47SDmitry Borisov while (CurrentEntry != &FdoExt->DeviceListHead)
114721514e47SDmitry Borisov {
114821514e47SDmitry Borisov PISAPNP_PDO_EXTENSION PdoExt;
114921514e47SDmitry Borisov
115021514e47SDmitry Borisov IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceLink);
115121514e47SDmitry Borisov
1152f15de155SDmitry Borisov if (!(IsaDevice->Flags & ISAPNP_PRESENT))
1153f15de155SDmitry Borisov goto SkipPdo;
1154f15de155SDmitry Borisov
115521514e47SDmitry Borisov if (!IsaDevice->Pdo)
115621514e47SDmitry Borisov {
115721514e47SDmitry Borisov Status = IoCreateDevice(FdoExt->DriverObject,
115821514e47SDmitry Borisov sizeof(ISAPNP_PDO_EXTENSION),
115921514e47SDmitry Borisov NULL,
116021514e47SDmitry Borisov FILE_DEVICE_CONTROLLER,
116121514e47SDmitry Borisov FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
116221514e47SDmitry Borisov FALSE,
116321514e47SDmitry Borisov &IsaDevice->Pdo);
116421514e47SDmitry Borisov if (!NT_SUCCESS(Status))
1165f15de155SDmitry Borisov goto SkipPdo;
116621514e47SDmitry Borisov
116721514e47SDmitry Borisov IsaDevice->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
1168f15de155SDmitry Borisov /* The power pagable flag is always unset */
116921514e47SDmitry Borisov
117021514e47SDmitry Borisov PdoExt = IsaDevice->Pdo->DeviceExtension;
117121514e47SDmitry Borisov
117221514e47SDmitry Borisov RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION));
1173f15de155SDmitry Borisov PdoExt->Common.Signature = IsaPnpLogicalDevice;
117421514e47SDmitry Borisov PdoExt->Common.Self = IsaDevice->Pdo;
117521514e47SDmitry Borisov PdoExt->Common.State = dsStopped;
117621514e47SDmitry Borisov PdoExt->IsaPnpDevice = IsaDevice;
117721514e47SDmitry Borisov PdoExt->FdoExt = FdoExt;
117821514e47SDmitry Borisov
1179f15de155SDmitry Borisov if (!NT_SUCCESS(IsaPnpCreateLogicalDeviceRequirements(PdoExt)) ||
1180f15de155SDmitry Borisov !NT_SUCCESS(IsaPnpCreateLogicalDeviceResources(PdoExt)))
118121514e47SDmitry Borisov {
1182f15de155SDmitry Borisov if (PdoExt->RequirementsList)
1183f15de155SDmitry Borisov {
1184f15de155SDmitry Borisov ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP);
1185f15de155SDmitry Borisov PdoExt->RequirementsList = NULL;
1186f15de155SDmitry Borisov }
1187f15de155SDmitry Borisov
1188f15de155SDmitry Borisov if (PdoExt->ResourceList)
1189f15de155SDmitry Borisov {
1190f15de155SDmitry Borisov ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP);
1191f15de155SDmitry Borisov PdoExt->ResourceList = NULL;
1192f15de155SDmitry Borisov }
1193f15de155SDmitry Borisov
119421514e47SDmitry Borisov IoDeleteDevice(IsaDevice->Pdo);
119521514e47SDmitry Borisov IsaDevice->Pdo = NULL;
1196f15de155SDmitry Borisov goto SkipPdo;
119721514e47SDmitry Borisov }
119821514e47SDmitry Borisov }
1199f15de155SDmitry Borisov else
1200f15de155SDmitry Borisov {
1201f15de155SDmitry Borisov PdoExt = IsaDevice->Pdo->DeviceExtension;
1202f15de155SDmitry Borisov }
120321514e47SDmitry Borisov DeviceRelations->Objects[i++] = IsaDevice->Pdo;
120421514e47SDmitry Borisov ObReferenceObject(IsaDevice->Pdo);
120521514e47SDmitry Borisov
1206f15de155SDmitry Borisov PdoExt->Flags |= ISAPNP_ENUMERATED;
1207f15de155SDmitry Borisov
1208f15de155SDmitry Borisov CurrentEntry = CurrentEntry->Flink;
1209f15de155SDmitry Borisov continue;
1210f15de155SDmitry Borisov
1211f15de155SDmitry Borisov SkipPdo:
1212f15de155SDmitry Borisov if (IsaDevice->Pdo)
1213f15de155SDmitry Borisov {
1214f15de155SDmitry Borisov PdoExt = IsaDevice->Pdo->DeviceExtension;
1215f15de155SDmitry Borisov
1216f15de155SDmitry Borisov if (PdoExt)
1217f15de155SDmitry Borisov PdoExt->Flags &= ~ISAPNP_ENUMERATED;
1218f15de155SDmitry Borisov }
1219f15de155SDmitry Borisov
122021514e47SDmitry Borisov CurrentEntry = CurrentEntry->Flink;
122121514e47SDmitry Borisov }
122221514e47SDmitry Borisov
1223f15de155SDmitry Borisov IsaPnpReleaseDeviceDataLock(FdoExt);
1224f15de155SDmitry Borisov
122521514e47SDmitry Borisov DeviceRelations->Count = i;
122621514e47SDmitry Borisov
122721514e47SDmitry Borisov Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
122821514e47SDmitry Borisov
1229c4813f73SHervé Poussineau return Status;
1230c4813f73SHervé Poussineau }
1231c4813f73SHervé Poussineau
123270ba96f1SDmitry Borisov static CODE_SEG("PAGE") DRIVER_ADD_DEVICE IsaAddDevice;
123370ba96f1SDmitry Borisov
1234c4813f73SHervé Poussineau static
123570ba96f1SDmitry Borisov CODE_SEG("PAGE")
1236c4813f73SHervé Poussineau NTSTATUS
1237c4813f73SHervé Poussineau NTAPI
IsaAddDevice(_In_ PDRIVER_OBJECT DriverObject,_In_ PDEVICE_OBJECT PhysicalDeviceObject)1238c2c66affSColin Finck IsaAddDevice(
12398f44930fSDmitry Borisov _In_ PDRIVER_OBJECT DriverObject,
12408f44930fSDmitry Borisov _In_ PDEVICE_OBJECT PhysicalDeviceObject)
1241c2c66affSColin Finck {
1242c2c66affSColin Finck PDEVICE_OBJECT Fdo;
1243c2c66affSColin Finck PISAPNP_FDO_EXTENSION FdoExt;
1244c2c66affSColin Finck NTSTATUS Status;
1245e1959557SDmitry Borisov static ULONG BusNumber = 0;
1246c2c66affSColin Finck
124770ba96f1SDmitry Borisov PAGED_CODE();
124870ba96f1SDmitry Borisov
1249c2c66affSColin Finck DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject);
1250c2c66affSColin Finck
1251c2c66affSColin Finck Status = IoCreateDevice(DriverObject,
1252c2c66affSColin Finck sizeof(*FdoExt),
1253c2c66affSColin Finck NULL,
1254c2c66affSColin Finck FILE_DEVICE_BUS_EXTENDER,
1255c2c66affSColin Finck FILE_DEVICE_SECURE_OPEN,
1256f15de155SDmitry Borisov FALSE,
1257c2c66affSColin Finck &Fdo);
1258c2c66affSColin Finck if (!NT_SUCCESS(Status))
1259c2c66affSColin Finck {
12608f44930fSDmitry Borisov DPRINT1("Failed to create FDO (0x%08lx)\n", Status);
1261c2c66affSColin Finck return Status;
1262c2c66affSColin Finck }
1263c2c66affSColin Finck
1264c2c66affSColin Finck FdoExt = Fdo->DeviceExtension;
1265c2c66affSColin Finck RtlZeroMemory(FdoExt, sizeof(*FdoExt));
1266c2c66affSColin Finck
1267c2c66affSColin Finck FdoExt->Common.Self = Fdo;
1268f15de155SDmitry Borisov FdoExt->Common.Signature = IsaPnpBus;
1269c2c66affSColin Finck FdoExt->Common.State = dsStopped;
12707a98d28dSHervé Poussineau FdoExt->DriverObject = DriverObject;
1271e1959557SDmitry Borisov FdoExt->BusNumber = BusNumber++;
1272c2c66affSColin Finck FdoExt->Pdo = PhysicalDeviceObject;
1273c2c66affSColin Finck FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
1274c2c66affSColin Finck PhysicalDeviceObject);
1275f15de155SDmitry Borisov if (!FdoExt->Ldo)
1276f15de155SDmitry Borisov {
1277f15de155SDmitry Borisov IoDeleteDevice(Fdo);
1278f15de155SDmitry Borisov return STATUS_DEVICE_REMOVED;
1279f15de155SDmitry Borisov }
1280c2c66affSColin Finck
1281c2c66affSColin Finck InitializeListHead(&FdoExt->DeviceListHead);
128270ba96f1SDmitry Borisov KeInitializeEvent(&FdoExt->DeviceSyncEvent, SynchronizationEvent, TRUE);
1283c2c66affSColin Finck
1284f15de155SDmitry Borisov IsaPnpAcquireBusDataLock();
1285f15de155SDmitry Borisov InsertTailList(&BusListHead, &FdoExt->BusLink);
1286f15de155SDmitry Borisov IsaPnpReleaseBusDataLock();
1287f15de155SDmitry Borisov
1288c2c66affSColin Finck Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
1289c2c66affSColin Finck
1290c2c66affSColin Finck return STATUS_SUCCESS;
1291c2c66affSColin Finck }
1292c2c66affSColin Finck
_Dispatch_type_(IRP_MJ_POWER)12938f44930fSDmitry Borisov _Dispatch_type_(IRP_MJ_POWER)
129470ba96f1SDmitry Borisov static DRIVER_DISPATCH_RAISED IsaPower;
12958f44930fSDmitry Borisov
129670ba96f1SDmitry Borisov static
12979df05ba4SHervé Poussineau NTSTATUS
12989df05ba4SHervé Poussineau NTAPI
12999df05ba4SHervé Poussineau IsaPower(
13008f44930fSDmitry Borisov _In_ PDEVICE_OBJECT DeviceObject,
13018f44930fSDmitry Borisov _Inout_ PIRP Irp)
13029df05ba4SHervé Poussineau {
13039df05ba4SHervé Poussineau PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension;
13049df05ba4SHervé Poussineau NTSTATUS Status;
13059df05ba4SHervé Poussineau
1306f15de155SDmitry Borisov if (DevExt->Signature != IsaPnpBus)
13079df05ba4SHervé Poussineau {
1308f15de155SDmitry Borisov switch (IoGetCurrentIrpStackLocation(Irp)->MinorFunction)
1309f15de155SDmitry Borisov {
1310f15de155SDmitry Borisov case IRP_MN_SET_POWER:
1311f15de155SDmitry Borisov case IRP_MN_QUERY_POWER:
1312f15de155SDmitry Borisov Status = STATUS_SUCCESS;
1313f15de155SDmitry Borisov Irp->IoStatus.Status = Status;
1314f15de155SDmitry Borisov break;
1315f15de155SDmitry Borisov
1316f15de155SDmitry Borisov default:
13179df05ba4SHervé Poussineau Status = Irp->IoStatus.Status;
1318f15de155SDmitry Borisov break;
1319f15de155SDmitry Borisov }
1320f15de155SDmitry Borisov
1321f15de155SDmitry Borisov PoStartNextPowerIrp(Irp);
13229df05ba4SHervé Poussineau IoCompleteRequest(Irp, IO_NO_INCREMENT);
13239df05ba4SHervé Poussineau return Status;
13249df05ba4SHervé Poussineau }
13259df05ba4SHervé Poussineau
13269df05ba4SHervé Poussineau PoStartNextPowerIrp(Irp);
13279df05ba4SHervé Poussineau IoSkipCurrentIrpStackLocation(Irp);
13289df05ba4SHervé Poussineau return PoCallDriver(((PISAPNP_FDO_EXTENSION)DevExt)->Ldo, Irp);
13299df05ba4SHervé Poussineau }
13309df05ba4SHervé Poussineau
13318f44930fSDmitry Borisov _Dispatch_type_(IRP_MJ_PNP)
133270ba96f1SDmitry Borisov static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaPnp;
1333c2c66affSColin Finck
1334c2c66affSColin Finck static
133570ba96f1SDmitry Borisov CODE_SEG("PAGE")
1336c2c66affSColin Finck NTSTATUS
1337c2c66affSColin Finck NTAPI
IsaPnp(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)1338c2c66affSColin Finck IsaPnp(
13398f44930fSDmitry Borisov _In_ PDEVICE_OBJECT DeviceObject,
13408f44930fSDmitry Borisov _Inout_ PIRP Irp)
1341c2c66affSColin Finck {
1342c2c66affSColin Finck PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
1343c2c66affSColin Finck PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension;
1344c2c66affSColin Finck
134570ba96f1SDmitry Borisov PAGED_CODE();
134670ba96f1SDmitry Borisov
1347f15de155SDmitry Borisov if (DevExt->Signature == IsaPnpBus)
13488f44930fSDmitry Borisov return IsaFdoPnp((PISAPNP_FDO_EXTENSION)DevExt, Irp, IrpSp);
1349c2c66affSColin Finck else
13508f44930fSDmitry Borisov return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt, Irp, IrpSp);
1351c2c66affSColin Finck }
1352c2c66affSColin Finck
1353016d01e5SDmitry Borisov _Dispatch_type_(IRP_MJ_CREATE)
1354016d01e5SDmitry Borisov _Dispatch_type_(IRP_MJ_CLOSE)
1355016d01e5SDmitry Borisov static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaCreateClose;
1356016d01e5SDmitry Borisov
1357016d01e5SDmitry Borisov static
1358016d01e5SDmitry Borisov CODE_SEG("PAGE")
1359016d01e5SDmitry Borisov NTSTATUS
1360016d01e5SDmitry Borisov NTAPI
IsaCreateClose(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)1361016d01e5SDmitry Borisov IsaCreateClose(
1362016d01e5SDmitry Borisov _In_ PDEVICE_OBJECT DeviceObject,
1363016d01e5SDmitry Borisov _Inout_ PIRP Irp)
1364016d01e5SDmitry Borisov {
1365016d01e5SDmitry Borisov PAGED_CODE();
1366016d01e5SDmitry Borisov
1367016d01e5SDmitry Borisov Irp->IoStatus.Status = STATUS_SUCCESS;
1368016d01e5SDmitry Borisov
1369016d01e5SDmitry Borisov DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
1370016d01e5SDmitry Borisov
1371016d01e5SDmitry Borisov IoCompleteRequest(Irp, IO_NO_INCREMENT);
1372016d01e5SDmitry Borisov
1373016d01e5SDmitry Borisov return STATUS_SUCCESS;
1374016d01e5SDmitry Borisov }
1375016d01e5SDmitry Borisov
1376016d01e5SDmitry Borisov _Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
1377016d01e5SDmitry Borisov _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
1378016d01e5SDmitry Borisov static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaForwardOrIgnore;
1379016d01e5SDmitry Borisov
1380016d01e5SDmitry Borisov static
1381016d01e5SDmitry Borisov CODE_SEG("PAGE")
1382016d01e5SDmitry Borisov NTSTATUS
1383016d01e5SDmitry Borisov NTAPI
IsaForwardOrIgnore(_In_ PDEVICE_OBJECT DeviceObject,_Inout_ PIRP Irp)1384016d01e5SDmitry Borisov IsaForwardOrIgnore(
1385016d01e5SDmitry Borisov _In_ PDEVICE_OBJECT DeviceObject,
1386016d01e5SDmitry Borisov _Inout_ PIRP Irp)
1387016d01e5SDmitry Borisov {
1388016d01e5SDmitry Borisov PISAPNP_COMMON_EXTENSION CommonExt = DeviceObject->DeviceExtension;
1389016d01e5SDmitry Borisov
1390016d01e5SDmitry Borisov PAGED_CODE();
1391016d01e5SDmitry Borisov
1392016d01e5SDmitry Borisov DPRINT("%s(%p, %p) Minor - %X\n", __FUNCTION__, DeviceObject, Irp,
1393016d01e5SDmitry Borisov IoGetCurrentIrpStackLocation(Irp)->MinorFunction);
1394016d01e5SDmitry Borisov
1395016d01e5SDmitry Borisov if (CommonExt->Signature == IsaPnpBus)
1396016d01e5SDmitry Borisov {
1397016d01e5SDmitry Borisov IoSkipCurrentIrpStackLocation(Irp);
1398016d01e5SDmitry Borisov return IoCallDriver(((PISAPNP_FDO_EXTENSION)CommonExt)->Ldo, Irp);
1399016d01e5SDmitry Borisov }
1400016d01e5SDmitry Borisov else
1401016d01e5SDmitry Borisov {
1402016d01e5SDmitry Borisov NTSTATUS Status = Irp->IoStatus.Status;
1403016d01e5SDmitry Borisov
1404016d01e5SDmitry Borisov IoCompleteRequest(Irp, IO_NO_INCREMENT);
1405016d01e5SDmitry Borisov return Status;
1406016d01e5SDmitry Borisov }
1407016d01e5SDmitry Borisov }
1408016d01e5SDmitry Borisov
140970ba96f1SDmitry Borisov CODE_SEG("INIT")
1410c2c66affSColin Finck NTSTATUS
1411c2c66affSColin Finck NTAPI
DriverEntry(_In_ PDRIVER_OBJECT DriverObject,_In_ PUNICODE_STRING RegistryPath)1412c2c66affSColin Finck DriverEntry(
14138f44930fSDmitry Borisov _In_ PDRIVER_OBJECT DriverObject,
14148f44930fSDmitry Borisov _In_ PUNICODE_STRING RegistryPath)
1415c2c66affSColin Finck {
1416c2c66affSColin Finck DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath);
1417c2c66affSColin Finck
1418*10b08aa2SDmitry Borisov if (IsNEC_98)
1419*10b08aa2SDmitry Borisov {
1420*10b08aa2SDmitry Borisov IsaConfigPorts[0] = ISAPNP_WRITE_DATA_PC98;
1421*10b08aa2SDmitry Borisov IsaConfigPorts[1] = ISAPNP_ADDRESS_PC98;
1422*10b08aa2SDmitry Borisov }
1423*10b08aa2SDmitry Borisov
1424c2c66affSColin Finck DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaCreateClose;
1425c2c66affSColin Finck DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaCreateClose;
1426f15de155SDmitry Borisov DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaForwardOrIgnore;
1427f15de155SDmitry Borisov DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IsaForwardOrIgnore;
1428c2c66affSColin Finck DriverObject->MajorFunction[IRP_MJ_PNP] = IsaPnp;
14299df05ba4SHervé Poussineau DriverObject->MajorFunction[IRP_MJ_POWER] = IsaPower;
1430c2c66affSColin Finck DriverObject->DriverExtension->AddDevice = IsaAddDevice;
1431c2c66affSColin Finck
1432f15de155SDmitry Borisov /* FIXME: Fix SDK headers */
1433f15de155SDmitry Borisov #if 0
1434f15de155SDmitry Borisov _No_competing_thread_begin_
1435f15de155SDmitry Borisov #endif
1436f15de155SDmitry Borisov
1437f15de155SDmitry Borisov KeInitializeEvent(&BusSyncEvent, SynchronizationEvent, TRUE);
1438f15de155SDmitry Borisov InitializeListHead(&BusListHead);
1439f15de155SDmitry Borisov
1440f15de155SDmitry Borisov /* FIXME: Fix SDK headers */
1441f15de155SDmitry Borisov #if 0
1442f15de155SDmitry Borisov _No_competing_thread_end_
1443f15de155SDmitry Borisov #endif
1444f15de155SDmitry Borisov
1445c2c66affSColin Finck return STATUS_SUCCESS;
1446c2c66affSColin Finck }
1447c2c66affSColin Finck
1448b36d9bd9SDmitry Borisov #endif /* UNIT_TEST */
1449b36d9bd9SDmitry Borisov
1450c2c66affSColin Finck /* EOF */
1451