| ... | ... | @@ -72,66 +72,39 @@ pub const DevicePathProtocol = packed struct { |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath { |
| 75 | | return switch (self.type) { |
| 76 | | .Hardware => blk: { |
| 77 | | const hardware: ?HardwareDevicePath = switch (@intToEnum(HardwareDevicePath.Subtype, self.subtype)) { |
| 78 | | .Pci => .{ .Pci = @ptrCast(*const HardwareDevicePath.PciDevicePath, self) }, |
| 79 | | .PcCard => .{ .PcCard = @ptrCast(*const HardwareDevicePath.PcCardDevicePath, self) }, |
| 80 | | .MemoryMapped => .{ .MemoryMapped = @ptrCast(*const HardwareDevicePath.MemoryMappedDevicePath, self) }, |
| 81 | | .Vendor => .{ .Vendor = @ptrCast(*const HardwareDevicePath.VendorDevicePath, self) }, |
| 82 | | .Controller => .{ .Controller = @ptrCast(*const HardwareDevicePath.ControllerDevicePath, self) }, |
| 83 | | .Bmc => .{ .Bmc = @ptrCast(*const HardwareDevicePath.BmcDevicePath, self) }, |
| 84 | | _ => null, |
| 85 | | }; |
| 86 | | break :blk if (hardware) |h| .{ .Hardware = h } else null; |
| 87 | | }, |
| 88 | | .Acpi => blk: { |
| 89 | | const acpi: ?AcpiDevicePath = switch (@intToEnum(AcpiDevicePath.Subtype, self.subtype)) { |
| 90 | | .Acpi => .{ .Acpi = @ptrCast(*const AcpiDevicePath.BaseAcpiDevicePath, self) }, |
| 91 | | .ExpandedAcpi => .{ .ExpandedAcpi = @ptrCast(*const AcpiDevicePath.ExpandedAcpiDevicePath, self) }, |
| 92 | | .Adr => .{ .Adr = @ptrCast(*const AcpiDevicePath.AdrDevicePath, self) }, |
| 93 | | _ => null, |
| 94 | | }; |
| 95 | | break :blk if (acpi) |a| .{ .Acpi = a } else null; |
| 96 | | }, |
| 97 | | .Messaging => blk: { |
| 98 | | const messaging: ?MessagingDevicePath = switch (@intToEnum(MessagingDevicePath.Subtype, self.subtype)) { |
| 99 | | else => null, // TODO |
| 100 | | }; |
| 101 | | break :blk if (messaging) |m| .{ .Messaging = m } else null; |
| 102 | | }, |
| 103 | | .Media => blk: { |
| 104 | | const media: ?MediaDevicePath = switch (@intToEnum(MediaDevicePath.Subtype, self.subtype)) { |
| 105 | | .HardDrive => .{ .HardDrive = @ptrCast(*const MediaDevicePath.HardDriveDevicePath, self) }, |
| 106 | | .Cdrom => .{ .Cdrom = @ptrCast(*const MediaDevicePath.CdromDevicePath, self) }, |
| 107 | | .Vendor => .{ .Vendor = @ptrCast(*const MediaDevicePath.VendorDevicePath, self) }, |
| 108 | | .FilePath => .{ .FilePath = @ptrCast(*const MediaDevicePath.FilePathDevicePath, self) }, |
| 109 | | .MediaProtocol => .{ .MediaProtocol = @ptrCast(*const MediaDevicePath.MediaProtocolDevicePath, self) }, |
| 110 | | .PiwgFirmwareFile => .{ .PiwgFirmwareFile = @ptrCast(*const MediaDevicePath.PiwgFirmwareFileDevicePath, self) }, |
| 111 | | .PiwgFirmwareVolume => .{ .PiwgFirmwareVolume = @ptrCast(*const MediaDevicePath.PiwgFirmwareVolumeDevicePath, self) }, |
| 112 | | .RelativeOffsetRange => .{ .RelativeOffsetRange = @ptrCast(*const MediaDevicePath.RelativeOffsetRangeDevicePath, self) }, |
| 113 | | .RamDisk => .{ .RamDisk = @ptrCast(*const MediaDevicePath.RamDiskDevicePath, self) }, |
| 114 | | _ => null, |
| 115 | | }; |
| 116 | | break :blk if (media) |m| .{ .Media = m } else null; |
| 117 | | }, |
| 118 | | .BiosBootSpecification => blk: { |
| 119 | | const bbs: ?BiosBootSpecificationDevicePath = switch (@intToEnum(BiosBootSpecificationDevicePath.Subtype, self.subtype)) { |
| 120 | | .BBS101 => .{ .BBS101 = @ptrCast(*const BiosBootSpecificationDevicePath.BBS101DevicePath, self) }, |
| 121 | | _ => null, |
| 122 | | }; |
| 123 | | break :blk if (bbs) |b| .{ .BiosBootSpecification = b } else null; |
| 124 | | }, |
| 125 | | .End => blk: { |
| 126 | | const end: ?EndDevicePath = switch (@intToEnum(EndDevicePath.Subtype, self.subtype)) { |
| 127 | | .EndEntire => .{ .EndEntire = @ptrCast(*const EndDevicePath.EndEntireDevicePath, self) }, |
| 128 | | .EndThisInstance => .{ .EndThisInstance = @ptrCast(*const EndDevicePath.EndThisInstanceDevicePath, self) }, |
| 129 | | _ => null, |
| 130 | | }; |
| 131 | | break :blk if (end) |e| .{ .End = e } else null; |
| 132 | | }, |
| 133 | | _ => null, |
| 134 | | }; |
| 75 | inline for (@typeInfo(DevicePath).Union.fields) |ufield| { |
| 76 | const enum_value = std.meta.stringToEnum(DevicePathType, ufield.name); |
| 77 | |
| 78 | // Got the associated union type for self.type, now |
| 79 | // we need to initialize it and its subtype |
| 80 | if (self.type == enum_value) { |
| 81 | var subtype = self.initSubtype(ufield.field_type); |
| 82 | |
| 83 | if (subtype) |sb| { |
| 84 | // e.g. return .{ .Hardware = .{ .Pci = @ptrCast(...) } } |
| 85 | return @unionInit(DevicePath, ufield.name, sb); |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | return null; |
| 91 | } |
| 92 | |
| 93 | pub fn initSubtype(self: *const DevicePathProtocol, comptime TUnion: type) ?TUnion { |
| 94 | const type_info = @typeInfo(TUnion).Union; |
| 95 | const TTag = type_info.tag_type.?; |
| 96 | |
| 97 | inline for (type_info.fields) |subtype| { |
| 98 | // The tag names match the union names, so just grab that off the enum |
| 99 | const tag_val: u8 = @enumToInt(@field(TTag, subtype.name)); |
| 100 | |
| 101 | if (self.subtype == tag_val) { |
| 102 | // e.g. expr = .{ .Pci = @ptrCast(...) } |
| 103 | return @unionInit(TUnion, subtype.name, @ptrCast(subtype.field_type, self)); |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | return null; |
| 135 | 108 | } |
| 136 | 109 | }; |
| 137 | 110 | |
| ... | ... | @@ -268,7 +241,7 @@ pub const MessagingDevicePath = union(Subtype) { |
| 268 | 241 | Atapi: *const AtapiDevicePath, |
| 269 | 242 | Scsi: *const ScsiDevicePath, |
| 270 | 243 | FibreChannel: *const FibreChannelDevicePath, |
| 271 | | FibreChannelEx: FibreChannelExDevicePath, |
| 244 | FibreChannelEx: *const FibreChannelExDevicePath, |
| 272 | 245 | @"1394": *const F1394DevicePath, |
| 273 | 246 | Usb: *const UsbDevicePath, |
| 274 | 247 | Sata: *const SataDevicePath, |