root/drivers/block/genhd.c

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

DEFINITIONS

This source file includes following definitions.
  1. disk_name
  2. add_partition
  3. is_extended_partition
  4. extended_partition
  5. bsd_disklabel_partition
  6. msdos_partition
  7. osf_partition
  8. sun_partition
  9. check_partition
  10. resetup_one_dev
  11. setup_dev
  12. device_setup

   1 /*
   2  *  Code extracted from
   3  *  linux/kernel/hd.c
   4  *
   5  *  Copyright (C) 1991, 1992  Linus Torvalds
   6  *
   7  *
   8  *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
   9  *  in the early extended-partition checks and added DM partitions
  10  *
  11  *  Support for DiskManager v6.0x added by Mark Lord,
  12  *  with information provided by OnTrack.  This now works for linux fdisk
  13  *  and LILO, as well as loadlin and bootln.  Note that disks other than
  14  *  /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
  15  *
  16  *  More flexible handling of extended partitions - aeb, 950831
  17  *
  18  *  Check partition table on IDE disks for common CHS translations
  19  */
  20 
  21 #include <linux/config.h>
  22 #include <linux/fs.h>
  23 #include <linux/genhd.h>
  24 #include <linux/kernel.h>
  25 #include <linux/major.h>
  26 #include <linux/string.h>
  27 #ifdef CONFIG_BLK_DEV_INITRD
  28 #include <linux/blk.h>
  29 #endif
  30 
  31 #include <asm/system.h>
  32 
  33 #ifdef __alpha__
  34 /*
  35  * On the Alpha, we get unaligned access exceptions on
  36  *  p->nr_sects and p->start_sect, when the partition table
  37  *  is not on a 4-byte boundary, which is frequently the case.
  38  * This code uses unaligned load instructions to prevent
  39  *  such exceptions.
  40  */
  41 #include <asm/unaligned.h>
  42 #define NR_SECTS(p)     ldl_u(&p->nr_sects)
  43 #define START_SECT(p)   ldl_u(&p->start_sect)
  44 #else /* __alpha__ */
  45 #define NR_SECTS(p)     p->nr_sects
  46 #define START_SECT(p)   p->start_sect
  47 #endif /* __alpha__ */
  48 
  49 struct gendisk *gendisk_head = NULL;
  50 
  51 static int current_minor = 0;
  52 extern int *blk_size[];
  53 extern void rd_load(void);
  54 extern void initrd_load(void);
  55 
  56 extern int chr_dev_init(void);
  57 extern int blk_dev_init(void);
  58 extern int scsi_dev_init(void);
  59 extern int net_dev_init(void);
  60 
  61 /*
  62  * disk_name() is used by genhd.c and md.c.
  63  * It formats the devicename of the indicated disk
  64  * into the supplied buffer, and returns a pointer
  65  * to that same buffer (for convenience).
  66  */
  67 char *disk_name (struct gendisk *hd, int minor, char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         unsigned int part;
  70         const char *maj = hd->major_name;
  71         char unit = (minor >> hd->minor_shift) + 'a';
  72 
  73 #ifdef CONFIG_BLK_DEV_IDE
  74         /*
  75          * IDE devices use multiple major numbers, but the drives
  76          * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
  77          * This requires special handling here.
  78          */
  79         switch (hd->major) {
  80                 case IDE3_MAJOR:
  81                         unit += 2;
  82                 case IDE2_MAJOR:
  83                         unit += 2;
  84                 case IDE1_MAJOR:
  85                         unit += 2;
  86                 case IDE0_MAJOR:
  87                         maj = "hd";
  88         }
  89 #endif
  90         part = minor & ((1 << hd->minor_shift) - 1);
  91         if (part)
  92                 sprintf(buf, "%s%c%d", maj, unit, part);
  93         else
  94                 sprintf(buf, "%s%c", maj, unit);
  95         return buf;
  96 }
  97 
  98 static void add_partition (struct gendisk *hd, int minor, int start, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         char buf[8];
 101         hd->part[minor].start_sect = start;
 102         hd->part[minor].nr_sects   = size;
 103         printk(" %s", disk_name(hd, minor, buf));
 104 }
 105 
 106 static inline int is_extended_partition(struct partition *p)
     /* [previous][next][first][last][top][bottom][index][help] */
 107 {
 108         return (p->sys_ind == DOS_EXTENDED_PARTITION ||
 109                 p->sys_ind == LINUX_EXTENDED_PARTITION);
 110 }
 111 
 112 #ifdef CONFIG_MSDOS_PARTITION
 113 /*
 114  * Create devices for each logical partition in an extended partition.
 115  * The logical partitions form a linked list, with each entry being
 116  * a partition table with two entries.  The first entry
 117  * is the real data partition (with a start relative to the partition
 118  * table start).  The second is a pointer to the next logical partition
 119  * (with a start relative to the entire extended partition).
 120  * We do not create a Linux partition for the partition tables, but
 121  * only for the actual data partitions.
 122  */
 123 
 124 static void extended_partition(struct gendisk *hd, kdev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126         struct buffer_head *bh;
 127         struct partition *p;
 128         unsigned long first_sector, first_size, this_sector, this_size;
 129         int mask = (1 << hd->minor_shift) - 1;
 130         int i;
 131 
 132         first_sector = hd->part[MINOR(dev)].start_sect;
 133         first_size = hd->part[MINOR(dev)].nr_sects;
 134         this_sector = first_sector;
 135 
 136         while (1) {
 137                 if ((current_minor & mask) == 0)
 138                         return;
 139                 if (!(bh = bread(dev,0,1024)))
 140                         return;
 141           /*
 142            * This block is from a device that we're about to stomp on.
 143            * So make sure nobody thinks this block is usable.
 144            */
 145                 bh->b_state = 0;
 146 
 147                 if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
 148                         goto done;
 149 
 150                 p = (struct partition *) (0x1BE + bh->b_data);
 151 
 152                 this_size = hd->part[MINOR(dev)].nr_sects;
 153 
 154                 /*
 155                  * Usually, the first entry is the real data partition,
 156                  * the 2nd entry is the next extended partition, or empty,
 157                  * and the 3rd and 4th entries are unused.
 158                  * However, DRDOS sometimes has the extended partition as
 159                  * the first entry (when the data partition is empty),
 160                  * and OS/2 seems to use all four entries.
 161                  */
 162 
 163                 /* 
 164                  * First process the data partition(s)
 165                  */
 166                 for (i=0; i<4; i++, p++) {
 167                     if (!NR_SECTS(p) || is_extended_partition(p))
 168                       continue;
 169 
 170                     /* Check the 3rd and 4th entries -
 171                        these sometimes contain random garbage */
 172                     if (i >= 2
 173                         && START_SECT(p) + NR_SECTS(p) > this_size
 174                         && (this_sector + START_SECT(p) < first_sector ||
 175                             this_sector + START_SECT(p) + NR_SECTS(p) >
 176                              first_sector + first_size))
 177                       continue;
 178 
 179                     add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
 180                     current_minor++;
 181                     if ((current_minor & mask) == 0)
 182                       goto done;
 183                 }
 184                 /*
 185                  * Next, process the (first) extended partition, if present.
 186                  * (So far, there seems to be no reason to make
 187                  *  extended_partition()  recursive and allow a tree
 188                  *  of extended partitions.)
 189                  * It should be a link to the next logical partition.
 190                  * Create a minor for this just long enough to get the next
 191                  * partition table.  The minor will be reused for the next
 192                  * data partition.
 193                  */
 194                 p -= 4;
 195                 for (i=0; i<4; i++, p++)
 196                   if(NR_SECTS(p) && is_extended_partition(p))
 197                     break;
 198                 if (i == 4)
 199                   goto done;     /* nothing left to do */
 200 
 201                 hd->part[current_minor].nr_sects = NR_SECTS(p);
 202                 hd->part[current_minor].start_sect = first_sector + START_SECT(p);
 203                 this_sector = first_sector + START_SECT(p);
 204                 dev = MKDEV(hd->major, current_minor);
 205                 brelse(bh);
 206         }
 207 done:
 208         brelse(bh);
 209 }
 210 
 211 #ifdef CONFIG_BSD_DISKLABEL
 212 /* 
 213  * Create devices for BSD partitions listed in a disklabel, under a
 214  * dos-like partition. See extended_partition() for more information.
 215  */
 216 static void bsd_disklabel_partition(struct gendisk *hd, int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218         struct buffer_head *bh;
 219         struct bsd_disklabel *l;
 220         struct bsd_partition *p;
 221         int mask = (1 << hd->minor_shift) - 1;
 222 
 223         if (!(bh = bread(dev,0,1024)))
 224                 return;
 225         bh->b_state = 0;
 226         l = (struct bsd_disklabel *) (bh->b_data+512);
 227         if (l->d_magic != BSD_DISKMAGIC) {
 228                 brelse(bh);
 229                 return;
 230         }
 231 
 232         p = &l->d_partitions[0];
 233         while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
 234                 if ((current_minor & mask) >= (4 + hd->max_p))
 235                         break;
 236 
 237                 if (p->p_fstype != BSD_FS_UNUSED) {
 238                         add_partition(hd, current_minor, p->p_offset, p->p_size);
 239                         current_minor++;
 240                 }
 241                 p++;
 242         }
 243         brelse(bh);
 244 
 245 }
 246 #endif
 247 
 248 static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
     /* [previous][next][first][last][top][bottom][index][help] */
 249 {
 250         int i, minor = current_minor;
 251         struct buffer_head *bh;
 252         struct partition *p;
 253         unsigned char *data;
 254         int mask = (1 << hd->minor_shift) - 1;
 255 #ifdef CONFIG_BLK_DEV_IDE
 256         int tested_for_xlate = 0;
 257 
 258 read_mbr:
 259 #endif
 260         if (!(bh = bread(dev,0,1024))) {
 261                 printk(" unable to read partition table\n");
 262                 return -1;
 263         }
 264         data = bh->b_data;
 265         /* In some cases we modify the geometry    */
 266         /*  of the drive (below), so ensure that   */
 267         /*  nobody else tries to re-use this data. */
 268         bh->b_state = 0;
 269 #ifdef CONFIG_BLK_DEV_IDE
 270 check_table:
 271 #endif
 272         if (*(unsigned short *)  (0x1fe + data) != 0xAA55) {
 273                 brelse(bh);
 274                 return 0;
 275         }
 276         p = (struct partition *) (0x1be + data);
 277 
 278 #ifdef CONFIG_BLK_DEV_IDE
 279         if (!tested_for_xlate++) {      /* Do this only once per disk */
 280                 /*
 281                  * Look for various forms of IDE disk geometry translation
 282                  */
 283                 extern int ide_xlate_1024(kdev_t, int, const char *);
 284                 unsigned int sig = *(unsigned short *)(data + 2);
 285                 if (p->sys_ind == EZD_PARTITION) {
 286                         /*
 287                          * The remainder of the disk must be accessed using
 288                          * a translated geometry that reduces the number of 
 289                          * apparent cylinders to less than 1024 if possible.
 290                          *
 291                          * ide_xlate_1024() will take care of the necessary
 292                          * adjustments to fool fdisk/LILO and partition check.
 293                          */
 294                         if (ide_xlate_1024(dev, -1, " [EZD]")) {
 295                                 data += 512;
 296                                 goto check_table;
 297                         }
 298                 } else if (p->sys_ind == DM6_PARTITION) {
 299 
 300                         /*
 301                          * Everything on the disk is offset by 63 sectors,
 302                          * including a "new" MBR with its own partition table,
 303                          * and the remainder of the disk must be accessed using
 304                          * a translated geometry that reduces the number of 
 305                          * apparent cylinders to less than 1024 if possible.
 306                          *
 307                          * ide_xlate_1024() will take care of the necessary
 308                          * adjustments to fool fdisk/LILO and partition check.
 309                          */
 310                         if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
 311                                 brelse(bh);
 312                                 goto read_mbr;  /* start over with new MBR */
 313                         }
 314                 } else if (sig <= 0x1ae && *(unsigned short *)(data + sig) == 0x55AA
 315                          && (1 & *(unsigned char *)(data + sig + 2)) ) 
 316                 {
 317                         /*
 318                          * DM6 signature in MBR, courtesy of OnTrack
 319                          */
 320                         (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
 321                 } else if (p->sys_ind == DM6_AUX1PARTITION || p->sys_ind == DM6_AUX3PARTITION) {
 322                         /*
 323                          * DM6 on other than the first (boot) drive
 324                          */
 325                         (void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
 326                 } else {
 327                         /*
 328                          * Examine the partition table for common translations.
 329                          * This is necessary for drives for situations where
 330                          * the translated geometry is unavailable from the BIOS.
 331                          */
 332                         for (i = 0; i < 4 ; i++) {
 333                                 struct partition *q = &p[i];
 334                                 if (NR_SECTS(q) && q->sector == 1 && q->end_sector == 63) {
 335                                         unsigned int heads = q->end_head + 1;
 336                                         if (heads == 32 || heads == 64 || heads == 128) {
 337 
 338                                                 (void) ide_xlate_1024(dev, heads, " [PTBL]");
 339                                                 break;
 340                                         }
 341                                 }
 342                         }
 343                 }
 344         }
 345 #endif  /* CONFIG_BLK_DEV_IDE */
 346 
 347         current_minor += 4;  /* first "extra" minor (for extended partitions) */
 348         for (i=1 ; i<=4 ; minor++,i++,p++) {
 349                 if (!NR_SECTS(p))
 350                         continue;
 351                 add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
 352                 if (is_extended_partition(p)) {
 353                         printk(" <");
 354                         /*
 355                          * If we are rereading the partition table, we need
 356                          * to set the size of the partition so that we will
 357                          * be able to bread the block containing the extended
 358                          * partition info.
 359                          */
 360                         hd->sizes[minor] = hd->part[minor].nr_sects 
 361                                 >> (BLOCK_SIZE_BITS - 9);
 362                         extended_partition(hd, MKDEV(hd->major, minor));
 363                         printk(" >");
 364                         /* prevent someone doing mkfs or mkswap on an
 365                            extended partition, but leave room for LILO */
 366                         if (hd->part[minor].nr_sects > 2)
 367                                 hd->part[minor].nr_sects = 2;
 368                 }
 369 #ifdef CONFIG_BSD_DISKLABEL
 370                 if (p->sys_ind == BSD_PARTITION) {
 371                         printk(" <");
 372                         bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
 373                         printk(" >");
 374                 }
 375 #endif
 376         }
 377         /*
 378          *  Check for old-style Disk Manager partition table
 379          */
 380         if (*(unsigned short *) (data+0xfc) == 0x55AA) {
 381                 p = (struct partition *) (0x1be + data);
 382                 for (i = 4 ; i < 16 ; i++, current_minor++) {
 383                         p--;
 384                         if ((current_minor & mask) == 0)
 385                                 break;
 386                         if (!(START_SECT(p) && NR_SECTS(p)))
 387                                 continue;
 388                         add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
 389                 }
 390         }
 391         printk("\n");
 392         brelse(bh);
 393         return 1;
 394 }
 395 
 396 #endif /* CONFIG_MSDOS_PARTITION */
 397 
 398 #ifdef CONFIG_OSF_PARTITION
 399 
 400 static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
     /* [previous][next][first][last][top][bottom][index][help] */
 401 {
 402         int i;
 403         int mask = (1 << hd->minor_shift) - 1;
 404         struct buffer_head *bh;
 405         struct disklabel {
 406                 u32 d_magic;
 407                 u16 d_type,d_subtype;
 408                 u8 d_typename[16];
 409                 u8 d_packname[16];
 410                 u32 d_secsize;
 411                 u32 d_nsectors;
 412                 u32 d_ntracks;
 413                 u32 d_ncylinders;
 414                 u32 d_secpercyl;
 415                 u32 d_secprtunit;
 416                 u16 d_sparespertrack;
 417                 u16 d_sparespercyl;
 418                 u32 d_acylinders;
 419                 u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
 420                 u32 d_headswitch, d_trkseek, d_flags;
 421                 u32 d_drivedata[5];
 422                 u32 d_spare[5];
 423                 u32 d_magic2;
 424                 u16 d_checksum;
 425                 u16 d_npartitions;
 426                 u32 d_bbsize, d_sbsize;
 427                 struct d_partition {
 428                         u32 p_size;
 429                         u32 p_offset;
 430                         u32 p_fsize;
 431                         u8  p_fstype;
 432                         u8  p_frag;
 433                         u16 p_cpg;
 434                 } d_partitions[8];
 435         } * label;
 436         struct d_partition * partition;
 437 #define DISKLABELMAGIC (0x82564557UL)
 438 
 439         if (!(bh = bread(dev,0,1024))) {
 440                 printk("unable to read partition table\n");
 441                 return -1;
 442         }
 443         label = (struct disklabel *) (bh->b_data+64);
 444         partition = label->d_partitions;
 445         if (label->d_magic != DISKLABELMAGIC) {
 446                 printk("magic: %08x\n", label->d_magic);
 447                 brelse(bh);
 448                 return 0;
 449         }
 450         if (label->d_magic2 != DISKLABELMAGIC) {
 451                 printk("magic2: %08x\n", label->d_magic2);
 452                 brelse(bh);
 453                 return 0;
 454         }
 455         for (i = 0 ; i < label->d_npartitions; i++, partition++) {
 456                 if ((current_minor & mask) == 0)
 457                         break;
 458                 if (partition->p_size)
 459                         add_partition(hd, current_minor,
 460                                 first_sector+partition->p_offset,
 461                                 partition->p_size);
 462                 current_minor++;
 463         }
 464         printk("\n");
 465         brelse(bh);
 466         return 1;
 467 }
 468 
 469 #endif /* CONFIG_OSF_PARTITION */
 470 
 471 #ifdef CONFIG_SUN_PARTITION
 472 
 473 static int sun_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
     /* [previous][next][first][last][top][bottom][index][help] */
 474 {
 475         int i, csum;
 476         unsigned short *ush;
 477         struct buffer_head *bh;
 478         struct sun_disklabel {
 479                 unsigned char info[128];   /* Informative text string */
 480                 unsigned char spare[292];  /* Boot information etc. */
 481                 unsigned short rspeed;     /* Disk rotational speed */
 482                 unsigned short pcylcount;  /* Physical cylinder count */
 483                 unsigned short sparecyl;   /* extra sects per cylinder */
 484                 unsigned char spare2[4];   /* More magic... */
 485                 unsigned short ilfact;     /* Interleave factor */
 486                 unsigned short ncyl;       /* Data cylinder count */
 487                 unsigned short nacyl;      /* Alt. cylinder count */
 488                 unsigned short ntrks;      /* Tracks per cylinder */
 489                 unsigned short nsect;      /* Sectors per track */
 490                 unsigned char spare3[4];   /* Even more magic... */
 491                 struct sun_partition {
 492                         __u32 start_cylinder;
 493                         __u32 num_sectors;
 494                 } partitions[8];
 495                 unsigned short magic;      /* Magic number */
 496                 unsigned short csum;       /* Label xor'd checksum */
 497         } * label;              
 498         struct sun_partition *p;
 499         int other_endian;
 500         unsigned long spc;
 501 #define SUN_LABEL_MAGIC          0xDABE
 502 #define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
 503 /* No need to optimize these macros since they are called only when reading
 504  * the partition table. This occurs only at each disk change. */
 505 #define SWAP16(x)  (other_endian ? (((__u16)(x) & 0xFF) << 8) \
 506                                  | (((__u16)(x) & 0xFF00) >> 8) \
 507                                  : (__u16)(x))
 508 #define SWAP32(x)  (other_endian ? (((__u32)(x) & 0xFF) << 24) \
 509                                  | (((__u32)(x) & 0xFF00) << 8) \
 510                                  | (((__u32)(x) & 0xFF0000) >> 8) \
 511                                  | (((__u32)(x) & 0xFF000000) >> 24) \
 512                                  : (__u32)(x))
 513 
 514         if(!(bh = bread(dev, 0, 1024))) {
 515                 printk("Dev %d: unable to read partition table\n", dev);
 516                 return -1;
 517         }
 518         label = (struct sun_disklabel *) bh->b_data;
 519         p = label->partitions;
 520         if (label->magic != SUN_LABEL_MAGIC && label->magic != SUN_LABEL_MAGIC_SWAPPED) {
 521                 printk("Dev %d Sun disklabel: bad magic %04x\n", dev, label->magic);
 522                 brelse(bh);
 523                 return 0;
 524         }
 525         other_endian = (label->magic == SUN_LABEL_MAGIC_SWAPPED);
 526         /* Look at the checksum */
 527         ush = ((unsigned short *) (label+1)) - 1;
 528         for(csum = 0; ush >= ((unsigned short *) label);)
 529                 csum ^= *ush--;
 530         if(csum) {
 531                 printk("Dev %d Sun disklabel: Csum bad, label corrupted\n", dev);
 532                 brelse(bh);
 533                 return 0;
 534         }
 535         /* All Sun disks have 8 partition entries */
 536         spc = SWAP16(label->ntrks) * SWAP16(label->nsect);
 537         for(i=0; i < 8; i++, p++) {
 538                 unsigned long st_sector;
 539 
 540                 /* We register all partitions, even if zero size, so that
 541                  * the minor numbers end up ok as per SunOS interpretation.
 542                  */
 543                 st_sector = first_sector + SWAP32(p->start_cylinder) * spc;
 544                 add_partition(hd, current_minor, st_sector, SWAP32(p->num_sectors));
 545                 current_minor++;
 546         }
 547         printk("\n");
 548         brelse(bh);
 549         return 1;
 550 #undef SWAP16
 551 #undef SWAP32
 552 }
 553 
 554 #endif /* CONFIG_SUN_PARTITION */
 555 
 556 static void check_partition(struct gendisk *hd, kdev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 557 {
 558         static int first_time = 1;
 559         unsigned long first_sector;
 560         char buf[8];
 561 
 562         if (first_time)
 563                 printk("Partition check:\n");
 564         first_time = 0;
 565         first_sector = hd->part[MINOR(dev)].start_sect;
 566 
 567         /*
 568          * This is a kludge to allow the partition check to be
 569          * skipped for specific drives (e.g. IDE cd-rom drives)
 570          */
 571         if ((int)first_sector == -1) {
 572                 hd->part[MINOR(dev)].start_sect = 0;
 573                 return;
 574         }
 575 
 576         printk(" %s:", disk_name(hd, MINOR(dev), buf));
 577 #ifdef CONFIG_MSDOS_PARTITION
 578         if (msdos_partition(hd, dev, first_sector))
 579                 return;
 580 #endif
 581 #ifdef CONFIG_OSF_PARTITION
 582         if (osf_partition(hd, dev, first_sector))
 583                 return;
 584 #endif
 585 #ifdef CONFIG_SUN_PARTITION
 586         if(sun_partition(hd, dev, first_sector))
 587                 return;
 588 #endif
 589         printk(" unknown partition table\n");
 590 }
 591 
 592 /* This function is used to re-read partition tables for removable disks.
 593    Much of the cleanup from the old partition tables should have already been
 594    done */
 595 
 596 /* This function will re-read the partition tables for a given device,
 597 and set things back up again.  There are some important caveats,
 598 however.  You must ensure that no one is using the device, and no one
 599 can start using the device while this function is being executed. */
 600 
 601 void resetup_one_dev(struct gendisk *dev, int drive)
     /* [previous][next][first][last][top][bottom][index][help] */
 602 {
 603         int i;
 604         int first_minor = drive << dev->minor_shift;
 605         int end_minor   = first_minor + dev->max_p;
 606 
 607         blk_size[dev->major] = NULL;
 608         current_minor = 1 + first_minor;
 609         check_partition(dev, MKDEV(dev->major, first_minor));
 610 
 611         /*
 612          * We need to set the sizes array before we will be able to access
 613          * any of the partitions on this device.
 614          */
 615         if (dev->sizes != NULL) {       /* optional safeguard in ll_rw_blk.c */
 616                 for (i = first_minor; i < end_minor; i++)
 617                         dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
 618                 blk_size[dev->major] = dev->sizes;
 619         }
 620 }
 621 
 622 static void setup_dev(struct gendisk *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 623 {
 624         int i, drive;
 625         int end_minor   = dev->max_nr * dev->max_p;
 626 
 627         blk_size[dev->major] = NULL;
 628         for (i = 0 ; i < end_minor; i++) {
 629                 dev->part[i].start_sect = 0;
 630                 dev->part[i].nr_sects = 0;
 631         }
 632         dev->init(dev); 
 633         for (drive = 0 ; drive < dev->nr_real ; drive++) {
 634                 int first_minor = drive << dev->minor_shift;
 635                 current_minor = 1 + first_minor;
 636                 check_partition(dev, MKDEV(dev->major, first_minor));
 637         }
 638         if (dev->sizes != NULL) {       /* optional safeguard in ll_rw_blk.c */
 639                 for (i = 0; i < end_minor; i++)
 640                         dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
 641                 blk_size[dev->major] = dev->sizes;
 642         }
 643 }
 644 
 645 void device_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 646 {
 647         extern void console_map_init(void);
 648         struct gendisk *p;
 649         int nr=0;
 650 
 651         chr_dev_init();
 652         blk_dev_init();
 653         sti();
 654 #ifdef CONFIG_SCSI
 655         scsi_dev_init();
 656 #endif
 657 #ifdef CONFIG_INET
 658         net_dev_init();
 659 #endif
 660         console_map_init();
 661 
 662         for (p = gendisk_head ; p ; p=p->next) {
 663                 setup_dev(p);
 664                 nr += p->nr_real;
 665         }
 666 #ifdef CONFIG_BLK_DEV_RAM
 667 #ifdef CONFIG_BLK_DEV_INITRD
 668         if (initrd_start && mount_initrd) initrd_load();
 669         else
 670 #endif
 671         rd_load();
 672 #endif
 673 }

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