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