]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
Add missing braces around initializer.
[mirror_edk2.git] / ShellPkg / Library / UefiShellCommandLib / ConsistMapping.c
... / ...
CommitLineData
1/** @file\r
2 Main file for support of shell consist mapping.\r
3\r
4 Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
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
32 UINTN Hi;\r
33 MTD_TYPE Mtd;\r
34 POOL_PRINT Csd;\r
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
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
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
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
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
150 if (Str == NULL) {\r
151 return (EFI_INVALID_PARAMETER);\r
152 }\r
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
160 return (EFI_SUCCESS);\r
161}\r
162\r
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
174AppendCSDNum (\r
175 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
176 IN UINT64 Num\r
177 )\r
178{\r
179 if (MappingItem == NULL) {\r
180 return EFI_INVALID_PARAMETER;\r
181 }\r
182\r
183 if (MappingItem->Digital) {\r
184 CatPrint (&MappingItem->Csd, L"%ld", Num);\r
185 } else {\r
186 AppendCSDNum2 (&MappingItem->Csd, Num);\r
187 }\r
188\r
189 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);\r
190\r
191 return (EFI_SUCCESS);\r
192}\r
193\r
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
205AppendCSDStr (\r
206 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
207 IN CHAR16 *Str\r
208 )\r
209{\r
210 CHAR16 *Index;\r
211\r
212 if (Str == NULL || MappingItem == NULL) {\r
213 return (EFI_INVALID_PARAMETER);\r
214 }\r
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
233 CatPrint (&MappingItem->Csd, L"%c", *Index);\r
234 break;\r
235\r
236 case '1':\r
237 CatPrint (&MappingItem->Csd, L"16");\r
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
246 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'a' + '0');\r
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
255 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'A' + '0');\r
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
267 CatPrint (&MappingItem->Csd, L"%c", *Index - '0' + 'a');\r
268 } else if (*Index >= 'a' && *Index <= 'f') {\r
269 CatPrint (&MappingItem->Csd, L"%c", *Index - 'a' + 'k');\r
270 } else if (*Index >= 'A' && *Index <= 'F') {\r
271 CatPrint (&MappingItem->Csd, L"%c", *Index - 'A' + 'k');\r
272 }\r
273 }\r
274 }\r
275\r
276 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);\r
277\r
278 return (EFI_SUCCESS);\r
279}\r
280\r
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
292AppendCSDGuid (\r
293 DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
294 EFI_GUID *Guid\r
295 )\r
296{\r
297 CHAR16 Buffer[64];\r
298\r
299 if (Guid == NULL || MappingItem == NULL) {\r
300 return (EFI_INVALID_PARAMETER);\r
301 }\r
302\r
303 UnicodeSPrint (\r
304 Buffer,\r
305 0,\r
306 L"%g",\r
307 Guid\r
308 );\r
309\r
310 AppendCSDStr (MappingItem, Buffer);\r
311\r
312 return (EFI_SUCCESS);\r
313}\r
314\r
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
324INTN\r
325EFIAPI\r
326DevPathCompareAcpi (\r
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
334 if (DevicePath1 == NULL || DevicePath2 == NULL) {\r
335 return (-2);\r
336 }\r
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
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
360INTN\r
361EFIAPI\r
362DevPathComparePci (\r
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
439 if (MappingItem->Mtd == MTDTypeUnknown) {\r
440 MappingItem->Mtd = MTDTypeHardDisk;\r
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
487 MappingItem->Mtd = MTDTypeCDRom;\r
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
567\r
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
578\r
579 if (DevicePathNode == NULL || MappingItem == NULL) {\r
580 return;\r
581 }\r
582\r
583 Vendor = (VENDOR_DEVICE_PATH *) DevicePathNode;\r
584 AppendCSDGuid (MappingItem, &Vendor->Guid);\r
585\r
586 if (CompareGuid (&gEfiSasDevicePathGuid, &Vendor->Guid)) {\r
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
656// As Csd of ISCSI node is quite long, we comment\r
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
703 I2O_DEVICE_PATH *DevicePath_I20;\r
704\r
705 ASSERT(DevicePathNode != NULL);\r
706 ASSERT(MappingItem != NULL);\r
707\r
708 DevicePath_I20 = (I2O_DEVICE_PATH *) DevicePathNode;\r
709 AppendCSDNum (MappingItem, DevicePath_I20->Tid);\r
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
896 F1394_DEVICE_PATH *DevicePath_F1394;\r
897 CHAR16 Buffer[20];\r
898\r
899 ASSERT(DevicePathNode != NULL);\r
900 ASSERT(MappingItem != NULL);\r
901\r
902 DevicePath_F1394 = (F1394_DEVICE_PATH *) DevicePathNode;\r
903 UnicodeSPrint (Buffer, 0, L"%lx", DevicePath_F1394->Guid);\r
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
928 MappingItem->Mtd = MTDTypeFloppy;\r
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
937 @param[in] DevicePathNode Ignored.\r
938 @param[in] MappingItem Ignored.\r
939\r
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
949 return;\r
950}\r
951\r
952DEV_PATH_CONSIST_MAPPING_TABLE DevPathConsistMappingTable[] = {\r
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
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
1086 @retval TRUE The node is Hi.\r
1087 @retval FALSE The node is not Hi.\r
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
1120 Function to convert a standard device path structure into a Hi version.\r
1121\r
1122 @param[in] DevicePath The device path to convert.\r
1123\r
1124 @return the device path portion that is Hi.\r
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
1142 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
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
1188 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);\r
1189\r
1190 UINTN Index;\r
1191\r
1192 ASSERT(DevicePath != NULL);\r
1193 ASSERT(MappingItem != NULL);\r
1194\r
1195 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);\r
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
1329 Create a consistent mapped name for the device specified by DevicePath\r
1330 based on the Table.\r
1331\r
1332 This must be called after ShellCommandConsistMappingInitialize() and\r
1333 before ShellCommandConsistMappingUnInitialize() is called.\r
1334\r
1335 @param[in] DevicePath The pointer to the dev path for the device.\r
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
1344 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1345 IN EFI_DEVICE_PATH_PROTOCOL **Table\r
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
1373 MappingInfo.Hi = Index;\r
1374 MappingInfo.Mtd = MTDTypeUnknown;\r
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
1381 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {\r
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
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
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
1402 if (Str.Str == NULL) {\r
1403 return (NULL);\r
1404 }\r
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