2 ReactOS specific functions for UHCI module
3 by Aleksey Bragin (aleksey@reactos.com)
4 Some parts of code are inspired (or even just copied) from ReactOS Videoport driver
9 #include "../linux/linux_wrapper.h"
10 #include "../host/ohci_main.h"
12 // declare basic init funcs
13 void init_wrapper(struct pci_dev
*probe_dev
);
14 int uhci_hcd_init(void);
15 void uhci_hcd_cleanup(void);
16 int STDCALL
usb_init(void);
17 void STDCALL
usb_exit(void);
18 extern struct pci_driver uhci_pci_driver
;
19 extern const struct pci_device_id uhci_pci_ids
[];
23 // This should be removed, but for testing purposes it's here
25 //struct pci_device_id *dev_id;
28 #define USB_UHCI_TAG TAG('u','s','b','u')
30 NTSTATUS STDCALL
AddDevice(PDRIVER_OBJECT DriverObject
, PDEVICE_OBJECT pdo
)
34 WCHAR DeviceBuffer
[20];
35 UNICODE_STRING DeviceName
;
36 POHCI_DRIVER_EXTENSION DriverExtension
;
37 POHCI_DEVICE_EXTENSION DeviceExtension
;
38 ULONG Size
, DeviceNumber
;
40 DPRINT1("uhci: AddDevice called\n");
42 // Allocate driver extension now
43 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
44 if (DriverExtension
== NULL
)
46 Status
= IoAllocateDriverObjectExtension(
49 sizeof(OHCI_DRIVER_EXTENSION
),
50 (PVOID
*)&DriverExtension
);
52 if (!NT_SUCCESS(Status
))
54 DPRINT1("Allocating DriverObjectExtension failed.\n");
59 // Create a unicode device name
60 DeviceNumber
= 0; //TODO: Allocate new device number every time
61 swprintf(DeviceBuffer
, L
"\\Device\\USBFDO-%lu", DeviceNumber
);
62 RtlInitUnicodeString(&DeviceName
, DeviceBuffer
);
64 Status
= IoCreateDevice(DriverObject
,
65 sizeof(OHCI_DEVICE_EXTENSION
)/* + DriverExtension->InitializationData.HwDeviceExtensionSize*/,
67 FILE_DEVICE_CONTROLLER
,
72 if (!NT_SUCCESS(Status
))
74 DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status
);
78 // zerofill device extension
79 DeviceExtension
= (POHCI_DEVICE_EXTENSION
)pdo
->DeviceExtension
;
80 RtlZeroMemory(DeviceExtension
, sizeof(OHCI_DEVICE_EXTENSION
));
81 DeviceExtension
->NextDeviceObject
= IoAttachDeviceToDeviceStack(fdo
, pdo
);
83 fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
85 // Initialize device extension
86 DeviceExtension
->DeviceNumber
= DeviceNumber
;
87 DeviceExtension
->PhysicalDeviceObject
= pdo
;
88 DeviceExtension
->FunctionalDeviceObject
= fdo
;
89 DeviceExtension
->DriverExtension
= DriverExtension
;
91 /* Get bus number from the upper level bus driver. */
93 Status
= IoGetDeviceProperty(
95 DevicePropertyBusNumber
,
97 &DeviceExtension
->SystemIoBusNumber
,
100 if (!NT_SUCCESS(Status
))
102 DPRINT("Couldn't get an information from bus driver. Panic!!!\n");
106 DPRINT("Done AddDevice\n");
107 return STATUS_SUCCESS
;
110 VOID STDCALL
DriverUnload(PDRIVER_OBJECT DriverObject
)
112 DPRINT1("DriverUnload()\n");
117 // Remove device (ohci_pci_driver.remove)
118 uhci_pci_driver
.remove(dev
);
120 ExFreePool(dev
->slot_name
);
123 // Perform some cleanup
127 NTSTATUS
InitLinuxWrapper(PDEVICE_OBJECT DeviceObject
)
130 POHCI_DEVICE_EXTENSION DeviceExtension
= (POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
132 // Fill generic linux structs
133 dev
= ExAllocatePoolWithTag(PagedPool
, sizeof(struct pci_dev
), USB_UHCI_TAG
);
136 dev
->irq
= DeviceExtension
->InterruptLevel
;
137 dev
->dev_ext
= (PVOID
)DeviceExtension
;
138 dev
->slot_name
= ExAllocatePoolWithTag(NonPagedPool
, 128, USB_UHCI_TAG
); // 128 max len for slot name
140 strcpy(dev
->dev
.name
, "UnivHCI PCI-USB Controller");
141 strcpy(dev
->slot_name
, "UHCD PCI Slot");
143 // Init the OHCI HCD. Probe will be called automatically, but will fail because id=NULL
144 Status
= uhci_hcd_init();
145 //FIXME: Check status returned value
150 // Probe device with real id now
151 uhci_pci_driver
.probe(dev
, uhci_pci_ids
);
153 DPRINT("InitLinuxWrapper() done\n");
155 return STATUS_SUCCESS
;
159 OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject
,
162 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
163 PDRIVER_OBJECT DriverObject
;
164 POHCI_DRIVER_EXTENSION DriverExtension
;
165 POHCI_DEVICE_EXTENSION DeviceExtension
;
166 PCM_RESOURCE_LIST AllocatedResources
;
169 * Get the initialization data we saved in VideoPortInitialize.
171 DriverObject
= DeviceObject
->DriverObject
;
172 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
173 DeviceExtension
= (POHCI_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
176 * Store some resources in the DeviceExtension.
178 AllocatedResources
= Stack
->Parameters
.StartDevice
.AllocatedResources
;
179 if (AllocatedResources
!= NULL
)
181 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
182 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
184 ULONG ResourceListSize
;
186 /* Save the resource list */
187 ResourceCount
= AllocatedResources
->List
[0].PartialResourceList
.Count
;
189 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
190 PartialDescriptors
[ResourceCount
]);
191 DeviceExtension
->AllocatedResources
= ExAllocatePool(PagedPool
, ResourceListSize
);
192 if (DeviceExtension
->AllocatedResources
== NULL
)
194 return STATUS_INSUFFICIENT_RESOURCES
;
197 RtlCopyMemory(DeviceExtension
->AllocatedResources
,
201 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
202 for (FullList
= AllocatedResources
->List
;
203 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
206 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
207 /*ASSERT(FullList->InterfaceType == PCIBus &&
208 FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
209 1 == FullList->PartialResourceList.Version &&
210 1 == FullList->PartialResourceList.Revision);*/
211 DPRINT1("AllocRess->Count: %d, PartResList.Count: %d\n",
212 AllocatedResources
->Count
, FullList
->PartialResourceList
.Count
);
214 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
215 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
218 if (Descriptor
->Type
== CmResourceTypeInterrupt
)
220 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
221 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
223 DPRINT1("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
224 DeviceExtension
->InterruptLevel
,
225 DeviceExtension
->InterruptVector
);
227 else if (Descriptor
->Type
== CmResourceTypePort
)
229 DeviceExtension
->BaseAddress
= Descriptor
->u
.Memory
.Start
;
230 DeviceExtension
->BaseAddrLength
= Descriptor
->u
.Memory
.Length
;
232 DPRINT1("I/O resource: start=0x%x, length=0x%x\n",
233 DeviceExtension
->BaseAddress
.u
.LowPart
, DeviceExtension
->BaseAddrLength
);
236 DPRINT1("Get resource type: %d, Generic start=0x%x Generic length=0x%x\n",
237 Descriptor
->Type
, Descriptor
->u
.Generic
.Start
.u
.LowPart
, Descriptor
->u
.Generic
.Length
);
244 * Init wrapper with this object
246 return InitLinuxWrapper(DeviceObject
);
250 NTSTATUS STDCALL
DispatchPnp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
252 PIO_STACK_LOCATION IrpSp
;
255 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
257 switch (IrpSp
->MinorFunction
)
259 case IRP_MN_START_DEVICE
:
260 //Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
261 //if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
263 Status
= OHCD_PnPStartDevice(DeviceObject
, Irp
);
264 Irp
->IoStatus
.Status
= Status
;
265 Irp
->IoStatus
.Information
= 0;
266 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
270 case IRP_MN_REMOVE_DEVICE
:
271 case IRP_MN_QUERY_REMOVE_DEVICE
:
272 case IRP_MN_CANCEL_REMOVE_DEVICE
:
273 case IRP_MN_SURPRISE_REMOVAL
:
275 case IRP_MN_STOP_DEVICE
:
276 //Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
277 //if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
278 Status
= STATUS_SUCCESS
;
279 Irp
->IoStatus
.Status
= Status
;
280 Irp
->IoStatus
.Information
= 0;
281 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
283 IoDeleteDevice(DeviceObject
); // just delete device for now
286 case IRP_MN_QUERY_STOP_DEVICE
:
287 case IRP_MN_CANCEL_STOP_DEVICE
:
288 Status
= STATUS_SUCCESS
;
289 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
290 Irp
->IoStatus
.Information
= 0;
291 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
295 return STATUS_NOT_IMPLEMENTED
;
302 NTSTATUS STDCALL
DispatchPower(PDEVICE_OBJECT fido
, PIRP Irp
)
304 DbgPrint("IRP_MJ_POWER dispatch\n");
305 return STATUS_SUCCESS
;
309 * Standard DriverEntry method.
312 DriverEntry(IN PDRIVER_OBJECT DriverObject
, IN PUNICODE_STRING RegPath
)
314 DriverObject
->DriverUnload
= DriverUnload
;
315 DriverObject
->DriverExtension
->AddDevice
= AddDevice
;
316 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = DispatchPnp
;
317 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = DispatchPower
;
319 return STATUS_SUCCESS
;