Annotation of Gnu-Mach/linux/dev/drivers/block/genhd.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  *  Code extracted from
                      3:  *  linux/kernel/hd.c
                      4:  *
                      5:  *  Copyright (C) 1991, 1992  Linus Torvalds
                      6:  *
                      7:  *
                      8:  *  Thanks to Branko Lankester, [email protected], who found a bug
                      9:  *  in the early extended-partition checks and added DM partitions
                     10:  *
                     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).
                     15:  *
                     16:  *  More flexible handling of extended partitions - aeb, 950831
                     17:  *
                     18:  *  Check partition table on IDE disks for common CHS translations
                     19:  */
                     20: 
                     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: #ifdef CONFIG_BLK_DEV_INITRD
                     28: #include <linux/blk.h>
                     29: #endif
1.1.1.4 ! root       30: #include <linux/hdreg.h>
        !            31: #include <alloca.h>
1.1       root       32: 
                     33: #include <asm/system.h>
                     34: 
                     35: /*
                     36:  * Many architectures don't like unaligned accesses, which is
                     37:  * frequently the case with the nr_sects and start_sect partition
                     38:  * table entries.
                     39:  */
                     40: #include <asm/unaligned.h>
                     41: 
                     42: #ifdef MACH
                     43: #include <machine/spl.h>
1.1.1.3   root       44: #include <linux/dev/glue/glue.h>
1.1       root       45: #endif
                     46: 
                     47: #define SYS_IND(p)     get_unaligned(&p->sys_ind)
                     48: #define NR_SECTS(p)    get_unaligned(&p->nr_sects)
                     49: #define START_SECT(p)  get_unaligned(&p->start_sect)
                     50: 
                     51: 
                     52: struct gendisk *gendisk_head = NULL;
                     53: 
                     54: static int current_minor = 0;
                     55: extern int *blk_size[];
                     56: extern void rd_load(void);
                     57: extern void initrd_load(void);
                     58: 
                     59: extern int chr_dev_init(void);
                     60: extern int blk_dev_init(void);
                     61: extern int scsi_dev_init(void);
                     62: extern int net_dev_init(void);
                     63: 
                     64: /*
                     65:  * disk_name() is used by genhd.c and md.c.
                     66:  * It formats the devicename of the indicated disk
                     67:  * into the supplied buffer, and returns a pointer
                     68:  * to that same buffer (for convenience).
                     69:  */
                     70: char *disk_name (struct gendisk *hd, int minor, char *buf)
                     71: {
                     72:        unsigned int part;
                     73:        const char *maj = hd->major_name;
                     74: #ifdef MACH
                     75:        char unit = (minor >> hd->minor_shift) + '0';
                     76: #else
                     77:        char unit = (minor >> hd->minor_shift) + 'a';
                     78: #endif
                     79: 
                     80: #ifdef CONFIG_BLK_DEV_IDE
                     81:        /*
                     82:         * IDE devices use multiple major numbers, but the drives
                     83:         * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
                     84:         * This requires special handling here.
                     85:         */
                     86:        switch (hd->major) {
                     87:                case IDE3_MAJOR:
                     88:                        unit += 2;
                     89:                case IDE2_MAJOR:
                     90:                        unit += 2;
                     91:                case IDE1_MAJOR:
                     92:                        unit += 2;
                     93:                case IDE0_MAJOR:
                     94:                        maj = "hd";
                     95:        }
                     96: #endif
                     97:        part = minor & ((1 << hd->minor_shift) - 1);
                     98:        if (part)
                     99: #ifdef MACH
                    100:                sprintf(buf, "%s%cs%d", maj, unit, part);
                    101: #else
                    102:                sprintf(buf, "%s%c%d", maj, unit, part);
                    103: #endif
                    104:        else
                    105:                sprintf(buf, "%s%c", maj, unit);
                    106:        return buf;
                    107: }
                    108: 
                    109: static void add_partition (struct gendisk *hd, int minor, int start, int size)
                    110: {
                    111:        char buf[8];
                    112:        hd->part[minor].start_sect = start;
                    113:        hd->part[minor].nr_sects   = size;
                    114:        printk(" %s", disk_name(hd, minor, buf));
                    115: }
                    116: 
