]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Usb/UsbBus/Dxe/usb.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbBus / Dxe / usb.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12 Module Name:\r
13\r
14 Usb.c\r
15\r
16 Abstract:\r
17\r
18 Parse usb device configurations.\r
19\r
20 Revision History\r
21\r
22--*/\r
23\r
24#include "usbbus.h"\r
25\r
26//\r
27// Here are some internal helper functions\r
28//\r
29STATIC\r
30EFI_STATUS\r
31GetExpectedDescriptor (\r
32 IN UINT8 *Buffer,\r
33 IN UINTN Length,\r
34 IN UINT8 DescType,\r
35 IN UINT8 DescLength,\r
36 OUT UINTN *ParsedBytes\r
37 );\r
38\r
39STATIC\r
40EFI_STATUS\r
41ParseThisEndpoint (\r
42 IN ENDPOINT_DESC_LIST_ENTRY *EndpointEntry,\r
43 IN UINT8 *Buffer,\r
44 IN UINTN BufferLength,\r
45 OUT UINTN *ParsedBytes\r
46 );\r
47\r
48STATIC\r
49EFI_STATUS\r
50ParseThisInterface (\r
51 IN INTERFACE_DESC_LIST_ENTRY *InterfaceEntry,\r
52 IN UINT8 *Buffer,\r
53 IN UINTN *BufferLen,\r
54 OUT UINTN *ParsedBytes\r
55 );\r
56\r
57STATIC\r
58EFI_STATUS\r
59ParseThisConfig (\r
60 IN CONFIG_DESC_LIST_ENTRY *ConfigDescEntry,\r
61 IN UINT8 *Buffer,\r
62 IN UINTN Length\r
63 );\r
64\r
65//\r
66// Implementations\r
67//\r
68BOOLEAN\r
69IsHub (\r
70 IN USB_IO_CONTROLLER_DEVICE *Dev\r
71 )\r
72/*++\r
73 \r
74 Routine Description:\r
75 Tell if a usb controller is a hub controller.\r
76 \r
77 Arguments:\r
78 Dev - UsbIoController device structure.\r
79 \r
80 Returns:\r
81 TRUE/FALSE\r
82--*/\r
83{\r
84 EFI_USB_INTERFACE_DESCRIPTOR Interface;\r
85 EFI_USB_IO_PROTOCOL *UsbIo;\r
86 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;\r
87 UINT8 Index;\r
88\r
89 if (Dev == NULL) {\r
90 return FALSE;\r
91 }\r
92\r
93 UsbIo = &Dev->UsbIo;\r
94\r
95 UsbIo->UsbGetInterfaceDescriptor (\r
96 UsbIo,\r
97 &Interface\r
98 );\r
99\r
100 //\r
101 // Check classcode\r
102 //\r
103 if (Interface.InterfaceClass != 0x09) {\r
104 return FALSE;\r
105 }\r
106 \r
107 //\r
108 // Check protocol\r
109 //\r
110 if (Interface.InterfaceProtocol != 0x0) {\r
111 return FALSE;\r
112 }\r
113\r
114 for (Index = 0; Index < Interface.NumEndpoints; Index++) {\r
115 UsbIo->UsbGetEndpointDescriptor (\r
116 UsbIo,\r
117 Index,\r
118 &EndpointDescriptor\r
119 );\r
120\r
121 if ((EndpointDescriptor.EndpointAddress & 0x80) == 0) {\r
122 continue;\r
123 }\r
124\r
125 if (EndpointDescriptor.Attributes != 0x03) {\r
126 continue;\r
127 }\r
128\r
129 Dev->HubEndpointAddress = EndpointDescriptor.EndpointAddress;\r
130 return TRUE;\r
131 }\r
132\r
133 return FALSE;\r
134}\r
135\r
136EFI_STATUS\r
137UsbGetStringtable (\r
138 IN USB_IO_DEVICE *Dev\r
139 )\r
140/*++\r
141 \r
142 Routine Description:\r
143 Get the string table stored in a usb device.\r
144 \r
145 Arguments:\r
146 Dev - UsbIoController device structure.\r
147 \r
148 Returns:\r
149 EFI_SUCCESS\r
150 EFI_UNSUPPORTED\r
151 EFI_OUT_OF_RESOURCES\r
152 \r
153--*/\r
154{\r
155 EFI_STATUS Result;\r
156 UINT32 Status;\r
157 EFI_USB_SUPPORTED_LANGUAGES *LanguageTable;\r
158 UINT8 *Buffer;\r
159 UINT8 *ptr;\r
160 UINTN Index;\r
161 UINTN LangTableSize;\r
162 EFI_USB_IO_PROTOCOL *UsbIo;\r
163 UINT16 TempBuffer;\r
164\r
165 UsbIo = &(Dev->UsbController[0]->UsbIo);\r
166\r
167 //\r
168 // We get first 2 byte of langID table,\r
169 // so we can have the whole table length\r
170 //\r
171 Result = UsbGetString (\r
172 UsbIo,\r
173 0,\r
174 0,\r
175 &TempBuffer,\r
176 2,\r
177 &Status\r
178 );\r
179 if (EFI_ERROR (Result)) {\r
180 return EFI_UNSUPPORTED;\r
181 }\r
182\r
183 LanguageTable = (EFI_USB_SUPPORTED_LANGUAGES *) &TempBuffer;\r
184\r
185 if (LanguageTable->Length == 0) {\r
186 return EFI_UNSUPPORTED;\r
187 }\r
188 //\r
189 // If length is 2, then there is no string table\r
190 //\r
191 if (LanguageTable->Length == 2) {\r
192 return EFI_UNSUPPORTED;\r
193 }\r
194\r
195 Buffer = AllocateZeroPool (LanguageTable->Length);\r
196 if (Buffer == NULL) {\r
197 return EFI_OUT_OF_RESOURCES;\r
198 }\r
199 \r
200 //\r
201 // Now we get the whole LangID table\r
202 //\r
203 Result = UsbGetString (\r
204 UsbIo,\r
205 0,\r
206 0,\r
207 Buffer,\r
208 LanguageTable->Length,\r
209 &Status\r
210 );\r
211 if (EFI_ERROR (Result)) {\r
212 gBS->FreePool (Buffer);\r
213 return EFI_UNSUPPORTED;\r
214 }\r
215\r
216 LanguageTable = (EFI_USB_SUPPORTED_LANGUAGES *) Buffer;\r
217\r
218 //\r
219 // ptr point to the LangID table\r
220 //\r
221 ptr = Buffer + 2;\r
222 LangTableSize = (LanguageTable->Length - 2) / 2;\r
223\r
224 for (Index = 0; Index < LangTableSize && Index < USB_MAXLANID; Index++) {\r
225 Dev->LangID[Index] = *((UINT16 *) ptr);\r
226 ptr += 2;\r
227 }\r
228\r
229 gBS->FreePool (Buffer);\r
230 LanguageTable = NULL;\r
231\r
232 return EFI_SUCCESS;\r
233}\r
234\r
235\r
236EFI_STATUS\r
237UsbGetAllConfigurations (\r
238 IN USB_IO_DEVICE *UsbIoDevice\r
239 )\r
240/*++\r
241\r
242 Routine Description:\r
243 This function is to parse all the configuration descriptor.\r
244 \r
245 Arguments:\r
246 UsbIoDevice - USB_IO_DEVICE device structure.\r
247 \r
248 Returns:\r
249 EFI_SUCCESS\r
250 EFI_DEVICE_ERROR\r
251 EFI_OUT_OF_RESOURCES \r
252\r
253--*/\r
254{\r
255 EFI_STATUS Result;\r
256 UINT32 Status;\r
257 UINTN Index;\r
258 UINTN TotalLength;\r
259 UINT8 *Buffer;\r
260 CONFIG_DESC_LIST_ENTRY *ConfigDescEntry;\r
261 EFI_USB_IO_PROTOCOL *UsbIo;\r
262\r
263 InitializeListHead (&UsbIoDevice->ConfigDescListHead);\r
264 UsbIo = &(UsbIoDevice->UsbController[0]->UsbIo);\r
265\r
266 for (Index = 0; Index < UsbIoDevice->DeviceDescriptor.NumConfigurations; Index++) {\r
267 ConfigDescEntry = NULL;\r
268\r
269 ConfigDescEntry = AllocateZeroPool (sizeof (CONFIG_DESC_LIST_ENTRY));\r
270 if (ConfigDescEntry == NULL) {\r
271 return EFI_OUT_OF_RESOURCES;\r
272 }\r
273 //\r
274 // 1st only get 1st 4 bytes config descriptor,\r
275 // so we can know the whole length\r
276 //\r
277 Result = UsbGetDescriptor (\r
278 UsbIo,\r
279 (UINT16) ((USB_DT_CONFIG << 8) | Index),\r
280 0,\r
281 4,\r
282 &ConfigDescEntry->CongfigDescriptor,\r
283 &Status\r
284 );\r
285 if (EFI_ERROR (Result)) {\r
286 DEBUG ((gUSBErrorLevel, "First get config descriptor error\n"));\r
287 gBS->FreePool (ConfigDescEntry);\r
288 return EFI_DEVICE_ERROR;\r
289 }\r
290\r
291 TotalLength = ConfigDescEntry->CongfigDescriptor.TotalLength;\r
292\r
293 Buffer = AllocateZeroPool (TotalLength);\r
294 if (Buffer == NULL) {\r
295 gBS->FreePool (ConfigDescEntry);\r
296 return EFI_OUT_OF_RESOURCES;\r
297 }\r
298 //\r
299 // Then we get the total descriptors for this configuration\r
300 //\r
301 Result = UsbGetDescriptor (\r
302 UsbIo,\r
303 (UINT16) ((USB_DT_CONFIG << 8) | Index),\r
304 0,\r
305 (UINT16) TotalLength,\r
306 Buffer,\r
307 &Status\r
308 );\r
309 if (EFI_ERROR (Result)) {\r
310 DEBUG ((gUSBErrorLevel, "Get whole config descriptor error\n"));\r
311 gBS->FreePool (ConfigDescEntry);\r
312 gBS->FreePool (Buffer);\r
313 return EFI_DEVICE_ERROR;\r
314 }\r
315\r
316 InitializeListHead (&ConfigDescEntry->InterfaceDescListHead);\r
317\r
318 //\r
319 // Parse this whole configuration\r
320 //\r
321 Result = ParseThisConfig (ConfigDescEntry, Buffer, TotalLength);\r
322\r
323 if (EFI_ERROR (Result)) {\r
324 //\r
325 // Ignore this configuration, parse next one\r
326 //\r
327 gBS->FreePool (ConfigDescEntry);\r
328 gBS->FreePool (Buffer);\r
329 continue;\r
330 }\r
331\r
332 InsertTailList (&UsbIoDevice->ConfigDescListHead, &ConfigDescEntry->Link);\r
333\r
334 gBS->FreePool (Buffer);\r
335\r
336 }\r
337\r
338 return EFI_SUCCESS;\r
339}\r
340\r
341STATIC\r
342EFI_STATUS\r
343GetExpectedDescriptor (\r
344 IN UINT8 *Buffer,\r
345 IN UINTN Length,\r
346 IN UINT8 DescType,\r
347 IN UINT8 DescLength,\r
348 OUT UINTN *ParsedBytes\r
349 )\r
350/*++\r
351 \r
352 Routine Description:\r
353 Get the start position of next wanted descriptor.\r
354 \r
355 Arguments:\r
356 Buffer - Buffer to parse\r
357 Length - Buffer length \r
358 DescType - Descriptor type \r
359 DescLength - Descriptor length\r
360 ParsedBytes - Parsed Bytes to return\r
361 Returns:\r
362 EFI_SUCCESS\r
363 EFI_DEVICE_ERROR\r
364\r
365--*/\r
366{\r
367 UINT16 DescriptorHeader;\r
368 UINT8 Len;\r
369 UINT8 *ptr;\r
370 UINTN Parsed;\r
371\r
372 Parsed = 0;\r
373 ptr = Buffer;\r
374\r
375 while (TRUE) {\r
376 //\r
377 // Buffer length should not less than Desc length\r
378 //\r
379 if (Length < DescLength) {\r
380 return EFI_DEVICE_ERROR;\r
381 }\r
382 //\r
383 // DescriptorHeader = *((UINT16 *)ptr), compatible with IPF\r
384 //\r
385 DescriptorHeader = (UINT16) ((*(ptr + 1) << 8) | *ptr);\r
386\r
387 Len = ptr[0];\r
388\r
389 //\r
390 // Check to see if it is a start of expected descriptor\r
391 //\r
392 if (DescriptorHeader == ((DescType << 8) | DescLength)) {\r
393 break;\r
394 }\r
395\r
396 if ((UINT8) (DescriptorHeader >> 8) == DescType) {\r
397 if (Len > DescLength) {\r
398 return EFI_DEVICE_ERROR;\r
399 }\r
400 }\r
401 //\r
402 // Descriptor length should be at least 2\r
403 // and should not exceed the buffer length\r
404 //\r
405 if (Len < 2) {\r
406 return EFI_DEVICE_ERROR;\r
407 }\r
408\r
409 if (Len > Length) {\r
410 return EFI_DEVICE_ERROR;\r
411 }\r
412 //\r
413 // Skip this mismatch descriptor\r
414 //\r
415 Length -= Len;\r
416 ptr += Len;\r
417 Parsed += Len;\r
418 }\r
419\r
420 *ParsedBytes = Parsed;\r
421\r
422 return EFI_SUCCESS;\r
423}\r
424\r
425\r
426STATIC\r
427EFI_STATUS\r
428ParseThisEndpoint (\r
429 IN ENDPOINT_DESC_LIST_ENTRY *EndpointEntry,\r
430 IN UINT8 *Buffer,\r
431 IN UINTN BufferLength,\r
432 OUT UINTN *ParsedBytes\r
433 )\r
434/*++\r
435\r
436 Routine Description:\r
437 Get the start position of next wanted endpoint descriptor.\r
438\r
439 Arguments:\r
440 EndpointEntry - ENDPOINT_DESC_LIST_ENTRY\r
441 Buffer - Buffer to parse \r
442 BufferLength - Buffer Length\r
443 ParsedBytes - Parsed Bytes to return\r
444 Returns:\r
445 EFI_SUCCESS\r
446 EFI_DEVICE_ERROR\r
447\r
448--*/\r
449{\r
450 UINT8 *ptr;\r
451 EFI_STATUS Status;\r
452 UINTN SkipBytes;\r
453\r
454 //\r
455 // Skip some data for this interface\r
456 //\r
457 Status = GetExpectedDescriptor (\r
458 Buffer,\r
459 BufferLength,\r
460 USB_DT_ENDPOINT,\r
461 sizeof (EFI_USB_ENDPOINT_DESCRIPTOR),\r
462 &SkipBytes\r
463 );\r
464\r
465 if (EFI_ERROR (Status)) {\r
466 return Status;\r
467 }\r
468\r
469 ptr = Buffer + SkipBytes;\r
470 *ParsedBytes = SkipBytes;\r
471\r
472 CopyMem (\r
473 &EndpointEntry->EndpointDescriptor,\r
474 ptr,\r
475 sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)\r
476 );\r
477\r
478 *ParsedBytes += sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);\r
479\r
480 return EFI_SUCCESS;\r
481}\r
482\r
483STATIC\r
484EFI_STATUS\r
485ParseThisInterface (\r
486 IN INTERFACE_DESC_LIST_ENTRY *InterfaceEntry,\r
487 IN UINT8 *Buffer,\r
488 IN UINTN *BufferLen,\r
489 OUT UINTN *ParsedBytes\r
490 )\r
491/*++\r
492\r
493 Routine Description:\r
494 Get the start position of next wanted interface descriptor.\r
495\r
496 Arguments:\r
497 InterfaceEntry - INTERFACE_DESC_LIST_ENTRY\r
498 Buffer - Buffer to parse \r
499 BufferLength - Buffer Length\r
500 ParsedBytes - Parsed Bytes to return\r
501\r
502 Returns:\r
503 EFI_SUCCESS\r
504 EFI_DEVICE_ERROR\r
505\r
506--*/\r
507{\r
508 UINT8 *ptr;\r
509 UINTN SkipBytes;\r
510 UINTN Index;\r
511 UINTN Length;\r
512 UINTN Parsed;\r
513 ENDPOINT_DESC_LIST_ENTRY *EndpointEntry;\r
514 EFI_STATUS Status;\r
515\r
516 Parsed = 0;\r
517\r
518 //\r
519 // Skip some data for this interface\r
520 //\r
521 Status = GetExpectedDescriptor (\r
522 Buffer,\r
523 *BufferLen,\r
524 USB_DT_INTERFACE,\r
525 sizeof (EFI_USB_INTERFACE_DESCRIPTOR),\r
526 &SkipBytes\r
527 );\r
528\r
529 if (EFI_ERROR (Status)) {\r
530 return Status;\r
531 }\r
532\r
533 ptr = Buffer + SkipBytes;\r
534 *ParsedBytes = SkipBytes;\r
535\r
536 //\r
537 // Copy the interface descriptor\r
538 //\r
539 CopyMem (\r
540 &InterfaceEntry->InterfaceDescriptor,\r
541 ptr,\r
542 sizeof (EFI_USB_INTERFACE_DESCRIPTOR)\r
543 );\r
544\r
545 ptr = Buffer + sizeof (EFI_USB_INTERFACE_DESCRIPTOR);\r
546 *ParsedBytes += sizeof (EFI_USB_INTERFACE_DESCRIPTOR);\r
547\r
548 InitializeListHead (&InterfaceEntry->EndpointDescListHead);\r
549\r
550 Length = *BufferLen - SkipBytes - sizeof (EFI_USB_INTERFACE_DESCRIPTOR);\r
551\r
552 for (Index = 0; Index < InterfaceEntry->InterfaceDescriptor.NumEndpoints; Index++) {\r
553 EndpointEntry = AllocateZeroPool (sizeof (ENDPOINT_DESC_LIST_ENTRY));\r
554 if (EndpointEntry == NULL) {\r
555 return EFI_OUT_OF_RESOURCES;\r
556 }\r
557 \r
558 //\r
559 // Parses all the endpoint descriptors within this interface.\r
560 //\r
561 Status = ParseThisEndpoint (EndpointEntry, ptr, Length, &Parsed);\r
562\r
563 if (EFI_ERROR (Status)) {\r
564 gBS->FreePool (EndpointEntry);\r
565 return Status;\r
566 }\r
567\r
568 InsertTailList (\r
569 &InterfaceEntry->EndpointDescListHead,\r
570 &EndpointEntry->Link\r
571 );\r
572\r
573 Length -= Parsed;\r
574 ptr += Parsed;\r
575 *ParsedBytes += Parsed;\r
576 }\r
577\r
578 return EFI_SUCCESS;\r
579}\r
580\r
581STATIC\r
582EFI_STATUS\r
583ParseThisConfig (\r
584 IN CONFIG_DESC_LIST_ENTRY *ConfigDescEntry,\r
585 IN UINT8 *Buffer,\r
586 IN UINTN Length\r
587 )\r
588/*++\r
589\r
590 Routine Description:\r
591 Parse the current configuration descriptior.\r
592\r
593 Arguments:\r
594 ConfigDescEntry - CONFIG_DESC_LIST_ENTRY\r
595 Buffer - Buffer to parse \r
596 Length - Buffer Length\r
597\r
598 Returns\r
599 EFI_SUCCESS\r
600 EFI_DEVICE_ERROR\r
601\r
602--*/\r
603{\r
604 UINT8 *ptr;\r
605 UINT8 NumInterface;\r
606 UINTN Index;\r
607 INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;\r
608 UINTN SkipBytes;\r
609 UINTN Parsed;\r
610 EFI_STATUS Status;\r
611 UINTN LengthLeft;\r
612\r
613 Parsed = 0;\r
614\r
615 //\r
616 // First skip the current config descriptor;\r
617 //\r
618 Status = GetExpectedDescriptor (\r
619 Buffer,\r
620 Length,\r
621 USB_DT_CONFIG,\r
622 sizeof (EFI_USB_CONFIG_DESCRIPTOR),\r
623 &SkipBytes\r
624 );\r
625\r
626 if (EFI_ERROR (Status)) {\r
627 return Status;\r
628 }\r
629\r
630 ptr = Buffer + SkipBytes;\r
631\r
632 CopyMem (\r
633 &ConfigDescEntry->CongfigDescriptor,\r
634 ptr,\r
635 sizeof (EFI_USB_CONFIG_DESCRIPTOR)\r
636 );\r
637\r
638 NumInterface = ConfigDescEntry->CongfigDescriptor.NumInterfaces;\r
639\r
640 //\r
641 // Skip size of Configuration Descriptor\r
642 //\r
643 ptr += sizeof (EFI_USB_CONFIG_DESCRIPTOR);\r
644\r
645 LengthLeft = Length - SkipBytes - sizeof (EFI_USB_CONFIG_DESCRIPTOR);\r
646\r
647 for (Index = 0; Index < NumInterface; Index++) {\r
648 //\r
649 // Parse all Interface\r
650 //\r
651 InterfaceEntry = AllocateZeroPool (sizeof (INTERFACE_DESC_LIST_ENTRY));\r
652 if (InterfaceEntry == NULL) {\r
653 return EFI_OUT_OF_RESOURCES;\r
654 }\r
655\r
656 Status = ParseThisInterface (InterfaceEntry, ptr, &LengthLeft, &Parsed);\r
657 if (EFI_ERROR (Status)) {\r
658 gBS->FreePool (InterfaceEntry);\r
659 return Status;\r
660 }\r
661\r
662 InsertTailList (\r
663 &ConfigDescEntry->InterfaceDescListHead,\r
664 &InterfaceEntry->Link\r
665 );\r
666\r
667 //\r
668 // Parsed for next interface\r
669 //\r
670 LengthLeft -= Parsed;\r
671 ptr += Parsed;\r
672 }\r
673 //\r
674 // Parse for additional alt setting;\r
675 //\r
676 return EFI_SUCCESS;\r
677}\r
678\r
679EFI_STATUS\r
680UsbSetConfiguration (\r
681 IN USB_IO_DEVICE *UsbIoDev,\r
682 IN UINTN ConfigurationValue\r
683 )\r
684/*++\r
685\r
686 Routine Description:\r
687 Set the device to a configuration value.\r
688 \r
689 Arguments:\r
690 UsbIoDev - USB_IO_DEVICE to be set configuration\r
691 ConfigrationValue - The configuration value to be set to that device\r
692 \r
693 Returns:\r
694 EFI_SUCCESS\r
695 EFI_DEVICE_ERROR\r
696 \r
697--*/\r
698{\r
699 LIST_ENTRY *NextEntry;\r
700 CONFIG_DESC_LIST_ENTRY *ConfigEntry;\r
701 UINT32 Status;\r
702 EFI_STATUS Result;\r
703 EFI_USB_IO_PROTOCOL *UsbIo;\r
704\r
705 UsbIo = &(UsbIoDev->UsbController[0]->UsbIo);\r
706 NextEntry = UsbIoDev->ConfigDescListHead.ForwardLink;\r
707\r
708 while (NextEntry != &UsbIoDev->ConfigDescListHead) {\r
709 //\r
710 // Get one entry\r
711 //\r
712 ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;\r
713 if (ConfigEntry->CongfigDescriptor.ConfigurationValue == ConfigurationValue) {\r
714 //\r
715 // Find one, set to the active configuration\r
716 //\r
717 UsbIoDev->ActiveConfig = ConfigEntry;\r
718 break;\r
719 }\r
720\r
721 NextEntry = NextEntry->ForwardLink;\r
722 }\r
723 //\r
724 // Next Entry should not be null\r
725 //\r
726 Result = UsbSetDeviceConfiguration (\r
727 UsbIo,\r
728 (UINT16) ConfigurationValue,\r
729 &Status\r
730 );\r
731\r
732 return Result;\r
733}\r
734\r
735EFI_STATUS\r
736UsbSetDefaultConfiguration (\r
737 IN USB_IO_DEVICE *UsbIoDev\r
738 )\r
739/*++\r
740\r
741 Routine Description:\r
742 Set the device to a default configuration value.\r
743 \r
744 Arguments:\r
745 UsbIoDev - USB_IO_DEVICE to be set configuration\r
746 \r
747 Returns\r
748 EFI_SUCCESS\r
749 EFI_DEVICE_ERROR\r
750 \r
751--*/\r
752{\r
753 CONFIG_DESC_LIST_ENTRY *ConfigEntry;\r
754 UINT16 ConfigValue;\r
755 LIST_ENTRY *NextEntry;\r
756\r
757 if (IsListEmpty (&UsbIoDev->ConfigDescListHead)) {\r
758 return EFI_DEVICE_ERROR;\r
759 }\r
760\r
761 NextEntry = UsbIoDev->ConfigDescListHead.ForwardLink;\r
762\r
763 ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;\r
764 ConfigValue = ConfigEntry->CongfigDescriptor.ConfigurationValue;\r
765\r
766 return UsbSetConfiguration (UsbIoDev, ConfigValue);\r
767}\r
768\r
769VOID\r
770UsbDestroyAllConfiguration (\r
771 IN USB_IO_DEVICE *UsbIoDevice\r
772 )\r
773/*++\r
774\r
775 Routine Description:\r
776 Delete all configuration data when device is not used.\r
777 \r
778 Arguments:\r
779 UsbIoDevice - USB_IO_DEVICE to be set configuration\r
780 \r
781 Returns:\r
782 N/A\r
783 \r
784--*/\r
785{\r
786 CONFIG_DESC_LIST_ENTRY *ConfigEntry;\r
787 INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;\r
788 ENDPOINT_DESC_LIST_ENTRY *EndpointEntry;\r
789 LIST_ENTRY *NextEntry;\r
790\r
791 //\r
792 // Delete all configuration descriptor data\r
793 //\r
794 ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) UsbIoDevice->ConfigDescListHead.ForwardLink;\r
795\r
796 while (ConfigEntry != (CONFIG_DESC_LIST_ENTRY *) &UsbIoDevice->ConfigDescListHead) {\r
797 //\r
798 // Delete all its interface descriptors\r
799 //\r
800 InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *) ConfigEntry->InterfaceDescListHead.ForwardLink;\r
801\r
802 while (InterfaceEntry != (INTERFACE_DESC_LIST_ENTRY *) &ConfigEntry->InterfaceDescListHead) {\r
803 //\r
804 // Delete all its endpoint descriptors\r
805 //\r
806 EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *) InterfaceEntry->EndpointDescListHead.ForwardLink;\r
807 while (EndpointEntry != (ENDPOINT_DESC_LIST_ENTRY *) &InterfaceEntry->EndpointDescListHead) {\r
808 NextEntry = ((LIST_ENTRY *) EndpointEntry)->ForwardLink;\r
809 RemoveEntryList ((LIST_ENTRY *) EndpointEntry);\r
810 gBS->FreePool (EndpointEntry);\r
811 EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *) NextEntry;\r
812 }\r
813\r
814 NextEntry = ((LIST_ENTRY *) InterfaceEntry)->ForwardLink;\r
815 RemoveEntryList ((LIST_ENTRY *) InterfaceEntry);\r
816 gBS->FreePool (InterfaceEntry);\r
817 InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *) NextEntry;\r
818 }\r
819\r
820 NextEntry = ((LIST_ENTRY *) ConfigEntry)->ForwardLink;\r
821 RemoveEntryList ((LIST_ENTRY *) ConfigEntry);\r
822 gBS->FreePool (ConfigEntry);\r
823 ConfigEntry = (CONFIG_DESC_LIST_ENTRY *) NextEntry;\r
824 }\r
825}\r