[USB-BRINGUP-TRUNK]
[reactos.git] / drivers / input / kbdclass / setup.c
1 /*
2 * PROJECT: ReactOS Keyboard class driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/kbdclass/setup.c
5 * PURPOSE: Create a legacy PDO during ReactOS installation
6 * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
7 */
8
9 /* NOTE:
10 * All this file is a big hack and should be removed one day...
11 */
12
13 /* INCLUDES ******************************************************************/
14
15 #include "kbdclass.h"
16
17 /* GLOBALS *******************************************************************/
18
19 #define KEYBOARD_DATA_PORT 0x60
20 #define KEYBOARD_CONTROL_PORT 0x64
21 #define KEYBOARD_IRQ 1
22
23 /* FUNCTIONS *****************************************************************/
24
25 BOOLEAN
26 IsFirstStageSetup(
27 VOID)
28 {
29 UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup");
30 OBJECT_ATTRIBUTES ObjectAttributes;
31 HANDLE hSetupKey = (HANDLE)NULL;
32 NTSTATUS Status;
33 BOOLEAN ret = TRUE;
34
35 InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
36 Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes);
37
38 if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
39 ret = TRUE;
40 else
41 ret = FALSE;
42
43 if (hSetupKey != (HANDLE)NULL)
44 ZwClose(hSetupKey);
45 INFO_(CLASS_NAME, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO");
46 return ret;
47 }
48
49 VOID NTAPI
50 Send8042StartDevice(
51 IN PDRIVER_OBJECT DriverObject,
52 IN PDEVICE_OBJECT Pdo)
53 {
54 PCM_RESOURCE_LIST AllocatedResources = NULL;
55 PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL;
56 PDEVICE_OBJECT TopDeviceObject = NULL;
57 KEVENT Event;
58 IO_STATUS_BLOCK IoStatusBlock;
59 PIRP Irp;
60 PIO_STACK_LOCATION Stack;
61 ULONG ResourceListSize;
62 NTSTATUS Status;
63
64 TRACE_(CLASS_NAME, "SendStartDevice(%p)\n", Pdo);
65
66 /* Create default resource list */
67 ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
68 AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, CLASS_TAG);
69 if (!AllocatedResources)
70 {
71 WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
72 Status = STATUS_NO_MEMORY;
73 goto cleanup;
74 }
75 AllocatedResources->Count = 1;
76 AllocatedResources->List[0].PartialResourceList.Version = 1;
77 AllocatedResources->List[0].PartialResourceList.Revision = 1;
78 AllocatedResources->List[0].PartialResourceList.Count = 3;
79 /* Data port */
80 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort;
81 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive;
82 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */
83 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0;
84 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT;
85 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1;
86 /* Control port */
87 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort;
88 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive;
89 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */
90 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0;
91 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT;
92 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1;
93 /* Interrupt */
94 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt;
95 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive;
96 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
97 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = KEYBOARD_IRQ;
98 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = 0;
99 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1;
100
101 /* Create default resource list translated */
102 AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, CLASS_TAG);
103 if (!AllocatedResourcesTranslated)
104 {
105 WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n");
106 Status = STATUS_NO_MEMORY;
107 goto cleanup;
108 }
109 RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize);
110 AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector(
111 Internal, 0,
112 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
113 AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector,
114 (PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level,
115 &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity);
116
117 /* Send IRP_MN_START_DEVICE */
118 TopDeviceObject = IoGetAttachedDeviceReference(Pdo);
119 KeInitializeEvent(
120 &Event,
121 NotificationEvent,
122 FALSE);
123 Irp = IoBuildSynchronousFsdRequest(
124 IRP_MJ_PNP,
125 TopDeviceObject,
126 NULL,
127 0,
128 NULL,
129 &Event,
130 &IoStatusBlock);
131 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
132 Irp->IoStatus.Information = 0;
133 Stack = IoGetNextIrpStackLocation(Irp);
134 Stack->MinorFunction = IRP_MN_START_DEVICE;
135 Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources;
136 Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated;
137 Status = IoCallDriver(TopDeviceObject, Irp);
138 if (Status == STATUS_PENDING)
139 {
140 KeWaitForSingleObject(
141 &Event,
142 Executive,
143 KernelMode,
144 FALSE,
145 NULL);
146 Status = IoStatusBlock.Status;
147 }
148 if (!NT_SUCCESS(Status))
149 {
150 WARN_(CLASS_NAME, "IoCallDriver() failed with status 0x%08lx\n", Status);
151 goto cleanup;
152 }
153
154 cleanup:
155 if (TopDeviceObject)
156 ObDereferenceObject(TopDeviceObject);
157 if (AllocatedResources)
158 ExFreePoolWithTag(AllocatedResources, CLASS_TAG);
159 if (AllocatedResourcesTranslated)
160 ExFreePoolWithTag(AllocatedResourcesTranslated, CLASS_TAG);
161 }