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