]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
Comment's added and fixed.
[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
1a63ec8f 4 Copyright (c) 2005 - 2011, 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
134 @param[in,out] Str The string so append onto.\r
135 @param[in] Num The number to divide and append.\r
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
166 @param[in,out] MappingItem The mapping info object to append onto.\r
167 @param[in] Num The info to append.\r
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
197 @param[in,out] MappingItem The mapping info object to append onto.\r
198 @param[in] Str The info to append.\r
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
284 @param[in,out] MappingItem The item to append onto.\r
285 @param[in] Guid The guid to append.\r
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
953 HARDWARE_DEVICE_PATH,\r
954 HW_PCI_DP,\r
955 DevPathSerialDefault,\r
1a63ec8f 956 DevPathComparePci,\r
a405b86d 957 ACPI_DEVICE_PATH,\r
958 ACPI_DP,\r
959 DevPathSerialAcpi,\r
1a63ec8f 960 DevPathCompareAcpi,\r
a405b86d 961 MESSAGING_DEVICE_PATH,\r
962 MSG_ATAPI_DP,\r
963 DevPathSerialAtapi,\r
964 DevPathCompareDefault,\r
965 MESSAGING_DEVICE_PATH,\r
966 MSG_SCSI_DP,\r
967 DevPathSerialScsi,\r
968 DevPathCompareDefault,\r
969 MESSAGING_DEVICE_PATH,\r
970 MSG_FIBRECHANNEL_DP,\r
971 DevPathSerialFibre,\r
972 DevPathCompareDefault,\r
973 MESSAGING_DEVICE_PATH,\r
974 MSG_1394_DP,\r
975 DevPathSerial1394,\r
976 DevPathCompareDefault,\r
977 MESSAGING_DEVICE_PATH,\r
978 MSG_USB_DP,\r
979 DevPathSerialUsb,\r
980 DevPathCompareDefault,\r
981 MESSAGING_DEVICE_PATH,\r
982 MSG_I2O_DP,\r
983 DevPathSerialI2O,\r
984 DevPathCompareDefault,\r
985 MESSAGING_DEVICE_PATH,\r
986 MSG_MAC_ADDR_DP,\r
987 DevPathSerialMacAddr,\r
988 DevPathCompareDefault,\r
989 MESSAGING_DEVICE_PATH,\r
990 MSG_IPv4_DP,\r
991 DevPathSerialIPv4,\r
992 DevPathCompareDefault,\r
993 MESSAGING_DEVICE_PATH,\r
994 MSG_IPv6_DP,\r
995 DevPathSerialIPv6,\r
996 DevPathCompareDefault,\r
997 MESSAGING_DEVICE_PATH,\r
998 MSG_INFINIBAND_DP,\r
999 DevPathSerialInfiniBand,\r
1000 DevPathCompareDefault,\r
1001 MESSAGING_DEVICE_PATH,\r
1002 MSG_UART_DP,\r
1003 DevPathSerialUart,\r
1004 DevPathCompareDefault,\r
1005 MESSAGING_DEVICE_PATH,\r
1006 MSG_VENDOR_DP,\r
1007 DevPathSerialVendor,\r
1008 DevPathCompareDefault,\r
1009 MESSAGING_DEVICE_PATH,\r
1010 MSG_DEVICE_LOGICAL_UNIT_DP,\r
1011 DevPathSerialLun,\r
1012 DevPathCompareDefault,\r
1013 MESSAGING_DEVICE_PATH,\r
1014 MSG_SATA_DP,\r
1015 DevPathSerialSata,\r
1016 DevPathCompareDefault,\r
1017 MESSAGING_DEVICE_PATH,\r
1018 MSG_ISCSI_DP,\r
1019 DevPathSerialIScsi,\r
1020 DevPathCompareDefault,\r
1021 MEDIA_DEVICE_PATH,\r
1022 MEDIA_HARDDRIVE_DP,\r
1023 DevPathSerialHardDrive,\r
1024 DevPathCompareDefault,\r
1025 MEDIA_DEVICE_PATH,\r
1026 MEDIA_CDROM_DP,\r
1027 DevPathSerialCdRom,\r
1028 DevPathCompareDefault,\r
1029 MEDIA_DEVICE_PATH,\r
1030 MEDIA_VENDOR_DP,\r
1031 DevPathSerialVendor,\r
1032 DevPathCompareDefault,\r
1033 0,\r
1034 0,\r
1035 NULL,\r
1036 NULL\r
1037};\r
1038\r
1039/**\r
1040 Function to determine if a device path node is Hi or not.\r
1041\r
1042 @param[in] DevicePathNode The node to check.\r
1043\r
1a63ec8f 1044 @retval TRUE The node is Hi.\r
1045 @retval FALSE The node is not Hi.\r
a405b86d 1046**/\r
1047BOOLEAN\r
1048EFIAPI\r
1049IsHIDevicePathNode (\r
1050 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode\r
1051 )\r
1052{\r
1053 ACPI_HID_DEVICE_PATH *Acpi;\r
1054\r
1055 ASSERT(DevicePathNode != NULL);\r
1056\r
1057 if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {\r
1058 return TRUE;\r
1059 }\r
1060\r
1061 if (DevicePathNode->Type == ACPI_DEVICE_PATH) {\r
1062 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;\r
1063 switch (EISA_ID_TO_NUM (Acpi->HID)) {\r
1064 case 0x0301:\r
1065 case 0x0401:\r
1066 case 0x0501:\r
1067 case 0x0604:\r
1068 return FALSE;\r
1069 }\r
1070\r
1071 return TRUE;\r
1072 }\r
1073\r
1074 return FALSE;\r
1075}\r
1076\r
1077/**\r
1a63ec8f 1078 Function to convert a standard device path structure into a Hi version.\r
a405b86d 1079\r
1080 @param[in] DevicePath The device path to convert.\r
1081\r
1a63ec8f 1082 @return the device path portion that is Hi.\r
a405b86d 1083**/\r
1084EFI_DEVICE_PATH_PROTOCOL *\r
1085EFIAPI\r
1086GetHIDevicePath (\r
1087 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
1088 )\r
1089{\r
1090 UINTN NonHIDevicePathNodeCount;\r
1091 UINTN Index;\r
1092 EFI_DEV_PATH Node;\r
1093 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1094 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
1095\r
1096 ASSERT(DevicePath != NULL);\r
1097\r
1098 NonHIDevicePathNodeCount = 0;\r
1099\r
1a63ec8f 1100 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
a405b86d 1101 SetDevicePathEndNode (HIDevicePath);\r
1102\r
1103 Node.DevPath.Type = END_DEVICE_PATH_TYPE;\r
1104 Node.DevPath.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;\r
1105 Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
1106 Node.DevPath.Length[1] = 0;\r
1107\r
1108 while (!IsDevicePathEnd (DevicePath)) {\r
1109 if (IsHIDevicePathNode (DevicePath)) {\r
1110 for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {\r
1111 TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);\r
1112 FreePool (HIDevicePath);\r
1113 HIDevicePath = TempDevicePath;\r
1114 }\r
1115\r
1116 TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);\r
1117 FreePool (HIDevicePath);\r
1118 HIDevicePath = TempDevicePath;\r
1119 } else {\r
1120 NonHIDevicePathNodeCount++;\r
1121 }\r
1122 //\r
1123 // Next device path node\r
1124 //\r
1125 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);\r
1126 }\r
1127\r
1128 return HIDevicePath;\r
1129}\r
1130\r
1131/**\r
1132 Function to walk the device path looking for a dumpable node.\r
1133\r
1134 @param[in] MappingItem The Item to fill with data.\r
1135 @param[in] DevicePath The path of the item to get data on.\r
1136\r
1137 @return EFI_SUCCESS Always returns success.\r
1138**/\r
1139EFI_STATUS\r
1140EFIAPI\r
1141GetDeviceConsistMappingInfo (\r
1142 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
1143 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
1144 )\r
1145{\r
e26d7b59 1146 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);\r
a405b86d 1147\r
1148 UINTN Index;\r
1149\r
1150 ASSERT(DevicePath != NULL);\r
1151 ASSERT(MappingItem != NULL);\r
1152\r
1a63ec8f 1153 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);\r
a405b86d 1154\r
1155 while (!IsDevicePathEnd (DevicePath)) {\r
1156 //\r
1157 // Find the handler to dump this device path node\r
1158 //\r
1159 SerialFun = NULL;\r
1160 for (Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) {\r
1161\r
1162 if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type &&\r
1163 DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType\r
1164 ) {\r
1165 SerialFun = DevPathConsistMappingTable[Index].SerialFun;\r
1166 break;\r
1167 }\r
1168 }\r
1169 //\r
1170 // If not found, use a generic function\r
1171 //\r
1172 if (!SerialFun) {\r
1173 SerialFun = DevPathSerialDefault;\r
1174 }\r
1175\r
1176 SerialFun (DevicePath, MappingItem);\r
1177\r
1178 //\r
1179 // Next device path node\r
1180 //\r
1181 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);\r
1182 }\r
1183\r
1184 return EFI_SUCCESS;\r
1185}\r
1186\r
1187/**\r
1188 Function to initialize the table for creating consistent map names.\r
1189\r
1190 @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object.\r
1191\r
1192 @retval EFI_SUCCESS The table was created successfully.\r
1193**/\r
1194EFI_STATUS\r
1195EFIAPI\r
1196ShellCommandConsistMappingInitialize (\r
1197 OUT EFI_DEVICE_PATH_PROTOCOL ***Table\r
1198 )\r
1199{\r
1200 EFI_HANDLE *HandleBuffer;\r
1201 UINTN HandleNum;\r
1202 UINTN HandleLoop;\r
1203 EFI_DEVICE_PATH_PROTOCOL **TempTable;\r
1204 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
1205 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1206 UINTN Index;\r
1207 EFI_STATUS Status;\r
1208\r
1209 HandleBuffer = NULL;\r
1210\r
1211 Status = gBS->LocateHandleBuffer (\r
1212 AllHandles,\r
1213 NULL,\r
1214 NULL,\r
1215 &HandleNum,\r
1216 &HandleBuffer\r
1217 );\r
1218 ASSERT_EFI_ERROR(Status);\r
1219\r
1220 TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));\r
1221 if (TempTable == NULL) {\r
1222 return EFI_OUT_OF_RESOURCES;\r
1223 }\r
1224\r
1225 for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) {\r
1226 DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]);\r
1227 if (DevicePath == NULL) {\r
1228 continue;\r
1229 }\r
1230\r
1231 HIDevicePath = GetHIDevicePath (DevicePath);\r
1232 if (HIDevicePath == NULL) {\r
1233 continue;\r
1234 }\r
1235\r
1236 for (Index = 0; TempTable[Index] != NULL; Index++) {\r
1237 if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) {\r
1238 FreePool (HIDevicePath);\r
1239 break;\r
1240 }\r
1241 }\r
1242\r
1243 if (TempTable[Index] == NULL) {\r
1244 TempTable[Index] = HIDevicePath;\r
1245 }\r
1246 }\r
1247\r
1248 for (Index = 0; TempTable[Index] != NULL; Index++);\r
1249 PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);\r
1250 *Table = TempTable;\r
1251\r
1252 if (HandleBuffer != NULL) {\r
1253 FreePool (HandleBuffer);\r
1254 }\r
1255\r
1256 return EFI_SUCCESS;\r
1257}\r
1258\r
1259/**\r
1260 Function to uninitialize the table for creating consistent map names.\r
1261\r
1262 The parameter must have been received from ShellCommandConsistMappingInitialize.\r
1263\r
1264 @param[out] Table The pointer to pointer to DevicePathProtocol object.\r
1265\r
1266 @retval EFI_SUCCESS The table was deleted successfully.\r
1267**/\r
1268EFI_STATUS\r
1269EFIAPI\r
1270ShellCommandConsistMappingUnInitialize (\r
1271 EFI_DEVICE_PATH_PROTOCOL **Table\r
1272 )\r
1273{\r
1274 UINTN Index;\r
1275\r
1276 ASSERT(Table != NULL);\r
1277\r
1278 for (Index = 0; Table[Index] != NULL; Index++) {\r
1279 FreePool (Table[Index]);\r
1280 }\r
1281\r
1282 FreePool (Table);\r
1283 return EFI_SUCCESS;\r
1284}\r
1285\r
1286/**\r
e26d7b59 1287 Create a consistent mapped name for the device specified by DevicePath\r
a405b86d 1288 based on the Table.\r
1289\r
e26d7b59 1290 This must be called after ShellCommandConsistMappingInitialize() and\r
a405b86d 1291 before ShellCommandConsistMappingUnInitialize() is called.\r
1292\r
1a63ec8f 1293 @param[in] DevicePath The pointer to the dev path for the device.\r
a405b86d 1294 @param[in] Table The Table of mapping information.\r
1295\r
1296 @retval NULL A consistent mapped name could not be created.\r
1297 @return A pointer to a string allocated from pool with the device name.\r
1298**/\r
1299CHAR16 *\r
1300EFIAPI\r
1301ShellCommandConsistMappingGenMappingName (\r
1a63ec8f 1302 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1303 IN EFI_DEVICE_PATH_PROTOCOL **Table\r
a405b86d 1304 )\r
1305{\r
1306 POOL_PRINT Str;\r
1307 DEVICE_CONSIST_MAPPING_INFO MappingInfo;\r
1308 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1309 UINTN Index;\r
1310 UINTN NewSize;\r
1311\r
1312 ASSERT(DevicePath != NULL);\r
1313 ASSERT(Table != NULL);\r
1314\r
1315 HIDevicePath = GetHIDevicePath (DevicePath);\r
1316 if (HIDevicePath == NULL) {\r
1317 return NULL;\r
1318 }\r
1319\r
1320 for (Index = 0; Table[Index] != NULL; Index++) {\r
1321 if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) {\r
1322 break;\r
1323 }\r
1324 }\r
1325\r
1326 FreePool (HIDevicePath);\r
1327 if (Table[Index] == NULL) {\r
1328 return NULL;\r
1329 }\r
1330\r
1a63ec8f 1331 MappingInfo.Hi = Index;\r
1332 MappingInfo.Mtd = MTDTypeUnknown;\r
a405b86d 1333 MappingInfo.Digital = FALSE;\r
1334\r
1335 GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);\r
1336\r
1337 SetMem (&Str, sizeof (Str), 0);\r
1338 for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {\r
1a63ec8f 1339 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {\r
a405b86d 1340 break;\r
1341 }\r
1342 }\r
1343\r
1344 if (mMTDName[Index].MTDType != MTDTypeEnd) {\r
1345 CatPrint (&Str, L"%s", mMTDName[Index].Name);\r
1346 }\r
1347\r
1a63ec8f 1348 CatPrint (&Str, L"%d", (UINTN) MappingInfo.Hi);\r
1349 if (MappingInfo.Csd.Str != NULL) {\r
1350 CatPrint (&Str, L"%s", MappingInfo.Csd.Str);\r
1351 FreePool (MappingInfo.Csd.Str);\r
a405b86d 1352 }\r
1353\r
1354 if (Str.Str != NULL) {\r
1355 CatPrint (&Str, L":");\r
1356 }\r
1357\r
1358 NewSize = (Str.Len + 1) * sizeof (CHAR16);\r
1359 Str.Str = ReallocatePool (Str.Len, NewSize, Str.Str);\r
e53bf79d 1360 if (Str.Str == NULL) {\r
1361 return (NULL);\r
1362 }\r
a405b86d 1363 Str.Str[Str.Len] = CHAR_NULL;\r
1364 return Str.Str;\r
1365}\r
1366\r
1367/**\r
1368 Function to search the list of mappings for the node on the list based on the key.\r
1369\r
1370 @param[in] MapKey String Key to search for on the map\r
1371\r
1372 @return the node on the list.\r
1373**/\r
1374SHELL_MAP_LIST *\r
1375EFIAPI\r
1376ShellCommandFindMapItem (\r
1377 IN CONST CHAR16 *MapKey\r
1378 )\r
1379{\r
1380 SHELL_MAP_LIST *MapListItem;\r
1381\r
1382 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)\r
1383 ; !IsNull(&gShellMapList.Link, &MapListItem->Link)\r
1384 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &MapListItem->Link)\r
1385 ){\r
1386 if (gUnicodeCollation->StriColl(gUnicodeCollation,MapListItem->MapName,(CHAR16*)MapKey) == 0) {\r
1387 return (MapListItem);\r
1388 }\r
1389 }\r
1390 return (NULL);\r
1391}\r
1392\r
1393\r