+ } else if (NumNodes >= 3 &&\r
+ SubstringEq (OfwNode[1].DriverName, "scsi") &&\r
+ SubstringEq (OfwNode[2].DriverName, "disk")\r
+ ) {\r
+ //\r
+ // OpenFirmware device path (virtio-blk disk):\r
+ //\r
+ // /pci@i0cf8/scsi@6[,3]/disk@0,0\r
+ // ^ ^ ^ ^ ^\r
+ // | | | fixed\r
+ // | | PCI function corresponding to disk (optional)\r
+ // | PCI slot holding disk\r
+ // PCI root at system bus port, PIO\r
+ //\r
+ // UEFI device path prefix:\r
+ //\r
+ // PciRoot(0x0)/Pci(0x6,0x0)/HD( -- if PCI function is 0 or absent\r
+ // PciRoot(0x0)/Pci(0x6,0x3)/HD( -- if PCI function is present and nonzero\r
+ //\r
+ Written = UnicodeSPrintAsciiFormat (\r
+ Translated,\r
+ *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
+ "PciRoot(0x0)/Pci(0x%x,0x%x)/HD(",\r
+ PciDevFun[0],\r
+ PciDevFun[1]\r
+ );\r
+ } else if (NumNodes >= 4 &&\r
+ SubstringEq (OfwNode[1].DriverName, "scsi") &&\r
+ SubstringEq (OfwNode[2].DriverName, "channel") &&\r
+ SubstringEq (OfwNode[3].DriverName, "disk")\r
+ ) {\r
+ //\r
+ // OpenFirmware device path (virtio-scsi disk):\r
+ //\r
+ // /pci@i0cf8/scsi@7[,3]/channel@0/disk@2,3\r
+ // ^ ^ ^ ^ ^\r
+ // | | | | LUN\r
+ // | | | target\r
+ // | | channel (unused, fixed 0)\r
+ // | PCI slot[, function] holding SCSI controller\r
+ // PCI root at system bus port, PIO\r
+ //\r
+ // UEFI device path prefix:\r
+ //\r
+ // PciRoot(0x0)/Pci(0x7,0x0)/Scsi(0x2,0x3)\r
+ // -- if PCI function is 0 or absent\r
+ // PciRoot(0x0)/Pci(0x7,0x3)/Scsi(0x2,0x3)\r
+ // -- if PCI function is present and nonzero\r
+ //\r
+ UINT32 TargetLun[2];\r
+\r
+ TargetLun[1] = 0;\r
+ NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);\r
+ if (ParseUnitAddressHexList (\r
+ OfwNode[3].UnitAddress,\r
+ TargetLun,\r
+ &NumEntries\r
+ ) != RETURN_SUCCESS\r
+ ) {\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ Written = UnicodeSPrintAsciiFormat (\r
+ Translated,\r
+ *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
+ "PciRoot(0x0)/Pci(0x%x,0x%x)/Scsi(0x%x,0x%x)",\r
+ PciDevFun[0],\r
+ PciDevFun[1],\r
+ TargetLun[0],\r
+ TargetLun[1]\r
+ );\r
+ } else if (NumNodes >= 3 &&\r
+ SubstringEq (OfwNode[1].DriverName, "ethernet") &&\r
+ SubstringEq (OfwNode[2].DriverName, "ethernet-phy")\r
+ ) {\r
+ //\r
+ // OpenFirmware device path (Ethernet NIC):\r
+ //\r
+ // /pci@i0cf8/ethernet@3[,2]/ethernet-phy@0\r
+ // ^ ^ ^\r
+ // | | fixed\r
+ // | PCI slot[, function] holding Ethernet card\r
+ // PCI root at system bus port, PIO\r
+ //\r
+ // UEFI device path prefix (dependent on presence of nonzero PCI function):\r
+ //\r
+ // PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400E15EEF,0x1)\r
+ // PciRoot(0x0)/Pci(0x3,0x2)/MAC(525400E15EEF,0x1)\r
+ // ^ ^\r
+ // MAC address IfType (1 == Ethernet)\r
+ //\r
+ // (Some UEFI NIC drivers don't set 0x1 for IfType.)\r
+ //\r
+ Written = UnicodeSPrintAsciiFormat (\r
+ Translated,\r
+ *TranslatedSize * sizeof (*Translated), // BufferSize in bytes\r
+ "PciRoot(0x0)/Pci(0x%x,0x%x)/MAC",\r
+ PciDevFun[0],\r
+ PciDevFun[1]\r
+ );\r
+ } else {\r
+ return RETURN_UNSUPPORTED;\r
+ }\r