Annotation of Gnu-Mach/linux/src/drivers/block/genhd.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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