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