Annotation of linux/kernel/blk_drv/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: /*
        !             9:  *  Thanks to Branko Lankester, [email protected], who found a bug
        !            10:  *  in the early extended-partition checks and added DM partitions
        !            11:  */
        !            12: 
        !            13: #include <linux/config.h>
        !            14: #include <linux/fs.h>
        !            15: #include <linux/genhd.h>
        !            16: #include <linux/kernel.h>
        !            17: struct gendisk *gendisk_head = NULL;
        !            18: 
        !            19: static int current_minor = 0;
        !            20: extern int *blk_size[];
        !            21: /*
        !            22:  * Create devices for each logical partition in an extended partition.
        !            23:  * The logical partitions form a linked list, with each entry being
        !            24:  * a partition table with two entries.  The first entry
        !            25:  * is the real data partition (with a start relative to the partition
        !            26:  * table start).  The second is a pointer to the next logical partition
        !            27:  * (with a start relative to the entire extended partition).
        !            28:  * We do not create a Linux partition for the partition tables, but
        !            29:  * only for the actual data partitions.
        !            30:  */
        !            31: 
        !            32: static void extended_partition(struct gendisk *hd, int dev)
        !            33: {
        !            34:        struct buffer_head *bh;
        !            35:        struct partition *p;
        !            36:        unsigned long first_sector, this_sector;
        !            37:        int mask = (1 << hd->minor_shift) - 1;
        !            38: 
        !            39:        first_sector = hd->part[MINOR(dev)].start_sect;
        !            40:        this_sector = first_sector;
        !            41: 
        !            42:        while (1) {
        !            43:                if ((current_minor & mask) >= (4 + hd->max_p))
        !            44:                        return;
        !            45:                if (!(bh = bread(dev,0,1024))) {
        !            46:                        printk("Unable to read partition table of device %04x\n",dev);
        !            47:                        return;
        !            48:                }
        !            49:          /*
        !            50:           * This block is from a device that we're about to stomp on.
        !            51:           * So make sure nobody thinks this block is usable.
        !            52:           */
        !            53:                bh->b_dirt=0;
        !            54:                bh->b_uptodate=0;
        !            55:                if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
        !            56:                        p = 0x1BE + (void *)bh->b_data;
        !            57:                /*
        !            58:                 * Process the first entry, which should be the real
        !            59:                 * data partition.
        !            60:                 */
        !            61:                        if (p->sys_ind == EXTENDED_PARTITION ||
        !            62:                            !(hd->part[current_minor].nr_sects = p->nr_sects))
        !            63:                                goto done;  /* shouldn't happen */
        !            64:                        hd->part[current_minor].start_sect = this_sector + p->start_sect;
        !            65:                        printk("  Logical part %d start %d size %d end %d\n\r", 
        !            66:                               current_minor, hd->part[current_minor].start_sect, 
        !            67:                               hd->part[current_minor].nr_sects,
        !            68:                               hd->part[current_minor].start_sect + 
        !            69:                               hd->part[current_minor].nr_sects - 1);
        !            70:                        current_minor++;
        !            71:                        p++;
        !            72:                /*
        !            73:                 * Process the second entry, which should be a link
        !            74:                 * to the next logical partition.  Create a minor
        !            75:                 * for this just long enough to get the next partition
        !            76:                 * table.  The minor will be reused for the real
        !            77:                 * data partition.
        !            78:                 */
        !            79:                        if (p->sys_ind != EXTENDED_PARTITION ||
        !            80:                            !(hd->part[current_minor].nr_sects = p->nr_sects))
        !            81:                                goto done;  /* no more logicals in this partition */
        !            82:                        hd->part[current_minor].start_sect = first_sector + p->start_sect;
        !            83:                        this_sector = first_sector + p->start_sect;
        !            84:                        dev = ((hd->major) << 8) | current_minor;
        !            85:                        brelse(bh);
        !            86:                } else
        !            87:                        goto done;
        !            88:        }
        !            89: done:
        !            90:        brelse(bh);
        !            91: }
        !            92: 
        !            93: static void check_partition(struct gendisk *hd, unsigned int dev)
        !            94: {
        !            95:        int i, minor = current_minor;
        !            96:        struct buffer_head *bh;
        !            97:        struct partition *p;
        !            98:        unsigned long first_sector;
        !            99: 
        !           100:        first_sector = hd->part[MINOR(dev)].start_sect;
        !           101: 
        !           102:        if (!(bh = bread(dev,0,1024))) {
        !           103:                printk("Unable to read partition table of device %04x\n",dev);
        !           104:                return;
        !           105:        }
        !           106:        printk("%s%d :\n\r", hd->major_name, minor >> hd->minor_shift);
        !           107:        current_minor += 4;  /* first "extra" minor */
        !           108:        if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
        !           109:                p = 0x1BE + (void *)bh->b_data;
        !           110:                for (i=1 ; i<=4 ; minor++,i++,p++) {
        !           111:                        if (!(hd->part[minor].nr_sects = p->nr_sects))
        !           112:                                continue;
        !           113:                        hd->part[minor].start_sect = first_sector + p->start_sect;
        !           114:                        printk(" part %d start %d size %d end %d \n\r", i, 
        !           115:                               hd->part[minor].start_sect, hd->part[minor].nr_sects, 
        !           116:                               hd->part[minor].start_sect + hd->part[minor].nr_sects - 1);
        !           117:                        if ((current_minor & 0x3f) >= 60)
        !           118:                                continue;
        !           119:                        if (p->sys_ind == EXTENDED_PARTITION) {
        !           120:                                extended_partition(hd, (hd->major << 8) | minor);
        !           121:                        }
        !           122:                }
        !           123:                /*
        !           124:                 * check for Disk Manager partition table
        !           125:                 */
        !           126:                if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
        !           127:                        p = 0x1BE + (void *)bh->b_data;
        !           128:                        for (i = 4 ; i < 16 ; i++, current_minor++) {
        !           129:                                p--;
        !           130:                                if ((current_minor & 0x3f) >= 60)
        !           131:                                        break;
        !           132:                                if (!(p->start_sect && p->nr_sects))
        !           133:                                        continue;
        !           134:                                hd->part[current_minor].start_sect = p->start_sect;
        !           135:                                hd->part[current_minor].nr_sects = p->nr_sects;
        !           136:                                printk(" DM part %d start %d size %d end %d\n\r",
        !           137:                                       current_minor,
        !           138:                                       hd->part[current_minor].start_sect, 
        !           139:                                       hd->part[current_minor].nr_sects,
        !           140:                                       hd->part[current_minor].start_sect + 
        !           141:                                       hd->part[current_minor].nr_sects - 1);
        !           142:                        }
        !           143:                }
        !           144:        } else
        !           145:                printk("Bad partition table on dev %04x\n",dev);
        !           146:        brelse(bh);
        !           147: }
        !           148: 
        !           149: static void setup_dev(struct gendisk *dev)
        !           150: {
        !           151:        int i;
        !           152:        int j = dev->max_nr * dev->max_p;
        !           153:        int major = dev->major << 8;
        !           154:        int drive;
        !           155:        
        !           156: 
        !           157:        for (i = 0 ; i < j; i++)  {
        !           158:                dev->part[i].start_sect = 0;
        !           159:                dev->part[i].nr_sects = 0;
        !           160:        }
        !           161:        dev->init();    
        !           162:        for (drive=0 ; drive<dev->nr_real ; drive++) {
        !           163:                current_minor = 1+(drive<<dev->minor_shift);
        !           164:                check_partition(dev, major+(drive<<dev->minor_shift));
        !           165:        }
        !           166:        for (i=0 ; i < j ; i++)
        !           167:                dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
        !           168:        blk_size[dev->major] = dev->sizes;
        !           169: }
        !           170:        
        !           171: /* This may be used only once, enforced by 'static int callable' */
        !           172: int sys_setup(void * BIOS)
        !           173: {
        !           174:        static int callable = 1;
        !           175:        struct gendisk *p;
        !           176:        int nr=0;
        !           177: 
        !           178:        if (!callable)
        !           179:                return -1;
        !           180:        callable = 0;
        !           181: 
        !           182:        for (p = gendisk_head ; p ; p=p->next) {
        !           183:                setup_dev(p);
        !           184:                nr += p->nr_real;
        !           185:        }
        !           186:                
        !           187:        if (nr)
        !           188:                printk("Partition table%s ok.\n\r",(nr>1)?"s":"");
        !           189: 
        !           190: #ifdef RAMDISK
        !           191:        rd_load();
        !           192: #endif
        !           193:        mount_root();
        !           194:        return (0);
        !           195: }

unix.superglobalmegacorp.com

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