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)
19 USBCCGP_GetDescriptor(
20 IN PDEVICE_OBJECT DeviceObject
,
21 IN UCHAR DescriptorType
,
22 IN ULONG DescriptorLength
,
23 IN UCHAR DescriptorIndex
,
25 OUT PVOID
*OutDescriptor
)
35 ASSERT(OutDescriptor
);
36 ASSERT(DescriptorLength
);
39 // first allocate descriptor buffer
41 Descriptor
= AllocateItem(NonPagedPool
, DescriptorLength
);
47 return STATUS_INSUFFICIENT_RESOURCES
;
53 Urb
= (PURB
) AllocateItem(NonPagedPool
, sizeof(URB
));
60 return STATUS_INSUFFICIENT_RESOURCES
;
66 UsbBuildGetDescriptorRequest(Urb
,
67 sizeof(Urb
->UrbControlDescriptorRequest
),
79 Status
= USBCCGP_SyncUrbRequest(DeviceObject
, Urb
);
86 if (NT_SUCCESS(Status
))
91 *OutDescriptor
= Descriptor
;
102 USBCCGP_GetStringDescriptor(
103 IN PDEVICE_OBJECT DeviceObject
,
104 IN ULONG DescriptorLength
,
105 IN UCHAR DescriptorIndex
,
106 IN LANGID LanguageId
,
107 OUT PVOID
*OutDescriptor
)
110 PUSB_STRING_DESCRIPTOR StringDescriptor
;
114 // retrieve descriptor
115 Status
= USBCCGP_GetDescriptor(DeviceObject
, USB_STRING_DESCRIPTOR_TYPE
, DescriptorLength
, DescriptorIndex
, LanguageId
, OutDescriptor
);
116 if (!NT_SUCCESS(Status
))
122 // get descriptor structure
123 StringDescriptor
= (PUSB_STRING_DESCRIPTOR
)*OutDescriptor
;
126 ASSERT(StringDescriptor
->bLength
< DescriptorLength
- 2);
128 if (StringDescriptor
->bLength
== 2)
130 // invalid descriptor
131 FreeItem(StringDescriptor
);
132 return STATUS_DEVICE_DATA_ERROR
;
136 Size
= StringDescriptor
->bLength
+ sizeof(WCHAR
);
139 Buffer
= AllocateItem(NonPagedPool
, Size
);
143 FreeItem(StringDescriptor
);
144 return STATUS_INSUFFICIENT_RESOURCES
;
148 RtlCopyMemory(Buffer
, StringDescriptor
->bString
, Size
- FIELD_OFFSET(USB_STRING_DESCRIPTOR
, bString
));
151 FreeItem(StringDescriptor
);
154 *OutDescriptor
= (PVOID
)Buffer
;
155 return STATUS_SUCCESS
;
160 USBCCGP_GetDescriptors(
161 IN PDEVICE_OBJECT DeviceObject
)
164 PFDO_DEVICE_EXTENSION DeviceExtension
;
165 USHORT DescriptorLength
;
168 // get device extension
170 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
173 // first get device descriptor
175 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_DEVICE_DESCRIPTOR_TYPE
, sizeof(USB_DEVICE_DESCRIPTOR
), 0, 0, (PVOID
*)&DeviceExtension
->DeviceDescriptor
);
176 if (!NT_SUCCESS(Status
))
179 // failed to get device descriptor
181 DeviceExtension
->DeviceDescriptor
= NULL
;
186 // now get basic configuration descriptor
188 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, sizeof(USB_CONFIGURATION_DESCRIPTOR
), 0, 0, (PVOID
*)&DeviceExtension
->ConfigurationDescriptor
);
189 if (!NT_SUCCESS(Status
))
192 // failed to get configuration descriptor
194 FreeItem(DeviceExtension
->DeviceDescriptor
);
195 DeviceExtension
->DeviceDescriptor
= NULL
;
202 DescriptorLength
= DeviceExtension
->ConfigurationDescriptor
->wTotalLength
;
205 // release basic descriptor
207 FreeItem(DeviceExtension
->ConfigurationDescriptor
);
208 DeviceExtension
->ConfigurationDescriptor
= NULL
;
211 // allocate full descriptor
213 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, DescriptorLength
, 0, 0, (PVOID
*)&DeviceExtension
->ConfigurationDescriptor
);
214 if (!NT_SUCCESS(Status
))
217 // failed to get configuration descriptor
219 FreeItem(DeviceExtension
->DeviceDescriptor
);
220 DeviceExtension
->DeviceDescriptor
= NULL
;
227 AllocateInterfaceDescriptorsArray(
228 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
229 OUT PUSB_INTERFACE_DESCRIPTOR
**OutArray
)
231 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
233 PUSB_INTERFACE_DESCRIPTOR
*Array
;
238 Array
= AllocateItem(NonPagedPool
, sizeof(PUSB_INTERFACE_DESCRIPTOR
) * ConfigurationDescriptor
->bNumInterfaces
);
240 return STATUS_INSUFFICIENT_RESOURCES
;
243 // enumerate all interfaces
249 // find next descriptor
251 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, Count
, 0, -1, -1, -1);
252 if (!InterfaceDescriptor
)
258 Array
[Count
] = InterfaceDescriptor
;
271 return STATUS_SUCCESS
;
275 DumpFullConfigurationDescriptor(
276 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
277 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
279 PUSB_COMMON_DESCRIPTOR Descriptor
;
281 Descriptor
= (PUSB_COMMON_DESCRIPTOR
)ConfigurationDescriptor
;
283 DbgPrint("Bogus ConfigurationDescriptor Found\n");
284 DbgPrint("InterfaceCount %x\n", ConfigurationDescriptor
->bNumInterfaces
);
288 if (((ULONG_PTR
)Descriptor
) >= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
291 DbgPrint("Descriptor Type %x Length %lu Offset %lu\n", Descriptor
->bDescriptorType
, Descriptor
->bLength
, ((ULONG_PTR
)Descriptor
- (ULONG_PTR
)ConfigurationDescriptor
));
293 // check for invalid descriptors
294 if (!Descriptor
->bLength
)
296 DbgPrint("Bogus Descriptor!!!\n");
300 // advance to next descriptor
301 Descriptor
= (PUSB_COMMON_DESCRIPTOR
)((ULONG_PTR
)Descriptor
+ Descriptor
->bLength
);
311 USBCCGP_ScanConfigurationDescriptor(
312 IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension
,
313 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
315 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
316 ULONG InterfaceIndex
= 0;
317 ULONG DescriptorCount
;
322 ASSERT(ConfigurationDescriptor
);
323 ASSERT(ConfigurationDescriptor
->bNumInterfaces
);
326 // count all interface descriptors
328 DescriptorCount
= ConfigurationDescriptor
->bNumInterfaces
;
329 if (DescriptorCount
== 0)
331 DPRINT1("[USBCCGP] DescriptorCount is zero\n");
332 return STATUS_INVALID_PARAMETER
;
336 // allocate array holding the interface descriptors
338 FDODeviceExtension
->InterfaceList
= AllocateItem(NonPagedPool
, sizeof(USBD_INTERFACE_LIST_ENTRY
) * (DescriptorCount
+ 1));
339 if (!FDODeviceExtension
->InterfaceList
)
344 return STATUS_INSUFFICIENT_RESOURCES
;
348 // reset interface list count
350 FDODeviceExtension
->InterfaceListCount
= 0;
355 // parse configuration descriptor
357 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, InterfaceIndex
, -1, -1, -1, -1);
358 if (InterfaceDescriptor
)
361 // store in interface list
363 ASSERT(FDODeviceExtension
->InterfaceListCount
< DescriptorCount
);
364 FDODeviceExtension
->InterfaceList
[FDODeviceExtension
->InterfaceListCount
].InterfaceDescriptor
= InterfaceDescriptor
;
365 FDODeviceExtension
->InterfaceListCount
++;
369 DumpConfigurationDescriptor(ConfigurationDescriptor
);
370 DumpFullConfigurationDescriptor(FDODeviceExtension
, ConfigurationDescriptor
);
374 // CORE-6574 Test 3 (USB Web Cam)
376 if (FDODeviceExtension
->DeviceDescriptor
&& FDODeviceExtension
->DeviceDescriptor
->idVendor
== 0x0458 && FDODeviceExtension
->DeviceDescriptor
->idProduct
== 0x705f)
381 // move to next interface
385 }while(InterfaceIndex
< DescriptorCount
);
390 ASSERT(FDODeviceExtension
->InterfaceListCount
);
395 return STATUS_SUCCESS
;
399 DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
401 DbgPrint("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor
);
402 DbgPrint("bLength %x\n", ConfigurationDescriptor
->bLength
);
403 DbgPrint("bDescriptorType %x\n", ConfigurationDescriptor
->bDescriptorType
);
404 DbgPrint("wTotalLength %x\n", ConfigurationDescriptor
->wTotalLength
);
405 DbgPrint("bNumInterfaces %x\n", ConfigurationDescriptor
->bNumInterfaces
);
406 DbgPrint("bConfigurationValue %x\n", ConfigurationDescriptor
->bConfigurationValue
);
407 DbgPrint("iConfiguration %x\n", ConfigurationDescriptor
->iConfiguration
);
408 DbgPrint("bmAttributes %x\n", ConfigurationDescriptor
->bmAttributes
);
409 DbgPrint("MaxPower %x\n", ConfigurationDescriptor
->MaxPower
);
413 USBCCGP_SelectInterface(
414 IN PDEVICE_OBJECT DeviceObject
,
415 IN PFDO_DEVICE_EXTENSION DeviceExtension
,
416 IN ULONG InterfaceIndex
)
424 Urb
= AllocateItem(NonPagedPool
, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bNumEndpoints
));
430 return STATUS_INSUFFICIENT_RESOURCES
;
434 // now prepare interface urb
436 UsbBuildSelectInterfaceRequest(Urb
, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bNumEndpoints
), DeviceExtension
->ConfigurationHandle
, DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bInterfaceNumber
, DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bAlternateSetting
);
439 // now select the interface
441 Status
= USBCCGP_SyncUrbRequest(DeviceExtension
->NextDeviceObject
, Urb
);
446 if (NT_SUCCESS(Status
))
449 // update configuration info
451 ASSERT(Urb
->UrbSelectInterface
.Interface
.Length
== DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->Length
);
452 RtlCopyMemory(DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
, &Urb
->UrbSelectInterface
.Interface
, Urb
->UrbSelectInterface
.Interface
.Length
);
467 USBCCGP_SelectConfiguration(
468 IN PDEVICE_OBJECT DeviceObject
,
469 IN PFDO_DEVICE_EXTENSION DeviceExtension
)
471 PUSBD_INTERFACE_INFORMATION InterfaceInformation
;
477 // now scan configuration descriptors
479 Status
= USBCCGP_ScanConfigurationDescriptor(DeviceExtension
, DeviceExtension
->ConfigurationDescriptor
);
480 if (!NT_SUCCESS(Status
))
489 // now allocate the urb
491 Urb
= USBD_CreateConfigurationRequestEx(DeviceExtension
->ConfigurationDescriptor
, DeviceExtension
->InterfaceList
);
497 return STATUS_INSUFFICIENT_RESOURCES
;
503 Status
= USBCCGP_SyncUrbRequest(DeviceExtension
->NextDeviceObject
, Urb
);
504 if (!NT_SUCCESS(Status
))
507 // failed to set configuration
509 DPRINT1("USBCCGP_SyncUrbRequest failed to set interface %x\n", Status
);
515 // get interface information
517 InterfaceInformation
= &Urb
->UrbSelectConfiguration
.Interface
;
518 for(Index
= 0; Index
< DeviceExtension
->InterfaceListCount
; Index
++)
521 // allocate buffer to store interface information
523 DeviceExtension
->InterfaceList
[Index
].Interface
= AllocateItem(NonPagedPool
, InterfaceInformation
->Length
);
524 if (!DeviceExtension
->InterfaceList
[Index
].Interface
)
529 return STATUS_INSUFFICIENT_RESOURCES
;
533 // copy interface information
535 RtlCopyMemory(DeviceExtension
->InterfaceList
[Index
].Interface
, InterfaceInformation
, InterfaceInformation
->Length
);
538 // move to next interface
540 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ InterfaceInformation
->Length
);
547 DeviceExtension
->ConfigurationHandle
= Urb
->UrbSelectConfiguration
.ConfigurationHandle
;
550 // free interface list & urb