1 /** @file 2 Main file for support of shell consist mapping. 3 4 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 **/ 13 14 #include "UefiShellCommandLib.h" 15 #include <Library/DevicePathLib.h> 16 #include <Library/SortLib.h> 17 #include <Library/UefiLib.h> 18 #include <Protocol/UsbIo.h> 19 #include <Protocol/BlockIo.h> 20 #include <Protocol/SimpleFileSystem.h> 21 22 23 24 typedef enum { 25 MTDTypeUnknown, 26 MTDTypeFloppy, 27 MTDTypeHardDisk, 28 MTDTypeCDRom, 29 MTDTypeEnd 30 } MTD_TYPE; 31 32 typedef struct { 33 CHAR16 *Str; 34 UINTN Len; 35 } POOL_PRINT; 36 37 typedef struct { 38 UINTN Hi; 39 MTD_TYPE Mtd; 40 POOL_PRINT Csd; 41 BOOLEAN Digital; 42 } DEVICE_CONSIST_MAPPING_INFO; 43 44 typedef struct { 45 MTD_TYPE MTDType; 46 CHAR16 *Name; 47 } MTD_NAME; 48 49 /** 50 Serial Decode function. 51 52 @param DevPath The Device path info. 53 @param MapInfo The map info. 54 @param OrigDevPath The original device path protocol. 55 56 **/ 57 typedef 58 VOID 59 (EFIAPI *SERIAL_DECODE_FUNCTION) ( 60 EFI_DEVICE_PATH_PROTOCOL *DevPath, 61 DEVICE_CONSIST_MAPPING_INFO *MapInfo, 62 EFI_DEVICE_PATH_PROTOCOL *OrigDevPath 63 ); 64 65 typedef struct { 66 UINT8 Type; 67 UINT8 SubType; 68 SERIAL_DECODE_FUNCTION SerialFun; 69 INTN (EFIAPI *CompareFun) (EFI_DEVICE_PATH_PROTOCOL *DevPath, EFI_DEVICE_PATH_PROTOCOL *DevPath2); 70 } DEV_PATH_CONSIST_MAPPING_TABLE; 71 72 73 /** 74 Concatenates a formatted unicode string to allocated pool. 75 The caller must free the resulting buffer. 76 77 @param Str Tracks the allocated pool, size in use, and amount of pool allocated. 78 @param Fmt The format string 79 @param ... The data will be printed. 80 81 @return Allocated buffer with the formatted string printed in it. 82 The caller must free the allocated buffer. 83 The buffer allocation is not packed. 84 85 **/ 86 CHAR16 * 87 EFIAPI 88 CatPrint ( 89 IN OUT POOL_PRINT *Str, 90 IN CHAR16 *Fmt, 91 ... 92 ) 93 { 94 UINT16 *AppendStr; 95 VA_LIST Args; 96 UINTN StringSize; 97 98 AppendStr = AllocateZeroPool (0x1000); 99 if (AppendStr == NULL) { 100 ASSERT(FALSE); 101 return Str->Str; 102 } 103 104 VA_START (Args, Fmt); 105 UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args); 106 VA_END (Args); 107 if (NULL == Str->Str) { 108 StringSize = StrSize (AppendStr); 109 Str->Str = AllocateZeroPool (StringSize); 110 ASSERT (Str->Str != NULL); 111 } else { 112 StringSize = StrSize (AppendStr); 113 StringSize += (StrSize (Str->Str) - sizeof (UINT16)); 114 115 Str->Str = ReallocatePool ( 116 StrSize (Str->Str), 117 StringSize, 118 Str->Str 119 ); 120 ASSERT (Str->Str != NULL); 121 } 122 123 StrCatS (Str->Str, StringSize/sizeof(CHAR16), AppendStr); 124 Str->Len = StringSize; 125 126 FreePool (AppendStr); 127 return Str->Str; 128 } 129 130 MTD_NAME mMTDName[] = { 131 { 132 MTDTypeUnknown, 133 L"F" 134 }, 135 { 136 MTDTypeFloppy, 137 L"FP" 138 }, 139 { 140 MTDTypeHardDisk, 141 L"HD" 142 }, 143 { 144 MTDTypeCDRom, 145 L"CD" 146 }, 147 { 148 MTDTypeEnd, 149 NULL 150 } 151 }; 152 153 /** 154 Function to append a 64 bit number / 25 onto the string. 155 156 @param[in, out] Str The string so append onto. 157 @param[in] Num The number to divide and append. 158 159 @retval EFI_INVALID_PARAMETER A parameter was NULL. 160 @retval EFI_SUCCESS The appending was successful. 161 **/ 162 EFI_STATUS 163 EFIAPI 164 AppendCSDNum2 ( 165 IN OUT POOL_PRINT *Str, 166 IN UINT64 Num 167 ) 168 { 169 UINT64 Result; 170 UINT32 Rem; 171 172 if (Str == NULL) { 173 return (EFI_INVALID_PARAMETER); 174 } 175 176 Result = DivU64x32Remainder (Num, 25, &Rem); 177 if (Result > 0) { 178 AppendCSDNum2 (Str, Result); 179 } 180 181 CatPrint (Str, L"%c", Rem + 'a'); 182 return (EFI_SUCCESS); 183 } 184 185 /** 186 Function to append a 64 bit number onto the mapping info. 187 188 @param[in, out] MappingItem The mapping info object to append onto. 189 @param[in] Num The info to append. 190 191 @retval EFI_INVALID_PARAMETER A parameter was NULL. 192 @retval EFI_SUCCESS The appending was successful. 193 **/ 194 EFI_STATUS 195 EFIAPI 196 AppendCSDNum ( 197 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem, 198 IN UINT64 Num 199 ) 200 { 201 if (MappingItem == NULL) { 202 return EFI_INVALID_PARAMETER; 203 } 204 205 if (MappingItem->Digital) { 206 CatPrint (&MappingItem->Csd, L"%ld", Num); 207 } else { 208 AppendCSDNum2 (&MappingItem->Csd, Num); 209 } 210 211 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital); 212 213 return (EFI_SUCCESS); 214 } 215 216 /** 217 Function to append string into the mapping info. 218 219 @param[in, out] MappingItem The mapping info object to append onto. 220 @param[in] Str The info to append. 221 222 @retval EFI_INVALID_PARAMETER A parameter was NULL. 223 @retval EFI_SUCCESS The appending was successful. 224 **/ 225 EFI_STATUS 226 EFIAPI 227 AppendCSDStr ( 228 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem, 229 IN CHAR16 *Str 230 ) 231 { 232 CHAR16 *Index; 233 234 if (Str == NULL || MappingItem == NULL) { 235 return (EFI_INVALID_PARAMETER); 236 } 237 238 if (MappingItem->Digital) { 239 // 240 // To aVOID mult-meaning, the mapping is: 241 // 0 1 2 3 4 5 6 7 8 9 a b c d e f 242 // 0 16 2 3 4 5 6 7 8 9 10 11 12 13 14 15 243 // 244 for (Index = Str; *Index != 0; Index++) { 245 switch (*Index) { 246 case '0': 247 case '2': 248 case '3': 249 case '4': 250 case '5': 251 case '6': 252 case '7': 253 case '8': 254 case '9': 255 CatPrint (&MappingItem->Csd, L"%c", *Index); 256 break; 257 258 case '1': 259 CatPrint (&MappingItem->Csd, L"16"); 260 break; 261 262 case 'a': 263 case 'b': 264 case 'c': 265 case 'd': 266 case 'e': 267 case 'f': 268 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'a' + '0'); 269 break; 270 271 case 'A': 272 case 'B': 273 case 'C': 274 case 'D': 275 case 'E': 276 case 'F': 277 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'A' + '0'); 278 break; 279 } 280 } 281 } else { 282 for (Index = Str; *Index != 0; Index++) { 283 // 284 // The mapping is: 285 // 0 1 2 3 4 5 6 7 8 9 a b c d e f 286 // a b c d e f g h i j k l m n o p 287 // 288 if (*Index >= '0' && *Index <= '9') { 289 CatPrint (&MappingItem->Csd, L"%c", *Index - '0' + 'a'); 290 } else if (*Index >= 'a' && *Index <= 'f') { 291 CatPrint (&MappingItem->Csd, L"%c", *Index - 'a' + 'k'); 292 } else if (*Index >= 'A' && *Index <= 'F') { 293 CatPrint (&MappingItem->Csd, L"%c", *Index - 'A' + 'k'); 294 } 295 } 296 } 297 298 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital); 299 300 return (EFI_SUCCESS); 301 } 302 303 /** 304 Function to append a Guid to the mapping item. 305 306 @param[in, out] MappingItem The item to append onto. 307 @param[in] Guid The guid to append. 308 309 @retval EFI_SUCCESS The appending operation was successful. 310 @retval EFI_INVALID_PARAMETER A parameter was NULL. 311 **/ 312 EFI_STATUS 313 EFIAPI 314 AppendCSDGuid ( 315 DEVICE_CONSIST_MAPPING_INFO *MappingItem, 316 EFI_GUID *Guid 317 ) 318 { 319 CHAR16 Buffer[64]; 320 321 if (Guid == NULL || MappingItem == NULL) { 322 return (EFI_INVALID_PARAMETER); 323 } 324 325 UnicodeSPrint ( 326 Buffer, 327 0, 328 L"%g", 329 Guid 330 ); 331 332 AppendCSDStr (MappingItem, Buffer); 333 334 return (EFI_SUCCESS); 335 } 336 337 /** 338 Function to compare 2 APCI device paths. 339 340 @param[in] DevicePath1 The first device path to compare. 341 @param[in] DevicePath2 The second device path to compare. 342 343 @retval 0 The device paths represent the same device. 344 @return Non zero if the devices are different, zero otherwise. 345 **/ 346 INTN 347 EFIAPI 348 DevPathCompareAcpi ( 349 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, 350 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 351 ) 352 { 353 ACPI_HID_DEVICE_PATH *Acpi1; 354 ACPI_HID_DEVICE_PATH *Acpi2; 355 356 if (DevicePath1 == NULL || DevicePath2 == NULL) { 357 return (-2); 358 } 359 360 Acpi1 = (ACPI_HID_DEVICE_PATH *) DevicePath1; 361 Acpi2 = (ACPI_HID_DEVICE_PATH *) DevicePath2; 362 if (Acpi1->HID > Acpi2->HID || (Acpi1->HID == Acpi2->HID && Acpi1->UID > Acpi2->UID)) { 363 return 1; 364 } 365 366 if (Acpi1->HID == Acpi2->HID && Acpi1->UID == Acpi2->UID) { 367 return 0; 368 } 369 370 return -1; 371 } 372 373 /** 374 Function to compare 2 PCI device paths. 375 376 @param[in] DevicePath1 The first device path to compare. 377 @param[in] DevicePath2 The second device path to compare. 378 379 @retval 0 The device paths represent the same device. 380 @return Non zero if the devices are different, zero otherwise. 381 **/ 382 INTN 383 EFIAPI 384 DevPathComparePci ( 385 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, 386 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 387 ) 388 { 389 PCI_DEVICE_PATH *Pci1; 390 PCI_DEVICE_PATH *Pci2; 391 392 ASSERT(DevicePath1 != NULL); 393 ASSERT(DevicePath2 != NULL); 394 395 Pci1 = (PCI_DEVICE_PATH *) DevicePath1; 396 Pci2 = (PCI_DEVICE_PATH *) DevicePath2; 397 if (Pci1->Device > Pci2->Device || (Pci1->Device == Pci2->Device && Pci1->Function > Pci2->Function)) { 398 return 1; 399 } 400 401 if (Pci1->Device == Pci2->Device && Pci1->Function == Pci2->Function) { 402 return 0; 403 } 404 405 return -1; 406 } 407 408 /** 409 Do a comparison on 2 device paths. 410 411 @param[in] DevicePath1 The first device path. 412 @param[in] DevicePath2 The second device path. 413 414 @retval 0 The 2 device paths are the same. 415 @retval <0 DevicePath2 is greater than DevicePath1. 416 @retval >0 DevicePath1 is greater than DevicePath2. 417 **/ 418 INTN 419 EFIAPI 420 DevPathCompareDefault ( 421 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, 422 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 423 ) 424 { 425 UINTN DevPathSize1; 426 UINTN DevPathSize2; 427 428 ASSERT(DevicePath1 != NULL); 429 ASSERT(DevicePath2 != NULL); 430 431 DevPathSize1 = DevicePathNodeLength (DevicePath1); 432 DevPathSize2 = DevicePathNodeLength (DevicePath2); 433 if (DevPathSize1 > DevPathSize2) { 434 return 1; 435 } else if (DevPathSize1 < DevPathSize2) { 436 return -1; 437 } else { 438 return CompareMem (DevicePath1, DevicePath2, DevPathSize1); 439 } 440 } 441 442 /** 443 DevicePathNode must be SerialHDD Channel type and this will populate the MappingItem. 444 445 @param[in] DevicePathNode The node to get info on. 446 @param[in] MappingItem The info item to populate. 447 @param[in] DevicePath Ignored. 448 **/ 449 VOID 450 EFIAPI 451 DevPathSerialHardDrive ( 452 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 453 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 454 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 455 ) 456 { 457 HARDDRIVE_DEVICE_PATH *Hd; 458 459 ASSERT(DevicePathNode != NULL); 460 ASSERT(MappingItem != NULL); 461 462 Hd = (HARDDRIVE_DEVICE_PATH *) DevicePathNode; 463 if (MappingItem->Mtd == MTDTypeUnknown) { 464 MappingItem->Mtd = MTDTypeHardDisk; 465 } 466 467 AppendCSDNum (MappingItem, Hd->PartitionNumber); 468 } 469 470 /** 471 DevicePathNode must be SerialAtapi Channel type and this will populate the MappingItem. 472 473 @param[in] DevicePathNode The node to get info on. 474 @param[in] MappingItem The info item to populate. 475 @param[in] DevicePath Ignored. 476 **/ 477 VOID 478 EFIAPI 479 DevPathSerialAtapi ( 480 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 481 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 482 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 483 ) 484 { 485 ATAPI_DEVICE_PATH *Atapi; 486 487 ASSERT(DevicePathNode != NULL); 488 ASSERT(MappingItem != NULL); 489 490 Atapi = (ATAPI_DEVICE_PATH *) DevicePathNode; 491 AppendCSDNum (MappingItem, (Atapi->PrimarySecondary * 2 + Atapi->SlaveMaster)); 492 } 493 494 /** 495 DevicePathNode must be SerialCDROM Channel type and this will populate the MappingItem. 496 497 @param[in] DevicePathNode The node to get info on. 498 @param[in] MappingItem The info item to populate. 499 @param[in] DevicePath Ignored. 500 **/ 501 VOID 502 EFIAPI 503 DevPathSerialCdRom ( 504 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 505 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 506 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 507 ) 508 { 509 CDROM_DEVICE_PATH *Cd; 510 511 ASSERT(DevicePathNode != NULL); 512 ASSERT(MappingItem != NULL); 513 514 Cd = (CDROM_DEVICE_PATH *) DevicePathNode; 515 MappingItem->Mtd = MTDTypeCDRom; 516 AppendCSDNum (MappingItem, Cd->BootEntry); 517 } 518 519 /** 520 DevicePathNode must be SerialFibre Channel type and this will populate the MappingItem. 521 522 @param[in] DevicePathNode The node to get info on. 523 @param[in] MappingItem The info item to populate. 524 @param[in] DevicePath Ignored. 525 **/ 526 VOID 527 EFIAPI 528 DevPathSerialFibre ( 529 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 530 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 531 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 532 ) 533 { 534 FIBRECHANNEL_DEVICE_PATH *Fibre; 535 536 ASSERT(DevicePathNode != NULL); 537 ASSERT(MappingItem != NULL); 538 539 Fibre = (FIBRECHANNEL_DEVICE_PATH *) DevicePathNode; 540 AppendCSDNum (MappingItem, Fibre->WWN); 541 AppendCSDNum (MappingItem, Fibre->Lun); 542 } 543 544 /** 545 DevicePathNode must be SerialUart type and this will populate the MappingItem. 546 547 @param[in] DevicePathNode The node to get info on. 548 @param[in] MappingItem The info item to populate. 549 @param[in] DevicePath Ignored. 550 **/ 551 VOID 552 EFIAPI 553 DevPathSerialUart ( 554 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 555 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 556 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 557 ) 558 { 559 UART_DEVICE_PATH *Uart; 560 561 ASSERT(DevicePathNode != NULL); 562 ASSERT(MappingItem != NULL); 563 564 Uart = (UART_DEVICE_PATH *) DevicePathNode; 565 AppendCSDNum (MappingItem, Uart->BaudRate); 566 AppendCSDNum (MappingItem, Uart->DataBits); 567 AppendCSDNum (MappingItem, Uart->Parity); 568 AppendCSDNum (MappingItem, Uart->StopBits); 569 } 570 571 /** 572 DevicePathNode must be SerialUSB type and this will populate the MappingItem. 573 574 @param[in] DevicePathNode The node to get info on. 575 @param[in] MappingItem The info item to populate. 576 @param[in] DevicePath Ignored. 577 **/ 578 VOID 579 EFIAPI 580 DevPathSerialUsb ( 581 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 582 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 583 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 584 ) 585 { 586 USB_DEVICE_PATH *Usb; 587 EFI_USB_IO_PROTOCOL *UsbIo; 588 EFI_HANDLE TempHandle; 589 EFI_STATUS Status; 590 USB_INTERFACE_DESCRIPTOR InterfaceDesc; 591 592 593 ASSERT(DevicePathNode != NULL); 594 ASSERT(MappingItem != NULL); 595 596 Usb = (USB_DEVICE_PATH *) DevicePathNode; 597 AppendCSDNum (MappingItem, Usb->ParentPortNumber); 598 AppendCSDNum (MappingItem, Usb->InterfaceNumber); 599 600 if (PcdGetBool(PcdUsbExtendedDecode)) { 601 Status = gBS->LocateDevicePath( &gEfiUsbIoProtocolGuid, &DevicePath, &TempHandle ); 602 UsbIo = NULL; 603 if (!EFI_ERROR(Status)) { 604 Status = gBS->OpenProtocol(TempHandle, &gEfiUsbIoProtocolGuid, (VOID**)&UsbIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); 605 } 606 607 if (!EFI_ERROR(Status)) { 608 ASSERT(UsbIo != NULL); 609 Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &InterfaceDesc); 610 if (!EFI_ERROR(Status)) { 611 if (InterfaceDesc.InterfaceClass == USB_MASS_STORE_CLASS && MappingItem->Mtd == MTDTypeUnknown) { 612 switch (InterfaceDesc.InterfaceSubClass){ 613 case USB_MASS_STORE_SCSI: 614 MappingItem->Mtd = MTDTypeHardDisk; 615 break; 616 case USB_MASS_STORE_8070I: 617 case USB_MASS_STORE_UFI: 618 MappingItem->Mtd = MTDTypeFloppy; 619 break; 620 case USB_MASS_STORE_8020I: 621 MappingItem->Mtd = MTDTypeCDRom; 622 break; 623 } 624 } 625 } 626 } 627 } 628 } 629 630 /** 631 DevicePathNode must be SerialVendor type and this will populate the MappingItem. 632 633 @param[in] DevicePathNode The node to get info on. 634 @param[in] MappingItem The info item to populate. 635 @param[in] DevicePath Ignored. 636 637 **/ 638 VOID 639 EFIAPI 640 DevPathSerialVendor ( 641 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 642 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 643 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 644 ) 645 { 646 VENDOR_DEVICE_PATH *Vendor; 647 SAS_DEVICE_PATH *Sas; 648 UINTN TargetNameLength; 649 UINTN Index; 650 CHAR16 *Buffer; 651 652 if (DevicePathNode == NULL || MappingItem == NULL) { 653 return; 654 } 655 656 Vendor = (VENDOR_DEVICE_PATH *) DevicePathNode; 657 AppendCSDGuid (MappingItem, &Vendor->Guid); 658 659 if (CompareGuid (&gEfiSasDevicePathGuid, &Vendor->Guid)) { 660 Sas = (SAS_DEVICE_PATH *) Vendor; 661 AppendCSDNum (MappingItem, Sas->SasAddress); 662 AppendCSDNum (MappingItem, Sas->Lun); 663 AppendCSDNum (MappingItem, Sas->DeviceTopology); 664 AppendCSDNum (MappingItem, Sas->RelativeTargetPort); 665 } else { 666 TargetNameLength = MIN(DevicePathNodeLength (DevicePathNode) - sizeof (VENDOR_DEVICE_PATH), PcdGet32(PcdShellVendorExtendedDecode)); 667 if (TargetNameLength != 0) { 668 // 669 // String is 2 chars per data byte, plus NULL terminator 670 // 671 Buffer = AllocateZeroPool (((TargetNameLength * 2) + 1) * sizeof(CHAR16)); 672 ASSERT(Buffer != NULL); 673 if (Buffer == NULL) { 674 return; 675 } 676 677 // 678 // Build the string data 679 // 680 for (Index = 0; Index < TargetNameLength; Index++) { 681 Buffer = CatSPrint (Buffer, L"%02x", *((UINT8*)Vendor + sizeof (VENDOR_DEVICE_PATH) + Index)); 682 } 683 684 // 685 // Append the new data block 686 // 687 AppendCSDStr (MappingItem, Buffer); 688 689 FreePool(Buffer); 690 } 691 } 692 } 693 694 /** 695 DevicePathNode must be SerialLun type and this will populate the MappingItem. 696 697 @param[in] DevicePathNode The node to get info on. 698 @param[in] MappingItem The info item to populate. 699 @param[in] DevicePath Ignored. 700 **/ 701 VOID 702 EFIAPI 703 DevPathSerialLun ( 704 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 705 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 706 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 707 ) 708 { 709 DEVICE_LOGICAL_UNIT_DEVICE_PATH *Lun; 710 711 ASSERT(DevicePathNode != NULL); 712 ASSERT(MappingItem != NULL); 713 714 Lun = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) DevicePathNode; 715 AppendCSDNum (MappingItem, Lun->Lun); 716 } 717 718 /** 719 DevicePathNode must be SerialSata type and this will populate the MappingItem. 720 721 @param[in] DevicePathNode The node to get info on. 722 @param[in] MappingItem The info item to populate. 723 @param[in] DevicePath Ignored. 724 **/ 725 VOID 726 EFIAPI 727 DevPathSerialSata ( 728 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 729 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 730 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 731 ) 732 { 733 SATA_DEVICE_PATH *Sata; 734 735 ASSERT(DevicePathNode != NULL); 736 ASSERT(MappingItem != NULL); 737 738 Sata = (SATA_DEVICE_PATH *) DevicePathNode; 739 AppendCSDNum (MappingItem, Sata->HBAPortNumber); 740 AppendCSDNum (MappingItem, Sata->PortMultiplierPortNumber); 741 AppendCSDNum (MappingItem, Sata->Lun); 742 } 743 744 /** 745 DevicePathNode must be SerialSCSI type and this will populate the MappingItem. 746 747 @param[in] DevicePathNode The node to get info on. 748 @param[in] MappingItem The info item to populate. 749 @param[in] DevicePath Ignored. 750 **/ 751 VOID 752 EFIAPI 753 DevPathSerialIScsi ( 754 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 755 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 756 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 757 ) 758 { 759 ISCSI_DEVICE_PATH *IScsi; 760 UINT8 *IScsiTargetName; 761 CHAR16 *TargetName; 762 UINTN TargetNameLength; 763 UINTN Index; 764 765 ASSERT(DevicePathNode != NULL); 766 ASSERT(MappingItem != NULL); 767 768 if (PcdGetBool(PcdShellDecodeIScsiMapNames)) { 769 IScsi = (ISCSI_DEVICE_PATH *) DevicePathNode; 770 AppendCSDNum (MappingItem, IScsi->NetworkProtocol); 771 AppendCSDNum (MappingItem, IScsi->LoginOption); 772 AppendCSDNum (MappingItem, IScsi->Lun); 773 AppendCSDNum (MappingItem, IScsi->TargetPortalGroupTag); 774 TargetNameLength = DevicePathNodeLength (DevicePathNode) - sizeof (ISCSI_DEVICE_PATH); 775 if (TargetNameLength > 0) { 776 TargetName = AllocateZeroPool ((TargetNameLength + 1) * sizeof (CHAR16)); 777 if (TargetName != NULL) { 778 IScsiTargetName = (UINT8 *) (IScsi + 1); 779 for (Index = 0; Index < TargetNameLength; Index++) { 780 TargetName[Index] = (CHAR16) IScsiTargetName[Index]; 781 } 782 AppendCSDStr (MappingItem, TargetName); 783 FreePool (TargetName); 784 } 785 } 786 } 787 } 788 789 /** 790 DevicePathNode must be SerialI20 type and this will populate the MappingItem. 791 792 @param[in] DevicePathNode The node to get info on. 793 @param[in] MappingItem The info item to populate. 794 @param[in] DevicePath Ignored. 795 **/ 796 VOID 797 EFIAPI 798 DevPathSerialI2O ( 799 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 800 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 801 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 802 ) 803 { 804 I2O_DEVICE_PATH *DevicePath_I20; 805 806 ASSERT(DevicePathNode != NULL); 807 ASSERT(MappingItem != NULL); 808 809 DevicePath_I20 = (I2O_DEVICE_PATH *) DevicePathNode; 810 AppendCSDNum (MappingItem, DevicePath_I20->Tid); 811 } 812 813 /** 814 DevicePathNode must be Mac Address type and this will populate the MappingItem. 815 816 @param[in] DevicePathNode The node to get info on. 817 @param[in] MappingItem The info item to populate. 818 @param[in] DevicePath Ignored. 819 **/ 820 VOID 821 EFIAPI 822 DevPathSerialMacAddr ( 823 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 824 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 825 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 826 ) 827 { 828 MAC_ADDR_DEVICE_PATH *Mac; 829 UINTN HwAddressSize; 830 UINTN Index; 831 CHAR16 Buffer[64]; 832 CHAR16 *PBuffer; 833 834 ASSERT(DevicePathNode != NULL); 835 ASSERT(MappingItem != NULL); 836 837 Mac = (MAC_ADDR_DEVICE_PATH *) DevicePathNode; 838 839 HwAddressSize = sizeof (EFI_MAC_ADDRESS); 840 if (Mac->IfType == 0x01 || Mac->IfType == 0x00) { 841 HwAddressSize = 6; 842 } 843 844 for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) { 845 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Mac->MacAddress.Addr[Index]); 846 } 847 848 AppendCSDStr (MappingItem, Buffer); 849 } 850 851 /** 852 DevicePathNode must be InfiniBand type and this will populate the MappingItem. 853 854 @param[in] DevicePathNode The node to get info on. 855 @param[in] MappingItem The info item to populate. 856 @param[in] DevicePath Ignored. 857 **/ 858 VOID 859 EFIAPI 860 DevPathSerialInfiniBand ( 861 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 862 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 863 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 864 ) 865 { 866 INFINIBAND_DEVICE_PATH *InfiniBand; 867 UINTN Index; 868 CHAR16 Buffer[64]; 869 CHAR16 *PBuffer; 870 871 ASSERT(DevicePathNode != NULL); 872 ASSERT(MappingItem != NULL); 873 874 InfiniBand = (INFINIBAND_DEVICE_PATH *) DevicePathNode; 875 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) { 876 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) InfiniBand->PortGid[Index]); 877 } 878 879 AppendCSDStr (MappingItem, Buffer); 880 AppendCSDNum (MappingItem, InfiniBand->ServiceId); 881 AppendCSDNum (MappingItem, InfiniBand->TargetPortId); 882 AppendCSDNum (MappingItem, InfiniBand->DeviceId); 883 } 884 885 /** 886 DevicePathNode must be IPv4 type and this will populate the MappingItem. 887 888 @param[in] DevicePathNode The node to get info on. 889 @param[in] MappingItem The info item to populate. 890 @param[in] DevicePath Ignored. 891 **/ 892 VOID 893 EFIAPI 894 DevPathSerialIPv4 ( 895 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 896 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 897 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 898 ) 899 { 900 IPv4_DEVICE_PATH *Ip; 901 CHAR16 Buffer[10]; 902 903 ASSERT(DevicePathNode != NULL); 904 ASSERT(MappingItem != NULL); 905 906 Ip = (IPv4_DEVICE_PATH *) DevicePathNode; 907 UnicodeSPrint ( 908 Buffer, 909 0, 910 L"%02x%02x%02x%02x", 911 (UINTN) Ip->LocalIpAddress.Addr[0], 912 (UINTN) Ip->LocalIpAddress.Addr[1], 913 (UINTN) Ip->LocalIpAddress.Addr[2], 914 (UINTN) Ip->LocalIpAddress.Addr[3] 915 ); 916 AppendCSDStr (MappingItem, Buffer); 917 AppendCSDNum (MappingItem, Ip->LocalPort); 918 UnicodeSPrint ( 919 Buffer, 920 0, 921 L"%02x%02x%02x%02x", 922 (UINTN) Ip->RemoteIpAddress.Addr[0], 923 (UINTN) Ip->RemoteIpAddress.Addr[1], 924 (UINTN) Ip->RemoteIpAddress.Addr[2], 925 (UINTN) Ip->RemoteIpAddress.Addr[3] 926 ); 927 AppendCSDStr (MappingItem, Buffer); 928 AppendCSDNum (MappingItem, Ip->RemotePort); 929 } 930 931 /** 932 DevicePathNode must be IPv6 type and this will populate the MappingItem. 933 934 @param[in] DevicePathNode The node to get info on. 935 @param[in] MappingItem The info item to populate. 936 @param[in] DevicePath Ignored. 937 938 **/ 939 VOID 940 EFIAPI 941 DevPathSerialIPv6 ( 942 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 943 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 944 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 945 ) 946 { 947 IPv6_DEVICE_PATH *Ip; 948 UINTN Index; 949 CHAR16 Buffer[64]; 950 CHAR16 *PBuffer; 951 952 ASSERT(DevicePathNode != NULL); 953 ASSERT(MappingItem != NULL); 954 955 Ip = (IPv6_DEVICE_PATH *) DevicePathNode; 956 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) { 957 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->LocalIpAddress.Addr[Index]); 958 } 959 960 AppendCSDStr (MappingItem, Buffer); 961 AppendCSDNum (MappingItem, Ip->LocalPort); 962 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) { 963 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->RemoteIpAddress.Addr[Index]); 964 } 965 966 AppendCSDStr (MappingItem, Buffer); 967 AppendCSDNum (MappingItem, Ip->RemotePort); 968 } 969 970 /** 971 DevicePathNode must be SCSI type and this will populate the MappingItem. 972 973 @param[in] DevicePathNode The node to get info on. 974 @param[in] MappingItem The info item to populate. 975 @param[in] DevicePath Ignored. 976 977 **/ 978 VOID 979 EFIAPI 980 DevPathSerialScsi ( 981 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 982 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 983 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 984 ) 985 { 986 SCSI_DEVICE_PATH *Scsi; 987 988 ASSERT(DevicePathNode != NULL); 989 ASSERT(MappingItem != NULL); 990 991 Scsi = (SCSI_DEVICE_PATH *) DevicePathNode; 992 AppendCSDNum (MappingItem, Scsi->Pun); 993 AppendCSDNum (MappingItem, Scsi->Lun); 994 } 995 996 /** 997 DevicePathNode must be 1394 type and this will populate the MappingItem. 998 999 @param[in] DevicePathNode The node to get info on. 1000 @param[in] MappingItem The info item to populate. 1001 @param[in] DevicePath Ignored. 1002 **/ 1003 VOID 1004 EFIAPI 1005 DevPathSerial1394 ( 1006 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 1007 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 1008 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 1009 ) 1010 { 1011 F1394_DEVICE_PATH *DevicePath_F1394; 1012 CHAR16 Buffer[20]; 1013 1014 ASSERT(DevicePathNode != NULL); 1015 ASSERT(MappingItem != NULL); 1016 1017 DevicePath_F1394 = (F1394_DEVICE_PATH *) DevicePathNode; 1018 UnicodeSPrint (Buffer, 0, L"%lx", DevicePath_F1394->Guid); 1019 AppendCSDStr (MappingItem, Buffer); 1020 } 1021 1022 /** 1023 If the node is floppy type then populate the MappingItem. 1024 1025 @param[in] DevicePathNode The node to get info on. 1026 @param[in] MappingItem The info item to populate. 1027 @param[in] DevicePath Ignored. 1028 **/ 1029 VOID 1030 EFIAPI 1031 DevPathSerialAcpi ( 1032 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 1033 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 1034 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 1035 ) 1036 { 1037 ACPI_HID_DEVICE_PATH *Acpi; 1038 1039 ASSERT(DevicePathNode != NULL); 1040 ASSERT(MappingItem != NULL); 1041 1042 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode; 1043 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) { 1044 if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) { 1045 MappingItem->Mtd = MTDTypeFloppy; 1046 AppendCSDNum (MappingItem, Acpi->UID); 1047 } 1048 } 1049 } 1050 1051 /** 1052 Empty function used for unknown devices. 1053 1054 @param[in] DevicePathNode Ignored. 1055 @param[in] MappingItem Ignored. 1056 @param[in] DevicePath Ignored. 1057 1058 Does nothing. 1059 **/ 1060 VOID 1061 EFIAPI 1062 DevPathSerialDefault ( 1063 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode, 1064 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 1065 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 1066 ) 1067 { 1068 return; 1069 } 1070 1071 DEV_PATH_CONSIST_MAPPING_TABLE DevPathConsistMappingTable[] = { 1072 { 1073 HARDWARE_DEVICE_PATH, 1074 HW_PCI_DP, 1075 DevPathSerialDefault, 1076 DevPathComparePci 1077 }, 1078 { 1079 ACPI_DEVICE_PATH, 1080 ACPI_DP, 1081 DevPathSerialAcpi, 1082 DevPathCompareAcpi 1083 }, 1084 { 1085 MESSAGING_DEVICE_PATH, 1086 MSG_ATAPI_DP, 1087 DevPathSerialAtapi, 1088 DevPathCompareDefault 1089 }, 1090 { 1091 MESSAGING_DEVICE_PATH, 1092 MSG_SCSI_DP, 1093 DevPathSerialScsi, 1094 DevPathCompareDefault 1095 }, 1096 { 1097 MESSAGING_DEVICE_PATH, 1098 MSG_FIBRECHANNEL_DP, 1099 DevPathSerialFibre, 1100 DevPathCompareDefault 1101 }, 1102 { 1103 MESSAGING_DEVICE_PATH, 1104 MSG_1394_DP, 1105 DevPathSerial1394, 1106 DevPathCompareDefault 1107 }, 1108 { 1109 MESSAGING_DEVICE_PATH, 1110 MSG_USB_DP, 1111 DevPathSerialUsb, 1112 DevPathCompareDefault 1113 }, 1114 { 1115 MESSAGING_DEVICE_PATH, 1116 MSG_I2O_DP, 1117 DevPathSerialI2O, 1118 DevPathCompareDefault 1119 }, 1120 { 1121 MESSAGING_DEVICE_PATH, 1122 MSG_MAC_ADDR_DP, 1123 DevPathSerialMacAddr, 1124 DevPathCompareDefault 1125 }, 1126 { 1127 MESSAGING_DEVICE_PATH, 1128 MSG_IPv4_DP, 1129 DevPathSerialIPv4, 1130 DevPathCompareDefault 1131 }, 1132 { 1133 MESSAGING_DEVICE_PATH, 1134 MSG_IPv6_DP, 1135 DevPathSerialIPv6, 1136 DevPathCompareDefault 1137 }, 1138 { 1139 MESSAGING_DEVICE_PATH, 1140 MSG_INFINIBAND_DP, 1141 DevPathSerialInfiniBand, 1142 DevPathCompareDefault 1143 }, 1144 { 1145 MESSAGING_DEVICE_PATH, 1146 MSG_UART_DP, 1147 DevPathSerialUart, 1148 DevPathCompareDefault 1149 }, 1150 { 1151 MESSAGING_DEVICE_PATH, 1152 MSG_VENDOR_DP, 1153 DevPathSerialVendor, 1154 DevPathCompareDefault 1155 }, 1156 { 1157 MESSAGING_DEVICE_PATH, 1158 MSG_DEVICE_LOGICAL_UNIT_DP, 1159 DevPathSerialLun, 1160 DevPathCompareDefault 1161 }, 1162 { 1163 MESSAGING_DEVICE_PATH, 1164 MSG_SATA_DP, 1165 DevPathSerialSata, 1166 DevPathCompareDefault 1167 }, 1168 { 1169 MESSAGING_DEVICE_PATH, 1170 MSG_ISCSI_DP, 1171 DevPathSerialIScsi, 1172 DevPathCompareDefault 1173 }, 1174 { 1175 MEDIA_DEVICE_PATH, 1176 MEDIA_HARDDRIVE_DP, 1177 DevPathSerialHardDrive, 1178 DevPathCompareDefault 1179 }, 1180 { 1181 MEDIA_DEVICE_PATH, 1182 MEDIA_CDROM_DP, 1183 DevPathSerialCdRom, 1184 DevPathCompareDefault 1185 }, 1186 { 1187 MEDIA_DEVICE_PATH, 1188 MEDIA_VENDOR_DP, 1189 DevPathSerialVendor, 1190 DevPathCompareDefault 1191 }, 1192 { 1193 0, 1194 0, 1195 NULL, 1196 NULL 1197 } 1198 }; 1199 1200 /** 1201 Function to determine if a device path node is Hi or not. 1202 1203 @param[in] DevicePathNode The node to check. 1204 1205 @retval TRUE The node is Hi. 1206 @retval FALSE The node is not Hi. 1207 **/ 1208 BOOLEAN 1209 EFIAPI 1210 IsHIDevicePathNode ( 1211 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode 1212 ) 1213 { 1214 ACPI_HID_DEVICE_PATH *Acpi; 1215 1216 ASSERT(DevicePathNode != NULL); 1217 1218 if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) { 1219 return TRUE; 1220 } 1221 1222 if (DevicePathNode->Type == ACPI_DEVICE_PATH) { 1223 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode; 1224 switch (EISA_ID_TO_NUM (Acpi->HID)) { 1225 case 0x0301: 1226 case 0x0401: 1227 case 0x0501: 1228 case 0x0604: 1229 return FALSE; 1230 } 1231 1232 return TRUE; 1233 } 1234 1235 return FALSE; 1236 } 1237 1238 /** 1239 Function to convert a standard device path structure into a Hi version. 1240 1241 @param[in] DevicePath The device path to convert. 1242 1243 @return the device path portion that is Hi. 1244 **/ 1245 EFI_DEVICE_PATH_PROTOCOL * 1246 EFIAPI 1247 GetHIDevicePath ( 1248 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 1249 ) 1250 { 1251 UINTN NonHIDevicePathNodeCount; 1252 UINTN Index; 1253 EFI_DEV_PATH Node; 1254 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath; 1255 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; 1256 1257 ASSERT(DevicePath != NULL); 1258 1259 NonHIDevicePathNodeCount = 0; 1260 1261 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL)); 1262 SetDevicePathEndNode (HIDevicePath); 1263 1264 Node.DevPath.Type = END_DEVICE_PATH_TYPE; 1265 Node.DevPath.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; 1266 Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL); 1267 Node.DevPath.Length[1] = 0; 1268 1269 while (!IsDevicePathEnd (DevicePath)) { 1270 if (IsHIDevicePathNode (DevicePath)) { 1271 for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) { 1272 TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath); 1273 FreePool (HIDevicePath); 1274 HIDevicePath = TempDevicePath; 1275 } 1276 1277 TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath); 1278 FreePool (HIDevicePath); 1279 HIDevicePath = TempDevicePath; 1280 } else { 1281 NonHIDevicePathNodeCount++; 1282 } 1283 // 1284 // Next device path node 1285 // 1286 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath); 1287 } 1288 1289 return HIDevicePath; 1290 } 1291 1292 /** 1293 Function to walk the device path looking for a dumpable node. 1294 1295 @param[in] MappingItem The Item to fill with data. 1296 @param[in] DevicePath The path of the item to get data on. 1297 1298 @return EFI_SUCCESS Always returns success. 1299 **/ 1300 EFI_STATUS 1301 EFIAPI 1302 GetDeviceConsistMappingInfo ( 1303 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem, 1304 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 1305 ) 1306 { 1307 SERIAL_DECODE_FUNCTION SerialFun; 1308 UINTN Index; 1309 EFI_DEVICE_PATH_PROTOCOL *OriginalDevicePath; 1310 1311 ASSERT(DevicePath != NULL); 1312 ASSERT(MappingItem != NULL); 1313 1314 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0); 1315 OriginalDevicePath = DevicePath; 1316 1317 while (!IsDevicePathEnd (DevicePath)) { 1318 // 1319 // Find the handler to dump this device path node and 1320 // initialize with generic function in case nothing is found 1321 // 1322 for (SerialFun = DevPathSerialDefault, Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) { 1323 1324 if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type && 1325 DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType 1326 ) { 1327 SerialFun = DevPathConsistMappingTable[Index].SerialFun; 1328 break; 1329 } 1330 } 1331 1332 SerialFun (DevicePath, MappingItem, OriginalDevicePath); 1333 1334 // 1335 // Next device path node 1336 // 1337 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath); 1338 } 1339 1340 return EFI_SUCCESS; 1341 } 1342 1343 /** 1344 Function to initialize the table for creating consistent map names. 1345 1346 @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object. 1347 1348 @retval EFI_SUCCESS The table was created successfully. 1349 **/ 1350 EFI_STATUS 1351 EFIAPI 1352 ShellCommandConsistMappingInitialize ( 1353 OUT EFI_DEVICE_PATH_PROTOCOL ***Table 1354 ) 1355 { 1356 EFI_HANDLE *HandleBuffer; 1357 UINTN HandleNum; 1358 UINTN HandleLoop; 1359 EFI_DEVICE_PATH_PROTOCOL **TempTable; 1360 EFI_DEVICE_PATH_PROTOCOL *DevicePath; 1361 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath; 1362 EFI_BLOCK_IO_PROTOCOL *BlockIo; 1363 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; 1364 UINTN Index; 1365 EFI_STATUS Status; 1366 1367 HandleBuffer = NULL; 1368 1369 Status = gBS->LocateHandleBuffer ( 1370 ByProtocol, 1371 &gEfiDevicePathProtocolGuid, 1372 NULL, 1373 &HandleNum, 1374 &HandleBuffer 1375 ); 1376 ASSERT_EFI_ERROR(Status); 1377 1378 TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *)); 1379 if (TempTable == NULL) { 1380 return EFI_OUT_OF_RESOURCES; 1381 } 1382 1383 for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) { 1384 DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]); 1385 if (DevicePath == NULL) { 1386 continue; 1387 } 1388 1389 HIDevicePath = GetHIDevicePath (DevicePath); 1390 if (HIDevicePath == NULL) { 1391 continue; 1392 } 1393 1394 Status = gBS->HandleProtocol( HandleBuffer[HandleLoop], 1395 &gEfiBlockIoProtocolGuid, 1396 (VOID **)&BlockIo 1397 ); 1398 if (EFI_ERROR(Status)) { 1399 Status = gBS->HandleProtocol( HandleBuffer[HandleLoop], 1400 &gEfiSimpleFileSystemProtocolGuid, 1401 (VOID **)&SimpleFileSystem 1402 ); 1403 if (EFI_ERROR(Status)) { 1404 FreePool (HIDevicePath); 1405 continue; 1406 } 1407 } 1408 1409 for (Index = 0; TempTable[Index] != NULL; Index++) { 1410 if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) { 1411 FreePool (HIDevicePath); 1412 break; 1413 } 1414 } 1415 1416 if (TempTable[Index] == NULL) { 1417 TempTable[Index] = HIDevicePath; 1418 } 1419 } 1420 1421 for (Index = 0; TempTable[Index] != NULL; Index++); 1422 PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare); 1423 *Table = TempTable; 1424 1425 if (HandleBuffer != NULL) { 1426 FreePool (HandleBuffer); 1427 } 1428 1429 return EFI_SUCCESS; 1430 } 1431 1432 /** 1433 Function to uninitialize the table for creating consistent map names. 1434 1435 The parameter must have been received from ShellCommandConsistMappingInitialize. 1436 1437 @param[out] Table The pointer to pointer to DevicePathProtocol object. 1438 1439 @retval EFI_SUCCESS The table was deleted successfully. 1440 **/ 1441 EFI_STATUS 1442 EFIAPI 1443 ShellCommandConsistMappingUnInitialize ( 1444 EFI_DEVICE_PATH_PROTOCOL **Table 1445 ) 1446 { 1447 UINTN Index; 1448 1449 ASSERT(Table != NULL); 1450 1451 for (Index = 0; Table[Index] != NULL; Index++) { 1452 FreePool (Table[Index]); 1453 } 1454 1455 FreePool (Table); 1456 return EFI_SUCCESS; 1457 } 1458 1459 /** 1460 Create a consistent mapped name for the device specified by DevicePath 1461 based on the Table. 1462 1463 This must be called after ShellCommandConsistMappingInitialize() and 1464 before ShellCommandConsistMappingUnInitialize() is called. 1465 1466 @param[in] DevicePath The pointer to the dev path for the device. 1467 @param[in] Table The Table of mapping information. 1468 1469 @retval NULL A consistent mapped name could not be created. 1470 @return A pointer to a string allocated from pool with the device name. 1471 **/ 1472 CHAR16 * 1473 EFIAPI 1474 ShellCommandConsistMappingGenMappingName ( 1475 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 1476 IN EFI_DEVICE_PATH_PROTOCOL **Table 1477 ) 1478 { 1479 POOL_PRINT Str; 1480 DEVICE_CONSIST_MAPPING_INFO MappingInfo; 1481 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath; 1482 UINTN Index; 1483 UINTN NewSize; 1484 1485 ASSERT(DevicePath != NULL); 1486 ASSERT(Table != NULL); 1487 1488 HIDevicePath = GetHIDevicePath (DevicePath); 1489 if (HIDevicePath == NULL) { 1490 return NULL; 1491 } 1492 1493 for (Index = 0; Table[Index] != NULL; Index++) { 1494 if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) { 1495 break; 1496 } 1497 } 1498 1499 FreePool (HIDevicePath); 1500 if (Table[Index] == NULL) { 1501 return NULL; 1502 } 1503 1504 MappingInfo.Hi = Index; 1505 MappingInfo.Mtd = MTDTypeUnknown; 1506 MappingInfo.Digital = FALSE; 1507 1508 GetDeviceConsistMappingInfo (&MappingInfo, DevicePath); 1509 1510 SetMem (&Str, sizeof (Str), 0); 1511 for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) { 1512 if (MappingInfo.Mtd == mMTDName[Index].MTDType) { 1513 break; 1514 } 1515 } 1516 1517 if (mMTDName[Index].MTDType != MTDTypeEnd) { 1518 CatPrint (&Str, L"%s", mMTDName[Index].Name); 1519 } 1520 1521 CatPrint (&Str, L"%d", (UINTN) MappingInfo.Hi); 1522 if (MappingInfo.Csd.Str != NULL) { 1523 CatPrint (&Str, L"%s", MappingInfo.Csd.Str); 1524 FreePool (MappingInfo.Csd.Str); 1525 } 1526 1527 if (Str.Str != NULL) { 1528 CatPrint (&Str, L":"); 1529 } 1530 1531 NewSize = (Str.Len + 1) * sizeof (CHAR16); 1532 Str.Str = ReallocatePool (Str.Len, NewSize, Str.Str); 1533 if (Str.Str == NULL) { 1534 return (NULL); 1535 } 1536 Str.Str[Str.Len] = CHAR_NULL; 1537 return Str.Str; 1538 } 1539 1540 /** 1541 Function to search the list of mappings for the node on the list based on the key. 1542 1543 @param[in] MapKey String Key to search for on the map 1544 1545 @return the node on the list. 1546 **/ 1547 SHELL_MAP_LIST * 1548 EFIAPI 1549 ShellCommandFindMapItem ( 1550 IN CONST CHAR16 *MapKey 1551 ) 1552 { 1553 SHELL_MAP_LIST *MapListItem; 1554 1555 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link) 1556 ; !IsNull(&gShellMapList.Link, &MapListItem->Link) 1557 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &MapListItem->Link) 1558 ){ 1559 if (gUnicodeCollation->StriColl(gUnicodeCollation,MapListItem->MapName,(CHAR16*)MapKey) == 0) { 1560 return (MapListItem); 1561 } 1562 } 1563 return (NULL); 1564 } 1565 1566 1567