Disable USB keyboard and mouse support, as they conflict with i8042prt driver.
[reactos.git] / reactos / drivers / usb / miniport / common / main.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS USB miniport driver (Cromwell type)
4 * FILE: drivers/usb/miniport/common/main.c
5 * PURPOSE: Driver entry
6 *
7 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.com)
8 * Hervé Poussineau (hpoussin@reactos.org),
9 *
10 * Some parts of code are inspired (or even just copied) from
11 * ReactOS Videoport driver (drivers/video/videoprt)
12 */
13
14 #define NDEBUG
15 #include <debug.h>
16
17 #define INITGUID
18 #include "usbcommon.h"
19
20 // data for embedded drivers
21 CONNECT_DATA KbdClassInformation;
22 CONNECT_DATA MouseClassInformation;
23 PDEVICE_OBJECT KeyboardFdo = NULL;
24 PDEVICE_OBJECT MouseFdo = NULL;
25
26 static NTSTATUS
27 CreateRootHubPdo(
28 IN PDRIVER_OBJECT DriverObject,
29 IN PDEVICE_OBJECT Fdo,
30 OUT PDEVICE_OBJECT* pPdo)
31 {
32 PDEVICE_OBJECT Pdo;
33 PUSBMP_DEVICE_EXTENSION DeviceExtension;
34 NTSTATUS Status;
35
36 DPRINT("USBMP: CreateRootHubPdo()\n");
37
38 Status = IoCreateDevice(
39 DriverObject,
40 sizeof(USBMP_DEVICE_EXTENSION),
41 NULL, /* DeviceName */
42 FILE_DEVICE_BUS_EXTENDER,
43 FILE_DEVICE_SECURE_OPEN | FILE_AUTOGENERATED_DEVICE_NAME,
44 FALSE,
45 &Pdo);
46 if (!NT_SUCCESS(Status))
47 {
48 DPRINT("USBMP: IoCreateDevice() call failed with status 0x%08x\n", Status);
49 return Status;
50 }
51
52 Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
53 Pdo->Flags |= DO_POWER_PAGABLE;
54
55 // zerofill device extension
56 DeviceExtension = (PUSBMP_DEVICE_EXTENSION)Pdo->DeviceExtension;
57 RtlZeroMemory(DeviceExtension, sizeof(USBMP_DEVICE_EXTENSION));
58
59 DeviceExtension->IsFDO = FALSE;
60 DeviceExtension->FunctionalDeviceObject = Fdo;
61
62 Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
63
64 *pPdo = Pdo;
65 return STATUS_SUCCESS;
66 }
67
68 #if 0
69 static NTSTATUS
70 AddDevice_Keyboard(
71 IN PDRIVER_OBJECT DriverObject,
72 IN PDEVICE_OBJECT Pdo)
73 {
74 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
75 PDEVICE_OBJECT Fdo;
76 NTSTATUS Status;
77
78 Status = IoCreateDevice(DriverObject,
79 8, // debug
80 &DeviceName,
81 FILE_DEVICE_KEYBOARD,
82 FILE_DEVICE_SECURE_OPEN,
83 TRUE,
84 &Fdo);
85
86 if (!NT_SUCCESS(Status))
87 {
88 DPRINT1("USBMP: IoCreateDevice() for usb keyboard driver failed with status 0x%08lx\n", Status);
89 return Status;
90 }
91 KeyboardFdo = Fdo;
92 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
93 DPRINT("USBMP: Created keyboard Fdo: %p\n", Fdo);
94
95 return STATUS_SUCCESS;
96 }
97
98 static NTSTATUS
99 AddDevice_Mouse(
100 IN PDRIVER_OBJECT DriverObject,
101 IN PDEVICE_OBJECT Pdo)
102 {
103 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\PointerClass0");
104 PDEVICE_OBJECT Fdo;
105 NTSTATUS Status;
106
107 Status = IoCreateDevice(DriverObject,
108 8, // debug
109 &DeviceName,
110 FILE_DEVICE_MOUSE,
111 FILE_DEVICE_SECURE_OPEN,
112 TRUE,
113 &Fdo);
114
115 if (!NT_SUCCESS(Status))
116 {
117 DPRINT1("USBMP: IoCreateDevice() for usb mouse driver failed with status 0x%08lx\n", Status);
118 return Status;
119 }
120 MouseFdo = Fdo;
121 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
122 DPRINT("USBMP: Created mouse Fdo: %p\n", Fdo);
123
124 return STATUS_SUCCESS;
125 }
126 #endif
127
128 NTSTATUS STDCALL
129 AddDevice(
130 IN PDRIVER_OBJECT DriverObject,
131 IN PDEVICE_OBJECT pdo)
132 {
133 PDEVICE_OBJECT fdo;
134 NTSTATUS Status;
135 WCHAR DeviceBuffer[20];
136 WCHAR LinkDeviceBuffer[20];
137 UNICODE_STRING DeviceName;
138 UNICODE_STRING LinkDeviceName;
139 PUSBMP_DRIVER_EXTENSION DriverExtension;
140 PUSBMP_DEVICE_EXTENSION DeviceExtension;
141 ULONG DeviceNumber;
142
143 /* FIXME: actually, we prevent multiple USB controllers on a computer */
144 static BOOLEAN xbox_workaround = FALSE;
145
146 DPRINT("USBMP: AddDevice called\n");
147
148 if (xbox_workaround)
149 // Fail for any other host controller than the first
150 return STATUS_INSUFFICIENT_RESOURCES;
151 xbox_workaround = TRUE;
152
153 // Allocate driver extension now
154 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
155 if (DriverExtension == NULL)
156 {
157 Status = IoAllocateDriverObjectExtension(
158 DriverObject,
159 DriverObject,
160 sizeof(USBMP_DRIVER_EXTENSION),
161 (PVOID *)&DriverExtension);
162
163 if (!NT_SUCCESS(Status))
164 {
165 DPRINT("USBMP: Allocating DriverObjectExtension failed.\n");
166 return Status;
167 }
168 }
169
170 // Create a unicode device name
171 // DeviceNumber = 0; //TODO: Allocate new device number every time
172 swprintf(DeviceBuffer, L"\\Device\\USBFDO-%lu", DeviceNumber);
173 RtlInitUnicodeString(&DeviceName, DeviceBuffer);
174
175 Status = IoCreateDevice(DriverObject,
176 sizeof(USBMP_DEVICE_EXTENSION),
177 &DeviceName,
178 FILE_DEVICE_BUS_EXTENDER,
179 0,
180 FALSE,
181 &fdo);
182
183 if (!NT_SUCCESS(Status))
184 {
185 DPRINT("USBMP: IoCreateDevice call failed with status 0x%08lx\n", Status);
186 return Status;
187 }
188
189 // zerofill device extension
190 DeviceExtension = (PUSBMP_DEVICE_EXTENSION)fdo->DeviceExtension;
191 RtlZeroMemory(DeviceExtension, sizeof(USBMP_DEVICE_EXTENSION));
192
193 /* Create root hub Pdo */
194 Status = CreateRootHubPdo(DriverObject, fdo, &DeviceExtension->RootHubPdo);
195 if (!NT_SUCCESS(Status))
196 {
197 DPRINT("USBMP: CreateRootHubPdo() failed with status 0x%08lx\n", Status);
198 IoDeleteDevice(fdo);
199 return Status;
200 }
201
202 /* Register device interface for controller */
203 Status = IoRegisterDeviceInterface(
204 pdo,
205 &GUID_DEVINTERFACE_USB_HOST_CONTROLLER,
206 NULL,
207 &DeviceExtension->HcdInterfaceName);
208 if (!NT_SUCCESS(Status))
209 {
210 DPRINT("USBMP: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
211 IoDeleteDevice(DeviceExtension->RootHubPdo);
212 IoDeleteDevice(fdo);
213 return Status;
214 }
215
216 DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
217
218 // Initialize device extension
219 DeviceExtension->IsFDO = TRUE;
220 DeviceExtension->DeviceNumber = DeviceNumber;
221 DeviceExtension->PhysicalDeviceObject = pdo;
222 DeviceExtension->FunctionalDeviceObject = fdo;
223 DeviceExtension->DriverExtension = DriverExtension;
224
225 fdo->Flags &= ~DO_DEVICE_INITIALIZING;
226
227 /* FIXME: do a loop to find an available number */
228 swprintf(LinkDeviceBuffer, L"\\??\\HCD%lu", 0);
229
230 RtlInitUnicodeString(&LinkDeviceName, LinkDeviceBuffer);
231
232 Status = IoCreateSymbolicLink(&LinkDeviceName, &DeviceName);
233
234 /*
235 if (NT_SUCCESS(Status))
236 Status = AddDevice_Keyboard(DriverObject, pdo);
237 if (NT_SUCCESS(Status))
238 Status = AddDevice_Mouse(DriverObject, pdo);
239 */
240
241 if (!NT_SUCCESS(Status))
242 {
243 DPRINT("USBMP: IoCreateSymbolicLink() call failed with status 0x%08x\n", Status);
244 IoDeleteDevice(DeviceExtension->RootHubPdo);
245 IoDeleteDevice(fdo);
246 return Status;
247 }
248
249
250 return STATUS_SUCCESS;
251 }
252
253 NTSTATUS STDCALL
254 IrpStub(
255 IN PDEVICE_OBJECT DeviceObject,
256 IN PIRP Irp)
257 {
258 NTSTATUS Status = STATUS_NOT_SUPPORTED;
259
260 if (((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
261 {
262 DPRINT1("USBMP: FDO stub for major function 0x%lx\n",
263 IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
264 #ifndef NDEBUG
265 DbgBreakPoint();
266 #endif
267 return ForwardIrpAndForget(DeviceObject, Irp);
268 }
269 else
270 {
271 /* We can't forward request to the lower driver, because
272 * we are a Pdo, so we don't have lower driver...
273 */
274 DPRINT1("USBMP: PDO stub for major function 0x%lx\n",
275 IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
276 #ifndef NDEBUG
277 DbgBreakPoint();
278 #endif
279 }
280
281 Status = Irp->IoStatus.Status;
282 IoCompleteRequest(Irp, IO_NO_INCREMENT);
283 return Status;
284 }
285
286 static NTSTATUS STDCALL
287 DispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
288 {
289 if (((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
290 return UsbMpCreate(DeviceObject, Irp);
291 else
292 return IrpStub(DeviceObject, Irp);
293 }
294
295 static NTSTATUS STDCALL
296 DispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
297 {
298 if (((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
299 return UsbMpClose(DeviceObject, Irp);
300 else
301 return IrpStub(DeviceObject, Irp);
302 }
303
304 static NTSTATUS STDCALL
305 DispatchCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
306 {
307 if (((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
308 return UsbMpCleanup(DeviceObject, Irp);
309 else
310 return IrpStub(DeviceObject, Irp);
311 }
312
313 static NTSTATUS STDCALL
314 DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
315 {
316 if (((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
317 return UsbMpDeviceControlFdo(DeviceObject, Irp);
318 else
319 return UsbMpDeviceControlPdo(DeviceObject, Irp);
320 }
321
322 static NTSTATUS STDCALL
323 DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
324 {
325 if (((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
326 return UsbMpInternalDeviceControlFdo(DeviceObject, Irp);
327 else
328 return IrpStub(DeviceObject, Irp);
329 }
330
331 static NTSTATUS STDCALL
332 DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
333 {
334 if (((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
335 return UsbMpPnpFdo(DeviceObject, Irp);
336 else
337 return UsbMpPnpPdo(DeviceObject, Irp);
338 }
339
340 static NTSTATUS STDCALL
341 DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
342 {
343 DPRINT1("USBMP: IRP_MJ_POWER unimplemented\n");
344 Irp->IoStatus.Information = 0;
345 Irp->IoStatus.Status = STATUS_SUCCESS;
346 IoCompleteRequest(Irp, IO_NO_INCREMENT);
347 return STATUS_SUCCESS;
348 }
349
350 /*
351 * Standard DriverEntry method.
352 */
353 NTSTATUS STDCALL
354 DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
355 {
356 USBPORT_INTERFACE UsbPortInterface;
357 ULONG i;
358
359 DriverObject->DriverUnload = DriverUnload;
360 DriverObject->DriverExtension->AddDevice = AddDevice;
361
362 for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
363 DriverObject->MajorFunction[i] = IrpStub;
364
365 DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
366 DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
367 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
368 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
369 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalDeviceControl;
370 DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
371 DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
372
373 // Register in usbcore.sys
374 UsbPortInterface.KbdConnectData = &KbdClassInformation;
375 UsbPortInterface.MouseConnectData = &MouseClassInformation;
376
377 KbdClassInformation.ClassService = NULL;
378 KbdClassInformation.ClassDeviceObject = NULL;
379 MouseClassInformation.ClassService = NULL;
380 MouseClassInformation.ClassDeviceObject = NULL;
381
382 RegisterPortDriver(DriverObject, &UsbPortInterface);
383
384 return STATUS_SUCCESS;
385 }