Annotation of linux/kernel/blk_drv/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: /*
                      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.