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. resetup_one_dev
  4. setup_dev
  5. 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 /* This function is used to re-read partition tables for removable disks.
 151    Much of the cleanup from the old partition tables should have already been
 152    done */
 153 
 154 /* This function will re-read the partition tables for a given device,
 155 and set things back up again.  There are some important caveats,
 156 however.  You must ensure that no one is using the device, and no one
 157 can start using the device while this function is being executed. */
 158 
 159 void resetup_one_dev(struct gendisk *dev, int drive)
     /* [previous][next][first][last][top][bottom][index][help] */
 160 {
 161         int i;
 162         int start = drive<<dev->minor_shift;
 163         int j = start + dev->max_p;
 164         int major = dev->major << 8;
 165 
 166         current_minor = 1+(drive<<dev->minor_shift);
 167         check_partition(dev, major+(drive<<dev->minor_shift));
 168 
 169         for (i=start ; i < j ; i++)
 170                 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
 171 }
 172 
 173 static void setup_dev(struct gendisk *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175         int i;
 176         int j = dev->max_nr * dev->max_p;
 177         int major = dev->major << 8;
 178         int drive;
 179         
 180 
 181         for (i = 0 ; i < j; i++)  {
 182                 dev->part[i].start_sect = 0;
 183                 dev->part[i].nr_sects = 0;
 184         }
 185         dev->init();    
 186         for (drive=0 ; drive<dev->nr_real ; drive++) {
 187                 current_minor = 1+(drive<<dev->minor_shift);
 188                 check_partition(dev, major+(drive<<dev->minor_shift));
 189         }
 190         for (i=0 ; i < j ; i++)
 191                 dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
 192         blk_size[dev->major] = dev->sizes;
 193 }
 194         
 195 /* This may be used only once, enforced by 'static int callable' */
 196 int sys_setup(void * BIOS)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198         static int callable = 1;
 199         struct gendisk *p;
 200         int nr=0;
 201 
 202         if (!callable)
 203                 return -1;
 204         callable = 0;
 205 
 206         for (p = gendisk_head ; p ; p=p->next) {
 207                 setup_dev(p);
 208                 nr += p->nr_real;
 209         }
 210                 
 211         if (nr)
 212                 printk("Partition table%s ok.\n\r",(nr>1)?"s":"");
 213 
 214 #ifdef RAMDISK
 215         rd_load();
 216 #endif
 217         mount_root();
 218         return (0);
 219 }

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