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 } __attribute__((packed
)) CM_SERIAL_DEVICE_DATA
, *PCM_SERIAL_DEVICE_DATA
;
145 typedef struct _CM_FLOPPY_DEVICE_DATA
153 /* Version 2.0 data */
154 U8 StepRateHeadUnloadTime
;
159 U8 ReadWriteGapLength
;
160 U8 DataTransferLength
;
162 U8 FormatFillCharacter
;
165 U8 MaximumTrackValue
;
167 } __attribute__((packed
)) CM_FLOPPY_DEVICE_DATA
, *PCM_FLOPPY_DEVICE_DATA
;
170 static char Hex
[] = "0123456789ABCDEF";
171 static unsigned int delay_count
= 1;
174 /* FUNCTIONS ****************************************************************/
178 __KeStallExecutionProcessor(U32 Loops
)
180 register unsigned int i
;
181 for (i
= 0; i
< Loops
; i
++);
184 VOID
KeStallExecutionProcessor(U32 Microseconds
)
186 U64 LoopCount
= ((U64
)delay_count
* (U64
)Microseconds
) / 1000ULL;
187 __KeStallExecutionProcessor((U32
)LoopCount
);
196 WRITE_PORT_UCHAR((PU8
)0x43, 0x00);
197 Count
= READ_PORT_UCHAR((PU8
)0x40);
198 Count
|= READ_PORT_UCHAR((PU8
)0x40) << 8;
205 WaitFor8254Wraparound(VOID
)
211 CurCount
= Read8254Timer();
215 PrevCount
= CurCount
;
216 CurCount
= Read8254Timer();
217 Delta
= CurCount
- PrevCount
;
220 * This limit for delta seems arbitrary, but it isn't, it's
221 * slightly above the level of error a buggy Mercury/Neptune
222 * chipset timer can cause.
230 HalpCalibrateStallExecution(VOID
)
236 /* Initialise timer interrupt with MILLISECOND ms interval */
237 WRITE_PORT_UCHAR((PU8
)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
238 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
& 0xff); /* LSB */
239 WRITE_PORT_UCHAR((PU8
)0x40, LATCH
>> 8); /* MSB */
241 /* Stage 1: Coarse calibration */
243 WaitFor8254Wraparound();
248 delay_count
<<= 1; /* Next delay count to try */
250 WaitFor8254Wraparound();
252 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
254 CurCount
= Read8254Timer();
255 } while (CurCount
> LATCH
/ 2);
257 delay_count
>>= 1; /* Get bottom value for delay */
259 /* Stage 2: Fine calibration */
261 calib_bit
= delay_count
; /* Which bit are we going to test */
263 for(i
=0;i
<PRECISION
;i
++) {
264 calib_bit
>>= 1; /* Next bit to calibrate */
265 if(!calib_bit
) break; /* If we have done all bits, stop */
267 delay_count
|= calib_bit
; /* Set the bit in delay_count */
269 WaitFor8254Wraparound();
271 __KeStallExecutionProcessor(delay_count
); /* Do the delay */
273 CurCount
= Read8254Timer();
274 if (CurCount
<= LATCH
/ 2) /* If a tick has passed, turn the */
275 delay_count
&= ~calib_bit
; /* calibrated bit back off */
278 /* We're finished: Do the finishing touches */
279 delay_count
/= (MILLISEC
/ 2); /* Calculate delay_count for 1ms */
284 SetComponentInformation(HKEY ComponentKey
,
289 CM_COMPONENT_INFORMATION CompInfo
;
292 CompInfo
.Flags
= Flags
;
293 CompInfo
.Version
= 0;
295 CompInfo
.Affinity
= Affinity
;
297 /* Set 'Component Information' value */
298 Error
= RegSetValue(ComponentKey
,
299 "Component Information",
302 sizeof(CM_COMPONENT_INFORMATION
));
303 if (Error
!= ERROR_SUCCESS
)
305 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
311 DetectPnpBios(HKEY SystemKey
, U32
*BusNumber
)
313 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
314 PCM_PNP_BIOS_DEVICE_NODE DeviceNode
;
315 PCM_PNP_BIOS_INSTALLATION_CHECK InstData
;
329 InstData
= (PCM_PNP_BIOS_INSTALLATION_CHECK
)PnpBiosSupported();
330 if (InstData
== NULL
|| strncmp(InstData
->Signature
, "$PnP", 4))
332 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS not supported\n"));
335 DbgPrint((DPRINT_HWDETECT
, "Signature '%c%c%c%c'\n",
336 InstData
->Signature
[0], InstData
->Signature
[1],
337 InstData
->Signature
[2], InstData
->Signature
[3]));
340 x
= PnpBiosGetDeviceNodeCount(&NodeSize
, &NodeCount
);
341 if (x
!= 0 || NodeSize
== 0 || NodeCount
== 0)
343 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS failed to enumerate device nodes\n"));
346 DbgPrint((DPRINT_HWDETECT
, "PnP-BIOS supported\n"));
347 DbgPrint((DPRINT_HWDETECT
, "MaxNodeSize %u NodeCount %u\n", NodeSize
, NodeCount
));
348 DbgPrint((DPRINT_HWDETECT
, "Estimated buffer size %u\n", NodeSize
* NodeCount
));
350 /* Create new bus key */
352 "MultifunctionAdapter\\%u", *BusNumber
);
353 Error
= RegCreateKey(SystemKey
,
356 if (Error
!= ERROR_SUCCESS
)
358 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
362 /* Increment bus number */
365 /* Set 'Identifier' value */
366 Error
= RegSetValue(BusKey
,
371 if (Error
!= ERROR_SUCCESS
)
373 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
377 /* Set 'Configuration Data' value */
378 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + (NodeSize
* NodeCount
);
379 FullResourceDescriptor
= MmAllocateMemory(Size
);
380 if (FullResourceDescriptor
== NULL
)
382 DbgPrint((DPRINT_HWDETECT
,
383 "Failed to allocate resource descriptor\n"));
386 memset(FullResourceDescriptor
, 0, Size
);
388 /* Initialize resource descriptor */
389 FullResourceDescriptor
->InterfaceType
= Internal
;
390 FullResourceDescriptor
->BusNumber
= 0;
391 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
392 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
393 CmResourceTypeDeviceSpecific
;
394 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].ShareDisposition
=
395 CmResourceShareUndetermined
;
396 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
398 Ptr
= (char *)(((PVOID
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0]) +
399 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
401 /* Set instalation check data */
402 memcpy (Ptr
, InstData
, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
));
403 Ptr
+= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
405 /* Copy device nodes */
407 PnpBufferSize
= sizeof(CM_PNP_BIOS_INSTALLATION_CHECK
);
408 for (i
= 0; i
< 0xFF; i
++)
412 x
= PnpBiosGetDeviceNode(&NodeNumber
, (PVOID
)DISKREADBUFFER
);
415 DeviceNode
= (PCM_PNP_BIOS_DEVICE_NODE
)DISKREADBUFFER
;
417 DbgPrint((DPRINT_HWDETECT
,
418 "Node: %u Size %u (0x%x)\n",
422 // printf("Node: %u Size %u (0x%x)\n",
425 // DeviceNode->Size);
431 Ptr
+= DeviceNode
->Size
;
432 PnpBufferSize
+= DeviceNode
->Size
;
435 if (FoundNodeCount
>= NodeCount
)
440 /* Set real data size */
441 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
443 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + PnpBufferSize
;
445 DbgPrint((DPRINT_HWDETECT
, "Real buffer size: %u\n", PnpBufferSize
));
446 DbgPrint((DPRINT_HWDETECT
, "Resource size: %u\n", Size
));
448 /* Set 'Configuration Data' value */
449 Error
= RegSetValue(BusKey
,
450 "Configuration Data",
451 REG_FULL_RESOURCE_DESCRIPTOR
,
452 (PU8
) FullResourceDescriptor
,
454 MmFreeMemory(FullResourceDescriptor
);
455 if (Error
!= ERROR_SUCCESS
)
457 DbgPrint((DPRINT_HWDETECT
,
458 "RegSetValue(Configuration Data) failed (Error %u)\n",
466 SetHarddiskConfigurationData(HKEY DiskKey
,
469 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
470 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
471 EXTENDED_GEOMETRY ExtGeometry
;
476 /* Set 'Configuration Data' value */
477 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
478 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
479 FullResourceDescriptor
= MmAllocateMemory(Size
);
480 if (FullResourceDescriptor
== NULL
)
482 DbgPrint((DPRINT_HWDETECT
,
483 "Failed to allocate a full resource descriptor\n"));
487 memset(FullResourceDescriptor
, 0, Size
);
488 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
489 FullResourceDescriptor
->BusNumber
= 0;
490 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
491 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
492 CmResourceTypeDeviceSpecific
;
493 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
494 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
495 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
496 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
);
498 /* Get pointer to geometry data */
499 DiskGeometry
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
501 /* Get the disk geometry */
502 ExtGeometry
.Size
= sizeof(EXTENDED_GEOMETRY
);
503 if (DiskGetExtendedDriveParameters(DriveNumber
, &ExtGeometry
, ExtGeometry
.Size
))
505 DiskGeometry
->BytesPerSector
= ExtGeometry
.BytesPerSector
;
506 DiskGeometry
->NumberOfCylinders
= ExtGeometry
.Cylinders
;
507 DiskGeometry
->SectorsPerTrack
= ExtGeometry
.SectorsPerTrack
;
508 DiskGeometry
->NumberOfHeads
= ExtGeometry
.Heads
;
510 else if(DiskGetDriveParameters(DriveNumber
, &Geometry
))
512 DiskGeometry
->BytesPerSector
= Geometry
.BytesPerSector
;
513 DiskGeometry
->NumberOfCylinders
= Geometry
.Cylinders
;
514 DiskGeometry
->SectorsPerTrack
= Geometry
.Sectors
;
515 DiskGeometry
->NumberOfHeads
= Geometry
.Heads
;
519 DbgPrint((DPRINT_HWDETECT
, "Reading disk geometry failed\n"));
520 MmFreeMemory(FullResourceDescriptor
);
523 DbgPrint((DPRINT_HWDETECT
,
524 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
526 DiskGeometry
->NumberOfCylinders
,
527 DiskGeometry
->NumberOfHeads
,
528 DiskGeometry
->SectorsPerTrack
,
529 DiskGeometry
->BytesPerSector
));
531 Error
= RegSetValue(DiskKey
,
532 "Configuration Data",
533 REG_FULL_RESOURCE_DESCRIPTOR
,
534 (PU8
) FullResourceDescriptor
,
536 MmFreeMemory(FullResourceDescriptor
);
537 if (Error
!= ERROR_SUCCESS
)
539 DbgPrint((DPRINT_HWDETECT
,
540 "RegSetValue(Configuration Data) failed (Error %u)\n",
547 SetHarddiskIdentifier(HKEY DiskKey
,
550 PMASTER_BOOT_RECORD Mbr
;
559 if (!DiskReadLogicalSectors(DriveNumber
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
561 DbgPrint((DPRINT_HWDETECT
, "Reading MBR failed\n"));
565 Buffer
= (U32
*)DISKREADBUFFER
;
566 Mbr
= (PMASTER_BOOT_RECORD
)DISKREADBUFFER
;
568 Signature
= Mbr
->Signature
;
569 DbgPrint((DPRINT_HWDETECT
, "Signature: %x\n", Signature
));
571 /* Calculate the MBR checksum */
573 for (i
= 0; i
< 128; i
++)
575 Checksum
+= Buffer
[i
];
577 Checksum
= ~Checksum
+ 1;
578 DbgPrint((DPRINT_HWDETECT
, "Checksum: %x\n", Checksum
));
580 /* Convert checksum and signature to identifier string */
581 Identifier
[0] = Hex
[(Checksum
>> 28) & 0x0F];
582 Identifier
[1] = Hex
[(Checksum
>> 24) & 0x0F];
583 Identifier
[2] = Hex
[(Checksum
>> 20) & 0x0F];
584 Identifier
[3] = Hex
[(Checksum
>> 16) & 0x0F];
585 Identifier
[4] = Hex
[(Checksum
>> 12) & 0x0F];
586 Identifier
[5] = Hex
[(Checksum
>> 8) & 0x0F];
587 Identifier
[6] = Hex
[(Checksum
>> 4) & 0x0F];
588 Identifier
[7] = Hex
[Checksum
& 0x0F];
590 Identifier
[9] = Hex
[(Signature
>> 28) & 0x0F];
591 Identifier
[10] = Hex
[(Signature
>> 24) & 0x0F];
592 Identifier
[11] = Hex
[(Signature
>> 20) & 0x0F];
593 Identifier
[12] = Hex
[(Signature
>> 16) & 0x0F];
594 Identifier
[13] = Hex
[(Signature
>> 12) & 0x0F];
595 Identifier
[14] = Hex
[(Signature
>> 8) & 0x0F];
596 Identifier
[15] = Hex
[(Signature
>> 4) & 0x0F];
597 Identifier
[16] = Hex
[Signature
& 0x0F];
598 Identifier
[17] = '-';
599 Identifier
[18] = 'A';
601 DbgPrint((DPRINT_HWDETECT
, "Identifier: %xsn", Identifier
));
604 Error
= RegSetValue(DiskKey
,
609 if (Error
!= ERROR_SUCCESS
)
611 DbgPrint((DPRINT_HWDETECT
,
612 "RegSetValue(Identifier) failed (Error %u)\n",
619 DetectBiosDisks(HKEY SystemKey
,
622 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
623 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
632 /* Count the number of visible drives */
633 DiskReportError(FALSE
);
635 while (DiskReadLogicalSectors(0x80 + DiskCount
, 0ULL, 1, (PVOID
)DISKREADBUFFER
))
639 DiskReportError(TRUE
);
640 DbgPrint((DPRINT_HWDETECT
, "BIOS reports %d harddisk%s\n",
641 (int)DiskCount
, (DiskCount
== 1) ? "": "s"));
643 /* Allocate resource descriptor */
644 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
645 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
646 FullResourceDescriptor
= MmAllocateMemory(Size
);
647 if (FullResourceDescriptor
== NULL
)
649 DbgPrint((DPRINT_HWDETECT
,
650 "Failed to allocate resource descriptor\n"));
654 /* Initialize resource descriptor */
655 memset(FullResourceDescriptor
, 0, Size
);
656 FullResourceDescriptor
->InterfaceType
= InterfaceTypeUndefined
;
657 FullResourceDescriptor
->BusNumber
= -1;
658 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
659 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
=
660 CmResourceTypeDeviceSpecific
;
661 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
662 // FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
663 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
=
664 sizeof(CM_INT13_DRIVE_PARAMETER
) * DiskCount
;
666 /* Get harddisk Int13 geometry data */
667 Int13Drives
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
668 for (i
= 0; i
< DiskCount
; i
++)
670 if (DiskGetDriveParameters(0x80 + i
, &Geometry
))
672 Int13Drives
[i
].DriveSelect
= 0x80 + i
;
673 Int13Drives
[i
].MaxCylinders
= Geometry
.Cylinders
- 1;
674 Int13Drives
[i
].SectorsPerTrack
= Geometry
.Sectors
;
675 Int13Drives
[i
].MaxHeads
= Geometry
.Heads
- 1;
676 Int13Drives
[i
].NumberDrives
= DiskCount
;
678 DbgPrint((DPRINT_HWDETECT
,
679 "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
681 Geometry
.Cylinders
- 1,
684 Geometry
.BytesPerSector
));
688 /* Set 'Configuration Data' value */
689 Error
= RegSetValue(SystemKey
,
690 "Configuration Data",
691 REG_FULL_RESOURCE_DESCRIPTOR
,
692 (PU8
) FullResourceDescriptor
,
694 MmFreeMemory(FullResourceDescriptor
);
695 if (Error
!= ERROR_SUCCESS
)
697 DbgPrint((DPRINT_HWDETECT
,
698 "RegSetValue(Configuration Data) failed (Error %u)\n",
703 /* Create and fill subkey for each harddisk */
704 for (i
= 0; i
< DiskCount
; i
++)
706 /* Create disk key */
708 "DiskController\\0\\DiskPeripheral\\%u",
711 Error
= RegCreateKey(BusKey
,
714 if (Error
!= ERROR_SUCCESS
)
716 DbgPrint((DPRINT_HWDETECT
, "Failed to create drive key\n"));
719 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
721 /* Set disk values */
722 SetHarddiskConfigurationData(DiskKey
, 0x80 + i
);
723 SetHarddiskIdentifier(DiskKey
, 0x80 + i
);
733 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
734 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
736 return ((Data
& 0xF0) ? 1 : 0) + ((Data
& 0x0F) ? 1 : 0);
741 GetFloppyType(U8 DriveNumber
)
745 WRITE_PORT_UCHAR((PUCHAR
)0x70, 0x10);
746 Data
= READ_PORT_UCHAR((PUCHAR
)0x71);
748 if (DriveNumber
== 0)
750 else if (DriveNumber
== 1)
760 PU16 SegPtr
= (PU16
)0x7A;
761 PU16 OfsPtr
= (PU16
)0x78;
763 return (PVOID
)(((U32
)(*SegPtr
)) << 4) + (U32
)(*OfsPtr
);
768 DetectBiosFloppyPeripheral(HKEY ControllerKey
)
770 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
771 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
772 PCM_FLOPPY_DEVICE_DATA FloppyData
;
780 U32 MaxDensity
[6] = {0, 360, 1200, 720, 1440, 2880};
783 for (FloppyNumber
= 0; FloppyNumber
< 2; FloppyNumber
++)
785 FloppyType
= GetFloppyType(FloppyNumber
);
787 if ((FloppyType
> 5) || (FloppyType
== 0))
790 DiskResetController(FloppyNumber
);
792 Ptr
= GetInt1eTable();
794 sprintf(KeyName
, "FloppyDiskPeripheral\\%u", FloppyNumber
);
796 Error
= RegCreateKey(ControllerKey
,
797 "FloppyDiskPeripheral\\0",
799 if (Error
!= ERROR_SUCCESS
)
801 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
805 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", KeyName
));
807 /* Set 'ComponentInformation' value */
808 SetComponentInformation(PeripheralKey
,
813 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
814 sizeof(CM_FLOPPY_DEVICE_DATA
);
815 FullResourceDescriptor
= MmAllocateMemory(Size
);
816 if (FullResourceDescriptor
== NULL
)
818 DbgPrint((DPRINT_HWDETECT
,
819 "Failed to allocate resource descriptor\n"));
823 memset(FullResourceDescriptor
, 0, Size
);
824 FullResourceDescriptor
->InterfaceType
= Isa
;
825 FullResourceDescriptor
->BusNumber
= 0;
826 FullResourceDescriptor
->PartialResourceList
.Count
= 1;
828 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
829 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
830 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
831 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_FLOPPY_DEVICE_DATA
);
833 FloppyData
= ((PVOID
)FullResourceDescriptor
) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR
);
834 FloppyData
->Version
= 2;
835 FloppyData
->Revision
= 0;
836 FloppyData
->MaxDensity
= MaxDensity
[FloppyType
];
837 FloppyData
->MountDensity
= 0;
838 RtlCopyMemory(&FloppyData
->StepRateHeadUnloadTime
,
841 FloppyData
->MaximumTrackValue
= (FloppyType
== 1) ? 39 : 79;
842 FloppyData
->DataTransferRate
= 0;
844 /* Set 'Configuration Data' value */
845 Error
= RegSetValue(PeripheralKey
,
846 "Configuration Data",
847 REG_FULL_RESOURCE_DESCRIPTOR
,
848 (PU8
) FullResourceDescriptor
,
850 MmFreeMemory(FullResourceDescriptor
);
851 if (Error
!= ERROR_SUCCESS
)
853 DbgPrint((DPRINT_HWDETECT
,
854 "RegSetValue(Configuration Data) failed (Error %u)\n",
859 /* Set 'Identifier' value */
860 sprintf(Identifier
, "FLOPPY%u", FloppyNumber
+ 1);
861 Error
= RegSetValue(PeripheralKey
,
865 strlen(Identifier
) + 1);
866 if (Error
!= ERROR_SUCCESS
)
868 DbgPrint((DPRINT_HWDETECT
,
869 "RegSetValue() failed (Error %u)\n",
877 DetectBiosFloppyController(HKEY SystemKey
,
880 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
881 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
887 FloppyCount
= GetFloppyCount();
888 /* printf ("Floppy count: %u\n", FloppyCount);*/
890 if (FloppyCount
== 0)
893 Error
= RegCreateKey(BusKey
,
896 if (Error
!= ERROR_SUCCESS
)
898 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
902 DbgPrint((DPRINT_HWDETECT
, "Created key: DiskController\\0\n"));
904 /* Set 'ComponentInformation' value */
905 SetComponentInformation(ControllerKey
,
910 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
911 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
912 FullResourceDescriptor
= MmAllocateMemory(Size
);
913 if (FullResourceDescriptor
== NULL
)
915 DbgPrint((DPRINT_HWDETECT
,
916 "Failed to allocate resource descriptor\n"));
919 memset(FullResourceDescriptor
, 0, Size
);
921 /* Initialize resource descriptor */
922 FullResourceDescriptor
->InterfaceType
= Isa
;
923 FullResourceDescriptor
->BusNumber
= 0;
924 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
927 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
928 PartialDescriptor
->Type
= CmResourceTypePort
;
929 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
930 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
931 PartialDescriptor
->u
.Port
.Start
= (U64
)0x03F0;
932 PartialDescriptor
->u
.Port
.Length
= 8;
935 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
936 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
937 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
938 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
939 PartialDescriptor
->u
.Interrupt
.Level
= 6;
940 PartialDescriptor
->u
.Interrupt
.Vector
= 6;
941 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
943 /* Set DMA channel */
944 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
945 PartialDescriptor
->Type
= CmResourceTypeDma
;
946 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
947 PartialDescriptor
->Flags
= 0;
948 PartialDescriptor
->u
.Dma
.Channel
= 2;
949 PartialDescriptor
->u
.Dma
.Port
= 0;
951 /* Set 'Configuration Data' value */
952 Error
= RegSetValue(ControllerKey
,
953 "Configuration Data",
954 REG_FULL_RESOURCE_DESCRIPTOR
,
955 (PU8
) FullResourceDescriptor
,
957 MmFreeMemory(FullResourceDescriptor
);
958 if (Error
!= ERROR_SUCCESS
)
960 DbgPrint((DPRINT_HWDETECT
,
961 "RegSetValue(Configuration Data) failed (Error %u)\n",
966 DetectBiosFloppyPeripheral(ControllerKey
);
971 InitializeSerialPort(U32 Port
,
974 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, 0x80); /* set DLAB on */
975 WRITE_PORT_UCHAR((PUCHAR
)Port
, 0x60); /* speed LO byte */
976 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* speed HI byte */
977 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 3, LineControl
);
978 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 1, 0); /* set comm and DLAB to 0 */
979 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09); /* DR int enable */
980 READ_PORT_UCHAR((PUCHAR
)Port
+ 5); /* clear error bits */
985 DetectSerialMouse(U32 Port
)
992 /* Shutdown mouse or something like that */
993 LineControl
= READ_PORT_UCHAR((PUCHAR
)Port
+ 4);
994 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, (LineControl
& ~0x02) | 0x01);
995 KeStallExecutionProcessor(100000);
998 while (READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 0x01)
999 READ_PORT_UCHAR((PUCHAR
)Port
);
1002 * Send modem control with 'Data Terminal Ready', 'Request To Send' and
1003 * 'Output Line 2' message. This enables mouse to identify.
1005 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
1007 /* Wait 10 milliseconds for the mouse getting ready */
1008 KeStallExecutionProcessor(10000);
1010 /* Read first four bytes, which contains Microsoft Mouse signs */
1011 for (i
= 0; i
< 4; i
++)
1013 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1015 KeStallExecutionProcessor(1000);
1018 return MOUSE_TYPE_NONE
;
1020 Buffer
[i
] = READ_PORT_UCHAR((PUCHAR
)Port
);
1023 DbgPrint((DPRINT_HWDETECT
,
1024 "Mouse data: %x %x %x %x\n",
1025 Buffer
[0],Buffer
[1],Buffer
[2],Buffer
[3]));
1027 /* Check that four bytes for signs */
1028 for (i
= 0; i
< 4; ++i
)
1030 if (Buffer
[i
] == 'B')
1032 /* Sign for Microsoft Ballpoint */
1033 // DbgPrint("Microsoft Ballpoint device detected\n");
1034 // DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
1035 return MOUSE_TYPE_NONE
;
1037 else if (Buffer
[i
] == 'M')
1039 /* Sign for Microsoft Mouse protocol followed by button specifier */
1042 /* Overflow Error */
1043 return MOUSE_TYPE_NONE
;
1046 switch (Buffer
[i
+ 1])
1049 DbgPrint((DPRINT_HWDETECT
,
1050 "Microsoft Mouse with 3-buttons detected\n"));
1051 return MOUSE_TYPE_LOGITECH
;
1054 DbgPrint((DPRINT_HWDETECT
,
1055 "Microsoft Wheel Mouse detected\n"));
1056 return MOUSE_TYPE_WHEELZ
;
1060 DbgPrint((DPRINT_HWDETECT
,
1061 "Microsoft Mouse with 2-buttons detected\n"));
1062 return MOUSE_TYPE_MICROSOFT
;
1067 return MOUSE_TYPE_NONE
;
1072 GetSerialMousePnpId(U32 Port
, char *Buffer
)
1079 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x09);
1081 /* Wait 10 milliseconds for the mouse getting ready */
1082 KeStallExecutionProcessor(10000);
1084 WRITE_PORT_UCHAR((PUCHAR
)Port
+ 4, 0x0b);
1086 KeStallExecutionProcessor(10000);
1091 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1093 KeStallExecutionProcessor(1000);
1101 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
1102 if (c
== 0x08 || c
== 0x28)
1112 while (((READ_PORT_UCHAR((PUCHAR
)Port
+ 5) & 1) == 0) && (TimeOut
> 0))
1114 KeStallExecutionProcessor(1000);
1119 c
= READ_PORT_UCHAR((PUCHAR
)Port
);
1132 DetectSerialPointerPeripheral(HKEY ControllerKey
,
1135 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1137 char Identifier
[256];
1145 DbgPrint((DPRINT_HWDETECT
,
1146 "DetectSerialPointerPeripheral()\n"));
1150 InitializeSerialPort(Base
, 2);
1151 MouseType
= DetectSerialMouse(Base
);
1153 if (MouseType
!= MOUSE_TYPE_NONE
)
1155 Length
= GetSerialMousePnpId(Base
, Buffer
);
1156 DbgPrint((DPRINT_HWDETECT
,
1157 "PnP ID length: %u\n",
1162 /* Convert PnP sting to ASCII */
1163 if (Buffer
[0] == 0x08)
1165 for (i
= 0; i
< Length
; i
++)
1170 DbgPrint((DPRINT_HWDETECT
,
1171 "PnP ID string: %s\n",
1174 /* Copy PnpId string */
1175 memcpy(&Identifier
[0],
1178 memcpy(&Identifier
[7],
1182 /* Skip device serial number */
1184 if (Buffer
[i
] == '\\')
1186 for (j
= ++i
; i
< Length
; ++i
)
1188 if (Buffer
[i
] == '\\')
1195 /* Skip PnP class */
1196 if (Buffer
[i
] == '\\')
1198 for (j
= ++i
; i
< Length
; ++i
)
1200 if (Buffer
[i
] == '\\')
1208 /* Skip compatible PnP Id */
1209 if (Buffer
[i
] == '\\')
1211 for (j
= ++i
; i
< Length
; ++i
)
1213 if (Buffer
[i
] == '\\')
1216 if (Buffer
[j
] == '*')
1222 /* Get product description */
1223 if (Buffer
[i
] == '\\')
1225 for (j
= ++i
; i
< Length
; ++i
)
1227 if (Buffer
[i
] == ';')
1234 memcpy(&Identifier
[10],
1237 Identifier
[10 + (i
-j
)] = 0;
1241 DbgPrint((DPRINT_HWDETECT
,
1242 "Identifier string: %s\n",
1246 if (Length
== 0 || strlen(Identifier
) < 11)
1250 case MOUSE_TYPE_LOGITECH
:
1252 "LOGITECH SERIAL MOUSE");
1255 case MOUSE_TYPE_WHEELZ
:
1257 "MICROSOFT SERIAL MOUSE WITH WHEEL");
1260 case MOUSE_TYPE_MICROSOFT
:
1263 "MICROSOFT SERIAL MOUSE");
1268 /* Create 'PointerPeripheral' key */
1269 Error
= RegCreateKey(ControllerKey
,
1270 "PointerPeripheral\\0",
1272 if (Error
!= ERROR_SUCCESS
)
1274 DbgPrint((DPRINT_HWDETECT
,
1275 "Failed to create peripheral key\n"));
1278 DbgPrint((DPRINT_HWDETECT
,
1279 "Created key: PointerPeripheral\\0\n"));
1281 /* Set 'ComponentInformation' value */
1282 SetComponentInformation(PeripheralKey
,
1287 /* Set 'Configuration Data' value */
1288 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1289 FullResourceDescriptor
.InterfaceType
= Isa
;
1290 FullResourceDescriptor
.BusNumber
= 0;
1291 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1293 Error
= RegSetValue(PeripheralKey
,
1294 "Configuration Data",
1295 REG_FULL_RESOURCE_DESCRIPTOR
,
1296 (PU8
)&FullResourceDescriptor
,
1297 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1298 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1299 if (Error
!= ERROR_SUCCESS
)
1301 DbgPrint((DPRINT_HWDETECT
,
1302 "RegSetValue(Configuration Data) failed (Error %u)\n",
1306 /* Set 'Identifier' value */
1307 Error
= RegSetValue(PeripheralKey
,
1311 strlen(Identifier
) + 1);
1312 if (Error
!= ERROR_SUCCESS
)
1314 DbgPrint((DPRINT_HWDETECT
,
1315 "RegSetValue() failed (Error %u)\n",
1323 DetectSerialPorts(HKEY BusKey
)
1325 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1326 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor
;
1327 PCM_SERIAL_DEVICE_DATA SerialDeviceData
;
1328 U32 Base
[4] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
1329 U32 Irq
[4] = {4, 3, 4, 3};
1331 U32 ControllerNumber
= 0;
1337 DbgPrint((DPRINT_HWDETECT
, "DetectSerialPorts()\n"));
1339 for (i
= 0; i
< 4; i
++)
1341 WRITE_PORT_UCHAR ((PUCHAR
)(Base
[i
] + 4), 0x10);
1342 if (!(READ_PORT_UCHAR((PUCHAR
)Base
[i
] + 6) & 0xf0))
1344 DbgPrint((DPRINT_HWDETECT
,
1345 "Found COM%u port at 0x%x\n",
1349 /* Create controller key */
1351 "SerialController\\%u",
1354 Error
= RegCreateKey(BusKey
,
1357 if (Error
!= ERROR_SUCCESS
)
1359 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1362 DbgPrint((DPRINT_HWDETECT
, "Created key: %s\n", Buffer
));
1364 /* Set 'ComponentInformation' value */
1365 SetComponentInformation(ControllerKey
,
1370 /* Build full device descriptor */
1371 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) +
1372 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) +
1373 sizeof(CM_SERIAL_DEVICE_DATA
);
1374 FullResourceDescriptor
= MmAllocateMemory(Size
);
1375 if (FullResourceDescriptor
== NULL
)
1377 DbgPrint((DPRINT_HWDETECT
,
1378 "Failed to allocate resource descriptor\n"));
1381 memset(FullResourceDescriptor
, 0, Size
);
1383 /* Initialize resource descriptor */
1384 FullResourceDescriptor
->InterfaceType
= Isa
;
1385 FullResourceDescriptor
->BusNumber
= 0;
1386 FullResourceDescriptor
->PartialResourceList
.Count
= 3;
1389 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0];
1390 PartialDescriptor
->Type
= CmResourceTypePort
;
1391 PartialDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1392 PartialDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1393 PartialDescriptor
->u
.Port
.Start
= (U64
)Base
[i
];
1394 PartialDescriptor
->u
.Port
.Length
= 7;
1397 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[1];
1398 PartialDescriptor
->Type
= CmResourceTypeInterrupt
;
1399 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1400 PartialDescriptor
->Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1401 PartialDescriptor
->u
.Interrupt
.Level
= Irq
[i
];
1402 PartialDescriptor
->u
.Interrupt
.Vector
= Irq
[i
];
1403 PartialDescriptor
->u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1405 /* Set serial data (device specific) */
1406 PartialDescriptor
= &FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[2];
1407 PartialDescriptor
->Type
= CmResourceTypeDeviceSpecific
;
1408 PartialDescriptor
->ShareDisposition
= CmResourceShareUndetermined
;
1409 PartialDescriptor
->Flags
= 0;
1410 PartialDescriptor
->u
.DeviceSpecificData
.DataSize
= sizeof(CM_SERIAL_DEVICE_DATA
);
1413 (PCM_SERIAL_DEVICE_DATA
)&FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[3];
1414 SerialDeviceData
->BaudClock
= 1843200; /* UART Clock frequency (Hertz) */
1416 /* Set 'Configuration Data' value */
1417 Error
= RegSetValue(ControllerKey
,
1418 "Configuration Data",
1419 REG_FULL_RESOURCE_DESCRIPTOR
,
1420 (PU8
) FullResourceDescriptor
,
1422 MmFreeMemory(FullResourceDescriptor
);
1423 if (Error
!= ERROR_SUCCESS
)
1425 DbgPrint((DPRINT_HWDETECT
,
1426 "RegSetValue(Configuration Data) failed (Error %u)\n",
1430 /* Set 'Identifier' value */
1434 Error
= RegSetValue(ControllerKey
,
1439 if (Error
!= ERROR_SUCCESS
)
1441 DbgPrint((DPRINT_HWDETECT
,
1442 "RegSetValue() failed (Error %u)\n",
1446 DbgPrint((DPRINT_HWDETECT
,
1447 "Created value: Identifier %s\n",
1450 /* Detect serial mouse */
1451 DetectSerialPointerPeripheral(ControllerKey
, Base
[i
]);
1460 PS2ControllerWait(VOID
)
1465 for (Timeout
= 0; Timeout
< CONTROLLER_TIMEOUT
; Timeout
++)
1467 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1468 if ((Status
& CONTROLLER_STATUS_INPUT_BUFFER_FULL
) == 0)
1471 /* Sleep for one millisecond */
1472 KeStallExecutionProcessor(1000);
1478 DetectPS2AuxPort(VOID
)
1484 /* Put the value 0x5A in the output buffer using the
1485 * "WriteAuxiliary Device Output Buffer" command (0xD3).
1486 * Poll the Status Register for a while to see if the value really turns up
1487 * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
1488 * to 1 in the Status Register, we assume this controller has an
1489 * Auxiliary Port (a.k.a. Mouse Port).
1491 PS2ControllerWait();
1492 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1493 CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER
);
1494 PS2ControllerWait();
1496 /* 0x5A is a random dummy value */
1497 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1500 for (Loops
= 0; Loops
< 10; Loops
++)
1502 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1504 if ((Status
& CONTROLLER_STATUS_OUTPUT_BUFFER_FULL
) != 0)
1506 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1507 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) != 0)
1514 KeStallExecutionProcessor(10000);
1522 DetectPS2AuxDevice(VOID
)
1527 PS2ControllerWait();
1528 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_CONTROL
,
1529 CONTROLLER_COMMAND_WRITE_MOUSE
);
1530 PS2ControllerWait();
1532 /* Identify device */
1533 WRITE_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
,
1536 KeStallExecutionProcessor(10000);
1538 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1539 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1544 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1545 if (Scancode
!= 0xFA)
1548 KeStallExecutionProcessor(10000);
1550 Status
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_STATUS
);
1551 if ((Status
& CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL
) == 0)
1556 Scancode
= READ_PORT_UCHAR((PUCHAR
)CONTROLLER_REGISTER_DATA
);
1557 if (Scancode
!= 0x00)
1565 DetectPS2Mouse(HKEY BusKey
)
1567 CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1572 if (DetectPS2AuxPort())
1574 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 port\n"));
1576 /* Create controller key */
1577 Error
= RegCreateKey(BusKey
,
1578 "PointerController\\0",
1580 if (Error
!= ERROR_SUCCESS
)
1582 DbgPrint((DPRINT_HWDETECT
, "Failed to create controller key\n"));
1585 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerController\\0\n"));
1587 /* Set 'ComponentInformation' value */
1588 SetComponentInformation(ControllerKey
,
1593 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1595 /* Initialize resource descriptor */
1596 FullResourceDescriptor
.InterfaceType
= Isa
;
1597 FullResourceDescriptor
.BusNumber
= 0;
1598 FullResourceDescriptor
.PartialResourceList
.Count
= 1;
1601 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Type
= CmResourceTypeInterrupt
;
1602 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].ShareDisposition
= CmResourceShareUndetermined
;
1603 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].Flags
= CM_RESOURCE_INTERRUPT_LATCHED
;
1604 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Level
= 12;
1605 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Vector
= 12;
1606 FullResourceDescriptor
.PartialResourceList
.PartialDescriptors
[0].u
.Interrupt
.Affinity
= 0xFFFFFFFF;
1608 /* Set 'Configuration Data' value */
1609 Error
= RegSetValue(ControllerKey
,
1610 "Configuration Data",
1611 REG_FULL_RESOURCE_DESCRIPTOR
,
1612 (PU8
)&FullResourceDescriptor
,
1613 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1614 if (Error
!= ERROR_SUCCESS
)
1616 DbgPrint((DPRINT_HWDETECT
,
1617 "RegSetValue(Configuration Data) failed (Error %u)\n",
1623 if (DetectPS2AuxDevice())
1625 DbgPrint((DPRINT_HWDETECT
, "Detected PS2 mouse\n"));
1627 /* Create peripheral key */
1628 Error
= RegCreateKey(ControllerKey
,
1629 "PointerPeripheral\\0",
1631 if (Error
!= ERROR_SUCCESS
)
1633 DbgPrint((DPRINT_HWDETECT
, "Failed to create peripheral key\n"));
1636 DbgPrint((DPRINT_HWDETECT
, "Created key: PointerPeripheral\\0\n"));
1638 /* Set 'ComponentInformation' value */
1639 SetComponentInformation(PeripheralKey
,
1644 /* Initialize resource descriptor */
1645 memset(&FullResourceDescriptor
, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR
));
1646 FullResourceDescriptor
.InterfaceType
= Isa
;
1647 FullResourceDescriptor
.BusNumber
= 0;
1648 FullResourceDescriptor
.PartialResourceList
.Count
= 0;
1650 /* Set 'Configuration Data' value */
1651 Error
= RegSetValue(PeripheralKey
,
1652 "Configuration Data",
1653 REG_FULL_RESOURCE_DESCRIPTOR
,
1654 (PU8
)&FullResourceDescriptor
,
1655 sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1656 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
));
1657 if (Error
!= ERROR_SUCCESS
)
1659 DbgPrint((DPRINT_HWDETECT
,
1660 "RegSetValue(Configuration Data) failed (Error %u)\n",
1665 /* Set 'Identifier' value */
1666 Error
= RegSetValue(PeripheralKey
,
1669 (PU8
)"MICROSOFT PS2 MOUSE",
1671 if (Error
!= ERROR_SUCCESS
)
1673 DbgPrint((DPRINT_HWDETECT
,
1674 "RegSetValue() failed (Error %u)\n",
1684 DetectIsaBios(HKEY SystemKey
, U32
*BusNumber
)
1686 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
1692 /* Create new bus key */
1694 "MultifunctionAdapter\\%u", *BusNumber
);
1695 Error
= RegCreateKey(SystemKey
,
1698 if (Error
!= ERROR_SUCCESS
)
1700 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
1704 /* Increment bus number */
1707 /* Set 'Identifier' value */
1708 Error
= RegSetValue(BusKey
,
1713 if (Error
!= ERROR_SUCCESS
)
1715 DbgPrint((DPRINT_HWDETECT
, "RegSetValue() failed (Error %u)\n", (int)Error
));
1719 /* Set 'Configuration Data' value */
1720 Size
= sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) -
1721 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
);
1722 FullResourceDescriptor
= MmAllocateMemory(Size
);
1723 if (FullResourceDescriptor
== NULL
)
1725 DbgPrint((DPRINT_HWDETECT
,
1726 "Failed to allocate resource descriptor\n"));
1730 /* Initialize resource descriptor */
1731 memset(FullResourceDescriptor
, 0, Size
);
1732 FullResourceDescriptor
->InterfaceType
= Isa
;
1733 FullResourceDescriptor
->BusNumber
= 0;
1734 FullResourceDescriptor
->PartialResourceList
.Count
= 0;
1736 /* Set 'Configuration Data' value */
1737 Error
= RegSetValue(SystemKey
,
1738 "Configuration Data",
1739 REG_FULL_RESOURCE_DESCRIPTOR
,
1740 (PU8
) FullResourceDescriptor
,
1742 MmFreeMemory(FullResourceDescriptor
);
1743 if (Error
!= ERROR_SUCCESS
)
1745 DbgPrint((DPRINT_HWDETECT
,
1746 "RegSetValue(Configuration Data) failed (Error %u)\n",
1752 /* Detect ISA/BIOS devices */
1753 DetectBiosDisks(SystemKey
, BusKey
);
1755 DetectBiosFloppyController(SystemKey
, BusKey
);
1757 DetectSerialPorts(BusKey
);
1760 DetectBiosParallelPorts();
1764 DetectBiosKeyboard(BusKey
);
1767 DetectPS2Mouse(BusKey
);
1769 /* FIXME: Detect more ISA devices */
1774 DetectHardware(VOID
)
1780 DbgPrint((DPRINT_HWDETECT
, "DetectHardware()\n"));
1782 HalpCalibrateStallExecution ();
1784 /* Create the 'System' key */
1785 Error
= RegCreateKey(NULL
,
1786 "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
1788 if (Error
!= ERROR_SUCCESS
)
1790 DbgPrint((DPRINT_HWDETECT
, "RegCreateKey() failed (Error %u)\n", (int)Error
));
1797 DetectCPUs(SystemKey
);
1801 DetectPciBios(&BusNumber
);
1802 DetectApmBios(&BusNumber
);
1804 DetectPnpBios(SystemKey
, &BusNumber
);
1805 DetectIsaBios(SystemKey
, &BusNumber
);
1807 DetectAcpiBios(&BusNumber
);
1811 DbgPrint((DPRINT_HWDETECT
, "DetectHardware() Done\n"));
1814 printf("*** System stopped ***\n");