chiark / gitweb /
volume_id: support for GFS2 UUIDs
[elogind.git] / extras / volume_id / lib / adaptec_raid.c
1 /*
2  * volume_id - reads filesystem label and uuid
3  *
4  * Copyright (C) 2006 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE 1
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <ctype.h>
30
31 #include "libvolume_id.h"
32 #include "libvolume_id-private.h"
33
34 struct adaptec_meta {
35         uint32_t        b0idcode;
36         uint8_t         lunsave[8];
37         uint16_t        sdtype;
38         uint16_t        ssavecyl;
39         uint8_t         ssavehed;
40         uint8_t         ssavesec;
41         uint8_t         sb0flags;
42         uint8_t         jbodEnable;
43         uint8_t         lundsave;
44         uint8_t         svpdirty;
45         uint16_t        biosInfo;
46         uint16_t        svwbskip;
47         uint16_t        svwbcln;
48         uint16_t        svwbmax;
49         uint16_t        res3;
50         uint16_t        svwbmin;
51         uint16_t        res4;
52         uint16_t        svrcacth;
53         uint16_t        svwcacth;
54         uint16_t        svwbdly;
55         uint8_t         svsdtime;
56         uint8_t         res5;
57         uint16_t        firmval;
58         uint16_t        firmbln;
59         uint32_t        firmblk;
60         uint32_t        fstrsvrb;
61         uint16_t        svBlockStorageTid;
62         uint16_t        svtid;
63         uint8_t         svseccfl;
64         uint8_t         res6;
65         uint8_t         svhbanum;
66         uint8_t         resver;
67         uint32_t        drivemagic;
68         uint8_t         reserved[20];
69         uint8_t         testnum;
70         uint8_t         testflags;
71         uint16_t        maxErrorCount;
72         uint32_t        count;
73         uint32_t        startTime;
74         uint32_t        interval;
75         uint8_t         tstxt0;
76         uint8_t         tstxt1;
77         uint8_t         serNum[32];
78         uint8_t         res8[102];
79         uint32_t        fwTestMagic;
80         uint32_t        fwTestSeqNum;
81         uint8_t         fwTestRes[8];
82         uint8_t         smagic[4];
83         uint32_t        raidtbl;
84         uint16_t        raidline;
85         uint8_t         res9[0xF6];
86 } PACKED;
87
88 int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size)
89 {
90         const uint8_t *buf;
91         uint64_t meta_off;
92         struct adaptec_meta *ad;
93
94         info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size);
95
96         if (size < 0x10000)
97                 return -1;
98
99         meta_off = ((size / 0x200)-1) * 0x200;
100         buf = volume_id_get_buffer(id, off + meta_off, 0x200);
101         if (buf == NULL)
102                 return -1;
103
104         ad = (struct adaptec_meta *) buf;
105         if (memcmp(ad->smagic, "DPTM", 4) != 0)
106                 return -1;
107
108         if (ad->b0idcode != be32_to_cpu(0x37FC4D1E))
109                 return -1;
110
111         volume_id_set_usage(id, VOLUME_ID_RAID);
112         snprintf(id->type_version, sizeof(id->type_version)-1, "%u", ad->resver);
113         id->type = "adaptec_raid_member";
114
115         return 0;
116 }