]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
consist mapping - add comments and change variable names.
[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 - 2011, 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 HARDWARE_DEVICE_PATH,\r
954 HW_PCI_DP,\r
955 DevPathSerialDefault,\r
956 DevPathComparePci,\r
957 ACPI_DEVICE_PATH,\r
958 ACPI_DP,\r
959 DevPathSerialAcpi,\r
960 DevPathCompareAcpi,\r
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
1044 @retval TRUE The node is Hi.\r
1045 @retval FALSE The node is not Hi.\r
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
1078 Function to convert a standard device path structure into a Hi version.\r
1079\r
1080 @param[in] DevicePath The device path to convert.\r
1081\r
1082 @return the device path portion that is Hi.\r
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
1100 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
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
1146 VOID (EFIAPI *SerialFun) (EFI_DEVICE_PATH_PROTOCOL *, DEVICE_CONSIST_MAPPING_INFO *);\r
1147\r
1148 UINTN Index;\r
1149\r
1150 ASSERT(DevicePath != NULL);\r
1151 ASSERT(MappingItem != NULL);\r
1152\r
1153 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);\r
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
1287 Create a consistent mapped name for the device specified by DevicePath\r
1288 based on the Table.\r
1289\r
1290 This must be called after ShellCommandConsistMappingInitialize() and\r
1291 before ShellCommandConsistMappingUnInitialize() is called.\r
1292\r
1293 @param[in] DevicePath The pointer to the dev path for the device.\r
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
1302 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1303 IN EFI_DEVICE_PATH_PROTOCOL **Table\r
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
1331 MappingInfo.Hi = Index;\r
1332 MappingInfo.Mtd = MTDTypeUnknown;\r
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
1339 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {\r
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
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
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
1360 if (Str.Str == NULL) {\r
1361 return (NULL);\r
1362 }\r
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