Import 2.1.118
[davej-history.git] / drivers / block / genhd.c
blob0246d15bf9aa34d3d857b96477649289a092b84f
1 /*
2 * Code extracted from
3 * linux/kernel/hd.c
5 * Copyright (C) 1991-1998 Linus Torvalds
8 * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
9 * in the early extended-partition checks and added DM partitions
11 * Support for DiskManager v6.0x added by Mark Lord,
12 * with information provided by OnTrack. This now works for linux fdisk
13 * and LILO, as well as loadlin and bootln. Note that disks other than
14 * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
16 * More flexible handling of extended partitions - aeb, 950831
18 * Check partition table on IDE disks for common CHS translations
21 #include <linux/config.h>
22 #include <linux/fs.h>
23 #include <linux/genhd.h>
24 #include <linux/kernel.h>
25 #include <linux/major.h>
26 #include <linux/string.h>
27 #include <linux/blk.h>
28 #include <linux/init.h>
30 #include <asm/system.h>
33 * Many architectures don't like unaligned accesses, which is
34 * frequently the case with the nr_sects and start_sect partition
35 * table entries.
37 #include <asm/unaligned.h>
39 #define SYS_IND(p) (get_unaligned(&p->sys_ind))
40 #define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \
41 get_unaligned(&p->nr_sects); \
42 le32_to_cpu(__a); \
45 #define START_SECT(p) ({ __typeof__(p->start_sect) __a = \
46 get_unaligned(&p->start_sect); \
47 le32_to_cpu(__a); \
50 struct gendisk *gendisk_head = NULL;
52 static int current_minor = 0;
53 extern int *blk_size[];
54 extern void rd_load(void);
55 extern void initrd_load(void);
57 extern int chr_dev_init(void);
58 extern int blk_dev_init(void);
59 extern int scsi_dev_init(void);
60 extern int net_dev_init(void);
63 * disk_name() is used by genhd.c and md.c.
64 * It formats the devicename of the indicated disk
65 * into the supplied buffer, and returns a pointer
66 * to that same buffer (for convenience).
68 char *disk_name (struct gendisk *hd, int minor, char *buf)
70 unsigned int part;
71 const char *maj = hd->major_name;
72 char unit = (minor >> hd->minor_shift) + 'a';
75 * IDE devices use multiple major numbers, but the drives
76 * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
77 * This requires special handling here.
79 switch (hd->major) {
80 case IDE3_MAJOR:
81 unit += 2;
82 case IDE2_MAJOR:
83 unit += 2;
84 case IDE1_MAJOR:
85 unit += 2;
86 case IDE0_MAJOR:
87 maj = "hd";
89 part = minor & ((1 << hd->minor_shift) - 1);
90 if (part)
91 sprintf(buf, "%s%c%d", maj, unit, part);
92 else
93 sprintf(buf, "%s%c", maj, unit);
94 return buf;
97 static void add_partition (struct gendisk *hd, int minor, int start, int size)
99 char buf[8];
100 hd->part[minor].start_sect = start;
101 hd->part[minor].nr_sects = size;
102 printk(" %s", disk_name(hd, minor, buf));
105 static inline int is_extended_partition(struct partition *p)
107 return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
108 SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
109 SYS_IND(p) == LINUX_EXTENDED_PARTITION);
112 static unsigned int get_ptable_blocksize(kdev_t dev)
114 int ret = 1024;
117 * See whether the low-level driver has given us a minumum blocksize.
118 * If so, check to see whether it is larger than the default of 1024.
120 if (!blksize_size[MAJOR(dev)])
122 return ret;
126 * Check for certain special power of two sizes that we allow.
127 * With anything larger than 1024, we must force the blocksize up to
128 * the natural blocksize for the device so that we don't have to try
129 * and read partial sectors. Anything smaller should be just fine.
131 switch( blksize_size[MAJOR(dev)][MINOR(dev)] )
133 case 2048:
134 ret = 2048;
135 break;
136 case 4096:
137 ret = 4096;
138 break;
139 case 8192:
140 ret = 8192;
141 break;
142 case 1024:
143 case 512:
144 case 256:
145 case 0:
147 * These are all OK.
149 break;
150 default:
151 panic("Strange blocksize for partition table\n");
154 return ret;
158 #ifdef CONFIG_MSDOS_PARTITION
160 * Create devices for each logical partition in an extended partition.
161 * The logical partitions form a linked list, with each entry being
162 * a partition table with two entries. The first entry
163 * is the real data partition (with a start relative to the partition
164 * table start). The second is a pointer to the next logical partition
165 * (with a start relative to the entire extended partition).
166 * We do not create a Linux partition for the partition tables, but
167 * only for the actual data partitions.
170 #define MSDOS_LABEL_MAGIC 0xAA55
172 static void extended_partition(struct gendisk *hd, kdev_t dev)
174 struct buffer_head *bh;
175 struct partition *p;
176 unsigned long first_sector, first_size, this_sector, this_size;
177 int mask = (1 << hd->minor_shift) - 1;
178 int i;
180 first_sector = hd->part[MINOR(dev)].start_sect;
181 first_size = hd->part[MINOR(dev)].nr_sects;
182 this_sector = first_sector;
184 while (1) {
185 if ((current_minor & mask) == 0)
186 return;
187 if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
188 return;
190 * This block is from a device that we're about to stomp on.
191 * So make sure nobody thinks this block is usable.
193 bh->b_state = 0;
195 if ((*(unsigned short *) (bh->b_data+510)) != cpu_to_le16(MSDOS_LABEL_MAGIC))
196 goto done;
198 p = (struct partition *) (0x1BE + bh->b_data);
200 this_size = hd->part[MINOR(dev)].nr_sects;
203 * Usually, the first entry is the real data partition,
204 * the 2nd entry is the next extended partition, or empty,
205 * and the 3rd and 4th entries are unused.
206 * However, DRDOS sometimes has the extended partition as
207 * the first entry (when the data partition is empty),
208 * and OS/2 seems to use all four entries.
212 * First process the data partition(s)
214 for (i=0; i<4; i++, p++) {
215 if (!NR_SECTS(p) || is_extended_partition(p))
216 continue;
218 /* Check the 3rd and 4th entries -
219 these sometimes contain random garbage */
220 if (i >= 2
221 && START_SECT(p) + NR_SECTS(p) > this_size
222 && (this_sector + START_SECT(p) < first_sector ||
223 this_sector + START_SECT(p) + NR_SECTS(p) >
224 first_sector + first_size))
225 continue;
227 add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
228 current_minor++;
229 if ((current_minor & mask) == 0)
230 goto done;
233 * Next, process the (first) extended partition, if present.
234 * (So far, there seems to be no reason to make
235 * extended_partition() recursive and allow a tree
236 * of extended partitions.)
237 * It should be a link to the next logical partition.
238 * Create a minor for this just long enough to get the next
239 * partition table. The minor will be reused for the next
240 * data partition.
242 p -= 4;
243 for (i=0; i<4; i++, p++)
244 if(NR_SECTS(p) && is_extended_partition(p))
245 break;
246 if (i == 4)
247 goto done; /* nothing left to do */
249 hd->part[current_minor].nr_sects = NR_SECTS(p);
250 hd->part[current_minor].start_sect = first_sector + START_SECT(p);
251 this_sector = first_sector + START_SECT(p);
252 dev = MKDEV(hd->major, current_minor);
253 brelse(bh);
255 done:
256 brelse(bh);
258 #ifdef CONFIG_SOLARIS_X86_PARTITION
259 static void
260 solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) {
262 struct buffer_head *bh;
263 struct solaris_x86_vtoc *v;
264 struct solaris_x86_slice *s;
265 int i;
267 if(!(bh = bread(dev, 0, get_ptable_blocksize(dev))))
268 return;
269 v = (struct solaris_x86_vtoc *)(bh->b_data + 512);
270 if(v->v_sanity != SOLARIS_X86_VTOC_SANE) {
271 brelse(bh);
272 return;
274 printk(" <solaris:");
275 if(v->v_version != 1) {
276 printk(" cannot handle version %ld vtoc>", v->v_version);
277 brelse(bh);
278 return;
280 for(i=0; i<SOLARIS_X86_NUMSLICE; i++) {
281 s = &v->v_slice[i];
283 if (s->s_size == 0)
284 continue;
285 printk(" [s%d]", i);
286 /* solaris partitions are relative to current MS-DOS
287 * one but add_partition starts relative to sector
288 * zero of the disk. Therefore, must add the offset
289 * of the current partition */
290 add_partition(hd, current_minor, s->s_start+offset, s->s_size);
291 current_minor++;
293 brelse(bh);
294 printk(" >");
296 #endif
298 #ifdef CONFIG_BSD_DISKLABEL
300 * Create devices for BSD partitions listed in a disklabel, under a
301 * dos-like partition. See extended_partition() for more information.
303 static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
305 struct buffer_head *bh;
306 struct bsd_disklabel *l;
307 struct bsd_partition *p;
308 int mask = (1 << hd->minor_shift) - 1;
310 if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
311 return;
312 bh->b_state = 0;
313 l = (struct bsd_disklabel *) (bh->b_data+512);
314 if (l->d_magic != BSD_DISKMAGIC) {
315 brelse(bh);
316 return;
319 p = &l->d_partitions[0];
320 while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
321 if ((current_minor & mask) >= (4 + hd->max_p))
322 break;
324 if (p->p_fstype != BSD_FS_UNUSED) {
325 add_partition(hd, current_minor, p->p_offset, p->p_size);
326 current_minor++;
328 p++;
330 brelse(bh);
333 #endif
335 static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
337 int i, minor = current_minor;
338 struct buffer_head *bh;
339 struct partition *p;
340 unsigned char *data;
341 int mask = (1 << hd->minor_shift) - 1;
342 #ifdef CONFIG_BLK_DEV_IDE
343 int tested_for_xlate = 0;
345 read_mbr:
346 #endif
347 if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
348 printk(" unable to read partition table\n");
349 return -1;
351 data = bh->b_data;
352 /* In some cases we modify the geometry */
353 /* of the drive (below), so ensure that */
354 /* nobody else tries to re-use this data. */
355 bh->b_state = 0;
356 #ifdef CONFIG_BLK_DEV_IDE
357 check_table:
358 #endif
359 if (*(unsigned short *) (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
360 brelse(bh);
361 return 0;
363 p = (struct partition *) (0x1be + data);
365 #ifdef CONFIG_BLK_DEV_IDE
366 if (!tested_for_xlate++) { /* Do this only once per disk */
368 * Look for various forms of IDE disk geometry translation
370 extern int ide_xlate_1024(kdev_t, int, const char *);
371 unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
372 if (SYS_IND(p) == EZD_PARTITION) {
374 * The remainder of the disk must be accessed using
375 * a translated geometry that reduces the number of
376 * apparent cylinders to less than 1024 if possible.
378 * ide_xlate_1024() will take care of the necessary
379 * adjustments to fool fdisk/LILO and partition check.
381 if (ide_xlate_1024(dev, -1, " [EZD]")) {
382 data += 512;
383 goto check_table;
385 } else if (SYS_IND(p) == DM6_PARTITION) {
388 * Everything on the disk is offset by 63 sectors,
389 * including a "new" MBR with its own partition table,
390 * and the remainder of the disk must be accessed using
391 * a translated geometry that reduces the number of
392 * apparent cylinders to less than 1024 if possible.
394 * ide_xlate_1024() will take care of the necessary
395 * adjustments to fool fdisk/LILO and partition check.
397 if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
398 brelse(bh);
399 goto read_mbr; /* start over with new MBR */
401 } else if (sig <= 0x1ae &&
402 *(unsigned short *)(data + sig) == cpu_to_le16(0x55AA) &&
403 (1 & *(unsigned char *)(data + sig + 2))) {
404 /* DM6 signature in MBR, courtesy of OnTrack */
405 (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
406 } else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
408 * DM6 on other than the first (boot) drive
410 (void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
411 } else {
413 * Examine the partition table for common translations.
414 * This is useful for drives in situations where the
415 * translated geometry is unavailable from the BIOS.
417 for (i = 0; i < 4; i++) {
418 struct partition *q = &p[i];
419 if (NR_SECTS(q)
420 && (q->sector & 63) == 1
421 && (q->end_sector & 63) == 63) {
422 unsigned int heads = q->end_head + 1;
423 if (heads == 32 || heads == 64 ||
424 heads == 128 || heads == 255 ||
425 heads == 240) {
426 (void) ide_xlate_1024(dev, heads, " [PTBL]");
427 break;
433 #endif /* CONFIG_BLK_DEV_IDE */
435 current_minor += 4; /* first "extra" minor (for extended partitions) */
436 for (i=1 ; i<=4 ; minor++,i++,p++) {
437 if (!NR_SECTS(p))
438 continue;
439 add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
440 if (is_extended_partition(p)) {
441 printk(" <");
443 * If we are rereading the partition table, we need
444 * to set the size of the partition so that we will
445 * be able to bread the block containing the extended
446 * partition info.
448 hd->sizes[minor] = hd->part[minor].nr_sects
449 >> (BLOCK_SIZE_BITS - 9);
450 extended_partition(hd, MKDEV(hd->major, minor));
451 printk(" >");
452 /* prevent someone doing mkfs or mkswap on an
453 extended partition, but leave room for LILO */
454 if (hd->part[minor].nr_sects > 2)
455 hd->part[minor].nr_sects = 2;
457 #ifdef CONFIG_BSD_DISKLABEL
458 if (SYS_IND(p) == BSD_PARTITION) {
459 printk(" <");
460 bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
461 printk(" >");
463 #endif
464 #ifdef CONFIG_SOLARIS_X86_PARTITION
466 /* james@bpgc.com: Solaris has a nasty indicator: 0x82
467 * which also means linux swap. For that reason, all
468 * of the prints are done inside the
469 * solaris_x86_partition routine */
471 if(SYS_IND(p) == SOLARIS_X86_PARTITION) {
472 solaris_x86_partition(hd, MKDEV(hd->major, minor),
473 first_sector+START_SECT(p));
475 #endif
478 * Check for old-style Disk Manager partition table
480 if (*(unsigned short *) (data+0xfc) == cpu_to_le16(MSDOS_LABEL_MAGIC)) {
481 p = (struct partition *) (0x1be + data);
482 for (i = 4 ; i < 16 ; i++, current_minor++) {
483 p--;
484 if ((current_minor & mask) == 0)
485 break;
486 if (!(START_SECT(p) && NR_SECTS(p)))
487 continue;
488 add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
491 printk("\n");
492 brelse(bh);
493 return 1;
496 #endif /* CONFIG_MSDOS_PARTITION */
498 #ifdef CONFIG_OSF_PARTITION
500 static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
502 int i;
503 int mask = (1 << hd->minor_shift) - 1;
504 struct buffer_head *bh;
505 struct disklabel {
506 u32 d_magic;
507 u16 d_type,d_subtype;
508 u8 d_typename[16];
509 u8 d_packname[16];
510 u32 d_secsize;
511 u32 d_nsectors;
512 u32 d_ntracks;
513 u32 d_ncylinders;
514 u32 d_secpercyl;
515 u32 d_secprtunit;
516 u16 d_sparespertrack;
517 u16 d_sparespercyl;
518 u32 d_acylinders;
519 u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
520 u32 d_headswitch, d_trkseek, d_flags;
521 u32 d_drivedata[5];
522 u32 d_spare[5];
523 u32 d_magic2;
524 u16 d_checksum;
525 u16 d_npartitions;
526 u32 d_bbsize, d_sbsize;
527 struct d_partition {
528 u32 p_size;
529 u32 p_offset;
530 u32 p_fsize;
531 u8 p_fstype;
532 u8 p_frag;
533 u16 p_cpg;
534 } d_partitions[8];
535 } * label;
536 struct d_partition * partition;
537 #define DISKLABELMAGIC (0x82564557UL)
539 if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
540 printk("unable to read partition table\n");
541 return -1;
543 label = (struct disklabel *) (bh->b_data+64);
544 partition = label->d_partitions;
545 if (label->d_magic != DISKLABELMAGIC) {
546 printk("magic: %08x\n", label->d_magic);
547 brelse(bh);
548 return 0;
550 if (label->d_magic2 != DISKLABELMAGIC) {
551 printk("magic2: %08x\n", label->d_magic2);
552 brelse(bh);
553 return 0;
555 for (i = 0 ; i < label->d_npartitions; i++, partition++) {
556 if ((current_minor & mask) == 0)
557 break;
558 if (partition->p_size)
559 add_partition(hd, current_minor,
560 first_sector+partition->p_offset,
561 partition->p_size);
562 current_minor++;
564 printk("\n");
565 brelse(bh);
566 return 1;
569 #endif /* CONFIG_OSF_PARTITION */
571 #ifdef CONFIG_SUN_PARTITION
573 static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
575 int i, csum;
576 unsigned short *ush;
577 struct buffer_head *bh;
578 struct sun_disklabel {
579 unsigned char info[128]; /* Informative text string */
580 unsigned char spare[292]; /* Boot information etc. */
581 unsigned short rspeed; /* Disk rotational speed */
582 unsigned short pcylcount; /* Physical cylinder count */
583 unsigned short sparecyl; /* extra sects per cylinder */
584 unsigned char spare2[4]; /* More magic... */
585 unsigned short ilfact; /* Interleave factor */
586 unsigned short ncyl; /* Data cylinder count */
587 unsigned short nacyl; /* Alt. cylinder count */
588 unsigned short ntrks; /* Tracks per cylinder */
589 unsigned short nsect; /* Sectors per track */
590 unsigned char spare3[4]; /* Even more magic... */
591 struct sun_partition {
592 __u32 start_cylinder;
593 __u32 num_sectors;
594 } partitions[8];
595 unsigned short magic; /* Magic number */
596 unsigned short csum; /* Label xor'd checksum */
597 } * label;
598 struct sun_partition *p;
599 unsigned long spc;
600 #define SUN_LABEL_MAGIC 0xDABE
602 if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
603 printk("Dev %s: unable to read partition table\n",
604 kdevname(dev));
605 return -1;
607 label = (struct sun_disklabel *) bh->b_data;
608 p = label->partitions;
609 if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
610 printk("Dev %s Sun disklabel: bad magic %04x\n",
611 kdevname(dev), be16_to_cpu(label->magic));
612 brelse(bh);
613 return 0;
615 /* Look at the checksum */
616 ush = ((unsigned short *) (label+1)) - 1;
617 for(csum = 0; ush >= ((unsigned short *) label);)
618 csum ^= *ush--;
619 if(csum) {
620 printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
621 kdevname(dev));
622 brelse(bh);
623 return 0;
625 /* All Sun disks have 8 partition entries */
626 spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
627 for(i=0; i < 8; i++, p++) {
628 unsigned long st_sector;
629 int num_sectors;
631 st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
632 num_sectors = be32_to_cpu(p->num_sectors);
633 if (num_sectors)
634 add_partition(hd, current_minor, st_sector, num_sectors);
635 current_minor++;
637 printk("\n");
638 brelse(bh);
639 return 1;
642 #endif /* CONFIG_SUN_PARTITION */
644 #ifdef CONFIG_AMIGA_PARTITION
645 #include <asm/byteorder.h>
646 #include <linux/affs_hardblocks.h>
648 static __inline__ u32
649 checksum_block(u32 *m, int size)
651 u32 sum = 0;
653 while (size--)
654 sum += htonl(*m++);
655 return sum;
658 static int
659 amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
661 struct buffer_head *bh;
662 struct RigidDiskBlock *rdb;
663 struct PartitionBlock *pb;
664 int start_sect;
665 int nr_sects;
666 int blk;
667 int part, res;
669 set_blocksize(dev,512);
670 res = 0;
672 for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
673 if(!(bh = bread(dev,blk,512))) {
674 printk("Dev %s: unable to read RDB block %d\n",
675 kdevname(dev),blk);
676 goto rdb_done;
678 if (*(u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) {
679 rdb = (struct RigidDiskBlock *)bh->b_data;
680 if (checksum_block((u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) {
681 printk("Dev %s: RDB in block %d has bad checksum\n",
682 kdevname(dev),blk);
683 brelse(bh);
684 continue;
686 printk(" RDSK");
687 blk = htonl(rdb->rdb_PartitionList);
688 brelse(bh);
689 for (part = 1; blk > 0 && part <= 16; part++) {
690 if (!(bh = bread(dev,blk,512))) {
691 printk("Dev %s: unable to read partition block %d\n",
692 kdevname(dev),blk);
693 goto rdb_done;
695 pb = (struct PartitionBlock *)bh->b_data;
696 blk = htonl(pb->pb_Next);
697 if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block(
698 (u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) {
700 /* Tell Kernel about it */
702 if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 -
703 htonl(pb->pb_Environment[9])) *
704 htonl(pb->pb_Environment[3]) *
705 htonl(pb->pb_Environment[5]))) {
706 continue;
708 start_sect = htonl(pb->pb_Environment[9]) *
709 htonl(pb->pb_Environment[3]) *
710 htonl(pb->pb_Environment[5]);
711 add_partition(hd,current_minor,start_sect,nr_sects);
712 current_minor++;
713 res = 1;
715 brelse(bh);
717 printk("\n");
718 break;
722 rdb_done:
723 set_blocksize(dev,BLOCK_SIZE);
724 return res;
726 #endif /* CONFIG_AMIGA_PARTITION */
728 #ifdef CONFIG_MAC_PARTITION
729 #include <linux/ctype.h>
732 * Code to understand MacOS partition tables.
735 #define MAC_PARTITION_MAGIC 0x504d
737 /* type field value for A/UX or other Unix partitions */
738 #define APPLE_AUX_TYPE "Apple_UNIX_SVR2"
740 struct mac_partition {
741 __u16 signature; /* expected to be MAC_PARTITION_MAGIC */
742 __u16 res1;
743 __u32 map_count; /* # blocks in partition map */
744 __u32 start_block; /* absolute starting block # of partition */
745 __u32 block_count; /* number of blocks in partition */
746 char name[32]; /* partition name */
747 char type[32]; /* string type description */
748 __u32 data_start; /* rel block # of first data block */
749 __u32 data_count; /* number of data blocks */
750 __u32 status; /* partition status bits */
751 __u32 boot_start;
752 __u32 boot_size;
753 __u32 boot_load;
754 __u32 boot_load2;
755 __u32 boot_entry;
756 __u32 boot_entry2;
757 __u32 boot_cksum;
758 char processor[16]; /* identifies ISA of boot */
759 /* there is more stuff after this that we don't need */
762 #define MAC_STATUS_BOOTABLE 8 /* partition is bootable */
764 #define MAC_DRIVER_MAGIC 0x4552
766 /* Driver descriptor structure, in block 0 */
767 struct mac_driver_desc {
768 __u16 signature; /* expected to be MAC_DRIVER_MAGIC */
769 __u16 block_size;
770 __u32 block_count;
771 /* ... more stuff */
774 static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec)
776 struct buffer_head *bh;
777 int blk, blocks_in_map;
778 int dev_bsize, dev_pos, pos;
779 unsigned secsize;
780 #ifdef CONFIG_PMAC
781 int first_bootable = 1;
782 #endif
783 struct mac_partition *part;
784 struct mac_driver_desc *md;
786 dev_bsize = get_ptable_blocksize(dev);
787 dev_pos = 0;
788 /* Get 0th block and look at the first partition map entry. */
789 if ((bh = bread(dev, 0, dev_bsize)) == 0) {
790 printk("%s: error reading partition table\n",
791 kdevname(dev));
792 return -1;
794 md = (struct mac_driver_desc *) bh->b_data;
795 if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
796 brelse(bh);
797 return 0;
799 secsize = be16_to_cpu(md->block_size);
800 if (secsize >= dev_bsize) {
801 brelse(bh);
802 dev_pos = secsize;
803 if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
804 printk("%s: error reading partition table\n",
805 kdevname(dev));
806 return -1;
809 part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);
810 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
811 brelse(bh);
812 return 0; /* not a MacOS disk */
814 blocks_in_map = be32_to_cpu(part->map_count);
815 for (blk = 1; blk <= blocks_in_map; ++blk) {
816 pos = blk * secsize;
817 if (pos >= dev_pos + dev_bsize) {
818 brelse(bh);
819 dev_pos = pos;
820 if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {
821 printk("%s: error reading partition table\n",
822 kdevname(dev));
823 return -1;
826 part = (struct mac_partition *) (bh->b_data + pos - dev_pos);
827 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
828 break;
829 blocks_in_map = be32_to_cpu(part->map_count);
830 add_partition(hd, current_minor,
831 fsec + be32_to_cpu(part->start_block) * (secsize/512),
832 be32_to_cpu(part->block_count) * (secsize/512));
834 #ifdef CONFIG_PMAC
836 * If this is the first bootable partition, tell the
837 * setup code, in case it wants to make this the root.
839 if (first_bootable
840 && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
841 && strcasecmp(part->processor, "powerpc") == 0) {
842 note_bootable_part(dev, blk);
843 first_bootable = 0;
845 #endif /* CONFIG_PMAC */
847 ++current_minor;
849 brelse(bh);
850 printk("\n");
851 return 1;
854 #endif /* CONFIG_MAC_PARTITION */
856 #ifdef CONFIG_ATARI_PARTITION
857 #include <asm/atari_rootsec.h>
859 /* ++guenther: this should be settable by the user ("make config")?.
861 #define ICD_PARTS
863 static int atari_partition (struct gendisk *hd, kdev_t dev,
864 unsigned long first_sector)
866 int minor = current_minor, m_lim = current_minor + hd->max_p;
867 struct buffer_head *bh;
868 struct rootsector *rs;
869 struct partition_info *pi;
870 ulong extensect;
871 #ifdef ICD_PARTS
872 int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
873 #endif
875 bh = bread (dev, 0, get_ptable_blocksize(dev));
876 if (!bh)
878 printk (" unable to read block 0\n");
879 return -1;
882 rs = (struct rootsector *) bh->b_data;
883 pi = &rs->part[0];
884 printk (" AHDI");
885 for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
887 if (pi->flg & 1)
888 /* active partition */
890 if (memcmp (pi->id, "XGM", 3) == 0)
891 /* extension partition */
893 struct rootsector *xrs;
894 struct buffer_head *xbh;
895 ulong partsect;
897 #ifdef ICD_PARTS
898 part_fmt = 1;
899 #endif
900 printk(" XGM<");
901 partsect = extensect = pi->st;
902 while (1)
904 xbh = bread (dev, partsect / 2, 1024);
905 if (!xbh)
907 printk (" block %ld read failed\n", partsect);
908 brelse(bh);
909 return 0;
911 if (partsect & 1)
912 xrs = (struct rootsector *) &xbh->b_data[512];
913 else
914 xrs = (struct rootsector *) &xbh->b_data[0];
916 /* ++roman: sanity check: bit 0 of flg field must be set */
917 if (!(xrs->part[0].flg & 1)) {
918 printk( "\nFirst sub-partition in extended partition is not valid!\n" );
919 break;
922 add_partition(hd, minor, partsect + xrs->part[0].st,
923 xrs->part[0].siz);
925 if (!(xrs->part[1].flg & 1)) {
926 /* end of linked partition list */
927 brelse( xbh );
928 break;
930 if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
931 printk( "\nID of extended partition is not XGM!\n" );
932 brelse( xbh );
933 break;
936 partsect = xrs->part[1].st + extensect;
937 brelse (xbh);
938 minor++;
939 if (minor >= m_lim) {
940 printk( "\nMaximum number of partitions reached!\n" );
941 break;
944 printk(" >");
946 else
948 /* we don't care about other id's */
949 add_partition (hd, minor, pi->st, pi->siz);
953 #ifdef ICD_PARTS
954 if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
956 pi = &rs->icdpart[0];
957 /* sanity check: no ICD format if first partition invalid */
958 if (memcmp (pi->id, "GEM", 3) == 0 ||
959 memcmp (pi->id, "BGM", 3) == 0 ||
960 memcmp (pi->id, "LNX", 3) == 0 ||
961 memcmp (pi->id, "SWP", 3) == 0 ||
962 memcmp (pi->id, "RAW", 3) == 0 )
964 printk(" ICD<");
965 for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
967 /* accept only GEM,BGM,RAW,LNX,SWP partitions */
968 if (pi->flg & 1 &&
969 (memcmp (pi->id, "GEM", 3) == 0 ||
970 memcmp (pi->id, "BGM", 3) == 0 ||
971 memcmp (pi->id, "LNX", 3) == 0 ||
972 memcmp (pi->id, "SWP", 3) == 0 ||
973 memcmp (pi->id, "RAW", 3) == 0) )
975 part_fmt = 2;
976 add_partition (hd, minor, pi->st, pi->siz);
979 printk(" >");
982 #endif
983 brelse (bh);
985 printk ("\n");
987 return 1;
989 #endif /* CONFIG_ATARI_PARTITION */
991 static void check_partition(struct gendisk *hd, kdev_t dev)
993 static int first_time = 1;
994 unsigned long first_sector;
995 char buf[8];
997 if (first_time)
998 printk("Partition check:\n");
999 first_time = 0;
1000 first_sector = hd->part[MINOR(dev)].start_sect;
1003 * This is a kludge to allow the partition check to be
1004 * skipped for specific drives (e.g. IDE CD-ROM drives)
1006 if ((int)first_sector == -1) {
1007 hd->part[MINOR(dev)].start_sect = 0;
1008 return;
1011 printk(" %s:", disk_name(hd, MINOR(dev), buf));
1012 #ifdef CONFIG_MSDOS_PARTITION
1013 if (msdos_partition(hd, dev, first_sector))
1014 return;
1015 #endif
1016 #ifdef CONFIG_OSF_PARTITION
1017 if (osf_partition(hd, dev, first_sector))
1018 return;
1019 #endif
1020 #ifdef CONFIG_SUN_PARTITION
1021 if(sun_partition(hd, dev, first_sector))
1022 return;
1023 #endif
1024 #ifdef CONFIG_AMIGA_PARTITION
1025 if(amiga_partition(hd, dev, first_sector))
1026 return;
1027 #endif
1028 #ifdef CONFIG_ATARI_PARTITION
1029 if(atari_partition(hd, dev, first_sector))
1030 return;
1031 #endif
1032 #ifdef CONFIG_MAC_PARTITION
1033 if (mac_partition(hd, dev, first_sector))
1034 return;
1035 #endif
1036 printk(" unknown partition table\n");
1039 /* This function is used to re-read partition tables for removable disks.
1040 Much of the cleanup from the old partition tables should have already been
1041 done */
1043 /* This function will re-read the partition tables for a given device,
1044 and set things back up again. There are some important caveats,
1045 however. You must ensure that no one is using the device, and no one
1046 can start using the device while this function is being executed. */
1048 void resetup_one_dev(struct gendisk *dev, int drive)
1050 int i;
1051 int first_minor = drive << dev->minor_shift;
1052 int end_minor = first_minor + dev->max_p;
1054 blk_size[dev->major] = NULL;
1055 current_minor = 1 + first_minor;
1056 check_partition(dev, MKDEV(dev->major, first_minor));
1059 * We need to set the sizes array before we will be able to access
1060 * any of the partitions on this device.
1062 if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
1063 for (i = first_minor; i < end_minor; i++)
1064 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
1065 blk_size[dev->major] = dev->sizes;
1069 static inline void setup_dev(struct gendisk *dev)
1071 int i, drive;
1072 int end_minor = dev->max_nr * dev->max_p;
1074 blk_size[dev->major] = NULL;
1075 for (i = 0 ; i < end_minor; i++) {
1076 dev->part[i].start_sect = 0;
1077 dev->part[i].nr_sects = 0;
1079 dev->init(dev);
1080 for (drive = 0 ; drive < dev->nr_real ; drive++) {
1081 int first_minor = drive << dev->minor_shift;
1082 current_minor = 1 + first_minor;
1083 check_partition(dev, MKDEV(dev->major, first_minor));
1085 if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
1086 for (i = 0; i < end_minor; i++)
1087 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
1088 blk_size[dev->major] = dev->sizes;
1092 __initfunc(void device_setup(void))
1094 extern void console_map_init(void);
1095 #ifdef CONFIG_PARPORT
1096 extern int parport_init(void);
1097 #endif
1098 #ifdef CONFIG_MD_BOOT
1099 extern void md_setup_drive(void) __init;
1100 #endif
1101 #ifdef CONFIG_FC4_SOC
1102 extern int soc_probe(void);
1103 #endif
1104 struct gendisk *p;
1106 #ifdef CONFIG_PARPORT
1107 parport_init();
1108 #endif
1109 chr_dev_init();
1110 blk_dev_init();
1111 sti();
1112 #ifdef CONFIG_FC4_SOC
1113 /* This has to be done before scsi_dev_init */
1114 soc_probe();
1115 #endif
1116 #ifdef CONFIG_SCSI
1117 scsi_dev_init();
1118 #endif
1119 #ifdef CONFIG_INET
1120 net_dev_init();
1121 #endif
1122 #ifdef CONFIG_VT
1123 console_map_init();
1124 #endif
1126 for (p = gendisk_head ; p ; p=p->next)
1127 setup_dev(p);
1129 #ifdef CONFIG_BLK_DEV_RAM
1130 #ifdef CONFIG_BLK_DEV_INITRD
1131 if (initrd_start && mount_initrd) initrd_load();
1132 else
1133 #endif
1134 rd_load();
1135 #endif
1136 #ifdef CONFIG_MD_BOOT
1137 md_setup_drive();
1138 #endif
1141 #ifdef CONFIG_PROC_FS
1142 int get_partition_list(char * page)
1144 struct gendisk *p;
1145 char buf[8];
1146 int n, len;
1148 len = sprintf(page, "major minor #blocks name\n\n");
1149 for (p = gendisk_head; p; p = p->next) {
1150 for (n=0; n < (p->nr_real << p->minor_shift); n++) {
1151 if (p->part[n].nr_sects && len < PAGE_SIZE - 80) {
1152 len += sprintf(page+len,
1153 "%4d %4d %10d %s\n",
1154 p->major, n, p->sizes[n],
1155 disk_name(p, n, buf));
1159 return len;
1161 #endif