This source file includes following definitions.
- print_minor_name
- add_partition
- extended_partition
- msdos_partition
- osf_partition
- check_partition
- resetup_one_dev
- setup_dev
- device_setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <linux/config.h>
21 #include <linux/fs.h>
22 #include <linux/genhd.h>
23 #include <linux/kernel.h>
24 #include <linux/major.h>
25 #include <linux/string.h>
26
27 struct gendisk *gendisk_head = NULL;
28
29 static int current_minor = 0;
30 extern int *blk_size[];
31 extern void rd_load(void);
32 extern int ramdisk_size;
33
34 static void print_minor_name (struct gendisk *hd, int minor)
35 {
36 unsigned int unit = minor >> hd->minor_shift;
37 unsigned int part = minor & ((1 << hd->minor_shift) - 1);
38
39 #ifdef CONFIG_BLK_DEV_IDE
40
41
42
43
44
45
46 if (!strcmp(hd->major_name,"ide")) {
47 char name[16];
48 strcpy(name, hd->real_devices);
49 name[strlen(name)-1] += unit;
50 printk(" %s", name);
51 } else
52 #endif
53 printk(" %s%c", hd->major_name, 'a' + unit);
54 if (part)
55 printk("%d", part);
56 else
57 printk(":");
58 }
59
60 static void add_partition (struct gendisk *hd, int minor, int start, int size)
61 {
62 hd->part[minor].start_sect = start;
63 hd->part[minor].nr_sects = size;
64 print_minor_name(hd, minor);
65 }
66
67 #ifdef CONFIG_MSDOS_PARTITION
68
69
70
71
72
73
74
75
76
77
78
79 static void extended_partition(struct gendisk *hd, int dev)
80 {
81 struct buffer_head *bh;
82 struct partition *p;
83 unsigned long first_sector, this_sector;
84 int mask = (1 << hd->minor_shift) - 1;
85
86 first_sector = hd->part[MINOR(dev)].start_sect;
87 this_sector = first_sector;
88
89 while (1) {
90 if ((current_minor & mask) >= (4 + hd->max_p))
91 return;
92 if (!(bh = bread(dev,0,1024)))
93 return;
94
95
96
97
98 bh->b_dirt = 0;
99 bh->b_uptodate = 0;
100 bh->b_req = 0;
101 if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
102 p = (struct partition *) (0x1BE + bh->b_data);
103
104
105
106
107 if (p->sys_ind == EXTENDED_PARTITION || !p->nr_sects)
108 goto done;
109 add_partition(hd, current_minor, this_sector+p->start_sect, p->nr_sects);
110 current_minor++;
111 p++;
112
113
114
115
116
117
118
119 if (p->sys_ind != EXTENDED_PARTITION ||
120 !(hd->part[current_minor].nr_sects = p->nr_sects))
121 goto done;
122 hd->part[current_minor].start_sect = first_sector + p->start_sect;
123 this_sector = first_sector + p->start_sect;
124 dev = ((hd->major) << 8) | current_minor;
125 brelse(bh);
126 } else
127 goto done;
128 }
129 done:
130 brelse(bh);
131 }
132
133 static int msdos_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
134 {
135 int i, minor = current_minor;
136 struct buffer_head *bh;
137 struct partition *p;
138 int mask = (1 << hd->minor_shift) - 1;
139 #ifdef CONFIG_BLK_DEV_IDE
140 int tested_for_dm6 = 0;
141
142 read_mbr:
143 #endif
144 if (!(bh = bread(dev,0,1024))) {
145 printk(" unable to read partition table\n");
146 return -1;
147 }
148 if (*(unsigned short *) (0x1fe + bh->b_data) != 0xAA55) {
149 brelse(bh);
150 return 0;
151 }
152 p = (struct partition *) (0x1be + bh->b_data);
153
154 #ifdef CONFIG_BLK_DEV_IDE
155
156
157
158 if (!tested_for_dm6++) {
159 extern int ide_xlate_1024(dev_t, int, const char *);
160
161 if (p->sys_ind == DM6_PARTITION || p->sys_ind == EZD_PARTITION) {
162 const char *label = (p->sys_ind == DM6_PARTITION)?" [DM6:DDO]":" [EZDRIVE]";
163
164
165
166
167
168
169
170
171
172
173
174 if (ide_xlate_1024(dev, 1, label)) {
175 bh->b_dirt = 0;
176 bh->b_uptodate = 0;
177 bh->b_req = 0;
178 brelse(bh);
179 goto read_mbr;
180 }
181 } else {
182
183 unsigned int sig = *(unsigned short *)(bh->b_data + 2);
184 if (sig <= 0x1ae
185 && *(unsigned short *)(bh->b_data + sig) == 0x55AA
186 && (1 & *(unsigned char *)(bh->b_data + sig + 2)) )
187 {
188 (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
189 } else {
190
191 if (p->sys_ind == DM6_AUX1PARTITION
192 || p->sys_ind == DM6_AUX3PARTITION)
193 {
194 (void)ide_xlate_1024(dev,0," [DM6:AUX]");
195 }
196 }
197 }
198 }
199 #endif
200
201 current_minor += 4;
202 for (i=1 ; i<=4 ; minor++,i++,p++) {
203 if (!p->nr_sects)
204 continue;
205 add_partition(hd, minor, first_sector+p->start_sect, p->nr_sects);
206 if ((current_minor & 0x3f) >= 60)
207 continue;
208 if (p->sys_ind == EXTENDED_PARTITION) {
209 printk(" <");
210 extended_partition(hd, (hd->major << 8) | minor);
211 printk(" >");
212 }
213 }
214
215
216
217 if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
218 p = (struct partition *) (0x1be + bh->b_data);
219 for (i = 4 ; i < 16 ; i++, current_minor++) {
220 p--;
221 if ((current_minor & mask) >= mask-2)
222 break;
223 if (!(p->start_sect && p->nr_sects))
224 continue;
225 add_partition(hd, current_minor, p->start_sect, p->nr_sects);
226 }
227 }
228 printk("\n");
229 brelse(bh);
230 return 1;
231 }
232
233 #endif
234
235 #ifdef CONFIG_OSF_PARTITION
236
237 static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
238 {
239 int i;
240 struct buffer_head *bh;
241 struct disklabel {
242 u32 d_magic;
243 u16 d_type,d_subtype;
244 u8 d_typename[16];
245 u8 d_packname[16];
246 u32 d_secsize;
247 u32 d_nsectors;
248 u32 d_ntracks;
249 u32 d_ncylinders;
250 u32 d_secpercyl;
251 u32 d_secprtunit;
252 u16 d_sparespertrack;
253 u16 d_sparespercyl;
254 u32 d_acylinders;
255 u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
256 u32 d_headswitch, d_trkseek, d_flags;
257 u32 d_drivedata[5];
258 u32 d_spare[5];
259 u32 d_magic2;
260 u16 d_checksum;
261 u16 d_npartitions;
262 u32 d_bbsize, d_sbsize;
263 struct d_partition {
264 u32 p_size;
265 u32 p_offset;
266 u32 p_fsize;
267 u8 p_fstype;
268 u8 p_frag;
269 u16 p_cpg;
270 } d_partitions[8];
271 } * label;
272 struct d_partition * partition;
273 #define DISKLABELMAGIC (0x82564557UL)
274
275 if (!(bh = bread(dev,0,1024))) {
276 printk("unable to read partition table\n");
277 return -1;
278 }
279 label = (struct disklabel *) (bh->b_data+64);
280 partition = label->d_partitions;
281 if (label->d_magic != DISKLABELMAGIC) {
282 printk("magic: %08x\n", label->d_magic);
283 brelse(bh);
284 return 0;
285 }
286 if (label->d_magic2 != DISKLABELMAGIC) {
287 printk("magic2: %08x\n", label->d_magic2);
288 brelse(bh);
289 return 0;
290 }
291 for (i = 0 ; i < label->d_npartitions; i++, partition++) {
292 if (partition->p_size)
293 add_partition(hd, current_minor,
294 first_sector+partition->p_offset,
295 partition->p_size);
296 current_minor++;
297 }
298 printk("\n");
299 brelse(bh);
300 return 1;
301 }
302
303 #endif
304
305 static void check_partition(struct gendisk *hd, unsigned int dev)
306 {
307 static int first_time = 1;
308 unsigned long first_sector;
309
310 if (first_time)
311 printk("Partition check:\n");
312 first_time = 0;
313 first_sector = hd->part[MINOR(dev)].start_sect;
314
315
316
317
318
319 if ((int)first_sector == -1) {
320 hd->part[MINOR(dev)].start_sect = 0;
321 return;
322 }
323
324 printk(" ");
325 print_minor_name(hd, MINOR(dev));
326 #ifdef CONFIG_MSDOS_PARTITION
327 if (msdos_partition(hd, dev, first_sector))
328 return;
329 #endif
330 #ifdef CONFIG_OSF_PARTITION
331 if (osf_partition(hd, dev, first_sector))
332 return;
333 #endif
334 printk(" unknown partition table\n");
335 }
336
337
338
339
340
341
342
343
344
345
346 void resetup_one_dev(struct gendisk *dev, int drive)
347 {
348 int i;
349 int major = dev->major << 8;
350 int first_minor = drive << dev->minor_shift;
351 int end_minor = first_minor + dev->max_p;
352
353 blk_size[dev->major] = NULL;
354 current_minor = 1 + first_minor;
355 check_partition(dev, major + first_minor);
356
357 if (dev->sizes != NULL) {
358 for (i = first_minor; i < end_minor; i++)
359 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
360 blk_size[dev->major] = dev->sizes;
361 }
362 }
363
364 static void setup_dev(struct gendisk *dev)
365 {
366 int i, drive;
367 int major = dev->major << 8;
368 int end_minor = dev->max_nr * dev->max_p;
369
370 blk_size[dev->major] = NULL;
371 for (i = 0 ; i < end_minor; i++) {
372 dev->part[i].start_sect = 0;
373 dev->part[i].nr_sects = 0;
374 }
375 dev->init(dev);
376 for (drive = 0 ; drive < dev->nr_real ; drive++) {
377 int first_minor = drive << dev->minor_shift;
378 current_minor = 1 + first_minor;
379 check_partition(dev, major + first_minor);
380 }
381 if (dev->sizes != NULL) {
382 for (i = 0; i < end_minor; i++)
383 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
384 blk_size[dev->major] = dev->sizes;
385 }
386 }
387
388 void device_setup(void)
389 {
390 struct gendisk *p;
391 int nr=0;
392
393 for (p = gendisk_head ; p ; p=p->next) {
394 setup_dev(p);
395 nr += p->nr_real;
396 }
397
398 if (ramdisk_size)
399 rd_load();
400 }