| ... | @@ -72,66 +72,39 @@ pub const DevicePathProtocol = packed struct { | ... | @@ -72,66 +72,39 @@ pub const DevicePathProtocol = packed struct { |
| 72 | } | 72 | } |
| 73 | | 73 | |
| 74 | pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath { | 74 | pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath { |
| 75 | return switch (self.type) { | 75 | inline for (@typeInfo(DevicePath).Union.fields) |ufield| { |
| 76 | .Hardware => blk: { | 76 | const enum_value = std.meta.stringToEnum(DevicePathType, ufield.name); |
| 77 | const hardware: ?HardwareDevicePath = switch (@intToEnum(HardwareDevicePath.Subtype, self.subtype)) { | 77 | |
| 78 | .Pci => .{ .Pci = @ptrCast(*const HardwareDevicePath.PciDevicePath, self) }, | 78 | // Got the associated union type for self.type, now |
| 79 | .PcCard => .{ .PcCard = @ptrCast(*const HardwareDevicePath.PcCardDevicePath, self) }, | 79 | // we need to initialize it and its subtype |
| 80 | .MemoryMapped => .{ .MemoryMapped = @ptrCast(*const HardwareDevicePath.MemoryMappedDevicePath, self) }, | 80 | if (self.type == enum_value) { |
| 81 | .Vendor => .{ .Vendor = @ptrCast(*const HardwareDevicePath.VendorDevicePath, self) }, | 81 | var subtype = self.initSubtype(ufield.field_type); |
| 82 | .Controller => .{ .Controller = @ptrCast(*const HardwareDevicePath.ControllerDevicePath, self) }, | 82 | |
| 83 | .Bmc => .{ .Bmc = @ptrCast(*const HardwareDevicePath.BmcDevicePath, self) }, | 83 | if (subtype) |sb| { |
| 84 | _ => null, | 84 | // e.g. return .{ .Hardware = .{ .Pci = @ptrCast(...) } } |
| 85 | }; | 85 | return @unionInit(DevicePath, ufield.name, sb); |
| 86 | break :blk if (hardware) |h| .{ .Hardware = h } else null; | 86 | } |
| 87 | }, | 87 | } |
| 88 | .Acpi => blk: { | 88 | } |
| 89 | const acpi: ?AcpiDevicePath = switch (@intToEnum(AcpiDevicePath.Subtype, self.subtype)) { | 89 | |
| 90 | .Acpi => .{ .Acpi = @ptrCast(*const AcpiDevicePath.BaseAcpiDevicePath, self) }, | 90 | return null; |
| 91 | .ExpandedAcpi => .{ .ExpandedAcpi = @ptrCast(*const AcpiDevicePath.ExpandedAcpiDevicePath, self) }, | 91 | } |
| 92 | .Adr => .{ .Adr = @ptrCast(*const AcpiDevicePath.AdrDevicePath, self) }, | 92 | |
| 93 | _ => null, | 93 | pub fn initSubtype(self: *const DevicePathProtocol, comptime TUnion: type) ?TUnion { |
| 94 | }; | 94 | const type_info = @typeInfo(TUnion).Union; |
| 95 | break :blk if (acpi) |a| .{ .Acpi = a } else null; | 95 | const TTag = type_info.tag_type.?; |
| 96 | }, | 96 | |
| 97 | .Messaging => blk: { | 97 | inline for (type_info.fields) |subtype| { |
| 98 | const messaging: ?MessagingDevicePath = switch (@intToEnum(MessagingDevicePath.Subtype, self.subtype)) { | 98 | // The tag names match the union names, so just grab that off the enum |
| 99 | else => null, // TODO | 99 | const tag_val: u8 = @enumToInt(@field(TTag, subtype.name)); |
| 100 | }; | 100 | |
| 101 | break :blk if (messaging) |m| .{ .Messaging = m } else null; | 101 | if (self.subtype == tag_val) { |
| 102 | }, | 102 | // e.g. expr = .{ .Pci = @ptrCast(...) } |
| 103 | .Media => blk: { | 103 | return @unionInit(TUnion, subtype.name, @ptrCast(subtype.field_type, self)); |
| 104 | const media: ?MediaDevicePath = switch (@intToEnum(MediaDevicePath.Subtype, self.subtype)) { | 104 | } |
| 105 | .HardDrive => .{ .HardDrive = @ptrCast(*const MediaDevicePath.HardDriveDevicePath, self) }, | 105 | } |
| 106 | .Cdrom => .{ .Cdrom = @ptrCast(*const MediaDevicePath.CdromDevicePath, self) }, | 106 | |
| 107 | .Vendor => .{ .Vendor = @ptrCast(*const MediaDevicePath.VendorDevicePath, self) }, | 107 | return null; |
| 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 | }; | | |
| 135 | } | 108 | } |
| 136 | }; | 109 | }; |
| 137 | | 110 | |
| ... | @@ -268,7 +241,7 @@ pub const MessagingDevicePath = union(Subtype) { | ... | @@ -268,7 +241,7 @@ pub const MessagingDevicePath = union(Subtype) { |
| 268 | Atapi: *const AtapiDevicePath, | 241 | Atapi: *const AtapiDevicePath, |
| 269 | Scsi: *const ScsiDevicePath, | 242 | Scsi: *const ScsiDevicePath, |
| 270 | FibreChannel: *const FibreChannelDevicePath, | 243 | FibreChannel: *const FibreChannelDevicePath, |
| 271 | FibreChannelEx: FibreChannelExDevicePath, | 244 | FibreChannelEx: *const FibreChannelExDevicePath, |
| 272 | @"1394": *const F1394DevicePath, | 245 | @"1394": *const F1394DevicePath, |
| 273 | Usb: *const UsbDevicePath, | 246 | Usb: *const UsbDevicePath, |
| 274 | Sata: *const SataDevicePath, | 247 | Sata: *const SataDevicePath, |