3 * PROJECT: ReactOS ISA PnP Bus driver
5 * PURPOSE: Driver entry
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * NOTE: Parts adapted from linux ISA PnP driver
9 * 01-05-2001 CSH Created
21 // Make the initialization routines discardable, so that they
24 #pragma alloc_text(init, DriverEntry)
27 #endif /* ALLOC_PRAGMA */
30 PUCHAR IsaPnPReadPort
;
33 #define UCHAR2USHORT(v0, v1) \
36 #define UCHAR2ULONG(v0, v1, v2, v3) \
37 ((UCHAR2USHORT(v2, v3) << 16) | UCHAR2USHORT(v0, v1))
46 {"Unknown Small Tag"},
47 {"ISAPNP_SRIN_VERSION"},
48 {"ISAPNP_SRIN_LDEVICE_ID"},
49 {"ISAPNP_SRIN_CDEVICE_ID"},
50 {"ISAPNP_SRIN_IRQ_FORMAT"},
51 {"ISAPNP_SRIN_DMA_FORMAT"},
52 {"ISAPNP_SRIN_START_DFUNCTION"},
53 {"ISAPNP_SRIN_END_DFUNCTION"},
54 {"ISAPNP_SRIN_IO_DESCRIPTOR"},
55 {"ISAPNP_SRIN_FL_IO_DESCRIPOTOR"},
56 {"Reserved Small Tag"},
57 {"Reserved Small Tag"},
58 {"Reserved Small Tag"},
59 {"Reserved Small Tag"},
60 {"ISAPNP_SRIN_VENDOR_DEFINED"},
61 {"ISAPNP_SRIN_END_TAG"}
68 {"Unknown Large Tag"},
69 {"ISAPNP_LRIN_MEMORY_RANGE"},
70 {"ISAPNP_LRIN_ID_STRING_ANSI"},
71 {"ISAPNP_LRIN_ID_STRING_UNICODE"},
72 {"ISAPNP_LRIN_VENDOR_DEFINED"},
73 {"ISAPNP_LRIN_MEMORY_RANGE32"},
74 {"ISAPNP_LRIN_FL_MEMORY_RANGE32"}
77 PCSZ
TagName(ULONG Tag
, BOOLEAN Small
)
79 if (Small
&& (Tag
<= ISAPNP_SRIN_END_TAG
)) {
80 return SmallTags
[Tag
].Name
;
81 } else if (Tag
<= ISAPNP_LRIN_FL_MEMORY_RANGE32
){
82 return LargeTags
[Tag
].Name
;
90 static __inline VOID
WriteData(UCHAR Value
)
92 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_WRITE_PORT
, Value
);
95 static __inline VOID
WriteAddress(UCHAR Value
)
97 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_ADDRESS_PORT
, Value
);
98 KeStallExecutionProcessor(20);
101 static __inline UCHAR
ReadData(VOID
)
103 return READ_PORT_UCHAR(IsaPnPReadPort
);
106 static UCHAR
ReadUchar(UCHAR Index
)
113 static USHORT
ReadUshort(UCHAR Index
)
117 Value
= ReadUchar(Index
);
118 Value
= (Value
<< 8) + ReadUchar(Index
+ 1);
122 static ULONG
ReadUlong(UCHAR Index
)
126 Value
= ReadUchar(Index
);
127 Value
= (Value
<< 8) + ReadUchar(Index
+ 1);
128 Value
= (Value
<< 8) + ReadUchar(Index
+ 2);
129 Value
= (Value
<< 8) + ReadUchar(Index
+ 3);
134 static VOID
WriteUchar(UCHAR Index
, UCHAR Value
)
141 static VOID
WriteUshort(UCHAR Index
, USHORT Value
)
143 WriteUchar(Index
, Value
>> 8);
144 WriteUchar(Index
+ 1, Value
);
147 static VOID
WriteUlong(UCHAR Index
, ULONG Value
)
149 WriteUchar(Index
, Value
>> 24);
150 WriteUchar(Index
+ 1, Value
>> 16);
151 WriteUchar(Index
+ 2, Value
>> 8);
152 WriteUchar(Index
+ 3, Value
);
156 static __inline VOID
SetReadDataPort(ULONG_PTR Port
)
158 IsaPnPReadPort
= (PUCHAR
)Port
;
159 WriteUchar(0x00, (UCHAR
) (Port
>> 2));
160 KeStallExecutionProcessor(100);
163 static VOID
SendKey(VOID
)
169 /* FIXME: Is there something better? */
170 KeStallExecutionProcessor(1000);
176 for (i
= 1; i
< 32; i
++) {
177 msb
= ((code
& 0x01) ^ ((code
& 0x02) >> 1)) << 7;
178 code
= (code
>> 1) | msb
;
183 /* Place all PnP cards in wait-for-key state */
184 static VOID
SendWait(VOID
)
186 WriteUchar(0x02, 0x02);
189 static VOID
SendWake(UCHAR csn
)
191 WriteUchar(ISAPNP_CARD_WAKECSN
, csn
);
195 static VOID
SelectLogicalDevice(UCHAR LogicalDevice
)
197 WriteUchar(ISAPNP_CARD_LOG_DEVICE_NUM
, LogicalDevice
);
200 static VOID
ActivateLogicalDevice(UCHAR LogicalDevice
)
202 SelectLogicalDevice(LogicalDevice
);
203 WriteUchar(ISAPNP_CONTROL_ACTIVATE
, 0x1);
204 KeStallExecutionProcessor(250);
207 static VOID
DeactivateLogicalDevice(UCHAR LogicalDevice
)
209 SelectLogicalDevice(LogicalDevice
);
210 WriteUchar(ISAPNP_CONTROL_ACTIVATE
, 0x0);
211 KeStallExecutionProcessor(500);
215 #define READ_DATA_PORT_STEP 32 /* Minimum is 4 */
217 static ULONG_PTR
FindNextReadPort(VOID
)
223 Port
= (ULONG_PTR
)IsaPnPReadPort
;
227 Port
+= READ_DATA_PORT_STEP
;
231 if (Port
> ISAPNP_MAX_READ_PORT
)
243 * We cannot use NE2000 probe spaces for
245 * ISAPnP or we will lock up machines
249 if ((Port
< 0x280) || (Port
> 0x380))
261 static BOOLEAN
IsolateReadDataPortSelect(VOID
)
268 /* Control: reset CSN and conditionally everything else too */
269 WriteUchar(0x02, 0x05);
270 KeStallExecutionProcessor(2000);
276 Port
= FindNextReadPort();
282 SetReadDataPort(Port
);
283 KeStallExecutionProcessor(1000);
285 KeStallExecutionProcessor(1000);
290 * Isolate (assign uniqued CSN) to all ISA PnP devices
292 static ULONG
IsolatePnPCards(VOID
)
294 UCHAR checksum
= 0x6a;
304 IsaPnPReadPort
= (PUCHAR
)(ISAPNP_MIN_READ_PORT
- READ_DATA_PORT_STEP
);
305 if (!IsolateReadDataPortSelect()) {
306 DPRINT("Could not set read data port\n");
311 for (i
= 1; i
<= 64; i
++) {
312 data
= ReadData() << 8;
313 KeStallExecutionProcessor(250);
314 data
= data
| ReadData();
315 KeStallExecutionProcessor(250);
318 checksum
= ((((checksum
^ (checksum
>> 1)) & 0x01) ^ bit
) << 7) | (checksum
>> 1);
321 for (i
= 65; i
<= 72; i
++) {
322 data
= ReadData() << 8;
323 KeStallExecutionProcessor(250);
324 data
= data
| ReadData();
325 KeStallExecutionProcessor(250);
327 chksum
|= (1 << (i
- 65));
329 if ((checksum
!= 0x00) && (checksum
== chksum
)) {
332 WriteUchar(0x06, (UCHAR
) csn
);
333 KeStallExecutionProcessor(250);
336 SetReadDataPort((ULONG_PTR
)IsaPnPReadPort
);
337 KeStallExecutionProcessor(1000);
339 KeStallExecutionProcessor(1000);
342 if (iteration
== 1) {
343 if (!IsolateReadDataPortSelect()) {
344 DPRINT("Could not set read data port\n");
347 } else if (iteration
> 1) {
360 static VOID
Peek(PUCHAR Data
, ULONG Count
)
365 for (i
= 1; i
<= Count
; i
++) {
366 for (j
= 0; j
< 20; j
++) {
370 KeStallExecutionProcessor(100);
377 d
= ReadUchar(0x04); /* PRESDI */
385 * Skip specified number of bytes from stream
387 static VOID
Skip(ULONG Count
)
394 * Read one tag from stream
396 static BOOLEAN
ReadTag(PUCHAR Type
,
405 DPRINT("Invalid tag with value 0\n");
412 if (tag
& ISAPNP_RESOURCE_ITEM_TYPE
) {
413 /* Large resource item */
414 *Type
= (tag
& 0x7f);
416 *Size
= UCHAR2USHORT(tmp
[0], tmp
[1]);
419 if (*Type
> ISAPNP_LRIN_FL_MEMORY_RANGE32
) {
420 DPRINT("Invalid large tag with value 0x%X\n", *Type
);
425 /* Small resource item */
426 *Type
= (tag
>> 3) & 0x0f;
430 if (*Type
> ISAPNP_SRIN_END_TAG
) {
431 DPRINT("Invalid small tag with value 0x%X\n", *Type
);
437 DPRINT("Tag = 0x%X, Type = 0x%X, Size = %d (%s)\n",
438 tag
, *Type
, *Size
, TagName(*Type
, *Small
));
440 /* Probably invalid data */
441 if ((*Type
== 0xff) && (*Size
== 0xffff)) {
442 DPRINT("Invalid data (Type 0x%X Size 0x%X)\n", *Type
, *Size
);
452 * Parse ANSI name for ISA PnP logical device
454 static NTSTATUS
ParseAnsiName(PUNICODE_STRING Name
, PUSHORT Size
)
456 ANSI_STRING AnsiString
;
460 size1
= (*Size
>= sizeof(Buffer
)) ? (sizeof(Buffer
) - 1) : *Size
;
463 Buffer
[size1
] = '\0';
466 /* Clean whitespace from end of string */
467 while ((size1
> 0) && (Buffer
[--size1
] == ' '))
468 Buffer
[size1
] = '\0';
470 DPRINT("ANSI name: %s\n", Buffer
);
472 RtlInitAnsiString(&AnsiString
, (PCSZ
)&Buffer
);
473 return RtlAnsiStringToUnicodeString(Name
, &AnsiString
, TRUE
);
478 * Add a resource list to the
479 * resource lists of a logical device
481 static NTSTATUS
AddResourceList(
482 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
484 PISAPNP_CONFIGURATION_LIST
*NewList
)
486 PISAPNP_CONFIGURATION_LIST List
;
488 DPRINT("Adding resource list for logical device %d on card %d (Priority %d)\n",
489 LogicalDevice
->Number
,
490 LogicalDevice
->Card
->CardId
,
493 List
= (PISAPNP_CONFIGURATION_LIST
)
494 ExAllocatePoolWithTag(PagedPool
, sizeof(ISAPNP_CONFIGURATION_LIST
), TAG_ISAPNP
);
496 return STATUS_INSUFFICIENT_RESOURCES
;
498 RtlZeroMemory(List
, sizeof(ISAPNP_CONFIGURATION_LIST
));
500 List
->Priority
= Priority
;
502 InitializeListHead(&List
->ListHead
);
504 InsertTailList(&LogicalDevice
->Configuration
, &List
->ListEntry
);
508 return STATUS_SUCCESS
;
513 * Add a resource entry to the
514 * resource list of a logical device
516 static NTSTATUS
AddResourceDescriptor(
517 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
520 PISAPNP_DESCRIPTOR
*Descriptor
)
522 PLIST_ENTRY CurrentEntry
;
523 PISAPNP_CONFIGURATION_LIST List
;
524 PISAPNP_DESCRIPTOR d
;
527 DPRINT("Adding resource descriptor for logical device %d on card %d (%d of %d)\n",
528 LogicalDevice
->Number
,
529 LogicalDevice
->Card
->CardId
,
530 LogicalDevice
->CurrentDescriptorCount
,
531 LogicalDevice
->DescriptorCount
);
533 d
= (PISAPNP_DESCRIPTOR
)
534 ExAllocatePoolWithTag(PagedPool
, sizeof(ISAPNP_DESCRIPTOR
), TAG_ISAPNP
);
536 return STATUS_NO_MEMORY
;
538 RtlZeroMemory(d
, sizeof(ISAPNP_DESCRIPTOR
));
540 d
->Descriptor
.Option
= (UCHAR
) Option
;
544 CurrentEntry
= LogicalDevice
->Configuration
.Flink
;
545 while (CurrentEntry
!= &LogicalDevice
->Configuration
) {
546 List
= CONTAINING_RECORD(
547 CurrentEntry
, ISAPNP_CONFIGURATION_LIST
, ListEntry
);
549 if (List
->Priority
== Priority
) {
551 LogicalDevice
->ConfigurationSize
+= sizeof(IO_RESOURCE_DESCRIPTOR
);
552 InsertTailList(&List
->ListHead
, &d
->ListEntry
);
553 LogicalDevice
->CurrentDescriptorCount
++;
554 if (LogicalDevice
->DescriptorCount
<
555 LogicalDevice
->CurrentDescriptorCount
) {
556 LogicalDevice
->DescriptorCount
=
557 LogicalDevice
->CurrentDescriptorCount
;
560 return STATUS_SUCCESS
;
562 CurrentEntry
= CurrentEntry
->Flink
;
565 Status
= AddResourceList(LogicalDevice
, Priority
, &List
);
566 if (NT_SUCCESS(Status
)) {
567 LogicalDevice
->ConfigurationSize
+= sizeof(IO_RESOURCE_LIST
);
568 LogicalDevice
->CurrentDescriptorCount
= 0;
569 InsertTailList(&List
->ListHead
, &d
->ListEntry
);
577 * Add IRQ resource to resources list
579 static NTSTATUS
AddIrqResource(
580 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
585 PISAPNP_DESCRIPTOR Descriptor
;
587 ULONG irq
, i
, last
= 0;
593 irq
= UCHAR2USHORT(tmp
[0], tmp
[0]);
595 DPRINT("IRQ bitmask: 0x%X\n", irq
);
598 for (i
= 0; i
< 16; i
++) {
599 if (!found
&& (irq
& (1 << i
))) {
604 if ((found
&& !(irq
& (1 << i
))) || (irq
& (1 << i
) && (i
== 15))) {
605 Status
= AddResourceDescriptor(LogicalDevice
,
606 Priority
, Option
, &Descriptor
);
607 if (!NT_SUCCESS(Status
))
609 Descriptor
->Descriptor
.Type
= CmResourceTypeInterrupt
;
610 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
611 Descriptor
->Descriptor
.u
.Interrupt
.MinimumVector
= last
;
613 if ((irq
& (1 << i
)) && (i
== 15))
614 Descriptor
->Descriptor
.u
.Interrupt
.MaximumVector
= i
;
616 Descriptor
->Descriptor
.u
.Interrupt
.MaximumVector
= i
- 1;
618 DPRINT("Found IRQ range %d - %d for logical device %d on card %d\n",
619 Descriptor
->Descriptor
.u
.Interrupt
.MinimumVector
,
620 Descriptor
->Descriptor
.u
.Interrupt
.MaximumVector
,
621 LogicalDevice
->Number
,
622 LogicalDevice
->Card
->CardId
);
628 return STATUS_SUCCESS
;
632 * Add DMA resource to resources list
634 static NTSTATUS
AddDmaResource(
635 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
640 PISAPNP_DESCRIPTOR Descriptor
;
642 ULONG dma
, flags
, i
, last
= 0;
651 DPRINT("DMA bitmask: 0x%X\n", dma
);
654 for (i
= 0; i
< 8; i
++) {
655 if (!found
&& (dma
& (1 << i
))) {
660 if ((found
&& !(dma
& (1 << i
))) || (dma
& (1 << i
) && (i
== 15))) {
661 Status
= AddResourceDescriptor(LogicalDevice
,
662 Priority
, Option
, &Descriptor
);
663 if (!NT_SUCCESS(Status
))
665 Descriptor
->Descriptor
.Type
= CmResourceTypeDma
;
666 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
667 Descriptor
->Descriptor
.u
.Dma
.MinimumChannel
= last
;
669 if ((dma
& (1 << i
)) && (i
== 15))
670 Descriptor
->Descriptor
.u
.Dma
.MaximumChannel
= i
;
672 Descriptor
->Descriptor
.u
.Dma
.MaximumChannel
= i
- 1;
674 /* FIXME: Parse flags */
676 DPRINT("Found DMA range %d - %d for logical device %d on card %d\n",
677 Descriptor
->Descriptor
.u
.Dma
.MinimumChannel
,
678 Descriptor
->Descriptor
.u
.Dma
.MaximumChannel
,
679 LogicalDevice
->Number
,
680 LogicalDevice
->Card
->CardId
);
686 return STATUS_SUCCESS
;
690 * Add port resource to resources list
692 static NTSTATUS
AddIOPortResource(
693 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
699 DPRINT("I/O port: size 0x%X\n", Size
);
702 PISAPNP_DESCRIPTOR Descriptor
;
708 Status
= AddResourceDescriptor(LogicalDevice
,
709 Priority
, Option
, &Descriptor
);
710 if (!NT_SUCCESS(Status
))
712 Descriptor
->Descriptor
.Type
= CmResourceTypePort
;
713 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
714 Descriptor
->Descriptor
.u
.Port
.Length
= tmp
[6];
715 /* FIXME: Parse flags */
716 Descriptor
->Descriptor
.u
.Port
.Alignment
= 0;
717 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
.QuadPart
= UCHAR2USHORT(tmp
[1], tmp
[2]);
718 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
.QuadPart
= UCHAR2USHORT(tmp
[4], tmp
[4]);
720 DPRINT("Found I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
721 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
,
722 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
,
723 LogicalDevice
->Number
,
724 LogicalDevice
->Card
->CardId
);
726 return STATUS_SUCCESS
;
730 * Add fixed port resource to resources list
732 static NTSTATUS
AddFixedIOPortResource(
733 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
739 DPRINT("Fixed I/O port: size 0x%X\n", Size
);
742 PISAPNP_DESCRIPTOR Descriptor
;
748 Status
= AddResourceDescriptor(LogicalDevice
,
749 Priority
, Option
, &Descriptor
);
750 if (!NT_SUCCESS(Status
))
752 Descriptor
->Descriptor
.Type
= CmResourceTypePort
;
753 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
754 Descriptor
->Descriptor
.u
.Port
.Length
= tmp
[2];
755 Descriptor
->Descriptor
.u
.Port
.Alignment
= 0;
756 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
.QuadPart
= UCHAR2USHORT(tmp
[0], tmp
[1]);
757 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
.QuadPart
= UCHAR2USHORT(tmp
[0], tmp
[1]);
759 DPRINT("Found fixed I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
760 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
,
761 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
,
762 LogicalDevice
->Number
,
763 LogicalDevice
->Card
->CardId
);
765 return STATUS_SUCCESS
;
769 * Add memory resource to resources list
771 static NTSTATUS
AddMemoryResource(
772 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
778 DPRINT("Memory range: size 0x%X\n", Size
);
781 PISAPNP_DESCRIPTOR Descriptor
;
787 Status
= AddResourceDescriptor(LogicalDevice
,
788 Priority
, Option
, &Descriptor
);
789 if (!NT_SUCCESS(Status
))
791 Descriptor
->Descriptor
.Type
= CmResourceTypeMemory
;
792 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
793 Descriptor
->Descriptor
.u
.Memory
.Length
= UCHAR2USHORT(tmp
[7], tmp
[8]) << 8;
794 Descriptor
->Descriptor
.u
.Memory
.Alignment
= UCHAR2USHORT(tmp
[5], tmp
[6]);
795 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
.QuadPart
= UCHAR2USHORT(tmp
[1], tmp
[2]) << 8;
796 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
.QuadPart
= UCHAR2USHORT(tmp
[3], tmp
[4]) << 8;
798 DPRINT("Found memory range 0x%X - 0x%X for logical device %d on card %d\n",
799 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
,
800 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
,
801 LogicalDevice
->Number
,
802 LogicalDevice
->Card
->CardId
);
804 return STATUS_SUCCESS
;
808 * Add 32-bit memory resource to resources list
810 static NTSTATUS
AddMemory32Resource(
811 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
817 DPRINT("Memory32 range: size 0x%X\n", Size
);
820 PISAPNP_DESCRIPTOR Descriptor
;
826 Status
= AddResourceDescriptor(LogicalDevice
,
827 Priority
, Option
, &Descriptor
);
828 if (!NT_SUCCESS(Status
))
830 Descriptor
->Descriptor
.Type
= CmResourceTypeMemory
;
831 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
832 Descriptor
->Descriptor
.u
.Memory
.Length
=
833 UCHAR2ULONG(tmp
[13], tmp
[14], tmp
[15], tmp
[16]);
834 Descriptor
->Descriptor
.u
.Memory
.Alignment
=
835 UCHAR2ULONG(tmp
[9], tmp
[10], tmp
[11], tmp
[12]);
836 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
.QuadPart
=
837 UCHAR2ULONG(tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
838 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
.QuadPart
=
839 UCHAR2ULONG(tmp
[5], tmp
[6], tmp
[7], tmp
[8]);
841 DPRINT("Found memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
842 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
,
843 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
,
844 LogicalDevice
->Number
,
845 LogicalDevice
->Card
->CardId
);
847 return STATUS_SUCCESS
;
851 * Add 32-bit fixed memory resource to resources list
853 static NTSTATUS
AddFixedMemory32Resource(
854 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
860 DPRINT("Memory32 range: size 0x%X\n", Size
);
863 PISAPNP_DESCRIPTOR Descriptor
;
869 Status
= AddResourceDescriptor(LogicalDevice
,
870 Priority
, Option
, &Descriptor
);
871 if (!NT_SUCCESS(Status
))
873 Descriptor
->Descriptor
.Type
= CmResourceTypeMemory
;
874 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
875 Descriptor
->Descriptor
.u
.Memory
.Length
=
876 UCHAR2ULONG(tmp
[9], tmp
[10], tmp
[11], tmp
[12]);
877 Descriptor
->Descriptor
.u
.Memory
.Alignment
=
878 UCHAR2ULONG(tmp
[5], tmp
[6], tmp
[7], tmp
[8]);
879 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
.QuadPart
=
880 UCHAR2ULONG(tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
881 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
.QuadPart
=
882 UCHAR2ULONG(tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
884 DPRINT("Found fixed memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
885 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
,
886 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
,
887 LogicalDevice
->Number
,
888 LogicalDevice
->Card
->CardId
);
890 return STATUS_SUCCESS
;
895 * Parse logical device tag
897 static PISAPNP_LOGICAL_DEVICE
ParseLogicalDevice(
898 PISAPNP_DEVICE_EXTENSION DeviceExtension
,
904 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
906 DPRINT("Card %d Number %d\n", Card
->CardId
, Number
);
910 LogicalDevice
= (PISAPNP_LOGICAL_DEVICE
)ExAllocatePoolWithTag(
911 PagedPool
, sizeof(ISAPNP_LOGICAL_DEVICE
), TAG_ISAPNP
);
915 RtlZeroMemory(LogicalDevice
, sizeof(ISAPNP_LOGICAL_DEVICE
));
917 LogicalDevice
->Number
= Number
;
918 LogicalDevice
->VendorId
= UCHAR2USHORT(tmp
[0], tmp
[1]);
919 LogicalDevice
->DeviceId
= UCHAR2USHORT(tmp
[2], tmp
[3]);
920 LogicalDevice
->Regs
= tmp
[4];
921 LogicalDevice
->Card
= Card
;
923 LogicalDevice
->Regs
|= tmp
[5] << 8;
925 InitializeListHead(&LogicalDevice
->Configuration
);
927 ExInterlockedInsertTailList(&Card
->LogicalDevices
,
928 &LogicalDevice
->CardListEntry
,
929 &Card
->LogicalDevicesLock
);
931 ExInterlockedInsertTailList(&DeviceExtension
->DeviceListHead
,
932 &LogicalDevice
->DeviceListEntry
,
933 &DeviceExtension
->GlobalListLock
);
935 DeviceExtension
->DeviceListCount
++;
937 return LogicalDevice
;
942 * Parse resource map for logical device
944 static BOOLEAN
CreateLogicalDevice(PISAPNP_DEVICE_EXTENSION DeviceExtension
,
945 PISAPNP_CARD Card
, USHORT Size
)
947 ULONG number
= 0, skip
= 0, compat
= 0;
949 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
952 ULONG Option
= IO_RESOURCE_REQUIRED
;
954 DPRINT("Card %d Size %d\n", Card
->CardId
, Size
);
956 LogicalDevice
= ParseLogicalDevice(DeviceExtension
, Card
, Size
, (USHORT
) number
++);
961 if (!ReadTag(&type
, &Size
, &Small
))
964 if (skip
&& !(Small
&& ((type
== ISAPNP_SRIN_LDEVICE_ID
)
965 || (type
== ISAPNP_SRIN_END_TAG
))))
970 case ISAPNP_SRIN_LDEVICE_ID
:
971 if ((Size
>= 5) && (Size
<= 6)) {
972 LogicalDevice
= ParseLogicalDevice(
973 DeviceExtension
, Card
, Size
, (USHORT
)number
++);
982 Option
= IO_RESOURCE_REQUIRED
;
986 case ISAPNP_SRIN_CDEVICE_ID
:
987 if ((Size
== 4) && (compat
< MAX_COMPATIBLE_ID
)) {
989 LogicalDevice
->CVendorId
[compat
] = UCHAR2USHORT(tmp
[0], tmp
[1]);
990 LogicalDevice
->CDeviceId
[compat
] = UCHAR2USHORT(tmp
[2], tmp
[3]);
996 case ISAPNP_SRIN_IRQ_FORMAT
:
997 if ((Size
< 2) || (Size
> 3))
999 AddIrqResource(LogicalDevice
, Size
, Priority
, Option
);
1003 case ISAPNP_SRIN_DMA_FORMAT
:
1006 AddDmaResource(LogicalDevice
, Size
, Priority
, Option
);
1010 case ISAPNP_SRIN_START_DFUNCTION
:
1018 /* FIXME: Maybe use IO_RESOURCE_PREFERRED for some */
1019 Option
= IO_RESOURCE_ALTERNATIVE
;
1022 Option
= IO_RESOURCE_ALTERNATIVE
;
1025 DPRINT(" Start priority %d \n", Priority
);
1027 LogicalDevice
->CurrentDescriptorCount
= 0;
1031 case ISAPNP_SRIN_END_DFUNCTION
:
1033 DPRINT(" End priority %d \n", Priority
);
1038 Option
= IO_RESOURCE_REQUIRED
;
1039 LogicalDevice
->CurrentDescriptorCount
= 0;
1042 case ISAPNP_SRIN_IO_DESCRIPTOR
:
1045 AddIOPortResource(LogicalDevice
, Size
, Priority
, Option
);
1049 case ISAPNP_SRIN_FL_IO_DESCRIPOTOR
:
1052 AddFixedIOPortResource(LogicalDevice
, Size
, Priority
, Option
);
1056 case ISAPNP_SRIN_VENDOR_DEFINED
:
1059 case ISAPNP_SRIN_END_TAG
:
1065 DPRINT("Ignoring small tag of type 0x%X for logical device %d on card %d\n",
1066 type
, LogicalDevice
->Number
, Card
->CardId
);
1070 case ISAPNP_LRIN_MEMORY_RANGE
:
1073 AddMemoryResource(LogicalDevice
, Size
, Priority
, Option
);
1077 case ISAPNP_LRIN_ID_STRING_ANSI
:
1078 ParseAnsiName(&LogicalDevice
->Name
, &Size
);
1081 case ISAPNP_LRIN_ID_STRING_UNICODE
:
1084 case ISAPNP_LRIN_VENDOR_DEFINED
:
1087 case ISAPNP_LRIN_MEMORY_RANGE32
:
1090 AddMemory32Resource(LogicalDevice
, Size
, Priority
, Option
);
1094 case ISAPNP_LRIN_FL_MEMORY_RANGE32
:
1097 AddFixedMemory32Resource(LogicalDevice
, Size
, Priority
, Option
);
1102 DPRINT("Ignoring large tag of type 0x%X for logical device %d on card %d\n",
1103 type
, LogicalDevice
->Number
, Card
->CardId
);
1116 * Parse resource map for ISA PnP card
1118 static BOOLEAN
ParseResourceMap(PISAPNP_DEVICE_EXTENSION DeviceExtension
,
1121 UCHAR type
, tmp
[17];
1125 DPRINT("Card %d\n", Card
->CardId
);
1128 if (!ReadTag(&type
, &size
, &Small
))
1133 case ISAPNP_SRIN_VERSION
:
1137 Card
->PNPVersion
= tmp
[0];
1138 Card
->ProductVersion
= tmp
[1];
1142 case ISAPNP_SRIN_LDEVICE_ID
:
1143 if ((size
>= 5) && (size
<= 6)) {
1144 if (!CreateLogicalDevice(DeviceExtension
, Card
, size
))
1150 case ISAPNP_SRIN_CDEVICE_ID
:
1151 /* FIXME: Parse compatible IDs */
1154 case ISAPNP_SRIN_END_TAG
:
1160 DPRINT("Ignoring small tag Type 0x%X for Card %d\n", type
, Card
->CardId
);
1164 case ISAPNP_LRIN_ID_STRING_ANSI
:
1165 ParseAnsiName(&Card
->Name
, &size
);
1169 DPRINT("Ignoring large tag Type 0x%X for Card %d\n",
1170 type
, Card
->CardId
);
1183 * Compute ISA PnP checksum for first eight bytes
1185 static UCHAR
Checksum(PUCHAR data
)
1188 UCHAR checksum
= 0x6a, bit
, b
;
1190 for (i
= 0; i
< 8; i
++) {
1192 for (j
= 0; j
< 8; j
++) {
1196 checksum
= ((((checksum
^ (checksum
>> 1)) &
1197 0x01) ^ bit
) << 7) | (checksum
>> 1);
1205 * Build a resource list for a logical ISA PnP device
1207 static NTSTATUS
BuildResourceList(PISAPNP_LOGICAL_DEVICE LogicalDevice
,
1208 PIO_RESOURCE_LIST DestinationList
,
1211 PLIST_ENTRY CurrentEntry
, Entry
;
1212 PISAPNP_CONFIGURATION_LIST List
;
1213 PISAPNP_DESCRIPTOR Descriptor
;
1216 if (IsListEmpty(&LogicalDevice
->Configuration
))
1217 return STATUS_NOT_FOUND
;
1219 CurrentEntry
= LogicalDevice
->Configuration
.Flink
;
1220 while (CurrentEntry
!= &LogicalDevice
->Configuration
) {
1221 List
= CONTAINING_RECORD(
1222 CurrentEntry
, ISAPNP_CONFIGURATION_LIST
, ListEntry
);
1224 if (List
->Priority
== Priority
) {
1226 DPRINT("Logical device %d DestinationList %p\n",
1227 LogicalDevice
->Number
,
1230 DestinationList
->Version
= 1;
1231 DestinationList
->Revision
= 1;
1232 DestinationList
->Count
= LogicalDevice
->DescriptorCount
;
1235 Entry
= List
->ListHead
.Flink
;
1236 while (Entry
!= &List
->ListHead
) {
1237 Descriptor
= CONTAINING_RECORD(
1238 Entry
, ISAPNP_DESCRIPTOR
, ListEntry
);
1240 DPRINT("Logical device %d Destination %p(%d)\n",
1241 LogicalDevice
->Number
,
1242 &DestinationList
->Descriptors
[i
],
1245 RtlCopyMemory(&DestinationList
->Descriptors
[i
],
1246 &Descriptor
->Descriptor
,
1247 sizeof(IO_RESOURCE_DESCRIPTOR
));
1251 Entry
= Entry
->Flink
;
1254 RemoveEntryList(&List
->ListEntry
);
1258 return STATUS_SUCCESS
;
1261 CurrentEntry
= CurrentEntry
->Flink
;
1264 return STATUS_UNSUCCESSFUL
;
1269 * Build resource lists for a logical ISA PnP device
1271 static NTSTATUS
BuildResourceLists(PISAPNP_LOGICAL_DEVICE LogicalDevice
)
1275 ULONG SingleListSize
;
1276 PIO_RESOURCE_LIST p
;
1279 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
)
1280 - sizeof(IO_RESOURCE_LIST
)
1281 + LogicalDevice
->ConfigurationSize
;
1283 DPRINT("Logical device %d ListSize 0x%X ConfigurationSize 0x%X DescriptorCount %d\n",
1284 LogicalDevice
->Number
, ListSize
,
1285 LogicalDevice
->ConfigurationSize
,
1286 LogicalDevice
->DescriptorCount
);
1288 LogicalDevice
->ResourceLists
=
1289 (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePoolWithTag(
1290 PagedPool
, ListSize
, TAG_ISAPNP
);
1291 if (!LogicalDevice
->ResourceLists
)
1292 return STATUS_INSUFFICIENT_RESOURCES
;
1294 RtlZeroMemory(LogicalDevice
->ResourceLists
, ListSize
);
1296 SingleListSize
= sizeof(IO_RESOURCE_LIST
) +
1297 (LogicalDevice
->DescriptorCount
- 1) *
1298 sizeof(IO_RESOURCE_DESCRIPTOR
);
1300 DPRINT("SingleListSize %d\n", SingleListSize
);
1303 p
= &LogicalDevice
->ResourceLists
->List
[0];
1305 Status
= BuildResourceList(LogicalDevice
, p
, Priority
);
1306 if (NT_SUCCESS(Status
)) {
1307 p
= (PIO_RESOURCE_LIST
)((ULONG_PTR
)p
+ SingleListSize
);
1310 } while (Status
!= STATUS_NOT_FOUND
);
1312 LogicalDevice
->ResourceLists
->ListSize
= ListSize
;
1313 LogicalDevice
->ResourceLists
->AlternativeLists
= Priority
+ 1;
1315 return STATUS_SUCCESS
;
1320 * Build resource lists for a ISA PnP card
1322 static NTSTATUS
BuildResourceListsForCard(PISAPNP_CARD Card
)
1324 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
1325 PLIST_ENTRY CurrentEntry
;
1328 CurrentEntry
= Card
->LogicalDevices
.Flink
;
1329 while (CurrentEntry
!= &Card
->LogicalDevices
) {
1330 LogicalDevice
= CONTAINING_RECORD(
1331 CurrentEntry
, ISAPNP_LOGICAL_DEVICE
, CardListEntry
);
1332 Status
= BuildResourceLists(LogicalDevice
);
1333 if (!NT_SUCCESS(Status
))
1335 CurrentEntry
= CurrentEntry
->Flink
;
1338 return STATUS_SUCCESS
;
1343 * Build resource lists for all present ISA PnP cards
1345 static NTSTATUS
BuildResourceListsForAll(
1346 PISAPNP_DEVICE_EXTENSION DeviceExtension
)
1348 PLIST_ENTRY CurrentEntry
;
1352 CurrentEntry
= DeviceExtension
->CardListHead
.Flink
;
1353 while (CurrentEntry
!= &DeviceExtension
->CardListHead
) {
1354 Card
= CONTAINING_RECORD(
1355 CurrentEntry
, ISAPNP_CARD
, ListEntry
);
1356 Status
= BuildResourceListsForCard(Card
);
1357 if (!NT_SUCCESS(Status
))
1359 CurrentEntry
= CurrentEntry
->Flink
;
1362 return STATUS_SUCCESS
;
1367 * Build device list for all present ISA PnP cards
1369 static NTSTATUS
BuildDeviceList(PISAPNP_DEVICE_EXTENSION DeviceExtension
)
1372 UCHAR header
[9], checksum
;
1379 for (csn
= 1; csn
<= 10; csn
++) {
1380 SendWake((UCHAR
)csn
);
1382 checksum
= Checksum(header
);
1384 if (checksum
== 0x00 || checksum
!= header
[8]) /* Invalid CSN */
1387 DPRINT("VENDOR: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1388 header
[0], header
[1], header
[2], header
[3],
1389 header
[4], header
[5], header
[6], header
[7], header
[8]);
1391 Card
= (PISAPNP_CARD
)ExAllocatePoolWithTag(
1392 PagedPool
, sizeof(ISAPNP_CARD
), TAG_ISAPNP
);
1394 return STATUS_INSUFFICIENT_RESOURCES
;
1396 RtlZeroMemory(Card
, sizeof(ISAPNP_CARD
));
1398 Card
->CardId
= (USHORT
) csn
;
1399 Card
->VendorId
= (header
[1] << 8) | header
[0];
1400 Card
->DeviceId
= (header
[3] << 8) | header
[2];
1401 Card
->Serial
= (header
[7] << 24) | (header
[6] << 16) | (header
[5] << 8) | header
[4];
1403 InitializeListHead(&Card
->LogicalDevices
);
1404 KeInitializeSpinLock(&Card
->LogicalDevicesLock
);
1406 ParseResourceMap(DeviceExtension
, Card
);
1408 ExInterlockedInsertTailList(&DeviceExtension
->CardListHead
,
1410 &DeviceExtension
->GlobalListLock
);
1413 return STATUS_SUCCESS
;
1418 ISAPNPQueryBusRelations(
1419 IN PDEVICE_OBJECT DeviceObject
,
1421 PIO_STACK_LOCATION IrpSp
)
1423 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1424 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
1425 PDEVICE_RELATIONS Relations
;
1426 PLIST_ENTRY CurrentEntry
;
1427 NTSTATUS Status
= STATUS_SUCCESS
;
1433 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1435 if (Irp
->IoStatus
.Information
) {
1436 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
1437 structure so we must merge this structure with our own */
1440 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
1441 (DeviceExtension
->DeviceListCount
- 1);
1442 Relations
= (PDEVICE_RELATIONS
)ExAllocatePoolWithTag(PagedPool
, Size
, TAG_ISAPNP
);
1444 return STATUS_INSUFFICIENT_RESOURCES
;
1446 Relations
->Count
= DeviceExtension
->DeviceListCount
;
1449 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
1450 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
) {
1451 LogicalDevice
= CONTAINING_RECORD(
1452 CurrentEntry
, ISAPNP_LOGICAL_DEVICE
, DeviceListEntry
);
1454 if (!LogicalDevice
->Pdo
) {
1455 /* Create a physical device object for the
1456 device as it does not already have one */
1457 Status
= IoCreateDevice(DeviceObject
->DriverObject
, 0,
1458 NULL
, FILE_DEVICE_CONTROLLER
, 0, FALSE
, &LogicalDevice
->Pdo
);
1459 if (!NT_SUCCESS(Status
)) {
1460 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
1461 ExFreePool(Relations
);
1465 LogicalDevice
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
1468 /* Reference the physical device object. The PnP manager
1469 will dereference it again when it is no longer needed */
1470 ObReferenceObject(LogicalDevice
->Pdo
);
1472 Relations
->Objects
[i
] = LogicalDevice
->Pdo
;
1476 CurrentEntry
= CurrentEntry
->Flink
;
1479 Irp
->IoStatus
.Information
= (ULONG_PTR
)Relations
;
1486 ISAPNPQueryDeviceRelations(
1487 IN PDEVICE_OBJECT DeviceObject
,
1489 PIO_STACK_LOCATION IrpSp
)
1491 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1496 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1498 if (DeviceExtension
->State
== dsStopped
)
1499 return STATUS_UNSUCCESSFUL
;
1501 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
1503 Status
= ISAPNPQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
1507 Status
= STATUS_NOT_IMPLEMENTED
;
1516 IN PDEVICE_OBJECT DeviceObject
,
1518 PIO_STACK_LOCATION IrpSp
)
1520 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1526 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1528 if (DeviceExtension
->State
== dsStarted
)
1529 return STATUS_SUCCESS
;
1531 NumCards
= IsolatePnPCards();
1533 DPRINT("Number of ISA PnP cards found: %d\n", NumCards
);
1535 Status
= BuildDeviceList(DeviceExtension
);
1536 if (!NT_SUCCESS(Status
)) {
1537 DPRINT("BuildDeviceList() failed with status 0x%X\n", Status
);
1541 Status
= BuildResourceListsForAll(DeviceExtension
);
1542 if (!NT_SUCCESS(Status
)) {
1543 DPRINT("BuildResourceListsForAll() failed with status 0x%X\n", Status
);
1547 DeviceExtension
->State
= dsStarted
;
1549 return STATUS_SUCCESS
;
1555 IN PDEVICE_OBJECT DeviceObject
,
1557 PIO_STACK_LOCATION IrpSp
)
1559 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1563 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1565 if (DeviceExtension
->State
!= dsStopped
) {
1566 /* FIXME: Stop device */
1567 DeviceExtension
->State
= dsStopped
;
1570 return STATUS_SUCCESS
;
1574 static DRIVER_DISPATCH ISAPNPDispatchOpenClose
;
1577 ISAPNPDispatchOpenClose(
1578 IN PDEVICE_OBJECT DeviceObject
,
1583 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1584 Irp
->IoStatus
.Information
= FILE_OPENED
;
1585 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1587 return STATUS_SUCCESS
;
1590 static DRIVER_DISPATCH ISAPNPDispatchReadWrite
;
1593 ISAPNPDispatchReadWrite(
1594 IN PDEVICE_OBJECT PhysicalDeviceObject
,
1599 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1600 Irp
->IoStatus
.Information
= 0;
1601 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1603 return STATUS_UNSUCCESSFUL
;
1606 static DRIVER_DISPATCH ISAPNPDispatchDeviceControl
;
1609 ISAPNPDispatchDeviceControl(
1610 IN PDEVICE_OBJECT DeviceObject
,
1613 PIO_STACK_LOCATION IrpSp
;
1618 Irp
->IoStatus
.Information
= 0;
1620 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1621 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
1623 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1624 Status
= STATUS_NOT_IMPLEMENTED
;
1628 if (Status
!= STATUS_PENDING
) {
1629 Irp
->IoStatus
.Status
= Status
;
1630 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1633 DPRINT("Leaving. Status 0x%X\n", Status
);
1638 static DRIVER_DISPATCH ISAPNPControl
;
1642 IN PDEVICE_OBJECT DeviceObject
,
1645 PIO_STACK_LOCATION IrpSp
;
1650 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1651 switch (IrpSp
->MinorFunction
) {
1652 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1653 Status
= ISAPNPQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1656 case IRP_MN_START_DEVICE
:
1657 Status
= ISAPNPStartDevice(DeviceObject
, Irp
, IrpSp
);
1660 case IRP_MN_STOP_DEVICE
:
1661 Status
= ISAPNPStopDevice(DeviceObject
, Irp
, IrpSp
);
1664 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
1665 /* Nothing to do here */
1666 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1667 Status
= Irp
->IoStatus
.Status
;
1671 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1672 Status
= STATUS_NOT_IMPLEMENTED
;
1676 if (Status
!= STATUS_PENDING
) {
1677 Irp
->IoStatus
.Status
= Status
;
1678 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1681 DPRINT("Leaving. Status 0x%X\n", Status
);
1690 IN PDRIVER_OBJECT DriverObject
,
1691 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1693 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1699 Status
= IoCreateDevice(DriverObject
, sizeof(ISAPNP_DEVICE_EXTENSION
),
1700 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
1701 if (!NT_SUCCESS(Status
)) {
1702 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
1706 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
1708 DeviceExtension
->Pdo
= PhysicalDeviceObject
;
1710 DeviceExtension
->Ldo
=
1711 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
1713 InitializeListHead(&DeviceExtension
->CardListHead
);
1714 InitializeListHead(&DeviceExtension
->DeviceListHead
);
1715 DeviceExtension
->DeviceListCount
= 0;
1716 KeInitializeSpinLock(&DeviceExtension
->GlobalListLock
);
1718 DeviceExtension
->State
= dsStopped
;
1720 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1722 DPRINT("Done AddDevice\n");
1724 return STATUS_SUCCESS
;
1731 IN PDRIVER_OBJECT DriverObject
,
1732 IN PUNICODE_STRING RegistryPath
)
1734 DbgPrint("ISA Plug and Play Bus Driver\n");
1736 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ISAPNPDispatchOpenClose
;
1737 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ISAPNPDispatchOpenClose
;
1738 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ISAPNPDispatchReadWrite
;
1739 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ISAPNPDispatchReadWrite
;
1740 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ISAPNPDispatchDeviceControl
;
1741 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = ISAPNPControl
;
1742 DriverObject
->DriverExtension
->AddDevice
= ISAPNPAddDevice
;
1744 return STATUS_SUCCESS
;