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