blob: fc2c39d3e597f4302f22c968f274b4e4c4dec1ca [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
2 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
3 *
4 * Inspired by libvolume_id by
5 * Kay Sievers <kay.sievers@vrfy.org>
6 *
7 * This file may be redistributed under the terms of the
8 * GNU Lesser General Public License.
9 */
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <string.h>
14#include <stdint.h>
15
16#include "superblocks.h"
17
18/* http://www.snia.org/standards/home */
19#define DDF_GUID_LENGTH 24
20#define DDF_REV_LENGTH 8
21#define DDF_MAGIC 0xDE11DE11
22
23
24struct ddf_header {
25 uint32_t signature;
26 uint32_t crc;
27 uint8_t guid[DDF_GUID_LENGTH];
28 char ddf_rev[8]; /* 01.02.00 */
29 uint32_t seq; /* starts at '1' */
30 uint32_t timestamp;
31 uint8_t openflag;
32 uint8_t foreignflag;
33 uint8_t enforcegroups;
34 uint8_t pad0; /* 0xff */
35 uint8_t pad1[12]; /* 12 * 0xff */
36 /* 64 bytes so far */
37 uint8_t header_ext[32]; /* reserved: fill with 0xff */
38 uint64_t primary_lba;
39 uint64_t secondary_lba;
40 uint8_t type;
41 uint8_t pad2[3]; /* 0xff */
42 uint32_t workspace_len; /* sectors for vendor space -
43 * at least 32768(sectors) */
44 uint64_t workspace_lba;
45 uint16_t max_pd_entries; /* one of 15, 63, 255, 1023, 4095 */
46 uint16_t max_vd_entries; /* 2^(4,6,8,10,12)-1 : i.e. as above */
47 uint16_t max_partitions; /* i.e. max num of configuration
48 record entries per disk */
49 uint16_t config_record_len; /* 1 +ROUNDUP(max_primary_element_entries
50 *12/512) */
51 uint16_t max_primary_element_entries; /* 16, 64, 256, 1024, or 4096 */
52 uint8_t pad3[54]; /* 0xff */
53 /* 192 bytes so far */
54 uint32_t controller_section_offset;
55 uint32_t controller_section_length;
56 uint32_t phys_section_offset;
57 uint32_t phys_section_length;
58 uint32_t virt_section_offset;
59 uint32_t virt_section_length;
60 uint32_t config_section_offset;
61 uint32_t config_section_length;
62 uint32_t data_section_offset;
63 uint32_t data_section_length;
64 uint32_t bbm_section_offset;
65 uint32_t bbm_section_length;
66 uint32_t diag_space_offset;
67 uint32_t diag_space_length;
68 uint32_t vendor_offset;
69 uint32_t vendor_length;
70 /* 256 bytes so far */
71 uint8_t pad4[256]; /* 0xff */
72} __attribute__((packed));
73
74static int probe_ddf(blkid_probe pr,
75 const struct blkid_idmag *mag __attribute__((__unused__)))
76{
77 int hdrs[] = { 1, 257 };
78 size_t i;
79 struct ddf_header *ddf = NULL;
80 char version[DDF_REV_LENGTH + 1];
81 uint64_t off, lba;
82
83 if (pr->size < 0x30000)
bigbiff7b4c7a62015-01-01 19:44:14 -050084 return 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050085
86 for (i = 0; i < ARRAY_SIZE(hdrs); i++) {
87 off = ((pr->size / 0x200) - hdrs[i]) * 0x200;
88
89 ddf = (struct ddf_header *) blkid_probe_get_buffer(pr,
90 off,
91 sizeof(struct ddf_header));
92 if (!ddf)
bigbiff7b4c7a62015-01-01 19:44:14 -050093 return errno ? -errno : 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -050094 if (ddf->signature == cpu_to_be32(DDF_MAGIC) ||
95 ddf->signature == cpu_to_le32(DDF_MAGIC))
96 break;
97 ddf = NULL;
98 }
99
100 if (!ddf)
bigbiff7b4c7a62015-01-01 19:44:14 -0500101 return 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500102
103 lba = ddf->signature == cpu_to_be32(DDF_MAGIC) ?
104 be64_to_cpu(ddf->primary_lba) :
105 le64_to_cpu(ddf->primary_lba);
106
107 if (lba > 0) {
108 /* check primary header */
109 unsigned char *buf;
110
111 buf = blkid_probe_get_buffer(pr,
112 lba << 9, sizeof(ddf->signature));
bigbiff7b4c7a62015-01-01 19:44:14 -0500113 if (!buf)
114 return errno ? -errno : 1;
115
116 if (memcmp(buf, &ddf->signature, 4) != 0)
117 return 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500118 }
119
120 blkid_probe_strncpy_uuid(pr, ddf->guid, sizeof(ddf->guid));
121
122 memcpy(version, ddf->ddf_rev, sizeof(ddf->ddf_rev));
123 *(version + sizeof(ddf->ddf_rev)) = '\0';
124
125 if (blkid_probe_set_version(pr, version) != 0)
bigbiff7b4c7a62015-01-01 19:44:14 -0500126 return 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500127 if (blkid_probe_set_magic(pr, off,
128 sizeof(ddf->signature),
129 (unsigned char *) &ddf->signature))
bigbiff7b4c7a62015-01-01 19:44:14 -0500130 return 1;
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500131 return 0;
132}
133
134const struct blkid_idinfo ddfraid_idinfo = {
135 .name = "ddf_raid_member",
136 .usage = BLKID_USAGE_RAID,
137 .probefunc = probe_ddf,
138 .magics = BLKID_NONE_MAGIC
139};
140
141