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 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
FindNextReadPort(VOID
)
223 Port
= (ULONG
)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
;
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
)IsaPnPReadPort
);
337 KeStallExecutionProcessor(1000);
339 KeStallExecutionProcessor(1000);
342 if (iteration
== 1) {
343 IsaPnPReadPort
+= READ_DATA_PORT_STEP
;
344 if (!IsolateReadDataPortSelect()) {
345 DPRINT("Could not set read data port\n");
348 } else if (iteration
> 1) {
361 static VOID
Peek(PUCHAR Data
, ULONG Count
)
366 for (i
= 1; i
<= Count
; i
++) {
367 for (j
= 0; j
< 20; j
++) {
371 KeStallExecutionProcessor(100);
378 d
= ReadUchar(0x04); /* PRESDI */
386 * Skip specified number of bytes from stream
388 static VOID
Skip(ULONG Count
)
395 * Read one tag from stream
397 static BOOLEAN
ReadTag(PUCHAR Type
,
406 DPRINT("Invalid tag with value 0\n");
413 if (tag
& ISAPNP_RESOURCE_ITEM_TYPE
) {
414 /* Large resource item */
415 *Type
= (tag
& 0x7f);
417 *Size
= UCHAR2USHORT(tmp
[0], tmp
[1]);
420 if (*Type
> ISAPNP_LRIN_FL_MEMORY_RANGE32
) {
421 DPRINT("Invalid large tag with value 0x%X\n", *Type
);
426 /* Small resource item */
427 *Type
= (tag
>> 3) & 0x0f;
431 if (*Type
> ISAPNP_SRIN_END_TAG
) {
432 DPRINT("Invalid small tag with value 0x%X\n", *Type
);
438 DPRINT("Tag = 0x%X, Type = 0x%X, Size = %d (%s)\n",
439 tag
, *Type
, *Size
, TagName(*Type
, *Small
));
441 /* Probably invalid data */
442 if ((*Type
== 0xff) && (*Size
== 0xffff)) {
443 DPRINT("Invalid data (Type 0x%X Size 0x%X)\n", *Type
, *Size
);
453 * Parse ANSI name for ISA PnP logical device
455 static NTSTATUS
ParseAnsiName(PUNICODE_STRING Name
, PUSHORT Size
)
457 ANSI_STRING AnsiString
;
461 size1
= (*Size
>= sizeof(Buffer
)) ? (sizeof(Buffer
) - 1) : *Size
;
464 Buffer
[size1
] = '\0';
467 /* Clean whitespace from end of string */
468 while ((size1
> 0) && (Buffer
[--size1
] == ' '))
469 Buffer
[size1
] = '\0';
471 DPRINT("ANSI name: %s\n", Buffer
);
473 RtlInitAnsiString(&AnsiString
, (PCSZ
)&Buffer
);
474 return RtlAnsiStringToUnicodeString(Name
, &AnsiString
, TRUE
);
479 * Add a resource list to the
480 * resource lists of a logical device
482 static NTSTATUS
AddResourceList(
483 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
485 PISAPNP_CONFIGURATION_LIST
*NewList
)
487 PISAPNP_CONFIGURATION_LIST List
;
489 DPRINT("Adding resource list for logical device %d on card %d (Priority %d)\n",
490 LogicalDevice
->Number
,
491 LogicalDevice
->Card
->CardId
,
494 List
= (PISAPNP_CONFIGURATION_LIST
)
495 ExAllocatePoolWithTag(PagedPool
, sizeof(ISAPNP_CONFIGURATION_LIST
), TAG_ISAPNP
);
497 return STATUS_INSUFFICIENT_RESOURCES
;
499 RtlZeroMemory(List
, sizeof(ISAPNP_CONFIGURATION_LIST
));
501 List
->Priority
= Priority
;
503 InitializeListHead(&List
->ListHead
);
505 InsertTailList(&LogicalDevice
->Configuration
, &List
->ListEntry
);
509 return STATUS_SUCCESS
;
514 * Add a resource entry to the
515 * resource list of a logical device
517 static NTSTATUS
AddResourceDescriptor(
518 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
521 PISAPNP_DESCRIPTOR
*Descriptor
)
523 PLIST_ENTRY CurrentEntry
;
524 PISAPNP_CONFIGURATION_LIST List
;
525 PISAPNP_DESCRIPTOR d
;
528 DPRINT("Adding resource descriptor for logical device %d on card %d (%d of %d)\n",
529 LogicalDevice
->Number
,
530 LogicalDevice
->Card
->CardId
,
531 LogicalDevice
->CurrentDescriptorCount
,
532 LogicalDevice
->DescriptorCount
);
534 d
= (PISAPNP_DESCRIPTOR
)
535 ExAllocatePoolWithTag(PagedPool
, sizeof(ISAPNP_DESCRIPTOR
), TAG_ISAPNP
);
537 return STATUS_NO_MEMORY
;
539 RtlZeroMemory(d
, sizeof(ISAPNP_DESCRIPTOR
));
541 d
->Descriptor
.Option
= (UCHAR
) Option
;
545 CurrentEntry
= LogicalDevice
->Configuration
.Flink
;
546 while (CurrentEntry
!= &LogicalDevice
->Configuration
) {
547 List
= CONTAINING_RECORD(
548 CurrentEntry
, ISAPNP_CONFIGURATION_LIST
, ListEntry
);
550 if (List
->Priority
== Priority
) {
552 LogicalDevice
->ConfigurationSize
+= sizeof(IO_RESOURCE_DESCRIPTOR
);
553 InsertTailList(&List
->ListHead
, &d
->ListEntry
);
554 LogicalDevice
->CurrentDescriptorCount
++;
555 if (LogicalDevice
->DescriptorCount
<
556 LogicalDevice
->CurrentDescriptorCount
) {
557 LogicalDevice
->DescriptorCount
=
558 LogicalDevice
->CurrentDescriptorCount
;
561 return STATUS_SUCCESS
;
563 CurrentEntry
= CurrentEntry
->Flink
;
566 Status
= AddResourceList(LogicalDevice
, Priority
, &List
);
567 if (NT_SUCCESS(Status
)) {
568 LogicalDevice
->ConfigurationSize
+= sizeof(IO_RESOURCE_LIST
);
569 LogicalDevice
->CurrentDescriptorCount
= 0;
570 InsertTailList(&List
->ListHead
, &d
->ListEntry
);
578 * Add IRQ resource to resources list
580 static NTSTATUS
AddIrqResource(
581 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
586 PISAPNP_DESCRIPTOR Descriptor
;
588 ULONG irq
, i
, last
= 0;
594 irq
= UCHAR2USHORT(tmp
[0], tmp
[0]);
596 DPRINT("IRQ bitmask: 0x%X\n", irq
);
599 for (i
= 0; i
< 16; i
++) {
600 if (!found
&& (irq
& (1 << i
))) {
605 if ((found
&& !(irq
& (1 << i
))) || (irq
& (1 << i
) && (i
== 15))) {
606 Status
= AddResourceDescriptor(LogicalDevice
,
607 Priority
, Option
, &Descriptor
);
608 if (!NT_SUCCESS(Status
))
610 Descriptor
->Descriptor
.Type
= CmResourceTypeInterrupt
;
611 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
612 Descriptor
->Descriptor
.u
.Interrupt
.MinimumVector
= last
;
614 if ((irq
& (1 << i
)) && (i
== 15))
615 Descriptor
->Descriptor
.u
.Interrupt
.MaximumVector
= i
;
617 Descriptor
->Descriptor
.u
.Interrupt
.MaximumVector
= i
- 1;
619 DPRINT("Found IRQ range %d - %d for logical device %d on card %d\n",
620 Descriptor
->Descriptor
.u
.Interrupt
.MinimumVector
,
621 Descriptor
->Descriptor
.u
.Interrupt
.MaximumVector
,
622 LogicalDevice
->Number
,
623 LogicalDevice
->Card
->CardId
);
629 return STATUS_SUCCESS
;
633 * Add DMA resource to resources list
635 static NTSTATUS
AddDmaResource(
636 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
641 PISAPNP_DESCRIPTOR Descriptor
;
643 ULONG dma
, flags
, i
, last
= 0;
652 DPRINT("DMA bitmask: 0x%X\n", dma
);
655 for (i
= 0; i
< 8; i
++) {
656 if (!found
&& (dma
& (1 << i
))) {
661 if ((found
&& !(dma
& (1 << i
))) || (dma
& (1 << i
) && (i
== 15))) {
662 Status
= AddResourceDescriptor(LogicalDevice
,
663 Priority
, Option
, &Descriptor
);
664 if (!NT_SUCCESS(Status
))
666 Descriptor
->Descriptor
.Type
= CmResourceTypeDma
;
667 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
668 Descriptor
->Descriptor
.u
.Dma
.MinimumChannel
= last
;
670 if ((dma
& (1 << i
)) && (i
== 15))
671 Descriptor
->Descriptor
.u
.Dma
.MaximumChannel
= i
;
673 Descriptor
->Descriptor
.u
.Dma
.MaximumChannel
= i
- 1;
675 /* FIXME: Parse flags */
677 DPRINT("Found DMA range %d - %d for logical device %d on card %d\n",
678 Descriptor
->Descriptor
.u
.Dma
.MinimumChannel
,
679 Descriptor
->Descriptor
.u
.Dma
.MaximumChannel
,
680 LogicalDevice
->Number
,
681 LogicalDevice
->Card
->CardId
);
687 return STATUS_SUCCESS
;
691 * Add port resource to resources list
693 static NTSTATUS
AddIOPortResource(
694 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
700 DPRINT("I/O port: size 0x%X\n", Size
);
703 PISAPNP_DESCRIPTOR Descriptor
;
709 Status
= AddResourceDescriptor(LogicalDevice
,
710 Priority
, Option
, &Descriptor
);
711 if (!NT_SUCCESS(Status
))
713 Descriptor
->Descriptor
.Type
= CmResourceTypePort
;
714 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
715 Descriptor
->Descriptor
.u
.Port
.Length
= tmp
[6];
716 /* FIXME: Parse flags */
717 Descriptor
->Descriptor
.u
.Port
.Alignment
= 0;
718 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
.QuadPart
= UCHAR2USHORT(tmp
[1], tmp
[2]);
719 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
.QuadPart
= UCHAR2USHORT(tmp
[4], tmp
[4]);
721 DPRINT("Found I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
722 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
,
723 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
,
724 LogicalDevice
->Number
,
725 LogicalDevice
->Card
->CardId
);
727 return STATUS_SUCCESS
;
731 * Add fixed port resource to resources list
733 static NTSTATUS
AddFixedIOPortResource(
734 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
740 DPRINT("Fixed I/O port: size 0x%X\n", Size
);
743 PISAPNP_DESCRIPTOR Descriptor
;
749 Status
= AddResourceDescriptor(LogicalDevice
,
750 Priority
, Option
, &Descriptor
);
751 if (!NT_SUCCESS(Status
))
753 Descriptor
->Descriptor
.Type
= CmResourceTypePort
;
754 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
755 Descriptor
->Descriptor
.u
.Port
.Length
= tmp
[2];
756 Descriptor
->Descriptor
.u
.Port
.Alignment
= 0;
757 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
.QuadPart
= UCHAR2USHORT(tmp
[0], tmp
[1]);
758 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
.QuadPart
= UCHAR2USHORT(tmp
[0], tmp
[1]);
760 DPRINT("Found fixed I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
761 Descriptor
->Descriptor
.u
.Port
.MinimumAddress
,
762 Descriptor
->Descriptor
.u
.Port
.MaximumAddress
,
763 LogicalDevice
->Number
,
764 LogicalDevice
->Card
->CardId
);
766 return STATUS_SUCCESS
;
770 * Add memory resource to resources list
772 static NTSTATUS
AddMemoryResource(
773 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
779 DPRINT("Memory range: size 0x%X\n", Size
);
782 PISAPNP_DESCRIPTOR Descriptor
;
788 Status
= AddResourceDescriptor(LogicalDevice
,
789 Priority
, Option
, &Descriptor
);
790 if (!NT_SUCCESS(Status
))
792 Descriptor
->Descriptor
.Type
= CmResourceTypeMemory
;
793 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
794 Descriptor
->Descriptor
.u
.Memory
.Length
= UCHAR2USHORT(tmp
[7], tmp
[8]) << 8;
795 Descriptor
->Descriptor
.u
.Memory
.Alignment
= UCHAR2USHORT(tmp
[5], tmp
[6]);
796 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
.QuadPart
= UCHAR2USHORT(tmp
[1], tmp
[2]) << 8;
797 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
.QuadPart
= UCHAR2USHORT(tmp
[3], tmp
[4]) << 8;
799 DPRINT("Found memory range 0x%X - 0x%X for logical device %d on card %d\n",
800 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
,
801 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
,
802 LogicalDevice
->Number
,
803 LogicalDevice
->Card
->CardId
);
805 return STATUS_SUCCESS
;
809 * Add 32-bit memory resource to resources list
811 static NTSTATUS
AddMemory32Resource(
812 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
818 DPRINT("Memory32 range: size 0x%X\n", Size
);
821 PISAPNP_DESCRIPTOR Descriptor
;
827 Status
= AddResourceDescriptor(LogicalDevice
,
828 Priority
, Option
, &Descriptor
);
829 if (!NT_SUCCESS(Status
))
831 Descriptor
->Descriptor
.Type
= CmResourceTypeMemory
;
832 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
833 Descriptor
->Descriptor
.u
.Memory
.Length
=
834 UCHAR2ULONG(tmp
[13], tmp
[14], tmp
[15], tmp
[16]);
835 Descriptor
->Descriptor
.u
.Memory
.Alignment
=
836 UCHAR2ULONG(tmp
[9], tmp
[10], tmp
[11], tmp
[12]);
837 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
.QuadPart
=
838 UCHAR2ULONG(tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
839 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
.QuadPart
=
840 UCHAR2ULONG(tmp
[5], tmp
[6], tmp
[7], tmp
[8]);
842 DPRINT("Found memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
843 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
,
844 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
,
845 LogicalDevice
->Number
,
846 LogicalDevice
->Card
->CardId
);
848 return STATUS_SUCCESS
;
852 * Add 32-bit fixed memory resource to resources list
854 static NTSTATUS
AddFixedMemory32Resource(
855 PISAPNP_LOGICAL_DEVICE LogicalDevice
,
861 DPRINT("Memory32 range: size 0x%X\n", Size
);
864 PISAPNP_DESCRIPTOR Descriptor
;
870 Status
= AddResourceDescriptor(LogicalDevice
,
871 Priority
, Option
, &Descriptor
);
872 if (!NT_SUCCESS(Status
))
874 Descriptor
->Descriptor
.Type
= CmResourceTypeMemory
;
875 Descriptor
->Descriptor
.ShareDisposition
= CmResourceShareDeviceExclusive
;
876 Descriptor
->Descriptor
.u
.Memory
.Length
=
877 UCHAR2ULONG(tmp
[9], tmp
[10], tmp
[11], tmp
[12]);
878 Descriptor
->Descriptor
.u
.Memory
.Alignment
=
879 UCHAR2ULONG(tmp
[5], tmp
[6], tmp
[7], tmp
[8]);
880 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
.QuadPart
=
881 UCHAR2ULONG(tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
882 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
.QuadPart
=
883 UCHAR2ULONG(tmp
[1], tmp
[2], tmp
[3], tmp
[4]);
885 DPRINT("Found fixed memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
886 Descriptor
->Descriptor
.u
.Memory
.MinimumAddress
,
887 Descriptor
->Descriptor
.u
.Memory
.MaximumAddress
,
888 LogicalDevice
->Number
,
889 LogicalDevice
->Card
->CardId
);
891 return STATUS_SUCCESS
;
896 * Parse logical device tag
898 static PISAPNP_LOGICAL_DEVICE
ParseLogicalDevice(
899 PISAPNP_DEVICE_EXTENSION DeviceExtension
,
905 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
907 DPRINT("Card %d Number %d\n", Card
->CardId
, Number
);
911 LogicalDevice
= (PISAPNP_LOGICAL_DEVICE
)ExAllocatePoolWithTag(
912 PagedPool
, sizeof(ISAPNP_LOGICAL_DEVICE
), TAG_ISAPNP
);
916 RtlZeroMemory(LogicalDevice
, sizeof(ISAPNP_LOGICAL_DEVICE
));
918 LogicalDevice
->Number
= Number
;
919 LogicalDevice
->VendorId
= UCHAR2USHORT(tmp
[0], tmp
[1]);
920 LogicalDevice
->DeviceId
= UCHAR2USHORT(tmp
[2], tmp
[3]);
921 LogicalDevice
->Regs
= tmp
[4];
922 LogicalDevice
->Card
= Card
;
924 LogicalDevice
->Regs
|= tmp
[5] << 8;
926 InitializeListHead(&LogicalDevice
->Configuration
);
928 ExInterlockedInsertTailList(&Card
->LogicalDevices
,
929 &LogicalDevice
->CardListEntry
,
930 &Card
->LogicalDevicesLock
);
932 ExInterlockedInsertTailList(&DeviceExtension
->DeviceListHead
,
933 &LogicalDevice
->DeviceListEntry
,
934 &DeviceExtension
->GlobalListLock
);
936 DeviceExtension
->DeviceListCount
++;
938 return LogicalDevice
;
943 * Parse resource map for logical device
945 static BOOLEAN
CreateLogicalDevice(PISAPNP_DEVICE_EXTENSION DeviceExtension
,
946 PISAPNP_CARD Card
, USHORT Size
)
948 ULONG number
= 0, skip
= 0, compat
= 0;
950 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
953 ULONG Option
= IO_RESOURCE_REQUIRED
;
955 DPRINT("Card %d Size %d\n", Card
->CardId
, Size
);
957 LogicalDevice
= ParseLogicalDevice(DeviceExtension
, Card
, Size
, (USHORT
) number
++);
962 if (!ReadTag(&type
, &Size
, &Small
))
965 if (skip
&& !(Small
&& ((type
== ISAPNP_SRIN_LDEVICE_ID
)
966 || (type
== ISAPNP_SRIN_END_TAG
))))
971 case ISAPNP_SRIN_LDEVICE_ID
:
972 if ((Size
>= 5) && (Size
<= 6)) {
973 LogicalDevice
= ParseLogicalDevice(
974 DeviceExtension
, Card
, Size
, (USHORT
)number
++);
983 Option
= IO_RESOURCE_REQUIRED
;
987 case ISAPNP_SRIN_CDEVICE_ID
:
988 if ((Size
== 4) && (compat
< MAX_COMPATIBLE_ID
)) {
990 LogicalDevice
->CVendorId
[compat
] = UCHAR2USHORT(tmp
[0], tmp
[1]);
991 LogicalDevice
->CDeviceId
[compat
] = UCHAR2USHORT(tmp
[2], tmp
[3]);
997 case ISAPNP_SRIN_IRQ_FORMAT
:
998 if ((Size
< 2) || (Size
> 3))
1000 AddIrqResource(LogicalDevice
, Size
, Priority
, Option
);
1004 case ISAPNP_SRIN_DMA_FORMAT
:
1007 AddDmaResource(LogicalDevice
, Size
, Priority
, Option
);
1011 case ISAPNP_SRIN_START_DFUNCTION
:
1019 /* FIXME: Maybe use IO_RESOURCE_PREFERRED for some */
1020 Option
= IO_RESOURCE_ALTERNATIVE
;
1023 Option
= IO_RESOURCE_ALTERNATIVE
;
1026 DPRINT(" Start priority %d \n", Priority
);
1028 LogicalDevice
->CurrentDescriptorCount
= 0;
1032 case ISAPNP_SRIN_END_DFUNCTION
:
1034 DPRINT(" End priority %d \n", Priority
);
1039 Option
= IO_RESOURCE_REQUIRED
;
1040 LogicalDevice
->CurrentDescriptorCount
= 0;
1043 case ISAPNP_SRIN_IO_DESCRIPTOR
:
1046 AddIOPortResource(LogicalDevice
, Size
, Priority
, Option
);
1050 case ISAPNP_SRIN_FL_IO_DESCRIPOTOR
:
1053 AddFixedIOPortResource(LogicalDevice
, Size
, Priority
, Option
);
1057 case ISAPNP_SRIN_VENDOR_DEFINED
:
1060 case ISAPNP_SRIN_END_TAG
:
1066 DPRINT("Ignoring small tag of type 0x%X for logical device %d on card %d\n",
1067 type
, LogicalDevice
->Number
, Card
->CardId
);
1071 case ISAPNP_LRIN_MEMORY_RANGE
:
1074 AddMemoryResource(LogicalDevice
, Size
, Priority
, Option
);
1078 case ISAPNP_LRIN_ID_STRING_ANSI
:
1079 ParseAnsiName(&LogicalDevice
->Name
, &Size
);
1082 case ISAPNP_LRIN_ID_STRING_UNICODE
:
1085 case ISAPNP_LRIN_VENDOR_DEFINED
:
1088 case ISAPNP_LRIN_MEMORY_RANGE32
:
1091 AddMemory32Resource(LogicalDevice
, Size
, Priority
, Option
);
1095 case ISAPNP_LRIN_FL_MEMORY_RANGE32
:
1098 AddFixedMemory32Resource(LogicalDevice
, Size
, Priority
, Option
);
1103 DPRINT("Ignoring large tag of type 0x%X for logical device %d on card %d\n",
1104 type
, LogicalDevice
->Number
, Card
->CardId
);
1117 * Parse resource map for ISA PnP card
1119 static BOOLEAN
ParseResourceMap(PISAPNP_DEVICE_EXTENSION DeviceExtension
,
1122 UCHAR type
, tmp
[17];
1126 DPRINT("Card %d\n", Card
->CardId
);
1129 if (!ReadTag(&type
, &size
, &Small
))
1134 case ISAPNP_SRIN_VERSION
:
1138 Card
->PNPVersion
= tmp
[0];
1139 Card
->ProductVersion
= tmp
[1];
1143 case ISAPNP_SRIN_LDEVICE_ID
:
1144 if ((size
>= 5) && (size
<= 6)) {
1145 if (!CreateLogicalDevice(DeviceExtension
, Card
, size
))
1151 case ISAPNP_SRIN_CDEVICE_ID
:
1152 /* FIXME: Parse compatible IDs */
1155 case ISAPNP_SRIN_END_TAG
:
1161 DPRINT("Ignoring small tag Type 0x%X for Card %d\n", type
, Card
->CardId
);
1165 case ISAPNP_LRIN_ID_STRING_ANSI
:
1166 ParseAnsiName(&Card
->Name
, &size
);
1170 DPRINT("Ignoring large tag Type 0x%X for Card %d\n",
1171 type
, Card
->CardId
);
1184 * Compute ISA PnP checksum for first eight bytes
1186 static UCHAR
Checksum(PUCHAR data
)
1189 UCHAR checksum
= 0x6a, bit
, b
;
1191 for (i
= 0; i
< 8; i
++) {
1193 for (j
= 0; j
< 8; j
++) {
1197 checksum
= ((((checksum
^ (checksum
>> 1)) &
1198 0x01) ^ bit
) << 7) | (checksum
>> 1);
1206 * Build a resource list for a logical ISA PnP device
1208 static NTSTATUS
BuildResourceList(PISAPNP_LOGICAL_DEVICE LogicalDevice
,
1209 PIO_RESOURCE_LIST DestinationList
,
1212 PLIST_ENTRY CurrentEntry
, Entry
;
1213 PISAPNP_CONFIGURATION_LIST List
;
1214 PISAPNP_DESCRIPTOR Descriptor
;
1217 if (IsListEmpty(&LogicalDevice
->Configuration
))
1218 return STATUS_NOT_FOUND
;
1220 CurrentEntry
= LogicalDevice
->Configuration
.Flink
;
1221 while (CurrentEntry
!= &LogicalDevice
->Configuration
) {
1222 List
= CONTAINING_RECORD(
1223 CurrentEntry
, ISAPNP_CONFIGURATION_LIST
, ListEntry
);
1225 if (List
->Priority
== Priority
) {
1227 DPRINT("Logical device %d DestinationList %p\n",
1228 LogicalDevice
->Number
,
1231 DestinationList
->Version
= 1;
1232 DestinationList
->Revision
= 1;
1233 DestinationList
->Count
= LogicalDevice
->DescriptorCount
;
1236 Entry
= List
->ListHead
.Flink
;
1237 while (Entry
!= &List
->ListHead
) {
1238 Descriptor
= CONTAINING_RECORD(
1239 Entry
, ISAPNP_DESCRIPTOR
, ListEntry
);
1241 DPRINT("Logical device %d Destination %p(%d)\n",
1242 LogicalDevice
->Number
,
1243 &DestinationList
->Descriptors
[i
],
1246 RtlCopyMemory(&DestinationList
->Descriptors
[i
],
1247 &Descriptor
->Descriptor
,
1248 sizeof(IO_RESOURCE_DESCRIPTOR
));
1252 Entry
= Entry
->Flink
;
1255 RemoveEntryList(&List
->ListEntry
);
1259 return STATUS_SUCCESS
;
1262 CurrentEntry
= CurrentEntry
->Flink
;
1265 return STATUS_UNSUCCESSFUL
;
1270 * Build resource lists for a logical ISA PnP device
1272 static NTSTATUS
BuildResourceLists(PISAPNP_LOGICAL_DEVICE LogicalDevice
)
1276 ULONG SingleListSize
;
1277 PIO_RESOURCE_LIST p
;
1280 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
)
1281 - sizeof(IO_RESOURCE_LIST
)
1282 + LogicalDevice
->ConfigurationSize
;
1284 DPRINT("Logical device %d ListSize 0x%X ConfigurationSize 0x%X DescriptorCount %d\n",
1285 LogicalDevice
->Number
, ListSize
,
1286 LogicalDevice
->ConfigurationSize
,
1287 LogicalDevice
->DescriptorCount
);
1289 LogicalDevice
->ResourceLists
=
1290 (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePoolWithTag(
1291 PagedPool
, ListSize
, TAG_ISAPNP
);
1292 if (!LogicalDevice
->ResourceLists
)
1293 return STATUS_INSUFFICIENT_RESOURCES
;
1295 RtlZeroMemory(LogicalDevice
->ResourceLists
, ListSize
);
1297 SingleListSize
= sizeof(IO_RESOURCE_LIST
) +
1298 (LogicalDevice
->DescriptorCount
- 1) *
1299 sizeof(IO_RESOURCE_DESCRIPTOR
);
1301 DPRINT("SingleListSize %d\n", SingleListSize
);
1304 p
= &LogicalDevice
->ResourceLists
->List
[0];
1306 Status
= BuildResourceList(LogicalDevice
, p
, Priority
);
1307 if (NT_SUCCESS(Status
)) {
1308 p
= (PIO_RESOURCE_LIST
)((ULONG
)p
+ SingleListSize
);
1311 } while (Status
!= STATUS_NOT_FOUND
);
1313 LogicalDevice
->ResourceLists
->ListSize
= ListSize
;
1314 LogicalDevice
->ResourceLists
->AlternativeLists
= Priority
+ 1;
1316 return STATUS_SUCCESS
;
1321 * Build resource lists for a ISA PnP card
1323 static NTSTATUS
BuildResourceListsForCard(PISAPNP_CARD Card
)
1325 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
1326 PLIST_ENTRY CurrentEntry
;
1329 CurrentEntry
= Card
->LogicalDevices
.Flink
;
1330 while (CurrentEntry
!= &Card
->LogicalDevices
) {
1331 LogicalDevice
= CONTAINING_RECORD(
1332 CurrentEntry
, ISAPNP_LOGICAL_DEVICE
, CardListEntry
);
1333 Status
= BuildResourceLists(LogicalDevice
);
1334 if (!NT_SUCCESS(Status
))
1336 CurrentEntry
= CurrentEntry
->Flink
;
1339 return STATUS_SUCCESS
;
1344 * Build resource lists for all present ISA PnP cards
1346 static NTSTATUS
BuildResourceListsForAll(
1347 PISAPNP_DEVICE_EXTENSION DeviceExtension
)
1349 PLIST_ENTRY CurrentEntry
;
1353 CurrentEntry
= DeviceExtension
->CardListHead
.Flink
;
1354 while (CurrentEntry
!= &DeviceExtension
->CardListHead
) {
1355 Card
= CONTAINING_RECORD(
1356 CurrentEntry
, ISAPNP_CARD
, ListEntry
);
1357 Status
= BuildResourceListsForCard(Card
);
1358 if (!NT_SUCCESS(Status
))
1360 CurrentEntry
= CurrentEntry
->Flink
;
1363 return STATUS_SUCCESS
;
1368 * Build device list for all present ISA PnP cards
1370 static NTSTATUS
BuildDeviceList(PISAPNP_DEVICE_EXTENSION DeviceExtension
)
1373 UCHAR header
[9], checksum
;
1380 for (csn
= 1; csn
<= 10; csn
++) {
1381 SendWake((UCHAR
)csn
);
1383 checksum
= Checksum(header
);
1385 if (checksum
== 0x00 || checksum
!= header
[8]) /* Invalid CSN */
1388 DPRINT("VENDOR: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1389 header
[0], header
[1], header
[2], header
[3],
1390 header
[4], header
[5], header
[6], header
[7], header
[8]);
1392 Card
= (PISAPNP_CARD
)ExAllocatePoolWithTag(
1393 PagedPool
, sizeof(ISAPNP_CARD
), TAG_ISAPNP
);
1395 return STATUS_INSUFFICIENT_RESOURCES
;
1397 RtlZeroMemory(Card
, sizeof(ISAPNP_CARD
));
1399 Card
->CardId
= (USHORT
) csn
;
1400 Card
->VendorId
= (header
[1] << 8) | header
[0];
1401 Card
->DeviceId
= (header
[3] << 8) | header
[2];
1402 Card
->Serial
= (header
[7] << 24) | (header
[6] << 16) | (header
[5] << 8) | header
[4];
1404 InitializeListHead(&Card
->LogicalDevices
);
1405 KeInitializeSpinLock(&Card
->LogicalDevicesLock
);
1407 ParseResourceMap(DeviceExtension
, Card
);
1409 ExInterlockedInsertTailList(&DeviceExtension
->CardListHead
,
1411 &DeviceExtension
->GlobalListLock
);
1414 return STATUS_SUCCESS
;
1419 ISAPNPQueryBusRelations(
1420 IN PDEVICE_OBJECT DeviceObject
,
1422 PIO_STACK_LOCATION IrpSp
)
1424 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1425 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
1426 PDEVICE_RELATIONS Relations
;
1427 PLIST_ENTRY CurrentEntry
;
1428 NTSTATUS Status
= STATUS_SUCCESS
;
1434 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1436 if (Irp
->IoStatus
.Information
) {
1437 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
1438 structure so we must merge this structure with our own */
1441 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
1442 (DeviceExtension
->DeviceListCount
- 1);
1443 Relations
= (PDEVICE_RELATIONS
)ExAllocatePoolWithTag(PagedPool
, Size
, TAG_ISAPNP
);
1445 return STATUS_INSUFFICIENT_RESOURCES
;
1447 Relations
->Count
= DeviceExtension
->DeviceListCount
;
1450 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
1451 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
) {
1452 LogicalDevice
= CONTAINING_RECORD(
1453 CurrentEntry
, ISAPNP_LOGICAL_DEVICE
, DeviceListEntry
);
1455 if (!LogicalDevice
->Pdo
) {
1456 /* Create a physical device object for the
1457 device as it does not already have one */
1458 Status
= IoCreateDevice(DeviceObject
->DriverObject
, 0,
1459 NULL
, FILE_DEVICE_CONTROLLER
, 0, FALSE
, &LogicalDevice
->Pdo
);
1460 if (!NT_SUCCESS(Status
)) {
1461 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
1462 ExFreePool(Relations
);
1466 LogicalDevice
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
1469 /* Reference the physical device object. The PnP manager
1470 will dereference it again when it is no longer needed */
1471 ObReferenceObject(LogicalDevice
->Pdo
);
1473 Relations
->Objects
[i
] = LogicalDevice
->Pdo
;
1477 CurrentEntry
= CurrentEntry
->Flink
;
1480 Irp
->IoStatus
.Information
= (ULONG
)Relations
;
1487 ISAPNPQueryDeviceRelations(
1488 IN PDEVICE_OBJECT DeviceObject
,
1490 PIO_STACK_LOCATION IrpSp
)
1492 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1497 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1499 if (DeviceExtension
->State
== dsStopped
)
1500 return STATUS_UNSUCCESSFUL
;
1502 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
1504 Status
= ISAPNPQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
1508 Status
= STATUS_NOT_IMPLEMENTED
;
1517 IN PDEVICE_OBJECT DeviceObject
,
1519 PIO_STACK_LOCATION IrpSp
)
1521 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1527 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1529 if (DeviceExtension
->State
== dsStarted
)
1530 return STATUS_SUCCESS
;
1532 NumCards
= IsolatePnPCards();
1534 DPRINT("Number of ISA PnP cards found: %d\n", NumCards
);
1536 Status
= BuildDeviceList(DeviceExtension
);
1537 if (!NT_SUCCESS(Status
)) {
1538 DPRINT("BuildDeviceList() failed with status 0x%X\n", Status
);
1542 Status
= BuildResourceListsForAll(DeviceExtension
);
1543 if (!NT_SUCCESS(Status
)) {
1544 DPRINT("BuildResourceListsForAll() failed with status 0x%X\n", Status
);
1548 DeviceExtension
->State
= dsStarted
;
1550 return STATUS_SUCCESS
;
1556 IN PDEVICE_OBJECT DeviceObject
,
1558 PIO_STACK_LOCATION IrpSp
)
1560 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1564 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1566 if (DeviceExtension
->State
!= dsStopped
) {
1567 /* FIXME: Stop device */
1568 DeviceExtension
->State
= dsStopped
;
1571 return STATUS_SUCCESS
;
1575 static DRIVER_DISPATCH ISAPNPDispatchOpenClose
;
1578 ISAPNPDispatchOpenClose(
1579 IN PDEVICE_OBJECT DeviceObject
,
1584 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1585 Irp
->IoStatus
.Information
= FILE_OPENED
;
1586 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1588 return STATUS_SUCCESS
;
1591 static DRIVER_DISPATCH ISAPNPDispatchReadWrite
;
1594 ISAPNPDispatchReadWrite(
1595 IN PDEVICE_OBJECT PhysicalDeviceObject
,
1600 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1601 Irp
->IoStatus
.Information
= 0;
1602 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1604 return STATUS_UNSUCCESSFUL
;
1607 static DRIVER_DISPATCH ISAPNPDispatchDeviceControl
;
1610 ISAPNPDispatchDeviceControl(
1611 IN PDEVICE_OBJECT DeviceObject
,
1614 PIO_STACK_LOCATION IrpSp
;
1619 Irp
->IoStatus
.Information
= 0;
1621 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1622 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
1624 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1625 Status
= STATUS_NOT_IMPLEMENTED
;
1629 if (Status
!= STATUS_PENDING
) {
1630 Irp
->IoStatus
.Status
= Status
;
1631 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1634 DPRINT("Leaving. Status 0x%X\n", Status
);
1639 static DRIVER_DISPATCH ISAPNPControl
;
1643 IN PDEVICE_OBJECT DeviceObject
,
1646 PIO_STACK_LOCATION IrpSp
;
1651 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1652 switch (IrpSp
->MinorFunction
) {
1653 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1654 Status
= ISAPNPQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1657 case IRP_MN_START_DEVICE
:
1658 Status
= ISAPNPStartDevice(DeviceObject
, Irp
, IrpSp
);
1661 case IRP_MN_STOP_DEVICE
:
1662 Status
= ISAPNPStopDevice(DeviceObject
, Irp
, IrpSp
);
1666 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1667 Status
= STATUS_NOT_IMPLEMENTED
;
1671 if (Status
!= STATUS_PENDING
) {
1672 Irp
->IoStatus
.Status
= Status
;
1673 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1676 DPRINT("Leaving. Status 0x%X\n", Status
);
1685 IN PDRIVER_OBJECT DriverObject
,
1686 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1688 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1694 Status
= IoCreateDevice(DriverObject
, sizeof(ISAPNP_DEVICE_EXTENSION
),
1695 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
1696 if (!NT_SUCCESS(Status
)) {
1697 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
1701 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
1703 DeviceExtension
->Pdo
= PhysicalDeviceObject
;
1705 DeviceExtension
->Ldo
=
1706 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
1708 InitializeListHead(&DeviceExtension
->CardListHead
);
1709 InitializeListHead(&DeviceExtension
->DeviceListHead
);
1710 DeviceExtension
->DeviceListCount
= 0;
1711 KeInitializeSpinLock(&DeviceExtension
->GlobalListLock
);
1713 DeviceExtension
->State
= dsStopped
;
1715 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1717 DPRINT("Done AddDevice\n");
1719 return STATUS_SUCCESS
;
1726 IN PDRIVER_OBJECT DriverObject
,
1727 IN PUNICODE_STRING RegistryPath
)
1729 DbgPrint("ISA Plug and Play Bus Driver\n");
1731 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ISAPNPDispatchOpenClose
;
1732 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ISAPNPDispatchOpenClose
;
1733 DriverObject
->MajorFunction
[IRP_MJ_READ
] = ISAPNPDispatchReadWrite
;
1734 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = ISAPNPDispatchReadWrite
;
1735 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ISAPNPDispatchDeviceControl
;
1736 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = ISAPNPControl
;
1737 DriverObject
->DriverExtension
->AddDevice
= ISAPNPAddDevice
;
1739 return STATUS_SUCCESS
;