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                                mask & 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         int mask = (1 << hd->minor_shift) - 1;
 100 
 101         first_sector = hd->part[MINOR(dev)].start_sect;
 102 
 103         if (!(bh = bread(dev,0,1024))) {
 104                 printk("Unable to read partition table of device %04x\n",dev);
 105                 return;
 106         }
 107         printk("%s%c :\n\r", hd->major_name, 'a'+(minor >> hd->minor_shift));
 108         current_minor += 4;  /* first "extra" minor */
 109         if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
 110                 p = 0x1BE + (void *)bh->b_data;
 111                 for (i=1 ; i<=4 ; minor++,i++,p++) {
 112                         if (!(hd->part[minor].nr_sects = p->nr_sects))
 113                                 continue;
 114                         hd->part[minor].start_sect = first_sector + p->start_sect;
 115                         printk(" part %d start %d size %d end %d \n\r", i, 
 116                                hd->part[minor].start_sect, hd->part[minor].nr_sects, 
 117                                hd->part[minor].start_sect + hd->part[minor].nr_sects - 1);
 118                         if ((current_minor & 0x3f) >= 60)
 119                                 continue;
 120                         if (p->sys_ind == EXTENDED_PARTITION) {
 121                                 extended_partition(hd, (hd->major << 8) | minor);
 122                         }
 123                 }
 124                 /*
 125                  * check for Disk Manager partition table
 126                  */
 127                 if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
 128                         p = 0x1BE + (void *)bh->b_data;
 129                         for (i = 4 ; i < 16 ; i++, current_minor++) {
 130                                 p--;
 131                                 if ((current_minor & mask) >= mask-2)
 132                                         break;
 133                                 if (!(p->start_sect && p->nr_sects))
 134                                         continue;
 135                                 hd->part[current_minor].start_sect = p->start_sect;
 136                                 hd->part[current_minor].nr_sects = p->nr_sects;
 137                                 printk(" DM part %d start %d size %d end %d\n\r",
 138                                        current_minor & mask,
 139                                        hd->part[current_minor].start_sect, 
 140                                        hd->part[current_minor].nr_sects,
 141                                        hd->part[current_minor].start_sect + 
 142                                        hd->part[current_minor].nr_sects - 1);
 143                         }
 144                 }
 145         } else
 146                 printk("Bad partition table on dev %04x\n",dev);
 147         brelse(bh);
 148 }
 149 
 150 static void setup_dev(struct gendisk *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 151 {
 152         int i;
 153         int j = dev->max_nr * dev->max_p;
 154         int major = dev->major << 8;
 155         int drive;
 156         
 157 
 158         for (i = 0 ; i < j; i++)  {
 159                 dev->part[i].start_sect = 0;
 160                 dev->part[i].nr_sects = 0;
 161         }
 162         dev->init();    
 163         for (drive=0 ; drive<dev->nr_real ; drive++) {
 164                 current_minor = 1+(drive<<dev->minor_shift);
 165                 check_partition(dev, major+(drive<<dev->minor_shift));
 166         }
 167         for (i=0 ; i < j ; i++)
 168                 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
 169         blk_size[dev->major] = dev->sizes;
 170 }
 171         
 172 /* This may be used only once, enforced by 'static int callable' */
 173 int sys_setup(void * BIOS)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175         static int callable = 1;
 176         struct gendisk *p;
 177         int nr=0;
 178 
 179         if (!callable)
 180                 return -1;
 181         callable = 0;
 182 
 183         for (p = gendisk_head ; p ; p=p->next) {
 184                 setup_dev(p);
 185                 nr += p->nr_real;
 186         }
 187                 
 188         if (nr)
 189                 printk("Partition table%s ok.\n\r",(nr>1)?"s":"");
 190 
 191 #ifdef RAMDISK
 192         rd_load();
 193 #endif
 194         mount_root();
 195         return (0);
 196 }

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