1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
/*
pdc: Promise Fake Raid reader
Copyright (C) 2001
*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/hdreg.h>
#ifdef DIET
#include <sys/mount.h>
#else
#include <linux/fs.h>
#endif
#include <string.h>
#ifdef DIET
typedef char char16_t;
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef uint32_t u_int32_t;
#else
typedef unsigned int uint32_t;
#endif
#ifndef BLKSSZGET
#define BLKSSZGET _IO(0x12,104)/* get block device sector size */
#endif
struct promise_raid_conf {
char promise_id[24];
#define PR_MAGIC "Promise Technology, Inc."
int32_t dummy_0;
int32_t magic_0;
int32_t dummy_1;
int32_t magic_1;
int16_t dummy_2;
int8_t filler1[470];
struct {
int32_t flags; /* 0x200 */
#define PR_F_CONFED 0x00000080
int8_t dummy_0;
int8_t disk_number;
int8_t channel;
int8_t device;
int32_t magic_0;
int32_t dummy_1;
int32_t dummy_2; /* 0x210 */
int32_t disk_secs;
int32_t dummy_3;
int16_t dummy_4;
int8_t status;
#define PR_S_DEFINED 0x01
#define PR_S_ONLINE 0x02
#define PR_S_OFFLINE 0x10
int8_t type;
#define PR_T_STRIPE 0x00
#define PR_T_MIRROR 0x01
#define PR_T_STRIPE_MIRROR 0x04
#define PR_T_SPAN 0x08
u_int8_t total_disks; /* 0x220 */
u_int8_t raid0_shift;
u_int8_t raid0_disks;
u_int8_t array_number;
u_int32_t total_secs;
u_int16_t cylinders;
u_int8_t heads;
u_int8_t sectors;
int32_t magic_1;
int32_t dummy_5; /* 0x230 */
struct {
int16_t dummy_0;
int8_t channel;
int8_t device;
int32_t magic_0;
int32_t disk_number;
} disk[8];
} raid;
int32_t filler2[346];
uint32_t checksum;
};
static unsigned long calc_pdcblock_offset (int fd) {
unsigned long lba = 0;
struct hd_big_geometry g;
long sectors;
int sector_size = 1;
if (ioctl(fd, HDIO_GETGEO_BIG_RAW, &g))
return -1;
if (ioctl(fd, BLKGETSIZE, §ors))
return -1;
if (ioctl(fd, BLKSSZGET, §or_size))
return -1;
if (!sector_size || !sectors || !g.cylinders || !g.heads || !g.sectors)
return -1;
sector_size /= 512;
g.cylinders = (sectors / (g.heads * g.sectors)) / sector_size;
lba = g.cylinders * (g.heads*g.sectors);
lba = lba - g.sectors;
return lba;
}
static int read_disk_sb (int fd, unsigned char *buffer,int bufsize)
{
int ret = -1;
char bh[4096];
unsigned long long sb_offset;
/*
* Calculate the position of the superblock,
* it's at first sector of the last cylinder
*/
sb_offset = calc_pdcblock_offset(fd) * 512;
if (sb_offset == -1)
return -1;
lseek64(fd, sb_offset, SEEK_SET);
read (fd, buffer, bufsize);
ret = 0;
return ret;
}
static unsigned int calc_sb_csum (unsigned int* ptr)
{
unsigned int sum;
int count;
sum = 0;
for (count=0;count<511;count++)
sum += *ptr++;
return sum;
}
static int check_disk_sb (void)
{
return 0;
}
int pdc_dev_running_raid(int fd)
{
int i;
struct promise_raid_conf *prom;
unsigned char block[4096];
if (read_disk_sb(fd,(unsigned char*)&block,sizeof(block)))
return -1;
prom = (struct promise_raid_conf*)&block[0];
if (!strcmp(prom->promise_id, "Promise Technology, Inc.") &&
(prom->checksum == calc_sb_csum((unsigned int*)prom)))
return 1;
return 0;
}
|