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