1.1.1.3   root      117: #if defined (MACH) && defined (CONFIG_BSD_DISKLABEL)
1.1       root      118: static int mach_minor;
                    119: static void
                    120: add_bsd_partition (struct gendisk *hd, int minor, int slice,
                    121:                   int start, int size)
                    122: {
                    123:   char buf[16];
                    124:   hd->part[minor].start_sect = start;
                    125:   hd->part[minor].nr_sects = size;
                    126:   printk (" %s%c", disk_name (hd, mach_minor, buf), slice);
                    127: }
                    128: #endif
1.1.1.2   root      129: 
1.1       root      130: static inline int is_extended_partition(struct partition *p)
                    131: {
                    132:        return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
                    133:                SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
                    134:                SYS_IND(p) == LINUX_EXTENDED_PARTITION);
                    135: }
                    136: 
                    137: #ifdef CONFIG_MSDOS_PARTITION
                    138: /*
                    139:  * Create devices for each logical partition in an extended partition.
                    140:  * The logical partitions form a linked list, with each entry being
                    141:  * a partition table with two entries.  The first entry
                    142:  * is the real data partition (with a start relative to the partition
                    143:  * table start).  The second is a pointer to the next logical partition
                    144:  * (with a start relative to the entire extended partition).
                    145:  * We do not create a Linux partition for the partition tables, but
                    146:  * only for the actual data partitions.
                    147:  */
                    148: 
                    149: static void extended_partition(struct gendisk *hd, kdev_t dev)
                    150: {
                    151:        struct buffer_head *bh;
                    152:        struct partition *p;
                    153:        unsigned long first_sector, first_size, this_sector, this_size;
                    154:        int mask = (1 << hd->minor_shift) - 1;
                    155:        int i;
                    156: 
                    157:        first_sector = hd->part[MINOR(dev)].start_sect;
                    158:        first_size = hd->part[MINOR(dev)].nr_sects;
                    159:        this_sector = first_sector;
                    160: 
                    161:        while (1) {
                    162:                if ((current_minor & mask) == 0)
                    163:                        return;
                    164:                if (!(bh = bread(dev,0,1024)))
                    165:                        return;
                    166:          /*
                    167:           * This block is from a device that we're about to stomp on.
                    168:           * So make sure nobody thinks this block is usable.
                    169:           */
                    170:                bh->b_state = 0;
                    171: 
                    172:                if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
                    173:                        goto done;
                    174: 
                    175:                p = (struct partition *) (0x1BE + bh->b_data);
                    176: 
                    177:                this_size = hd->part[MINOR(dev)].nr_sects;
                    178: 
                    179:                /*
                    180:                 * Usually, the first entry is the real data partition,
                    181:                 * the 2nd entry is the next extended partition, or empty,
                    182:                 * and the 3rd and 4th entries are unused.
                    183:                 * However, DRDOS sometimes has the extended partition as
                    184:                 * the first entry (when the data partition is empty),
                    185:                 * and OS/2 seems to use all four entries.
                    186:                 */
                    187: 
1.1.1.2   root      188:                /*
1.1       root      189:                 * First process the data partition(s)
                    190:                 */
                    191:                for (i=0; i<4; i++, p++) {
                    192:                    if (!NR_SECTS(p) || is_extended_partition(p))
                    193:                      continue;
                    194: 
                    195:                    /* Check the 3rd and 4th entries -
                    196:                       these sometimes contain random garbage */
                    197:                    if (i >= 2
                    198:                        && START_SECT(p) + NR_SECTS(p) > this_size
                    199:                        && (this_sector + START_SECT(p) < first_sector ||
                    200:                            this_sector + START_SECT(p) + NR_SECTS(p) >
                    201:                             first_sector + first_size))
                    202:                      continue;
                    203: 
                    204:                    add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
                    205:                    current_minor++;
                    206:                    if ((current_minor & mask) == 0)
                    207:                      goto done;
                    208:                }
                    209:                /*
                    210:                 * Next, process the (first) extended partition, if present.
                    211:                 * (So far, there seems to be no reason to make
                    212:                 *  extended_partition()  recursive and allow a tree
                    213:                 *  of extended partitions.)
                    214:                 * It should be a link to the next logical partition.
                    215:                 * Create a minor for this just long enough to get the next
                    216:                 * partition table.  The minor will be reused for the next
                    217:                 * data partition.
                    218:                 */
                    219:                p -= 4;
                    220:                for (i=0; i<4; i++, p++)
                    221:                  if(NR_SECTS(p) && is_extended_partition(p))
                    222:                    break;
                    223:                if (i == 4)
                    224:                  goto done;     /* nothing left to do */
                    225: 
                    226:                hd->part[current_minor].nr_sects = NR_SECTS(p);
                    227:                hd->part[current_minor].start_sect = first_sector + START_SECT(p);
                    228:                this_sector = first_sector + START_SECT(p);
                    229:                dev = MKDEV(hd->major, current_minor);
                    230:                brelse(bh);
                    231:        }
                    232: done:
                    233:        brelse(bh);
                    234: }
                    235: 
                    236: #ifdef CONFIG_BSD_DISKLABEL
