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
7 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.com)
8 * Hervé Poussineau (hpoussin@reactos.org),
10 * Some parts of code are inspired (or even just copied) from
11 * ReactOS Videoport driver (drivers/video/videoprt)
18 #include "usbcommon.h"
20 // data for embedded drivers
21 CONNECT_DATA KbdClassInformation
;
22 CONNECT_DATA MouseClassInformation
;
23 PDEVICE_OBJECT KeyboardFdo
= NULL
;
24 PDEVICE_OBJECT MouseFdo
= NULL
;
28 IN PDRIVER_OBJECT DriverObject
,
29 IN PDEVICE_OBJECT Fdo
,
30 OUT PDEVICE_OBJECT
* pPdo
)
33 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
36 DPRINT("USBMP: CreateRootHubPdo()\n");
38 Status
= IoCreateDevice(
40 sizeof(USBMP_DEVICE_EXTENSION
),
41 NULL
, /* DeviceName */
42 FILE_DEVICE_BUS_EXTENDER
,
43 FILE_DEVICE_SECURE_OPEN
| FILE_AUTOGENERATED_DEVICE_NAME
,
46 if (!NT_SUCCESS(Status
))
48 DPRINT("USBMP: IoCreateDevice() call failed with status 0x%08x\n", Status
);
52 Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
53 Pdo
->Flags
|= DO_POWER_PAGABLE
;
55 // zerofill device extension
56 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)Pdo
->DeviceExtension
;
57 RtlZeroMemory(DeviceExtension
, sizeof(USBMP_DEVICE_EXTENSION
));
59 DeviceExtension
->IsFDO
= FALSE
;
60 DeviceExtension
->FunctionalDeviceObject
= Fdo
;
62 Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
65 return STATUS_SUCCESS
;
70 IN PDRIVER_OBJECT DriverObject
,
71 IN PDEVICE_OBJECT Pdo
)
73 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\KeyboardClass0");
77 Status
= IoCreateDevice(DriverObject
,
81 FILE_DEVICE_SECURE_OPEN
,
85 if (!NT_SUCCESS(Status
))
87 DPRINT1("USBMP: IoCreateDevice() for usb keyboard driver failed with status 0x%08lx\n", Status
);
91 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
92 DPRINT("USBMP: Created keyboard Fdo: %p\n", Fdo
);
94 return STATUS_SUCCESS
;
99 IN PDRIVER_OBJECT DriverObject
,
100 IN PDEVICE_OBJECT Pdo
)
102 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Device\\PointerClass0");
106 Status
= IoCreateDevice(DriverObject
,
110 FILE_DEVICE_SECURE_OPEN
,
114 if (!NT_SUCCESS(Status
))
116 DPRINT1("USBMP: IoCreateDevice() for usb mouse driver failed with status 0x%08lx\n", Status
);
120 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
121 DPRINT("USBMP: Created mouse Fdo: %p\n", Fdo
);
123 return STATUS_SUCCESS
;
128 IN PDRIVER_OBJECT DriverObject
,
129 IN PDEVICE_OBJECT pdo
)
133 WCHAR DeviceBuffer
[20];
134 WCHAR LinkDeviceBuffer
[20];
135 UNICODE_STRING DeviceName
;
136 UNICODE_STRING LinkDeviceName
;
137 PUSBMP_DRIVER_EXTENSION DriverExtension
;
138 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
141 /* FIXME: actually, we prevent multiple USB controllers on a computer */
142 static BOOLEAN xbox_workaround
= FALSE
;
144 DPRINT("USBMP: AddDevice called\n");
147 // Fail for any other host controller than the first
148 return STATUS_INSUFFICIENT_RESOURCES
;
149 xbox_workaround
= TRUE
;
151 // Allocate driver extension now
152 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
153 if (DriverExtension
== NULL
)
155 Status
= IoAllocateDriverObjectExtension(
158 sizeof(USBMP_DRIVER_EXTENSION
),
159 (PVOID
*)&DriverExtension
);
161 if (!NT_SUCCESS(Status
))
163 DPRINT("USBMP: Allocating DriverObjectExtension failed.\n");
168 // Create a unicode device name
169 // DeviceNumber = 0; //TODO: Allocate new device number every time
170 swprintf(DeviceBuffer
, L
"\\Device\\USBFDO-%lu", DeviceNumber
);
171 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
173 Status
= IoCreateDevice(DriverObject
,
174 sizeof(USBMP_DEVICE_EXTENSION
),
176 FILE_DEVICE_BUS_EXTENDER
,
181 if (!NT_SUCCESS(Status
))
183 DPRINT("USBMP: IoCreateDevice call failed with status 0x%08lx\n", Status
);
187 // zerofill device extension
188 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)fdo
->DeviceExtension
;
189 RtlZeroMemory(DeviceExtension
, sizeof(USBMP_DEVICE_EXTENSION
));
191 /* Create root hub Pdo */
192 Status
= CreateRootHubPdo(DriverObject
, fdo
, &DeviceExtension
->RootHubPdo
);
193 if (!NT_SUCCESS(Status
))
195 DPRINT("USBMP: CreateRootHubPdo() failed with status 0x%08lx\n", Status
);
200 /* Register device interface for controller */
201 Status
= IoRegisterDeviceInterface(
203 &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
,
205 &DeviceExtension
->HcdInterfaceName
);
206 if (!NT_SUCCESS(Status
))
208 DPRINT("USBMP: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status
);
209 IoDeleteDevice(DeviceExtension
->RootHubPdo
);
214 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(fdo
, pdo
);
216 // Initialize device extension
217 DeviceExtension
->IsFDO
= TRUE
;
218 DeviceExtension
->DeviceNumber
= DeviceNumber
;
219 DeviceExtension
->PhysicalDeviceObject
= pdo
;
220 DeviceExtension
->FunctionalDeviceObject
= fdo
;
221 DeviceExtension
->DriverExtension
= DriverExtension
;
223 fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
225 /* FIXME: do a loop to find an available number */
226 swprintf(LinkDeviceBuffer
, L
"\\??\\HCD%lu", 0);
228 RtlInitUnicodeString(&LinkDeviceName
, LinkDeviceBuffer
);
230 Status
= IoCreateSymbolicLink(&LinkDeviceName
, &DeviceName
);
232 if (NT_SUCCESS(Status
))
233 Status
= AddDevice_Keyboard(DriverObject
, pdo
);
234 if (NT_SUCCESS(Status
))
235 Status
= AddDevice_Mouse(DriverObject
, pdo
);
237 if (!NT_SUCCESS(Status
))
239 DPRINT("USBMP: IoCreateSymbolicLink() call failed with status 0x%08x\n", Status
);
240 IoDeleteDevice(DeviceExtension
->RootHubPdo
);
246 return STATUS_SUCCESS
;
251 IN PDEVICE_OBJECT DeviceObject
,
254 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
256 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
258 DPRINT1("USBMP: FDO stub for major function 0x%lx\n",
259 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
263 return ForwardIrpAndForget(DeviceObject
, Irp
);
267 /* We can't forward request to the lower driver, because
268 * we are a Pdo, so we don't have lower driver...
270 DPRINT1("USBMP: PDO stub for major function 0x%lx\n",
271 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
277 Status
= Irp
->IoStatus
.Status
;
278 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
282 static NTSTATUS STDCALL
283 DispatchCreate(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
285 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
286 return UsbMpCreate(DeviceObject
, Irp
);
288 return IrpStub(DeviceObject
, Irp
);
291 static NTSTATUS STDCALL
292 DispatchClose(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
294 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
295 return UsbMpClose(DeviceObject
, Irp
);
297 return IrpStub(DeviceObject
, Irp
);
300 static NTSTATUS STDCALL
301 DispatchCleanup(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
303 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
304 return UsbMpCleanup(DeviceObject
, Irp
);
306 return IrpStub(DeviceObject
, Irp
);
309 static NTSTATUS STDCALL
310 DispatchDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
312 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
313 return UsbMpDeviceControlFdo(DeviceObject
, Irp
);
315 return UsbMpDeviceControlPdo(DeviceObject
, Irp
);
318 static NTSTATUS STDCALL
319 DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
321 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
322 return UsbMpInternalDeviceControlFdo(DeviceObject
, Irp
);
324 return IrpStub(DeviceObject
, Irp
);
327 static NTSTATUS STDCALL
328 DispatchPnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
330 if (((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
331 return UsbMpPnpFdo(DeviceObject
, Irp
);
333 return UsbMpPnpPdo(DeviceObject
, Irp
);
336 static NTSTATUS STDCALL
337 DispatchPower(PDEVICE_OBJECT fido
, PIRP Irp
)
339 DPRINT1("USBMP: IRP_MJ_POWER unimplemented\n");
340 Irp
->IoStatus
.Information
= 0;
341 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
342 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
343 return STATUS_SUCCESS
;
347 * Standard DriverEntry method.
350 DriverEntry(IN PDRIVER_OBJECT DriverObject
, IN PUNICODE_STRING RegPath
)
352 USBPORT_INTERFACE UsbPortInterface
;
355 DriverObject
->DriverUnload
= DriverUnload
;
356 DriverObject
->DriverExtension
->AddDevice
= AddDevice
;
358 for (i
= 0; i
< IRP_MJ_MAXIMUM_FUNCTION
; i
++)
359 DriverObject
->MajorFunction
[i
] = IrpStub
;
361 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = DispatchCreate
;
362 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = DispatchClose
;
363 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = DispatchCleanup
;
364 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = DispatchDeviceControl
;
365 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = DispatchInternalDeviceControl
;
366 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = DispatchPnp
;
367 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = DispatchPower
;
369 // Register in usbcore.sys
370 UsbPortInterface
.KbdConnectData
= &KbdClassInformation
;
371 UsbPortInterface
.MouseConnectData
= &MouseClassInformation
;
373 KbdClassInformation
.ClassService
= NULL
;
374 KbdClassInformation
.ClassDeviceObject
= NULL
;
375 MouseClassInformation
.ClassService
= NULL
;
376 MouseClassInformation
.ClassDeviceObject
= NULL
;
378 RegisterPortDriver(DriverObject
, &UsbPortInterface
);
380 return STATUS_SUCCESS
;