3 Manage Usb Descriptor List
5 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
14 Free the interface setting descriptor.
16 @param Setting The descriptor to free.
20 UsbFreeInterfaceDesc (
21 IN USB_INTERFACE_SETTING
*Setting
24 USB_ENDPOINT_DESC
*Ep
;
27 if (Setting
->Endpoints
!= NULL
) {
29 // Each interface setting may have several endpoints, free them first.
31 for (Index
= 0; Index
< Setting
->Desc
.NumEndpoints
; Index
++) {
32 Ep
= Setting
->Endpoints
[Index
];
40 // Only call FreePool() if NumEndpoints > 0.
42 if (Setting
->Desc
.NumEndpoints
> 0) {
43 FreePool (Setting
->Endpoints
);
52 Free a configuration descriptor with its interface
53 descriptors. It may be initialized partially.
55 @param Config The configuration descriptor to free.
60 IN USB_CONFIG_DESC
*Config
63 USB_INTERFACE_DESC
*Interface
;
67 if (Config
->Interfaces
!= NULL
) {
69 // A configuration may have several interfaces, free the interface
71 for (Index
= 0; Index
< Config
->Desc
.NumInterfaces
; Index
++) {
72 Interface
= Config
->Interfaces
[Index
];
74 if (Interface
== NULL
) {
79 // Each interface may have several settings, free the settings
81 for (SetIndex
= 0; SetIndex
< Interface
->NumOfSetting
; SetIndex
++) {
82 if (Interface
->Settings
[SetIndex
] != NULL
) {
83 UsbFreeInterfaceDesc (Interface
->Settings
[SetIndex
]);
90 FreePool (Config
->Interfaces
);
99 Free a device descriptor with its configurations.
101 @param DevDesc The device descriptor.
106 IN USB_DEVICE_DESC
*DevDesc
111 if (DevDesc
->Configs
!= NULL
) {
112 for (Index
= 0; Index
< DevDesc
->Desc
.NumConfigurations
; Index
++) {
113 if (DevDesc
->Configs
[Index
] != NULL
) {
114 UsbFreeConfigDesc (DevDesc
->Configs
[Index
]);
118 FreePool (DevDesc
->Configs
);
128 @param DescBuf The buffer of raw descriptor.
129 @param Len The length of the raw descriptor buffer.
130 @param Type The type of descriptor to create.
131 @param Consumed Number of bytes consumed.
133 @return Created descriptor or NULL.
155 case USB_DESC_TYPE_DEVICE
:
156 DescLen
= sizeof (EFI_USB_DEVICE_DESCRIPTOR
);
157 CtrlLen
= sizeof (USB_DEVICE_DESC
);
160 case USB_DESC_TYPE_CONFIG
:
161 DescLen
= sizeof (EFI_USB_CONFIG_DESCRIPTOR
);
162 CtrlLen
= sizeof (USB_CONFIG_DESC
);
165 case USB_DESC_TYPE_INTERFACE
:
166 DescLen
= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
);
167 CtrlLen
= sizeof (USB_INTERFACE_SETTING
);
170 case USB_DESC_TYPE_ENDPOINT
:
171 DescLen
= sizeof (EFI_USB_ENDPOINT_DESCRIPTOR
);
172 CtrlLen
= sizeof (USB_ENDPOINT_DESC
);
181 // Total length is too small that cannot hold the single descriptor header plus data.
183 if (Len
<= sizeof (USB_DESC_HEAD
)) {
184 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len
));
189 // All the descriptor has a common LTV (Length, Type, Value)
190 // format. Skip the descriptor that isn't of this Type
193 Head
= (USB_DESC_HEAD
*)DescBuf
;
194 while (Offset
< Len
- sizeof (USB_DESC_HEAD
)) {
196 // Above condition make sure Head->Len and Head->Type are safe to access
198 Head
= (USB_DESC_HEAD
*)&DescBuf
[Offset
];
200 if (Head
->Len
== 0) {
201 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
206 // Make sure no overflow when adding Head->Len to Offset.
208 if (Head
->Len
> MAX_UINTN
- Offset
) {
209 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head
->Len
));
215 if (Head
->Type
== Type
) {
221 // Head->Len is invalid resulting data beyond boundary, or
222 // Descriptor cannot be found: No such type.
225 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset
, Len
));
229 if ((Head
->Type
!= Type
) || (Head
->Len
< DescLen
)) {
230 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head
->Type
, Head
->Len
));
234 Desc
= AllocateZeroPool ((UINTN
) CtrlLen
);
239 CopyMem (Desc
, Head
, (UINTN
) DescLen
);
248 Parse an interface descriptor and its endpoints.
250 @param DescBuf The buffer of raw descriptor.
251 @param Len The length of the raw descriptor buffer.
252 @param Consumed The number of raw descriptor consumed.
254 @return The create interface setting or NULL if failed.
257 USB_INTERFACE_SETTING
*
258 UsbParseInterfaceDesc (
264 USB_INTERFACE_SETTING
*Setting
;
265 USB_ENDPOINT_DESC
*Ep
;
272 Setting
= UsbCreateDesc (DescBuf
, Len
, USB_DESC_TYPE_INTERFACE
, &Used
);
274 if (Setting
== NULL
) {
275 DEBUG (( EFI_D_ERROR
, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));
282 // Create an array to hold the interface's endpoints
284 NumEp
= Setting
->Desc
.NumEndpoints
;
286 DEBUG (( EFI_D_INFO
, "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",
287 Setting
->Desc
.InterfaceNumber
, Setting
->Desc
.AlternateSetting
, (UINT32
)NumEp
));
293 Setting
->Endpoints
= AllocateZeroPool (sizeof (USB_ENDPOINT_DESC
*) * NumEp
);
295 if (Setting
->Endpoints
== NULL
) {
300 // Create the endpoints for this interface
302 for (Index
= 0; (Index
< NumEp
) && (Offset
< Len
); Index
++) {
303 Ep
= UsbCreateDesc (DescBuf
+ Offset
, Len
- Offset
, USB_DESC_TYPE_ENDPOINT
, &Used
);
306 DEBUG (( EFI_D_ERROR
, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32
)Index
));
310 Setting
->Endpoints
[Index
] = Ep
;
320 UsbFreeInterfaceDesc (Setting
);
326 Parse the configuration descriptor and its interfaces.
328 @param DescBuf The buffer of raw descriptor.
329 @param Len The length of the raw descriptor buffer.
331 @return The created configuration descriptor.
340 USB_CONFIG_DESC
*Config
;
341 USB_INTERFACE_SETTING
*Setting
;
342 USB_INTERFACE_DESC
*Interface
;
347 ASSERT (DescBuf
!= NULL
);
349 Config
= UsbCreateDesc (DescBuf
, Len
, USB_DESC_TYPE_CONFIG
, &Consumed
);
351 if (Config
== NULL
) {
356 // Initialize an array of setting for the configuration's interfaces.
358 NumIf
= Config
->Desc
.NumInterfaces
;
359 Config
->Interfaces
= AllocateZeroPool (sizeof (USB_INTERFACE_DESC
*) * NumIf
);
361 if (Config
->Interfaces
== NULL
) {
365 DEBUG (( EFI_D_INFO
, "UsbParseConfigDesc: config %d has %d interfaces\n",
366 Config
->Desc
.ConfigurationValue
, (UINT32
)NumIf
));
368 for (Index
= 0; Index
< NumIf
; Index
++) {
369 Interface
= AllocateZeroPool (sizeof (USB_INTERFACE_DESC
));
371 if (Interface
== NULL
) {
375 Config
->Interfaces
[Index
] = Interface
;
379 // If a configuration has several interfaces, these interfaces are
380 // numbered from zero to n. If a interface has several settings,
381 // these settings are also number from zero to m. The interface
382 // setting must be organized as |interface 0, setting 0|interface 0
383 // setting 1|interface 1, setting 0|interface 2, setting 0|. Check
384 // USB2.0 spec, page 267.
390 // Make allowances for devices that return extra data at the
391 // end of their config descriptors
393 while (Len
>= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
)) {
394 Setting
= UsbParseInterfaceDesc (DescBuf
, Len
, &Consumed
);
396 if (Setting
== NULL
) {
397 DEBUG (( EFI_D_ERROR
, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));
400 } else if (Setting
->Desc
.InterfaceNumber
>= NumIf
) {
401 DEBUG (( EFI_D_ERROR
, "UsbParseConfigDesc: mal-formated interface descriptor\n"));
403 UsbFreeInterfaceDesc (Setting
);
408 // Insert the descriptor to the corresponding set.
410 Interface
= Config
->Interfaces
[Setting
->Desc
.InterfaceNumber
];
412 if (Interface
->NumOfSetting
>= USB_MAX_INTERFACE_SETTING
) {
416 Interface
->Settings
[Interface
->NumOfSetting
] = Setting
;
417 Interface
->NumOfSetting
++;
426 UsbFreeConfigDesc (Config
);
432 USB standard control transfer support routine. This
433 function is used by USB device. It is possible that
434 the device's interfaces are still waiting to be
437 @param UsbDev The usb device.
438 @param Direction The direction of data transfer.
439 @param Type Standard / class specific / vendor specific.
440 @param Target The receiving target.
441 @param Request Which request.
442 @param Value The wValue parameter of the request.
443 @param Index The wIndex parameter of the request.
444 @param Buf The buffer to receive data into / transmit from.
445 @param Length The length of the buffer.
447 @retval EFI_SUCCESS The control request is executed.
448 @retval EFI_DEVICE_ERROR Failed to execute the control transfer.
453 IN USB_DEVICE
*UsbDev
,
454 IN EFI_USB_DATA_DIRECTION Direction
,
464 EFI_USB_DEVICE_REQUEST DevReq
;
469 ASSERT ((UsbDev
!= NULL
) && (UsbDev
->Bus
!= NULL
));
471 DevReq
.RequestType
= USB_REQUEST_TYPE (Direction
, Type
, Target
);
472 DevReq
.Request
= (UINT8
) Request
;
473 DevReq
.Value
= Value
;
474 DevReq
.Index
= Index
;
475 DevReq
.Length
= (UINT16
) Length
;
478 Status
= UsbHcControlTransfer (
487 USB_GENERAL_DEVICE_REQUEST_TIMEOUT
,
497 Get the standard descriptors.
499 @param UsbDev The USB device to read descriptor from.
500 @param DescType The type of descriptor to read.
501 @param DescIndex The index of descriptor to read.
502 @param LangId Language ID, only used to get string, otherwise set
504 @param Buf The buffer to hold the descriptor read.
505 @param Length The length of the buffer.
507 @retval EFI_SUCCESS The descriptor is read OK.
508 @retval Others Failed to retrieve the descriptor.
513 IN USB_DEVICE
*UsbDev
,
523 Status
= UsbCtrlRequest (
526 USB_REQ_TYPE_STANDARD
,
528 USB_REQ_GET_DESCRIPTOR
,
529 (UINT16
) ((DescType
<< 8) | DescIndex
),
540 Return the max packet size for endpoint zero. This function
541 is the first function called to get descriptors during bus
544 @param UsbDev The usb device.
546 @retval EFI_SUCCESS The max packet size of endpoint zero is retrieved.
547 @retval EFI_DEVICE_ERROR Failed to retrieve it.
551 UsbGetMaxPacketSize0 (
552 IN USB_DEVICE
*UsbDev
555 EFI_USB_DEVICE_DESCRIPTOR DevDesc
;
561 // Get the first 8 bytes of the device descriptor which contains
562 // max packet size for endpoint 0, which is at least 8.
564 for (Index
= 0; Index
< 3; Index
++) {
565 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_DEVICE
, 0, 0, &DevDesc
, 8);
567 if (!EFI_ERROR (Status
)) {
568 if ((DevDesc
.BcdUSB
>= 0x0300) && (DevDesc
.MaxPacketSize0
== 9)) {
569 UsbDev
->MaxPacket0
= 1 << 9;
572 UsbDev
->MaxPacket0
= DevDesc
.MaxPacketSize0
;
576 gBS
->Stall (USB_RETRY_MAX_PACK_SIZE_STALL
);
579 return EFI_DEVICE_ERROR
;
584 Get the device descriptor for the device.
586 @param UsbDev The Usb device to retrieve descriptor from.
588 @retval EFI_SUCCESS The device descriptor is returned.
589 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
594 IN USB_DEVICE
*UsbDev
597 USB_DEVICE_DESC
*DevDesc
;
600 DevDesc
= AllocateZeroPool (sizeof (USB_DEVICE_DESC
));
602 if (DevDesc
== NULL
) {
603 return EFI_OUT_OF_RESOURCES
;
606 Status
= UsbCtrlGetDesc (
608 USB_DESC_TYPE_DEVICE
,
612 sizeof (EFI_USB_DEVICE_DESCRIPTOR
)
615 if (EFI_ERROR (Status
)) {
616 gBS
->FreePool (DevDesc
);
618 UsbDev
->DevDesc
= DevDesc
;
626 Retrieve the indexed string for the language. It requires two
627 steps to get a string, first to get the string's length. Then
630 @param UsbDev The usb device.
631 @param Index The index the string to retrieve.
632 @param LangId Language ID.
634 @return The created string descriptor or NULL.
637 EFI_USB_STRING_DESCRIPTOR
*
639 IN USB_DEVICE
*UsbDev
,
644 EFI_USB_STRING_DESCRIPTOR Desc
;
649 // First get two bytes which contains the string length.
651 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_STRING
, Index
, LangId
, &Desc
, 2);
654 // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even.
656 if (EFI_ERROR (Status
) ||
657 (Desc
.Length
< OFFSET_OF (EFI_USB_STRING_DESCRIPTOR
, Length
) + sizeof (Desc
.Length
)) ||
658 (Desc
.Length
% 2 != 0)
663 Buf
= AllocateZeroPool (Desc
.Length
);
669 Status
= UsbCtrlGetDesc (
671 USB_DESC_TYPE_STRING
,
678 if (EFI_ERROR (Status
)) {
683 return (EFI_USB_STRING_DESCRIPTOR
*) Buf
;
688 Build the language ID table for string descriptors.
690 @param UsbDev The Usb device.
692 @retval EFI_UNSUPPORTED This device doesn't support string table.
697 IN USB_DEVICE
*UsbDev
700 EFI_USB_STRING_DESCRIPTOR
*Desc
;
707 // The string of language ID zero returns the supported languages
709 Desc
= UsbGetOneString (UsbDev
, 0, 0);
712 return EFI_UNSUPPORTED
;
715 if (Desc
->Length
< 4) {
716 Status
= EFI_UNSUPPORTED
;
720 Status
= EFI_SUCCESS
;
722 Max
= (Desc
->Length
- 2) / 2;
723 Max
= MIN(Max
, USB_MAX_LANG_ID
);
725 Point
= Desc
->String
;
726 for (Index
= 0; Index
< Max
; Index
++) {
727 UsbDev
->LangId
[Index
] = *Point
;
731 UsbDev
->TotalLangId
= (UINT16
)Max
;
734 gBS
->FreePool (Desc
);
740 Retrieve the indexed configure for the device. USB device
741 returns the configuration together with the interfaces for
742 this configuration. Configuration descriptor is also of
745 @param UsbDev The Usb interface.
746 @param Index The index of the configuration.
748 @return The created configuration descriptor.
751 EFI_USB_CONFIG_DESCRIPTOR
*
753 IN USB_DEVICE
*UsbDev
,
757 EFI_USB_CONFIG_DESCRIPTOR Desc
;
762 // First get four bytes which contains the total length
763 // for this configuration.
765 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_CONFIG
, Index
, 0, &Desc
, 8);
767 if (EFI_ERROR (Status
)) {
768 DEBUG (( EFI_D_ERROR
, "UsbGetOneConfig: failed to get descript length(%d) %r\n",
769 Desc
.TotalLength
, Status
));
774 DEBUG (( EFI_D_INFO
, "UsbGetOneConfig: total length is %d\n", Desc
.TotalLength
));
777 // Reject if TotalLength even cannot cover itself.
779 if (Desc
.TotalLength
< OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR
, TotalLength
) + sizeof (Desc
.TotalLength
)) {
783 Buf
= AllocateZeroPool (Desc
.TotalLength
);
789 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_CONFIG
, Index
, 0, Buf
, Desc
.TotalLength
);
791 if (EFI_ERROR (Status
)) {
792 DEBUG (( EFI_D_ERROR
, "UsbGetOneConfig: failed to get full descript %r\n", Status
));
803 Build the whole array of descriptors. This function must
804 be called after UsbGetMaxPacketSize0 returns the max packet
805 size correctly for endpoint 0.
807 @param UsbDev The Usb device.
809 @retval EFI_SUCCESS The descriptor table is build.
810 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the descriptor.
815 IN USB_DEVICE
*UsbDev
818 EFI_USB_CONFIG_DESCRIPTOR
*Config
;
819 USB_DEVICE_DESC
*DevDesc
;
820 USB_CONFIG_DESC
*ConfigDesc
;
826 // Get the device descriptor, then allocate the configure
827 // descriptor pointer array to hold configurations.
829 Status
= UsbGetDevDesc (UsbDev
);
831 if (EFI_ERROR (Status
)) {
832 DEBUG (( EFI_D_ERROR
, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status
));
836 DevDesc
= UsbDev
->DevDesc
;
837 NumConfig
= DevDesc
->Desc
.NumConfigurations
;
838 if (NumConfig
== 0) {
839 return EFI_DEVICE_ERROR
;
842 DevDesc
->Configs
= AllocateZeroPool (NumConfig
* sizeof (USB_CONFIG_DESC
*));
843 if (DevDesc
->Configs
== NULL
) {
844 return EFI_OUT_OF_RESOURCES
;
847 DEBUG (( EFI_D_INFO
, "UsbBuildDescTable: device has %d configures\n", NumConfig
));
850 // Read each configurations, then parse them
852 for (Index
= 0; Index
< NumConfig
; Index
++) {
853 Config
= UsbGetOneConfig (UsbDev
, Index
);
855 if (Config
== NULL
) {
856 DEBUG (( EFI_D_ERROR
, "UsbBuildDescTable: failed to get configure (index %d)\n", Index
));
859 // If we can get the default descriptor, it is likely that the
860 // device is still operational.
863 return EFI_DEVICE_ERROR
;
869 ConfigDesc
= UsbParseConfigDesc ((UINT8
*) Config
, Config
->TotalLength
);
873 if (ConfigDesc
== NULL
) {
874 DEBUG (( EFI_D_ERROR
, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index
));
877 // If we can get the default descriptor, it is likely that the
878 // device is still operational.
881 return EFI_DEVICE_ERROR
;
887 DevDesc
->Configs
[Index
] = ConfigDesc
;
891 // Don't return error even this function failed because
892 // it is possible for the device to not support strings.
894 Status
= UsbBuildLangTable (UsbDev
);
896 if (EFI_ERROR (Status
)) {
897 DEBUG (( EFI_D_INFO
, "UsbBuildDescTable: get language ID table %r\n", Status
));
905 Set the device's address.
907 @param UsbDev The device to set address to.
908 @param Address The address to set.
910 @retval EFI_SUCCESS The device is set to the address.
911 @retval Others Failed to set the device address.
916 IN USB_DEVICE
*UsbDev
,
922 Status
= UsbCtrlRequest (
925 USB_REQ_TYPE_STANDARD
,
939 Set the device's configuration. This function changes
940 the device's internal state. UsbSelectConfig changes
941 the Usb bus's internal state.
943 @param UsbDev The USB device to set configure to.
944 @param ConfigIndex The configure index to set.
946 @retval EFI_SUCCESS The device is configured now.
947 @retval Others Failed to set the device configure.
952 IN USB_DEVICE
*UsbDev
,
958 Status
= UsbCtrlRequest (
961 USB_REQ_TYPE_STANDARD
,
975 Usb UsbIo interface to clear the feature. This is should
976 only be used by HUB which is considered a device driver
977 on top of the UsbIo interface.
979 @param UsbIo The UsbIo interface.
980 @param Target The target of the transfer: endpoint/device.
981 @param Feature The feature to clear.
982 @param Index The wIndex parameter.
984 @retval EFI_SUCCESS The device feature is cleared.
985 @retval Others Failed to clear the feature.
990 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
996 EFI_USB_DEVICE_REQUEST DevReq
;
1000 DevReq
.RequestType
= USB_REQUEST_TYPE (EfiUsbNoData
, USB_REQ_TYPE_STANDARD
, Target
);
1001 DevReq
.Request
= USB_REQ_CLEAR_FEATURE
;
1002 DevReq
.Value
= Feature
;
1003 DevReq
.Index
= Index
;
1006 Status
= UsbIo
->UsbControlTransfer (
1010 USB_CLEAR_FEATURE_REQUEST_TIMEOUT
,