0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "check.h"
0012
0013 #define SUN_LABEL_MAGIC 0xDABE
0014 #define SUN_VTOC_SANITY 0x600DDEEE
0015
0016 enum {
0017 SUN_WHOLE_DISK = 5,
0018 LINUX_RAID_PARTITION = 0xfd,
0019 };
0020
0021 int sun_partition(struct parsed_partitions *state)
0022 {
0023 int i;
0024 __be16 csum;
0025 int slot = 1;
0026 __be16 *ush;
0027 Sector sect;
0028 struct sun_disklabel {
0029 unsigned char info[128];
0030 struct sun_vtoc {
0031 __be32 version;
0032 char volume[8];
0033 __be16 nparts;
0034 struct sun_info {
0035 __be16 id;
0036 __be16 flags;
0037 } infos[8];
0038 __be16 padding;
0039 __be32 bootinfo[3];
0040 __be32 sanity;
0041 __be32 reserved[10];
0042 __be32 timestamp[8];
0043 } vtoc;
0044 __be32 write_reinstruct;
0045 __be32 read_reinstruct;
0046 unsigned char spare[148];
0047 __be16 rspeed;
0048 __be16 pcylcount;
0049 __be16 sparecyl;
0050 __be16 obs1;
0051 __be16 obs2;
0052 __be16 ilfact;
0053 __be16 ncyl;
0054 __be16 nacyl;
0055 __be16 ntrks;
0056 __be16 nsect;
0057 __be16 obs3;
0058 __be16 obs4;
0059 struct sun_partition {
0060 __be32 start_cylinder;
0061 __be32 num_sectors;
0062 } partitions[8];
0063 __be16 magic;
0064 __be16 csum;
0065 } * label;
0066 struct sun_partition *p;
0067 unsigned long spc;
0068 int use_vtoc;
0069 int nparts;
0070
0071 label = read_part_sector(state, 0, §);
0072 if (!label)
0073 return -1;
0074
0075 p = label->partitions;
0076 if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
0077
0078
0079 put_dev_sector(sect);
0080 return 0;
0081 }
0082
0083 ush = ((__be16 *) (label+1)) - 1;
0084 for (csum = 0; ush >= ((__be16 *) label);)
0085 csum ^= *ush--;
0086 if (csum) {
0087 printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
0088 state->disk->disk_name);
0089 put_dev_sector(sect);
0090 return 0;
0091 }
0092
0093
0094 use_vtoc = ((be32_to_cpu(label->vtoc.sanity) == SUN_VTOC_SANITY) &&
0095 (be32_to_cpu(label->vtoc.version) == 1) &&
0096 (be16_to_cpu(label->vtoc.nparts) <= 8));
0097
0098
0099 nparts = (use_vtoc) ? be16_to_cpu(label->vtoc.nparts) : 8;
0100
0101
0102
0103
0104
0105 use_vtoc = use_vtoc || !(label->vtoc.sanity ||
0106 label->vtoc.version || label->vtoc.nparts);
0107 spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
0108 for (i = 0; i < nparts; i++, p++) {
0109 unsigned long st_sector;
0110 unsigned int num_sectors;
0111
0112 st_sector = be32_to_cpu(p->start_cylinder) * spc;
0113 num_sectors = be32_to_cpu(p->num_sectors);
0114 if (num_sectors) {
0115 put_partition(state, slot, st_sector, num_sectors);
0116 state->parts[slot].flags = 0;
0117 if (use_vtoc) {
0118 if (be16_to_cpu(label->vtoc.infos[i].id) == LINUX_RAID_PARTITION)
0119 state->parts[slot].flags |= ADDPART_FLAG_RAID;
0120 else if (be16_to_cpu(label->vtoc.infos[i].id) == SUN_WHOLE_DISK)
0121 state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK;
0122 }
0123 }
0124 slot++;
0125 }
0126 strlcat(state->pp_buf, "\n", PAGE_SIZE);
0127 put_dev_sector(sect);
0128 return 1;
0129 }