root/kernel/blk_drv/genhd.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. extended_partition
  2. check_partition
  3. setup_dev
  4. sys_setup

   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, lankeste@fwi.uva.nl, 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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */