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