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