2 * PROJECT: ReactOS ISA PnP Bus driver
4 * PURPOSE: Hardware support code
5 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
17 WriteAddress(USHORT Address
)
19 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_ADDRESS
, Address
);
25 WriteData(USHORT Data
)
27 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_WRITE_DATA
, Data
);
33 ReadData(PUCHAR ReadDataPort
)
35 return READ_PORT_UCHAR(ReadDataPort
);
41 WriteByte(USHORT Address
, USHORT Value
)
43 WriteAddress(Address
);
50 ReadByte(PUCHAR ReadDataPort
, USHORT Address
)
52 WriteAddress(Address
);
53 return ReadData(ReadDataPort
);
59 ReadWord(PUCHAR ReadDataPort
, USHORT Address
)
61 return ((ReadByte(ReadDataPort
, Address
) << 8) |
62 (ReadByte(ReadDataPort
, Address
+ 1)));
68 SetReadDataPort(PUCHAR ReadDataPort
)
70 WriteByte(ISAPNP_READPORT
, ((ULONG_PTR
)ReadDataPort
>> 2));
76 EnterIsolationState(VOID
)
78 WriteAddress(ISAPNP_SERIALISOLATION
);
86 WriteByte(ISAPNP_CONFIGCONTROL
, ISAPNP_CONFIG_WAIT_FOR_KEY
);
94 WriteByte(ISAPNP_CONFIGCONTROL
, ISAPNP_CONFIG_RESET_CSN
);
102 WriteByte(ISAPNP_WAKE
, Csn
);
108 ReadResourceData(PUCHAR ReadDataPort
)
110 return ReadByte(ReadDataPort
, ISAPNP_RESOURCEDATA
);
116 ReadStatus(PUCHAR ReadDataPort
)
118 return ReadByte(ReadDataPort
, ISAPNP_STATUS
);
126 WriteByte(ISAPNP_CARDSELECTNUMBER
, Csn
);
132 WriteLogicalDeviceNumber(USHORT LogDev
)
134 WriteByte(ISAPNP_LOGICALDEVICENUMBER
, LogDev
);
140 ActivateDevice(USHORT LogDev
)
142 WriteLogicalDeviceNumber(LogDev
);
143 WriteByte(ISAPNP_ACTIVATE
, 1);
149 DeactivateDevice(USHORT LogDev
)
151 WriteLogicalDeviceNumber(LogDev
);
152 WriteByte(ISAPNP_ACTIVATE
, 0);
158 ReadIoBase(PUCHAR ReadDataPort
, USHORT Index
)
160 return ReadWord(ReadDataPort
, ISAPNP_IOBASE(Index
));
166 ReadIrqNo(PUCHAR ReadDataPort
, USHORT Index
)
168 return ReadByte(ReadDataPort
, ISAPNP_IRQNO(Index
));
176 KeStallExecutionProcessor(1000);
182 NextLFSR(USHORT Lfsr
, USHORT InputBit
)
184 ULONG NextLfsr
= Lfsr
>> 1;
186 NextLfsr
|= (((Lfsr
^ NextLfsr
) ^ InputBit
)) << 7;
201 Lfsr
= ISAPNP_LFSR_SEED
;
202 for (i
= 0; i
< 32; i
++)
205 Lfsr
= NextLFSR(Lfsr
, 0);
211 PeekByte(PUCHAR ReadDataPort
)
215 for (i
= 0; i
< 20; i
++)
217 if (ReadStatus(ReadDataPort
) & 0x01)
218 return ReadResourceData(ReadDataPort
);
228 Peek(PUCHAR ReadDataPort
, PVOID Buffer
, ULONG Length
)
232 for (i
= 0; i
< Length
; i
++)
234 byte
= PeekByte(ReadDataPort
);
236 *((PUCHAR
)Buffer
+ i
) = byte
;
242 IsaPnpChecksum(PISAPNP_IDENTIFIER Identifier
)
244 USHORT i
,j
, Lfsr
, Byte
;
246 Lfsr
= ISAPNP_LFSR_SEED
;
247 for (i
= 0; i
< 8; i
++)
249 Byte
= *(((PUCHAR
)Identifier
) + i
);
250 for (j
= 0; j
< 8; j
++)
252 Lfsr
= NextLFSR(Lfsr
, Byte
);
262 FindTag(PUCHAR ReadDataPort
, USHORT WantedTag
, PVOID Buffer
, ULONG Length
)
268 Tag
= PeekByte(ReadDataPort
);
269 if (ISAPNP_IS_SMALL_TAG(Tag
))
271 TagLen
= ISAPNP_SMALL_TAG_LEN(Tag
);
272 Tag
= ISAPNP_SMALL_TAG_NAME(Tag
);
276 TagLen
= PeekByte(ReadDataPort
) + (PeekByte(ReadDataPort
) << 8);
277 Tag
= ISAPNP_LARGE_TAG_NAME(Tag
);
280 if (Tag
== WantedTag
)
285 Peek(ReadDataPort
, Buffer
, Length
);
291 Peek(ReadDataPort
, NULL
, Length
);
293 } while (Tag
!= ISAPNP_TAG_END
);
300 FindLogDevId(PUCHAR ReadDataPort
, USHORT LogDev
, PISAPNP_LOGDEVID LogDeviceId
)
304 for (i
= 0; i
<= LogDev
; i
++)
306 if (!FindTag(ReadDataPort
, ISAPNP_TAG_LOGDEVID
, LogDeviceId
, sizeof(*LogDeviceId
)))
315 TryIsolate(PUCHAR ReadDataPort
)
317 ISAPNP_IDENTIFIER Identifier
;
319 BOOLEAN Seen55aa
, SeenLife
;
323 DPRINT("Setting read data port: 0x%p\n", ReadDataPort
);
336 SetReadDataPort(ReadDataPort
);
341 EnterIsolationState();
344 RtlZeroMemory(&Identifier
, sizeof(Identifier
));
346 Seen55aa
= SeenLife
= FALSE
;
347 for (i
= 0; i
< 9; i
++)
350 for (j
= 0; j
< 8; j
++)
352 Data
= ReadData(ReadDataPort
);
354 Data
= ((Data
<< 8) | ReadData(ReadDataPort
));
368 *(((PUCHAR
)&Identifier
) + i
) = Byte
;
375 DPRINT("Found no more cards\n");
381 DPRINT("Saw life but no cards, trying new read port\n");
386 DPRINT("Saw no sign of life, abandoning isolation\n");
392 if (Identifier
.Checksum
!= IsaPnpChecksum(&Identifier
))
394 DPRINT("Bad checksum, trying next read data port\n");
412 DPRINT("Found %d cards at read port 0x%p\n", Csn
, ReadDataPort
);
424 for (ReadPort
= (PUCHAR
)ISAPNP_READ_PORT_START
;
425 (ULONG_PTR
)ReadPort
<= ISAPNP_READ_PORT_MAX
;
426 ReadPort
+= ISAPNP_READ_PORT_STEP
)
428 /* Avoid the NE2000 probe space */
429 if ((ULONG_PTR
)ReadPort
>= 0x280 &&
430 (ULONG_PTR
)ReadPort
<= 0x380)
433 if (TryIsolate(ReadPort
) > 0)
441 DeviceActivation(PISAPNP_LOGICAL_DEVICE IsaDevice
,
446 Wake(IsaDevice
->CSN
);
449 ActivateDevice(IsaDevice
->LDN
);
451 DeactivateDevice(IsaDevice
->LDN
);
459 ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt
)
461 PISAPNP_LOGICAL_DEVICE LogDevice
;
462 ISAPNP_IDENTIFIER Identifier
;
463 ISAPNP_LOGDEVID LogDevId
;
469 ASSERT(FdoExt
->ReadDataPort
);
471 for (Csn
= 1; Csn
<= 0xFF; Csn
++)
473 for (LogDev
= 0; LogDev
<= 0xFF; LogDev
++)
475 Status
= IoCreateDevice(FdoExt
->Common
.Self
->DriverObject
,
476 sizeof(ISAPNP_LOGICAL_DEVICE
),
478 FILE_DEVICE_CONTROLLER
,
479 FILE_DEVICE_SECURE_OPEN
,
482 if (!NT_SUCCESS(Status
))
485 Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
487 LogDevice
= Pdo
->DeviceExtension
;
489 RtlZeroMemory(LogDevice
, sizeof(ISAPNP_LOGICAL_DEVICE
));
491 LogDevice
->Common
.Self
= Pdo
;
492 LogDevice
->Common
.IsFdo
= FALSE
;
493 LogDevice
->Common
.State
= dsStopped
;
495 LogDevice
->CSN
= Csn
;
496 LogDevice
->LDN
= LogDev
;
502 Peek(FdoExt
->ReadDataPort
, &Identifier
, sizeof(Identifier
));
504 if (Identifier
.VendorId
& 0x80)
506 IoDeleteDevice(LogDevice
->Common
.Self
);
507 return STATUS_SUCCESS
;
510 if (!FindLogDevId(FdoExt
->ReadDataPort
, LogDev
, &LogDevId
))
513 WriteLogicalDeviceNumber(LogDev
);
515 LogDevice
->VendorId
= LogDevId
.VendorId
;
516 LogDevice
->ProdId
= LogDevId
.ProdId
;
517 LogDevice
->IoAddr
= ReadIoBase(FdoExt
->ReadDataPort
, 0);
518 LogDevice
->IrqNo
= ReadIrqNo(FdoExt
->ReadDataPort
, 0);
520 DPRINT1("Detected ISA PnP device - VID: 0x%x PID: 0x%x IoBase: 0x%x IRQ:0x%x\n",
521 LogDevice
->VendorId
, LogDevice
->ProdId
, LogDevice
->IoAddr
, LogDevice
->IrqNo
);
525 Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
527 InsertTailList(&FdoExt
->DeviceListHead
, &LogDevice
->ListEntry
);
528 FdoExt
->DeviceCount
++;
532 return STATUS_SUCCESS
;
537 IsaHwDetectReadDataPort(
538 IN PISAPNP_FDO_EXTENSION FdoExt
)
540 FdoExt
->ReadDataPort
= Isolate();
541 if (!FdoExt
->ReadDataPort
)
543 DPRINT1("No read data port found\n");
544 return STATUS_UNSUCCESSFUL
;
547 DPRINT1("Detected read data port at 0x%p\n", FdoExt
->ReadDataPort
);
549 return STATUS_SUCCESS
;
555 IN PISAPNP_LOGICAL_DEVICE LogicalDevice
)
557 DeviceActivation(LogicalDevice
,
560 return STATUS_SUCCESS
;
565 IsaHwDeactivateDevice(
566 IN PISAPNP_LOGICAL_DEVICE LogicalDevice
)
568 DeviceActivation(LogicalDevice
,
571 return STATUS_SUCCESS
;
577 IN PISAPNP_FDO_EXTENSION FdoExt
)
579 return ProbeIsaPnpBus(FdoExt
);