/* http://www.snia.org/standards/home */
#define DDF_GUID_LENGTH 24
#define DDF_REV_LENGTH 8
+#define DDF_MAGIC 0xDE11DE11
+
struct ddf_header {
- uint8_t signature[4];
+ uint32_t signature;
uint32_t crc;
uint8_t guid[DDF_GUID_LENGTH];
- uint8_t ddf_rev[DDF_REV_LENGTH];
+ char ddf_rev[8]; /* 01.02.00 */
+ uint32_t seq; /* starts at '1' */
+ uint32_t timestamp;
+ uint8_t openflag;
+ uint8_t foreignflag;
+ uint8_t enforcegroups;
+ uint8_t pad0; /* 0xff */
+ uint8_t pad1[12]; /* 12 * 0xff */
+ /* 64 bytes so far */
+ uint8_t header_ext[32]; /* reserved: fill with 0xff */
+ uint64_t primary_lba;
+ uint64_t secondary_lba;
+ uint8_t type;
+ uint8_t pad2[3]; /* 0xff */
+ uint32_t workspace_len; /* sectors for vendor space -
+ * at least 32768(sectors) */
+ uint64_t workspace_lba;
+ uint16_t max_pd_entries; /* one of 15, 63, 255, 1023, 4095 */
+ uint16_t max_vd_entries; /* 2^(4,6,8,10,12)-1 : i.e. as above */
+ uint16_t max_partitions; /* i.e. max num of configuration
+ record entries per disk */
+ uint16_t config_record_len; /* 1 +ROUNDUP(max_primary_element_entries
+ *12/512) */
+ uint16_t max_primary_element_entries; /* 16, 64, 256, 1024, or 4096 */
+ uint8_t pad3[54]; /* 0xff */
+ /* 192 bytes so far */
+ uint32_t controller_section_offset;
+ uint32_t controller_section_length;
+ uint32_t phys_section_offset;
+ uint32_t phys_section_length;
+ uint32_t virt_section_offset;
+ uint32_t virt_section_length;
+ uint32_t config_section_offset;
+ uint32_t config_section_length;
+ uint32_t data_section_offset;
+ uint32_t data_section_length;
+ uint32_t bbm_section_offset;
+ uint32_t bbm_section_length;
+ uint32_t diag_space_offset;
+ uint32_t diag_space_length;
+ uint32_t vendor_offset;
+ uint32_t vendor_length;
+ /* 256 bytes so far */
+ uint8_t pad4[256]; /* 0xff */
} __attribute__((packed));
static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
int i;
struct ddf_header *ddf = NULL;
char version[DDF_REV_LENGTH + 1];
- uint64_t off;
+ uint64_t off, lba;
if (pr->size < 0x30000)
return -1;
if (!ddf)
return -1;
- if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0 ||
- memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0)
+ if (ddf->signature == cpu_to_be32(DDF_MAGIC) ||
+ ddf->signature == cpu_to_le32(DDF_MAGIC))
break;
ddf = NULL;
}
if (!ddf)
return -1;
+ lba = ddf->signature == cpu_to_be32(DDF_MAGIC) ?
+ be64_to_cpu(ddf->primary_lba) :
+ le64_to_cpu(ddf->primary_lba);
+
+ if (lba > 0) {
+ /* check primary header */
+ unsigned char *buf;
+
+ buf = blkid_probe_get_buffer(pr,
+ lba << 9, sizeof(ddf->signature));
+ if (!buf || memcmp(buf, &ddf->signature, 4))
+ return -1;
+ }
+
blkid_probe_strncpy_uuid(pr, ddf->guid, sizeof(ddf->guid));
memcpy(version, ddf->ddf_rev, sizeof(ddf->ddf_rev));
return -1;
if (blkid_probe_set_magic(pr, off,
sizeof(ddf->signature),
- (unsigned char *) ddf->signature))
+ (unsigned char *) &ddf->signature))
return -1;
return 0;
}