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

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

unix.superglobalmegacorp.com

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