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