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