chiark / gitweb /
45a56dcfbdde9f7dbc657aa2df3ca735aca14d4c
[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 "libvolume_id-private.h"
28 #include "util.h"
29
30 struct adaptec_meta {
31         uint32_t        b0idcode;
32         uint8_t         lunsave[8];
33         uint16_t        sdtype;
34         uint16_t        ssavecyl;
35         uint8_t         ssavehed;
36         uint8_t         ssavesec;
37         uint8_t         sb0flags;
38         uint8_t         jbodEnable;
39         uint8_t         lundsave;
40         uint8_t         svpdirty;
41         uint16_t        biosInfo;
42         uint16_t        svwbskip;
43         uint16_t        svwbcln;
44         uint16_t        svwbmax;
45         uint16_t        res3;
46         uint16_t        svwbmin;
47         uint16_t        res4;
48         uint16_t        svrcacth;
49         uint16_t        svwcacth;
50         uint16_t        svwbdly;
51         uint8_t         svsdtime;
52         uint8_t         res5;
53         uint16_t        firmval;
54         uint16_t        firmbln;
55         uint32_t        firmblk;
56         uint32_t        fstrsvrb;
57         uint16_t        svBlockStorageTid;
58         uint16_t        svtid;
59         uint8_t         svseccfl;
60         uint8_t         res6;
61         uint8_t         svhbanum;
62         uint8_t         resver;
63         uint32_t        drivemagic;
64         uint8_t         reserved[20];
65         uint8_t         testnum;
66         uint8_t         testflags;
67         uint16_t        maxErrorCount;
68         uint32_t        count;
69         uint32_t        startTime;
70         uint32_t        interval;
71         uint8_t         tstxt0;
72         uint8_t         tstxt1;
73         uint8_t         serNum[32];
74         uint8_t         res8[102];
75         uint32_t        fwTestMagic;
76         uint32_t        fwTestSeqNum;
77         uint8_t         fwTestRes[8];
78         uint8_t         smagic[4];
79         uint32_t        raidtbl;
80         uint16_t        raidline;
81         uint8_t         res9[0xF6];
82 } PACKED;
83
84 int volume_id_probe_adaptec_raid(struct volume_id *id, uint64_t off, uint64_t size)
85 {
86         const uint8_t *buf;
87         uint64_t meta_off;
88         struct adaptec_meta *ad;
89
90         info("probing at offset 0x%llx, size 0x%llx\n",
91             (unsigned long long) off, (unsigned long long) size);
92
93         if (size < 0x10000)
94                 return -1;
95
96         meta_off = ((size / 0x200)-1) * 0x200;
97         buf = volume_id_get_buffer(id, off + meta_off, 0x200);
98         if (buf == NULL)
99                 return -1;
100
101         ad = (struct adaptec_meta *) buf;
102         if (memcmp(ad->smagic, "DPTM", 4) != 0)
103                 return -1;
104
105         if (ad->b0idcode != be32_to_cpu(0x37FC4D1E))
106                 return -1;
107
108         volume_id_set_usage(id, VOLUME_ID_RAID);
109         snprintf(id->type_version, sizeof(id->type_version)-1, "%u", ad->resver);
110         id->type = "adaptec_raid_member";
111
112         return 0;
113 }