Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
1da177e4 LT |
2 | /* |
3 | * fs/partitions/sgi.c | |
4 | * | |
5 | * Code extracted from drivers/block/genhd.c | |
6 | */ | |
7 | ||
8 | #include "check.h" | |
95f77ef3 CH |
9 | |
10 | #define SGI_LABEL_MAGIC 0x0be5a941 | |
1da177e4 | 11 | |
0226e9ea CH |
12 | enum { |
13 | LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ | |
14 | }; | |
15 | ||
1da177e4 LT |
16 | struct sgi_disklabel { |
17 | __be32 magic_mushroom; /* Big fat spliff... */ | |
18 | __be16 root_part_num; /* Root partition number */ | |
19 | __be16 swap_part_num; /* Swap partition number */ | |
20 | s8 boot_file[16]; /* Name of boot file for ARCS */ | |
21 | u8 _unused0[48]; /* Device parameter useless crapola.. */ | |
22 | struct sgi_volume { | |
23 | s8 name[8]; /* Name of volume */ | |
24 | __be32 block_num; /* Logical block number */ | |
25 | __be32 num_bytes; /* How big, in bytes */ | |
26 | } volume[15]; | |
27 | struct sgi_partition { | |
28 | __be32 num_blocks; /* Size in logical blocks */ | |
29 | __be32 first_block; /* First logical block */ | |
30 | __be32 type; /* Type of this partition */ | |
31 | } partitions[16]; | |
32 | __be32 csum; /* Disk label checksum */ | |
33 | __be32 _unused1; /* Padding */ | |
34 | }; | |
35 | ||
1493bf21 | 36 | int sgi_partition(struct parsed_partitions *state) |
1da177e4 LT |
37 | { |
38 | int i, csum; | |
39 | __be32 magic; | |
40 | int slot = 1; | |
41 | unsigned int start, blocks; | |
42 | __be32 *ui, cs; | |
43 | Sector sect; | |
44 | struct sgi_disklabel *label; | |
45 | struct sgi_partition *p; | |
46 | char b[BDEVNAME_SIZE]; | |
47 | ||
1493bf21 | 48 | label = read_part_sector(state, 0, §); |
1da177e4 LT |
49 | if (!label) |
50 | return -1; | |
51 | p = &label->partitions[0]; | |
52 | magic = label->magic_mushroom; | |
53 | if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { | |
54 | /*printk("Dev %s SGI disklabel: bad magic %08x\n", | |
55 | bdevname(bdev, b), be32_to_cpu(magic));*/ | |
56 | put_dev_sector(sect); | |
57 | return 0; | |
58 | } | |
59 | ui = ((__be32 *) (label + 1)) - 1; | |
60 | for(csum = 0; ui >= ((__be32 *) label);) { | |
61 | cs = *ui--; | |
62 | csum += be32_to_cpu(cs); | |
63 | } | |
64 | if(csum) { | |
65 | printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n", | |
1493bf21 | 66 | bdevname(state->bdev, b)); |
1da177e4 LT |
67 | put_dev_sector(sect); |
68 | return 0; | |
69 | } | |
70 | /* All SGI disk labels have 16 partitions, disks under Linux only | |
71 | * have 15 minor's. Luckily there are always a few zero length | |
72 | * partitions which we don't care about so we never overflow the | |
73 | * current_minor. | |
74 | */ | |
75 | for(i = 0; i < 16; i++, p++) { | |
76 | blocks = be32_to_cpu(p->num_blocks); | |
77 | start = be32_to_cpu(p->first_block); | |
78 | if (blocks) { | |
79 | put_partition(state, slot, start, blocks); | |
80 | if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION) | |
d18d7682 | 81 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
1da177e4 LT |
82 | } |
83 | slot++; | |
84 | } | |
9c867fbe | 85 | strlcat(state->pp_buf, "\n", PAGE_SIZE); |
1da177e4 LT |
86 | put_dev_sector(sect); |
87 | return 1; | |
88 | } |