1234848Smav/*-
2234848Smav * Copyright (c) 2012 Alexander Motin <mav@FreeBSD.org>
3234848Smav * Copyright (c) 2008 Scott Long
4234848Smav * All rights reserved.
5234848Smav *
6234848Smav * Redistribution and use in source and binary forms, with or without
7234848Smav * modification, are permitted provided that the following conditions
8234848Smav * are met:
9234848Smav * 1. Redistributions of source code must retain the above copyright
10234848Smav *    notice, this list of conditions and the following disclaimer,
11234848Smav *    without modification, immediately at the beginning of the file.
12234848Smav * 2. Redistributions in binary form must reproduce the above copyright
13234848Smav *    notice, this list of conditions and the following disclaimer in the
14234848Smav *    documentation and/or other materials provided with the distribution.
15234848Smav *
16234848Smav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17234848Smav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18234848Smav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19234848Smav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20234848Smav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21234848Smav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22234848Smav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23234848Smav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24234848Smav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25234848Smav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26234848Smav *
27234848Smav * $FreeBSD$
28234848Smav */
29234848Smav
30234848Smav#ifndef MD_DDF_H
31234848Smav#define MD_DDF_H
32234848Smav
33234848Smav/* Definitions from the SNIA DDF spec, rev 1.2/2.0 */
34234848Smav
35234848Smav#define	DDF_HEADER_LENGTH		512
36234848Smavstruct ddf_header {
37234848Smav	uint32_t	Signature;
38234848Smav#define	DDF_HEADER_SIGNATURE	0xde11de11
39234848Smav	uint32_t	CRC;
40234848Smav	uint8_t		DDF_Header_GUID[24];
41234848Smav	uint8_t		DDF_rev[8];
42234848Smav	uint32_t	Sequence_Number;
43234848Smav	uint32_t	TimeStamp;
44234848Smav	uint8_t		Open_Flag;
45234848Smav#define	DDF_HEADER_CLOSED	0x00
46234848Smav#define	DDF_HEADER_OPENED_MASK	0x0f
47234848Smav#define	DDF_HEADER_OPEN_ANCHOR	0xff
48234848Smav	uint8_t		Foreign_Flag;
49234848Smav	uint8_t		Diskgrouping;
50234848Smav	uint8_t		pad1[13];
51234848Smav	uint8_t		Header_ext[32];
52234848Smav	uint64_t	Primary_Header_LBA;
53234848Smav	uint64_t	Secondary_Header_LBA;
54234848Smav	uint8_t		Header_Type;
55234848Smav#define	DDF_HEADER_ANCHOR	0x00
56234848Smav#define	DDF_HEADER_PRIMARY	0x01
57234848Smav#define	DDF_HEADER_SECONDARY	0x02
58234848Smav	uint8_t		pad2[3];
59234848Smav	uint32_t	WorkSpace_Length;
60234848Smav	uint64_t	WorkSpace_LBA;
61234848Smav	uint16_t	Max_PD_Entries;
62234848Smav	uint16_t	Max_VD_Entries;
63234848Smav	uint16_t	Max_Partitions;
64234848Smav	uint16_t	Configuration_Record_Length;
65234848Smav	uint16_t	Max_Primary_Element_Entries;
66234848Smav	uint32_t	Max_Mapped_Block_Entries; /* DDF 2.0 */
67234848Smav	uint8_t		pad3[50];
68234848Smav	uint32_t	cd_section;	/* Controller_Data_Section */
69234848Smav	uint32_t	cd_length;	/* Controller_Data_Section_Length */
70234848Smav	uint32_t	pdr_section;	/* Physical_Drive_Records_Section */
71234848Smav	uint32_t	pdr_length;	/* Physical_Drive_Records_Length */
72234848Smav	uint32_t	vdr_section;	/* Virtual_Drive_Records_Section */
73234848Smav	uint32_t	vdr_length;	/* Virtual_Drive_Records_Length */
74234848Smav	uint32_t	cr_section;	/* Configuration_Records_Section */
75234848Smav	uint32_t	cr_length;	/* Configuration_Records_Length */
76234848Smav	uint32_t	pdd_section;	/* Physical_Drive_Data_Section */
77234848Smav	uint32_t	pdd_length;	/* Physical_Drive_Data_Length */
78234848Smav	uint32_t	bbmlog_section;	/* BBM_Log_Section */
79234848Smav	uint32_t	bbmlog_length;	/* BBM_Log_Section_Length */
80234848Smav	uint32_t	Diagnostic_Space;
81234848Smav	uint32_t	Diagnostic_Space_Length;
82234848Smav	uint32_t	Vendor_Specific_Logs;
83234848Smav	uint32_t	Vendor_Specific_Logs_Length;
84234848Smav	uint8_t		pad4[256];
85234848Smav} __packed;
86234848Smav
87234848Smavstruct ddf_cd_record {
88234848Smav	uint32_t	Signature;
89234848Smav#define	DDF_CONTROLLER_DATA_SIGNATURE	0xad111111
90234848Smav	uint32_t	CRC;
91234848Smav	uint8_t		Controller_GUID[24];
92234848Smav	struct {
93234848Smav		uint16_t	Vendor_ID;
94234848Smav		uint16_t	Device_ID;
95234848Smav		uint16_t	SubVendor_ID;
96234848Smav		uint16_t	SubDevice_ID;
97234848Smav	} Controller_Type __packed;
98234848Smav	uint8_t		Product_ID[16];
99234848Smav	uint8_t		pad1[8];
100234848Smav	uint8_t		Controller_Data[448];
101234848Smav} __packed;
102234848Smav
103234848Smavstruct ddf_device_scsi {
104234848Smav	uint8_t		Lun;
105234848Smav	uint8_t		Id;
106234848Smav	uint8_t		Channel;
107234848Smav	uint8_t		Path_Flags;
108234848Smav#define DDF_DEVICE_SCSI_FLAG_BROKEN	(1 << 7)
109234848Smav} __packed;
110234848Smav
111234848Smavstruct ddf_device_sas {
112234848Smav	uint64_t	Initiator_Path;
113234848Smav} __packed;
114234848Smav
115234848Smavunion ddf_pathinfo {
116234848Smav	struct {
117234848Smav		struct ddf_device_scsi	Path0;
118234848Smav		struct ddf_device_scsi	Path1;
119234848Smav		uint8_t			pad[10];
120234848Smav	} __packed scsi;
121234848Smav	struct {
122234848Smav		struct ddf_device_sas	Path0;
123234848Smav		struct ddf_device_sas	Path1;
124234848Smav		uint8_t			Path0_Flags;
125234848Smav		uint8_t			Path1_Flags;
126234848Smav#define DDF_DEVICE_SAS_PHY_ID		0x7f
127234848Smav#define DDF_DEVICE_SAS_FLAG_BROKEN	(1 << 7)
128234848Smav	} __packed sas;
129234848Smav} __packed;
130234848Smav
131234848Smavstruct ddf_pd_entry {
132234848Smav	uint8_t			PD_GUID[24];
133234848Smav	uint32_t		PD_Reference;
134234848Smav	uint16_t		PD_Type;
135234848Smav#define	DDF_PDE_GUID_FORCE	(1 << 0)
136234848Smav#define	DDF_PDE_PARTICIPATING	(1 << 1)
137234848Smav#define	DDF_PDE_GLOBAL_SPARE	(1 << 2)
138234848Smav#define	DDF_PDE_CONFIG_SPARE	(1 << 3)
139234848Smav#define	DDF_PDE_FOREIGN		(1 << 4)
140234848Smav#define	DDF_PDE_LEGACY		(1 << 5)
141234848Smav#define DDF_PDE_TYPE_MASK	(0x0f << 12)
142234848Smav#define DDF_PDE_UNKNOWN		(0x00 << 12)
143234848Smav#define DDF_PDE_SCSI		(0x01 << 12)
144234848Smav#define DDF_PDE_SAS		(0x02 << 12)
145234848Smav#define DDF_PDE_SATA		(0x03 << 12)
146234848Smav#define DDF_PDE_FC		(0x04 << 12)
147234848Smav	uint16_t		PD_State;
148234848Smav#define	DDF_PDE_ONLINE		(1 << 0)
149234848Smav#define	DDF_PDE_FAILED		(1 << 1)
150234848Smav#define	DDF_PDE_REBUILD		(1 << 2)
151234848Smav#define	DDF_PDE_TRANSITION	(1 << 3)
152234848Smav#define	DDF_PDE_PFA		(1 << 4)
153234848Smav#define	DDF_PDE_UNRECOVERED	(1 << 5)
154234848Smav#define	DDF_PDE_MISSING		(1 << 6)
155234848Smav	uint64_t		Configured_Size;
156234848Smav	union ddf_pathinfo	Path_Information;
157234848Smav	uint16_t		Block_Size;	/* DDF 2.0 */
158234848Smav	uint8_t			pad1[4];
159234848Smav} __packed;
160234848Smav
161234848Smavstruct ddf_pd_record {
162234848Smav	uint32_t		Signature;
163234848Smav#define	DDF_PDR_SIGNATURE	0x22222222
164234848Smav	uint32_t		CRC;
165234848Smav	uint16_t		Populated_PDEs;
166234848Smav	uint16_t		Max_PDE_Supported;
167234848Smav	uint8_t			pad1[52];
168234848Smav	struct ddf_pd_entry	entry[0];
169234848Smav} __packed;
170234848Smav
171234848Smavstruct ddf_vd_entry {
172234848Smav	uint8_t			VD_GUID[24];
173234848Smav	uint16_t		VD_Number;
174234848Smav	uint8_t			pad1[2];
175234848Smav	uint16_t		VD_Type;
176234848Smav#define DDF_VDE_SHARED		(1 << 0)
177234848Smav#define	DDF_VDE_ENFORCE_GROUP	(1 << 1)
178234848Smav#define	DDF_VDE_UNICODE_NAME	(1 << 2)
179234848Smav#define	DDF_VDE_OWNER_ID_VALID	(1 << 3)
180234848Smav	uint16_t		Controller_GUID_CRC;
181234848Smav	uint8_t			VD_State;
182234848Smav#define	DDF_VDE_OPTIMAL		0x00
183234848Smav#define	DDF_VDE_DEGRADED	0x01
184234848Smav#define	DDF_VDE_DELETED		0x02
185234848Smav#define	DDF_VDE_MISSING		0x03
186234848Smav#define	DDF_VDE_FAILED		0x04
187234848Smav#define DDF_VDE_PARTIAL		0x05
188234848Smav#define DDF_VDE_OFFLINE		0x06
189234848Smav#define	DDF_VDE_STATE_MASK	0x07
190234848Smav#define	DDF_VDE_MORPH		(1 << 3)
191234848Smav#define	DDF_VDE_DIRTY		(1 << 4)
192234848Smav	uint8_t			Init_State;
193234848Smav#define	DDF_VDE_UNINTIALIZED	0x00
194234848Smav#define	DDF_VDE_INIT_QUICK	0x01
195234848Smav#define	DDF_VDE_INIT_FULL	0x02
196234848Smav#define	DDF_VDE_INIT_MASK	0x03
197234848Smav#define	DDF_VDE_UACCESS_RW	0x00
198234848Smav#define	DDF_VDE_UACCESS_RO	0x80
199234848Smav#define	DDF_VDE_UACCESS_BLOCKED	0xc0
200234848Smav#define	DDF_VDE_UACCESS_MASK	0xc0
201234848Smav	uint8_t			Drive_Failures_Remaining;	/* DDF 2.0 */
202234848Smav	uint8_t			pad2[13];
203234848Smav	uint8_t			VD_Name[16];
204234848Smav} __packed;
205234848Smav
206234848Smavstruct ddf_vd_record {
207234848Smav	uint32_t		Signature;
208234848Smav#define	DDF_VD_RECORD_SIGNATURE	0xdddddddd
209234848Smav	uint32_t		CRC;
210234848Smav	uint16_t		Populated_VDEs;
211234848Smav	uint16_t		Max_VDE_Supported;
212234848Smav	uint8_t			pad1[52];
213234848Smav	struct ddf_vd_entry	entry[0];
214234848Smav} __packed;
215234848Smav
216234848Smav#define DDF_CR_INVALID		0xffffffff
217234848Smav
218234848Smavstruct ddf_vdc_record {
219234848Smav	uint32_t	Signature;
220234848Smav#define	DDF_VDCR_SIGNATURE	0xeeeeeeee
221234848Smav	uint32_t	CRC;
222234848Smav	uint8_t		VD_GUID[24];
223234848Smav	uint32_t	Timestamp;
224234848Smav	uint32_t	Sequence_Number;
225234848Smav	uint8_t		pad1[24];
226234848Smav	uint16_t	Primary_Element_Count;
227234848Smav	uint8_t		Stripe_Size;
228234848Smav	uint8_t		Primary_RAID_Level;
229234848Smav#define DDF_VDCR_RAID0		0x00
230234848Smav#define DDF_VDCR_RAID1		0x01
231234848Smav#define DDF_VDCR_RAID3		0x03
232234848Smav#define DDF_VDCR_RAID4		0x04
233234848Smav#define DDF_VDCR_RAID5		0x05
234234848Smav#define DDF_VDCR_RAID6		0x06
235234848Smav#define DDF_VDCR_RAID1E		0x11
236234848Smav#define DDF_VDCR_SINGLE		0x0f
237234848Smav#define DDF_VDCR_CONCAT		0x1f
238234848Smav#define DDF_VDCR_RAID5E		0x15
239234848Smav#define DDF_VDCR_RAID5EE	0x25
240234848Smav	uint8_t		RLQ;
241234848Smav	uint8_t		Secondary_Element_Count;
242234848Smav	uint8_t		Secondary_Element_Seq;
243234848Smav	uint8_t		Secondary_RAID_Level;
244234848Smav	uint64_t	Block_Count;
245234848Smav	uint64_t	VD_Size;
246234848Smav	uint16_t	Block_Size;			/* DDF 2.0 */
247234848Smav	uint8_t		Rotate_Parity_count;		/* DDF 2.0 */
248234848Smav	uint8_t		pad2[5];
249234848Smav	uint32_t	Associated_Spares[8];
250234848Smav	uint64_t	Cache_Flags;
251234848Smav#define DDF_VDCR_CACHE_WB		(1 << 0)
252234848Smav#define	DDF_VDCR_CACHE_WB_ADAPTIVE	(1 << 1)
253234848Smav#define	DDF_VDCR_CACHE_RA		(1 << 2)
254234848Smav#define	DDF_VDCR_CACHE_RA_ADAPTIVE	(1 << 3)
255234848Smav#define	DDF_VDCR_CACHE_WCACHE_NOBATTERY	(1 << 4)
256234848Smav#define	DDF_VDCR_CACHE_WCACHE_ALLOW	(1 << 5)
257234848Smav#define	DDF_VDCR_CACHE_RCACHE_ALLOW	(1 << 6)
258234848Smav#define	DDF_VDCR_CACHE_VENDOR		(1 << 7)
259234848Smav	uint8_t		BG_Rate;
260234848Smav	uint8_t		pad3[3];
261234848Smav	uint8_t		MDF_Parity_Disks;		/* DDF 2.0 */
262234848Smav	uint16_t	MDF_Parity_Generator_Polynomial; /* DDF 2.0 */
263234848Smav	uint8_t		pad4;
264234848Smav	uint8_t		MDF_Constant_Generation_Method; /* DDF 2.0 */
265234848Smav	uint8_t		pad5[47];
266234848Smav	uint8_t		pad6[192];
267234848Smav	uint8_t		V0[32];
268234848Smav	uint8_t		V1[32];
269234848Smav	uint8_t		V2[16];
270234848Smav	uint8_t		V3[16];
271234848Smav	uint8_t		Vendor_Scratch[32];
272234848Smav	uint32_t	Physical_Disk_Sequence[0];
273234848Smav} __packed;
274234848Smav
275234848Smavstruct ddf_vuc_record {
276234848Smav	uint32_t	Signature;
277234848Smav#define	DDF_VUCR_SIGNATURE	0x88888888
278234848Smav	uint32_t	CRC;
279234848Smav	uint8_t		VD_GUID[24];
280234848Smav} __packed;
281234848Smav
282234848Smavstruct ddf_sa_entry {
283234848Smav	uint8_t		VD_GUID[24];
284234848Smav	uint16_t	Secondary_Element;
285234848Smav	uint8_t		rsrvd2[6];
286234848Smav} __packed;
287234848Smav
288234848Smavstruct ddf_sa_record {
289234848Smav	uint32_t	Signature;
290234848Smav#define	DDF_SA_SIGNATURE	0x55555555
291234848Smav	uint32_t	CRC;
292234848Smav	uint32_t	Timestamp;
293234848Smav	uint8_t		pad1[7];
294234848Smav	uint8_t		Spare_Type;
295234848Smav#define	DDF_SAR_TYPE_DEDICATED		(1 << 0)
296234848Smav#define	DDF_SAR_TYPE_REVERTIBLE		(1 << 1)
297234848Smav#define	DDF_SAR_TYPE_ACTIVE		(1 << 2)
298234848Smav#define	DDF_SAR_TYPE_ENCL_AFFINITY	(1 << 3)
299234848Smav	uint16_t	Populated_SAEs;
300234848Smav	uint16_t	MAX_SAE_Supported;
301234848Smav	uint8_t		pad2[8];
302234848Smav	struct ddf_sa_entry	entry[0];
303234848Smav} __packed;
304234848Smav
305234848Smavstruct ddf_pdd_record {
306234848Smav	uint32_t	Signature;
307234848Smav#define	DDF_PDD_SIGNATURE	0x33333333
308234848Smav	uint32_t	CRC;
309234848Smav	uint8_t		PD_GUID[24];
310234848Smav	uint32_t	PD_Reference;
311234848Smav	uint8_t		Forced_Ref_Flag;
312234848Smav#define	DDF_PDD_FORCED_REF	0x01
313234848Smav	uint8_t		Forced_PD_GUID_Flag;
314234848Smav#define	DDF_PDD_FORCED_GUID	0x01
315234848Smav	uint8_t		Vendor_Scratch[32];
316234848Smav	uint8_t		pad2[442];
317234848Smav} __packed;
318234848Smav
319234848Smavstruct ddf_bbm_entry {
320234848Smav	uint64_t	Defective_Block_Start;
321234848Smav	uint32_t	Spare_Block_Offset;
322234848Smav	uint16_t	Remapped_Count;
323234848Smav	uint8_t	pad[2];
324234848Smav};
325234848Smav
326234848Smavstruct ddf_bbm_log {
327234848Smav	uint32_t	Signature;
328234848Smav#define	DDF_BBML_SIGNATURE	0xabadb10c
329234848Smav	uint32_t	CRC;
330234848Smav	uint32_t	Entry_Count;
331234848Smav	uint32_t	Spare_Block_Count;
332234848Smav	uint8_t		pad1[8];
333234848Smav	uint64_t	First_Spare_LBA;
334234848Smav	uint64_t	Mapped_Block_Entry[0];
335234848Smav} __packed;
336234848Smav
337234848Smavstruct ddf_vendor_log {
338234848Smav	uint32_t	Signature;
339234848Smav#define	DDF_VENDOR_LOG_SIGNATURE	0x01dbeef0
340234848Smav	uint32_t	CRC;
341234848Smav	uint64_t	Log_Owner;
342234848Smav	uint8_t		pad1[16];
343234848Smav} __packed;
344234848Smav
345234848Smav#endif
346