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

unix.superglobalmegacorp.com

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