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>
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
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); \
45 #define START_SECT(p) ({ __typeof__(p->start_sect) __a = \
46 get_unaligned(&p->start_sect); \
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
)
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.
89 part
= minor
& ((1 << hd
->minor_shift
) - 1);
91 sprintf(buf
, "%s%c%d", maj
, unit
, part
);
93 sprintf(buf
, "%s%c", maj
, unit
);
97 static void add_partition (struct gendisk
*hd
, int minor
, int start
, int size
)
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
)
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
)])
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
)] )
151 panic("Strange blocksize for partition table\n");
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
;
176 unsigned long first_sector
, first_size
, this_sector
, this_size
;
177 int mask
= (1 << hd
->minor_shift
) - 1;
180 first_sector
= hd
->part
[MINOR(dev
)].start_sect
;
181 first_size
= hd
->part
[MINOR(dev
)].nr_sects
;
182 this_sector
= first_sector
;
185 if ((current_minor
& mask
) == 0)
187 if (!(bh
= bread(dev
,0,get_ptable_blocksize(dev
))))
190 * This block is from a device that we're about to stomp on.
191 * So make sure nobody thinks this block is usable.
195 if ((*(unsigned short *) (bh
->b_data
+510)) != cpu_to_le16(MSDOS_LABEL_MAGIC
))
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
))
218 /* Check the 3rd and 4th entries -
219 these sometimes contain random garbage */
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
))
227 add_partition(hd
, current_minor
, this_sector
+START_SECT(p
), NR_SECTS(p
));
229 if ((current_minor
& mask
) == 0)
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
243 for (i
=0; i
<4; i
++, p
++)
244 if(NR_SECTS(p
) && is_extended_partition(p
))
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
);
258 #ifdef CONFIG_SOLARIS_X86_PARTITION
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
;
267 if(!(bh
= bread(dev
, 0, get_ptable_blocksize(dev
))))
269 v
= (struct solaris_x86_vtoc
*)(bh
->b_data
+ 512);
270 if(v
->v_sanity
!= SOLARIS_X86_VTOC_SANE
) {
274 printk(" <solaris:");
275 if(v
->v_version
!= 1) {
276 printk(" cannot handle version %ld vtoc>", v
->v_version
);
280 for(i
=0; i
<SOLARIS_X86_NUMSLICE
; 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
);
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
))))
313 l
= (struct bsd_disklabel
*) (bh
->b_data
+512);
314 if (l
->d_magic
!= BSD_DISKMAGIC
) {
319 p
= &l
->d_partitions
[0];
320 while (p
- &l
->d_partitions
[0] <= BSD_MAXPARTITIONS
) {
321 if ((current_minor
& mask
) >= (4 + hd
->max_p
))
324 if (p
->p_fstype
!= BSD_FS_UNUSED
) {
325 add_partition(hd
, current_minor
, p
->p_offset
, p
->p_size
);
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
;
341 int mask
= (1 << hd
->minor_shift
) - 1;
342 #ifdef CONFIG_BLK_DEV_IDE
343 int tested_for_xlate
= 0;
347 if (!(bh
= bread(dev
,0,get_ptable_blocksize(dev
)))) {
348 printk(" unable to read partition table\n");
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. */
356 #ifdef CONFIG_BLK_DEV_IDE
359 if (*(unsigned short *) (0x1fe + data
) != cpu_to_le16(MSDOS_LABEL_MAGIC
)) {
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]")) {
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]")) {
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]");
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
];
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 ||
426 (void) ide_xlate_1024(dev
, heads
, " [PTBL]");
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
++) {
439 add_partition(hd
, minor
, first_sector
+START_SECT(p
), NR_SECTS(p
));
440 if (is_extended_partition(p
)) {
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
448 hd
->sizes
[minor
] = hd
->part
[minor
].nr_sects
449 >> (BLOCK_SIZE_BITS
- 9);
450 extended_partition(hd
, MKDEV(hd
->major
, minor
));
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
) {
460 bsd_disklabel_partition(hd
, MKDEV(hd
->major
, minor
));
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
));
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
++) {
484 if ((current_minor
& mask
) == 0)
486 if (!(START_SECT(p
) && NR_SECTS(p
)))
488 add_partition(hd
, current_minor
, START_SECT(p
), NR_SECTS(p
));
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
)
503 int mask
= (1 << hd
->minor_shift
) - 1;
504 struct buffer_head
*bh
;
507 u16 d_type
,d_subtype
;
516 u16 d_sparespertrack
;
519 u16 d_rpm
, d_interleave
, d_trackskew
, d_cylskew
;
520 u32 d_headswitch
, d_trkseek
, d_flags
;
526 u32 d_bbsize
, d_sbsize
;
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");
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
);
550 if (label
->d_magic2
!= DISKLABELMAGIC
) {
551 printk("magic2: %08x\n", label
->d_magic2
);
555 for (i
= 0 ; i
< label
->d_npartitions
; i
++, partition
++) {
556 if ((current_minor
& mask
) == 0)
558 if (partition
->p_size
)
559 add_partition(hd
, current_minor
,
560 first_sector
+partition
->p_offset
,
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
)
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
;
595 unsigned short magic
; /* Magic number */
596 unsigned short csum
; /* Label xor'd checksum */
598 struct sun_partition
*p
;
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",
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
));
615 /* Look at the checksum */
616 ush
= ((unsigned short *) (label
+1)) - 1;
617 for(csum
= 0; ush
>= ((unsigned short *) label
);)
620 printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
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
;
631 st_sector
= first_sector
+ be32_to_cpu(p
->start_cylinder
) * spc
;
632 num_sectors
= be32_to_cpu(p
->num_sectors
);
634 add_partition(hd
, current_minor
, st_sector
, num_sectors
);
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
)
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
;
669 set_blocksize(dev
,512);
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",
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",
687 blk
= htonl(rdb
->rdb_PartitionList
);
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",
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]))) {
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
);
723 set_blocksize(dev
,BLOCK_SIZE
);
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 */
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 */
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 */
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
;
781 int first_bootable
= 1;
783 struct mac_partition
*part
;
784 struct mac_driver_desc
*md
;
786 dev_bsize
= get_ptable_blocksize(dev
);
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",
794 md
= (struct mac_driver_desc
*) bh
->b_data
;
795 if (be16_to_cpu(md
->signature
) != MAC_DRIVER_MAGIC
) {
799 secsize
= be16_to_cpu(md
->block_size
);
800 if (secsize
>= dev_bsize
) {
803 if ((bh
= bread(dev
, secsize
/dev_bsize
, dev_bsize
)) == 0) {
804 printk("%s: error reading partition table\n",
809 part
= (struct mac_partition
*) (bh
->b_data
+ secsize
- dev_pos
);
810 if (be16_to_cpu(part
->signature
) != MAC_PARTITION_MAGIC
) {
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
) {
817 if (pos
>= dev_pos
+ dev_bsize
) {
820 if ((bh
= bread(dev
, pos
/dev_bsize
, dev_bsize
)) == 0) {
821 printk("%s: error reading partition table\n",
826 part
= (struct mac_partition
*) (bh
->b_data
+ pos
- dev_pos
);
827 if (be16_to_cpu(part
->signature
) != MAC_PARTITION_MAGIC
)
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));
836 * If this is the first bootable partition, tell the
837 * setup code, in case it wants to make this the root.
840 && (be32_to_cpu(part
->status
) & MAC_STATUS_BOOTABLE
)
841 && strcasecmp(part
->processor
, "powerpc") == 0) {
842 note_bootable_part(dev
, blk
);
845 #endif /* CONFIG_PMAC */
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")?.
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
;
872 int part_fmt
= 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
875 bh
= bread (dev
, 0, get_ptable_blocksize(dev
));
878 printk (" unable to read block 0\n");
882 rs
= (struct rootsector
*) bh
->b_data
;
885 for (; pi
< &rs
->part
[4] && minor
< m_lim
; minor
++, pi
++)
888 /* active partition */
890 if (memcmp (pi
->id
, "XGM", 3) == 0)
891 /* extension partition */
893 struct rootsector
*xrs
;
894 struct buffer_head
*xbh
;
901 partsect
= extensect
= pi
->st
;
904 xbh
= bread (dev
, partsect
/ 2, 1024);
907 printk (" block %ld read failed\n", partsect
);
912 xrs
= (struct rootsector
*) &xbh
->b_data
[512];
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" );
922 add_partition(hd
, minor
, partsect
+ xrs
->part
[0].st
,
925 if (!(xrs
->part
[1].flg
& 1)) {
926 /* end of linked partition list */
930 if (memcmp( xrs
->part
[1].id
, "XGM", 3 ) != 0) {
931 printk( "\nID of extended partition is not XGM!\n" );
936 partsect
= xrs
->part
[1].st
+ extensect
;
939 if (minor
>= m_lim
) {
940 printk( "\nMaximum number of partitions reached!\n" );
948 /* we don't care about other id's */
949 add_partition (hd
, minor
, pi
->st
, pi
->siz
);
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 )
965 for (; pi
< &rs
->icdpart
[8] && minor
< m_lim
; minor
++, pi
++)
967 /* accept only GEM,BGM,RAW,LNX,SWP partitions */
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) )
976 add_partition (hd
, minor
, pi
->st
, pi
->siz
);
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
;
998 printk("Partition check:\n");
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;
1011 printk(" %s:", disk_name(hd
, MINOR(dev
), buf
));
1012 #ifdef CONFIG_MSDOS_PARTITION
1013 if (msdos_partition(hd
, dev
, first_sector
))
1016 #ifdef CONFIG_OSF_PARTITION
1017 if (osf_partition(hd
, dev
, first_sector
))
1020 #ifdef CONFIG_SUN_PARTITION
1021 if(sun_partition(hd
, dev
, first_sector
))
1024 #ifdef CONFIG_AMIGA_PARTITION
1025 if(amiga_partition(hd
, dev
, first_sector
))
1028 #ifdef CONFIG_ATARI_PARTITION
1029 if(atari_partition(hd
, dev
, first_sector
))
1032 #ifdef CONFIG_MAC_PARTITION
1033 if (mac_partition(hd
, dev
, first_sector
))
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
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
)
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
)
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;
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);
1098 #ifdef CONFIG_MD_BOOT
1099 extern void md_setup_drive(void) __init
;
1101 #ifdef CONFIG_FC4_SOC
1102 extern int soc_probe(void);
1106 #ifdef CONFIG_PARPORT
1112 #ifdef CONFIG_FC4_SOC
1113 /* This has to be done before scsi_dev_init */
1126 for (p
= gendisk_head
; p
; p
=p
->next
)
1129 #ifdef CONFIG_BLK_DEV_RAM
1130 #ifdef CONFIG_BLK_DEV_INITRD
1131 if (initrd_start
&& mount_initrd
) initrd_load();
1136 #ifdef CONFIG_MD_BOOT
1141 #ifdef CONFIG_PROC_FS
1142 int get_partition_list(char * page
)
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
));