1 /* $Id: isapnp.c,v 1.7 2003/09/20 20:31:57 weiden Exp $
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
11 #include <ddk/ntddk.h>
20 // Make the initialization routines discardable, so that they
23 #pragma alloc_text(init, DriverEntry)
25 // Make the PASSIVE_LEVEL routines pageable, so that they don't
26 // waste nonpaged memory
28 #pragma alloc_text(page, ACPIDispatchOpenClose)
29 #pragma alloc_text(page, ACPIDispatchRead)
30 #pragma alloc_text(page, ACPIDispatchWrite)
32 #endif /* ALLOC_PRAGMA */
35 PUCHAR IsaPnPReadPort
;
38 #define UCHAR2USHORT(v0, v1) \
41 #define UCHAR2ULONG(v0, v1, v2, v3) \
42 ((UCHAR2USHORT(v2, v3) << 16) | UCHAR2USHORT(v0, v1))
51 {"Unknown Small Tag"},
52 {"ISAPNP_SRIN_VERSION"},
53 {"ISAPNP_SRIN_LDEVICE_ID"},
54 {"ISAPNP_SRIN_CDEVICE_ID"},
55 {"ISAPNP_SRIN_IRQ_FORMAT"},
56 {"ISAPNP_SRIN_DMA_FORMAT"},
57 {"ISAPNP_SRIN_START_DFUNCTION"},
58 {"ISAPNP_SRIN_END_DFUNCTION"},
59 {"ISAPNP_SRIN_IO_DESCRIPTOR"},
60 {"ISAPNP_SRIN_FL_IO_DESCRIPOTOR"},
61 {"Reserved Small Tag"},
62 {"Reserved Small Tag"},
63 {"Reserved Small Tag"},
64 {"Reserved Small Tag"},
65 {"ISAPNP_SRIN_VENDOR_DEFINED"},
66 {"ISAPNP_SRIN_END_TAG"}
73 {"Unknown Large Tag"},
74 {"ISAPNP_LRIN_MEMORY_RANGE"},
75 {"ISAPNP_LRIN_ID_STRING_ANSI"},
76 {"ISAPNP_LRIN_ID_STRING_UNICODE"},
77 {"ISAPNP_LRIN_VENDOR_DEFINED"},
78 {"ISAPNP_LRIN_MEMORY_RANGE32"},
79 {"ISAPNP_LRIN_FL_MEMORY_RANGE32"}
82 PCSZ
TagName(ULONG Tag
, BOOLEAN Small
)
84 if (Small
&& (Tag
<= ISAPNP_SRIN_END_TAG
)) {
85 return SmallTags
[Tag
].Name
;
86 } else if (Tag
<= ISAPNP_LRIN_FL_MEMORY_RANGE32
){
87 return LargeTags
[Tag
].Name
;
95 static inline VOID
WriteData(UCHAR Value
)
97 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_WRITE_PORT
, Value
);
100 static inline VOID
WriteAddress(UCHAR Value
)
102 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_ADDRESS_PORT
, Value
);
103 KeStallExecutionProcessor(20);
106 static inline UCHAR
ReadData(VOID
)
108 return READ_PORT_UCHAR(IsaPnPReadPort
);
111 UCHAR
ReadUchar(UCHAR Index
)
117 USHORT
ReadUshort(UCHAR Index
)
121 Value
= ReadUchar(Index
);
122 Value
= (Value
<< 8) + ReadUchar(Index
+ 1);
126 ULONG
ReadUlong(UCHAR Index
)
130 Value
= ReadUchar(Index
);
131 Value
= (Value
<< 8) + ReadUchar(Index
+ 1);
132 Value
= (Value
<< 8) + ReadUchar(Index
+ 2);
133 Value
= (Value
<< 8) + ReadUchar(Index
+ 3);
137 VOID
WriteUchar(UCHAR Index
, UCHAR Value
)
143 VOID
WriteUshort(UCHAR Index
, USHORT Value
)
145 WriteUchar(Index
, Value
>> 8);
146 WriteUchar(Index
+ 1, Value
);
149 VOID
WriteUlong(UCHAR Index
, ULONG Value
)
151 WriteUchar(Index
, Value
>> 24);
152 WriteUchar(Index
+ 1, Value
>> 16);
153 WriteUchar(Index
+ 2, Value
>> 8);
154 WriteUchar(Index
+ 3, Value
);
157 static inline VOID
SetReadDataPort(ULONG Port
)
159 IsaPnPReadPort
= (PUCHAR
)Port
;
160 WriteUchar(0x00, Port
>> 2);
161 KeStallExecutionProcessor(100);
164 static VOID
SendKey(VOID
)
170 /* FIXME: Is there something better? */
171 KeStallExecutionProcessor(1000);
177 for (i
= 1; i
< 32; i
++) {
178 msb
= ((code
& 0x01) ^ ((code
& 0x02) >> 1)) << 7;
179 code
= (code
>> 1) | msb
;
184 /* Place all PnP cards in wait-for-key state */
185 static VOID
SendWait(VOID
)
187 WriteUchar(0x02, 0x02);
190 VOID
SendWake(UCHAR csn
)
192 WriteUchar(ISAPNP_CARD_WAKECSN
, csn
);
195 VOID
SelectLogicalDevice(UCHAR LogicalDevice
)
197 WriteUchar(ISAPNP_CARD_LOG_DEVICE_NUM
, LogicalDevice
);
200 VOID
ActivateLogicalDevice(UCHAR LogicalDevice
)
202 SelectLogicalDevice(LogicalDevice
);
203 WriteUchar(ISAPNP_CONTROL_ACTIVATE
, 0x1);
204 KeStallExecutionProcessor(250);
207 VOID
DeactivateLogicalDevice(UCHAR LogicalDevice
)
209 SelectLogicalDevice(LogicalDevice
);
210 WriteUchar(ISAPNP_CONTROL_ACTIVATE
, 0x0);
211 KeStallExecutionProcessor(500);
214 #define READ_DATA_PORT_STEP 32 /* Minimum is 4 */
216 static ULONG
FindNextReadPort(VOID
)
222 Port
= (ULONG
)IsaPnPReadPort
;
226 Port
+= READ_DATA_PORT_STEP
;
230 if (Port
> ISAPNP_MAX_READ_PORT
)
242 * We cannot use NE2000 probe spaces for
244 * ISAPnP or we will lock up machines
248 if ((Port
< 0x280) || (Port
> 0x380))
260 static BOOLEAN
IsolateReadDataPortSelect(VOID
)
267 /* Control: reset CSN and conditionally everything else too */
268 WriteUchar(0x02, 0x05);
269 KeStallExecutionProcessor(2000);
275 Port
= FindNextReadPort();
281 SetReadDataPort(Port
);
282 KeStallExecutionProcessor(1000);
284 KeStallExecutionProcessor(1000);
289 * Isolate (assign uniqued CSN) to all ISA PnP devices
291 static ULONG
IsolatePnPCards(VOID
)
293 UCHAR checksum
= 0x6a;
303 IsaPnPReadPort
= (PUCHAR
)ISAPNP_MIN_READ_PORT
;
304 if (!IsolateReadDataPortSelect()) {
305 DPRINT("Could not set read data port\n");
310 for (i
= 1; i
<= 64; i
++) {
311 data
= ReadData() << 8;
312 KeStallExecutionProcessor(250);
313 data
= data
| ReadData();
314 KeStallExecutionProcessor(250);
317 checksum
= ((((checksum
^ (checksum
>> 1)) & 0x01) ^ bit
) << 7) | (checksum
>> 1);
320 for (i
= 65; i
<= 72; i
++) {
321 data
= ReadData() << 8;
322 KeStallExecutionProcessor(250);
323 data
= data
| ReadData();
324 KeStallExecutionProcessor(250);
326 chksum
|= (1 << (i
- 65));
328 if ((checksum
!= 0x00) && (checksum
== chksum
)) {
331 WriteUchar(0x06, csn
);
332 KeStallExecutionProcessor(250);
335 SetReadDataPort((ULONG
)IsaPnPReadPort
);
336 KeStallExecutionProcessor(1000);
338 KeStallExecutionProcessor(1000);
341 if (iteration
== 1) {
342 IsaPnPReadPort
+= READ_DATA_PORT_STEP
;
343 if (!IsolateReadDataPortSelect()) {
344 DPRINT("Could not set read data port\n");
347 } else if (iteration
> 1) {
360 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
;
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 ExAllocatePool(PagedPool
, sizeof(ISAPNP_CONFIGURATION_LIST
));
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 ExAllocatePool(PagedPool
, sizeof(ISAPNP_DESCRIPTOR
));
537 return STATUS_NO_MEMORY
;
539 RtlZeroMemory(d
, sizeof(ISAPNP_DESCRIPTOR
));
541 d
->Descriptor
.Option
= 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
;
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
;
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
)ExAllocatePool(
912 PagedPool
, sizeof(ISAPNP_LOGICAL_DEVICE
));
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
, 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
, 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
;
1218 if (IsListEmpty(&LogicalDevice
->Configuration
))
1219 return STATUS_NOT_FOUND
;
1221 CurrentEntry
= LogicalDevice
->Configuration
.Flink
;
1222 while (CurrentEntry
!= &LogicalDevice
->Configuration
) {
1223 List
= CONTAINING_RECORD(
1224 CurrentEntry
, ISAPNP_CONFIGURATION_LIST
, ListEntry
);
1226 if (List
->Priority
== Priority
) {
1228 DPRINT("Logical device %d DestinationList 0x%X\n",
1229 LogicalDevice
->Number
,
1232 DestinationList
->Version
= 1;
1233 DestinationList
->Revision
= 1;
1234 DestinationList
->Count
= LogicalDevice
->DescriptorCount
;
1237 Entry
= List
->ListHead
.Flink
;
1238 while (Entry
!= &List
->ListHead
) {
1239 Descriptor
= CONTAINING_RECORD(
1240 Entry
, ISAPNP_DESCRIPTOR
, ListEntry
);
1242 DPRINT("Logical device %d Destination 0x%X(%d)\n",
1243 LogicalDevice
->Number
,
1244 &DestinationList
->Descriptors
[i
],
1247 RtlCopyMemory(&DestinationList
->Descriptors
[i
],
1248 &Descriptor
->Descriptor
,
1249 sizeof(IO_RESOURCE_DESCRIPTOR
));
1253 Entry
= Entry
->Flink
;
1256 RemoveEntryList(&List
->ListEntry
);
1260 return STATUS_SUCCESS
;
1263 CurrentEntry
= CurrentEntry
->Flink
;
1266 return STATUS_UNSUCCESSFUL
;
1271 * Build resource lists for a logical ISA PnP device
1273 static NTSTATUS
BuildResourceLists(PISAPNP_LOGICAL_DEVICE LogicalDevice
)
1277 ULONG SingleListSize
;
1278 PIO_RESOURCE_LIST p
;
1281 ListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
)
1282 - sizeof(IO_RESOURCE_LIST
)
1283 + LogicalDevice
->ConfigurationSize
;
1285 DPRINT("Logical device %d ListSize 0x%X ConfigurationSize 0x%X DescriptorCount %d\n",
1286 LogicalDevice
->Number
, ListSize
,
1287 LogicalDevice
->ConfigurationSize
,
1288 LogicalDevice
->DescriptorCount
);
1290 LogicalDevice
->ResourceLists
=
1291 (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePool(
1292 PagedPool
, ListSize
);
1293 if (!LogicalDevice
->ResourceLists
)
1294 return STATUS_INSUFFICIENT_RESOURCES
;
1296 RtlZeroMemory(LogicalDevice
->ResourceLists
, ListSize
);
1298 SingleListSize
= sizeof(IO_RESOURCE_LIST
) +
1299 (LogicalDevice
->DescriptorCount
- 1) *
1300 sizeof(IO_RESOURCE_DESCRIPTOR
);
1302 DPRINT("SingleListSize %d\n", SingleListSize
);
1305 p
= &LogicalDevice
->ResourceLists
->List
[0];
1307 Status
= BuildResourceList(LogicalDevice
, p
, Priority
);
1308 if (NT_SUCCESS(Status
)) {
1309 p
= (PIO_RESOURCE_LIST
)((ULONG
)p
+ SingleListSize
);
1312 } while (Status
!= STATUS_NOT_FOUND
);
1314 LogicalDevice
->ResourceLists
->ListSize
= ListSize
;
1315 LogicalDevice
->ResourceLists
->AlternativeLists
= Priority
+ 1;
1317 return STATUS_SUCCESS
;
1322 * Build resource lists for a ISA PnP card
1324 static NTSTATUS
BuildResourceListsForCard(PISAPNP_CARD Card
)
1326 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
1327 PLIST_ENTRY CurrentEntry
;
1330 CurrentEntry
= Card
->LogicalDevices
.Flink
;
1331 while (CurrentEntry
!= &Card
->LogicalDevices
) {
1332 LogicalDevice
= CONTAINING_RECORD(
1333 CurrentEntry
, ISAPNP_LOGICAL_DEVICE
, CardListEntry
);
1334 Status
= BuildResourceLists(LogicalDevice
);
1335 if (!NT_SUCCESS(Status
))
1337 CurrentEntry
= CurrentEntry
->Flink
;
1340 return STATUS_SUCCESS
;
1345 * Build resource lists for all present ISA PnP cards
1347 static NTSTATUS
BuildResourceListsForAll(
1348 PISAPNP_DEVICE_EXTENSION DeviceExtension
)
1350 PLIST_ENTRY CurrentEntry
;
1354 CurrentEntry
= DeviceExtension
->CardListHead
.Flink
;
1355 while (CurrentEntry
!= &DeviceExtension
->CardListHead
) {
1356 Card
= CONTAINING_RECORD(
1357 CurrentEntry
, ISAPNP_CARD
, ListEntry
);
1358 Status
= BuildResourceListsForCard(Card
);
1359 if (!NT_SUCCESS(Status
))
1361 CurrentEntry
= CurrentEntry
->Flink
;
1364 return STATUS_SUCCESS
;
1369 * Build device list for all present ISA PnP cards
1371 static NTSTATUS
BuildDeviceList(PISAPNP_DEVICE_EXTENSION DeviceExtension
)
1374 UCHAR header
[9], checksum
;
1382 for (csn
= 1; csn
<= 10; csn
++) {
1385 checksum
= Checksum(header
);
1387 if (checksum
== 0x00 || checksum
!= header
[8]) /* Invalid CSN */
1390 DPRINT("VENDOR: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1391 header
[0], header
[1], header
[2], header
[3],
1392 header
[4], header
[5], header
[6], header
[7], header
[8]);
1394 Card
= (PISAPNP_CARD
)ExAllocatePool(
1395 PagedPool
, sizeof(ISAPNP_CARD
));
1397 return STATUS_INSUFFICIENT_RESOURCES
;
1399 RtlZeroMemory(Card
, sizeof(ISAPNP_CARD
));
1402 Card
->VendorId
= (header
[1] << 8) | header
[0];
1403 Card
->DeviceId
= (header
[3] << 8) | header
[2];
1404 Card
->Serial
= (header
[7] << 24) | (header
[6] << 16) | (header
[5] << 8) | header
[4];
1406 InitializeListHead(&Card
->LogicalDevices
);
1407 KeInitializeSpinLock(&Card
->LogicalDevicesLock
);
1409 ParseResourceMap(DeviceExtension
, Card
);
1411 ExInterlockedInsertTailList(&DeviceExtension
->CardListHead
,
1413 &DeviceExtension
->GlobalListLock
);
1416 return STATUS_SUCCESS
;
1421 ISAPNPQueryBusRelations(
1422 IN PDEVICE_OBJECT DeviceObject
,
1424 PIO_STACK_LOCATION IrpSp
)
1426 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1427 PISAPNP_LOGICAL_DEVICE LogicalDevice
;
1428 PDEVICE_RELATIONS Relations
;
1429 PLIST_ENTRY CurrentEntry
;
1436 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1438 if (Irp
->IoStatus
.Information
) {
1439 /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
1440 structure so we must merge this structure with our own */
1443 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
1444 (DeviceExtension
->DeviceListCount
- 1);
1445 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
1447 return STATUS_INSUFFICIENT_RESOURCES
;
1449 Relations
->Count
= DeviceExtension
->DeviceListCount
;
1452 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
1453 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
) {
1454 LogicalDevice
= CONTAINING_RECORD(
1455 CurrentEntry
, ISAPNP_LOGICAL_DEVICE
, DeviceListEntry
);
1457 if (!LogicalDevice
->Pdo
) {
1458 /* Create a physical device object for the
1459 device as it does not already have one */
1460 Status
= IoCreateDevice(DeviceObject
->DriverObject
, 0,
1461 NULL
, FILE_DEVICE_CONTROLLER
, 0, FALSE
, &LogicalDevice
->Pdo
);
1462 if (!NT_SUCCESS(Status
)) {
1463 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
1464 ExFreePool(Relations
);
1468 LogicalDevice
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
1471 /* Reference the physical device object. The PnP manager
1472 will dereference it again when it is no longer needed */
1473 ObReferenceObject(LogicalDevice
->Pdo
);
1475 Relations
->Objects
[i
] = LogicalDevice
->Pdo
;
1479 CurrentEntry
= CurrentEntry
->Flink
;
1482 Irp
->IoStatus
.Information
= (ULONG
)Relations
;
1489 ISAPNPQueryDeviceRelations(
1490 IN PDEVICE_OBJECT DeviceObject
,
1492 PIO_STACK_LOCATION IrpSp
)
1494 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1499 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1501 if (DeviceExtension
->State
== dsStopped
)
1502 return STATUS_UNSUCCESSFUL
;
1504 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
) {
1506 Status
= ISAPNPQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
1510 Status
= STATUS_NOT_IMPLEMENTED
;
1519 IN PDEVICE_OBJECT DeviceObject
,
1521 PIO_STACK_LOCATION IrpSp
)
1523 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1529 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1531 if (DeviceExtension
->State
== dsStarted
)
1532 return STATUS_SUCCESS
;
1534 NumCards
= IsolatePnPCards();
1536 DPRINT("Number of ISA PnP cards found: %d\n", NumCards
);
1538 Status
= BuildDeviceList(DeviceExtension
);
1539 if (!NT_SUCCESS(Status
)) {
1540 DPRINT("BuildDeviceList() failed with status 0x%X\n", Status
);
1544 Status
= BuildResourceListsForAll(DeviceExtension
);
1545 if (!NT_SUCCESS(Status
)) {
1546 DPRINT("BuildResourceListsForAll() failed with status 0x%X\n", Status
);
1550 DeviceExtension
->State
= dsStarted
;
1552 return STATUS_SUCCESS
;
1558 IN PDEVICE_OBJECT DeviceObject
,
1560 PIO_STACK_LOCATION IrpSp
)
1562 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1566 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1568 if (DeviceExtension
->State
!= dsStopped
) {
1569 /* FIXME: Stop device */
1570 DeviceExtension
->State
= dsStopped
;
1573 return STATUS_SUCCESS
;
1579 ISAPNPDispatchOpenClose(
1580 IN PDEVICE_OBJECT DeviceObject
,
1585 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1586 Irp
->IoStatus
.Information
= FILE_OPENED
;
1587 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1589 return STATUS_SUCCESS
;
1595 ISAPNPDispatchReadWrite(
1596 IN PDEVICE_OBJECT PhysicalDeviceObject
,
1601 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1602 Irp
->IoStatus
.Information
= 0;
1603 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1605 return STATUS_UNSUCCESSFUL
;
1611 ISAPNPDispatchDeviceControl(
1612 IN PDEVICE_OBJECT DeviceObject
,
1615 PIO_STACK_LOCATION IrpSp
;
1620 Irp
->IoStatus
.Information
= 0;
1622 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1623 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
1625 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1626 Status
= STATUS_NOT_IMPLEMENTED
;
1630 if (Status
!= STATUS_PENDING
) {
1631 Irp
->IoStatus
.Status
= Status
;
1632 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1635 DPRINT("Leaving. Status 0x%X\n", Status
);
1644 IN PDEVICE_OBJECT DeviceObject
,
1647 PIO_STACK_LOCATION IrpSp
;
1652 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
1653 switch (IrpSp
->MinorFunction
) {
1654 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1655 Status
= ISAPNPQueryDeviceRelations(DeviceObject
, Irp
, IrpSp
);
1658 case IRP_MN_START_DEVICE
:
1659 Status
= ISAPNPStartDevice(DeviceObject
, Irp
, IrpSp
);
1662 case IRP_MN_STOP_DEVICE
:
1663 Status
= ISAPNPStopDevice(DeviceObject
, Irp
, IrpSp
);
1667 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
1668 Status
= STATUS_NOT_IMPLEMENTED
;
1672 if (Status
!= STATUS_PENDING
) {
1673 Irp
->IoStatus
.Status
= Status
;
1674 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1677 DPRINT("Leaving. Status 0x%X\n", Status
);
1686 IN PDRIVER_OBJECT DriverObject
,
1687 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1689 PISAPNP_DEVICE_EXTENSION DeviceExtension
;
1695 Status
= IoCreateDevice(DriverObject
, sizeof(ISAPNP_DEVICE_EXTENSION
),
1696 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
1697 if (!NT_SUCCESS(Status
)) {
1698 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
1702 DeviceExtension
= (PISAPNP_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
1704 DeviceExtension
->Pdo
= PhysicalDeviceObject
;
1706 DeviceExtension
->Ldo
=
1707 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
1709 InitializeListHead(&DeviceExtension
->CardListHead
);
1710 InitializeListHead(&DeviceExtension
->DeviceListHead
);
1711 DeviceExtension
->DeviceListCount
= 0;
1712 KeInitializeSpinLock(&DeviceExtension
->GlobalListLock
);
1714 DeviceExtension
->State
= dsStopped
;
1716 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1718 DPRINT("Done AddDevice\n");
1720 return STATUS_SUCCESS
;
1727 IN PDRIVER_OBJECT DriverObject
,
1728 IN PUNICODE_STRING RegistryPath
)
1730 DbgPrint("ISA Plug and Play Bus Driver\n");
1732 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = (PDRIVER_DISPATCH
)ISAPNPDispatchOpenClose
;
1733 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = (PDRIVER_DISPATCH
)ISAPNPDispatchOpenClose
;
1734 DriverObject
->MajorFunction
[IRP_MJ_READ
] = (PDRIVER_DISPATCH
)ISAPNPDispatchReadWrite
;
1735 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = (PDRIVER_DISPATCH
)ISAPNPDispatchReadWrite
;
1736 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = (PDRIVER_DISPATCH
)ISAPNPDispatchDeviceControl
;
1737 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = (PDRIVER_DISPATCH
)ISAPNPControl
;
1738 DriverObject
->DriverExtension
->AddDevice
= ISAPNPAddDevice
;
1740 return STATUS_SUCCESS
;