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