chiark / gitweb /
vol_id: add --offset option
[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 it
7  *      under the terms of the GNU General Public License as published by the
8  *      Free Software Foundation version 2 of the License.
9  */
10
11 #ifndef _GNU_SOURCE
12 #define _GNU_SOURCE 1
13 #endif
14
15 #ifdef HAVE_CONFIG_H
16 #  include <config.h>
17 #endif
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <ctype.h>
25
26 #include "libvolume_id.h"
27 #include "util.h"
28
29 struct adaptec_meta {
30         uint32_t        b0idcode;
31         uint8_t         lunsave[8];
32         uint16_t        sdtype;
33         uint16_t        ssavecyl;
34         uint8_t         ssavehed;
35         uint8_t         ssavesec;
36         uint8_t         sb0flags;
37         uint8_t         jbodEnable;
38         uint8_t         lundsave;
39         uint8_t         svpdirty;
40         uint16_t        biosInfo;
41         uint16_t        svwbskip;
42         uint16_t        svwbcln;
43         uint16_t        svwbmax;
44         uint16_t        res3;
45         uint16_t        svwbmin;
46         uint16_t        res4;
47         uint16_t        svrcacth;
48         uint16_t        svwcacth;
49         uint16_t        svwbdly;
50         uint8_t         svsdtime;
51         uint8_t         res5;
52         uint16_t        firmval;
53         uint16_t        firmbln;
54         uint32_t        firmblk;
55         uint32_t        fstrsvrb;
56         uint16_t        svBlockStorageTid;
57         uint16_t        svtid;
58         uint8_t         svseccfl;
59         uint8_t         res6;
60         uint8_t         svhbanum;
61         uint8_t         resver;
62         uint32_t        drivemagic;
63         uint8_t         reserved[20];
64         uint8_t         testnum;
65         uint8_t         testflags;
66         uint16_t        maxErrorCount;
67         uint32_t        count;
68         uint32_t        startTime;
69         uint32_t        interval;
70         uint8_t         tstxt0;
71         uint8_t         tstxt1;
72         uint8_t         serNum[32];
73         uint8_t         res8[102];
74         uint32_t        fwTestMagic;
75         uint32_t        fwTestSeqNum;
76         uint8_t         fwTestRes[8];
77         uint8_t         smagic[4];
78         uint32_t        raidtbl;
79         uint16_t        raidline;
80         uint8_t         res9[0xF6];
81 } PACKED;
82
83 int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size)
84 {
85         const uint8_t *buf;
86         uint64_t meta_off;
87         struct adaptec_meta *ad;
88
89         info("probing at offset 0x%llx, size 0x%llx",
90             (unsigned long long) off, (unsigned long long) size);
91
92         if (size < 0x10000)
93                 return -1;
94
95         meta_off = ((size / 0x200)-1) * 0x200;
96         buf = volume_id_get_buffer(id, off + meta_off, 0x200);
97         if (buf == NULL)
98                 return -1;
99
100         ad = (struct adaptec_meta *) buf;
101         if (memcmp(ad->smagic, "DPTM", 4) != 0)
102                 return -1;
103
104         if (ad->b0idcode != be32_to_cpu(0x37FC4D1E))
105                 return -1;
106
107         volume_id_set_usage(id, VOLUME_ID_RAID);
108         snprintf(id->type_version, sizeof(id->type_version)-1, "%u", ad->resver);
109         id->type = "adaptec_raid_member";
110
111         return 0;
112 }