1
2
3
4
5
6
7
8
9
10
11#include "check.h"
12
13#define SUN_LABEL_MAGIC 0xDABE
14#define SUN_VTOC_SANITY 0x600DDEEE
15
16enum {
17 SUN_WHOLE_DISK = 5,
18 LINUX_RAID_PARTITION = 0xfd,
19};
20
21int sun_partition(struct parsed_partitions *state)
22{
23 int i;
24 __be16 csum;
25 int slot = 1;
26 __be16 *ush;
27 Sector sect;
28 struct sun_disklabel {
29 unsigned char info[128];
30 struct sun_vtoc {
31 __be32 version;
32 char volume[8];
33 __be16 nparts;
34 struct sun_info {
35 __be16 id;
36 __be16 flags;
37 } infos[8];
38 __be16 padding;
39 __be32 bootinfo[3];
40 __be32 sanity;
41 __be32 reserved[10];
42 __be32 timestamp[8];
43 } vtoc;
44 __be32 write_reinstruct;
45 __be32 read_reinstruct;
46 unsigned char spare[148];
47 __be16 rspeed;
48 __be16 pcylcount;
49 __be16 sparecyl;
50 __be16 obs1;
51 __be16 obs2;
52 __be16 ilfact;
53 __be16 ncyl;
54 __be16 nacyl;
55 __be16 ntrks;
56 __be16 nsect;
57 __be16 obs3;
58 __be16 obs4;
59 struct sun_partition {
60 __be32 start_cylinder;
61 __be32 num_sectors;
62 } partitions[8];
63 __be16 magic;
64 __be16 csum;
65 } * label;
66 struct sun_partition *p;
67 unsigned long spc;
68 char b[BDEVNAME_SIZE];
69 int use_vtoc;
70 int nparts;
71
72 label = read_part_sector(state, 0, §);
73 if (!label)
74 return -1;
75
76 p = label->partitions;
77 if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
78
79
80 put_dev_sector(sect);
81 return 0;
82 }
83
84 ush = ((__be16 *) (label+1)) - 1;
85 for (csum = 0; ush >= ((__be16 *) label);)
86 csum ^= *ush--;
87 if (csum) {
88 printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
89 bdevname(state->bdev, b));
90 put_dev_sector(sect);
91 return 0;
92 }
93
94
95 use_vtoc = ((be32_to_cpu(label->vtoc.sanity) == SUN_VTOC_SANITY) &&
96 (be32_to_cpu(label->vtoc.version) == 1) &&
97 (be16_to_cpu(label->vtoc.nparts) <= 8));
98
99
100 nparts = (use_vtoc) ? be16_to_cpu(label->vtoc.nparts) : 8;
101
102
103
104
105
106 use_vtoc = use_vtoc || !(label->vtoc.sanity ||
107 label->vtoc.version || label->vtoc.nparts);
108 spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
109 for (i = 0; i < nparts; i++, p++) {
110 unsigned long st_sector;
111 unsigned int num_sectors;
112
113 st_sector = be32_to_cpu(p->start_cylinder) * spc;
114 num_sectors = be32_to_cpu(p->num_sectors);
115 if (num_sectors) {
116 put_partition(state, slot, st_sector, num_sectors);
117 state->parts[slot].flags = 0;
118 if (use_vtoc) {
119 if (be16_to_cpu(label->vtoc.infos[i].id) == LINUX_RAID_PARTITION)
120 state->parts[slot].flags |= ADDPART_FLAG_RAID;
121 else if (be16_to_cpu(label->vtoc.infos[i].id) == SUN_WHOLE_DISK)
122 state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK;
123 }
124 }
125 slot++;
126 }
127 strlcat(state->pp_buf, "\n", PAGE_SIZE);
128 put_dev_sector(sect);
129 return 1;
130}
131