/src/util-linux/libblkid/src/superblocks/silicon_raid.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2008 Karel Zak <kzak@redhat.com> |
3 | | * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> |
4 | | * |
5 | | * Inspired by libvolume_id by |
6 | | * Kay Sievers <kay.sievers@vrfy.org> |
7 | | * |
8 | | * This file may be redistributed under the terms of the |
9 | | * GNU Lesser General Public License. |
10 | | */ |
11 | | #include <stdio.h> |
12 | | #include <stdlib.h> |
13 | | #include <unistd.h> |
14 | | #include <string.h> |
15 | | #include <errno.h> |
16 | | #include <ctype.h> |
17 | | #include <stdint.h> |
18 | | #include <stddef.h> |
19 | | |
20 | | #include "superblocks.h" |
21 | | |
22 | | struct silicon_metadata { |
23 | | uint8_t unknown0[0x2E]; |
24 | | uint8_t ascii_version[0x36 - 0x2E]; |
25 | | int8_t diskname[0x56 - 0x36]; |
26 | | int8_t unknown1[0x60 - 0x56]; |
27 | | uint32_t magic; |
28 | | int8_t unknown1a[0x6C - 0x64]; |
29 | | uint32_t array_sectors_low; |
30 | | uint32_t array_sectors_high; |
31 | | int8_t unknown2[0x78 - 0x74]; |
32 | | uint32_t thisdisk_sectors; |
33 | | int8_t unknown3[0x100 - 0x7C]; |
34 | | int8_t unknown4[0x104 - 0x100]; |
35 | | uint16_t product_id; |
36 | | uint16_t vendor_id; |
37 | | uint16_t minor_ver; |
38 | | uint16_t major_ver; |
39 | | uint8_t seconds; |
40 | | uint8_t minutes; |
41 | | uint8_t hour; |
42 | | uint8_t day; |
43 | | uint8_t month; |
44 | | uint8_t year; |
45 | | uint16_t raid0_stride; |
46 | | int8_t unknown6[0x116 - 0x114]; |
47 | | uint8_t disk_number; |
48 | | uint8_t type; /* SILICON_TYPE_* */ |
49 | | int8_t drives_per_striped_set; |
50 | | int8_t striped_set_number; |
51 | | int8_t drives_per_mirrored_set; |
52 | | int8_t mirrored_set_number; |
53 | | uint32_t rebuild_ptr_low; |
54 | | uint32_t rebuild_ptr_high; |
55 | | uint32_t incarnation_no; |
56 | | uint8_t member_status; |
57 | | uint8_t mirrored_set_state; /* SILICON_MIRROR_* */ |
58 | | uint8_t reported_device_location; |
59 | | uint8_t idechannel; |
60 | | uint8_t auto_rebuild; |
61 | | uint8_t unknown8; |
62 | | uint8_t text_type[0x13E - 0x12E]; |
63 | | uint16_t checksum1; |
64 | | int8_t assumed_zeros[0x1FE - 0x140]; |
65 | | uint16_t checksum2; |
66 | | } __attribute__((packed)); |
67 | | |
68 | 3.99k | #define SILICON_MAGIC 0x2F000000 |
69 | | |
70 | | static uint16_t silraid_checksum(struct silicon_metadata *sil) |
71 | 0 | { |
72 | 0 | int sum = 0; |
73 | 0 | unsigned short count = offsetof(struct silicon_metadata, checksum1) / 2; |
74 | 0 | unsigned char *ptr = (unsigned char *) sil; |
75 | |
|
76 | 0 | while (count--) { |
77 | 0 | uint16_t val; |
78 | |
|
79 | 0 | memcpy(&val, ptr, sizeof(uint16_t)); |
80 | 0 | sum += le16_to_cpu(val); |
81 | |
|
82 | 0 | ptr += sizeof(uint16_t); |
83 | 0 | } |
84 | |
|
85 | 0 | return (-sum & 0xFFFF); |
86 | 0 | } |
87 | | |
88 | | static int probe_silraid(blkid_probe pr, |
89 | | const struct blkid_idmag *mag __attribute__((__unused__))) |
90 | 3.99k | { |
91 | 3.99k | uint64_t off; |
92 | 3.99k | struct silicon_metadata *sil; |
93 | | |
94 | 3.99k | if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) |
95 | 0 | return 1; |
96 | | |
97 | 3.99k | off = ((pr->size / 0x200) - 1) * 0x200; |
98 | | |
99 | 3.99k | sil = (struct silicon_metadata *) |
100 | 3.99k | blkid_probe_get_buffer(pr, off, |
101 | 3.99k | sizeof(struct silicon_metadata)); |
102 | 3.99k | if (!sil) |
103 | 0 | return errno ? -errno : 1; |
104 | | |
105 | 3.99k | if (le32_to_cpu(sil->magic) != SILICON_MAGIC) |
106 | 3.99k | return 1; |
107 | 0 | if (sil->disk_number >= 8) |
108 | 0 | return 1; |
109 | 0 | if (!blkid_probe_verify_csum(pr, silraid_checksum(sil), le16_to_cpu(sil->checksum1))) |
110 | 0 | return 1; |
111 | | |
112 | 0 | if (blkid_probe_sprintf_version(pr, "%u.%u", |
113 | 0 | le16_to_cpu(sil->major_ver), |
114 | 0 | le16_to_cpu(sil->minor_ver)) != 0) |
115 | 0 | return 1; |
116 | | |
117 | 0 | if (blkid_probe_set_magic(pr, |
118 | 0 | off + offsetof(struct silicon_metadata, magic), |
119 | 0 | sizeof(sil->magic), |
120 | 0 | (unsigned char *) &sil->magic)) |
121 | 0 | return 1; |
122 | 0 | return 0; |
123 | 0 | } |
124 | | |
125 | | const struct blkid_idinfo silraid_idinfo = { |
126 | | .name = "silicon_medley_raid_member", |
127 | | .usage = BLKID_USAGE_RAID, |
128 | | .minsz = 0x10000, |
129 | | .probefunc = probe_silraid, |
130 | | .magics = BLKID_NONE_MAGIC |
131 | | }; |
132 | | |
133 | | |