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