diff options
Diffstat (limited to 'libblkid/src/superblocks/adaptec_raid.c')
-rw-r--r-- | libblkid/src/superblocks/adaptec_raid.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/libblkid/src/superblocks/adaptec_raid.c b/libblkid/src/superblocks/adaptec_raid.c new file mode 100644 index 000000000..65fd5b8b4 --- /dev/null +++ b/libblkid/src/superblocks/adaptec_raid.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2008 Karel Zak <kzak@redhat.com> + * + * Inspired by libvolume_id by + * Kay Sievers <kay.sievers@vrfy.org> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdint.h> + +#include "superblocks.h" + +struct adaptec_metadata { + + uint32_t b0idcode; + uint8_t lunsave[8]; + uint16_t sdtype; + uint16_t ssavecyl; + uint8_t ssavehed; + uint8_t ssavesec; + uint8_t sb0flags; + uint8_t jbodEnable; + uint8_t lundsave; + uint8_t svpdirty; + uint16_t biosInfo; + uint16_t svwbskip; + uint16_t svwbcln; + uint16_t svwbmax; + uint16_t res3; + uint16_t svwbmin; + uint16_t res4; + uint16_t svrcacth; + uint16_t svwcacth; + uint16_t svwbdly; + uint8_t svsdtime; + uint8_t res5; + uint16_t firmval; + uint16_t firmbln; + uint32_t firmblk; + uint32_t fstrsvrb; + uint16_t svBlockStorageTid; + uint16_t svtid; + uint8_t svseccfl; + uint8_t res6; + uint8_t svhbanum; + uint8_t resver; + uint32_t drivemagic; + uint8_t reserved[20]; + uint8_t testnum; + uint8_t testflags; + uint16_t maxErrorCount; + uint32_t count; + uint32_t startTime; + uint32_t interval; + uint8_t tstxt0; + uint8_t tstxt1; + uint8_t serNum[32]; + uint8_t res8[102]; + uint32_t fwTestMagic; + uint32_t fwTestSeqNum; + uint8_t fwTestRes[8]; + uint32_t smagic; + uint32_t raidtbl; + uint16_t raidline; + uint8_t res9[0xF6]; +} __attribute__((packed)); + +#define AD_SIGNATURE 0x4450544D /* "DPTM" */ +#define AD_MAGIC 0x37FC4D1E + +static int probe_adraid(blkid_probe pr, + const struct blkid_idmag *mag __attribute__((__unused__))) +{ + uint64_t off; + struct adaptec_metadata *ad; + + if (pr->size < 0x10000) + return BLKID_PROBE_NONE; + + if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) + return BLKID_PROBE_NONE; + + off = ((pr->size / 0x200)-1) * 0x200; + ad = (struct adaptec_metadata *) + blkid_probe_get_buffer(pr, + off, + sizeof(struct adaptec_metadata)); + if (!ad) + return errno ? -errno : BLKID_PROBE_NONE;; + + if (ad->smagic != be32_to_cpu(AD_SIGNATURE)) + return BLKID_PROBE_NONE; + if (ad->b0idcode != be32_to_cpu(AD_MAGIC)) + return BLKID_PROBE_NONE; + if (blkid_probe_sprintf_version(pr, "%u", ad->resver) != 0) + return BLKID_PROBE_NONE; + if (blkid_probe_set_magic(pr, off, sizeof(ad->b0idcode), + (unsigned char *) &ad->b0idcode)) + return BLKID_PROBE_NONE; + + return BLKID_PROBE_OK; +} + +const struct blkid_idinfo adraid_idinfo = { + .name = "adaptec_raid_member", + .usage = BLKID_USAGE_RAID, + .probefunc = probe_adraid, + .magics = BLKID_NONE_MAGIC +}; + + |