]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * fs/partitions/mac.c | |
3 | * | |
4 | * Code extracted from drivers/block/genhd.c | |
5 | * Copyright (C) 1991-1998 Linus Torvalds | |
6 | * Re-organised Feb 1998 Russell King | |
7 | */ | |
8 | ||
1da177e4 LT |
9 | #include <linux/ctype.h> |
10 | #include "check.h" | |
11 | #include "mac.h" | |
12 | ||
13 | #ifdef CONFIG_PPC_PMAC | |
e8222502 | 14 | #include <asm/machdep.h> |
1da177e4 LT |
15 | extern void note_bootable_part(dev_t dev, int part, int goodness); |
16 | #endif | |
17 | ||
18 | /* | |
19 | * Code to understand MacOS partition tables. | |
20 | */ | |
21 | ||
22 | static inline void mac_fix_string(char *stg, int len) | |
23 | { | |
24 | int i; | |
25 | ||
26 | for (i = len - 1; i >= 0 && stg[i] == ' '; i--) | |
27 | stg[i] = 0; | |
28 | } | |
29 | ||
30 | int mac_partition(struct parsed_partitions *state, struct block_device *bdev) | |
31 | { | |
32 | int slot = 1; | |
33 | Sector sect; | |
34 | unsigned char *data; | |
35 | int blk, blocks_in_map; | |
36 | unsigned secsize; | |
37 | #ifdef CONFIG_PPC_PMAC | |
38 | int found_root = 0; | |
39 | int found_root_goodness = 0; | |
40 | #endif | |
41 | struct mac_partition *part; | |
42 | struct mac_driver_desc *md; | |
43 | ||
44 | /* Get 0th block and look at the first partition map entry. */ | |
45 | md = (struct mac_driver_desc *) read_dev_sector(bdev, 0, §); | |
46 | if (!md) | |
47 | return -1; | |
48 | if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) { | |
49 | put_dev_sector(sect); | |
50 | return 0; | |
51 | } | |
52 | secsize = be16_to_cpu(md->block_size); | |
53 | put_dev_sector(sect); | |
54 | data = read_dev_sector(bdev, secsize/512, §); | |
55 | if (!data) | |
56 | return -1; | |
57 | part = (struct mac_partition *) (data + secsize%512); | |
58 | if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) { | |
59 | put_dev_sector(sect); | |
60 | return 0; /* not a MacOS disk */ | |
61 | } | |
62 | printk(" [mac]"); | |
63 | blocks_in_map = be32_to_cpu(part->map_count); | |
64 | for (blk = 1; blk <= blocks_in_map; ++blk) { | |
65 | int pos = blk * secsize; | |
66 | put_dev_sector(sect); | |
67 | data = read_dev_sector(bdev, pos/512, §); | |
68 | if (!data) | |
69 | return -1; | |
70 | part = (struct mac_partition *) (data + pos%512); | |
71 | if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) | |
72 | break; | |
73 | put_partition(state, slot, | |
74 | be32_to_cpu(part->start_block) * (secsize/512), | |
75 | be32_to_cpu(part->block_count) * (secsize/512)); | |
76 | ||
a79f43a5 DW |
77 | if (!strnicmp(part->type, "Linux_RAID", 10)) |
78 | state->parts[slot].flags = 1; | |
1da177e4 LT |
79 | #ifdef CONFIG_PPC_PMAC |
80 | /* | |
81 | * If this is the first bootable partition, tell the | |
82 | * setup code, in case it wants to make this the root. | |
83 | */ | |
e8222502 | 84 | if (machine_is(powermac)) { |
1da177e4 LT |
85 | int goodness = 0; |
86 | ||
87 | mac_fix_string(part->processor, 16); | |
88 | mac_fix_string(part->name, 32); | |
89 | mac_fix_string(part->type, 32); | |
90 | ||
91 | if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE) | |
92 | && strcasecmp(part->processor, "powerpc") == 0) | |
93 | goodness++; | |
94 | ||
95 | if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0 | |
96 | || (strnicmp(part->type, "Linux", 5) == 0 | |
97 | && strcasecmp(part->type, "Linux_swap") != 0)) { | |
98 | int i, l; | |
99 | ||
100 | goodness++; | |
101 | l = strlen(part->name); | |
102 | if (strcmp(part->name, "/") == 0) | |
103 | goodness++; | |
104 | for (i = 0; i <= l - 4; ++i) { | |
105 | if (strnicmp(part->name + i, "root", | |
106 | 4) == 0) { | |
107 | goodness += 2; | |
108 | break; | |
109 | } | |
110 | } | |
111 | if (strnicmp(part->name, "swap", 4) == 0) | |
112 | goodness--; | |
113 | } | |
114 | ||
115 | if (goodness > found_root_goodness) { | |
116 | found_root = blk; | |
117 | found_root_goodness = goodness; | |
118 | } | |
119 | } | |
120 | #endif /* CONFIG_PPC_PMAC */ | |
121 | ||
122 | ++slot; | |
123 | } | |
124 | #ifdef CONFIG_PPC_PMAC | |
125 | if (found_root_goodness) | |
126 | note_bootable_part(bdev->bd_dev, found_root, found_root_goodness); | |
127 | #endif | |
128 | ||
129 | put_dev_sector(sect); | |
130 | printk("\n"); | |
131 | return 1; | |
132 | } |