1/* 2 * fs/partitions/sun.c 3 * 4 * Code extracted from drivers/block/genhd.c 5 * 6 * Copyright (C) 1991-1998 Linus Torvalds 7 * Re-organised Feb 1998 Russell King 8 */ 9 10#include <linux/config.h> 11#include <linux/fs.h> 12#include <linux/genhd.h> 13#include <linux/kernel.h> 14#include <linux/major.h> 15#include <linux/string.h> 16#include <linux/blk.h> 17 18#include <asm/system.h> 19 20#include "check.h" 21#include "sun.h" 22 23#ifdef CONFIG_BLK_DEV_MD 24extern void md_autodetect_dev(kdev_t dev); 25#endif 26 27int sun_partition(struct gendisk *hd, struct block_device *bdev, unsigned long first_sector, int first_part_minor) 28{ 29 int i, csum; 30 unsigned short *ush; 31 Sector sect; 32 kdev_t dev = to_kdev_t(bdev->bd_dev); 33 struct sun_disklabel { 34 unsigned char info[128]; /* Informative text string */ 35 unsigned char spare0[14]; 36 struct sun_info { 37 unsigned char spare1; 38 unsigned char id; 39 unsigned char spare2; 40 unsigned char flags; 41 } infos[8]; 42 unsigned char spare[246]; /* Boot information etc. */ 43 unsigned short rspeed; /* Disk rotational speed */ 44 unsigned short pcylcount; /* Physical cylinder count */ 45 unsigned short sparecyl; /* extra sects per cylinder */ 46 unsigned char spare2[4]; /* More magic... */ 47 unsigned short ilfact; /* Interleave factor */ 48 unsigned short ncyl; /* Data cylinder count */ 49 unsigned short nacyl; /* Alt. cylinder count */ 50 unsigned short ntrks; /* Tracks per cylinder */ 51 unsigned short nsect; /* Sectors per track */ 52 unsigned char spare3[4]; /* Even more magic... */ 53 struct sun_partition { 54 __u32 start_cylinder; 55 __u32 num_sectors; 56 } partitions[8]; 57 unsigned short magic; /* Magic number */ 58 unsigned short csum; /* Label xor'd checksum */ 59 } * label; 60 struct sun_partition *p; 61 unsigned long spc; 62 63 label = (struct sun_disklabel *)read_dev_sector(bdev, 0, §); 64 if (!label) 65 return -1; 66 67 p = label->partitions; 68 if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) { 69/* printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n", 70 bdevname(dev), be16_to_cpu(label->magic)); */ 71 put_dev_sector(sect); 72 return 0; 73 } 74 /* Look at the checksum */ 75 ush = ((unsigned short *) (label+1)) - 1; 76 for (csum = 0; ush >= ((unsigned short *) label);) 77 csum ^= *ush--; 78 if (csum) { 79 printk("Dev %s Sun disklabel: Csum bad, label corrupted\n", 80 bdevname(dev)); 81 put_dev_sector(sect); 82 return 0; 83 } 84 85 /* All Sun disks have 8 partition entries */ 86 spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect); 87 for (i = 0; i < 8; i++, p++) { 88 unsigned long st_sector; 89 int num_sectors; 90 91 st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc; 92 num_sectors = be32_to_cpu(p->num_sectors); 93 if (num_sectors) { 94 add_gd_partition(hd, first_part_minor, 95 st_sector, num_sectors); 96#ifdef CONFIG_BLK_DEV_MD 97 if (label->infos[i].id == LINUX_RAID_PARTITION) 98 md_autodetect_dev(MKDEV(hd->major, 99 first_part_minor)); 100#endif 101 } 102 first_part_minor++; 103 } 104 printk("\n"); 105 put_dev_sector(sect); 106 return 1; 107} 108