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