1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * fs/partitions/sgi.c |
4 | * |
5 | * Code extracted from drivers/block/genhd.c |
6 | */ |
7 | |
8 | #include "check.h" |
9 | |
10 | #define SGI_LABEL_MAGIC 0x0be5a941 |
11 | |
12 | enum { |
13 | LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ |
14 | }; |
15 | |
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 | |
36 | int sgi_partition(struct parsed_partitions *state) |
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 | |
47 | label = read_part_sector(state, n: 0, p: §); |
48 | if (!label) |
49 | return -1; |
50 | p = &label->partitions[0]; |
51 | magic = label->magic_mushroom; |
52 | if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { |
53 | /*printk("Dev %s SGI disklabel: bad magic %08x\n", |
54 | state->disk->disk_name, be32_to_cpu(magic));*/ |
55 | put_dev_sector(p: sect); |
56 | return 0; |
57 | } |
58 | ui = ((__be32 *) (label + 1)) - 1; |
59 | for(csum = 0; ui >= ((__be32 *) label);) { |
60 | cs = *ui--; |
61 | csum += be32_to_cpu(cs); |
62 | } |
63 | if(csum) { |
64 | printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n" , |
65 | state->disk->disk_name); |
66 | put_dev_sector(p: sect); |
67 | return 0; |
68 | } |
69 | /* All SGI disk labels have 16 partitions, disks under Linux only |
70 | * have 15 minor's. Luckily there are always a few zero length |
71 | * partitions which we don't care about so we never overflow the |
72 | * current_minor. |
73 | */ |
74 | for(i = 0; i < 16; i++, p++) { |
75 | blocks = be32_to_cpu(p->num_blocks); |
76 | start = be32_to_cpu(p->first_block); |
77 | if (blocks) { |
78 | put_partition(p: state, n: slot, from: start, size: blocks); |
79 | if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION) |
80 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
81 | } |
82 | slot++; |
83 | } |
84 | strlcat(p: state->pp_buf, q: "\n" , PAGE_SIZE); |
85 | put_dev_sector(p: sect); |
86 | return 1; |
87 | } |
88 | |