]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
Add missing braces around initializer.
[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
ce68d3bc 4 Copyright (c) 2005 - 2012, 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
101 StrCat (Str->Str, AppendStr);\r
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
654///@todo make this a PCD\r
655//\r
1a63ec8f 656// As Csd of ISCSI node is quite long, we comment\r
a405b86d 657// the code below to keep the consistent mapping\r
658// short. Uncomment if you really need it.\r
659//\r
660/*\r
661 ISCSI_DEVICE_PATH *IScsi;\r
662 UINT8 *IScsiTargetName;\r
663 CHAR16 *TargetName;\r
664 UINTN TargetNameLength;\r
665 UINTN Index;\r
666\r
667 ASSERT(DevicePathNode != NULL);\r
668 ASSERT(MappingItem != NULL);\r
669\r
670 IScsi = (ISCSI_DEVICE_PATH *) DevicePathNode;\r
671 AppendCSDNum (MappingItem, IScsi->NetworkProtocol);\r
672 AppendCSDNum (MappingItem, IScsi->LoginOption);\r
673 AppendCSDNum (MappingItem, IScsi->Lun);\r
674 AppendCSDNum (MappingItem, IScsi->TargetPortalGroupTag);\r
675 TargetNameLength = DevicePathNodeLength (DevicePathNode) - sizeof (ISCSI_DEVICE_PATH);\r
676 if (TargetNameLength > 0) {\r
677 TargetName = AllocateZeroPool ((TargetNameLength + 1) * sizeof (CHAR16));\r
678 if (TargetName != NULL) {\r
679 IScsiTargetName = (UINT8 *) (IScsi + 1);\r
680 for (Index = 0; Index < TargetNameLength; Index++) {\r
681 TargetName[Index] = (CHAR16) IScsiTargetName[Index];\r
682 }\r
683 AppendCSDStr (MappingItem, TargetName);\r
684 FreePool (TargetName);\r
685 }\r
686 }\r
687 */\r
688}\r
689\r
690/**\r
691 DevicePathNode must be SerialI20 type and this will populate the MappingItem.\r
692\r
693 @param[in] DevicePathNode The node to get info on.\r
694 @param[in] MappingItem The info item to populate.\r
695**/\r
696VOID\r
697EFIAPI\r
698DevPathSerialI2O (\r
699 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
700 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
701 )\r
702{\r
1a63ec8f 703 I2O_DEVICE_PATH *DevicePath_I20;\r
a405b86d 704\r
705 ASSERT(DevicePathNode != NULL);\r
706 ASSERT(MappingItem != NULL);\r
707\r
1a63ec8f 708 DevicePath_I20 = (I2O_DEVICE_PATH *) DevicePathNode;\r
709 AppendCSDNum (MappingItem, DevicePath_I20->Tid);\r
a405b86d 710}\r
711\r
712/**\r
713 DevicePathNode must be Mac Address type and this will populate the MappingItem.\r
714\r
715 @param[in] DevicePathNode The node to get info on.\r
716 @param[in] MappingItem The info item to populate.\r
717**/\r
718VOID\r
719EFIAPI\r
720DevPathSerialMacAddr (\r
721 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
722 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
723 )\r
724{\r
725 MAC_ADDR_DEVICE_PATH *Mac;\r
726 UINTN HwAddressSize;\r
727 UINTN Index;\r
728 CHAR16 Buffer[64];\r
729 CHAR16 *PBuffer;\r
730\r
731 ASSERT(DevicePathNode != NULL);\r
732 ASSERT(MappingItem != NULL);\r
733\r
734 Mac = (MAC_ADDR_DEVICE_PATH *) DevicePathNode;\r
735\r
736 HwAddressSize = sizeof (EFI_MAC_ADDRESS);\r
737 if (Mac->IfType == 0x01 || Mac->IfType == 0x00) {\r
738 HwAddressSize = 6;\r
739 }\r
740\r
741 for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) {\r
742 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Mac->MacAddress.Addr[Index]);\r
743 }\r
744\r
745 AppendCSDStr (MappingItem, Buffer);\r
746}\r
747\r
748/**\r
749 DevicePathNode must be InfiniBand type and this will populate the MappingItem.\r
750\r
751 @param[in] DevicePathNode The node to get info on.\r
752 @param[in] MappingItem The info item to populate.\r
753**/\r
754VOID\r
755EFIAPI\r
756DevPathSerialInfiniBand (\r
757 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
758 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
759 )\r
760{\r
761 INFINIBAND_DEVICE_PATH *InfiniBand;\r
762 UINTN Index;\r
763 CHAR16 Buffer[64];\r
764 CHAR16 *PBuffer;\r
765\r
766 ASSERT(DevicePathNode != NULL);\r
767 ASSERT(MappingItem != NULL);\r
768\r
769 InfiniBand = (INFINIBAND_DEVICE_PATH *) DevicePathNode;\r
770 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {\r
771 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) InfiniBand->PortGid[Index]);\r
772 }\r
773\r
774 AppendCSDStr (MappingItem, Buffer);\r
775 AppendCSDNum (MappingItem, InfiniBand->ServiceId);\r
776 AppendCSDNum (MappingItem, InfiniBand->TargetPortId);\r
777 AppendCSDNum (MappingItem, InfiniBand->DeviceId);\r
778}\r
779\r
780/**\r
781 DevicePathNode must be IPv4 type and this will populate the MappingItem.\r
782\r
783 @param[in] DevicePathNode The node to get info on.\r
784 @param[in] MappingItem The info item to populate.\r
785**/\r
786VOID\r
787EFIAPI\r
788DevPathSerialIPv4 (\r
789 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
790 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
791 )\r
792{\r
793 IPv4_DEVICE_PATH *Ip;\r
794 CHAR16 Buffer[10];\r
795\r
796 ASSERT(DevicePathNode != NULL);\r
797 ASSERT(MappingItem != NULL);\r
798\r
799 Ip = (IPv4_DEVICE_PATH *) DevicePathNode;\r
800 UnicodeSPrint (\r
801 Buffer,\r
802 0,\r
803 L"%02x%02x%02x%02x",\r
804 (UINTN) Ip->LocalIpAddress.Addr[0],\r
805 (UINTN) Ip->LocalIpAddress.Addr[1],\r
806 (UINTN) Ip->LocalIpAddress.Addr[2],\r
807 (UINTN) Ip->LocalIpAddress.Addr[3]\r
808 );\r
809 AppendCSDStr (MappingItem, Buffer);\r
810 AppendCSDNum (MappingItem, Ip->LocalPort);\r
811 UnicodeSPrint (\r
812 Buffer,\r
813 0,\r
814 L"%02x%02x%02x%02x",\r
815 (UINTN) Ip->RemoteIpAddress.Addr[0],\r
816 (UINTN) Ip->RemoteIpAddress.Addr[1],\r
817 (UINTN) Ip->RemoteIpAddress.Addr[2],\r
818 (UINTN) Ip->RemoteIpAddress.Addr[3]\r
819 );\r
820 AppendCSDStr (MappingItem, Buffer);\r
821 AppendCSDNum (MappingItem, Ip->RemotePort);\r
822}\r
823\r
824/**\r
825 DevicePathNode must be IPv6 type and this will populate the MappingItem.\r
826\r
827 @param[in] DevicePathNode The node to get info on.\r
828 @param[in] MappingItem The info item to populate.\r
829**/\r
830VOID\r
831EFIAPI\r
832DevPathSerialIPv6 (\r
833 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
834 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
835 )\r
836{\r
837 IPv6_DEVICE_PATH *Ip;\r
838 UINTN Index;\r
839 CHAR16 Buffer[64];\r
840 CHAR16 *PBuffer;\r
841\r
842 ASSERT(DevicePathNode != NULL);\r
843 ASSERT(MappingItem != NULL);\r
844\r
845 Ip = (IPv6_DEVICE_PATH *) DevicePathNode;\r
846 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {\r
847 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->LocalIpAddress.Addr[Index]);\r
848 }\r
849\r
850 AppendCSDStr (MappingItem, Buffer);\r
851 AppendCSDNum (MappingItem, Ip->LocalPort);\r
852 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {\r
853 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->RemoteIpAddress.Addr[Index]);\r
854 }\r
855\r
856 AppendCSDStr (MappingItem, Buffer);\r
857 AppendCSDNum (MappingItem, Ip->RemotePort);\r
858}\r
859\r
860/**\r
861 DevicePathNode must be SCSI type and this will populate the MappingItem.\r
862\r
863 @param[in] DevicePathNode The node to get info on.\r
864 @param[in] MappingItem The info item to populate.\r
865**/\r
866VOID\r
867EFIAPI\r
868DevPathSerialScsi (\r
869 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
870 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
871 )\r
872{\r
873 SCSI_DEVICE_PATH *Scsi;\r
874\r
875 ASSERT(DevicePathNode != NULL);\r
876 ASSERT(MappingItem != NULL);\r
877\r
878 Scsi = (SCSI_DEVICE_PATH *) DevicePathNode;\r
879 AppendCSDNum (MappingItem, Scsi->Pun);\r
880 AppendCSDNum (MappingItem, Scsi->Lun);\r
881}\r
882\r
883/**\r
884 DevicePathNode must be 1394 type and this will populate the MappingItem.\r
885\r
886 @param[in] DevicePathNode The node to get info on.\r
887 @param[in] MappingItem The info item to populate.\r
888**/\r
889VOID\r
890EFIAPI\r
891DevPathSerial1394 (\r
892 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
893 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
894 )\r
895{\r
1a63ec8f 896 F1394_DEVICE_PATH *DevicePath_F1394;\r
a405b86d 897 CHAR16 Buffer[20];\r
898\r
899 ASSERT(DevicePathNode != NULL);\r
900 ASSERT(MappingItem != NULL);\r
901\r
1a63ec8f 902 DevicePath_F1394 = (F1394_DEVICE_PATH *) DevicePathNode;\r
903 UnicodeSPrint (Buffer, 0, L"%lx", DevicePath_F1394->Guid);\r
a405b86d 904 AppendCSDStr (MappingItem, Buffer);\r
905}\r
906\r
907/**\r
908 If the node is floppy type then populate the MappingItem.\r
909\r
910 @param[in] DevicePathNode The node to get info on.\r
911 @param[in] MappingItem The info item to populate.\r
912**/\r
913VOID\r
914EFIAPI\r
915DevPathSerialAcpi (\r
916 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
917 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
918 )\r
919{\r
920 ACPI_HID_DEVICE_PATH *Acpi;\r
921\r
922 ASSERT(DevicePathNode != NULL);\r
923 ASSERT(MappingItem != NULL);\r
924\r
925 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;\r
926 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
927 if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {\r
1a63ec8f 928 MappingItem->Mtd = MTDTypeFloppy;\r
a405b86d 929 AppendCSDNum (MappingItem, Acpi->UID);\r
930 }\r
931 }\r
932}\r
933\r
934/**\r
935 Empty function used for unknown devices.\r
936\r
1a63ec8f 937 @param[in] DevicePathNode Ignored.\r
938 @param[in] MappingItem Ignored.\r
939\r
a405b86d 940 Does nothing.\r
941**/\r
942VOID\r
943EFIAPI\r
944DevPathSerialDefault (\r
945 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
946 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem\r
947 )\r
948{\r
1a63ec8f 949 return;\r
a405b86d 950}\r
951\r
952DEV_PATH_CONSIST_MAPPING_TABLE DevPathConsistMappingTable[] = {\r
ce68d3bc
SZ
953 {\r
954 HARDWARE_DEVICE_PATH,\r
955 HW_PCI_DP,\r
956 DevPathSerialDefault,\r
957 DevPathComparePci\r
958 },\r
959 {\r
960 ACPI_DEVICE_PATH,\r
961 ACPI_DP,\r
962 DevPathSerialAcpi,\r
963 DevPathCompareAcpi\r
964 },\r
965 {\r
966 MESSAGING_DEVICE_PATH,\r
967 MSG_ATAPI_DP,\r
968 DevPathSerialAtapi,\r
969 DevPathCompareDefault\r
970 },\r
971 {\r
972 MESSAGING_DEVICE_PATH,\r
973 MSG_SCSI_DP,\r
974 DevPathSerialScsi,\r
975 DevPathCompareDefault\r
976 },\r
977 {\r
978 MESSAGING_DEVICE_PATH,\r
979 MSG_FIBRECHANNEL_DP,\r
980 DevPathSerialFibre,\r
981 DevPathCompareDefault\r
982 },\r
983 {\r
984 MESSAGING_DEVICE_PATH,\r
985 MSG_1394_DP,\r
986 DevPathSerial1394,\r
987 DevPathCompareDefault\r
988 },\r
989 {\r
990 MESSAGING_DEVICE_PATH,\r
991 MSG_USB_DP,\r
992 DevPathSerialUsb,\r
993 DevPathCompareDefault\r
994 },\r
995 {\r
996 MESSAGING_DEVICE_PATH,\r
997 MSG_I2O_DP,\r
998 DevPathSerialI2O,\r
999 DevPathCompareDefault\r
1000 },\r
1001 {\r
1002 MESSAGING_DEVICE_PATH,\r
1003 MSG_MAC_ADDR_DP,\r
1004 DevPathSerialMacAddr,\r
1005 DevPathCompareDefault\r
1006 },\r
1007 {\r
1008 MESSAGING_DEVICE_PATH,\r
1009 MSG_IPv4_DP,\r
1010 DevPathSerialIPv4,\r
1011 DevPathCompareDefault\r
1012 },\r
1013 {\r
1014 MESSAGING_DEVICE_PATH,\r
1015 MSG_IPv6_DP,\r
1016 DevPathSerialIPv6,\r
1017 DevPathCompareDefault\r
1018 },\r
1019 {\r
1020 MESSAGING_DEVICE_PATH,\r
1021 MSG_INFINIBAND_DP,\r
1022 DevPathSerialInfiniBand,\r
1023 DevPathCompareDefault\r
1024 },\r
1025 {\r
1026 MESSAGING_DEVICE_PATH,\r
1027 MSG_UART_DP,\r
1028 DevPathSerialUart,\r
1029 DevPathCompareDefault\r
1030 },\r
1031 {\r
1032 MESSAGING_DEVICE_PATH,\r
1033 MSG_VENDOR_DP,\r
1034 DevPathSerialVendor,\r
1035 DevPathCompareDefault\r
1036 },\r
1037 {\r
1038 MESSAGING_DEVICE_PATH,\r
1039 MSG_DEVICE_LOGICAL_UNIT_DP,\r
1040 DevPathSerialLun,\r
1041 DevPathCompareDefault\r
1042 },\r
1043 {\r
1044 MESSAGING_DEVICE_PATH,\r
1045 MSG_SATA_DP,\r
1046 DevPathSerialSata,\r
1047 DevPathCompareDefault\r
1048 },\r
1049 {\r
1050 MESSAGING_DEVICE_PATH,\r
1051 MSG_ISCSI_DP,\r
1052 DevPathSerialIScsi,\r
1053 DevPathCompareDefault\r
1054 },\r
1055 {\r
1056 MEDIA_DEVICE_PATH,\r
1057 MEDIA_HARDDRIVE_DP,\r
1058 DevPathSerialHardDrive,\r
1059 DevPathCompareDefault\r
1060 },\r
1061 {\r
1062 MEDIA_DEVICE_PATH,\r
1063 MEDIA_CDROM_DP,\r
1064 DevPathSerialCdRom,\r
1065 DevPathCompareDefault\r
1066 },\r
1067 {\r
1068 MEDIA_DEVICE_PATH,\r
1069 MEDIA_VENDOR_DP,\r
1070 DevPathSerialVendor,\r
1071 DevPathCompareDefault\r
1072 },\r
1073 {\r
1074 0,\r
1075 0,\r
1076 NULL,\r
1077 NULL\r
1078 }\r
a405b86d 1079};\r
1080\r
1081/**\r
1082 Function to determine if a device path node is Hi or not.\r
1083\r
1084 @param[in] DevicePathNode The node to check.\r
1085\r
1a63ec8f 1086 @retval TRUE The node is Hi.\r
1087 @retval FALSE The node is not Hi.\r
a405b86d 1088**/\r
1089BOOLEAN\r
1090EFIAPI\r
1091IsHIDevicePathNode (\r
1092 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode\r
1093 )\r
1094{\r
1095 ACPI_HID_DEVICE_PATH *Acpi;\r
1096\r
1097 ASSERT(DevicePathNode != NULL);\r
1098\r
1099 if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {\r
1100 return TRUE;\r
1101 }\r
1102\r
1103 if (DevicePathNode->Type == ACPI_DEVICE_PATH) {\r
1104 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;\r
1105 switch (EISA_ID_TO_NUM (Acpi->HID)) {\r
1106 case 0x0301:\r
1107 case 0x0401:\r
1108 case 0x0501:\r
1109 case 0x0604:\r
1110 return FALSE;\r
1111 }\r
1112\r
1113 return TRUE;\r
1114 }\r
1115\r
1116 return FALSE;\r
1117}\r
1118\r
1119/**\r
1a63ec8f 1120 Function to convert a standard device path structure into a Hi version.\r
a405b86d 1121\r
1122 @param[in] DevicePath The device path to convert.\r
1123\r
1a63ec8f 1124 @return the device path portion that is Hi.\r
a405b86d 1125**/\r
1126EFI_DEVICE_PATH_PROTOCOL *\r
1127EFIAPI\r
1128GetHIDevicePath (\r
1129 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
1130 )\r
1131{\r
1132 UINTN NonHIDevicePathNodeCount;\r
1133 UINTN Index;\r
1134 EFI_DEV_PATH Node;\r
1135 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1136 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
1137\r
1138 ASSERT(DevicePath != NULL);\r
1139\r
1140 NonHIDevicePathNodeCount = 0;\r
1141\r
1a63ec8f 1142 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
a405b86d 1143 SetDevicePathEndNode (HIDevicePath);\r
1144\r
1145 Node.DevPath.Type = END_DEVICE_PATH_TYPE;\r
1146 Node.DevPath.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;\r
1147 Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
1148 Node.DevPath.Length[1] = 0;\r
1149\r
1150 while (!IsDevicePathEnd (DevicePath)) {\r
1151 if (IsHIDevicePathNode (DevicePath)) {\r
1152 for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {\r
1153 TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);\r
1154 FreePool (HIDevicePath);\r
1155 HIDevicePath = TempDevicePath;\r
1156 }\r
1157\r
1158 TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);\r
1159 FreePool (HIDevicePath);\r
1160 HIDevicePath = TempDevicePath;\r
1161 } else {\r
1162 NonHIDevicePathNodeCount++;\r
1163 }\r
1164 //\r
1165 // Next device path node\r
1166 //\r
1167 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);\r
1168 }\r
1169\r
1170 return HIDevicePath;\r
1171}\r
1172\r
1173/**\r
1174 Function to walk the device path looking for a dumpable node.\r
1175\r
1176 @param[in] MappingItem The Item to fill with data.\r
1177 @param[in] DevicePath The path of the item to get data on.\r
1178\r
1179 @return EFI_SUCCESS Always returns success.\r
1180**/\r
1181EFI_STATUS\r
1182EFIAPI\r
1183GetDeviceConsistMappingInfo (\r
1184 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
1185 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
1186 )\r
1187{\r
e26d7b59 1188 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);\r
a405b86d 1189\r
1190 UINTN Index;\r
1191\r
1192 ASSERT(DevicePath != NULL);\r
1193 ASSERT(MappingItem != NULL);\r
1194\r
1a63ec8f 1195 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);\r
a405b86d 1196\r
1197 while (!IsDevicePathEnd (DevicePath)) {\r
1198 //\r
1199 // Find the handler to dump this device path node\r
1200 //\r
1201 SerialFun = NULL;\r
1202 for (Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) {\r
1203\r
1204 if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type &&\r
1205 DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType\r
1206 ) {\r
1207 SerialFun = DevPathConsistMappingTable[Index].SerialFun;\r
1208 break;\r
1209 }\r
1210 }\r
1211 //\r
1212 // If not found, use a generic function\r
1213 //\r
1214 if (!SerialFun) {\r
1215 SerialFun = DevPathSerialDefault;\r
1216 }\r
1217\r
1218 SerialFun (DevicePath, MappingItem);\r
1219\r
1220 //\r
1221 // Next device path node\r
1222 //\r
1223 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);\r
1224 }\r
1225\r
1226 return EFI_SUCCESS;\r
1227}\r
1228\r
1229/**\r
1230 Function to initialize the table for creating consistent map names.\r
1231\r
1232 @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object.\r
1233\r
1234 @retval EFI_SUCCESS The table was created successfully.\r
1235**/\r
1236EFI_STATUS\r
1237EFIAPI\r
1238ShellCommandConsistMappingInitialize (\r
1239 OUT EFI_DEVICE_PATH_PROTOCOL ***Table\r
1240 )\r
1241{\r
1242 EFI_HANDLE *HandleBuffer;\r
1243 UINTN HandleNum;\r
1244 UINTN HandleLoop;\r
1245 EFI_DEVICE_PATH_PROTOCOL **TempTable;\r
1246 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
1247 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1248 UINTN Index;\r
1249 EFI_STATUS Status;\r
1250\r
1251 HandleBuffer = NULL;\r
1252\r
1253 Status = gBS->LocateHandleBuffer (\r
1254 AllHandles,\r
1255 NULL,\r
1256 NULL,\r
1257 &HandleNum,\r
1258 &HandleBuffer\r
1259 );\r
1260 ASSERT_EFI_ERROR(Status);\r
1261\r
1262 TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));\r
1263 if (TempTable == NULL) {\r
1264 return EFI_OUT_OF_RESOURCES;\r
1265 }\r
1266\r
1267 for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) {\r
1268 DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]);\r
1269 if (DevicePath == NULL) {\r
1270 continue;\r
1271 }\r
1272\r
1273 HIDevicePath = GetHIDevicePath (DevicePath);\r
1274 if (HIDevicePath == NULL) {\r
1275 continue;\r
1276 }\r
1277\r
1278 for (Index = 0; TempTable[Index] != NULL; Index++) {\r
1279 if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) {\r
1280 FreePool (HIDevicePath);\r
1281 break;\r
1282 }\r
1283 }\r
1284\r
1285 if (TempTable[Index] == NULL) {\r
1286 TempTable[Index] = HIDevicePath;\r
1287 }\r
1288 }\r
1289\r
1290 for (Index = 0; TempTable[Index] != NULL; Index++);\r
1291 PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);\r
1292 *Table = TempTable;\r
1293\r
1294 if (HandleBuffer != NULL) {\r
1295 FreePool (HandleBuffer);\r
1296 }\r
1297\r
1298 return EFI_SUCCESS;\r
1299}\r
1300\r
1301/**\r
1302 Function to uninitialize the table for creating consistent map names.\r
1303\r
1304 The parameter must have been received from ShellCommandConsistMappingInitialize.\r
1305\r
1306 @param[out] Table The pointer to pointer to DevicePathProtocol object.\r
1307\r
1308 @retval EFI_SUCCESS The table was deleted successfully.\r
1309**/\r
1310EFI_STATUS\r
1311EFIAPI\r
1312ShellCommandConsistMappingUnInitialize (\r
1313 EFI_DEVICE_PATH_PROTOCOL **Table\r
1314 )\r
1315{\r
1316 UINTN Index;\r
1317\r
1318 ASSERT(Table != NULL);\r
1319\r
1320 for (Index = 0; Table[Index] != NULL; Index++) {\r
1321 FreePool (Table[Index]);\r
1322 }\r
1323\r
1324 FreePool (Table);\r
1325 return EFI_SUCCESS;\r
1326}\r
1327\r
1328/**\r
e26d7b59 1329 Create a consistent mapped name for the device specified by DevicePath\r
a405b86d 1330 based on the Table.\r
1331\r
e26d7b59 1332 This must be called after ShellCommandConsistMappingInitialize() and\r
a405b86d 1333 before ShellCommandConsistMappingUnInitialize() is called.\r
1334\r
1a63ec8f 1335 @param[in] DevicePath The pointer to the dev path for the device.\r
a405b86d 1336 @param[in] Table The Table of mapping information.\r
1337\r
1338 @retval NULL A consistent mapped name could not be created.\r
1339 @return A pointer to a string allocated from pool with the device name.\r
1340**/\r
1341CHAR16 *\r
1342EFIAPI\r
1343ShellCommandConsistMappingGenMappingName (\r
1a63ec8f 1344 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1345 IN EFI_DEVICE_PATH_PROTOCOL **Table\r
a405b86d 1346 )\r
1347{\r
1348 POOL_PRINT Str;\r
1349 DEVICE_CONSIST_MAPPING_INFO MappingInfo;\r
1350 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1351 UINTN Index;\r
1352 UINTN NewSize;\r
1353\r
1354 ASSERT(DevicePath != NULL);\r
1355 ASSERT(Table != NULL);\r
1356\r
1357 HIDevicePath = GetHIDevicePath (DevicePath);\r
1358 if (HIDevicePath == NULL) {\r
1359 return NULL;\r
1360 }\r
1361\r
1362 for (Index = 0; Table[Index] != NULL; Index++) {\r
1363 if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) {\r
1364 break;\r
1365 }\r
1366 }\r
1367\r
1368 FreePool (HIDevicePath);\r
1369 if (Table[Index] == NULL) {\r
1370 return NULL;\r
1371 }\r
1372\r
1a63ec8f 1373 MappingInfo.Hi = Index;\r
1374 MappingInfo.Mtd = MTDTypeUnknown;\r
a405b86d 1375 MappingInfo.Digital = FALSE;\r
1376\r
1377 GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);\r
1378\r
1379 SetMem (&Str, sizeof (Str), 0);\r
1380 for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {\r
1a63ec8f 1381 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {\r
a405b86d 1382 break;\r
1383 }\r
1384 }\r
1385\r
1386 if (mMTDName[Index].MTDType != MTDTypeEnd) {\r
1387 CatPrint (&Str, L"%s", mMTDName[Index].Name);\r
1388 }\r
1389\r
1a63ec8f 1390 CatPrint (&Str, L"%d", (UINTN) MappingInfo.Hi);\r
1391 if (MappingInfo.Csd.Str != NULL) {\r
1392 CatPrint (&Str, L"%s", MappingInfo.Csd.Str);\r
1393 FreePool (MappingInfo.Csd.Str);\r
a405b86d 1394 }\r
1395\r
1396 if (Str.Str != NULL) {\r
1397 CatPrint (&Str, L":");\r
1398 }\r
1399\r
1400 NewSize = (Str.Len + 1) * sizeof (CHAR16);\r
1401 Str.Str = ReallocatePool (Str.Len, NewSize, Str.Str);\r
e53bf79d 1402 if (Str.Str == NULL) {\r
1403 return (NULL);\r
1404 }\r
a405b86d 1405 Str.Str[Str.Len] = CHAR_NULL;\r
1406 return Str.Str;\r
1407}\r
1408\r
1409/**\r
1410 Function to search the list of mappings for the node on the list based on the key.\r
1411\r
1412 @param[in] MapKey String Key to search for on the map\r
1413\r
1414 @return the node on the list.\r
1415**/\r
1416SHELL_MAP_LIST *\r
1417EFIAPI\r
1418ShellCommandFindMapItem (\r
1419 IN CONST CHAR16 *MapKey\r
1420 )\r
1421{\r
1422 SHELL_MAP_LIST *MapListItem;\r
1423\r
1424 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)\r
1425 ; !IsNull(&gShellMapList.Link, &MapListItem->Link)\r
1426 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &MapListItem->Link)\r
1427 ){\r
1428 if (gUnicodeCollation->StriColl(gUnicodeCollation,MapListItem->MapName,(CHAR16*)MapKey) == 0) {\r
1429 return (MapListItem);\r
1430 }\r
1431 }\r
1432 return (NULL);\r
1433}\r
1434\r
1435\r