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