root/drivers/block/genhd.c

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

DEFINITIONS

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

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