]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
MdeModulePkg/UsbBusDxe: Add missing "return NULL" in UsbCreateDesc()
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbDesc.c
1 /** @file
2
3 Manage Usb Descriptor List
4
5 Copyright (c) 2007 - 2018, 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
10
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.
13
14 **/
15
16 #include "UsbBus.h"
17
18
19 /**
20 Free the interface setting descriptor.
21
22 @param Setting The descriptor to free.
23
24 **/
25 VOID
26 UsbFreeInterfaceDesc (
27 IN USB_INTERFACE_SETTING *Setting
28 )
29 {
30 USB_ENDPOINT_DESC *Ep;
31 UINTN Index;
32
33 if (Setting->Endpoints != NULL) {
34 //
35 // Each interface setting may have several endpoints, free them first.
36 //
37 for (Index = 0; Index < Setting->Desc.NumEndpoints; Index++) {
38 Ep = Setting->Endpoints[Index];
39
40 if (Ep != NULL) {
41 FreePool (Ep);
42 }
43 }
44
45 //
46 // Only call FreePool() if NumEndpoints > 0.
47 //
48 if (Setting->Desc.NumEndpoints > 0) {
49 FreePool (Setting->Endpoints);
50 }
51 }
52
53 FreePool (Setting);
54 }
55
56
57 /**
58 Free a configuration descriptor with its interface
59 descriptors. It may be initialized partially.
60
61 @param Config The configuration descriptor to free.
62
63 **/
64 VOID
65 UsbFreeConfigDesc (
66 IN USB_CONFIG_DESC *Config
67 )
68 {
69 USB_INTERFACE_DESC *Interface;
70 UINTN Index;
71 UINTN SetIndex;
72
73 if (Config->Interfaces != NULL) {
74 //
75 // A configuration may have several interfaces, free the interface
76 //
77 for (Index = 0; Index < Config->Desc.NumInterfaces; Index++) {
78 Interface = Config->Interfaces[Index];
79
80 if (Interface == NULL) {
81 continue;
82 }
83
84 //
85 // Each interface may have several settings, free the settings
86 //
87 for (SetIndex = 0; SetIndex < Interface->NumOfSetting; SetIndex++) {
88 if (Interface->Settings[SetIndex] != NULL) {
89 UsbFreeInterfaceDesc (Interface->Settings[SetIndex]);
90 }
91 }
92
93 FreePool (Interface);
94 }
95
96 FreePool (Config->Interfaces);
97 }
98
99 FreePool (Config);
100
101 }
102
103
104 /**
105 Free a device descriptor with its configurations.
106
107 @param DevDesc The device descriptor.
108
109 **/
110 VOID
111 UsbFreeDevDesc (
112 IN USB_DEVICE_DESC *DevDesc
113 )
114 {
115 UINTN Index;
116
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]);
121 }
122 }
123
124 FreePool (DevDesc->Configs);
125 }
126
127 FreePool (DevDesc);
128 }
129
130
131 /**
132 Create a descriptor.
133
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.
138
139 @return Created descriptor or NULL.
140
141 **/
142 VOID *
143 UsbCreateDesc (
144 IN UINT8 *DescBuf,
145 IN UINTN Len,
146 IN UINT8 Type,
147 OUT UINTN *Consumed
148 )
149 {
150 USB_DESC_HEAD *Head;
151 UINTN DescLen;
152 UINTN CtrlLen;
153 UINTN Offset;
154 VOID *Desc;
155
156 DescLen = 0;
157 CtrlLen = 0;
158 *Consumed = 0;
159
160 switch (Type) {
161 case USB_DESC_TYPE_DEVICE:
162 DescLen = sizeof (EFI_USB_DEVICE_DESCRIPTOR);
163 CtrlLen = sizeof (USB_DEVICE_DESC);
164 break;
165
166 case USB_DESC_TYPE_CONFIG:
167 DescLen = sizeof (EFI_USB_CONFIG_DESCRIPTOR);
168 CtrlLen = sizeof (USB_CONFIG_DESC);
169 break;
170
171 case USB_DESC_TYPE_INTERFACE:
172 DescLen = sizeof (EFI_USB_INTERFACE_DESCRIPTOR);
173 CtrlLen = sizeof (USB_INTERFACE_SETTING);
174 break;
175
176 case USB_DESC_TYPE_ENDPOINT:
177 DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);
178 CtrlLen = sizeof (USB_ENDPOINT_DESC);
179 break;
180
181 default:
182 ASSERT (FALSE);
183 return NULL;
184 }
185
186 //
187 // Total length is too small that cannot hold the single descriptor header plus data.
188 //
189 if (Len <= sizeof (USB_DESC_HEAD)) {
190 DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len));
191 return NULL;
192 }
193
194 //
195 // All the descriptor has a common LTV (Length, Type, Value)
196 // format. Skip the descriptor that isn't of this Type
197 //
198 Offset = 0;
199 Head = (USB_DESC_HEAD *)DescBuf;
200 while (Offset < Len - sizeof (USB_DESC_HEAD)) {
201 //
202 // Above condition make sure Head->Len and Head->Type are safe to access
203 //
204 Head = (USB_DESC_HEAD *)&DescBuf[Offset];
205
206 if (Head->Len == 0) {
207 DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
208 return NULL;
209 }
210
211 //
212 // Make sure no overflow when adding Head->Len to Offset.
213 //
214 if (Head->Len > MAX_UINTN - Offset) {
215 DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head->Len));
216 return NULL;
217 }
218
219 Offset += Head->Len;
220
221 if (Head->Type == Type) {
222 break;
223 }
224 }
225
226 //
227 // Head->Len is invalid resulting data beyond boundary, or
228 // Descriptor cannot be found: No such type.
229 //
230 if (Len < Offset) {
231 DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset, Len));
232 return NULL;
233 }
234
235 if ((Head->Type != Type) || (Head->Len < DescLen)) {
236 DEBUG ((DEBUG_ERROR, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head->Type, Head->Len));
237 return NULL;
238 }
239
240 Desc = AllocateZeroPool ((UINTN) CtrlLen);
241 if (Desc == NULL) {
242 return NULL;
243 }
244
245 CopyMem (Desc, Head, (UINTN) DescLen);
246
247 *Consumed = Offset;
248
249 return Desc;
250 }
251
252
253 /**
254 Parse an interface descriptor and its endpoints.
255
256 @param DescBuf The buffer of raw descriptor.
257 @param Len The length of the raw descriptor buffer.
258 @param Consumed The number of raw descriptor consumed.
259
260 @return The create interface setting or NULL if failed.
261
262 **/
263 USB_INTERFACE_SETTING *
264 UsbParseInterfaceDesc (
265 IN UINT8 *DescBuf,
266 IN UINTN Len,
267 OUT UINTN *Consumed
268 )
269 {
270 USB_INTERFACE_SETTING *Setting;
271 USB_ENDPOINT_DESC *Ep;
272 UINTN Index;
273 UINTN NumEp;
274 UINTN Used;
275 UINTN Offset;
276
277 *Consumed = 0;
278 Setting = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);
279
280 if (Setting == NULL) {
281 DEBUG (( EFI_D_ERROR, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));
282 return NULL;
283 }
284
285 Offset = Used;
286
287 //
288 // Create an array to hold the interface's endpoints
289 //
290 NumEp = Setting->Desc.NumEndpoints;
291
292 DEBUG (( EFI_D_INFO, "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",
293 Setting->Desc.InterfaceNumber, Setting->Desc.AlternateSetting, (UINT32)NumEp));
294
295 if (NumEp == 0) {
296 goto ON_EXIT;
297 }
298
299 Setting->Endpoints = AllocateZeroPool (sizeof (USB_ENDPOINT_DESC *) * NumEp);
300
301 if (Setting->Endpoints == NULL) {
302 goto ON_ERROR;
303 }
304
305 //
306 // Create the endpoints for this interface
307 //
308 for (Index = 0; (Index < NumEp) && (Offset < Len); Index++) {
309 Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);
310
311 if (Ep == NULL) {
312 DEBUG (( EFI_D_ERROR, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32)Index));
313 goto ON_ERROR;
314 }
315
316 Setting->Endpoints[Index] = Ep;
317 Offset += Used;
318 }
319
320
321 ON_EXIT:
322 *Consumed = Offset;
323 return Setting;
324
325 ON_ERROR:
326 UsbFreeInterfaceDesc (Setting);
327 return NULL;
328 }
329
330
331 /**
332 Parse the configuration descriptor and its interfaces.
333
334 @param DescBuf The buffer of raw descriptor.
335 @param Len The length of the raw descriptor buffer.
336
337 @return The created configuration descriptor.
338
339 **/
340 USB_CONFIG_DESC *
341 UsbParseConfigDesc (
342 IN UINT8 *DescBuf,
343 IN UINTN Len
344 )
345 {
346 USB_CONFIG_DESC *Config;
347 USB_INTERFACE_SETTING *Setting;
348 USB_INTERFACE_DESC *Interface;
349 UINTN Index;
350 UINTN NumIf;
351 UINTN Consumed;
352
353 ASSERT (DescBuf != NULL);
354
355 Config = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_CONFIG, &Consumed);
356
357 if (Config == NULL) {
358 return NULL;
359 }
360
361 //
362 // Initialize an array of setting for the configuration's interfaces.
363 //
364 NumIf = Config->Desc.NumInterfaces;
365 Config->Interfaces = AllocateZeroPool (sizeof (USB_INTERFACE_DESC *) * NumIf);
366
367 if (Config->Interfaces == NULL) {
368 goto ON_ERROR;
369 }
370
371 DEBUG (( EFI_D_INFO, "UsbParseConfigDesc: config %d has %d interfaces\n",
372 Config->Desc.ConfigurationValue, (UINT32)NumIf));
373
374 for (Index = 0; Index < NumIf; Index++) {
375 Interface = AllocateZeroPool (sizeof (USB_INTERFACE_DESC));
376
377 if (Interface == NULL) {
378 goto ON_ERROR;
379 }
380
381 Config->Interfaces[Index] = Interface;
382 }
383
384 //
385 // If a configuration has several interfaces, these interfaces are
386 // numbered from zero to n. If a interface has several settings,
387 // these settings are also number from zero to m. The interface
388 // setting must be organized as |interface 0, setting 0|interface 0
389 // setting 1|interface 1, setting 0|interface 2, setting 0|. Check
390 // USB2.0 spec, page 267.
391 //
392 DescBuf += Consumed;
393 Len -= Consumed;
394
395 //
396 // Make allowances for devices that return extra data at the
397 // end of their config descriptors
398 //
399 while (Len >= sizeof (EFI_USB_INTERFACE_DESCRIPTOR)) {
400 Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed);
401
402 if (Setting == NULL) {
403 DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));
404 break;
405
406 } else if (Setting->Desc.InterfaceNumber >= NumIf) {
407 DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: mal-formated interface descriptor\n"));
408
409 UsbFreeInterfaceDesc (Setting);
410 goto ON_ERROR;
411 }
412
413 //
414 // Insert the descriptor to the corresponding set.
415 //
416 Interface = Config->Interfaces[Setting->Desc.InterfaceNumber];
417
418 if (Interface->NumOfSetting >= USB_MAX_INTERFACE_SETTING) {
419 goto ON_ERROR;
420 }
421
422 Interface->Settings[Interface->NumOfSetting] = Setting;
423 Interface->NumOfSetting++;
424
425 DescBuf += Consumed;
426 Len -= Consumed;
427 }
428
429 return Config;
430
431 ON_ERROR:
432 UsbFreeConfigDesc (Config);
433 return NULL;
434 }
435
436
437 /**
438 USB standard control transfer support routine. This
439 function is used by USB device. It is possible that
440 the device's interfaces are still waiting to be
441 enumerated.
442
443 @param UsbDev The usb device.
444 @param Direction The direction of data transfer.
445 @param Type Standard / class specific / vendor specific.
446 @param Target The receiving target.
447 @param Request Which request.
448 @param Value The wValue parameter of the request.
449 @param Index The wIndex parameter of the request.
450 @param Buf The buffer to receive data into / transmit from.
451 @param Length The length of the buffer.
452
453 @retval EFI_SUCCESS The control request is executed.
454 @retval EFI_DEVICE_ERROR Failed to execute the control transfer.
455
456 **/
457 EFI_STATUS
458 UsbCtrlRequest (
459 IN USB_DEVICE *UsbDev,
460 IN EFI_USB_DATA_DIRECTION Direction,
461 IN UINTN Type,
462 IN UINTN Target,
463 IN UINTN Request,
464 IN UINT16 Value,
465 IN UINT16 Index,
466 IN OUT VOID *Buf,
467 IN UINTN Length
468 )
469 {
470 EFI_USB_DEVICE_REQUEST DevReq;
471 EFI_STATUS Status;
472 UINT32 Result;
473 UINTN Len;
474
475 ASSERT ((UsbDev != NULL) && (UsbDev->Bus != NULL));
476
477 DevReq.RequestType = USB_REQUEST_TYPE (Direction, Type, Target);
478 DevReq.Request = (UINT8) Request;
479 DevReq.Value = Value;
480 DevReq.Index = Index;
481 DevReq.Length = (UINT16) Length;
482
483 Len = Length;
484 Status = UsbHcControlTransfer (
485 UsbDev->Bus,
486 UsbDev->Address,
487 UsbDev->Speed,
488 UsbDev->MaxPacket0,
489 &DevReq,
490 Direction,
491 Buf,
492 &Len,
493 USB_GENERAL_DEVICE_REQUEST_TIMEOUT,
494 &UsbDev->Translator,
495 &Result
496 );
497
498 return Status;
499 }
500
501
502 /**
503 Get the standard descriptors.
504
505 @param UsbDev The USB device to read descriptor from.
506 @param DescType The type of descriptor to read.
507 @param DescIndex The index of descriptor to read.
508 @param LangId Language ID, only used to get string, otherwise set
509 it to 0.
510 @param Buf The buffer to hold the descriptor read.
511 @param Length The length of the buffer.
512
513 @retval EFI_SUCCESS The descriptor is read OK.
514 @retval Others Failed to retrieve the descriptor.
515
516 **/
517 EFI_STATUS
518 UsbCtrlGetDesc (
519 IN USB_DEVICE *UsbDev,
520 IN UINTN DescType,
521 IN UINTN DescIndex,
522 IN UINT16 LangId,
523 OUT VOID *Buf,
524 IN UINTN Length
525 )
526 {
527 EFI_STATUS Status;
528
529 Status = UsbCtrlRequest (
530 UsbDev,
531 EfiUsbDataIn,
532 USB_REQ_TYPE_STANDARD,
533 USB_TARGET_DEVICE,
534 USB_REQ_GET_DESCRIPTOR,
535 (UINT16) ((DescType << 8) | DescIndex),
536 LangId,
537 Buf,
538 Length
539 );
540
541 return Status;
542 }
543
544
545 /**
546 Return the max packet size for endpoint zero. This function
547 is the first function called to get descriptors during bus
548 enumeration.
549
550 @param UsbDev The usb device.
551
552 @retval EFI_SUCCESS The max packet size of endpoint zero is retrieved.
553 @retval EFI_DEVICE_ERROR Failed to retrieve it.
554
555 **/
556 EFI_STATUS
557 UsbGetMaxPacketSize0 (
558 IN USB_DEVICE *UsbDev
559 )
560 {
561 EFI_USB_DEVICE_DESCRIPTOR DevDesc;
562 EFI_STATUS Status;
563 UINTN Index;
564
565
566 //
567 // Get the first 8 bytes of the device descriptor which contains
568 // max packet size for endpoint 0, which is at least 8.
569 //
570 for (Index = 0; Index < 3; Index++) {
571 Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, &DevDesc, 8);
572
573 if (!EFI_ERROR (Status)) {
574 if ((DevDesc.BcdUSB >= 0x0300) && (DevDesc.MaxPacketSize0 == 9)) {
575 UsbDev->MaxPacket0 = 1 << 9;
576 return EFI_SUCCESS;
577 }
578 UsbDev->MaxPacket0 = DevDesc.MaxPacketSize0;
579 return EFI_SUCCESS;
580 }
581
582 gBS->Stall (USB_RETRY_MAX_PACK_SIZE_STALL);
583 }
584
585 return EFI_DEVICE_ERROR;
586 }
587
588
589 /**
590 Get the device descriptor for the device.
591
592 @param UsbDev The Usb device to retrieve descriptor from.
593
594 @retval EFI_SUCCESS The device descriptor is returned.
595 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
596
597 **/
598 EFI_STATUS
599 UsbGetDevDesc (
600 IN USB_DEVICE *UsbDev
601 )
602 {
603 USB_DEVICE_DESC *DevDesc;
604 EFI_STATUS Status;
605
606 DevDesc = AllocateZeroPool (sizeof (USB_DEVICE_DESC));
607
608 if (DevDesc == NULL) {
609 return EFI_OUT_OF_RESOURCES;
610 }
611
612 Status = UsbCtrlGetDesc (
613 UsbDev,
614 USB_DESC_TYPE_DEVICE,
615 0,
616 0,
617 DevDesc,
618 sizeof (EFI_USB_DEVICE_DESCRIPTOR)
619 );
620
621 if (EFI_ERROR (Status)) {
622 gBS->FreePool (DevDesc);
623 } else {
624 UsbDev->DevDesc = DevDesc;
625 }
626
627 return Status;
628 }
629
630
631 /**
632 Retrieve the indexed string for the language. It requires two
633 steps to get a string, first to get the string's length. Then
634 the string itself.
635
636 @param UsbDev The usb device.
637 @param Index The index the string to retrieve.
638 @param LangId Language ID.
639
640 @return The created string descriptor or NULL.
641
642 **/
643 EFI_USB_STRING_DESCRIPTOR *
644 UsbGetOneString (
645 IN USB_DEVICE *UsbDev,
646 IN UINT8 Index,
647 IN UINT16 LangId
648 )
649 {
650 EFI_USB_STRING_DESCRIPTOR Desc;
651 EFI_STATUS Status;
652 UINT8 *Buf;
653
654 //
655 // First get two bytes which contains the string length.
656 //
657 Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2);
658
659 //
660 // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even.
661 //
662 if (EFI_ERROR (Status) ||
663 (Desc.Length < OFFSET_OF (EFI_USB_STRING_DESCRIPTOR, Length) + sizeof (Desc.Length)) ||
664 (Desc.Length % 2 != 0)
665 ) {
666 return NULL;
667 }
668
669 Buf = AllocateZeroPool (Desc.Length);
670
671 if (Buf == NULL) {
672 return NULL;
673 }
674
675 Status = UsbCtrlGetDesc (
676 UsbDev,
677 USB_DESC_TYPE_STRING,
678 Index,
679 LangId,
680 Buf,
681 Desc.Length
682 );
683
684 if (EFI_ERROR (Status)) {
685 FreePool (Buf);
686 return NULL;
687 }
688
689 return (EFI_USB_STRING_DESCRIPTOR *) Buf;
690 }
691
692
693 /**
694 Build the language ID table for string descriptors.
695
696 @param UsbDev The Usb device.
697
698 @retval EFI_UNSUPPORTED This device doesn't support string table.
699
700 **/
701 EFI_STATUS
702 UsbBuildLangTable (
703 IN USB_DEVICE *UsbDev
704 )
705 {
706 EFI_USB_STRING_DESCRIPTOR *Desc;
707 EFI_STATUS Status;
708 UINTN Index;
709 UINTN Max;
710 UINT16 *Point;
711
712 //
713 // The string of language ID zero returns the supported languages
714 //
715 Desc = UsbGetOneString (UsbDev, 0, 0);
716
717 if (Desc == NULL) {
718 return EFI_UNSUPPORTED;
719 }
720
721 if (Desc->Length < 4) {
722 Status = EFI_UNSUPPORTED;
723 goto ON_EXIT;
724 }
725
726 Status = EFI_SUCCESS;
727
728 Max = (Desc->Length - 2) / 2;
729 Max = MIN(Max, USB_MAX_LANG_ID);
730
731 Point = Desc->String;
732 for (Index = 0; Index < Max; Index++) {
733 UsbDev->LangId[Index] = *Point;
734 Point++;
735 }
736
737 UsbDev->TotalLangId = (UINT16)Max;
738
739 ON_EXIT:
740 gBS->FreePool (Desc);
741 return Status;
742 }
743
744
745 /**
746 Retrieve the indexed configure for the device. USB device
747 returns the configuration together with the interfaces for
748 this configuration. Configuration descriptor is also of
749 variable length.
750
751 @param UsbDev The Usb interface.
752 @param Index The index of the configuration.
753
754 @return The created configuration descriptor.
755
756 **/
757 EFI_USB_CONFIG_DESCRIPTOR *
758 UsbGetOneConfig (
759 IN USB_DEVICE *UsbDev,
760 IN UINT8 Index
761 )
762 {
763 EFI_USB_CONFIG_DESCRIPTOR Desc;
764 EFI_STATUS Status;
765 VOID *Buf;
766
767 //
768 // First get four bytes which contains the total length
769 // for this configuration.
770 //
771 Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, &Desc, 8);
772
773 if (EFI_ERROR (Status)) {
774 DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get descript length(%d) %r\n",
775 Desc.TotalLength, Status));
776
777 return NULL;
778 }
779
780 DEBUG (( EFI_D_INFO, "UsbGetOneConfig: total length is %d\n", Desc.TotalLength));
781
782 //
783 // Reject if TotalLength even cannot cover itself.
784 //
785 if (Desc.TotalLength < OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR, TotalLength) + sizeof (Desc.TotalLength)) {
786 return NULL;
787 }
788
789 Buf = AllocateZeroPool (Desc.TotalLength);
790
791 if (Buf == NULL) {
792 return NULL;
793 }
794
795 Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, Buf, Desc.TotalLength);
796
797 if (EFI_ERROR (Status)) {
798 DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get full descript %r\n", Status));
799
800 FreePool (Buf);
801 return NULL;
802 }
803
804 return Buf;
805 }
806
807
808 /**
809 Build the whole array of descriptors. This function must
810 be called after UsbGetMaxPacketSize0 returns the max packet
811 size correctly for endpoint 0.
812
813 @param UsbDev The Usb device.
814
815 @retval EFI_SUCCESS The descriptor table is build.
816 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the descriptor.
817
818 **/
819 EFI_STATUS
820 UsbBuildDescTable (
821 IN USB_DEVICE *UsbDev
822 )
823 {
824 EFI_USB_CONFIG_DESCRIPTOR *Config;
825 USB_DEVICE_DESC *DevDesc;
826 USB_CONFIG_DESC *ConfigDesc;
827 UINT8 NumConfig;
828 EFI_STATUS Status;
829 UINT8 Index;
830
831 //
832 // Get the device descriptor, then allocate the configure
833 // descriptor pointer array to hold configurations.
834 //
835 Status = UsbGetDevDesc (UsbDev);
836
837 if (EFI_ERROR (Status)) {
838 DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status));
839 return Status;
840 }
841
842 DevDesc = UsbDev->DevDesc;
843 NumConfig = DevDesc->Desc.NumConfigurations;
844 if (NumConfig == 0) {
845 return EFI_DEVICE_ERROR;
846 }
847
848 DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));
849 if (DevDesc->Configs == NULL) {
850 return EFI_OUT_OF_RESOURCES;
851 }
852
853 DEBUG (( EFI_D_INFO, "UsbBuildDescTable: device has %d configures\n", NumConfig));
854
855 //
856 // Read each configurations, then parse them
857 //
858 for (Index = 0; Index < NumConfig; Index++) {
859 Config = UsbGetOneConfig (UsbDev, Index);
860
861 if (Config == NULL) {
862 DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get configure (index %d)\n", Index));
863
864 //
865 // If we can get the default descriptor, it is likely that the
866 // device is still operational.
867 //
868 if (Index == 0) {
869 return EFI_DEVICE_ERROR;
870 }
871
872 break;
873 }
874
875 ConfigDesc = UsbParseConfigDesc ((UINT8 *) Config, Config->TotalLength);
876
877 FreePool (Config);
878
879 if (ConfigDesc == NULL) {
880 DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index));
881
882 //
883 // If we can get the default descriptor, it is likely that the
884 // device is still operational.
885 //
886 if (Index == 0) {
887 return EFI_DEVICE_ERROR;
888 }
889
890 break;
891 }
892
893 DevDesc->Configs[Index] = ConfigDesc;
894 }
895
896 //
897 // Don't return error even this function failed because
898 // it is possible for the device to not support strings.
899 //
900 Status = UsbBuildLangTable (UsbDev);
901
902 if (EFI_ERROR (Status)) {
903 DEBUG (( EFI_D_INFO, "UsbBuildDescTable: get language ID table %r\n", Status));
904 }
905
906 return EFI_SUCCESS;
907 }
908
909
910 /**
911 Set the device's address.
912
913 @param UsbDev The device to set address to.
914 @param Address The address to set.
915
916 @retval EFI_SUCCESS The device is set to the address.
917 @retval Others Failed to set the device address.
918
919 **/
920 EFI_STATUS
921 UsbSetAddress (
922 IN USB_DEVICE *UsbDev,
923 IN UINT8 Address
924 )
925 {
926 EFI_STATUS Status;
927
928 Status = UsbCtrlRequest (
929 UsbDev,
930 EfiUsbNoData,
931 USB_REQ_TYPE_STANDARD,
932 USB_TARGET_DEVICE,
933 USB_REQ_SET_ADDRESS,
934 Address,
935 0,
936 NULL,
937 0
938 );
939
940 return Status;
941 }
942
943
944 /**
945 Set the device's configuration. This function changes
946 the device's internal state. UsbSelectConfig changes
947 the Usb bus's internal state.
948
949 @param UsbDev The USB device to set configure to.
950 @param ConfigIndex The configure index to set.
951
952 @retval EFI_SUCCESS The device is configured now.
953 @retval Others Failed to set the device configure.
954
955 **/
956 EFI_STATUS
957 UsbSetConfig (
958 IN USB_DEVICE *UsbDev,
959 IN UINT8 ConfigIndex
960 )
961 {
962 EFI_STATUS Status;
963
964 Status = UsbCtrlRequest (
965 UsbDev,
966 EfiUsbNoData,
967 USB_REQ_TYPE_STANDARD,
968 USB_TARGET_DEVICE,
969 USB_REQ_SET_CONFIG,
970 ConfigIndex,
971 0,
972 NULL,
973 0
974 );
975
976 return Status;
977 }
978
979
980 /**
981 Usb UsbIo interface to clear the feature. This is should
982 only be used by HUB which is considered a device driver
983 on top of the UsbIo interface.
984
985 @param UsbIo The UsbIo interface.
986 @param Target The target of the transfer: endpoint/device.
987 @param Feature The feature to clear.
988 @param Index The wIndex parameter.
989
990 @retval EFI_SUCCESS The device feature is cleared.
991 @retval Others Failed to clear the feature.
992
993 **/
994 EFI_STATUS
995 UsbIoClearFeature (
996 IN EFI_USB_IO_PROTOCOL *UsbIo,
997 IN UINTN Target,
998 IN UINT16 Feature,
999 IN UINT16 Index
1000 )
1001 {
1002 EFI_USB_DEVICE_REQUEST DevReq;
1003 UINT32 UsbResult;
1004 EFI_STATUS Status;
1005
1006 DevReq.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, Target);
1007 DevReq.Request = USB_REQ_CLEAR_FEATURE;
1008 DevReq.Value = Feature;
1009 DevReq.Index = Index;
1010 DevReq.Length = 0;
1011
1012 Status = UsbIo->UsbControlTransfer (
1013 UsbIo,
1014 &DevReq,
1015 EfiUsbNoData,
1016 USB_CLEAR_FEATURE_REQUEST_TIMEOUT,
1017 NULL,
1018 0,
1019 &UsbResult
1020 );
1021
1022 return Status;
1023 }