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