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