1 /*
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 <errno.h>
15 #include <ctype.h>
16 #include <stdint.h>
17
18 #include "superblocks.h"
19
20 struct promise_metadata {
21 uint8_t sig[24];
22 };
23
24 #define PDC_CONFIG_OFF 0x1200
25 #define PDC_SIGNATURE "Promise Technology, Inc."
26
27 static int probe_pdcraid(blkid_probe pr,
28 const struct blkid_idmag *mag __attribute__((__unused__)))
29 {
30 size_t i;
31 static unsigned int sectors[] = {
32 63, 255, 256, 16, 399, 591, 675, 735, 911, 974, 991, 951, 3087
33 };
34 uint64_t nsectors;
35
36 if (pr->size < 0x40000)
37 return 1;
38 if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr))
39 return 1;
40
41 nsectors = pr->size >> 9;
42
43 for (i = 0; i < ARRAY_SIZE(sectors); i++) {
44 uint64_t off;
45 struct promise_metadata *pdc;
46
47 if (nsectors < sectors[i])
48 return 1;
49
50 off = (nsectors - sectors[i]) << 9;
51 pdc = (struct promise_metadata *)
52 blkid_probe_get_buffer(pr,
53 off,
54 sizeof(struct promise_metadata));
55 if (!pdc)
56 return errno ? -errno : 1;
57
58 if (memcmp(pdc->sig, PDC_SIGNATURE,
59 sizeof(PDC_SIGNATURE) - 1) == 0) {
60
61 if (blkid_probe_set_magic(pr, off, sizeof(pdc->sig),
62 (unsigned char *) pdc->sig))
63 return 1;
64 return 0;
65 }
66 }
67 return 1;
68 }
69
70 const struct blkid_idinfo pdcraid_idinfo = {
71 .name = "promise_fasttrack_raid_member",
72 .usage = BLKID_USAGE_RAID,
73 .probefunc = probe_pdcraid,
74 .magics = BLKID_NONE_MAGIC
75 };
76
77