Import 2.1.81
[davej-history.git] / drivers / block / genhd.c
blob966a4031e25d63690d1a5627dd356aa64c16547f
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_tag == 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 necessary for drives for situations where
415 * the 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 || heads == 128 || heads == 255) {
425 (void) ide_xlate_1024(dev, heads, " [PTBL]");
426 break;
432 #endif /* CONFIG_BLK_DEV_IDE */
434 current_minor += 4; /* first "extra" minor (for extended partitions) */
435 for (i=1 ; i<=4 ; minor++,i++,p++) {
436 if (!NR_SECTS(p))
437 continue;
438 add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
439 if (is_extended_partition(p)) {
440 printk(" <");
442 * If we are rereading the partition table, we need
443 * to set the size of the partition so that we will
444 * be able to bread the block containing the extended
445 * partition info.
447 hd->sizes[minor] = hd->part[minor].nr_sects
448 >> (BLOCK_SIZE_BITS - 9);
449 extended_partition(hd, MKDEV(hd->major, minor));
450 printk(" >");
451 /* prevent someone doing mkfs or mkswap on an
452 extended partition, but leave room for LILO */
453 if (hd->part[minor].nr_sects > 2)
454 hd->part[minor].nr_sects = 2;
456 #ifdef CONFIG_BSD_DISKLABEL
457 if (SYS_IND(p) == BSD_PARTITION) {
458 printk(" <");
459 bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
460 printk(" >");
462 #endif
463 #ifdef CONFIG_SOLARIS_X86_PARTITION
465 /* james@bpgc.com: Solaris has a nasty indicator: 0x82
466 * which also means linux swap. For that reason, all
467 * of the prints are done inside the
468 * solaris_x86_partition routine */
470 if(SYS_IND(p) == SOLARIS_X86_PARTITION) {
471 solaris_x86_partition(hd, MKDEV(hd->major, minor),
472 first_sector+START_SECT(p));
474 #endif
477 * Check for old-style Disk Manager partition table
479 if (*(unsigned short *) (data+0xfc) == cpu_to_le16(MSDOS_LABEL_MAGIC)) {
480 p = (struct partition *) (0x1be + data);
481 for (i = 4 ; i < 16 ; i++, current_minor++) {
482 p--;
483 if ((current_minor & mask) == 0)
484 break;
485 if (!(START_SECT(p) && NR_SECTS(p)))
486 continue;
487 add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
490 printk("\n");
491 brelse(bh);
492 return 1;
495 #endif /* CONFIG_MSDOS_PARTITION */
497 #ifdef CONFIG_OSF_PARTITION
499 static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
501 int i;
502 int mask = (1 << hd->minor_shift) - 1;
503 struct buffer_head *bh;
504 struct disklabel {
505 u32 d_magic;
506 u16 d_type,d_subtype;
507 u8 d_typename[16];
508 u8 d_packname[16];
509 u32 d_secsize;
510 u32 d_nsectors;
511 u32 d_ntracks;
512 u32 d_ncylinders;
513 u32 d_secpercyl;
514 u32 d_secprtunit;
515 u16 d_sparespertrack;
516 u16 d_sparespercyl;
517 u32 d_acylinders;
518 u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
519 u32 d_headswitch, d_trkseek, d_flags;
520 u32 d_drivedata[5];
521 u32 d_spare[5];
522 u32 d_magic2;
523 u16 d_checksum;
524 u16 d_npartitions;
525 u32 d_bbsize, d_sbsize;
526 struct d_partition {
527 u32 p_size;
528 u32 p_offset;
529 u32 p_fsize;
530 u8 p_fstype;
531 u8 p_frag;
532 u16 p_cpg;
533 } d_partitions[8];
534 } * label;
535 struct d_partition * partition;
536 #define DISKLABELMAGIC (0x82564557UL)
538 if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
539 printk("unable to read partition table\n");
540 return -1;
542 label = (struct disklabel *) (bh->b_data+64);
543 partition = label->d_partitions;
544 if (label->d_magic != DISKLABELMAGIC) {
545 printk("magic: %08x\n", label->d_magic);
546 brelse(bh);
547 return 0;
549 if (label->d_magic2 != DISKLABELMAGIC) {
550 printk("magic2: %08x\n", label->d_magic2);
551 brelse(bh);
552 return 0;
554 for (i = 0 ; i < label->d_npartitions; i++, partition++) {
555 if ((current_minor & mask) == 0)
556 break;
557 if (partition->p_size)
558 add_partition(hd, current_minor,
559 first_sector+partition->p_offset,
560 partition->p_size);
561 current_minor++;
563 printk("\n");
564 brelse(bh);
565 return 1;
568 #endif /* CONFIG_OSF_PARTITION */
570 #ifdef CONFIG_SUN_PARTITION
572 static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
574 int i, csum;
575 unsigned short *ush;
576 struct buffer_head *bh;
577 struct sun_disklabel {
578 unsigned char info[128]; /* Informative text string */
579 unsigned char spare[292]; /* Boot information etc. */
580 unsigned short rspeed; /* Disk rotational speed */
581 unsigned short pcylcount; /* Physical cylinder count */
582 unsigned short sparecyl; /* extra sects per cylinder */
583 unsigned char spare2[4]; /* More magic... */
584 unsigned short ilfact; /* Interleave factor */
585 unsigned short ncyl; /* Data cylinder count */
586 unsigned short nacyl; /* Alt. cylinder count */
587 unsigned short ntrks; /* Tracks per cylinder */
588 unsigned short nsect; /* Sectors per track */
589 unsigned char spare3[4]; /* Even more magic... */
590 struct sun_partition {
591 __u32 start_cylinder;
592 __u32 num_sectors;
593 } partitions[8];
594 unsigned short magic; /* Magic number */
595 unsigned short csum; /* Label xor'd checksum */
596 } * label;
597 struct sun_partition *p;
598 unsigned long spc;
599 #define SUN_LABEL_MAGIC 0xDABE
601 if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
602 printk("Dev %s: unable to read partition table\n",
603 kdevname(dev));
604 return -1;
606 label = (struct sun_disklabel *) bh->b_data;
607 p = label->partitions;
608 if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
609 printk("Dev %s Sun disklabel: bad magic %04x\n",
610 kdevname(dev), be16_to_cpu(label->magic));
611 brelse(bh);
612 return 0;
614 /* Look at the checksum */
615 ush = ((unsigned short *) (label+1)) - 1;
616 for(csum = 0; ush >= ((unsigned short *) label);)
617 csum ^= *ush--;
618 if(csum) {
619 printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
620 kdevname(dev));
621 brelse(bh);
622 return 0;
624 /* All Sun disks have 8 partition entries */
625 spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
626 for(i=0; i < 8; i++, p++) {
627 unsigned long st_sector;
628 int num_sectors;
630 st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
631 num_sectors = be32_to_cpu(p->num_sectors);
632 if (num_sectors)
633 add_partition(hd, current_minor, st_sector, num_sectors);
634 current_minor++;
636 printk("\n");
637 brelse(bh);
638 return 1;
641 #endif /* CONFIG_SUN_PARTITION */
643 #ifdef CONFIG_AMIGA_PARTITION
644 #include <asm/byteorder.h>
645 #include <linux/affs_hardblocks.h>
647 static __inline__ u32
648 checksum_block(u32 *m, int size)
650 u32 sum = 0;
652 while (size--)
653 sum += htonl(*m++);
654 return sum;
657 static int
658 amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
660 struct buffer_head *bh;
661 struct RigidDiskBlock *rdb;
662 struct PartitionBlock *pb;
663 int start_sect;
664 int nr_sects;
665 int blk;
666 int part, res;
668 set_blocksize(dev,512);
669 res = 0;
671 for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
672 if(!(bh = bread(dev,blk,512))) {
673 printk("Dev %s: unable to read RDB block %d\n",
674 kdevname(dev),blk);
675 goto rdb_done;
677 if (*(u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) {
678 rdb = (struct RigidDiskBlock *)bh->b_data;
679 if (checksum_block((u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) {
680 printk("Dev %s: RDB in block %d has bad checksum\n",
681 kdevname(dev),blk);
682 brelse(bh);
683 continue;
685 printk(" RDSK");
686 blk = htonl(rdb->rdb_PartitionList);
687 brelse(bh);
688 for (part = 1; blk > 0 && part <= 16; part++) {
689 if (!(bh = bread(dev,blk,512))) {
690 printk("Dev %s: unable to read partition block %d\n",
691 kdevname(dev),blk);
692 goto rdb_done;
694 pb = (struct PartitionBlock *)bh->b_data;
695 blk = htonl(pb->pb_Next);
696 if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block(
697 (u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) {
699 /* Tell Kernel about it */
701 if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 -
702 htonl(pb->pb_Environment[9])) *
703 htonl(pb->pb_Environment[3]) *
704 htonl(pb->pb_Environment[5]))) {
705 continue;
707 start_sect = htonl(pb->pb_Environment[9]) *
708 htonl(pb->pb_Environment[3]) *
709 htonl(pb->pb_Environment[5]);
710 add_partition(hd,current_minor,start_sect,nr_sects);
711 current_minor++;
712 res = 1;
714 brelse(bh);
716 printk("\n");
717 break;
721 rdb_done:
722 set_blocksize(dev,BLOCK_SIZE);
723 return res;
725 #endif /* CONFIG_AMIGA_PARTITION */
727 #ifdef CONFIG_MAC_PARTITION
728 #include <linux/ctype.h>
731 * Code to understand MacOS partition tables.
734 #define MAC_PARTITION_MAGIC 0x504d
736 /* type field value for A/UX or other Unix partitions */
737 #define APPLE_AUX_TYPE "Apple_UNIX_SVR2"
739 struct mac_partition {
740 __u16 signature; /* expected to be MAC_PARTITION_MAGIC */
741 __u16 res1;
742 __u32 map_count; /* # blocks in partition map */
743 __u32 start_block; /* absolute starting block # of partition */
744 __u32 block_count; /* number of blocks in partition */
745 char name[32]; /* partition name */
746 char type[32]; /* string type description */
747 __u32 data_start; /* rel block # of first data block */
748 __u32 data_count; /* number of data blocks */
749 __u32 status; /* partition status bits */
750 __u32 boot_start;
751 __u32 boot_size;
752 __u32 boot_load;
753 __u32 boot_load2;
754 __u32 boot_entry;
755 __u32 boot_entry2;
756 __u32 boot_cksum;
757 char processor[16]; /* identifies ISA of boot */
758 /* there is more stuff after this that we don't need */
761 #define MAC_STATUS_BOOTABLE 8 /* partition is bootable */
763 #define MAC_DRIVER_MAGIC 0x4552
765 /* Driver descriptor structure, in block 0 */
766 struct mac_driver_desc {
767 __u16 signature; /* expected to be MAC_DRIVER_MAGIC */
768 __u16 block_size;
769 __u32 block_count;
770 /* ... more stuff */
773 static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec)
775 struct buffer_head *bh;
776 int blk, blocks_in_map;
777 int dev_bsize, dev_pos, pos;
778 unsigned secsize;
779 #ifdef CONFIG_PMAC
780 int first_bootable = 1;
781 #endif
782 struct mac_partition *part;
783 struct mac_driver_desc *md;
785 dev_bsize = get_ptable_blocksize(dev);
786 dev_pos = 0;
787 /* Get 0th block and look at the first partition map entry. */
788 if ((bh = bread(dev, 0, dev_bsize)) == 0) {
789 printk("%s: error reading partition table\n",
790 kdevname(dev));
791 return -1;
793 md = (struct mac_driver_desc *) bh->b_data;
794 if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
795 brelse(bh);
796 return 0;
798 secsize = be16_to_cpu(md->block_size);
799 if (secsize >= dev_bsize) {
800 brelse(bh);
801 dev_pos = secsize;
802 if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
803 printk("%s: error reading partition table\n",
804 kdevname(dev));
805 return -1;
808 part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);
809 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
810 brelse(bh);
811 return 0; /* not a MacOS disk */
813 blocks_in_map = be32_to_cpu(part->map_count);
814 for (blk = 1; blk <= blocks_in_map; ++blk) {
815 pos = blk * secsize;
816 if (pos >= dev_pos + dev_bsize) {
817 brelse(bh);
818 dev_pos = pos;
819 if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {
820 printk("%s: error reading partition table\n",
821 kdevname(dev));
822 return -1;
825 part = (struct mac_partition *) (bh->b_data + pos - dev_pos);
826 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
827 break;
828 blocks_in_map = be32_to_cpu(part->map_count);
829 add_partition(hd, current_minor,
830 fsec + be32_to_cpu(part->start_block) * (secsize/512),
831 be32_to_cpu(part->block_count) * (secsize/512));
833 #ifdef CONFIG_PMAC
835 * If this is the first bootable partition, tell the
836 * setup code, in case it wants to make this the root.
838 if (first_bootable
839 && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
840 && strcasecmp(part->processor, "powerpc") == 0) {
841 note_bootable_part(dev, blk);
842 first_bootable = 0;
844 #endif /* CONFIG_PMAC */
846 ++current_minor;
848 brelse(bh);
849 printk("\n");
850 return 1;
853 #endif /* CONFIG_MAC_PARTITION */
855 #ifdef CONFIG_ATARI_PARTITION
856 #include <asm/atari_rootsec.h>
858 /* ++guenther: this should be settable by the user ("make config")?.
860 #define ICD_PARTS
862 static int atari_partition (struct gendisk *hd, kdev_t dev,
863 unsigned long first_sector)
865 int minor = current_minor, m_lim = current_minor + hd->max_p;
866 struct buffer_head *bh;
867 struct rootsector *rs;
868 struct partition_info *pi;
869 ulong extensect;
870 #ifdef ICD_PARTS
871 int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
872 #endif
874 bh = bread (dev, 0, get_ptable_blocksize(dev));
875 if (!bh)
877 printk (" unable to read block 0\n");
878 return -1;
881 rs = (struct rootsector *) bh->b_data;
882 pi = &rs->part[0];
883 printk (" AHDI");
884 for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
886 if (pi->flg & 1)
887 /* active partition */
889 if (memcmp (pi->id, "XGM", 3) == 0)
890 /* extension partition */
892 struct rootsector *xrs;
893 struct buffer_head *xbh;
894 ulong partsect;
896 #ifdef ICD_PARTS
897 part_fmt = 1;
898 #endif
899 printk(" XGM<");
900 partsect = extensect = pi->st;
901 while (1)
903 xbh = bread (dev, partsect / 2, 1024);
904 if (!xbh)
906 printk (" block %ld read failed\n", partsect);
907 brelse(bh);
908 return 0;
910 if (partsect & 1)
911 xrs = (struct rootsector *) &xbh->b_data[512];
912 else
913 xrs = (struct rootsector *) &xbh->b_data[0];
915 /* ++roman: sanity check: bit 0 of flg field must be set */
916 if (!(xrs->part[0].flg & 1)) {
917 printk( "\nFirst sub-partition in extended partition is not valid!\n" );
918 break;
921 add_partition(hd, minor, partsect + xrs->part[0].st,
922 xrs->part[0].siz);
924 if (!(xrs->part[1].flg & 1)) {
925 /* end of linked partition list */
926 brelse( xbh );
927 break;
929 if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
930 printk( "\nID of extended partition is not XGM!\n" );
931 brelse( xbh );
932 break;
935 partsect = xrs->part[1].st + extensect;
936 brelse (xbh);
937 minor++;
938 if (minor >= m_lim) {
939 printk( "\nMaximum number of partitions reached!\n" );
940 break;
943 printk(" >");
945 else
947 /* we don't care about other id's */
948 add_partition (hd, minor, pi->st, pi->siz);
952 #ifdef ICD_PARTS
953 if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
955 pi = &rs->icdpart[0];
956 /* sanity check: no ICD format if first partition invalid */
957 if (memcmp (pi->id, "GEM", 3) == 0 ||
958 memcmp (pi->id, "BGM", 3) == 0 ||
959 memcmp (pi->id, "LNX", 3) == 0 ||
960 memcmp (pi->id, "SWP", 3) == 0 ||
961 memcmp (pi->id, "RAW", 3) == 0 )
963 printk(" ICD<");
964 for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
966 /* accept only GEM,BGM,RAW,LNX,SWP partitions */
967 if (pi->flg & 1 &&
968 (memcmp (pi->id, "GEM", 3) == 0 ||
969 memcmp (pi->id, "BGM", 3) == 0 ||
970 memcmp (pi->id, "LNX", 3) == 0 ||
971 memcmp (pi->id, "SWP", 3) == 0 ||
972 memcmp (pi->id, "RAW", 3) == 0) )
974 part_fmt = 2;
975 add_partition (hd, minor, pi->st, pi->siz);
978 printk(" >");
981 #endif
982 brelse (bh);
984 printk ("\n");
986 return 1;
988 #endif /* CONFIG_ATARI_PARTITION */
990 static void check_partition(struct gendisk *hd, kdev_t dev)
992 static int first_time = 1;
993 unsigned long first_sector;
994 char buf[8];
996 if (first_time)
997 printk("Partition check:\n");
998 first_time = 0;
999 first_sector = hd->part[MINOR(dev)].start_sect;
1002 * This is a kludge to allow the partition check to be
1003 * skipped for specific drives (e.g. IDE cd-rom drives)
1005 if ((int)first_sector == -1) {
1006 hd->part[MINOR(dev)].start_sect = 0;
1007 return;
1010 printk(" %s:", disk_name(hd, MINOR(dev), buf));
1011 #ifdef CONFIG_MSDOS_PARTITION
1012 if (msdos_partition(hd, dev, first_sector))
1013 return;
1014 #endif
1015 #ifdef CONFIG_OSF_PARTITION
1016 if (osf_partition(hd, dev, first_sector))
1017 return;
1018 #endif
1019 #ifdef CONFIG_SUN_PARTITION
1020 if(sun_partition(hd, dev, first_sector))
1021 return;
1022 #endif
1023 #ifdef CONFIG_AMIGA_PARTITION
1024 if(amiga_partition(hd, dev, first_sector))
1025 return;
1026 #endif
1027 #ifdef CONFIG_ATARI_PARTITION
1028 if(atari_partition(hd, dev, first_sector))
1029 return;
1030 #endif
1031 #ifdef CONFIG_MAC_PARTITION
1032 if (mac_partition(hd, dev, first_sector))
1033 return;
1034 #endif
1035 printk(" unknown partition table\n");
1038 /* This function is used to re-read partition tables for removable disks.
1039 Much of the cleanup from the old partition tables should have already been
1040 done */
1042 /* This function will re-read the partition tables for a given device,
1043 and set things back up again. There are some important caveats,
1044 however. You must ensure that no one is using the device, and no one
1045 can start using the device while this function is being executed. */
1047 void resetup_one_dev(struct gendisk *dev, int drive)
1049 int i;
1050 int first_minor = drive << dev->minor_shift;
1051 int end_minor = first_minor + dev->max_p;
1053 blk_size[dev->major] = NULL;
1054 current_minor = 1 + first_minor;
1055 check_partition(dev, MKDEV(dev->major, first_minor));
1058 * We need to set the sizes array before we will be able to access
1059 * any of the partitions on this device.
1061 if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
1062 for (i = first_minor; i < end_minor; i++)
1063 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
1064 blk_size[dev->major] = dev->sizes;
1068 static inline void setup_dev(struct gendisk *dev)
1070 int i, drive;
1071 int end_minor = dev->max_nr * dev->max_p;
1073 blk_size[dev->major] = NULL;
1074 for (i = 0 ; i < end_minor; i++) {
1075 dev->part[i].start_sect = 0;
1076 dev->part[i].nr_sects = 0;
1078 dev->init(dev);
1079 for (drive = 0 ; drive < dev->nr_real ; drive++) {
1080 int first_minor = drive << dev->minor_shift;
1081 current_minor = 1 + first_minor;
1082 check_partition(dev, MKDEV(dev->major, first_minor));
1084 if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
1085 for (i = 0; i < end_minor; i++)
1086 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
1087 blk_size[dev->major] = dev->sizes;
1091 __initfunc(void device_setup(void))
1093 extern void console_map_init(void);
1094 #ifdef CONFIG_PARPORT
1095 extern int parport_init(void);
1096 #endif
1097 struct gendisk *p;
1098 int nr=0;
1100 #ifdef CONFIG_PARPORT
1101 parport_init();
1102 #endif
1103 chr_dev_init();
1104 blk_dev_init();
1105 sti();
1106 #ifdef CONFIG_SCSI
1107 scsi_dev_init();
1108 #endif
1109 #ifdef CONFIG_INET
1110 net_dev_init();
1111 #endif
1112 #ifdef CONFIG_VT
1113 console_map_init();
1114 #endif
1116 for (p = gendisk_head ; p ; p=p->next) {
1117 setup_dev(p);
1118 nr += p->nr_real;
1120 #ifdef CONFIG_BLK_DEV_RAM
1121 #ifdef CONFIG_BLK_DEV_INITRD
1122 if (initrd_start && mount_initrd) initrd_load();
1123 else
1124 #endif
1125 rd_load();
1126 #endif