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