4 * Copyright (C) 2003 Eric Kohl
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include "../../reactos/registry.h"
37 #define CLOCK_TICK_RATE (1193182)
38 #define LATCH (CLOCK_TICK_RATE / HZ)
42 #define MOUSE_TYPE_NONE 0
43 /* Microsoft Mouse with 2 buttons */
44 #define MOUSE_TYPE_MICROSOFT 1
45 /* Logitech Mouse with 3 buttons */
46 #define MOUSE_TYPE_LOGITECH 2
47 /* Microsoft Wheel Mouse (aka Z Mouse) */
48 #define MOUSE_TYPE_WHEELZ 3
49 /* Mouse Systems Mouse */
50 #define MOUSE_TYPE_MOUSESYSTEMS 4
55 /* Controller registers. */
56 #define CONTROLLER_REGISTER_STATUS 0x64
57 #define CONTROLLER_REGISTER_CONTROL 0x64
58 #define CONTROLLER_REGISTER_DATA 0x60
60 /* Controller commands. */
61 #define CONTROLLER_COMMAND_READ_MODE 0x20
62 #define CONTROLLER_COMMAND_WRITE_MODE 0x60
63 #define CONTROLLER_COMMAND_GET_VERSION 0xA1
64 #define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
65 #define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
66 #define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
67 #define CONTROLLER_COMMAND_SELF_TEST 0xAA
68 #define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
69 #define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
70 #define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
71 #define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
72 #define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
74 /* Controller status */
75 #define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
76 #define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
77 #define CONTROLLER_STATUS_SELF_TEST 0x04
78 #define CONTROLLER_STATUS_COMMAND 0x08
79 #define CONTROLLER_STATUS_UNLOCKED 0x10
80 #define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
81 #define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
82 #define CONTROLLER_STATUS_PARITY_ERROR 0x80
83 #define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
84 CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
86 /* Timeout in ms for sending to keyboard controller. */
87 #define CONTROLLER_TIMEOUT 250
90 typedef struct _CM_INT13_DRIVE_PARAMETER
97 } CM_INT13_DRIVE_PARAMETER
, *PCM_INT13_DRIVE_PARAMETER
;
100 typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA
103 U32 NumberOfCylinders
;
106 } CM_DISK_GEOMETRY_DEVICE_DATA
, *PCM_DISK_GEOMETRY_DEVICE_DATA
;
109 typedef struct _CM_PNP_BIOS_DEVICE_NODE
115 U16 DeviceAttributes
;
116 } __attribute__((packed
)) CM_PNP_BIOS_DEVICE_NODE
, *PCM_PNP_BIOS_DEVICE_NODE
;
119 typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK
126 U32 EventFlagAddress
;
127 U16 RealModeEntryOffset
;
128 U16 RealModeEntrySegment
;
129 U16 ProtectedModeEntryOffset
;
130 U32 ProtectedModeCodeBaseAddress
;
132 U16 RealModeDataBaseAddress
;
133 U32 ProtectedModeDataBaseAddress
;
134 } __attribute__((packed
)) CM_PNP_BIOS_INSTALLATION_CHECK
, *PCM_PNP_BIOS_INSTALLATION_CHECK
;
137 typedef struct _CM_SERIAL_DEVICE_DATA
142 } CM_SERIAL_DEVICE_DATA
, *PCM_SERIAL_DEVICE_DATA
;
145 static char Hex
[] = "0123456789ABCDEF";
146 static unsigned int delay_count
= 1;
149 /* FUNCTIONS ****************************************************************/
153 __KeStallExecutionProcessor(U32 Loops
)
155 register unsigned int i
;
156 for (i
= 0; i
< Loops
; i
++);
159 VOID
KeStallExecutionProcessor(U32 Microseconds
)
161 U64 LoopCount
= ((U64
)delay_count
* (U64
)Microseconds
) / 1000ULL;
162 __KeStallExecutionProcessor((U32
)LoopCount
);
171 WRITE_PORT_UCHAR((PU8
)0x43, 0x00);
172 Count
= READ_PORT_UCHAR((PU8
)0x40);
173 Count
|= READ_PORT_UCHAR((PU8
)0x40) << 8;
180 WaitFor8254Wraparound(VOID
)
186 CurCount
= Read8254Timer();
190 PrevCount
= CurCount
;
191 CurCount
= Read8254Timer();
192 Delta
= CurCount
- PrevCount
;
195 * This limit for delta seems arbitrary, but it isn't, it's
196 * slightly above the level of error a buggy Mercury/Neptune
197 * chipset timer can cause.
205 HalpCalibrateStallExecution(VOID
)
211 /* Initialise timer interrupt with MILLISECOND ms interval */
212 WRITE_PORT_UCHAR((PU8
)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
213 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
& 0xff); /* LSB */
214 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
>> 8); /* MSB */
216 /* Stage 1: Coarse calibration */
218 WaitFor8254Wraparound();
223 delay_count
<<= 1; /* Next delay count to try */
225 WaitFor8254Wraparound();
227 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
229 CurCount
= Read8254Timer();
230 } while (CurCount
> LATCH
/ 2);
232 delay_count
>>= 1; /* Get bottom value for delay */
234 /* Stage 2: Fine calibration */
236 calib_bit
= delay_count
; /* Which bit are we going to test */
238 for(i
=0;i
<PRECISION
;i
++) {
239 calib_bit
>>= 1; /* Next bit to calibrate */
240 if(!calib_bit
) break; /* If we have done all bits, stop */
242 delay_count
|= calib_bit
; /* Set the bit in delay_count */
244 WaitFor8254Wraparound();
246 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
248 CurCount
= Read8254Timer();
249 if (CurCount
<= LATCH
/ 2) /* If a tick has passed, turn the */
250 delay_count
&= ~calib_bit
; /* calibrated bit back off */
253 /* We're finished: Do the finishing touches */
254 delay_count
/= (MILLISEC
/ 2); /* Calculate delay_count for 1ms */
259 SetComponentInformation(HKEY ComponentKey
,
264 CM_COMPONENT_INFORMATION CompInfo
;
267 CompInfo
.Flags
= Flags
;
268 CompInfo
.Version
= 0;
270 CompInfo
.Affinity
= Affinity
;
272 /* Set 'Component Information' value */
273 Error
= RegSetValue(ComponentKey
,
274 "Component Information",
277 sizeof(CM_COMPONENT_INFORMATION
));
278 if (Error
!= ERROR_SUCCESS
)
280 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
286 DetectPnpBios(HKEY SystemKey
, U32
*BusNumber
)
288 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
289 PCM_PNP_BIOS_DEVICE_NODE DeviceNode
;
290 PCM_PNP_BIOS_INSTALLATION_CHECK InstData
;
304 InstData
= (PCM_PNP_BIOS_INSTALLATION_CHECK
)PnpBiosSupported();
305 if (InstData
== NULL
|| strncmp(InstData
->Signature
, "$PnP", 4))
307 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS not supported\n"));
310 DbgPrint((DPRINT_HWDETECT
, "Signature '%c%c%c%c'\n",
311 InstData
->Signature
[0], InstData
->Signature
[1],
312 InstData
->Signature
[2], InstData
->Signature
[3]));
315 x
= PnpBiosGetDeviceNodeCount(&NodeSize
, &NodeCount
);
316 if (x
!= 0 || NodeSize
== 0 || NodeCount
== 0)
318 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS failed to enumerate device nodes\n"));
321 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS supported\n"));
322 DbgPrint((DPRINT_HWDETECT
, "MaxNodeSize %u NodeCount %u\n", NodeSize
, NodeCount
));
323 DbgPrint((DPRINT_HWDETECT
, "Estimated buffer size %u\n", NodeSize
* NodeCount
));
325 /* Create new bus key */
327 "MultifunctionAdapter\\%u", *BusNumber
);
328 Error
= RegCreateKey(SystemKey
,
331 if (Error
!= ERROR_SUCCESS
)
333 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
337 /* Increment bus number */
340 /* Set 'Identifier' value */
341 Error
= RegSetValue(BusKey
,
346 if (Error
!= ERROR_SUCCESS
)
348 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
352 /* Set 'Configuration Data' value */
353 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + (NodeSize
* NodeCount
);
354 FullResourceDescriptor
= MmAllocateMemory(Size
);
355 if (FullResourceDescriptor
== NULL
)
357 DbgPrint((DPRINT_HWDETECT
,
358 "Failed to allocate resource descriptor\n"));
361 memset(FullResourceDescriptor
, 0, Size
);
363 /* Initialize resource descriptor */
364 FullResourceDescriptor
->InterfaceType
= Internal
;
365 FullResourceDescriptor
->BusNumber
= 0;
366 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
367 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
368 CmResourceTypeDeviceSpecific
;
369 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].ShareDisposition
=
370 CmResourceShareUndetermined
;
371 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
373 Ptr
= (char *)(((PVOID
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0]) +
374 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
376 /* Set instalation check data */
377 memcpy (Ptr
, InstData
, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
));
378 Ptr
+= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
380 /* Copy device nodes */
382 PnpBufferSize
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
383 for (i
= 0; i
< 0xFF; i
++)
387 x
= PnpBiosGetDeviceNode(&NodeNumber
, (PVOID
)DISKREADBUFFER
);
390 DeviceNode
= (PCM_PNP_BIOS_DEVICE_NODE
)DISKREADBUFFER
;
392 DbgPrint((DPRINT_HWDETECT
,
393 "Node: %u Size %u (0x%x)\n",
397 // printf("Node: %u Size %u (0x%x)\n",
400 // DeviceNode->Size);
406 Ptr
+= DeviceNode
->Size
;
407 PnpBufferSize
+= DeviceNode
->Size
;
410 if (FoundNodeCount
>= NodeCount
)
415 /* Set real data size */
416 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
418 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + PnpBufferSize
;
420 DbgPrint((DPRINT_HWDETECT
, "Real buffer size: %u\n", PnpBufferSize
));
421 DbgPrint((DPRINT_HWDETECT
, "Resource size: %u\n", Size
));
423 /* Set 'Configuration Data' value */
424 Error
= RegSetValue(BusKey
,
425 "Configuration Data",
426 REG_FULL_RESOURCE_DESCRIPTOR
,
427 (PU8
) FullResourceDescriptor
,
429 MmFreeMemory(FullResourceDescriptor
);
430 if (Error
!= ERROR_SUCCESS
)
432 DbgPrint((DPRINT_HWDETECT
,
433 "RegSetValue(Configuration Data) failed (Error %u)\n",
441 SetHarddiskConfigurationData(HKEY DiskKey
,
444 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
445 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
446 EXTENDED_GEOMETRY ExtGeometry
;
451 /* Set 'Configuration Data' value */
452 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
453 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
454 FullResourceDescriptor
= MmAllocateMemory(Size
);
455 if (FullResourceDescriptor
== NULL
)
457 DbgPrint((DPRINT_HWDETECT
,
458 "Failed to allocate a full resource descriptor\n"));
462 memset(FullResourceDescriptor
, 0, Size
);
463 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
464 FullResourceDescriptor
->BusNumber
= 0;
465 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
466 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
467 CmResourceTypeDeviceSpecific
;
468 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
469 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
470 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
471 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
473 /* Get pointer to geometry data */
474 DiskGeometry
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
476 /* Get the disk geometry */
477 ExtGeometry
.Size
= sizeof(EXTENDED_GEOMETRY
);
478 if (DiskGetExtendedDriveParameters(DriveNumber
, &ExtGeometry
, ExtGeometry
.Size
))
480 DiskGeometry
->BytesPerSector
= ExtGeometry
.BytesPerSector
;
481 DiskGeometry
->NumberOfCylinders
= ExtGeometry
.Cylinders
;
482 DiskGeometry
->SectorsPerTrack
= ExtGeometry
.SectorsPerTrack
;
483 DiskGeometry
->NumberOfHeads
= ExtGeometry
.Heads
;
485 else if(DiskGetDriveParameters(DriveNumber
, &Geometry
))
487 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
488 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
489 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
490 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
494 DbgPrint((DPRINT_HWDETECT
, "Reading disk geometry failed\n"));
495 MmFreeMemory(FullResourceDescriptor
);
498 DbgPrint((DPRINT_HWDETECT
,
499 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
501 DiskGeometry
->NumberOfCylinders
,
502 DiskGeometry
->NumberOfHeads
,
503 DiskGeometry
->SectorsPerTrack
,
504 DiskGeometry
->BytesPerSector
));
506 Error
= RegSetValue(DiskKey
,
507 "Configuration Data",
508 REG_FULL_RESOURCE_DESCRIPTOR
,
509 (PU8
) FullResourceDescriptor
,
511 MmFreeMemory(FullResourceDescriptor
);
512 if (Error
!= ERROR_SUCCESS
)
514 DbgPrint((DPRINT_HWDETECT
,
515 "RegSetValue(Configuration Data) failed (Error %u)\n",
522 SetHarddiskIdentifier(HKEY DiskKey
,
525 PMASTER_BOOT_RECORD Mbr
;
534 if (!DiskReadLogicalSectors(DriveNumber
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
536 DbgPrint((DPRINT_HWDETECT
, "Reading MBR failed\n"));
540 Buffer
= (U32
*)DISKREADBUFFER
;
541 Mbr
= (PMASTER_BOOT_RECORD
)DISKREADBUFFER
;
543 Signature
= Mbr
->Signature
;
544 DbgPrint((DPRINT_HWDETECT
, "Signature: %x\n", Signature
));
546 /* Calculate the MBR checksum */
548 for (i
= 0; i
< 128; i
++)
550 Checksum
+= Buffer
[i
];
552 Checksum
= ~Checksum
+ 1;
553 DbgPrint((DPRINT_HWDETECT
, "Checksum: %x\n", Checksum
));
555 /* Convert checksum and signature to identifier string */
556 Identifier
[0] = Hex
[(Checksum
>> 28) & 0x0F];
557 Identifier
[1] = Hex
[(Checksum
>> 24) & 0x0F];
558 Identifier
[2] = Hex
[(Checksum
>> 20) & 0x0F];
559 Identifier
[3] = Hex
[(Checksum
>> 16) & 0x0F];
560 Identifier
[4] = Hex
[(Checksum
>> 12) & 0x0F];
561 Identifier
[5] = Hex
[(Checksum
>> 8) & 0x0F];
562 Identifier
[6] = Hex
[(Checksum
>> 4) & 0x0F];
563 Identifier
[7] = Hex
[Checksum
& 0x0F];
565 Identifier
[9] = Hex
[(Signature
>> 28) & 0x0F];
566 Identifier
[10] = Hex
[(Signature
>> 24) & 0x0F];
567 Identifier
[11] = Hex
[(Signature
>> 20) & 0x0F];
568 Identifier
[12] = Hex
[(Signature
>> 16) & 0x0F];
569 Identifier
[13] = Hex
[(Signature
>> 12) & 0x0F];
570 Identifier
[14] = Hex
[(Signature
>> 8) & 0x0F];
571 Identifier
[15] = Hex
[(Signature
>> 4) & 0x0F];
572 Identifier
[16] = Hex
[Signature
& 0x0F];
573 Identifier
[17] = '-';
574 Identifier
[18] = 'A';
576 DbgPrint((DPRINT_HWDETECT
, "Identifier: %xsn", Identifier
));
579 Error
= RegSetValue(DiskKey
,
584 if (Error
!= ERROR_SUCCESS
)
586 DbgPrint((DPRINT_HWDETECT
,
587 "RegSetValue(Identifier) failed (Error %u)\n",
594 DetectBiosDisks(HKEY SystemKey
,
597 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
598 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
607 /* Count the number of visible drives */
608 DiskReportError(FALSE
);
610 while (DiskReadLogicalSectors(0x80 + DiskCount
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
614 DiskReportError(TRUE
);
615 DbgPrint((DPRINT_HWDETECT
, "BIOS reports %d harddisk%s\n",
616 (int)DiskCount
, (DiskCount
== 1) ? "": "s"));
618 /* Allocate resource descriptor */
619 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
620 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
621 FullResourceDescriptor
= MmAllocateMemory(Size
);
622 if (FullResourceDescriptor
== NULL
)
624 DbgPrint((DPRINT_HWDETECT
,
625 "Failed to allocate resource descriptor\n"));
629 /* Initialize resource descriptor */
630 memset(FullResourceDescriptor
, 0, Size
);
631 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
632 FullResourceDescriptor
->BusNumber
= -1;
633 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
634 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
635 CmResourceTypeDeviceSpecific
;
636 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
637 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
638 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
639 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
641 /* Get harddisk Int13 geometry data */
642 Int13Drives
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
643 for (i
= 0; i
< DiskCount
; i
++)
645 if (DiskGetDriveParameters(0x80 + i
, &Geometry
))
647 Int13Drives
[i
].DriveSelect
= 0x80 + i
;
648 Int13Drives
[i
].MaxCylinders
= Geometry
.Cylinders
- 1;
649 Int13Drives
[i
].SectorsPerTrack
= Geometry
.Sectors
;
650 Int13Drives
[i
].MaxHeads
= Geometry
.Heads
- 1;
651 Int13Drives
[i
].NumberDrives
= DiskCount
;
653 DbgPrint((DPRINT_HWDETECT
,
654 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
656 Geometry
.Cylinders
- 1,
659 Geometry
.BytesPerSector
));
663 /* Set 'Configuration Data' value */
664 Error
= RegSetValue(SystemKey
,
665 "Configuration Data",
666 REG_FULL_RESOURCE_DESCRIPTOR
,
667 (PU8
) FullResourceDescriptor
,
669 MmFreeMemory(FullResourceDescriptor
);
670 if (Error
!= ERROR_SUCCESS
)
672 DbgPrint((DPRINT_HWDETECT
,
673 "RegSetValue(Configuration Data) failed (Error %u)\n",
678 /* Create and fill subkey for each harddisk */
679 for (i
= 0; i
< DiskCount
; i
++)
681 /* Create disk key */
683 "DiskController\\0\\DiskPeripheral\\%u",
686 Error
= RegCreateKey(BusKey
,
689 if (Error
!= ERROR_SUCCESS
)
691 DbgPrint((DPRINT_HWDETECT
, "Failed to create drive key\n"));
694 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
696 /* Set disk values */
697 SetHarddiskConfigurationData(DiskKey
, 0x80 + i
);
698 SetHarddiskIdentifier(DiskKey
, 0x80 + i
);
704 InitializeSerialPort(U32 Port
,
707 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, 0x80); /* set DLAB on */
708 WRITE_PORT_UCHAR((PUCHAR
)Port
, 0x60); /* speed LO byte */
709 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* speed HI byte */
710 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, LineControl
);
711 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* set comm and DLAB to 0 */
712 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09); /* DR int enable */
713 READ_PORT_UCHAR((PUCHAR
)Port
+ 5); /* clear error bits */
718 DetectMicrosoftMouse(U32 Port
)
725 /* Shutdown mouse or something like that */
726 LineControl
= READ_PORT_UCHAR((PUCHAR
)Port
+ 4);
727 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, (LineControl
& ~0x02) | 0x01);
728 KeStallExecutionProcessor(500000);
731 while (READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 0x01)
732 READ_PORT_UCHAR((PUCHAR
)Port
);
735 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
736 * 'Output Line 2' message. This enables mouse to identify.
738 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
740 /* Wait 10 milliseconds for the mouse getting ready */
741 KeStallExecutionProcessor(10000);
743 /* Read first four bytes, which contains Microsoft Mouse signs */
744 for (i
= 0; i
< 4; i
++)
746 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
748 KeStallExecutionProcessor(1000);
751 return MOUSE_TYPE_NONE
;
753 Buffer
[i
] = READ_PORT_UCHAR((PUCHAR
)Port
);
756 DbgPrint((DPRINT_HWDETECT
,
757 "Mouse data: %x %x %x %x\n",
758 Buffer
[0],Buffer
[1],Buffer
[2],Buffer
[3]));
760 /* Check that four bytes for signs */
761 for (i
= 0; i
< 4; ++i
)
763 if (Buffer
[i
] == 'B')
765 /* Sign for Microsoft Ballpoint */
766 // DbgPrint("Microsoft Ballpoint device detected\n");
767 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
768 return MOUSE_TYPE_NONE
;
770 else if (Buffer
[i
] == 'M')
772 /* Sign for Microsoft Mouse protocol followed by button specifier */
776 return MOUSE_TYPE_NONE
;
779 switch (Buffer
[i
+ 1])
782 DbgPrint((DPRINT_HWDETECT
,
783 "Microsoft Mouse with 3-buttons detected\n"));
784 return MOUSE_TYPE_LOGITECH
;
787 DbgPrint((DPRINT_HWDETECT
,
788 "Microsoft Wheel Mouse detected\n"));
789 return MOUSE_TYPE_WHEELZ
;
793 DbgPrint((DPRINT_HWDETECT
,
794 "Microsoft Mouse with 2-buttons detected\n"));
795 return MOUSE_TYPE_MICROSOFT
;
800 return MOUSE_TYPE_NONE
;
805 GetMousePnpId(U32 Port
, char *Buffer
)
812 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09);
814 /* Wait 10 milliseconds for the mouse getting ready */
815 KeStallExecutionProcessor(200000);
817 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
819 KeStallExecutionProcessor(200000);
824 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
826 KeStallExecutionProcessor(1000);
834 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
835 if (c
== 0x08 || c
== 0x28)
845 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
847 KeStallExecutionProcessor(1000);
852 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
865 DetectSerialPointerPeripheral(HKEY ControllerKey
,
868 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
870 char Identifier
[256];
878 DbgPrint((DPRINT_HWDETECT
,
879 "DetectSerialPointerPeripheral()\n"));
883 InitializeSerialPort(Base
, 2);
884 MouseType
= DetectMicrosoftMouse(Base
);
886 if (MouseType
!= MOUSE_TYPE_NONE
)
888 Length
= GetMousePnpId(Base
, Buffer
);
889 DbgPrint((DPRINT_HWDETECT
,
890 "PnP ID length: %u\n",
895 /* Convert PnP sting to ASCII */
896 if (Buffer
[0] == 0x08)
898 for (i
= 0; i
< Length
; i
++)
903 DbgPrint((DPRINT_HWDETECT
,
904 "PnP ID string: %s\n",
907 /* Copy PnpId string */
908 memcpy(&Identifier
[0],
911 memcpy(&Identifier
[7],
915 /* Skip device serial number */
917 if (Buffer
[i
] == '\\')
919 for (j
= ++i
; i
< Length
; ++i
)
921 if (Buffer
[i
] == '\\')
929 if (Buffer
[i
] == '\\')
931 for (j
= ++i
; i
< Length
; ++i
)
933 if (Buffer
[i
] == '\\')
941 /* Skip compatible PnP Id */
942 if (Buffer
[i
] == '\\')
944 for (j
= ++i
; i
< Length
; ++i
)
946 if (Buffer
[i
] == '\\')
949 if (Buffer
[j
] == '*')
955 /* Get product description */
956 if (Buffer
[i
] == '\\')
958 for (j
= ++i
; i
< Length
; ++i
)
960 if (Buffer
[i
] == ';')
967 memcpy(&Identifier
[10],
970 Identifier
[10 + (i
-j
)] = 0;
974 DbgPrint((DPRINT_HWDETECT
,
975 "Identifier string: %s\n",
979 if (Length
== 0 || strlen(Identifier
) < 11)
983 case MOUSE_TYPE_LOGITECH
:
985 "LOGITECH SERIAL MOUSE");
988 case MOUSE_TYPE_WHEELZ
:
990 "MICROSOFT SERIAL MOUSE WITH WHEEL");
993 case MOUSE_TYPE_MICROSOFT
:
996 "MICROSOFT SERIAL MOUSE");
1001 /* Create 'PointerPeripheral' key */
1002 Error
= RegCreateKey(ControllerKey
,
1003 "PointerPeripheral\\0",
1005 if (Error
!= ERROR_SUCCESS
)
1007 DbgPrint((DPRINT_HWDETECT
,
1008 "Failed to create peripheral key\n"));
1011 DbgPrint((DPRINT_HWDETECT
,
1012 "Created key: PointerPeripheral\\0\n"));
1014 /* Set 'ComponentInformation' value */
1015 SetComponentInformation(PeripheralKey
,
1020 /* Set 'Configuration Data' value */
1021 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1022 FullResourceDescriptor
.InterfaceType
= Isa
;
1023 FullResourceDescriptor
.BusNumber
= 0;
1024 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1026 Error
= RegSetValue(PeripheralKey
,
1027 "Configuration Data",
1028 REG_FULL_RESOURCE_DESCRIPTOR
,
1029 (PU8
)&FullResourceDescriptor
,
1030 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1031 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1032 if (Error
!= ERROR_SUCCESS
)
1034 DbgPrint((DPRINT_HWDETECT
,
1035 "RegSetValue(Configuration Data) failed (Error %u)\n",
1039 /* Set 'Identifier' value */
1040 Error
= RegSetValue(PeripheralKey
,
1044 strlen(Identifier
) + 1);
1045 if (Error
!= ERROR_SUCCESS
)
1047 DbgPrint((DPRINT_HWDETECT
,
1048 "RegSetValue() failed (Error %u)\n",
1056 DetectSerialPorts(HKEY BusKey
)
1058 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1059 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1060 PCM_SERIAL_DEVICE_DATA SerialDeviceData
;
1061 U32 Base
[4] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
1062 U32 Irq
[4] = {4, 3, 4, 3};
1064 U32 ControllerNumber
= 0;
1070 DbgPrint((DPRINT_HWDETECT
, "DetectSerialPorts()\n"));
1072 for (i
= 0; i
< 4; i
++)
1074 WRITE_PORT_UCHAR ((PUCHAR
)(Base
[i
] + 4), 0x10);
1075 if (!(READ_PORT_UCHAR((PUCHAR
)Base
[i
] + 6) & 0xf0))
1077 DbgPrint((DPRINT_HWDETECT
,
1078 "Found COM%u port at 0x%x\n",
1082 /* Create controller key */
1084 "SerialController\\%u",
1087 Error
= RegCreateKey(BusKey
,
1090 if (Error
!= ERROR_SUCCESS
)
1092 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1095 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
1097 /* Set 'ComponentInformation' value */
1098 SetComponentInformation(ControllerKey
,
1103 /* Build full device descriptor */
1104 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1105 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
1106 sizeof(CM_SERIAL_DEVICE_DATA
);
1107 FullResourceDescriptor
= MmAllocateMemory(Size
);
1108 if (FullResourceDescriptor
== NULL
)
1110 DbgPrint((DPRINT_HWDETECT
,
1111 "Failed to allocate resource descriptor\n"));
1114 memset(FullResourceDescriptor
, 0, Size
);
1116 /* Initialize resource descriptor */
1117 FullResourceDescriptor
->InterfaceType
= Isa
;
1118 FullResourceDescriptor
->BusNumber
= 0;
1119 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
1122 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1123 PartialDescriptor
->Type
= CmResourceTypePort
;
1124 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1125 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1126 PartialDescriptor
->u
.Port
.Start
= (U64
)Base
[i
];
1127 PartialDescriptor
->u
.Port
.Length
= 7;
1130 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
1131 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1132 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1133 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1134 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1135 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
[i
];
1136 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1138 /* Set serial data (device specific) */
1139 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
1140 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1141 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1142 PartialDescriptor
->Flags
= 0;
1143 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_SERIAL_DEVICE_DATA
);
1146 (PCM_SERIAL_DEVICE_DATA
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[3];
1147 SerialDeviceData
->BaudClock
= 1843200; /* UART Clock frequency (Hertz) */
1149 /* Set 'Configuration Data' value */
1150 Error
= RegSetValue(ControllerKey
,
1151 "Configuration Data",
1152 REG_FULL_RESOURCE_DESCRIPTOR
,
1153 (PU8
) FullResourceDescriptor
,
1155 MmFreeMemory(FullResourceDescriptor
);
1156 if (Error
!= ERROR_SUCCESS
)
1158 DbgPrint((DPRINT_HWDETECT
,
1159 "RegSetValue(Configuration Data) failed (Error %u)\n",
1163 /* Set 'Identifier' value */
1167 Error
= RegSetValue(BusKey
,
1172 if (Error
!= ERROR_SUCCESS
)
1174 DbgPrint((DPRINT_HWDETECT
,
1175 "RegSetValue() failed (Error %u)\n",
1179 DbgPrint((DPRINT_HWDETECT
,
1180 "Created value: Identifier %s\n",
1183 /* Detect serial mouse */
1184 DetectSerialPointerPeripheral(ControllerKey
, Base
[i
]);
1193 PS2ControllerWait(VOID
)
1198 for (Timeout
= 0; Timeout
< CONTROLLER_TIMEOUT
; Timeout
++)
1200 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1201 if ((Status
& CONTROLLER_STATUS_INPUT_BUFFER_FULL
) == 0)
1204 /* Sleep for one millisecond */
1205 KeStallExecutionProcessor(1000);
1211 DetectPS2AuxPort(VOID
)
1217 /* Put the value 0x5A in the output buffer using the
1218 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1219 * Poll the Status Register for a while to see if the value really turns up
1220 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1221 * to 1 in the Status Register, we assume this controller has an
1222 * Auxiliary Port (a.k.a. Mouse Port).
1224 PS2ControllerWait();
1225 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1226 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER
);
1227 PS2ControllerWait();
1229 /* 0x5A is a random dummy value */
1230 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1233 for (Loops
= 0; Loops
< 10; Loops
++)
1235 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1237 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1239 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1240 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) != 0)
1247 KeStallExecutionProcessor(10000);
1255 DetectPS2AuxDevice(VOID
)
1260 PS2ControllerWait();
1261 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1262 CONTROLLER_COMMAND_WRITE_MOUSE
);
1263 PS2ControllerWait();
1265 /* Identify device */
1266 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1269 KeStallExecutionProcessor(10000);
1271 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1272 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1277 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1278 if (Scancode
!= 0xFA)
1281 KeStallExecutionProcessor(10000);
1283 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1284 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1289 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1290 if (Scancode
!= 0x00)
1298 DetectPS2Mouse(HKEY BusKey
)
1300 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1305 if (DetectPS2AuxPort())
1307 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 port\n"));
1309 /* Create controller key */
1310 Error
= RegCreateKey(BusKey
,
1311 "PointerController\\0",
1313 if (Error
!= ERROR_SUCCESS
)
1315 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1318 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerController\\0\n"));
1320 /* Set 'ComponentInformation' value */
1321 SetComponentInformation(ControllerKey
,
1326 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1328 /* Initialize resource descriptor */
1329 FullResourceDescriptor
.InterfaceType
= Isa
;
1330 FullResourceDescriptor
.BusNumber
= 0;
1331 FullResourceDescriptor
.PartialResourceList
.Count
= 1;
1334 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Type
= CmResourceTypeInterrupt
;
1335 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].ShareDisposition
= CmResourceShareUndetermined
;
1336 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1337 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Level
= 12;
1338 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Vector
= 12;
1339 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1341 /* Set 'Configuration Data' value */
1342 Error
= RegSetValue(ControllerKey
,
1343 "Configuration Data",
1344 REG_FULL_RESOURCE_DESCRIPTOR
,
1345 (PU8
)&FullResourceDescriptor
,
1346 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1347 if (Error
!= ERROR_SUCCESS
)
1349 DbgPrint((DPRINT_HWDETECT
,
1350 "RegSetValue(Configuration Data) failed (Error %u)\n",
1356 if (DetectPS2AuxDevice())
1358 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 mouse\n"));
1360 /* Create peripheral key */
1361 Error
= RegCreateKey(ControllerKey
,
1362 "PointerPeripheral\\0",
1364 if (Error
!= ERROR_SUCCESS
)
1366 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
1369 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerPeripheral\\0\n"));
1371 /* Set 'ComponentInformation' value */
1372 SetComponentInformation(PeripheralKey
,
1377 /* Initialize resource descriptor */
1378 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1379 FullResourceDescriptor
.InterfaceType
= Isa
;
1380 FullResourceDescriptor
.BusNumber
= 0;
1381 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1383 /* Set 'Configuration Data' value */
1384 Error
= RegSetValue(PeripheralKey
,
1385 "Configuration Data",
1386 REG_FULL_RESOURCE_DESCRIPTOR
,
1387 (PU8
)&FullResourceDescriptor
,
1388 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1389 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1390 if (Error
!= ERROR_SUCCESS
)
1392 DbgPrint((DPRINT_HWDETECT
,
1393 "RegSetValue(Configuration Data) failed (Error %u)\n",
1398 /* Set 'Identifier' value */
1399 Error
= RegSetValue(PeripheralKey
,
1402 (PU8
)"MICROSOFT PS2 MOUSE",
1404 if (Error
!= ERROR_SUCCESS
)
1406 DbgPrint((DPRINT_HWDETECT
,
1407 "RegSetValue() failed (Error %u)\n",
1417 DetectIsaBios(HKEY SystemKey
, U32
*BusNumber
)
1419 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1425 /* Create new bus key */
1427 "MultifunctionAdapter\\%u", *BusNumber
);
1428 Error
= RegCreateKey(SystemKey
,
1431 if (Error
!= ERROR_SUCCESS
)
1433 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
1437 /* Increment bus number */
1440 /* Set 'Identifier' value */
1441 Error
= RegSetValue(BusKey
,
1446 if (Error
!= ERROR_SUCCESS
)
1448 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
1452 /* Set 'Configuration Data' value */
1453 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1454 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1455 FullResourceDescriptor
= MmAllocateMemory(Size
);
1456 if (FullResourceDescriptor
== NULL
)
1458 DbgPrint((DPRINT_HWDETECT
,
1459 "Failed to allocate resource descriptor\n"));
1463 /* Initialize resource descriptor */
1464 memset(FullResourceDescriptor
, 0, Size
);
1465 FullResourceDescriptor
->InterfaceType
= Isa
;
1466 FullResourceDescriptor
->BusNumber
= 0;
1467 FullResourceDescriptor
->PartialResourceList
.Count
= 0;
1469 /* Set 'Configuration Data' value */
1470 Error
= RegSetValue(SystemKey
,
1471 "Configuration Data",
1472 REG_FULL_RESOURCE_DESCRIPTOR
,
1473 (PU8
) FullResourceDescriptor
,
1475 MmFreeMemory(FullResourceDescriptor
);
1476 if (Error
!= ERROR_SUCCESS
)
1478 DbgPrint((DPRINT_HWDETECT
,
1479 "RegSetValue(Configuration Data) failed (Error %u)\n",
1485 /* Detect ISA/BIOS devices */
1486 DetectBiosDisks(SystemKey
, BusKey
);
1489 DetectBiosFloppyDisks(SystemKey
, BusKey
);
1492 DetectSerialPorts(BusKey
);
1495 DetectBiosParallelPorts();
1499 DetectBiosKeyboard(BusKey
);
1502 DetectPS2Mouse(BusKey
);
1504 /* FIXME: Detect more ISA devices */
1509 DetectHardware(VOID
)
1515 DbgPrint((DPRINT_HWDETECT
, "DetectHardware()\n"));
1517 HalpCalibrateStallExecution ();
1519 /* Create the 'System' key */
1520 Error
= RegCreateKey(NULL
,
1521 "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
1523 if (Error
!= ERROR_SUCCESS
)
1525 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
1532 DetectCPUs(SystemKey
);
1536 DetectPciBios(&BusNumber
);
1537 DetectApmBios(&BusNumber
);
1539 DetectPnpBios(SystemKey
, &BusNumber
);
1540 DetectIsaBios(SystemKey
, &BusNumber
);
1542 DetectAcpiBios(&BusNumber
);
1546 DbgPrint((DPRINT_HWDETECT
, "DetectHardware() Done\n"));
1549 printf("*** System stopped ***\n");