2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbccgp/fdo.c
5 * PURPOSE: USB device driver.
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
16 FDO_QueryCapabilitiesCompletionRoutine(
17 IN PDEVICE_OBJECT DeviceObject
,
24 KeSetEvent((PRKEVENT
)Context
, 0, FALSE
);
27 // completion is done in the HidClassFDO_QueryCapabilities routine
29 return STATUS_MORE_PROCESSING_REQUIRED
;
33 FDO_QueryCapabilities(
34 IN PDEVICE_OBJECT DeviceObject
,
35 IN OUT PDEVICE_CAPABILITIES Capabilities
)
40 PIO_STACK_LOCATION IoStack
;
41 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
44 // get device extension
46 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
47 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
52 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
55 // now allocte the irp
57 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, FALSE
);
63 return STATUS_INSUFFICIENT_RESOURCES
;
67 // get next stack location
69 IoStack
= IoGetNextIrpStackLocation(Irp
);
72 // init stack location
74 IoStack
->MajorFunction
= IRP_MJ_PNP
;
75 IoStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
76 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
= Capabilities
;
79 // set completion routine
81 IoSetCompletionRoutine(Irp
, FDO_QueryCapabilitiesCompletionRoutine
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
86 RtlZeroMemory(Capabilities
, sizeof(DEVICE_CAPABILITIES
));
87 Capabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
88 Capabilities
->Version
= 1; // FIXME hardcoded constant
89 Capabilities
->Address
= MAXULONG
;
90 Capabilities
->UINumber
= MAXULONG
;
93 // pnp irps have default completion code
95 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
100 Status
= IoCallDriver(FDODeviceExtension
->NextDeviceObject
, Irp
);
101 if (Status
== STATUS_PENDING
)
104 // wait for completion
106 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
112 Status
= Irp
->IoStatus
.Status
;
127 PDEVICE_OBJECT DeviceObject
,
130 ULONG DeviceCount
= 0;
132 PDEVICE_RELATIONS DeviceRelations
;
133 PIO_STACK_LOCATION IoStack
;
134 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
137 // get device extension
139 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
143 // get current irp stack location
145 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
148 // check if relation type is BusRelations
150 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= BusRelations
)
153 // FDO always only handles bus relations
155 return USBCCGP_SyncForwardIrp(FDODeviceExtension
->NextDeviceObject
, Irp
);
159 // go through array and count device objects
161 for(Index
= 0; Index
< FDODeviceExtension
->FunctionDescriptorCount
; Index
++)
163 if (FDODeviceExtension
->ChildPDO
[Index
])
173 // allocate device relations
175 DeviceRelations
= (PDEVICE_RELATIONS
)AllocateItem(PagedPool
, sizeof(DEVICE_RELATIONS
) + (DeviceCount
> 1 ? (DeviceCount
-1) * sizeof(PDEVICE_OBJECT
) : 0));
176 if (!DeviceRelations
)
181 return STATUS_INSUFFICIENT_RESOURCES
;
185 // add device objects
187 for(Index
= 0; Index
< FDODeviceExtension
->FunctionDescriptorCount
; Index
++)
189 if (FDODeviceExtension
->ChildPDO
[Index
])
194 DeviceRelations
->Objects
[DeviceRelations
->Count
] = FDODeviceExtension
->ChildPDO
[Index
];
199 ObReferenceObject(FDODeviceExtension
->ChildPDO
[Index
]);
204 DeviceRelations
->Count
++;
211 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
214 // request completed successfully
216 return STATUS_SUCCESS
;
221 IN PDEVICE_OBJECT DeviceObject
)
224 PDEVICE_OBJECT PDODeviceObject
;
225 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
226 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
230 // get device extension
232 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
233 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
236 // lets create array for the child PDO
238 FDODeviceExtension
->ChildPDO
= AllocateItem(NonPagedPool
, sizeof(PDEVICE_OBJECT
) * FDODeviceExtension
->FunctionDescriptorCount
);
239 if (!FDODeviceExtension
->ChildPDO
)
244 return STATUS_INSUFFICIENT_RESOURCES
;
248 // create pdo for each function
250 for(Index
= 0; Index
< FDODeviceExtension
->FunctionDescriptorCount
; Index
++)
255 Status
= IoCreateDevice(FDODeviceExtension
->DriverObject
, sizeof(PDO_DEVICE_EXTENSION
), NULL
, FILE_DEVICE_USB
, FILE_AUTOGENERATED_DEVICE_NAME
, FALSE
, &PDODeviceObject
);
256 if (!NT_SUCCESS(Status
))
259 // failed to create device object
261 DPRINT1("IoCreateDevice failed with %x\n", Status
);
268 FDODeviceExtension
->ChildPDO
[Index
] = PDODeviceObject
;
271 // get device extension
273 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)PDODeviceObject
->DeviceExtension
;
274 RtlZeroMemory(PDODeviceExtension
, sizeof(PDO_DEVICE_EXTENSION
));
277 // init device extension
279 PDODeviceExtension
->Common
.IsFDO
= FALSE
;
280 PDODeviceExtension
->FunctionDescriptor
= &FDODeviceExtension
->FunctionDescriptor
[Index
];
281 PDODeviceExtension
->NextDeviceObject
= DeviceObject
;
282 PDODeviceExtension
->FunctionIndex
= Index
;
283 RtlCopyMemory(&PDODeviceExtension
->Capabilities
, &FDODeviceExtension
->Capabilities
, sizeof(DEVICE_CAPABILITIES
));
286 // patch the stack size
288 PDODeviceObject
->StackSize
= DeviceObject
->StackSize
+ 1;
293 PDODeviceObject
->Flags
|= DO_DIRECT_IO
| DO_MAP_IO_BUFFER
;
296 // device is initialized
298 PDODeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
304 return STATUS_SUCCESS
;
309 PDEVICE_OBJECT DeviceObject
,
313 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
316 // get device extension
318 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
319 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
322 // first start lower device
324 Status
= USBCCGP_SyncForwardIrp(FDODeviceExtension
->NextDeviceObject
, Irp
);
326 if (!NT_SUCCESS(Status
))
329 // failed to start lower device
331 DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status
);
336 Status
= USBCCGP_GetDescriptors(DeviceObject
);
337 if (!NT_SUCCESS(Status
))
339 // failed to start lower device
340 DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status
);
345 Status
= FDO_QueryCapabilities(DeviceObject
, &FDODeviceExtension
->Capabilities
);
346 if (!NT_SUCCESS(Status
))
348 // failed to start lower device
349 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status
);
353 // now select the configuration
354 Status
= USBCCGP_SelectConfiguration(DeviceObject
, FDODeviceExtension
);
355 if (!NT_SUCCESS(Status
))
357 // failed to select interface
358 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status
);
362 // query bus interface
363 USBCCGP_QueryInterface(FDODeviceExtension
->NextDeviceObject
, &FDODeviceExtension
->BusInterface
);
365 // now enumerate the functions
366 Status
= USBCCGP_EnumerateFunctions(DeviceObject
);
367 if (!NT_SUCCESS(Status
))
369 // failed to enumerate functions
370 DPRINT1("Failed to enumerate functions with %x\n", Status
);
377 ASSERT(FDODeviceExtension
->FunctionDescriptorCount
);
378 ASSERT(FDODeviceExtension
->FunctionDescriptor
);
381 // now create the pdo
383 Status
= FDO_CreateChildPdo(DeviceObject
);
384 if (!NT_SUCCESS(Status
))
389 DPRINT1("FDO_CreateChildPdo failed with %x\n", Status
);
394 // inform pnp manager of new device objects
396 IoInvalidateDeviceRelations(FDODeviceExtension
->PhysicalDeviceObject
, BusRelations
);
401 DPRINT1("[USBCCGP] FDO initialized successfully\n");
407 PDEVICE_OBJECT DeviceObject
,
410 PIO_STACK_LOCATION IoStack
;
412 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
414 // get device extension
415 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
416 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
419 // get stack location
420 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
422 switch(IoStack
->MinorFunction
)
424 case IRP_MN_START_DEVICE
:
429 Status
= FDO_StartDevice(DeviceObject
, Irp
);
432 case IRP_MN_QUERY_DEVICE_RELATIONS
:
435 // handle device relations
437 Status
= FDO_DeviceRelations(DeviceObject
, Irp
);
440 case IRP_MN_QUERY_CAPABILITIES
:
445 RtlCopyMemory(IoStack
->Parameters
.DeviceCapabilities
.Capabilities
, &FDODeviceExtension
->Capabilities
, sizeof(DEVICE_CAPABILITIES
));
446 Status
= USBCCGP_SyncForwardIrp(FDODeviceExtension
->NextDeviceObject
, Irp
);
447 if (NT_SUCCESS(Status
))
450 // surprise removal ok
452 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->SurpriseRemovalOK
= TRUE
;
459 // forward irp to next device object
461 IoSkipCurrentIrpStackLocation(Irp
);
462 return IoCallDriver(FDODeviceExtension
->NextDeviceObject
, Irp
);
470 Irp
->IoStatus
.Status
= Status
;
471 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
479 PDEVICE_OBJECT DeviceObject
,
482 PIO_STACK_LOCATION IoStack
;
485 /* get stack location */
486 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
488 switch(IoStack
->MajorFunction
)
491 return FDO_HandlePnp(DeviceObject
, Irp
);
493 DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack
->MajorFunction
);
495 Status
= Irp
->IoStatus
.Status
;
496 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);