3 Manage Usb Descriptor List
5 Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 Free the interface setting descriptor.
22 @param Setting The descriptor to free.
26 UsbFreeInterfaceDesc (
27 IN USB_INTERFACE_SETTING
*Setting
30 USB_ENDPOINT_DESC
*Ep
;
33 if (Setting
->Endpoints
!= NULL
) {
35 // Each interface setting may have several endpoints, free them first.
37 for (Index
= 0; Index
< Setting
->Desc
.NumEndpoints
; Index
++) {
38 Ep
= Setting
->Endpoints
[Index
];
46 // Only call FreePool() if NumEndpoints > 0.
48 if (Setting
->Desc
.NumEndpoints
> 0) {
49 FreePool (Setting
->Endpoints
);
58 Free a configuration descriptor with its interface
59 descriptors. It may be initialized partially.
61 @param Config The configuration descriptor to free.
66 IN USB_CONFIG_DESC
*Config
69 USB_INTERFACE_DESC
*Interface
;
73 if (Config
->Interfaces
!= NULL
) {
75 // A configuration may have several interfaces, free the interface
77 for (Index
= 0; Index
< Config
->Desc
.NumInterfaces
; Index
++) {
78 Interface
= Config
->Interfaces
[Index
];
80 if (Interface
== NULL
) {
85 // Each interface may have several settings, free the settings
87 for (SetIndex
= 0; SetIndex
< Interface
->NumOfSetting
; SetIndex
++) {
88 if (Interface
->Settings
[SetIndex
] != NULL
) {
89 UsbFreeInterfaceDesc (Interface
->Settings
[SetIndex
]);
96 FreePool (Config
->Interfaces
);
105 Free a device descriptor with its configurations.
107 @param DevDesc The device descriptor.
112 IN USB_DEVICE_DESC
*DevDesc
117 if (DevDesc
->Configs
!= NULL
) {
118 for (Index
= 0; Index
< DevDesc
->Desc
.NumConfigurations
; Index
++) {
119 if (DevDesc
->Configs
[Index
] != NULL
) {
120 UsbFreeConfigDesc (DevDesc
->Configs
[Index
]);
124 FreePool (DevDesc
->Configs
);
134 @param DescBuf The buffer of raw descriptor.
135 @param Len The length of the raw descriptor buffer.
136 @param Type The type of descriptor to create.
137 @param Consumed Number of bytes consumed.
139 @return Created descriptor or NULL.
161 case USB_DESC_TYPE_DEVICE
:
162 DescLen
= sizeof (EFI_USB_DEVICE_DESCRIPTOR
);
163 CtrlLen
= sizeof (USB_DEVICE_DESC
);
166 case USB_DESC_TYPE_CONFIG
:
167 DescLen
= sizeof (EFI_USB_CONFIG_DESCRIPTOR
);
168 CtrlLen
= sizeof (USB_CONFIG_DESC
);
171 case USB_DESC_TYPE_INTERFACE
:
172 DescLen
= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
);
173 CtrlLen
= sizeof (USB_INTERFACE_SETTING
);
176 case USB_DESC_TYPE_ENDPOINT
:
177 DescLen
= sizeof (EFI_USB_ENDPOINT_DESCRIPTOR
);
178 CtrlLen
= sizeof (USB_ENDPOINT_DESC
);
183 // All the descriptor has a common LTV (Length, Type, Value)
184 // format. Skip the descriptor that isn't of this Type
187 Head
= (USB_DESC_HEAD
*)DescBuf
;
189 while ((Offset
< Len
) && (Head
->Type
!= Type
)) {
192 DEBUG (( EFI_D_ERROR
, "UsbCreateDesc: met mal-format descriptor, Beyond boundary!\n"));
195 Head
= (USB_DESC_HEAD
*)(DescBuf
+ Offset
);
196 if (Head
->Len
== 0) {
197 DEBUG (( EFI_D_ERROR
, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
202 if ((Len
<= Offset
) || (Len
< Offset
+ DescLen
) ||
203 (Head
->Type
!= Type
) || (Head
->Len
!= DescLen
)) {
204 DEBUG (( EFI_D_ERROR
, "UsbCreateDesc: met mal-format descriptor\n"));
208 Desc
= AllocateZeroPool ((UINTN
) CtrlLen
);
213 CopyMem (Desc
, Head
, (UINTN
) DescLen
);
215 *Consumed
= Offset
+ Head
->Len
;
222 Parse an interface descriptor and its endpoints.
224 @param DescBuf The buffer of raw descriptor.
225 @param Len The length of the raw descriptor buffer.
226 @param Consumed The number of raw descriptor consumed.
228 @return The create interface setting or NULL if failed.
231 USB_INTERFACE_SETTING
*
232 UsbParseInterfaceDesc (
238 USB_INTERFACE_SETTING
*Setting
;
239 USB_ENDPOINT_DESC
*Ep
;
246 Setting
= UsbCreateDesc (DescBuf
, Len
, USB_DESC_TYPE_INTERFACE
, &Used
);
248 if (Setting
== NULL
) {
249 DEBUG (( EFI_D_ERROR
, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));
256 // Create an array to hold the interface's endpoints
258 NumEp
= Setting
->Desc
.NumEndpoints
;
260 DEBUG (( EFI_D_INFO
, "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",
261 Setting
->Desc
.InterfaceNumber
, Setting
->Desc
.AlternateSetting
, (UINT32
)NumEp
));
267 Setting
->Endpoints
= AllocateZeroPool (sizeof (USB_ENDPOINT_DESC
*) * NumEp
);
269 if (Setting
->Endpoints
== NULL
) {
274 // Create the endpoints for this interface
276 for (Index
= 0; (Index
< NumEp
) && (Offset
< Len
); Index
++) {
277 Ep
= UsbCreateDesc (DescBuf
+ Offset
, Len
- Offset
, USB_DESC_TYPE_ENDPOINT
, &Used
);
280 DEBUG (( EFI_D_ERROR
, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32
)Index
));
284 Setting
->Endpoints
[Index
] = Ep
;
294 UsbFreeInterfaceDesc (Setting
);
300 Parse the configuration descriptor and its interfaces.
302 @param DescBuf The buffer of raw descriptor.
303 @param Len The length of the raw descriptor buffer.
305 @return The created configuration descriptor.
314 USB_CONFIG_DESC
*Config
;
315 USB_INTERFACE_SETTING
*Setting
;
316 USB_INTERFACE_DESC
*Interface
;
321 ASSERT (DescBuf
!= NULL
);
323 Config
= UsbCreateDesc (DescBuf
, Len
, USB_DESC_TYPE_CONFIG
, &Consumed
);
325 if (Config
== NULL
) {
330 // Initialize an array of setting for the configuration's interfaces.
332 NumIf
= Config
->Desc
.NumInterfaces
;
333 Config
->Interfaces
= AllocateZeroPool (sizeof (USB_INTERFACE_DESC
*) * NumIf
);
335 if (Config
->Interfaces
== NULL
) {
339 DEBUG (( EFI_D_INFO
, "UsbParseConfigDesc: config %d has %d interfaces\n",
340 Config
->Desc
.ConfigurationValue
, (UINT32
)NumIf
));
342 for (Index
= 0; Index
< NumIf
; Index
++) {
343 Interface
= AllocateZeroPool (sizeof (USB_INTERFACE_DESC
));
345 if (Interface
== NULL
) {
349 Config
->Interfaces
[Index
] = Interface
;
353 // If a configuration has several interfaces, these interfaces are
354 // numbered from zero to n. If a interface has several settings,
355 // these settings are also number from zero to m. The interface
356 // setting must be organized as |interface 0, setting 0|interface 0
357 // setting 1|interface 1, setting 0|interface 2, setting 0|. Check
358 // USB2.0 spec, page 267.
364 // Make allowances for devices that return extra data at the
365 // end of their config descriptors
367 while (Len
>= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
)) {
368 Setting
= UsbParseInterfaceDesc (DescBuf
, Len
, &Consumed
);
370 if (Setting
== NULL
) {
371 DEBUG (( EFI_D_ERROR
, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));
374 } else if (Setting
->Desc
.InterfaceNumber
>= NumIf
) {
375 DEBUG (( EFI_D_ERROR
, "UsbParseConfigDesc: mal-formated interface descriptor\n"));
377 UsbFreeInterfaceDesc (Setting
);
382 // Insert the descriptor to the corresponding set.
384 Interface
= Config
->Interfaces
[Setting
->Desc
.InterfaceNumber
];
386 if (Interface
->NumOfSetting
>= USB_MAX_INTERFACE_SETTING
) {
390 Interface
->Settings
[Interface
->NumOfSetting
] = Setting
;
391 Interface
->NumOfSetting
++;
400 UsbFreeConfigDesc (Config
);
406 USB standard control transfer support routine. This
407 function is used by USB device. It is possible that
408 the device's interfaces are still waiting to be
411 @param UsbDev The usb device.
412 @param Direction The direction of data transfer.
413 @param Type Standard / class specific / vendor specific.
414 @param Target The receiving target.
415 @param Request Which request.
416 @param Value The wValue parameter of the request.
417 @param Index The wIndex parameter of the request.
418 @param Buf The buffer to receive data into / transmit from.
419 @param Length The length of the buffer.
421 @retval EFI_SUCCESS The control request is executed.
422 @retval EFI_DEVICE_ERROR Failed to execute the control transfer.
427 IN USB_DEVICE
*UsbDev
,
428 IN EFI_USB_DATA_DIRECTION Direction
,
438 EFI_USB_DEVICE_REQUEST DevReq
;
443 ASSERT ((UsbDev
!= NULL
) && (UsbDev
->Bus
!= NULL
));
445 DevReq
.RequestType
= USB_REQUEST_TYPE (Direction
, Type
, Target
);
446 DevReq
.Request
= (UINT8
) Request
;
447 DevReq
.Value
= Value
;
448 DevReq
.Index
= Index
;
449 DevReq
.Length
= (UINT16
) Length
;
452 Status
= UsbHcControlTransfer (
461 USB_GENERAL_DEVICE_REQUEST_TIMEOUT
,
471 Get the standard descriptors.
473 @param UsbDev The USB device to read descriptor from.
474 @param DescType The type of descriptor to read.
475 @param DescIndex The index of descriptor to read.
476 @param LangId Language ID, only used to get string, otherwise set
478 @param Buf The buffer to hold the descriptor read.
479 @param Length The length of the buffer.
481 @retval EFI_SUCCESS The descriptor is read OK.
482 @retval Others Failed to retrieve the descriptor.
487 IN USB_DEVICE
*UsbDev
,
497 Status
= UsbCtrlRequest (
500 USB_REQ_TYPE_STANDARD
,
502 USB_REQ_GET_DESCRIPTOR
,
503 (UINT16
) ((DescType
<< 8) | DescIndex
),
514 Return the max packet size for endpoint zero. This function
515 is the first function called to get descriptors during bus
518 @param UsbDev The usb device.
520 @retval EFI_SUCCESS The max packet size of endpoint zero is retrieved.
521 @retval EFI_DEVICE_ERROR Failed to retrieve it.
525 UsbGetMaxPacketSize0 (
526 IN USB_DEVICE
*UsbDev
529 EFI_USB_DEVICE_DESCRIPTOR DevDesc
;
535 // Get the first 8 bytes of the device descriptor which contains
536 // max packet size for endpoint 0, which is at least 8.
538 for (Index
= 0; Index
< 3; Index
++) {
539 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_DEVICE
, 0, 0, &DevDesc
, 8);
541 if (!EFI_ERROR (Status
)) {
542 if ((DevDesc
.BcdUSB
>= 0x0300) && (DevDesc
.MaxPacketSize0
== 9)) {
543 UsbDev
->MaxPacket0
= 1 << 9;
546 UsbDev
->MaxPacket0
= DevDesc
.MaxPacketSize0
;
550 gBS
->Stall (USB_RETRY_MAX_PACK_SIZE_STALL
);
553 return EFI_DEVICE_ERROR
;
558 Get the device descriptor for the device.
560 @param UsbDev The Usb device to retrieve descriptor from.
562 @retval EFI_SUCCESS The device descriptor is returned.
563 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
568 IN USB_DEVICE
*UsbDev
571 USB_DEVICE_DESC
*DevDesc
;
574 DevDesc
= AllocateZeroPool (sizeof (USB_DEVICE_DESC
));
576 if (DevDesc
== NULL
) {
577 return EFI_OUT_OF_RESOURCES
;
580 Status
= UsbCtrlGetDesc (
582 USB_DESC_TYPE_DEVICE
,
586 sizeof (EFI_USB_DEVICE_DESCRIPTOR
)
589 if (EFI_ERROR (Status
)) {
590 gBS
->FreePool (DevDesc
);
592 UsbDev
->DevDesc
= DevDesc
;
600 Retrieve the indexed string for the language. It requires two
601 steps to get a string, first to get the string's length. Then
604 @param UsbDev The usb device.
605 @param Index The index the string to retrieve.
606 @param LangId Language ID.
608 @return The created string descriptor or NULL.
611 EFI_USB_STRING_DESCRIPTOR
*
613 IN USB_DEVICE
*UsbDev
,
618 EFI_USB_STRING_DESCRIPTOR Desc
;
623 // First get two bytes which contains the string length.
625 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_STRING
, Index
, LangId
, &Desc
, 2);
627 if (EFI_ERROR (Status
)) {
631 Buf
= AllocateZeroPool (Desc
.Length
);
637 Status
= UsbCtrlGetDesc (
639 USB_DESC_TYPE_STRING
,
646 if (EFI_ERROR (Status
)) {
651 return (EFI_USB_STRING_DESCRIPTOR
*) Buf
;
656 Build the language ID table for string descriptors.
658 @param UsbDev The Usb device.
660 @retval EFI_UNSUPPORTED This device doesn't support string table.
665 IN USB_DEVICE
*UsbDev
668 EFI_USB_STRING_DESCRIPTOR
*Desc
;
675 // The string of language ID zero returns the supported languages
677 Desc
= UsbGetOneString (UsbDev
, 0, 0);
680 return EFI_UNSUPPORTED
;
683 if (Desc
->Length
< 4) {
684 Status
= EFI_UNSUPPORTED
;
688 Status
= EFI_SUCCESS
;
690 Max
= (Desc
->Length
- 2) / 2;
691 Max
= MIN(Max
, USB_MAX_LANG_ID
);
693 Point
= Desc
->String
;
694 for (Index
= 0; Index
< Max
; Index
++) {
695 UsbDev
->LangId
[Index
] = *Point
;
699 UsbDev
->TotalLangId
= (UINT16
)Max
;
702 gBS
->FreePool (Desc
);
708 Retrieve the indexed configure for the device. USB device
709 returns the configuration together with the interfaces for
710 this configuration. Configuration descriptor is also of
713 @param UsbDev The Usb interface.
714 @param Index The index of the configuration.
716 @return The created configuration descriptor.
719 EFI_USB_CONFIG_DESCRIPTOR
*
721 IN USB_DEVICE
*UsbDev
,
725 EFI_USB_CONFIG_DESCRIPTOR Desc
;
730 // First get four bytes which contains the total length
731 // for this configuration.
733 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_CONFIG
, Index
, 0, &Desc
, 8);
735 if (EFI_ERROR (Status
)) {
736 DEBUG (( EFI_D_ERROR
, "UsbGetOneConfig: failed to get descript length(%d) %r\n",
737 Desc
.TotalLength
, Status
));
742 DEBUG (( EFI_D_INFO
, "UsbGetOneConfig: total length is %d\n", Desc
.TotalLength
));
744 Buf
= AllocateZeroPool (Desc
.TotalLength
);
750 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_CONFIG
, Index
, 0, Buf
, Desc
.TotalLength
);
752 if (EFI_ERROR (Status
)) {
753 DEBUG (( EFI_D_ERROR
, "UsbGetOneConfig: failed to get full descript %r\n", Status
));
764 Build the whole array of descriptors. This function must
765 be called after UsbGetMaxPacketSize0 returns the max packet
766 size correctly for endpoint 0.
768 @param UsbDev The Usb device.
770 @retval EFI_SUCCESS The descriptor table is build.
771 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the descriptor.
776 IN USB_DEVICE
*UsbDev
779 EFI_USB_CONFIG_DESCRIPTOR
*Config
;
780 USB_DEVICE_DESC
*DevDesc
;
781 USB_CONFIG_DESC
*ConfigDesc
;
787 // Get the device descriptor, then allocate the configure
788 // descriptor pointer array to hold configurations.
790 Status
= UsbGetDevDesc (UsbDev
);
792 if (EFI_ERROR (Status
)) {
793 DEBUG (( EFI_D_ERROR
, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status
));
797 DevDesc
= UsbDev
->DevDesc
;
798 NumConfig
= DevDesc
->Desc
.NumConfigurations
;
799 if (NumConfig
== 0) {
800 return EFI_DEVICE_ERROR
;
803 DevDesc
->Configs
= AllocateZeroPool (NumConfig
* sizeof (USB_CONFIG_DESC
*));
804 if (DevDesc
->Configs
== NULL
) {
805 return EFI_OUT_OF_RESOURCES
;
808 DEBUG (( EFI_D_INFO
, "UsbBuildDescTable: device has %d configures\n", NumConfig
));
811 // Read each configurations, then parse them
813 for (Index
= 0; Index
< NumConfig
; Index
++) {
814 Config
= UsbGetOneConfig (UsbDev
, Index
);
816 if (Config
== NULL
) {
817 DEBUG (( EFI_D_ERROR
, "UsbBuildDescTable: failed to get configure (index %d)\n", Index
));
820 // If we can get the default descriptor, it is likely that the
821 // device is still operational.
824 return EFI_DEVICE_ERROR
;
830 ConfigDesc
= UsbParseConfigDesc ((UINT8
*) Config
, Config
->TotalLength
);
834 if (ConfigDesc
== NULL
) {
835 DEBUG (( EFI_D_ERROR
, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index
));
838 // If we can get the default descriptor, it is likely that the
839 // device is still operational.
842 return EFI_DEVICE_ERROR
;
848 DevDesc
->Configs
[Index
] = ConfigDesc
;
852 // Don't return error even this function failed because
853 // it is possible for the device to not support strings.
855 Status
= UsbBuildLangTable (UsbDev
);
857 if (EFI_ERROR (Status
)) {
858 DEBUG (( EFI_D_INFO
, "UsbBuildDescTable: get language ID table %r\n", Status
));
866 Set the device's address.
868 @param UsbDev The device to set address to.
869 @param Address The address to set.
871 @retval EFI_SUCCESS The device is set to the address.
872 @retval Others Failed to set the device address.
877 IN USB_DEVICE
*UsbDev
,
883 Status
= UsbCtrlRequest (
886 USB_REQ_TYPE_STANDARD
,
900 Set the device's configuration. This function changes
901 the device's internal state. UsbSelectConfig changes
902 the Usb bus's internal state.
904 @param UsbDev The USB device to set configure to.
905 @param ConfigIndex The configure index to set.
907 @retval EFI_SUCCESS The device is configured now.
908 @retval Others Failed to set the device configure.
913 IN USB_DEVICE
*UsbDev
,
919 Status
= UsbCtrlRequest (
922 USB_REQ_TYPE_STANDARD
,
936 Usb UsbIo interface to clear the feature. This is should
937 only be used by HUB which is considered a device driver
938 on top of the UsbIo interface.
940 @param UsbIo The UsbIo interface.
941 @param Target The target of the transfer: endpoint/device.
942 @param Feature The feature to clear.
943 @param Index The wIndex parameter.
945 @retval EFI_SUCCESS The device feature is cleared.
946 @retval Others Failed to clear the feature.
951 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
957 EFI_USB_DEVICE_REQUEST DevReq
;
961 DevReq
.RequestType
= USB_REQUEST_TYPE (EfiUsbNoData
, USB_REQ_TYPE_STANDARD
, Target
);
962 DevReq
.Request
= USB_REQ_CLEAR_FEATURE
;
963 DevReq
.Value
= Feature
;
964 DevReq
.Index
= Index
;
967 Status
= UsbIo
->UsbControlTransfer (
971 USB_CLEAR_FEATURE_REQUEST_TIMEOUT
,