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