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/descriptor.c
5 * PURPOSE: USB device driver.
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
16 USBCCGP_GetDescriptor(
17 IN PDEVICE_OBJECT DeviceObject
,
18 IN UCHAR DescriptorType
,
19 IN ULONG DescriptorLength
,
20 IN UCHAR DescriptorIndex
,
22 OUT PVOID
*OutDescriptor
)
32 ASSERT(OutDescriptor
);
33 ASSERT(DescriptorLength
);
36 // first allocate descriptor buffer
38 Descriptor
= AllocateItem(NonPagedPool
, DescriptorLength
);
44 return STATUS_INSUFFICIENT_RESOURCES
;
50 Urb
= (PURB
) AllocateItem(NonPagedPool
, sizeof(URB
));
57 return STATUS_INSUFFICIENT_RESOURCES
;
63 UsbBuildGetDescriptorRequest(Urb
,
64 sizeof(Urb
->UrbControlDescriptorRequest
),
76 Status
= USBCCGP_SyncUrbRequest(DeviceObject
, Urb
);
83 if (NT_SUCCESS(Status
))
88 *OutDescriptor
= Descriptor
;
99 USBCCGP_GetStringDescriptor(
100 IN PDEVICE_OBJECT DeviceObject
,
101 IN ULONG DescriptorLength
,
102 IN UCHAR DescriptorIndex
,
103 IN LANGID LanguageId
,
104 OUT PVOID
*OutDescriptor
)
107 PUSB_STRING_DESCRIPTOR StringDescriptor
;
111 // retrieve descriptor
112 Status
= USBCCGP_GetDescriptor(DeviceObject
, USB_STRING_DESCRIPTOR_TYPE
, DescriptorLength
, DescriptorIndex
, LanguageId
, OutDescriptor
);
113 if (!NT_SUCCESS(Status
))
119 // get descriptor structure
120 StringDescriptor
= (PUSB_STRING_DESCRIPTOR
)*OutDescriptor
;
123 ASSERT(StringDescriptor
->bLength
< DescriptorLength
- 2);
125 if (StringDescriptor
->bLength
== 2)
127 // invalid descriptor
128 FreeItem(StringDescriptor
);
129 return STATUS_DEVICE_DATA_ERROR
;
133 Size
= StringDescriptor
->bLength
+ sizeof(WCHAR
);
136 Buffer
= AllocateItem(NonPagedPool
, Size
);
140 FreeItem(StringDescriptor
);
141 return STATUS_INSUFFICIENT_RESOURCES
;
145 RtlCopyMemory(Buffer
, StringDescriptor
->bString
, Size
- FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
));
148 FreeItem(StringDescriptor
);
151 *OutDescriptor
= (PVOID
)Buffer
;
152 return STATUS_SUCCESS
;
157 USBCCGP_GetDescriptors(
158 IN PDEVICE_OBJECT DeviceObject
)
161 PFDO_DEVICE_EXTENSION DeviceExtension
;
162 USHORT DescriptorLength
;
165 // get device extension
167 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
170 // first get device descriptor
172 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_DEVICE_DESCRIPTOR_TYPE
, sizeof(USB_DEVICE_DESCRIPTOR
), 0, 0, (PVOID
*)&DeviceExtension
->DeviceDescriptor
);
173 if (!NT_SUCCESS(Status
))
176 // failed to get device descriptor
178 DeviceExtension
->DeviceDescriptor
= NULL
;
183 // now get basic configuration descriptor
185 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, sizeof(USB_CONFIGURATION_DESCRIPTOR
), 0, 0, (PVOID
*)&DeviceExtension
->ConfigurationDescriptor
);
186 if (!NT_SUCCESS(Status
))
189 // failed to get configuration descriptor
191 FreeItem(DeviceExtension
->DeviceDescriptor
);
192 DeviceExtension
->DeviceDescriptor
= NULL
;
199 DescriptorLength
= DeviceExtension
->ConfigurationDescriptor
->wTotalLength
;
202 // release basic descriptor
204 FreeItem(DeviceExtension
->ConfigurationDescriptor
);
205 DeviceExtension
->ConfigurationDescriptor
= NULL
;
208 // allocate full descriptor
210 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, DescriptorLength
, 0, 0, (PVOID
*)&DeviceExtension
->ConfigurationDescriptor
);
211 if (!NT_SUCCESS(Status
))
214 // failed to get configuration descriptor
216 FreeItem(DeviceExtension
->DeviceDescriptor
);
217 DeviceExtension
->DeviceDescriptor
= NULL
;
224 AllocateInterfaceDescriptorsArray(
225 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
226 OUT PUSB_INTERFACE_DESCRIPTOR
**OutArray
)
228 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
230 PUSB_INTERFACE_DESCRIPTOR
*Array
;
235 Array
= AllocateItem(NonPagedPool
, sizeof(PUSB_INTERFACE_DESCRIPTOR
) * ConfigurationDescriptor
->bNumInterfaces
);
237 return STATUS_INSUFFICIENT_RESOURCES
;
240 // enumerate all interfaces
246 // find next descriptor
248 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, Count
, 0, -1, -1, -1);
249 if (!InterfaceDescriptor
)
255 Array
[Count
] = InterfaceDescriptor
;
268 return STATUS_SUCCESS
;
272 DumpFullConfigurationDescriptor(
273 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
274 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
276 PUSB_COMMON_DESCRIPTOR Descriptor
;
278 Descriptor
= (PUSB_COMMON_DESCRIPTOR
)ConfigurationDescriptor
;
280 DbgPrint("Bogus ConfigurationDescriptor Found\n");
281 DbgPrint("InterfaceCount %x\n", ConfigurationDescriptor
->bNumInterfaces
);
285 if (((ULONG_PTR
)Descriptor
+ Descriptor
->bLength
) <= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
288 DbgPrint("Descriptor Type %x Length %lu Offset %lu\n", Descriptor
->bDescriptorType
, Descriptor
->bLength
, ((ULONG_PTR
)Descriptor
- (ULONG_PTR
)ConfigurationDescriptor
));
290 // check for invalid descriptors
291 if (!Descriptor
->bLength
)
293 DbgPrint("Bogus Descriptor!!!\n");
297 // advance to next descriptor
298 Descriptor
= (PUSB_COMMON_DESCRIPTOR
)((ULONG_PTR
)Descriptor
+ Descriptor
->bLength
);
308 USBCCGP_ScanConfigurationDescriptor(
309 IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension
,
310 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
312 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
313 ULONG InterfaceIndex
= 0;
314 PVOID CurrentPosition
;
315 ULONG DescriptorCount
;
320 ASSERT(ConfigurationDescriptor
);
321 ASSERT(ConfigurationDescriptor
->bNumInterfaces
);
324 // count all interface descriptors
326 DescriptorCount
= ConfigurationDescriptor
->bNumInterfaces
;
329 // allocate array holding the interface descriptors
331 FDODeviceExtension
->InterfaceList
= AllocateItem(NonPagedPool
, sizeof(USBD_INTERFACE_LIST_ENTRY
) * (DescriptorCount
+ 1));
332 if (!FDODeviceExtension
->InterfaceList
)
337 return STATUS_INSUFFICIENT_RESOURCES
;
340 CurrentPosition
= ConfigurationDescriptor
;
344 // parse configuration descriptor
346 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, InterfaceIndex
, -1, -1, -1, -1);
347 if (InterfaceDescriptor
)
350 // store in interface list
352 FDODeviceExtension
->InterfaceList
[FDODeviceExtension
->InterfaceListCount
].InterfaceDescriptor
= InterfaceDescriptor
;
353 FDODeviceExtension
->InterfaceListCount
++;
354 CurrentPosition
= (PVOID
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
358 DumpFullConfigurationDescriptor(FDODeviceExtension
, ConfigurationDescriptor
);
362 // CORE-6574 Test 3 (USB Web Cam)
364 if (FDODeviceExtension
->DeviceDescriptor
&& FDODeviceExtension
->DeviceDescriptor
->idVendor
== 0x0458 && FDODeviceExtension
->DeviceDescriptor
->idProduct
== 0x705f)
369 // move to next interface
373 }while(InterfaceIndex
< DescriptorCount
);
378 ASSERT(FDODeviceExtension
->InterfaceListCount
);
383 return STATUS_SUCCESS
;
387 DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
389 DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor
);
390 DPRINT1("bLength %x\n", ConfigurationDescriptor
->bLength
);
391 DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor
->bDescriptorType
);
392 DPRINT1("wTotalLength %x\n", ConfigurationDescriptor
->wTotalLength
);
393 DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor
->bNumInterfaces
);
394 DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor
->bConfigurationValue
);
395 DPRINT1("iConfiguration %x\n", ConfigurationDescriptor
->iConfiguration
);
396 DPRINT1("bmAttributes %x\n", ConfigurationDescriptor
->bmAttributes
);
397 DPRINT1("MaxPower %x\n", ConfigurationDescriptor
->MaxPower
);
401 USBCCGP_SelectInterface(
402 IN PDEVICE_OBJECT DeviceObject
,
403 IN PFDO_DEVICE_EXTENSION DeviceExtension
,
404 IN ULONG InterfaceIndex
)
412 Urb
= AllocateItem(NonPagedPool
, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bNumEndpoints
));
418 return STATUS_INSUFFICIENT_RESOURCES
;
422 // now prepare interface urb
424 UsbBuildSelectInterfaceRequest(Urb
, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bNumEndpoints
), DeviceExtension
->ConfigurationHandle
, DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bInterfaceNumber
, DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bAlternateSetting
);
427 // now select the interface
429 Status
= USBCCGP_SyncUrbRequest(DeviceExtension
->NextDeviceObject
, Urb
);
434 if (NT_SUCCESS(Status
))
437 // update configuration info
439 ASSERT(Urb
->UrbSelectInterface
.Interface
.Length
== DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->Length
);
440 RtlCopyMemory(DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
, &Urb
->UrbSelectInterface
.Interface
, Urb
->UrbSelectInterface
.Interface
.Length
);
455 USBCCGP_SelectConfiguration(
456 IN PDEVICE_OBJECT DeviceObject
,
457 IN PFDO_DEVICE_EXTENSION DeviceExtension
)
459 PUSBD_INTERFACE_INFORMATION InterfaceInformation
;
465 // now scan configuration descriptors
467 Status
= USBCCGP_ScanConfigurationDescriptor(DeviceExtension
, DeviceExtension
->ConfigurationDescriptor
);
468 if (!NT_SUCCESS(Status
))
477 // now allocate the urb
479 Urb
= USBD_CreateConfigurationRequestEx(DeviceExtension
->ConfigurationDescriptor
, DeviceExtension
->InterfaceList
);
485 return STATUS_INSUFFICIENT_RESOURCES
;
491 Status
= USBCCGP_SyncUrbRequest(DeviceExtension
->NextDeviceObject
, Urb
);
492 if (!NT_SUCCESS(Status
))
495 // failed to set configuration
497 DPRINT1("USBCCGP_SyncUrbRequest failed to set interface %x\n", Status
);
503 // get interface information
505 InterfaceInformation
= &Urb
->UrbSelectConfiguration
.Interface
;
506 for(Index
= 0; Index
< DeviceExtension
->InterfaceListCount
; Index
++)
509 // allocate buffer to store interface information
511 DeviceExtension
->InterfaceList
[Index
].Interface
= AllocateItem(NonPagedPool
, InterfaceInformation
->Length
);
512 if (!DeviceExtension
->InterfaceList
[Index
].Interface
)
517 return STATUS_INSUFFICIENT_RESOURCES
;
521 // copy interface information
523 RtlCopyMemory(DeviceExtension
->InterfaceList
[Index
].Interface
, InterfaceInformation
, InterfaceInformation
->Length
);
526 // move to next interface
528 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ InterfaceInformation
->Length
);
535 DeviceExtension
->ConfigurationHandle
= Urb
->UrbSelectConfiguration
.ConfigurationHandle
;
538 // free interface list & urb