2 * PROJECT: ReactOS ISA PnP Bus driver
4 * PURPOSE: Hardware support code
5 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
16 WriteAddress(USHORT Address
)
18 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_ADDRESS
, Address
);
24 WriteData(USHORT Data
)
26 WRITE_PORT_UCHAR((PUCHAR
)ISAPNP_WRITE_DATA
, Data
);
32 ReadData(PUCHAR ReadDataPort
)
34 return READ_PORT_UCHAR(ReadDataPort
);
40 WriteByte(USHORT Address
, USHORT Value
)
42 WriteAddress(Address
);
49 ReadByte(PUCHAR ReadDataPort
, USHORT Address
)
51 WriteAddress(Address
);
52 return ReadData(ReadDataPort
);
58 ReadWord(PUCHAR ReadDataPort
, USHORT Address
)
60 return ((ReadByte(ReadDataPort
, Address
) << 8) |
61 (ReadByte(ReadDataPort
, Address
+ 1)));
67 SetReadDataPort(PUCHAR ReadDataPort
)
69 WriteByte(ISAPNP_READPORT
, ((ULONG_PTR
)ReadDataPort
>> 2));
75 EnterIsolationState(VOID
)
77 WriteAddress(ISAPNP_SERIALISOLATION
);
85 WriteByte(ISAPNP_CONFIGCONTROL
, ISAPNP_CONFIG_WAIT_FOR_KEY
);
93 WriteByte(ISAPNP_CONFIGCONTROL
, ISAPNP_CONFIG_RESET_CSN
);
101 WriteByte(ISAPNP_WAKE
, Csn
);
107 ReadResourceData(PUCHAR ReadDataPort
)
109 return ReadByte(ReadDataPort
, ISAPNP_RESOURCEDATA
);
115 ReadStatus(PUCHAR ReadDataPort
)
117 return ReadByte(ReadDataPort
, ISAPNP_STATUS
);
125 WriteByte(ISAPNP_CARDSELECTNUMBER
, Csn
);
131 WriteLogicalDeviceNumber(USHORT LogDev
)
133 WriteByte(ISAPNP_LOGICALDEVICENUMBER
, LogDev
);
139 ActivateDevice(USHORT LogDev
)
141 WriteLogicalDeviceNumber(LogDev
);
142 WriteByte(ISAPNP_ACTIVATE
, 1);
148 DeactivateDevice(USHORT LogDev
)
150 WriteLogicalDeviceNumber(LogDev
);
151 WriteByte(ISAPNP_ACTIVATE
, 0);
157 ReadIoBase(PUCHAR ReadDataPort
, USHORT Index
)
159 return ReadWord(ReadDataPort
, ISAPNP_IOBASE(Index
));
165 ReadIrqNo(PUCHAR ReadDataPort
, USHORT Index
)
167 return ReadByte(ReadDataPort
, ISAPNP_IRQNO(Index
));
175 KeStallExecutionProcessor(1000);
181 NextLFSR(USHORT Lfsr
, USHORT InputBit
)
183 ULONG NextLfsr
= Lfsr
>> 1;
185 NextLfsr
|= (((Lfsr
^ NextLfsr
) ^ InputBit
)) << 7;
200 Lfsr
= ISAPNP_LFSR_SEED
;
201 for (i
= 0; i
< 32; i
++)
204 Lfsr
= NextLFSR(Lfsr
, 0);
210 PeekByte(PUCHAR ReadDataPort
)
214 for (i
= 0; i
< 20; i
++)
216 if (ReadStatus(ReadDataPort
) & 0x01)
217 return ReadResourceData(ReadDataPort
);
227 Peek(PUCHAR ReadDataPort
, PVOID Buffer
, ULONG Length
)
231 for (i
= 0; i
< Length
; i
++)
233 byte
= PeekByte(ReadDataPort
);
235 *((PUCHAR
)Buffer
+ i
) = byte
;
241 IsaPnpChecksum(PISAPNP_IDENTIFIER Identifier
)
243 USHORT i
,j
, Lfsr
, Byte
;
245 Lfsr
= ISAPNP_LFSR_SEED
;
246 for (i
= 0; i
< 8; i
++)
248 Byte
= *(((PUCHAR
)Identifier
) + i
);
249 for (j
= 0; j
< 8; j
++)
251 Lfsr
= NextLFSR(Lfsr
, Byte
);
261 FindTag(PUCHAR ReadDataPort
, USHORT WantedTag
, PVOID Buffer
, ULONG Length
)
267 Tag
= PeekByte(ReadDataPort
);
268 if (ISAPNP_IS_SMALL_TAG(Tag
))
270 TagLen
= ISAPNP_SMALL_TAG_LEN(Tag
);
271 Tag
= ISAPNP_SMALL_TAG_NAME(Tag
);
275 TagLen
= PeekByte(ReadDataPort
) + (PeekByte(ReadDataPort
) << 8);
276 Tag
= ISAPNP_LARGE_TAG_NAME(Tag
);
279 if (Tag
== WantedTag
)
284 Peek(ReadDataPort
, Buffer
, Length
);
290 Peek(ReadDataPort
, NULL
, Length
);
292 } while (Tag
!= ISAPNP_TAG_END
);
299 FindLogDevId(PUCHAR ReadDataPort
, USHORT LogDev
, PISAPNP_LOGDEVID LogDeviceId
)
303 for (i
= 0; i
<= LogDev
; i
++)
305 if (!FindTag(ReadDataPort
, ISAPNP_TAG_LOGDEVID
, LogDeviceId
, sizeof(*LogDeviceId
)))
314 TryIsolate(PUCHAR ReadDataPort
)
316 ISAPNP_IDENTIFIER Identifier
;
318 BOOLEAN Seen55aa
, SeenLife
;
322 DPRINT("Setting read data port: 0x%x\n", ReadDataPort
);
335 SetReadDataPort(ReadDataPort
);
340 EnterIsolationState();
343 RtlZeroMemory(&Identifier
, sizeof(Identifier
));
345 Seen55aa
= SeenLife
= FALSE
;
346 for (i
= 0; i
< 9; i
++)
349 for (j
= 0; j
< 8; j
++)
351 Data
= ReadData(ReadDataPort
);
353 Data
= ((Data
<< 8) | ReadData(ReadDataPort
));
367 *(((PUCHAR
)&Identifier
) + i
) = Byte
;
374 DPRINT("Found no more cards\n");
380 DPRINT("Saw life but no cards, trying new read port\n");
385 DPRINT("Saw no sign of life, abandoning isolation\n");
391 if (Identifier
.Checksum
!= IsaPnpChecksum(&Identifier
))
393 DPRINT("Bad checksum, trying next read data port\n");
411 DPRINT("Found %d cards at read port 0x%x\n", Csn
, ReadDataPort
);
423 for (ReadPort
= (PUCHAR
)ISAPNP_READ_PORT_START
;
424 (ULONG_PTR
)ReadPort
<= ISAPNP_READ_PORT_MAX
;
425 ReadPort
+= ISAPNP_READ_PORT_STEP
)
427 /* Avoid the NE2000 probe space */
428 if ((ULONG_PTR
)ReadPort
>= 0x280 &&
429 (ULONG_PTR
)ReadPort
<= 0x380)
432 if (TryIsolate(ReadPort
) > 0)
440 DeviceActivation(PISAPNP_LOGICAL_DEVICE IsaDevice
,
445 Wake(IsaDevice
->CSN
);
448 ActivateDevice(IsaDevice
->LDN
);
450 DeactivateDevice(IsaDevice
->LDN
);
458 ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt
)
460 PISAPNP_LOGICAL_DEVICE LogDevice
;
461 ISAPNP_IDENTIFIER Identifier
;
462 ISAPNP_LOGDEVID LogDevId
;
468 ASSERT(FdoExt
->ReadDataPort
);
470 for (Csn
= 1; Csn
<= 0xFF; Csn
++)
472 for (LogDev
= 0; LogDev
<= 0xFF; LogDev
++)
474 Status
= IoCreateDevice(FdoExt
->Common
.Self
->DriverObject
,
475 sizeof(ISAPNP_LOGICAL_DEVICE
),
477 FILE_DEVICE_CONTROLLER
,
478 FILE_DEVICE_SECURE_OPEN
,
481 if (!NT_SUCCESS(Status
))
484 Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
486 LogDevice
= Pdo
->DeviceExtension
;
488 RtlZeroMemory(LogDevice
, sizeof(ISAPNP_LOGICAL_DEVICE
));
490 LogDevice
->Common
.Self
= Pdo
;
491 LogDevice
->Common
.IsFdo
= FALSE
;
492 LogDevice
->Common
.State
= dsStopped
;
494 LogDevice
->CSN
= Csn
;
495 LogDevice
->LDN
= LogDev
;
501 Peek(FdoExt
->ReadDataPort
, &Identifier
, sizeof(Identifier
));
503 if (Identifier
.VendorId
& 0x80)
505 IoDeleteDevice(LogDevice
->Common
.Self
);
506 return STATUS_SUCCESS
;
509 if (!FindLogDevId(FdoExt
->ReadDataPort
, LogDev
, &LogDevId
))
512 WriteLogicalDeviceNumber(LogDev
);
514 LogDevice
->VendorId
= LogDevId
.VendorId
;
515 LogDevice
->ProdId
= LogDevId
.ProdId
;
516 LogDevice
->IoAddr
= ReadIoBase(FdoExt
->ReadDataPort
, 0);
517 LogDevice
->IrqNo
= ReadIrqNo(FdoExt
->ReadDataPort
, 0);
519 DPRINT1("Detected ISA PnP device - VID: 0x%x PID: 0x%x IoBase: 0x%x IRQ:0x%x\n",
520 LogDevice
->VendorId
, LogDevice
->ProdId
, LogDevice
->IoAddr
, LogDevice
->IrqNo
);
524 Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
526 InsertTailList(&FdoExt
->DeviceListHead
, &LogDevice
->ListEntry
);
527 FdoExt
->DeviceCount
++;
531 return STATUS_SUCCESS
;
536 IsaHwDetectReadDataPort(
537 IN PISAPNP_FDO_EXTENSION FdoExt
)
539 FdoExt
->ReadDataPort
= Isolate();
540 if (!FdoExt
->ReadDataPort
)
542 DPRINT1("No read data port found\n");
543 return STATUS_UNSUCCESSFUL
;
546 DPRINT1("Detected read data port at 0x%x\n", FdoExt
->ReadDataPort
);
548 return STATUS_SUCCESS
;
554 IN PISAPNP_LOGICAL_DEVICE LogicalDevice
)
556 DeviceActivation(LogicalDevice
,
559 return STATUS_SUCCESS
;
564 IsaHwDeactivateDevice(
565 IN PISAPNP_LOGICAL_DEVICE LogicalDevice
)
567 DeviceActivation(LogicalDevice
,
570 return STATUS_SUCCESS
;
576 IN PISAPNP_FDO_EXTENSION FdoExt
)
578 return ProbeIsaPnpBus(FdoExt
);