3 Manage Usb Descriptor List
5 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Free the interface setting descriptor.
15 @param Setting The descriptor to free.
19 UsbFreeInterfaceDesc (
20 IN USB_INTERFACE_SETTING
*Setting
23 USB_ENDPOINT_DESC
*Ep
;
26 if (Setting
->Endpoints
!= NULL
) {
28 // Each interface setting may have several endpoints, free them first.
30 for (Index
= 0; Index
< Setting
->Desc
.NumEndpoints
; Index
++) {
31 Ep
= Setting
->Endpoints
[Index
];
39 // Only call FreePool() if NumEndpoints > 0.
41 if (Setting
->Desc
.NumEndpoints
> 0) {
42 FreePool (Setting
->Endpoints
);
50 Free a configuration descriptor with its interface
51 descriptors. It may be initialized partially.
53 @param Config The configuration descriptor to free.
58 IN USB_CONFIG_DESC
*Config
61 USB_INTERFACE_DESC
*Interface
;
65 if (Config
->Interfaces
!= NULL
) {
67 // A configuration may have several interfaces, free the interface
69 for (Index
= 0; Index
< Config
->Desc
.NumInterfaces
; Index
++) {
70 Interface
= Config
->Interfaces
[Index
];
72 if (Interface
== NULL
) {
77 // Each interface may have several settings, free the settings
79 for (SetIndex
= 0; SetIndex
< Interface
->NumOfSetting
; SetIndex
++) {
80 if (Interface
->Settings
[SetIndex
] != NULL
) {
81 UsbFreeInterfaceDesc (Interface
->Settings
[SetIndex
]);
88 FreePool (Config
->Interfaces
);
95 Free a device descriptor with its configurations.
97 @param DevDesc The device descriptor.
102 IN USB_DEVICE_DESC
*DevDesc
107 if (DevDesc
->Configs
!= NULL
) {
108 for (Index
= 0; Index
< DevDesc
->Desc
.NumConfigurations
; Index
++) {
109 if (DevDesc
->Configs
[Index
] != NULL
) {
110 UsbFreeConfigDesc (DevDesc
->Configs
[Index
]);
114 FreePool (DevDesc
->Configs
);
123 @param DescBuf The buffer of raw descriptor.
124 @param Len The length of the raw descriptor buffer.
125 @param Type The type of descriptor to create.
126 @param Consumed Number of bytes consumed.
128 @return Created descriptor or NULL.
150 case USB_DESC_TYPE_DEVICE
:
151 DescLen
= sizeof (EFI_USB_DEVICE_DESCRIPTOR
);
152 CtrlLen
= sizeof (USB_DEVICE_DESC
);
155 case USB_DESC_TYPE_CONFIG
:
156 DescLen
= sizeof (EFI_USB_CONFIG_DESCRIPTOR
);
157 CtrlLen
= sizeof (USB_CONFIG_DESC
);
160 case USB_DESC_TYPE_INTERFACE
:
161 DescLen
= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
);
162 CtrlLen
= sizeof (USB_INTERFACE_SETTING
);
165 case USB_DESC_TYPE_ENDPOINT
:
166 DescLen
= sizeof (EFI_USB_ENDPOINT_DESCRIPTOR
);
167 CtrlLen
= sizeof (USB_ENDPOINT_DESC
);
176 // Total length is too small that cannot hold the single descriptor header plus data.
178 if (Len
<= sizeof (USB_DESC_HEAD
)) {
179 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len
));
184 // All the descriptor has a common LTV (Length, Type, Value)
185 // format. Skip the descriptor that isn't of this Type
188 Head
= (USB_DESC_HEAD
*)DescBuf
;
189 while (Offset
< Len
- sizeof (USB_DESC_HEAD
)) {
191 // Above condition make sure Head->Len and Head->Type are safe to access
193 Head
= (USB_DESC_HEAD
*)&DescBuf
[Offset
];
195 if (Head
->Len
== 0) {
196 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
201 // Make sure no overflow when adding Head->Len to Offset.
203 if (Head
->Len
> MAX_UINTN
- Offset
) {
204 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head
->Len
));
210 if (Head
->Type
== Type
) {
216 // Head->Len is invalid resulting data beyond boundary, or
217 // Descriptor cannot be found: No such type.
220 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset
, Len
));
224 if ((Head
->Type
!= Type
) || (Head
->Len
< DescLen
)) {
225 DEBUG ((DEBUG_ERROR
, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head
->Type
, Head
->Len
));
229 Desc
= AllocateZeroPool ((UINTN
)CtrlLen
);
234 CopyMem (Desc
, Head
, (UINTN
)DescLen
);
242 Parse an interface descriptor and its endpoints.
244 @param DescBuf The buffer of raw descriptor.
245 @param Len The length of the raw descriptor buffer.
246 @param Consumed The number of raw descriptor consumed.
248 @return The create interface setting or NULL if failed.
251 USB_INTERFACE_SETTING
*
252 UsbParseInterfaceDesc (
258 USB_INTERFACE_SETTING
*Setting
;
259 USB_ENDPOINT_DESC
*Ep
;
266 Setting
= UsbCreateDesc (DescBuf
, Len
, USB_DESC_TYPE_INTERFACE
, &Used
);
268 if (Setting
== NULL
) {
269 DEBUG ((DEBUG_ERROR
, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));
276 // Create an array to hold the interface's endpoints
278 NumEp
= Setting
->Desc
.NumEndpoints
;
282 "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",
283 Setting
->Desc
.InterfaceNumber
,
284 Setting
->Desc
.AlternateSetting
,
292 Setting
->Endpoints
= AllocateZeroPool (sizeof (USB_ENDPOINT_DESC
*) * NumEp
);
294 if (Setting
->Endpoints
== NULL
) {
299 // Create the endpoints for this interface
301 for (Index
= 0; (Index
< NumEp
) && (Offset
< Len
); Index
++) {
302 Ep
= UsbCreateDesc (DescBuf
+ Offset
, Len
- Offset
, USB_DESC_TYPE_ENDPOINT
, &Used
);
305 DEBUG ((DEBUG_ERROR
, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32
)Index
));
309 Setting
->Endpoints
[Index
] = Ep
;
318 UsbFreeInterfaceDesc (Setting
);
323 Parse the configuration descriptor and its interfaces.
325 @param DescBuf The buffer of raw descriptor.
326 @param Len The length of the raw descriptor buffer.
328 @return The created configuration descriptor.
337 USB_CONFIG_DESC
*Config
;
338 USB_INTERFACE_SETTING
*Setting
;
339 USB_INTERFACE_DESC
*Interface
;
344 ASSERT (DescBuf
!= NULL
);
346 Config
= UsbCreateDesc (DescBuf
, Len
, USB_DESC_TYPE_CONFIG
, &Consumed
);
348 if (Config
== NULL
) {
353 // Initialize an array of setting for the configuration's interfaces.
355 NumIf
= Config
->Desc
.NumInterfaces
;
356 Config
->Interfaces
= AllocateZeroPool (sizeof (USB_INTERFACE_DESC
*) * NumIf
);
358 if (Config
->Interfaces
== NULL
) {
364 "UsbParseConfigDesc: config %d has %d interfaces\n",
365 Config
->Desc
.ConfigurationValue
,
369 for (Index
= 0; Index
< NumIf
; Index
++) {
370 Interface
= AllocateZeroPool (sizeof (USB_INTERFACE_DESC
));
372 if (Interface
== NULL
) {
376 Config
->Interfaces
[Index
] = Interface
;
380 // If a configuration has several interfaces, these interfaces are
381 // numbered from zero to n. If a interface has several settings,
382 // these settings are also number from zero to m. The interface
383 // setting must be organized as |interface 0, setting 0|interface 0
384 // setting 1|interface 1, setting 0|interface 2, setting 0|. Check
385 // USB2.0 spec, page 267.
391 // Make allowances for devices that return extra data at the
392 // end of their config descriptors
394 while (Len
>= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
)) {
395 Setting
= UsbParseInterfaceDesc (DescBuf
, Len
, &Consumed
);
397 if (Setting
== NULL
) {
398 DEBUG ((DEBUG_ERROR
, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));
400 } else if (Setting
->Desc
.InterfaceNumber
>= NumIf
) {
401 DEBUG ((DEBUG_ERROR
, "UsbParseConfigDesc: malformatted 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
);
431 USB standard control transfer support routine. This
432 function is used by USB device. It is possible that
433 the device's interfaces are still waiting to be
436 @param UsbDev The usb device.
437 @param Direction The direction of data transfer.
438 @param Type Standard / class specific / vendor specific.
439 @param Target The receiving target.
440 @param Request Which request.
441 @param Value The wValue parameter of the request.
442 @param Index The wIndex parameter of the request.
443 @param Buf The buffer to receive data into / transmit from.
444 @param Length The length of the buffer.
446 @retval EFI_SUCCESS The control request is executed.
447 @retval EFI_DEVICE_ERROR Failed to execute the control transfer.
452 IN USB_DEVICE
*UsbDev
,
453 IN EFI_USB_DATA_DIRECTION Direction
,
463 EFI_USB_DEVICE_REQUEST DevReq
;
468 ASSERT ((UsbDev
!= NULL
) && (UsbDev
->Bus
!= NULL
));
470 DevReq
.RequestType
= USB_REQUEST_TYPE (Direction
, Type
, Target
);
471 DevReq
.Request
= (UINT8
)Request
;
472 DevReq
.Value
= Value
;
473 DevReq
.Index
= Index
;
474 DevReq
.Length
= (UINT16
)Length
;
477 Status
= UsbHcControlTransfer (
486 USB_GENERAL_DEVICE_REQUEST_TIMEOUT
,
495 Get the standard descriptors.
497 @param UsbDev The USB device to read descriptor from.
498 @param DescType The type of descriptor to read.
499 @param DescIndex The index of descriptor to read.
500 @param LangId Language ID, only used to get string, otherwise set
502 @param Buf The buffer to hold the descriptor read.
503 @param Length The length of the buffer.
505 @retval EFI_SUCCESS The descriptor is read OK.
506 @retval Others Failed to retrieve the descriptor.
511 IN USB_DEVICE
*UsbDev
,
521 Status
= UsbCtrlRequest (
524 USB_REQ_TYPE_STANDARD
,
526 USB_REQ_GET_DESCRIPTOR
,
527 (UINT16
)((DescType
<< 8) | DescIndex
),
537 Return the max packet size for endpoint zero. This function
538 is the first function called to get descriptors during bus
541 @param UsbDev The usb device.
543 @retval EFI_SUCCESS The max packet size of endpoint zero is retrieved.
544 @retval EFI_DEVICE_ERROR Failed to retrieve it.
548 UsbGetMaxPacketSize0 (
549 IN USB_DEVICE
*UsbDev
552 EFI_USB_DEVICE_DESCRIPTOR DevDesc
;
557 // Get the first 8 bytes of the device descriptor which contains
558 // max packet size for endpoint 0, which is at least 8.
560 for (Index
= 0; Index
< 3; Index
++) {
561 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_DEVICE
, 0, 0, &DevDesc
, 8);
563 if (!EFI_ERROR (Status
)) {
564 if ((DevDesc
.BcdUSB
>= 0x0300) && (DevDesc
.MaxPacketSize0
== 9)) {
565 UsbDev
->MaxPacket0
= 1 << 9;
569 UsbDev
->MaxPacket0
= DevDesc
.MaxPacketSize0
;
573 gBS
->Stall (USB_RETRY_MAX_PACK_SIZE_STALL
);
576 return EFI_DEVICE_ERROR
;
580 Get the device descriptor for the device.
582 @param UsbDev The Usb device to retrieve descriptor from.
584 @retval EFI_SUCCESS The device descriptor is returned.
585 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
590 IN USB_DEVICE
*UsbDev
593 USB_DEVICE_DESC
*DevDesc
;
596 DevDesc
= AllocateZeroPool (sizeof (USB_DEVICE_DESC
));
598 if (DevDesc
== NULL
) {
599 return EFI_OUT_OF_RESOURCES
;
602 Status
= UsbCtrlGetDesc (
604 USB_DESC_TYPE_DEVICE
,
608 sizeof (EFI_USB_DEVICE_DESCRIPTOR
)
611 if (EFI_ERROR (Status
)) {
612 gBS
->FreePool (DevDesc
);
614 UsbDev
->DevDesc
= DevDesc
;
621 Retrieve the indexed string for the language. It requires two
622 steps to get a string, first to get the string's length. Then
625 @param UsbDev The usb device.
626 @param Index The index the string to retrieve.
627 @param LangId Language ID.
629 @return The created string descriptor or NULL.
632 EFI_USB_STRING_DESCRIPTOR
*
634 IN USB_DEVICE
*UsbDev
,
639 EFI_USB_STRING_DESCRIPTOR Desc
;
644 // First get two bytes which contains the string length.
646 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_STRING
, Index
, LangId
, &Desc
, 2);
649 // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even.
651 if (EFI_ERROR (Status
) ||
652 (Desc
.Length
< OFFSET_OF (EFI_USB_STRING_DESCRIPTOR
, Length
) + sizeof (Desc
.Length
)) ||
653 (Desc
.Length
% 2 != 0)
659 Buf
= AllocateZeroPool (Desc
.Length
);
665 Status
= UsbCtrlGetDesc (
667 USB_DESC_TYPE_STRING
,
674 if (EFI_ERROR (Status
)) {
679 return (EFI_USB_STRING_DESCRIPTOR
*)Buf
;
683 Build the language ID table for string descriptors.
685 @param UsbDev The Usb device.
687 @retval EFI_UNSUPPORTED This device doesn't support string table.
692 IN USB_DEVICE
*UsbDev
695 EFI_USB_STRING_DESCRIPTOR
*Desc
;
702 // The string of language ID zero returns the supported languages
704 Desc
= UsbGetOneString (UsbDev
, 0, 0);
707 return EFI_UNSUPPORTED
;
710 if (Desc
->Length
< 4) {
711 Status
= EFI_UNSUPPORTED
;
715 Status
= EFI_SUCCESS
;
717 Max
= (Desc
->Length
- 2) / 2;
718 Max
= MIN (Max
, USB_MAX_LANG_ID
);
720 Point
= Desc
->String
;
721 for (Index
= 0; Index
< Max
; Index
++) {
722 UsbDev
->LangId
[Index
] = *Point
;
726 UsbDev
->TotalLangId
= (UINT16
)Max
;
729 gBS
->FreePool (Desc
);
734 Retrieve the indexed configure for the device. USB device
735 returns the configuration together with the interfaces for
736 this configuration. Configuration descriptor is also of
739 @param UsbDev The Usb interface.
740 @param Index The index of the configuration.
742 @return The created configuration descriptor.
745 EFI_USB_CONFIG_DESCRIPTOR
*
747 IN USB_DEVICE
*UsbDev
,
751 EFI_USB_CONFIG_DESCRIPTOR Desc
;
756 // First get four bytes which contains the total length
757 // for this configuration.
759 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_CONFIG
, Index
, 0, &Desc
, 8);
761 if (EFI_ERROR (Status
)) {
764 "UsbGetOneConfig: failed to get descript length(%d) %r\n",
772 DEBUG ((DEBUG_INFO
, "UsbGetOneConfig: total length is %d\n", Desc
.TotalLength
));
775 // Reject if TotalLength even cannot cover itself.
777 if (Desc
.TotalLength
< OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR
, TotalLength
) + sizeof (Desc
.TotalLength
)) {
781 Buf
= AllocateZeroPool (Desc
.TotalLength
);
787 Status
= UsbCtrlGetDesc (UsbDev
, USB_DESC_TYPE_CONFIG
, Index
, 0, Buf
, Desc
.TotalLength
);
789 if (EFI_ERROR (Status
)) {
790 DEBUG ((DEBUG_ERROR
, "UsbGetOneConfig: failed to get full descript %r\n", Status
));
800 Build the whole array of descriptors. This function must
801 be called after UsbGetMaxPacketSize0 returns the max packet
802 size correctly for endpoint 0.
804 @param UsbDev The Usb device.
806 @retval EFI_SUCCESS The descriptor table is build.
807 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the descriptor.
812 IN USB_DEVICE
*UsbDev
815 EFI_USB_CONFIG_DESCRIPTOR
*Config
;
816 USB_DEVICE_DESC
*DevDesc
;
817 USB_CONFIG_DESC
*ConfigDesc
;
823 // Get the device descriptor, then allocate the configure
824 // descriptor pointer array to hold configurations.
826 Status
= UsbGetDevDesc (UsbDev
);
828 if (EFI_ERROR (Status
)) {
829 DEBUG ((DEBUG_ERROR
, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status
));
833 DevDesc
= UsbDev
->DevDesc
;
834 NumConfig
= DevDesc
->Desc
.NumConfigurations
;
835 if (NumConfig
== 0) {
836 return EFI_DEVICE_ERROR
;
839 DevDesc
->Configs
= AllocateZeroPool (NumConfig
* sizeof (USB_CONFIG_DESC
*));
840 if (DevDesc
->Configs
== NULL
) {
841 return EFI_OUT_OF_RESOURCES
;
844 DEBUG ((DEBUG_INFO
, "UsbBuildDescTable: device has %d configures\n", NumConfig
));
847 // Read each configurations, then parse them
849 for (Index
= 0; Index
< NumConfig
; Index
++) {
850 Config
= UsbGetOneConfig (UsbDev
, Index
);
852 if (Config
== NULL
) {
853 DEBUG ((DEBUG_ERROR
, "UsbBuildDescTable: failed to get configure (index %d)\n", Index
));
856 // If we can get the default descriptor, it is likely that the
857 // device is still operational.
860 return EFI_DEVICE_ERROR
;
866 ConfigDesc
= UsbParseConfigDesc ((UINT8
*)Config
, Config
->TotalLength
);
870 if (ConfigDesc
== NULL
) {
871 DEBUG ((DEBUG_ERROR
, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index
));
874 // If we can get the default descriptor, it is likely that the
875 // device is still operational.
878 return EFI_DEVICE_ERROR
;
884 DevDesc
->Configs
[Index
] = ConfigDesc
;
888 // Don't return error even this function failed because
889 // it is possible for the device to not support strings.
891 Status
= UsbBuildLangTable (UsbDev
);
893 if (EFI_ERROR (Status
)) {
894 DEBUG ((DEBUG_INFO
, "UsbBuildDescTable: get language ID table %r\n", Status
));
901 Set the device's address.
903 @param UsbDev The device to set address to.
904 @param Address The address to set.
906 @retval EFI_SUCCESS The device is set to the address.
907 @retval Others Failed to set the device address.
912 IN USB_DEVICE
*UsbDev
,
918 Status
= UsbCtrlRequest (
921 USB_REQ_TYPE_STANDARD
,
934 Set the device's configuration. This function changes
935 the device's internal state. UsbSelectConfig changes
936 the Usb bus's internal state.
938 @param UsbDev The USB device to set configure to.
939 @param ConfigIndex The configure index to set.
941 @retval EFI_SUCCESS The device is configured now.
942 @retval Others Failed to set the device configure.
947 IN USB_DEVICE
*UsbDev
,
953 Status
= UsbCtrlRequest (
956 USB_REQ_TYPE_STANDARD
,
969 Usb UsbIo interface to clear the feature. This is should
970 only be used by HUB which is considered a device driver
971 on top of the UsbIo interface.
973 @param UsbIo The UsbIo interface.
974 @param Target The target of the transfer: endpoint/device.
975 @param Feature The feature to clear.
976 @param Index The wIndex parameter.
978 @retval EFI_SUCCESS The device feature is cleared.
979 @retval Others Failed to clear the feature.
984 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
990 EFI_USB_DEVICE_REQUEST DevReq
;
994 DevReq
.RequestType
= USB_REQUEST_TYPE (EfiUsbNoData
, USB_REQ_TYPE_STANDARD
, Target
);
995 DevReq
.Request
= USB_REQ_CLEAR_FEATURE
;
996 DevReq
.Value
= Feature
;
997 DevReq
.Index
= Index
;
1000 Status
= UsbIo
->UsbControlTransfer (
1004 USB_CLEAR_FEATURE_REQUEST_TIMEOUT
,