]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
22b6a9d661139a73af49938ad1cbe16679b9eda2
[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 //
659 // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even.
660 //
661 if (EFI_ERROR (Status) ||
662 (Desc.Length < OFFSET_OF (EFI_USB_STRING_DESCRIPTOR, Length) + sizeof (Desc.Length)) ||
663 (Desc.Length % 2 != 0)
664 ) {
665 return NULL;
666 }
667
668 Buf = AllocateZeroPool (Desc.Length);
669
670 if (Buf == NULL) {
671 return NULL;
672 }
673
674 Status = UsbCtrlGetDesc (
675 UsbDev,
676 USB_DESC_TYPE_STRING,
677 Index,
678 LangId,
679 Buf,
680 Desc.Length
681 );
682
683 if (EFI_ERROR (Status)) {
684 FreePool (Buf);
685 return NULL;
686 }
687
688 return (EFI_USB_STRING_DESCRIPTOR *) Buf;
689 }
690
691
692 /**
693 Build the language ID table for string descriptors.
694
695 @param UsbDev The Usb device.
696
697 @retval EFI_UNSUPPORTED This device doesn't support string table.
698
699 **/
700 EFI_STATUS
701 UsbBuildLangTable (
702 IN USB_DEVICE *UsbDev
703 )
704 {
705 EFI_USB_STRING_DESCRIPTOR *Desc;
706 EFI_STATUS Status;
707 UINTN Index;
708 UINTN Max;
709 UINT16 *Point;
710
711 //
712 // The string of language ID zero returns the supported languages
713 //
714 Desc = UsbGetOneString (UsbDev, 0, 0);
715
716 if (Desc == NULL) {
717 return EFI_UNSUPPORTED;
718 }
719
720 if (Desc->Length < 4) {
721 Status = EFI_UNSUPPORTED;
722 goto ON_EXIT;
723 }
724
725 Status = EFI_SUCCESS;
726
727 Max = (Desc->Length - 2) / 2;
728 Max = MIN(Max, USB_MAX_LANG_ID);
729
730 Point = Desc->String;
731 for (Index = 0; Index < Max; Index++) {
732 UsbDev->LangId[Index] = *Point;
733 Point++;
734 }
735
736 UsbDev->TotalLangId = (UINT16)Max;
737
738 ON_EXIT:
739 gBS->FreePool (Desc);
740 return Status;
741 }
742
743
744 /**
745 Retrieve the indexed configure for the device. USB device
746 returns the configuration together with the interfaces for
747 this configuration. Configuration descriptor is also of
748 variable length.
749
750 @param UsbDev The Usb interface.
751 @param Index The index of the configuration.
752
753 @return The created configuration descriptor.
754
755 **/
756 EFI_USB_CONFIG_DESCRIPTOR *
757 UsbGetOneConfig (
758 IN USB_DEVICE *UsbDev,
759 IN UINT8 Index
760 )
761 {
762 EFI_USB_CONFIG_DESCRIPTOR Desc;
763 EFI_STATUS Status;
764 VOID *Buf;
765
766 //
767 // First get four bytes which contains the total length
768 // for this configuration.
769 //
770 Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, &Desc, 8);
771
772 if (EFI_ERROR (Status)) {
773 DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get descript length(%d) %r\n",
774 Desc.TotalLength, Status));
775
776 return NULL;
777 }
778
779 DEBUG (( EFI_D_INFO, "UsbGetOneConfig: total length is %d\n", Desc.TotalLength));
780
781 //
782 // Reject if TotalLength even cannot cover itself.
783 //
784 if (Desc.TotalLength < OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR, TotalLength) + sizeof (Desc.TotalLength)) {
785 return NULL;
786 }
787
788 Buf = AllocateZeroPool (Desc.TotalLength);
789
790 if (Buf == NULL) {
791 return NULL;
792 }
793
794 Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, Buf, Desc.TotalLength);
795
796 if (EFI_ERROR (Status)) {
797 DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get full descript %r\n", Status));
798
799 FreePool (Buf);
800 return NULL;
801 }
802
803 return Buf;
804 }
805
806
807 /**
808 Build the whole array of descriptors. This function must
809 be called after UsbGetMaxPacketSize0 returns the max packet
810 size correctly for endpoint 0.
811
812 @param UsbDev The Usb device.
813
814 @retval EFI_SUCCESS The descriptor table is build.
815 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the descriptor.
816
817 **/
818 EFI_STATUS
819 UsbBuildDescTable (
820 IN USB_DEVICE *UsbDev
821 )
822 {
823 EFI_USB_CONFIG_DESCRIPTOR *Config;
824 USB_DEVICE_DESC *DevDesc;
825 USB_CONFIG_DESC *ConfigDesc;
826 UINT8 NumConfig;
827 EFI_STATUS Status;
828 UINT8 Index;
829
830 //
831 // Get the device descriptor, then allocate the configure
832 // descriptor pointer array to hold configurations.
833 //
834 Status = UsbGetDevDesc (UsbDev);
835
836 if (EFI_ERROR (Status)) {
837 DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status));
838 return Status;
839 }
840
841 DevDesc = UsbDev->DevDesc;
842 NumConfig = DevDesc->Desc.NumConfigurations;
843 if (NumConfig == 0) {
844 return EFI_DEVICE_ERROR;
845 }
846
847 DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));
848 if (DevDesc->Configs == NULL) {
849 return EFI_OUT_OF_RESOURCES;
850 }
851
852 DEBUG (( EFI_D_INFO, "UsbBuildDescTable: device has %d configures\n", NumConfig));
853
854 //
855 // Read each configurations, then parse them
856 //
857 for (Index = 0; Index < NumConfig; Index++) {
858 Config = UsbGetOneConfig (UsbDev, Index);
859
860 if (Config == NULL) {
861 DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get configure (index %d)\n", Index));
862
863 //
864 // If we can get the default descriptor, it is likely that the
865 // device is still operational.
866 //
867 if (Index == 0) {
868 return EFI_DEVICE_ERROR;
869 }
870
871 break;
872 }
873
874 ConfigDesc = UsbParseConfigDesc ((UINT8 *) Config, Config->TotalLength);
875
876 FreePool (Config);
877
878 if (ConfigDesc == NULL) {
879 DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index));
880
881 //
882 // If we can get the default descriptor, it is likely that the
883 // device is still operational.
884 //
885 if (Index == 0) {
886 return EFI_DEVICE_ERROR;
887 }
888
889 break;
890 }
891
892 DevDesc->Configs[Index] = ConfigDesc;
893 }
894
895 //
896 // Don't return error even this function failed because
897 // it is possible for the device to not support strings.
898 //
899 Status = UsbBuildLangTable (UsbDev);
900
901 if (EFI_ERROR (Status)) {
902 DEBUG (( EFI_D_INFO, "UsbBuildDescTable: get language ID table %r\n", Status));
903 }
904
905 return EFI_SUCCESS;
906 }
907
908
909 /**
910 Set the device's address.
911
912 @param UsbDev The device to set address to.
913 @param Address The address to set.
914
915 @retval EFI_SUCCESS The device is set to the address.
916 @retval Others Failed to set the device address.
917
918 **/
919 EFI_STATUS
920 UsbSetAddress (
921 IN USB_DEVICE *UsbDev,
922 IN UINT8 Address
923 )
924 {
925 EFI_STATUS Status;
926
927 Status = UsbCtrlRequest (
928 UsbDev,
929 EfiUsbNoData,
930 USB_REQ_TYPE_STANDARD,
931 USB_TARGET_DEVICE,
932 USB_REQ_SET_ADDRESS,
933 Address,
934 0,
935 NULL,
936 0
937 );
938
939 return Status;
940 }
941
942
943 /**
944 Set the device's configuration. This function changes
945 the device's internal state. UsbSelectConfig changes
946 the Usb bus's internal state.
947
948 @param UsbDev The USB device to set configure to.
949 @param ConfigIndex The configure index to set.
950
951 @retval EFI_SUCCESS The device is configured now.
952 @retval Others Failed to set the device configure.
953
954 **/
955 EFI_STATUS
956 UsbSetConfig (
957 IN USB_DEVICE *UsbDev,
958 IN UINT8 ConfigIndex
959 )
960 {
961 EFI_STATUS Status;
962
963 Status = UsbCtrlRequest (
964 UsbDev,
965 EfiUsbNoData,
966 USB_REQ_TYPE_STANDARD,
967 USB_TARGET_DEVICE,
968 USB_REQ_SET_CONFIG,
969 ConfigIndex,
970 0,
971 NULL,
972 0
973 );
974
975 return Status;
976 }
977
978
979 /**
980 Usb UsbIo interface to clear the feature. This is should
981 only be used by HUB which is considered a device driver
982 on top of the UsbIo interface.
983
984 @param UsbIo The UsbIo interface.
985 @param Target The target of the transfer: endpoint/device.
986 @param Feature The feature to clear.
987 @param Index The wIndex parameter.
988
989 @retval EFI_SUCCESS The device feature is cleared.
990 @retval Others Failed to clear the feature.
991
992 **/
993 EFI_STATUS
994 UsbIoClearFeature (
995 IN EFI_USB_IO_PROTOCOL *UsbIo,
996 IN UINTN Target,
997 IN UINT16 Feature,
998 IN UINT16 Index
999 )
1000 {
1001 EFI_USB_DEVICE_REQUEST DevReq;
1002 UINT32 UsbResult;
1003 EFI_STATUS Status;
1004
1005 DevReq.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, Target);
1006 DevReq.Request = USB_REQ_CLEAR_FEATURE;
1007 DevReq.Value = Feature;
1008 DevReq.Index = Index;
1009 DevReq.Length = 0;
1010
1011 Status = UsbIo->UsbControlTransfer (
1012 UsbIo,
1013 &DevReq,
1014 EfiUsbNoData,
1015 USB_CLEAR_FEATURE_REQUEST_TIMEOUT,
1016 NULL,
1017 0,
1018 &UsbResult
1019 );
1020
1021 return Status;
1022 }