Annotation of Gnu-Mach/i386/i386at/gpl/linux/block/genhd.c, revision 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 ([email protected])
        !            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: 
        !            28: #include <asm/system.h>
        !            29: 
        !            30: #ifdef __alpha__
        !            31: /*
        !            32:  * On the Alpha, we get unaligned access exceptions on
        !            33:  *  p->nr_sects and p->start_sect, when the partition table
        !            34:  *  is not on a 4-byte boundary, which is frequently the case.
        !            35:  * This code uses unaligned load instructions to prevent
        !            36:  *  such exceptions.
        !            37:  */
        !            38: #include <asm/unaligned.h>
        !            39: #define NR_SECTS(p)    ldl_u(&p->nr_sects)
        !            40: #define START_SECT(p)  ldl_u(&p->start_sect)
        !            41: #else /* __alpha__ */
        !            42: #define NR_SECTS(p)    p->nr_sects
        !            43: #define START_SECT(p)  p->start_sect
        !            44: #endif /* __alpha__ */
        !            45: 
        !            46: #ifdef MACH
        !            47: #include <i386/ipl.h>
        !            48: #endif
        !            49: 
        !            50: struct gendisk *gendisk_head = NULL;
        !            51: 
        !            52: static int current_minor = 0;
        !            53: extern int *blk_size[];
        !            54: extern void rd_load(void);
        !            55: 
        !            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: static void print_minor_name (struct gendisk *hd, int minor)
        !            62: {
        !            63:        unsigned int unit = minor >> hd->minor_shift;
        !            64:        unsigned int part = minor & ((1 << hd->minor_shift) - 1);
        !            65: 
        !            66: #ifdef CONFIG_BLK_DEV_IDE
        !            67:        /*
        !            68:         * IDE devices use multiple major numbers, but the drives
        !            69:         * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
        !            70:         * This requires some creative handling here to find the
        !            71:         * correct name to use, with some help from ide.c
        !            72:         */
        !            73:        if (!strcmp(hd->major_name,"ide")) {
        !            74:                char name[16];          /* more than large enough */
        !            75:                strcpy(name, hd->real_devices); /* courtesy ide.c */
        !            76:                name[strlen(name)-1] += unit;
        !            77:                printk(" %s", name);
        !            78:        } else
        !            79: #endif
        !            80:                printk(" %s%c", hd->major_name, 'a' + unit);
        !            81:        if (part)
        !            82:                printk("%d", part);
        !            83:        else
        !            84:                printk(":");
        !            85: }
        !            86: 
        !            87: static void add_partition (struct gendisk *hd, int minor, int start, int size)
        !            88: {
        !            89:        hd->part[minor].start_sect = start;
        !            90:        hd->part[minor].nr_sects   = size;
        !            91:        /*      print_minor_name(hd, minor);*/
        !            92: }
        !            93: 
        !            94: static inline int is_extended_partition(struct partition *p)
        !            95: {
        !            96:        return (p->sys_ind == DOS_EXTENDED_PARTITION ||
        !            97:                p->sys_ind == LINUX_EXTENDED_PARTITION);
        !            98: }
        !            99: 
        !           100: #ifdef CONFIG_MSDOS_PARTITION
        !           101: /*
        !           102:  * Create devices for each logical partition in an extended partition.
        !           103:  * The logical partitions form a linked list, with each entry being
        !           104:  * a partition table with two entries.  The first entry
        !           105:  * is the real data partition (with a start relative to the partition
        !           106:  * table start).  The second is a pointer to the next logical partition
        !           107:  * (with a start relative to the entire extended partition).
        !           108:  * We do not create a Linux partition for the partition tables, but
        !           109:  * only for the actual data partitions.
        !           110:  */
        !           111: 
        !           112: static void extended_partition(struct gendisk *hd, kdev_t dev)
        !           113: {
        !           114:        struct buffer_head *bh;
        !           115:        struct partition *p;
        !           116:        unsigned long first_sector, first_size, this_sector, this_size;
        !           117:        int mask = (1 << hd->minor_shift) - 1;
        !           118:        int i;
        !           119: 
        !           120:        first_sector = hd->part[MINOR(dev)].start_sect;
        !           121:        first_size = hd->part[MINOR(dev)].nr_sects;
        !           122:        this_sector = first_sector;
        !           123: 
        !           124:        while (1) {
        !           125:                if ((current_minor & mask) == 0)
        !           126:                        return;
        !           127:                if (!(bh = bread(dev,0,1024)))
        !           128:                        return;
        !           129:          /*
        !           130:           * This block is from a device that we're about to stomp on.
        !           131:           * So make sure nobody thinks this block is usable.
        !           132:           */
        !           133:                bh->b_state = 0;
        !           134: 
        !           135:                if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
        !           136:                        goto done;
        !           137: 
        !           138:                p = (struct partition *) (0x1BE + bh->b_data);
        !           139: 
        !           140:                this_size = hd->part[MINOR(dev)].nr_sects;
        !           141: 
        !           142:                /*
        !           143:                 * Usually, the first entry is the real data partition,
        !           144:                 * the 2nd entry is the next extended partition, or empty,
        !           145:                 * and the 3rd and 4th entries are unused.
        !           146:                 * However, DRDOS sometimes has the extended partition as
        !           147:                 * the first entry (when the data partition is empty),
        !           148:                 * and OS/2 seems to use all four entries.
        !           149:                 */
        !           150: 
        !           151:                /* 
        !           152:                 * First process the data partition(s)
        !           153:                 */
        !           154:                for (i=0; i<4; i++, p++) {
        !           155:                    if (!NR_SECTS(p) || is_extended_partition(p))
        !           156:                      continue;
        !           157: 
        !           158:                    /* Check the 3rd and 4th entries -
        !           159:                       these sometimes contain random garbage */
        !           160:                    if (i >= 2
        !           161:                        && START_SECT(p) + NR_SECTS(p) > this_size
        !           162:                        && (this_sector + START_SECT(p) < first_sector ||
        !           163:                            this_sector + START_SECT(p) + NR_SECTS(p) >
        !           164:                             first_sector + first_size))
        !           165:                      continue;
        !           166: 
        !           167:                    add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
        !           168:                    current_minor++;
        !           169:                    if ((current_minor & mask) == 0)
        !           170:                      goto done;
        !           171:                }
        !           172:                /*
        !           173:                 * Next, process the (first) extended partition, if present.
        !           174:                 * (So far, there seems to be no reason to make
        !           175:                 *  extended_partition()  recursive and allow a tree
        !           176:                 *  of extended partitions.)
        !           177:                 * It should be a link to the next logical partition.
        !           178:                 * Create a minor for this just long enough to get the next
        !           179:                 * partition table.  The minor will be reused for the next
        !           180:                 * data partition.
        !           181:                 */
        !           182:                p -= 4;
        !           183:                for (i=0; i<4; i++, p++)
        !           184:                  if(NR_SECTS(p) && is_extended_partition(p))
        !           185:                    break;
        !           186:                if (i == 4)
        !           187:                  goto done;     /* nothing left to do */
        !           188: 
        !           189:                hd->part[current_minor].nr_sects = NR_SECTS(p);
        !           190:                hd->part[current_minor].start_sect = first_sector + START_SECT(p);
        !           191:                this_sector = first_sector + START_SECT(p);
        !           192:                dev = MKDEV(hd->major, current_minor);
        !           193:                brelse(bh);
        !           194:        }
        !           195: done:
        !           196:        brelse(bh);
        !           197: }
        !           198: 
        !           199: static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
        !           200: {
        !           201:        int i, minor = current_minor;
        !           202:        struct buffer_head *bh;
        !           203:        struct partition *p;
        !           204:        unsigned char *data;
        !           205:        int mask = (1 << hd->minor_shift) - 1;
        !           206: #ifdef CONFIG_BLK_DEV_IDE
        !           207:        int tested_for_xlate = 0;
        !           208: 
        !           209: read_mbr:
        !           210: #endif
        !           211:        if (!(bh = bread(dev,0,1024))) {
        !           212:                printk(" unable to read partition table\n");
        !           213:                return -1;
        !           214:        }
        !           215:        data = bh->b_data;
        !           216:        /* In some cases we modify the geometry    */
        !           217:        /*  of the drive (below), so ensure that   */
        !           218:        /*  nobody else tries to re-use this data. */
        !           219:        bh->b_state = 0;
        !           220: #ifdef CONFIG_BLK_DEV_IDE
        !           221: check_table:
        !           222: #endif
        !           223:        if (*(unsigned short *)  (0x1fe + data) != 0xAA55) {
        !           224:                brelse(bh);
        !           225:                return 0;
        !           226:        }
        !           227:        p = (struct partition *) (0x1be + data);
        !           228: 
        !           229: #ifdef CONFIG_BLK_DEV_IDE
        !           230:        if (!tested_for_xlate++) {      /* Do this only once per disk */
        !           231:                /*
        !           232:                 * Look for various forms of IDE disk geometry translation
        !           233:                 */
        !           234:                extern int ide_xlate_1024(kdev_t, int, const char *);
        !           235:                unsigned int sig = *(unsigned short *)(data + 2);
        !           236:                if (p->sys_ind == EZD_PARTITION) {
        !           237:                        /*
        !           238:                         * The remainder of the disk must be accessed using
        !           239:                         * a translated geometry that reduces the number of 
        !           240:                         * apparent cylinders to less than 1024 if possible.
        !           241:                         *
        !           242:                         * ide_xlate_1024() will take care of the necessary
        !           243:                         * adjustments to fool fdisk/LILO and partition check.
        !           244:                         */
        !           245:                        if (ide_xlate_1024(dev, -1, " [EZD]")) {
        !           246:                                data += 512;
        !           247:                                goto check_table;
        !           248:                        }
        !           249:                } else if (p->sys_ind == DM6_PARTITION) {
        !           250: 
        !           251:                        /*
        !           252:                         * Everything on the disk is offset by 63 sectors,
        !           253:                         * including a "new" MBR with its own partition table,
        !           254:                         * and the remainder of the disk must be accessed using
        !           255:                         * a translated geometry that reduces the number of 
        !           256:                         * apparent cylinders to less than 1024 if possible.
        !           257:                         *
        !           258:                         * ide_xlate_1024() will take care of the necessary
        !           259:                         * adjustments to fool fdisk/LILO and partition check.
        !           260:                         */
        !           261:                        if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
        !           262:                                brelse(bh);
        !           263:                                goto read_mbr;  /* start over with new MBR */
        !           264:                        }
        !           265:                } else if (sig <= 0x1ae && *(unsigned short *)(data + sig) == 0x55AA
        !           266:                         && (1 & *(unsigned char *)(data + sig + 2)) ) 
        !           267:                {
        !           268:                        /*
        !           269:                         * DM6 signature in MBR, courtesy of OnTrack
        !           270:                         */
        !           271:                        (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
        !           272:                } else if (p->sys_ind == DM6_AUX1PARTITION || p->sys_ind == DM6_AUX3PARTITION) {
        !           273:                        /*
        !           274:                         * DM6 on other than the first (boot) drive
        !           275:                         */
        !           276:                        (void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
        !           277:                } else {
        !           278:                        /*
        !           279:                         * Examine the partition table for common translations.
        !           280:                         * This is necessary for drives for situations where
        !           281:                         * the translated geometry is unavailable from the BIOS.
        !           282:                         */
        !           283:                        for (i = 0; i < 4 ; i++) {
        !           284:                                struct partition *q = &p[i];
        !           285:                                if (NR_SECTS(q) && q->sector == 1 && q->end_sector == 63) {
        !           286:                                        unsigned int heads = q->end_head + 1;
        !           287:                                        if (heads == 32 || heads == 64 || heads == 128) {
        !           288: 
        !           289:                                                (void) ide_xlate_1024(dev, heads, " [PTBL]");
        !           290:                                                break;
        !           291:                                        }
        !           292:                                }
        !           293:                        }
        !           294:                }
        !           295:        }
        !           296: #endif /* CONFIG_BLK_DEV_IDE */
        !           297: 
        !           298:        current_minor += 4;  /* first "extra" minor (for extended partitions) */
        !           299:        for (i=1 ; i<=4 ; minor++,i++,p++) {
        !           300:                if (!NR_SECTS(p))
        !           301:                        continue;
        !           302:                add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
        !           303:                if (is_extended_partition(p)) {
        !           304:                  /*                    printk(" <");*/
        !           305:                        /*
        !           306:                         * If we are rereading the partition table, we need
        !           307:                         * to set the size of the partition so that we will
        !           308:                         * be able to bread the block containing the extended
        !           309:                         * partition info.
        !           310:                         */
        !           311:                        hd->sizes[minor] = hd->part[minor].nr_sects 
        !           312:                                >> (BLOCK_SIZE_BITS - 9);
        !           313:                        extended_partition(hd, MKDEV(hd->major, minor));
        !           314:                        /*                      printk(" >");*/
        !           315:                        /* prevent someone doing mkfs or mkswap on an
        !           316:                           extended partition, but leave room for LILO */
        !           317:                        if (hd->part[minor].nr_sects > 2)
        !           318:                                hd->part[minor].nr_sects = 2;
        !           319:                }
        !           320:        }
        !           321:        /*
        !           322:         *  Check for old-style Disk Manager partition table
        !           323:         */
        !           324:        if (*(unsigned short *) (data+0xfc) == 0x55AA) {
        !           325:                p = (struct partition *) (0x1be + data);
        !           326:                for (i = 4 ; i < 16 ; i++, current_minor++) {
        !           327:                        p--;
        !           328:                        if ((current_minor & mask) == 0)
        !           329:                                break;
        !           330:                        if (!(START_SECT(p) && NR_SECTS(p)))
        !           331:                                continue;
        !           332:                        add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
        !           333:                }
        !           334:        }
        !           335:        /*      printk("\n");*/
        !           336:        brelse(bh);
        !           337:        return 1;
        !           338: }
        !           339: 
        !           340: #endif /* CONFIG_MSDOS_PARTITION */
        !           341: 
        !           342: #ifdef CONFIG_OSF_PARTITION
        !           343: 
        !           344: static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
        !           345: {
        !           346:        int i;
        !           347:        int mask = (1 << hd->minor_shift) - 1;
        !           348:        struct buffer_head *bh;
        !           349:        struct disklabel {
        !           350:                u32 d_magic;
        !           351:                u16 d_type,d_subtype;
        !           352:                u8 d_typename[16];
        !           353:                u8 d_packname[16];
        !           354:                u32 d_secsize;
        !           355:                u32 d_nsectors;
        !           356:                u32 d_ntracks;
        !           357:                u32 d_ncylinders;
        !           358:                u32 d_secpercyl;
        !           359:                u32 d_secprtunit;
        !           360:                u16 d_sparespertrack;
        !           361:                u16 d_sparespercyl;
        !           362:                u32 d_acylinders;
        !           363:                u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
        !           364:                u32 d_headswitch, d_trkseek, d_flags;
        !           365:                u32 d_drivedata[5];
        !           366:                u32 d_spare[5];
        !           367:                u32 d_magic2;
        !           368:                u16 d_checksum;
        !           369:                u16 d_npartitions;
        !           370:                u32 d_bbsize, d_sbsize;
        !           371:                struct d_partition {
        !           372:                        u32 p_size;
        !           373:                        u32 p_offset;
        !           374:                        u32 p_fsize;
        !           375:                        u8  p_fstype;
        !           376:                        u8  p_frag;
        !           377:                        u16 p_cpg;
        !           378:                } d_partitions[8];
        !           379:        } * label;
        !           380:        struct d_partition * partition;
        !           381: #define DISKLABELMAGIC (0x82564557UL)
        !           382: 
        !           383:        if (!(bh = bread(dev,0,1024))) {
        !           384:                printk("unable to read partition table\n");
        !           385:                return -1;
        !           386:        }
        !           387:        label = (struct disklabel *) (bh->b_data+64);
        !           388:        partition = label->d_partitions;
        !           389:        if (label->d_magic != DISKLABELMAGIC) {
        !           390:                printk("magic: %08x\n", label->d_magic);
        !           391:                brelse(bh);
        !           392:                return 0;
        !           393:        }
        !           394:        if (label->d_magic2 != DISKLABELMAGIC) {
        !           395:                printk("magic2: %08x\n", label->d_magic2);
        !           396:                brelse(bh);
        !           397:                return 0;
        !           398:        }
        !           399:        for (i = 0 ; i < label->d_npartitions; i++, partition++) {
        !           400:                if ((current_minor & mask) == 0)
        !           401:                        break;
        !           402:                if (partition->p_size)
        !           403:                        add_partition(hd, current_minor,
        !           404:                                first_sector+partition->p_offset,
        !           405:                                partition->p_size);
        !           406:                current_minor++;
        !           407:        }
        !           408:        /*      printk("\n");*/
        !           409:        brelse(bh);
        !           410:        return 1;
        !           411: }
        !           412: 
        !           413: #endif /* CONFIG_OSF_PARTITION */
        !           414: 
        !           415: #ifdef CONFIG_SUN_PARTITION
        !           416: 
        !           417: static int sun_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
        !           418: {
        !           419:        int i, csum;
        !           420:        unsigned short *ush;
        !           421:        struct buffer_head *bh;
        !           422:        struct sun_disklabel {
        !           423:                unsigned char info[128];   /* Informative text string */
        !           424:                unsigned char spare[292];  /* Boot information etc. */
        !           425:                unsigned short rspeed;     /* Disk rotational speed */
        !           426:                unsigned short pcylcount;  /* Physical cylinder count */
        !           427:                unsigned short sparecyl;   /* extra sects per cylinder */
        !           428:                unsigned char spare2[4];   /* More magic... */
        !           429:                unsigned short ilfact;     /* Interleave factor */
        !           430:                unsigned short ncyl;       /* Data cylinder count */
        !           431:                unsigned short nacyl;      /* Alt. cylinder count */
        !           432:                unsigned short ntrks;      /* Tracks per cylinder */
        !           433:                unsigned short nsect;      /* Sectors per track */
        !           434:                unsigned char spare3[4];   /* Even more magic... */
        !           435:                struct sun_partition {
        !           436:                        unsigned long start_cylinder;
        !           437:                        unsigned long num_sectors;
        !           438:                } partitions[8];
        !           439:                unsigned short magic;      /* Magic number */
        !           440:                unsigned short csum;       /* Label xor'd checksum */
        !           441:        } * label;              
        !           442:        struct sun_partition *p;
        !           443:        unsigned long spc;
        !           444: #define SUN_LABEL_MAGIC  0xDABE
        !           445: 
        !           446:        if(!(bh = bread(dev, 0, 1024))) {
        !           447:                printk("Dev %d: unable to read partition table\n", dev);
        !           448:                return -1;
        !           449:        }
        !           450:        label = (struct sun_disklabel *) bh->b_data;
        !           451:        p = label->partitions;
        !           452:        if(label->magic != SUN_LABEL_MAGIC) {
        !           453:                printk("Dev %d Sun disklabel: bad magic %08x\n", dev, label->magic);
        !           454:                brelse(bh);
        !           455:                return 0;
        !           456:        }
        !           457:        /* Look at the checksum */
        !           458:        ush = ((unsigned short *) (label+1)) - 1;
        !           459:        for(csum = 0; ush >= ((unsigned short *) label);)
        !           460:                csum ^= *ush--;
        !           461:        if(csum) {
        !           462:                printk("Dev %d Sun disklabel: Csum bad, label corrupted\n", dev);
        !           463:                brelse(bh);
        !           464:                return 0;
        !           465:        }
        !           466:        /* All Sun disks have 8 partition entries */
        !           467:        spc = (label->ntrks * label->nsect);
        !           468:        for(i=0; i < 8; i++, p++) {
        !           469:                unsigned long st_sector;
        !           470: 
        !           471:                /* We register all partitions, even if zero size, so that
        !           472:                 * the minor numbers end up ok as per SunOS interpretation.
        !           473:                 */
        !           474:                st_sector = first_sector + (p->start_cylinder * spc);
        !           475:                add_partition(hd, current_minor, st_sector, p->num_sectors);
        !           476:                current_minor++;
        !           477:        }
        !           478:        /*      printk("\n");*/
        !           479:        brelse(bh);
        !           480:        return 1;
        !           481: }
        !           482: 
        !           483: #endif /* CONFIG_SUN_PARTITION */
        !           484: 
        !           485: static void check_partition(struct gendisk *hd, kdev_t dev)
        !           486: {
        !           487:        static int first_time = 1;
        !           488:        unsigned long first_sector;
        !           489: 
        !           490:        /*      if (first_time)
        !           491:                printk("Partition check:\n");*/
        !           492:        first_time = 0;
        !           493:        first_sector = hd->part[MINOR(dev)].start_sect;
        !           494: 
        !           495:        /*
        !           496:         * This is a kludge to allow the partition check to be
        !           497:         * skipped for specific drives (e.g. IDE cd-rom drives)
        !           498:         */
        !           499:        if ((int)first_sector == -1) {
        !           500:                hd->part[MINOR(dev)].start_sect = 0;
        !           501:                return;
        !           502:        }
        !           503: 
        !           504:        /*      printk(" ");
        !           505:        print_minor_name(hd, MINOR(dev));*/
        !           506: #ifdef CONFIG_MSDOS_PARTITION
        !           507:        if (msdos_partition(hd, dev, first_sector))
        !           508:                return;
        !           509: #endif
        !           510: #ifdef CONFIG_OSF_PARTITION
        !           511:        if (osf_partition(hd, dev, first_sector))
        !           512:                return;
        !           513: #endif
        !           514: #ifdef CONFIG_SUN_PARTITION
        !           515:        if(sun_partition(hd, dev, first_sector))
        !           516:                return;
        !           517: #endif
        !           518:        printk(" unknown partition table\n");
        !           519: }
        !           520: 
        !           521: /* This function is used to re-read partition tables for removable disks.
        !           522:    Much of the cleanup from the old partition tables should have already been
        !           523:    done */
        !           524: 
        !           525: /* This function will re-read the partition tables for a given device,
        !           526: and set things back up again.  There are some important caveats,
        !           527: however.  You must ensure that no one is using the device, and no one
        !           528: can start using the device while this function is being executed. */
        !           529: 
        !           530: void resetup_one_dev(struct gendisk *dev, int drive)
        !           531: {
        !           532:        int i;
        !           533:        int first_minor = drive << dev->minor_shift;
        !           534:        int end_minor   = first_minor + dev->max_p;
        !           535: 
        !           536:        blk_size[dev->major] = NULL;
        !           537:        current_minor = 1 + first_minor;
        !           538:        check_partition(dev, MKDEV(dev->major, first_minor));
        !           539: 
        !           540:        /*
        !           541:         * We need to set the sizes array before we will be able to access
        !           542:         * any of the partitions on this device.
        !           543:         */
        !           544:        if (dev->sizes != NULL) {       /* optional safeguard in ll_rw_blk.c */
        !           545:                for (i = first_minor; i < end_minor; i++)
        !           546:                        dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
        !           547:                blk_size[dev->major] = dev->sizes;
        !           548:        }
        !           549: }
        !           550: 
        !           551: static void setup_dev(struct gendisk *dev)
        !           552: {
        !           553:        int i, drive;
        !           554:        int end_minor   = dev->max_nr * dev->max_p;
        !           555: 
        !           556:        blk_size[dev->major] = NULL;
        !           557:        for (i = 0 ; i < end_minor; i++) {
        !           558:                dev->part[i].start_sect = 0;
        !           559:                dev->part[i].nr_sects = 0;
        !           560:        }
        !           561:        dev->init(dev); 
        !           562:        for (drive = 0 ; drive < dev->nr_real ; drive++) {
        !           563:                int first_minor = drive << dev->minor_shift;
        !           564:                current_minor = 1 + first_minor;
        !           565:                check_partition(dev, MKDEV(dev->major, first_minor));
        !           566:        }
        !           567:        if (dev->sizes != NULL) {       /* optional safeguard in ll_rw_blk.c */
        !           568:                for (i = 0; i < end_minor; i++)
        !           569:                        dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
        !           570:                blk_size[dev->major] = dev->sizes;
        !           571:        }
        !           572: }
        !           573: 
        !           574: void device_setup(void)
        !           575: {
        !           576:        extern void console_map_init(void);
        !           577:        struct gendisk *p;
        !           578:        int nr=0;
        !           579: #ifdef MACH
        !           580:        extern int linux_intr_pri;
        !           581: 
        !           582:        linux_intr_pri = SPL5;
        !           583: #endif
        !           584: 
        !           585: #ifndef MACH
        !           586:        chr_dev_init();
        !           587: #endif
        !           588:        blk_dev_init();
        !           589:        sti();
        !           590: #ifdef CONFIG_SCSI
        !           591:        scsi_dev_init();
        !           592: #endif
        !           593: #ifdef CONFIG_INET
        !           594: #ifdef MACH
        !           595:        linux_intr_pri = SPL6;
        !           596: #endif
        !           597:        net_dev_init();
        !           598: #endif
        !           599: #ifndef MACH
        !           600:        console_map_init();
        !           601: #endif
        !           602: 
        !           603:        for (p = gendisk_head ; p ; p=p->next) {
        !           604:                setup_dev(p);
        !           605:                nr += p->nr_real;
        !           606:        }
        !           607: #ifdef CONFIG_BLK_DEV_RAM
        !           608:        rd_load();
        !           609: #endif
        !           610: }

unix.superglobalmegacorp.com

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