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_GetDescriptors(
100 IN PDEVICE_OBJECT DeviceObject
)
103 PFDO_DEVICE_EXTENSION DeviceExtension
;
104 USHORT DescriptorLength
;
107 // get device extension
109 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
112 // first get device descriptor
114 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_DEVICE_DESCRIPTOR_TYPE
, sizeof(USB_DEVICE_DESCRIPTOR
), 0, 0, (PVOID
*)&DeviceExtension
->DeviceDescriptor
);
115 if (!NT_SUCCESS(Status
))
118 // failed to get device descriptor
120 DeviceExtension
->DeviceDescriptor
= NULL
;
125 // now get basic configuration descriptor
127 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, sizeof(USB_CONFIGURATION_DESCRIPTOR
), 0, 0, (PVOID
*)&DeviceExtension
->ConfigurationDescriptor
);
128 if (!NT_SUCCESS(Status
))
131 // failed to get configuration descriptor
133 FreeItem(DeviceExtension
->DeviceDescriptor
);
134 DeviceExtension
->DeviceDescriptor
= NULL
;
141 DescriptorLength
= DeviceExtension
->ConfigurationDescriptor
->wTotalLength
;
144 // release basic descriptor
146 FreeItem(DeviceExtension
->ConfigurationDescriptor
);
147 DeviceExtension
->ConfigurationDescriptor
= NULL
;
150 // allocate full descriptor
152 Status
= USBCCGP_GetDescriptor(DeviceExtension
->NextDeviceObject
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, DescriptorLength
, 0, 0, (PVOID
*)&DeviceExtension
->ConfigurationDescriptor
);
153 if (!NT_SUCCESS(Status
))
156 // failed to get configuration descriptor
158 FreeItem(DeviceExtension
->DeviceDescriptor
);
159 DeviceExtension
->DeviceDescriptor
= NULL
;
167 USBCCGP_ScanConfigurationDescriptor(
168 IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension
,
169 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
171 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
172 ULONG InterfaceIndex
= 0;
177 ASSERT(ConfigurationDescriptor
);
178 ASSERT(ConfigurationDescriptor
->bNumInterfaces
);
181 // allocate array holding the interface descriptors
183 FDODeviceExtension
->InterfaceList
= AllocateItem(NonPagedPool
, sizeof(USB_CONFIGURATION_DESCRIPTOR
) * (ConfigurationDescriptor
->bNumInterfaces
+ 1));
184 if (!FDODeviceExtension
->InterfaceList
)
189 return STATUS_INSUFFICIENT_RESOURCES
;
195 // parse configuration descriptor
197 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
, ConfigurationDescriptor
, InterfaceIndex
, 0, -1, -1, -1);
198 if (InterfaceDescriptor
)
201 // store in interface list
203 FDODeviceExtension
->InterfaceList
[FDODeviceExtension
->InterfaceListCount
].InterfaceDescriptor
= InterfaceDescriptor
;
204 FDODeviceExtension
->InterfaceListCount
++;
208 // move to next interface
212 }while(InterfaceIndex
< ConfigurationDescriptor
->bNumInterfaces
);
217 ASSERT(FDODeviceExtension
->InterfaceListCount
);
222 return STATUS_SUCCESS
;
226 DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
228 DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor
);
229 DPRINT1("bLength %x\n", ConfigurationDescriptor
->bLength
);
230 DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor
->bDescriptorType
);
231 DPRINT1("wTotalLength %x\n", ConfigurationDescriptor
->wTotalLength
);
232 DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor
->bNumInterfaces
);
233 DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor
->bConfigurationValue
);
234 DPRINT1("iConfiguration %x\n", ConfigurationDescriptor
->iConfiguration
);
235 DPRINT1("bmAttributes %x\n", ConfigurationDescriptor
->bmAttributes
);
236 DPRINT1("MaxPower %x\n", ConfigurationDescriptor
->MaxPower
);
240 USBCCGP_SelectInterface(
241 IN PDEVICE_OBJECT DeviceObject
,
242 IN PFDO_DEVICE_EXTENSION DeviceExtension
,
243 IN ULONG InterfaceIndex
)
251 Urb
= AllocateItem(NonPagedPool
, sizeof(struct _URB_SELECT_INTERFACE
));
257 return STATUS_INSUFFICIENT_RESOURCES
;
261 // now prepare interface urb
263 UsbBuildSelectInterfaceRequest(Urb
, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bNumEndpoints
), DeviceExtension
->ConfigurationHandle
, DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bInterfaceNumber
, DeviceExtension
->InterfaceList
[InterfaceIndex
].InterfaceDescriptor
->bAlternateSetting
);
266 // copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ
268 RtlCopyMemory(&Urb
->UrbSelectInterface
.Interface
, DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
, DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->Length
);
271 // now select the interface
273 Status
= USBCCGP_SyncUrbRequest(DeviceExtension
->NextDeviceObject
, Urb
);
278 if (NT_SUCCESS(Status
))
281 // update configuration info
283 ASSERT(Urb
->UrbSelectInterface
.Interface
.Length
== DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->Length
);
284 RtlCopyMemory(DeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
, &Urb
->UrbSelectInterface
.Interface
, Urb
->UrbSelectInterface
.Interface
.Length
);
299 USBCCGP_SelectConfiguration(
300 IN PDEVICE_OBJECT DeviceObject
,
301 IN PFDO_DEVICE_EXTENSION DeviceExtension
)
303 PUSBD_INTERFACE_INFORMATION InterfaceInformation
;
309 // now scan configuration descriptors
311 Status
= USBCCGP_ScanConfigurationDescriptor(DeviceExtension
, DeviceExtension
->ConfigurationDescriptor
);
312 if (!NT_SUCCESS(Status
))
321 // now allocate the urb
323 Urb
= USBD_CreateConfigurationRequestEx(DeviceExtension
->ConfigurationDescriptor
, DeviceExtension
->InterfaceList
);
329 return STATUS_INSUFFICIENT_RESOURCES
;
335 Status
= USBCCGP_SyncUrbRequest(DeviceExtension
->NextDeviceObject
, Urb
);
336 if (!NT_SUCCESS(Status
))
339 // failed to set configuration
341 DPRINT1("USBCCGP_SyncUrbRequest failed to set interface %x\n", Status
);
347 // get interface information
349 InterfaceInformation
= &Urb
->UrbSelectConfiguration
.Interface
;
351 for(Index
= 0; Index
< DeviceExtension
->InterfaceListCount
; Index
++)
354 // allocate buffer to store interface information
356 DeviceExtension
->InterfaceList
[Index
].Interface
= AllocateItem(NonPagedPool
, InterfaceInformation
[Index
].Length
);
357 if (!DeviceExtension
->InterfaceList
[Index
].Interface
)
362 return STATUS_INSUFFICIENT_RESOURCES
;
366 // copy interface information
368 RtlCopyMemory(DeviceExtension
->InterfaceList
[Index
].Interface
, InterfaceInformation
, InterfaceInformation
->Length
);
374 DeviceExtension
->ConfigurationHandle
= Urb
->UrbSelectConfiguration
.ConfigurationHandle
;
377 // free interface list & urb