1.1.1.2   root      237: /*
1.1       root      238:  * Create devices for BSD partitions listed in a disklabel, under a
                    239:  * dos-like partition. See extended_partition() for more information.
                    240:  */
                    241: static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
                    242: {
                    243:        struct buffer_head *bh;
                    244:        struct bsd_disklabel *l;
                    245:        struct bsd_partition *p;
                    246:        int mask = (1 << hd->minor_shift) - 1;
                    247: 
                    248:        if (!(bh = bread(dev,0,1024)))
                    249:                return;
                    250:        bh->b_state = 0;
                    251:        l = (struct bsd_disklabel *) (bh->b_data+512);
                    252:        if (l->d_magic != BSD_DISKMAGIC) {
                    253:                brelse(bh);
                    254:                return;
                    255:        }
                    256: 
                    257:        p = &l->d_partitions[0];
                    258:        while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
                    259:                if ((current_minor & mask) >= (4 + hd->max_p))
                    260:                        break;
                    261: 
                    262:                if (p->p_fstype != BSD_FS_UNUSED) {
                    263: #ifdef MACH
                    264:                  add_bsd_partition (hd, current_minor,
                    265:                                     p - &l->d_partitions[0] + 'a',
                    266:                                     p->p_offset, p->p_size);
                    267: #else
                    268:                        add_partition(hd, current_minor, p->p_offset, p->p_size);
                    269: #endif
                    270:                        current_minor++;
                    271:                }
                    272:                p++;
                    273:        }
                    274:        brelse(bh);
                    275: 
                    276: }
                    277: #endif
                    278: 
                    279: static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
                    280: {
                    281:        int i, minor = current_minor;
                    282:        struct buffer_head *bh;
                    283:        struct partition *p;
                    284:        unsigned char *data;
                    285:        int mask = (1 << hd->minor_shift) - 1;
                    286: #ifdef CONFIG_BLK_DEV_IDE
                    287:        int tested_for_xlate = 0;
                    288: 
                    289: read_mbr:
                    290: #endif
                    291:        if (!(bh = bread(dev,0,1024))) {
                    292:                printk(" unable to read partition table\n");
                    293:                return -1;
                    294:        }
1.1.1.3   root      295:        data = (unsigned char *)bh->b_data;
1.1       root      296:        /* In some cases we modify the geometry    */
                    297:        /*  of the drive (below), so ensure that   */
                    298:        /*  nobody else tries to re-use this data. */
                    299:        bh->b_state = 0;
                    300: #ifdef CONFIG_BLK_DEV_IDE
                    301: check_table:
                    302: #endif
                    303:        if (*(unsigned short *)  (0x1fe + data) != 0xAA55) {
                    304:                brelse(bh);
                    305:                return 0;
                    306:        }
                    307:        p = (struct partition *) (0x1be + data);
                    308: 
                    309: #ifdef CONFIG_BLK_DEV_IDE
                    310:        if (!tested_for_xlate++) {      /* Do this only once per disk */
                    311:                /*
                    312:                 * Look for various forms of IDE disk geometry translation
                    313:                 */
                    314:                extern int ide_xlate_1024(kdev_t, int, const char *);
                    315:                unsigned int sig = *(unsigned short *)(data + 2);
                    316:                if (SYS_IND(p) == EZD_PARTITION) {
                    317:                        /*
                    318:                         * The remainder of the disk must be accessed using
1.1.1.2   root      319:                         * a translated geometry that reduces the number of
1.1       root      320:                         * apparent cylinders to less than 1024 if possible.
                    321:                         *
                    322:                         * ide_xlate_1024() will take care of the necessary
                    323:                         * adjustments to fool fdisk/LILO and partition check.
                    324:                         */
                    325:                        if (ide_xlate_1024(dev, -1, " [EZD]")) {
                    326:                                data += 512;
                    327:                                goto check_table;
                    328:                        }
                    329:                } else if (SYS_IND(p) == DM6_PARTITION) {
                    330: 
                    331:                        /*
                    332:                         * Everything on the disk is offset by 63 sectors,
                    333:                         * including a "new" MBR with its own partition table,
                    334:                         * and the remainder of the disk must be accessed using
1.1.1.2   root      335:                         * a translated geometry that reduces the number of
1.1       root      336:                         * apparent cylinders to less than 1024 if possible.
                    337:                         *
                    338:                         * ide_xlate_1024() will take care of the necessary
                    339:                         * adjustments to fool fdisk/LILO and partition check.
                    340:                         */
                    341:                        if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
                    342:                                brelse(bh);
                    343:                                goto read_mbr;  /* start over with new MBR */
                    344:                        }
                    345:                } else if (sig <= 0x1ae && *(unsigned short *)(data + sig) == 0x55AA
1.1.1.2   root      346:                         && (1 & *(unsigned char *)(data + sig + 2)) )
1.1       root      347:                {
                    348:                        /*
                    349:                         * DM6 signature in MBR, courtesy of OnTrack
                    350:                         */
                    351:                        (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
                    352:                } else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
                    353:                        /*
                    354:                         * DM6 on other than the first (boot) drive
                    355:                         */
                    356:                        (void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
                    357:                } else {
                    358:                        /*
                    359:                         * Examine the partition table for common translations.
                    360:                         * This is necessary for drives for situations where
                    361:                         * the translated geometry is unavailable from the BIOS.
                    362:                         */
                    363:                        for (i = 0; i < 4 ; i++) {
                    364:                                struct partition *q = &p[i];
                    365:                                if (NR_SECTS(q)
                    366:                                   && (q->sector & 63) == 1
                    367:                                   && (q->end_sector & 63) == 63) {
                    368:                                        unsigned int heads = q->end_head + 1;
                    369:                                        if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {
                    370: 
                    371:                                                (void) ide_xlate_1024(dev, heads, " [PTBL]");
                    372:                                                break;
                    373:                                        }
                    374:                                }
                    375:                        }
                    376:                }
                    377:        }
                    378: #endif /* CONFIG_BLK_DEV_IDE */
                    379: 
                    380:        current_minor += 4;  /* first "extra" minor (for extended partitions) */
                    381:        for (i=1 ; i<=4 ; minor++,i++,p++) {
                    382:                if (!NR_SECTS(p))
                    383:                        continue;
                    384:                add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
                    385:                if (is_extended_partition(p)) {
                    386:                        printk(" <");
                    387:                        /*
                    388:                         * If we are rereading the partition table, we need
                    389:                         * to set the size of the partition so that we will
                    390:                         * be able to bread the block containing the extended
                    391:                         * partition info.
                    392:                         */
1.1.1.2   root      393:                        hd->sizes[minor] = hd->part[minor].nr_sects
1.1       root      394:                                >> (BLOCK_SIZE_BITS - 9);
                    395:                        extended_partition(hd, MKDEV(hd->major, minor));
                    396:                        printk(" >");
                    397:                        /* prevent someone doing mkfs or mkswap on an
                    398:                           extended partition, but leave room for LILO */
                    399:                        if (hd->part[minor].nr_sects > 2)
                    400:                                hd->part[minor].nr_sects = 2;
                    401:                }
                    402: #ifdef CONFIG_BSD_DISKLABEL
                    403:                if (SYS_IND(p) == BSD_PARTITION) {
                    404:                        printk(" <");
                    405: #ifdef MACH
                    406:                        mach_minor = minor;
                    407: #endif
                    408:                        bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
                    409:                        printk(" >");
                    410:                }
                    411: #endif
                    412:        }
                    413:        /*
                    414:         *  Check for old-style Disk Manager partition table
                    415:         */
                    416:        if (*(unsigned short *) (data+0xfc) == 0x55AA) {
                    417:                p = (struct partition *) (0x1be + data);
                    418:                for (i = 4 ; i < 16 ; i++, current_minor++) {
                    419:                        p--;
                    420:                        if ((current_minor & mask) == 0)
                    421:                                break;
                    422:                        if (!(START_SECT(p) && NR_SECTS(p)))
                    423:                                continue;
                    424:                        add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
                    425:                }
                    426:        }
                    427:        printk("\n");
                    428:        brelse(bh);
                    429:        return 1;
                    430: }
                    431: 
                    432: #endif /* CONFIG_MSDOS_PARTITION */
                    433: 
                    434: #ifdef CONFIG_OSF_PARTITION
                    435: 
                    436: static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
                    437: {
                    438:        int i;
                    439:        int mask = (1 << hd->minor_shift) - 1;
                    440:        struct buffer_head *bh;
                    441:        struct disklabel {
                    442:                u32 d_magic;
                    443:                u16 d_type,d_subtype;
                    444:                u8 d_typename[16];
                    445:                u8 d_packname[16];
                    446:                u32 d_secsize;
                    447:                u32 d_nsectors;
                    448:                u32 d_ntracks;
                    449:                u32 d_ncylinders;
                    450:                u32 d_secpercyl;
                    451:                u32 d_secprtunit;
                    452:                u16 d_sparespertrack;
                    453:                u16 d_sparespercyl;
                    454:                u32 d_acylinders;
                    455:                u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
                    456:                u32 d_headswitch, d_trkseek, d_flags;
                    457:                u32 d_drivedata[5];
                    458:                u32 d_spare[5];
                    459:                u32 d_magic2;
                    460:                u16 d_checksum;
                    461:                u16 d_npartitions;
                    462:                u32 d_bbsize, d_sbsize;
                    463:                struct d_partition {
                    464:                        u32 p_size;
                    465:                        u32 p_offset;
                    466:                        u32 p_fsize;
                    467:                        u8  p_fstype;
                    468:                        u8  p_frag;
                    469:                        u16 p_cpg;
                    470:                } d_partitions[8];
                    471:        } * label;
                    472:        struct d_partition * partition;
                    473: #define DISKLABELMAGIC (0x82564557UL)
                    474: 
                    475:        if (!(bh = bread(dev,0,1024))) {
                    476:                printk("unable to read partition table\n");
                    477:                return -1;
                    478:        }
                    479:        label = (struct disklabel *) (bh->b_data+64);
                    480:        partition = label->d_partitions;
                    481:        if (label->d_magic != DISKLABELMAGIC) {
                    482:                printk("magic: %08x\n", label->d_magic);
                    483:                brelse(bh);
                    484:                return 0;
                    485:        }
                    486:        if (label->d_magic2 != DISKLABELMAGIC) {
                    487:                printk("magic2: %08x\n", label->d_magic2);
                    488:                brelse(bh);
                    489:                return 0;
                    490:        }
                    491:        for (i = 0 ; i < label->d_npartitions; i++, partition++) {
                    492:                if ((current_minor & mask) == 0)
                    493:                        break;
                    494:                if (partition->p_size)
                    495:                        add_partition(hd, current_minor,
                    496:                                first_sector+partition->p_offset,
                    497:                                partition->p_size);
                    498:                current_minor++;
                    499:        }
                    500:        printk("\n");
                    501:        brelse(bh);
                    502:        return 1;
                    503: }
                    504: 
                    505: #endif /* CONFIG_OSF_PARTITION */
                    506: 
                    507: #ifdef CONFIG_SUN_PARTITION
                    508: 
                    509: static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
                    510: {
                    511:        int i, csum;
                    512:        unsigned short *ush;
                    513:        struct buffer_head *bh;
                    514:        struct sun_disklabel {
                    515:                unsigned char info[128];   /* Informative text string */
                    516:                unsigned char spare[292];  /* Boot information etc. */
                    517:                unsigned short rspeed;     /* Disk rotational speed */
                    518:                unsigned short pcylcount;  /* Physical cylinder count */
                    519:                unsigned short sparecyl;   /* extra sects per cylinder */
                    520:                unsigned char spare2[4];   /* More magic... */
                    521:                unsigned short ilfact;     /* Interleave factor */
                    522:                unsigned short ncyl;       /* Data cylinder count */
                    523:                unsigned short nacyl;      /* Alt. cylinder count */
                    524:                unsigned short ntrks;      /* Tracks per cylinder */
                    525:                unsigned short nsect;      /* Sectors per track */
                    526:                unsigned char spare3[4];   /* Even more magic... */
                    527:                struct sun_partition {
                    528:                        __u32 start_cylinder;
                    529:                        __u32 num_sectors;
                    530:                } partitions[8];
                    531:                unsigned short magic;      /* Magic number */
                    532:                unsigned short csum;       /* Label xor'd checksum */
1.1.1.2   root      533:        } * label;
1.1       root      534:        struct sun_partition *p;
                    535:        int other_endian;
                    536:        unsigned long spc;
                    537: #define SUN_LABEL_MAGIC          0xDABE
                    538: #define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
                    539: /* No need to optimize these macros since they are called only when reading
                    540:  * the partition table. This occurs only at each disk change. */
                    541: #define SWAP16(x)  (other_endian ? (((__u16)(x) & 0xFF) << 8) \
                    542:                                 | (((__u16)(x) & 0xFF00) >> 8) \
                    543:                                 : (__u16)(x))
                    544: #define SWAP32(x)  (other_endian ? (((__u32)(x) & 0xFF) << 24) \
                    545:                                 | (((__u32)(x) & 0xFF00) << 8) \
                    546:                                 | (((__u32)(x) & 0xFF0000) >> 8) \
                    547:                                 | (((__u32)(x) & 0xFF000000) >> 24) \
                    548:                                 : (__u32)(x))
                    549: 
                    550:        if(!(bh = bread(dev, 0, 1024))) {
                    551:                printk("Dev %s: unable to read partition table\n",
                    552:                       kdevname(dev));
                    553:                return -1;
                    554:        }
                    555:        label = (struct sun_disklabel *) bh->b_data;
                    556:        p = label->partitions;
                    557:        if (label->magic != SUN_LABEL_MAGIC && label->magic != SUN_LABEL_MAGIC_SWAPPED) {
                    558:                printk("Dev %s Sun disklabel: bad magic %04x\n",
                    559:                       kdevname(dev), label->magic);
                    560:                brelse(bh);
                    561:                return 0;
                    562:        }
                    563:        other_endian = (label->magic == SUN_LABEL_MAGIC_SWAPPED);
                    564:        /* Look at the checksum */
                    565:        ush = ((unsigned short *) (label+1)) - 1;
                    566:        for(csum = 0; ush >= ((unsigned short *) label);)
                    567:                csum ^= *ush--;
                    568:        if(csum) {
                    569:                printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
                    570:                       kdevname(dev));
                    571:                brelse(bh);
                    572:                return 0;
                    573:        }
                    574:        /* All Sun disks have 8 partition entries */
                    575:        spc = SWAP16(label->ntrks) * SWAP16(label->nsect);
                    576:        for(i=0; i < 8; i++, p++) {
                    577:                unsigned long st_sector;
                    578: 
                    579:                /* We register all partitions, even if zero size, so that
                    580:                 * the minor numbers end up ok as per SunOS interpretation.
                    581:                 */
                    582:                st_sector = first_sector + SWAP32(p->start_cylinder) * spc;
                    583:                add_partition(hd, current_minor, st_sector, SWAP32(p->num_sectors));
                    584:                current_minor++;
                    585:        }
                    586:        printk("\n");
                    587:        brelse(bh);
                    588:        return 1;
                    589: #undef SWAP16
                    590: #undef SWAP32
                    591: }
                    592: 
                    593: #endif /* CONFIG_SUN_PARTITION */
                    594: 
                    595: #ifdef CONFIG_AMIGA_PARTITION
                    596: #include <asm/byteorder.h>
                    597: #include <linux/affs_hardblocks.h>
                    598: 
                    599: static __inline__ __u32
                    600: checksum_block(__u32 *m, int size)
                    601: {
                    602:        __u32 sum = 0;
                    603: 
                    604:        while (size--)
                    605:                sum += htonl(*m++);
                    606:        return sum;
                    607: }
                    608: 
                    609: static int
                    610: amiga_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
                    611: {
                    612:        struct buffer_head      *bh;
                    613:        struct RigidDiskBlock   *rdb;
                    614:        struct PartitionBlock   *pb;
                    615:        int                      start_sect;
                    616:        int                      nr_sects;
                    617:        int                      blk;
                    618:        int                      part, res;
                    619: 
                    620:        set_blocksize(dev,512);
                    621:        res = 0;
                    622: 
                    623:        for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
                    624:                if(!(bh = bread(dev,blk,512))) {
                    625:                        printk("Dev %d: unable to read RDB block %d\n",dev,blk);
                    626:                        goto rdb_done;
                    627:                }
                    628:                if (*(__u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) {
                    629:                        rdb = (struct RigidDiskBlock *)bh->b_data;
                    630:                        if (checksum_block((__u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) {
                    631:                                printk("Dev %d: RDB in block %d has bad checksum\n",dev,blk);
                    632:                                brelse(bh);
                    633:                                continue;
                    634:                        }
                    635:                        printk(" RDSK");
                    636:                        blk = htonl(rdb->rdb_PartitionList);
                    637:                        brelse(bh);
                    638:                        for (part = 1; blk > 0 && part <= 16; part++) {
                    639:                                if (!(bh = bread(dev,blk,512))) {
                    640:                                        printk("Dev %d: unable to read partition block %d\n",
                    641:                                                       dev,blk);
                    642:                                        goto rdb_done;
                    643:                                }
                    644:                                pb  = (struct PartitionBlock *)bh->b_data;
                    645:                                blk = htonl(pb->pb_Next);
                    646:                                if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block(
                    647:                                    (__u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) {
1.1.1.2   root      648: 
1.1       root      649:                                        /* Tell Kernel about it */
                    650: 
                    651:                                        if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 -
                    652:                                                          htonl(pb->pb_Environment[9])) *
                    653:                                                         htonl(pb->pb_Environment[3]) *
                    654:                                                         htonl(pb->pb_Environment[5]))) {
                    655:                                                continue;
                    656:                                        }
                    657:                                        start_sect = htonl(pb->pb_Environment[9]) *
                    658:                                                     htonl(pb->pb_Environment[3]) *
                    659:                                                     htonl(pb->pb_Environment[5]);
                    660:                                        add_partition(hd,current_minor,start_sect,nr_sects);
                    661:                                        current_minor++;
                    662:                                        res = 1;
                    663:                                }
                    664:                                brelse(bh);
                    665:                        }
                    666:                        printk("\n");
                    667:                        break;
                    668:                }
                    669:        }
                    670: 
                    671: rdb_done:
                    672:        set_blocksize(dev,BLOCK_SIZE);
                    673:        return res;
                    674: }
                    675: #endif /* CONFIG_AMIGA_PARTITION */
                    676: 
                    677: static void check_partition(struct gendisk *hd, kdev_t dev)
                    678: {
                    679:        static int first_time = 1;
                    680:        unsigned long first_sector;
                    681:        char buf[8];
                    682: 
                    683:        if (first_time)
1.1.1.2   root      684:                printk("Partition check (DOS partitions):\n");
1.1       root      685:        first_time = 0;
                    686:        first_sector = hd->part[MINOR(dev)].start_sect;
                    687: 
                    688:        /*
                    689:         * This is a kludge to allow the partition check to be
                    690:         * skipped for specific drives (e.g. IDE cd-rom drives)
                    691:         */
                    692:        if ((int)first_sector == -1) {
                    693:                hd->part[MINOR(dev)].start_sect = 0;
                    694:                return;
                    695:        }
                    696: 
                    697:        printk(" %s:", disk_name(hd, MINOR(dev), buf));
                    698: #ifdef CONFIG_MSDOS_PARTITION
                    699:        if (msdos_partition(hd, dev, first_sector))
                    700:                return;
                    701: #endif
                    702: #ifdef CONFIG_OSF_PARTITION
                    703:        if (osf_partition(hd, dev, first_sector))
                    704:                return;
                    705: #endif
                    706: #ifdef CONFIG_SUN_PARTITION
                    707:        if(sun_partition(hd, dev, first_sector))
                    708:                return;
                    709: #endif
                    710: #ifdef CONFIG_AMIGA_PARTITION
                    711:        if(amiga_partition(hd, dev, first_sector))
                    712:                return;
                    713: #endif
                    714:        printk(" unknown partition table\n");
                    715: }
                    716: 
                    717: /* This function is used to re-read partition tables for removable disks.
                    718:    Much of the cleanup from the old partition tables should have already been
                    719:    done */
                    720: 
                    721: /* This function will re-read the partition tables for a given device,
                    722: and set things back up again.  There are some important caveats,
                    723: however.  You must ensure that no one is using the device, and no one
                    724: can start using the device while this function is being executed. */
                    725: 
                    726: void resetup_one_dev(struct gendisk *dev, int drive)
                    727: {
                    728:        int i;
                    729:        int first_minor = drive << dev->minor_shift;
                    730:        int end_minor   = first_minor + dev->max_p;
                    731: 
                    732:        blk_size[dev->major] = NULL;
                    733:        current_minor = 1 + first_minor;
                    734:        check_partition(dev, MKDEV(dev->major, first_minor));
                    735: 
                    736:        /*
                    737:         * We need to set the sizes array before we will be able to access
                    738:         * any of the partitions on this device.
                    739:         */
                    740:        if (dev->sizes != NULL) {       /* optional safeguard in ll_rw_blk.c */
                    741:                for (i = first_minor; i < end_minor; i++)
                    742:                        dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
                    743:                blk_size[dev->major] = dev->sizes;
                    744:        }
                    745: }
                    746: 
                    747: static void setup_dev(struct gendisk *dev)
                    748: {
                    749:        int i, drive;
                    750:        int end_minor   = dev->max_nr * dev->max_p;
                    751: 
                    752:        blk_size[dev->major] = NULL;
                    753:        for (i = 0 ; i < end_minor; i++) {
                    754:                dev->part[i].start_sect = 0;
                    755:                dev->part[i].nr_sects = 0;
                    756:        }
1.1.1.2   root      757:        dev->init(dev);
1.1       root      758:        for (drive = 0 ; drive < dev->nr_real ; drive++) {
                    759:                int first_minor = drive << dev->minor_shift;
                    760:                current_minor = 1 + first_minor;
                    761:                check_partition(dev, MKDEV(dev->major, first_minor));
                    762:        }
                    763:        if (dev->sizes != NULL) {       /* optional safeguard in ll_rw_blk.c */
                    764:                for (i = 0; i < end_minor; i++)
                    765:                        dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
                    766:                blk_size[dev->major] = dev->sizes;
                    767:        }
                    768: }
                    769: 
                    770: void device_setup(void)
                    771: {
                    772:        extern void console_map_init(void);
1.1.1.4 ! root      773:        extern char *kernel_cmdline;
        !           774:        char *c, *param, *white;
1.1       root      775:        struct gendisk *p;
                    776:        int nr=0;
                    777: #ifdef MACH
1.1.1.3   root      778:        linux_intr_pri = SPL6;
1.1       root      779: #endif
                    780: 
1.1.1.4 ! root      781:        for (c = kernel_cmdline; c; )
        !           782:        {
        !           783:                param = strstr(c, " ide");
        !           784:                if (!param)
        !           785:                        param = strstr(c, " hd");
        !           786:                if (!param)
        !           787:                        break;
        !           788:                if (param) {
        !           789:                        param++;
        !           790:                        white = strchr(param, ' ');
        !           791:                        if (!white) {
        !           792:                                ide_setup(param);
        !           793:                                c = NULL;
        !           794:                        } else {
        !           795:                                char *word = alloca(white - param + 1);
        !           796:                                strncpy(word, param, white - param);
        !           797:                                word[white-param] = '\0';
        !           798:                                ide_setup(word);
        !           799:                                c = white + 1;
        !           800:                        }
        !           801:                }
        !           802:        }
1.1       root      803: #ifndef MACH
                    804:        chr_dev_init();
                    805: #endif
                    806:        blk_dev_init();
                    807:        sti();
                    808: #ifdef CONFIG_SCSI
                    809:        scsi_dev_init();
                    810: #endif
                    811: #ifdef CONFIG_INET
                    812: #ifdef MACH
                    813:        linux_intr_pri = SPL6;
                    814: #endif
                    815:        net_dev_init();
                    816: #endif
                    817: #ifndef MACH
                    818:        console_map_init();
                    819: #endif
                    820: 
                    821:        for (p = gendisk_head ; p ; p=p->next) {
                    822:                setup_dev(p);
                    823:                nr += p->nr_real;
                    824:        }
                    825: #ifdef CONFIG_BLK_DEV_RAM
                    826: #ifdef CONFIG_BLK_DEV_INITRD
                    827:        if (initrd_start && mount_initrd) initrd_load();
                    828:        else
                    829: #endif
                    830:        rd_load();
                    831: #endif
                    832: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.