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