diff --git a/DiscImageChef.Devices/FreeBSD/Enums.cs b/DiscImageChef.Devices/FreeBSD/Enums.cs
index 6096f417..ba40aed6 100644
--- a/DiscImageChef.Devices/FreeBSD/Enums.cs
+++ b/DiscImageChef.Devices/FreeBSD/Enums.cs
@@ -253,5 +253,137 @@ namespace DiscImageChef.Devices.FreeBSD
/// Vendor Unique codes: 0x80->0x8F
XPT_VUNIQUE = 0x80
}
+
+ enum ccb_dev_match_status
+ {
+ CAM_DEV_MATCH_LAST,
+ CAM_DEV_MATCH_MORE,
+ CAM_DEV_MATCH_LIST_CHANGED,
+ CAM_DEV_MATCH_SIZE_ERROR,
+ CAM_DEV_MATCH_ERROR
+ }
+
+ enum dev_match_type
+ {
+ DEV_MATCH_PERIPH,
+ DEV_MATCH_DEVICE,
+ DEV_MATCH_BUS
+ }
+
+ [Flags]
+ enum periph_pattern_flags
+ {
+ PERIPH_MATCH_NONE = 0x000,
+ PERIPH_MATCH_PATH = 0x001,
+ PERIPH_MATCH_TARGET = 0x002,
+ PERIPH_MATCH_LUN = 0x004,
+ PERIPH_MATCH_NAME = 0x008,
+ PERIPH_MATCH_UNIT = 0x010,
+ // PERIPH_MATCH_ANY = 0x01f
+ }
+
+ [Flags]
+ enum dev_pattern_flags
+ {
+ DEV_MATCH_NONE = 0x000,
+ DEV_MATCH_PATH = 0x001,
+ DEV_MATCH_TARGET = 0x002,
+ DEV_MATCH_LUN = 0x004,
+ DEV_MATCH_INQUIRY = 0x008,
+ DEV_MATCH_DEVID = 0x010,
+ // DEV_MATCH_ANY = 0x00f
+ }
+
+ [Flags]
+ enum bus_pattern_flags
+ {
+ BUS_MATCH_NONE = 0x000,
+ BUS_MATCH_PATH = 0x001,
+ BUS_MATCH_NAME = 0x002,
+ BUS_MATCH_UNIT = 0x004,
+ BUS_MATCH_BUS_ID = 0x008,
+ // BUS_MATCH_ANY = 0x00f
+ }
+
+ [Flags]
+ enum dev_result_flags
+ {
+ DEV_RESULT_NOFLAG = 0x00,
+ DEV_RESULT_UNCONFIGURED = 0x01
+ }
+
+ enum cam_proto
+ {
+ PROTO_UNKNOWN,
+ PROTO_UNSPECIFIED,
+
+ ///
+ /// Small Computer System Interface
+ ///
+ PROTO_SCSI,
+
+ ///
+ /// AT Attachment
+ ///
+ PROTO_ATA,
+
+ ///
+ /// AT Attachment Packetized Interface
+ ///
+ PROTO_ATAPI,
+
+ ///
+ /// SATA Port Multiplier
+ ///
+ PROTO_SATAPM,
+
+ ///
+ /// SATA Enclosure Management Bridge
+ ///
+ PROTO_SEMB,
+
+ ///
+ /// NVMe
+ ///
+ PROTO_NVME,
+
+ ///
+ /// MMC, SD, SDIO
+ ///
+ PROTO_MMCSD,
+ }
+
+ [Flags]
+ enum mmc_card_features
+ {
+ CARD_FEATURE_MEMORY = 0x1,
+ CARD_FEATURE_SDHC = 0x1 << 1,
+ CARD_FEATURE_SDIO = 0x1 << 2,
+ CARD_FEATURE_SD20 = 0x1 << 3,
+ CARD_FEATURE_MMC = 0x1 << 4,
+ CARD_FEATURE_18V = 0x1 << 5,
+ }
+
+ enum cam_generations : uint
+ {
+ CAM_BUS_GENERATION = 0x00,
+ CAM_TARGET_GENERATION = 0x01,
+ CAM_DEV_GENERATION = 0x02,
+ CAM_PERIPH_GENERATION = 0x03,
+ }
+
+ [Flags]
+ enum dev_pos_type
+ {
+ CAM_DEV_POS_NONE = 0x000,
+ CAM_DEV_POS_BUS = 0x001,
+ CAM_DEV_POS_TARGET = 0x002,
+ CAM_DEV_POS_DEVICE = 0x004,
+ CAM_DEV_POS_PERIPH = 0x008,
+ CAM_DEV_POS_PDPTR = 0x010,
+ // CAM_DEV_POS_TYPEMASK = 0xf00,
+ CAM_DEV_POS_EDT = 0x100,
+ CAM_DEV_POS_PDRV = 0x200
+ }
}
diff --git a/DiscImageChef.Devices/FreeBSD/Structs.cs b/DiscImageChef.Devices/FreeBSD/Structs.cs
index 98005f25..5d1d298a 100644
--- a/DiscImageChef.Devices/FreeBSD/Structs.cs
+++ b/DiscImageChef.Devices/FreeBSD/Structs.cs
@@ -33,6 +33,9 @@
using System;
using System.Runtime.InteropServices;
+using path_id_t = System.UInt32;
+using target_id_t = System.UInt32;
+using lun_id_t = System.UInt64;
namespace DiscImageChef.Devices.FreeBSD
{
@@ -375,5 +378,213 @@ namespace DiscImageChef.Devices.FreeBSD
/// padding for removed uint32_t
public ushort unused;
}
+
+ struct periph_match_pattern
+ {
+ private const int DEV_IDLEN = 16;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)] public byte[] periph_name;
+ public uint unit_number;
+ public path_id_t path_id;
+ public target_id_t target_id;
+ public lun_id_t target_lun;
+ public periph_pattern_flags flags;
+ }
+
+ struct device_id_match_pattern
+ {
+ public byte id_len;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] id;
+ }
+
+ struct scsi_static_inquiry_pattern
+ {
+ private const int SID_VENDOR_SIZE = 8;
+ private const int SID_PRODUCT_SIZE = 16;
+ private const int SID_REVISION_SIZE = 4;
+ public byte type;
+ public byte media_type;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_VENDOR_SIZE + 1)] public byte[] vendor;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_PRODUCT_SIZE + 1)] public byte[] product;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_REVISION_SIZE + 1)] public byte[] revision;
+ }
+
+ struct device_match_pattern_data
+ {
+ [FieldOffset(0)] public scsi_static_inquiry_pattern inq_pat;
+ [FieldOffset(0)] public device_id_match_pattern devid_pat;
+ }
+
+ struct device_match_pattern
+ {
+ public path_id_t path_id;
+ public target_id_t target_id;
+ public lun_id_t target_lun;
+ public dev_pattern_flags flags;
+ public device_match_pattern_data data;
+ }
+
+ struct bus_match_pattern
+ {
+ private const int DEV_IDLEN = 16;
+
+ public path_id_t path_id;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)] public byte[] dev_name;
+ public uint unit_number;
+ public uint bus_id;
+ bus_pattern_flags flags;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ struct match_pattern
+ {
+ [FieldOffset(0)] public periph_match_pattern periph_pattern;
+ [FieldOffset(0)] public device_match_pattern device_pattern;
+ [FieldOffset(0)] public bus_match_pattern bus_pattern;
+ }
+
+ struct dev_match_pattern
+ {
+ public dev_match_type type;
+ public match_pattern pattern;
+ }
+
+ struct periph_match_result
+ {
+ private const int DEV_IDLEN = 16;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)] public byte[] periph_name;
+ public uint unit_number;
+ public path_id_t path_id;
+ public target_id_t target_id;
+ public lun_id_t target_lun;
+ }
+
+ struct mmc_cid
+ {
+ public uint mid;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] pnm;
+ public uint psn;
+ public ushort oid;
+ public ushort mdt_year;
+ public byte mdt_month;
+ public byte prv;
+ public byte fwrev;
+ }
+
+ struct mmc_params
+ {
+ ///
+ /// Card model
+ ///
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] public byte[] model;
+
+ ///
+ /// Card OCR
+ ///
+ public uint card_ocr;
+
+ ///
+ /// OCR of the IO portion of the card
+ ///
+ public uint io_ocr;
+
+ ///
+ /// Card CID -- raw
+ ///
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] card_cid;
+
+ ///
+ /// Card CID -- parsed
+ ///
+ public mmc_cid cid;
+
+ ///
+ /// Card CSD -- raw
+ ///
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public uint[] card_csd;
+
+ ///
+ /// Card RCA
+ ///
+ public ushort card_rca;
+
+ ///
+ /// What kind of card is it
+ ///
+ public mmc_card_features card_features;
+
+ public byte sdio_func_count;
+ }
+
+ struct device_match_result
+ {
+ public path_id_t path_id;
+ public target_id_t target_id;
+ public lun_id_t target_lun;
+ public cam_proto protocol;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] inq_data;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] ident_data;
+ public dev_result_flags flags;
+ public mmc_params mmc_ident_data;
+ }
+ struct bus_match_result {
+ public path_id_t path_id;
+ private const int DEV_IDLEN = 16;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)] public byte[] dev_name;
+ public uint unit_number;
+ public uint bus_id;
+ }
+ [StructLayout(LayoutKind.Explicit)]
+ struct match_result
+ {
+ [FieldOffset(0)] public periph_match_result periph_result;
+ [FieldOffset(0)] public device_match_result device_result;
+ [FieldOffset(0)] public bus_match_result bus_result;
+ }
+
+ struct dev_match_result
+ {
+ public dev_match_type type;
+ public match_result result;
+ }
+
+ struct ccb_dm_cookie
+ {
+ public IntPtr bus;
+ public IntPtr target;
+ public IntPtr device;
+ public IntPtr periph;
+ public IntPtr pdrv;
+ }
+
+ struct ccb_dev_position
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public cam_generations[] generations;
+ dev_pos_type position_type;
+ public ccb_dm_cookie cookie;
+ }
+
+ struct ccb_dev_match
+ {
+ public ccb_hdr ccb_h;
+ ccb_dev_match_status status;
+ public uint num_patterns;
+ public uint pattern_buf_len;
+
+ ///
+ /// dev_match_pattern*
+ ///
+ public IntPtr patterns;
+
+ public uint num_matches;
+ public uint match_buf_len;
+
+ ///
+ /// dev_match_result*
+ ///
+ public IntPtr matches;
+
+ public ccb_dev_position pos;
+ }
}