2 ReactOS specific functions for UHCI module
3 by Aleksey Bragin (aleksey@reactos.com)
4 and Hervé Poussineau (hpoussin@reactos.com)
5 Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
11 /* declare basic init functions and structures */
12 void uhci_hcd_cleanup(void);
13 void STDCALL
usb_exit(void);
15 extern struct pci_driver uhci_pci_driver
;
17 static ULONG DeviceNumber
= 0; /* FIXME: what is that? */
21 IN PDRIVER_OBJECT DriverObject
,
22 IN PDEVICE_OBJECT Fdo
,
23 OUT PDEVICE_OBJECT
* pPdo
)
26 POHCI_DEVICE_EXTENSION DeviceExtension
;
29 DPRINT("UHCI: CreateRootHubPdo()\n");
31 Status
= IoCreateDevice(
33 sizeof(OHCI_DEVICE_EXTENSION
),
34 NULL
, /* DeviceName */
35 FILE_DEVICE_BUS_EXTENDER
,
36 FILE_DEVICE_SECURE_OPEN
| FILE_AUTOGENERATED_DEVICE_NAME
,
39 if (!NT_SUCCESS(Status
))
41 DPRINT("UHCI: IoCreateDevice() call failed with status 0x%08x\n", Status
);
45 Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
46 Pdo
->Flags
|= DO_POWER_PAGABLE
;
48 // zerofill device extension
49 DeviceExtension
= (POHCI_DEVICE_EXTENSION
)Pdo
->DeviceExtension
;
50 RtlZeroMemory(DeviceExtension
, sizeof(OHCI_DEVICE_EXTENSION
));
52 DeviceExtension
->IsFDO
= FALSE
;
53 DeviceExtension
->FunctionalDeviceObject
= Fdo
;
55 Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
58 return STATUS_SUCCESS
;
63 IN PDRIVER_OBJECT DriverObject
,
64 IN PDEVICE_OBJECT pdo
)
68 WCHAR DeviceBuffer
[20];
69 WCHAR LinkDeviceBuffer
[20];
70 UNICODE_STRING DeviceName
;
71 UNICODE_STRING LinkDeviceName
;
72 POHCI_DRIVER_EXTENSION DriverExtension
;
73 POHCI_DEVICE_EXTENSION DeviceExtension
;
75 DPRINT("UHCI: AddDevice called\n");
77 // Allocate driver extension now
78 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
79 if (DriverExtension
== NULL
)
81 Status
= IoAllocateDriverObjectExtension(
84 sizeof(OHCI_DRIVER_EXTENSION
),
85 (PVOID
*)&DriverExtension
);
87 if (!NT_SUCCESS(Status
))
89 DPRINT("UHCI: Allocating DriverObjectExtension failed.\n");
94 // Create a unicode device name
95 // DeviceNumber = 0; //TODO: Allocate new device number every time
96 swprintf(DeviceBuffer
, L
"\\Device\\USBFDO-%lu", DeviceNumber
);
97 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
99 Status
= IoCreateDevice(DriverObject
,
100 sizeof(OHCI_DEVICE_EXTENSION
),
102 FILE_DEVICE_BUS_EXTENDER
,
107 if (!NT_SUCCESS(Status
))
109 DPRINT("UHCI: IoCreateDevice call failed with status 0x%08lx\n", Status
);
113 // zerofill device extension
114 DeviceExtension
= (POHCI_DEVICE_EXTENSION
)fdo
->DeviceExtension
;
115 RtlZeroMemory(DeviceExtension
, sizeof(OHCI_DEVICE_EXTENSION
));
117 /* Create root hub Pdo */
118 Status
= CreateRootHubPdo(DriverObject
, fdo
, &DeviceExtension
->RootHubPdo
);
119 if (!NT_SUCCESS(Status
))
121 DPRINT("UHCI: CreateRootHubPdo() failed with status 0x%08lx\n", Status
);
126 /* Register device interface for controller */
127 Status
= IoRegisterDeviceInterface(
129 &GUID_DEVINTERFACE_USB_HOST_CONTROLLER
,
131 &DeviceExtension
->HcdInterfaceName
);
132 if (!NT_SUCCESS(Status
))
134 DPRINT("UHCI: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status
);
135 IoDeleteDevice(DeviceExtension
->RootHubPdo
);
140 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(fdo
, pdo
);
142 fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
144 // Initialize device extension
145 DeviceExtension
->IsFDO
= TRUE
;
146 DeviceExtension
->DeviceNumber
= DeviceNumber
;
147 DeviceExtension
->PhysicalDeviceObject
= pdo
;
148 DeviceExtension
->FunctionalDeviceObject
= fdo
;
149 DeviceExtension
->DriverExtension
= DriverExtension
;
151 /* FIXME: do a loop to find an available number */
152 swprintf(LinkDeviceBuffer
, L
"\\??\\HCD%lu", 0);
154 RtlInitUnicodeString(&LinkDeviceName
, LinkDeviceBuffer
);
156 Status
= IoCreateSymbolicLink(&LinkDeviceName
, &DeviceName
);
158 if (!NT_SUCCESS(Status
))
160 DPRINT("UHCI: IoCreateSymbolicLink call failed with status 0x%08x\n", Status
);
161 IoDeleteDevice(DeviceExtension
->RootHubPdo
);
166 return STATUS_SUCCESS
;
170 DriverUnload(PDRIVER_OBJECT DriverObject
)
172 POHCI_DEVICE_EXTENSION DeviceExtension
;
173 PDEVICE_OBJECT DeviceObject
;
176 DeviceObject
= DriverObject
->DeviceObject
;
177 DeviceExtension
= (POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
179 dev
= DeviceExtension
->pdev
;
181 DPRINT1("UHCI: DriverUnload()\n");
186 // Remove device (ohci_pci_driver.remove)
187 uhci_pci_driver
.remove(dev
);
189 ExFreePool(dev
->slot_name
);
192 // Perform some cleanup
198 IN PDEVICE_OBJECT DeviceObject
,
201 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
203 if (((POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
205 DPRINT1("UHCI: FDO stub for major function 0x%lx\n",
206 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
210 return ForwardIrpAndForget(DeviceObject
, Irp
);
214 /* We can't forward request to the lower driver, because
215 * we are a Pdo, so we don't have lower driver...
217 DPRINT1("UHCI: PDO stub for major function 0x%lx\n",
218 IoGetCurrentIrpStackLocation(Irp
)->MajorFunction
);
224 Status
= Irp
->IoStatus
.Status
;
225 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
229 static NTSTATUS STDCALL
230 DispatchCreate(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
232 if (((POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
233 return UhciCreate(DeviceObject
, Irp
);
235 return IrpStub(DeviceObject
, Irp
);
238 static NTSTATUS STDCALL
239 DispatchClose(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
241 if (((POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
242 return UhciClose(DeviceObject
, Irp
);
244 return IrpStub(DeviceObject
, Irp
);
247 static NTSTATUS STDCALL
248 DispatchCleanup(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
250 if (((POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
251 return UhciCleanup(DeviceObject
, Irp
);
253 return IrpStub(DeviceObject
, Irp
);
256 static NTSTATUS STDCALL
257 DispatchDeviceControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
259 if (((POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
260 return UhciDeviceControlFdo(DeviceObject
, Irp
);
262 return UhciDeviceControlPdo(DeviceObject
, Irp
);
265 static NTSTATUS STDCALL
266 DispatchPnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
268 if (((POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->IsFDO
)
269 return UhciPnpFdo(DeviceObject
, Irp
);
271 return UhciPnpPdo(DeviceObject
, Irp
);
274 static NTSTATUS STDCALL
275 DispatchPower(PDEVICE_OBJECT fido
, PIRP Irp
)
277 DPRINT1("UHCI: IRP_MJ_POWER unimplemented\n");
278 Irp
->IoStatus
.Information
= 0;
279 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
280 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
281 return STATUS_SUCCESS
;
285 * Standard DriverEntry method.
288 DriverEntry(IN PDRIVER_OBJECT DriverObject
, IN PUNICODE_STRING RegPath
)
291 DPRINT("********* Cromwell UHCI *********\n");
293 DriverObject
->DriverUnload
= DriverUnload
;
294 DriverObject
->DriverExtension
->AddDevice
= AddDevice
;
296 for (i
= 0; i
< IRP_MJ_MAXIMUM_FUNCTION
; i
++)
297 DriverObject
->MajorFunction
[i
] = IrpStub
;
299 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = DispatchCreate
;
300 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = DispatchClose
;
301 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = DispatchCleanup
;
302 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = DispatchDeviceControl
;
303 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = DispatchPnp
;
304 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = DispatchPower
;
306 return STATUS_SUCCESS
;