| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-2-Clause |
| 3 | * |
| 4 | * Copyright (c) 2012 Alexander Motin <mav@FreeBSD.org> |
| 5 | * Copyright (c) 2008 Scott Long |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions |
| 10 | * are met: |
| 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer, |
| 13 | * without modification, immediately at the beginning of the file. |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 15 | * notice, this list of conditions and the following disclaimer in the |
| 16 | * documentation and/or other materials provided with the distribution. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | */ |
| 29 | |
| 30 | #ifndef MD_DDF_H |
| 31 | #define MD_DDF_H |
| 32 | |
| 33 | /* Definitions from the SNIA DDF spec, rev 1.2/2.0 */ |
| 34 | |
| 35 | #define	DDF_HEADER_LENGTH		512 |
| 36 | struct ddf_header { |
| 37 | 	uint32_t	Signature; |
| 38 | #define	DDF_HEADER_SIGNATURE	0xde11de11 |
| 39 | 	uint32_t	CRC; |
| 40 | 	uint8_t		DDF_Header_GUID[24]; |
| 41 | 	uint8_t		DDF_rev[8]; |
| 42 | 	uint32_t	Sequence_Number; |
| 43 | 	uint32_t	TimeStamp; |
| 44 | 	uint8_t		Open_Flag; |
| 45 | #define	DDF_HEADER_CLOSED	0x00 |
| 46 | #define	DDF_HEADER_OPENED_MASK	0x0f |
| 47 | #define	DDF_HEADER_OPEN_ANCHOR	0xff |
| 48 | 	uint8_t		Foreign_Flag; |
| 49 | 	uint8_t		Diskgrouping; |
| 50 | 	uint8_t		pad1[13]; |
| 51 | 	uint8_t		Header_ext[32]; |
| 52 | 	uint64_t	Primary_Header_LBA; |
| 53 | 	uint64_t	Secondary_Header_LBA; |
| 54 | 	uint8_t		Header_Type; |
| 55 | #define	DDF_HEADER_ANCHOR	0x00 |
| 56 | #define	DDF_HEADER_PRIMARY	0x01 |
| 57 | #define	DDF_HEADER_SECONDARY	0x02 |
| 58 | 	uint8_t		pad2[3]; |
| 59 | 	uint32_t	WorkSpace_Length; |
| 60 | 	uint64_t	WorkSpace_LBA; |
| 61 | 	uint16_t	Max_PD_Entries; |
| 62 | 	uint16_t	Max_VD_Entries; |
| 63 | 	uint16_t	Max_Partitions; |
| 64 | 	uint16_t	Configuration_Record_Length; |
| 65 | 	uint16_t	Max_Primary_Element_Entries; |
| 66 | 	uint32_t	Max_Mapped_Block_Entries; /* DDF 2.0 */ |
| 67 | 	uint8_t		pad3[50]; |
| 68 | 	uint32_t	cd_section;	/* Controller_Data_Section */ |
| 69 | 	uint32_t	cd_length;	/* Controller_Data_Section_Length */ |
| 70 | 	uint32_t	pdr_section;	/* Physical_Drive_Records_Section */ |
| 71 | 	uint32_t	pdr_length;	/* Physical_Drive_Records_Length */ |
| 72 | 	uint32_t	vdr_section;	/* Virtual_Drive_Records_Section */ |
| 73 | 	uint32_t	vdr_length;	/* Virtual_Drive_Records_Length */ |
| 74 | 	uint32_t	cr_section;	/* Configuration_Records_Section */ |
| 75 | 	uint32_t	cr_length;	/* Configuration_Records_Length */ |
| 76 | 	uint32_t	pdd_section;	/* Physical_Drive_Data_Section */ |
| 77 | 	uint32_t	pdd_length;	/* Physical_Drive_Data_Length */ |
| 78 | 	uint32_t	bbmlog_section;	/* BBM_Log_Section */ |
| 79 | 	uint32_t	bbmlog_length;	/* BBM_Log_Section_Length */ |
| 80 | 	uint32_t	Diagnostic_Space; |
| 81 | 	uint32_t	Diagnostic_Space_Length; |
| 82 | 	uint32_t	Vendor_Specific_Logs; |
| 83 | 	uint32_t	Vendor_Specific_Logs_Length; |
| 84 | 	uint8_t		pad4[256]; |
| 85 | } __packed; |
| 86 | |
| 87 | struct ddf_cd_record { |
| 88 | 	uint32_t	Signature; |
| 89 | #define	DDF_CONTROLLER_DATA_SIGNATURE	0xad111111 |
| 90 | 	uint32_t	CRC; |
| 91 | 	uint8_t		Controller_GUID[24]; |
| 92 | 	struct { |
| 93 | 		uint16_t	Vendor_ID; |
| 94 | 		uint16_t	Device_ID; |
| 95 | 		uint16_t	SubVendor_ID; |
| 96 | 		uint16_t	SubDevice_ID; |
| 97 | 	} Controller_Type __packed; |
| 98 | 	uint8_t		Product_ID[16]; |
| 99 | 	uint8_t		pad1[8]; |
| 100 | 	uint8_t		Controller_Data[448]; |
| 101 | } __packed; |
| 102 | |
| 103 | struct ddf_device_scsi { |
| 104 | 	uint8_t		Lun; |
| 105 | 	uint8_t		Id; |
| 106 | 	uint8_t		Channel; |
| 107 | 	uint8_t		Path_Flags; |
| 108 | #define DDF_DEVICE_SCSI_FLAG_BROKEN	(1 << 7) |
| 109 | } __packed; |
| 110 | |
| 111 | struct ddf_device_sas { |
| 112 | 	uint64_t	Initiator_Path; |
| 113 | } __packed; |
| 114 | |
| 115 | union ddf_pathinfo { |
| 116 | 	struct { |
| 117 | 		struct ddf_device_scsi	Path0; |
| 118 | 		struct ddf_device_scsi	Path1; |
| 119 | 		uint8_t			pad[10]; |
| 120 | 	} __packed scsi; |
| 121 | 	struct { |
| 122 | 		struct ddf_device_sas	Path0; |
| 123 | 		struct ddf_device_sas	Path1; |
| 124 | 		uint8_t			Path0_Flags; |
| 125 | 		uint8_t			Path1_Flags; |
| 126 | #define DDF_DEVICE_SAS_PHY_ID		0x7f |
| 127 | #define DDF_DEVICE_SAS_FLAG_BROKEN	(1 << 7) |
| 128 | 	} __packed sas; |
| 129 | } __packed; |
| 130 | |
| 131 | struct ddf_pd_entry { |
| 132 | 	uint8_t			PD_GUID[24]; |
| 133 | 	uint32_t		PD_Reference; |
| 134 | 	uint16_t		PD_Type; |
| 135 | #define	DDF_PDE_GUID_FORCE	(1 << 0) |
| 136 | #define	DDF_PDE_PARTICIPATING	(1 << 1) |
| 137 | #define	DDF_PDE_GLOBAL_SPARE	(1 << 2) |
| 138 | #define	DDF_PDE_CONFIG_SPARE	(1 << 3) |
| 139 | #define	DDF_PDE_FOREIGN		(1 << 4) |
| 140 | #define	DDF_PDE_LEGACY		(1 << 5) |
| 141 | #define DDF_PDE_TYPE_MASK	(0x0f << 12) |
| 142 | #define DDF_PDE_UNKNOWN		(0x00 << 12) |
| 143 | #define DDF_PDE_SCSI		(0x01 << 12) |
| 144 | #define DDF_PDE_SAS		(0x02 << 12) |
| 145 | #define DDF_PDE_SATA		(0x03 << 12) |
| 146 | #define DDF_PDE_FC		(0x04 << 12) |
| 147 | 	uint16_t		PD_State; |
| 148 | #define	DDF_PDE_ONLINE		(1 << 0) |
| 149 | #define	DDF_PDE_FAILED		(1 << 1) |
| 150 | #define	DDF_PDE_REBUILD		(1 << 2) |
| 151 | #define	DDF_PDE_TRANSITION	(1 << 3) |
| 152 | #define	DDF_PDE_PFA		(1 << 4) |
| 153 | #define	DDF_PDE_UNRECOVERED	(1 << 5) |
| 154 | #define	DDF_PDE_MISSING		(1 << 6) |
| 155 | 	uint64_t		Configured_Size; |
| 156 | 	union ddf_pathinfo	Path_Information; |
| 157 | 	uint16_t		Block_Size;	/* DDF 2.0 */ |
| 158 | 	uint8_t			pad1[4]; |
| 159 | } __packed; |
| 160 | |
| 161 | struct ddf_pd_record { |
| 162 | 	uint32_t		Signature; |
| 163 | #define	DDF_PDR_SIGNATURE	0x22222222 |
| 164 | 	uint32_t		CRC; |
| 165 | 	uint16_t		Populated_PDEs; |
| 166 | 	uint16_t		Max_PDE_Supported; |
| 167 | 	uint8_t			pad1[52]; |
| 168 | 	struct ddf_pd_entry	entry[0]; |
| 169 | } __packed; |
| 170 | |
| 171 | struct ddf_vd_entry { |
| 172 | 	uint8_t			VD_GUID[24]; |
| 173 | 	uint16_t		VD_Number; |
| 174 | 	uint8_t			pad1[2]; |
| 175 | 	uint16_t		VD_Type; |
| 176 | #define DDF_VDE_SHARED		(1 << 0) |
| 177 | #define	DDF_VDE_ENFORCE_GROUP	(1 << 1) |
| 178 | #define	DDF_VDE_UNICODE_NAME	(1 << 2) |
| 179 | #define	DDF_VDE_OWNER_ID_VALID	(1 << 3) |
| 180 | 	uint16_t		Controller_GUID_CRC; |
| 181 | 	uint8_t			VD_State; |
| 182 | #define	DDF_VDE_OPTIMAL		0x00 |
| 183 | #define	DDF_VDE_DEGRADED	0x01 |
| 184 | #define	DDF_VDE_DELETED		0x02 |
| 185 | #define	DDF_VDE_MISSING		0x03 |
| 186 | #define	DDF_VDE_FAILED		0x04 |
| 187 | #define DDF_VDE_PARTIAL		0x05 |
| 188 | #define DDF_VDE_OFFLINE		0x06 |
| 189 | #define	DDF_VDE_STATE_MASK	0x07 |
| 190 | #define	DDF_VDE_MORPH		(1 << 3) |
| 191 | #define	DDF_VDE_DIRTY		(1 << 4) |
| 192 | 	uint8_t			Init_State; |
| 193 | #define	DDF_VDE_UNINTIALIZED	0x00 |
| 194 | #define	DDF_VDE_INIT_QUICK	0x01 |
| 195 | #define	DDF_VDE_INIT_FULL	0x02 |
| 196 | #define	DDF_VDE_INIT_MASK	0x03 |
| 197 | #define	DDF_VDE_UACCESS_RW	0x00 |
| 198 | #define	DDF_VDE_UACCESS_RO	0x80 |
| 199 | #define	DDF_VDE_UACCESS_BLOCKED	0xc0 |
| 200 | #define	DDF_VDE_UACCESS_MASK	0xc0 |
| 201 | 	uint8_t			Drive_Failures_Remaining;	/* DDF 2.0 */ |
| 202 | 	uint8_t			pad2[13]; |
| 203 | 	uint8_t			VD_Name[16]; |
| 204 | } __packed; |
| 205 | |
| 206 | struct ddf_vd_record { |
| 207 | 	uint32_t		Signature; |
| 208 | #define	DDF_VD_RECORD_SIGNATURE	0xdddddddd |
| 209 | 	uint32_t		CRC; |
| 210 | 	uint16_t		Populated_VDEs; |
| 211 | 	uint16_t		Max_VDE_Supported; |
| 212 | 	uint8_t			pad1[52]; |
| 213 | 	struct ddf_vd_entry	entry[0]; |
| 214 | } __packed; |
| 215 | |
| 216 | #define DDF_CR_INVALID		0xffffffff |
| 217 | |
| 218 | struct ddf_vdc_record { |
| 219 | 	uint32_t	Signature; |
| 220 | #define	DDF_VDCR_SIGNATURE	0xeeeeeeee |
| 221 | 	uint32_t	CRC; |
| 222 | 	uint8_t		VD_GUID[24]; |
| 223 | 	uint32_t	Timestamp; |
| 224 | 	uint32_t	Sequence_Number; |
| 225 | 	uint8_t		pad1[24]; |
| 226 | 	uint16_t	Primary_Element_Count; |
| 227 | 	uint8_t		Stripe_Size; |
| 228 | 	uint8_t		Primary_RAID_Level; |
| 229 | #define DDF_VDCR_RAID0		0x00 |
| 230 | #define DDF_VDCR_RAID1		0x01 |
| 231 | #define DDF_VDCR_RAID3		0x03 |
| 232 | #define DDF_VDCR_RAID4		0x04 |
| 233 | #define DDF_VDCR_RAID5		0x05 |
| 234 | #define DDF_VDCR_RAID6		0x06 |
| 235 | #define DDF_VDCR_RAID1E		0x11 |
| 236 | #define DDF_VDCR_SINGLE		0x0f |
| 237 | #define DDF_VDCR_CONCAT		0x1f |
| 238 | #define DDF_VDCR_RAID5E		0x15 |
| 239 | #define DDF_VDCR_RAID5EE	0x25 |
| 240 | 	uint8_t		RLQ; |
| 241 | 	uint8_t		Secondary_Element_Count; |
| 242 | 	uint8_t		Secondary_Element_Seq; |
| 243 | 	uint8_t		Secondary_RAID_Level; |
| 244 | 	uint64_t	Block_Count; |
| 245 | 	uint64_t	VD_Size; |
| 246 | 	uint16_t	Block_Size;			/* DDF 2.0 */ |
| 247 | 	uint8_t		Rotate_Parity_count;		/* DDF 2.0 */ |
| 248 | 	uint8_t		pad2[5]; |
| 249 | 	uint32_t	Associated_Spares[8]; |
| 250 | 	uint64_t	Cache_Flags; |
| 251 | #define DDF_VDCR_CACHE_WB		(1 << 0) |
| 252 | #define	DDF_VDCR_CACHE_WB_ADAPTIVE	(1 << 1) |
| 253 | #define	DDF_VDCR_CACHE_RA		(1 << 2) |
| 254 | #define	DDF_VDCR_CACHE_RA_ADAPTIVE	(1 << 3) |
| 255 | #define	DDF_VDCR_CACHE_WCACHE_NOBATTERY	(1 << 4) |
| 256 | #define	DDF_VDCR_CACHE_WCACHE_ALLOW	(1 << 5) |
| 257 | #define	DDF_VDCR_CACHE_RCACHE_ALLOW	(1 << 6) |
| 258 | #define	DDF_VDCR_CACHE_VENDOR		(1 << 7) |
| 259 | 	uint8_t		BG_Rate; |
| 260 | 	uint8_t		pad3[3]; |
| 261 | 	uint8_t		MDF_Parity_Disks;		/* DDF 2.0 */ |
| 262 | 	uint16_t	MDF_Parity_Generator_Polynomial; /* DDF 2.0 */ |
| 263 | 	uint8_t		pad4; |
| 264 | 	uint8_t		MDF_Constant_Generation_Method; /* DDF 2.0 */ |
| 265 | 	uint8_t		pad5[47]; |
| 266 | 	uint8_t		pad6[192]; |
| 267 | 	uint8_t		V0[32]; |
| 268 | 	uint8_t		V1[32]; |
| 269 | 	uint8_t		V2[16]; |
| 270 | 	uint8_t		V3[16]; |
| 271 | 	uint8_t		Vendor_Scratch[32]; |
| 272 | 	uint32_t	Physical_Disk_Sequence[0]; |
| 273 | } __packed; |
| 274 | |
| 275 | struct ddf_vuc_record { |
| 276 | 	uint32_t	Signature; |
| 277 | #define	DDF_VUCR_SIGNATURE	0x88888888 |
| 278 | 	uint32_t	CRC; |
| 279 | 	uint8_t		VD_GUID[24]; |
| 280 | } __packed; |
| 281 | |
| 282 | struct ddf_sa_entry { |
| 283 | 	uint8_t		VD_GUID[24]; |
| 284 | 	uint16_t	Secondary_Element; |
| 285 | 	uint8_t		rsrvd2[6]; |
| 286 | } __packed; |
| 287 | |
| 288 | struct ddf_sa_record { |
| 289 | 	uint32_t	Signature; |
| 290 | #define	DDF_SA_SIGNATURE	0x55555555 |
| 291 | 	uint32_t	CRC; |
| 292 | 	uint32_t	Timestamp; |
| 293 | 	uint8_t		pad1[7]; |
| 294 | 	uint8_t		Spare_Type; |
| 295 | #define	DDF_SAR_TYPE_DEDICATED		(1 << 0) |
| 296 | #define	DDF_SAR_TYPE_REVERTIBLE		(1 << 1) |
| 297 | #define	DDF_SAR_TYPE_ACTIVE		(1 << 2) |
| 298 | #define	DDF_SAR_TYPE_ENCL_AFFINITY	(1 << 3) |
| 299 | 	uint16_t	Populated_SAEs; |
| 300 | 	uint16_t	MAX_SAE_Supported; |
| 301 | 	uint8_t		pad2[8]; |
| 302 | 	struct ddf_sa_entry	entry[0]; |
| 303 | } __packed; |
| 304 | |
| 305 | struct ddf_pdd_record { |
| 306 | 	uint32_t	Signature; |
| 307 | #define	DDF_PDD_SIGNATURE	0x33333333 |
| 308 | 	uint32_t	CRC; |
| 309 | 	uint8_t		PD_GUID[24]; |
| 310 | 	uint32_t	PD_Reference; |
| 311 | 	uint8_t		Forced_Ref_Flag; |
| 312 | #define	DDF_PDD_FORCED_REF	0x01 |
| 313 | 	uint8_t		Forced_PD_GUID_Flag; |
| 314 | #define	DDF_PDD_FORCED_GUID	0x01 |
| 315 | 	uint8_t		Vendor_Scratch[32]; |
| 316 | 	uint8_t		pad2[442]; |
| 317 | } __packed; |
| 318 | |
| 319 | struct ddf_bbm_entry { |
| 320 | 	uint64_t	Defective_Block_Start; |
| 321 | 	uint32_t	Spare_Block_Offset; |
| 322 | 	uint16_t	Remapped_Count; |
| 323 | 	uint8_t	pad[2]; |
| 324 | }; |
| 325 | |
| 326 | struct ddf_bbm_log { |
| 327 | 	uint32_t	Signature; |
| 328 | #define	DDF_BBML_SIGNATURE	0xabadb10c |
| 329 | 	uint32_t	CRC; |
| 330 | 	uint32_t	Entry_Count; |
| 331 | 	uint32_t	Spare_Block_Count; |
| 332 | 	uint8_t		pad1[8]; |
| 333 | 	uint64_t	First_Spare_LBA; |
| 334 | 	uint64_t	Mapped_Block_Entry[0]; |
| 335 | } __packed; |
| 336 | |
| 337 | struct ddf_vendor_log { |
| 338 | 	uint32_t	Signature; |
| 339 | #define	DDF_VENDOR_LOG_SIGNATURE	0x01dbeef0 |
| 340 | 	uint32_t	CRC; |
| 341 | 	uint64_t	Log_Owner; |
| 342 | 	uint8_t		pad1[16]; |
| 343 | } __packed; |
| 344 | |
| 345 | #endif |