Blame view

block/partitions/mac.c 3.52 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
  /*
   *  fs/partitions/mac.c
   *
   *  Code extracted from drivers/block/genhd.c
   *  Copyright (C) 1991-1998  Linus Torvalds
   *  Re-organised Feb 1998 Russell King
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
  #include <linux/ctype.h>
  #include "check.h"
  #include "mac.h"
  
  #ifdef CONFIG_PPC_PMAC
e8222502e   Benjamin Herrenschmidt   [PATCH] powerpc: ...
13
  #include <asm/machdep.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  extern void note_bootable_part(dev_t dev, int part, int goodness);
  #endif
  
  /*
   * Code to understand MacOS partition tables.
   */
  
  static inline void mac_fix_string(char *stg, int len)
  {
  	int i;
  
  	for (i = len - 1; i >= 0 && stg[i] == ' '; i--)
  		stg[i] = 0;
  }
1493bf217   Tejun Heo   block: use struct...
28
  int mac_partition(struct parsed_partitions *state)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
  	Sector sect;
  	unsigned char *data;
fa7ea87a0   Timo Warns   fs/partitions: Va...
32
  	int slot, blocks_in_map;
02e2a5bfe   Kees Cook   mac: validate mac...
33
  	unsigned secsize, datasize, partoffset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
37
38
39
40
41
  #ifdef CONFIG_PPC_PMAC
  	int found_root = 0;
  	int found_root_goodness = 0;
  #endif
  	struct mac_partition *part;
  	struct mac_driver_desc *md;
  
  	/* Get 0th block and look at the first partition map entry. */
1493bf217   Tejun Heo   block: use struct...
42
  	md = read_part_sector(state, 0, &sect);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
47
48
49
50
  	if (!md)
  		return -1;
  	if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
  		put_dev_sector(sect);
  		return 0;
  	}
  	secsize = be16_to_cpu(md->block_size);
  	put_dev_sector(sect);
02e2a5bfe   Kees Cook   mac: validate mac...
51
52
  	datasize = round_down(secsize, 512);
  	data = read_part_sector(state, datasize / 512, &sect);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
  	if (!data)
  		return -1;
02e2a5bfe   Kees Cook   mac: validate mac...
55
56
57
58
  	partoffset = secsize % 512;
  	if (partoffset + sizeof(*part) > datasize)
  		return -1;
  	part = (struct mac_partition *) (data + partoffset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
  	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
  		put_dev_sector(sect);
  		return 0;		/* not a MacOS disk */
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  	blocks_in_map = be32_to_cpu(part->map_count);
fa7ea87a0   Timo Warns   fs/partitions: Va...
64
65
66
67
  	if (blocks_in_map < 0 || blocks_in_map >= DISK_MAX_PARTS) {
  		put_dev_sector(sect);
  		return 0;
  	}
06004e6ee   Ming Lei   block/partitions/...
68
69
70
  
  	if (blocks_in_map >= state->limit)
  		blocks_in_map = state->limit - 1;
fa7ea87a0   Timo Warns   fs/partitions: Va...
71
72
73
  	strlcat(state->pp_buf, " [mac]", PAGE_SIZE);
  	for (slot = 1; slot <= blocks_in_map; ++slot) {
  		int pos = slot * secsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  		put_dev_sector(sect);
1493bf217   Tejun Heo   block: use struct...
75
  		data = read_part_sector(state, pos/512, &sect);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
80
81
82
83
  		if (!data)
  			return -1;
  		part = (struct mac_partition *) (data + pos%512);
  		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
  			break;
  		put_partition(state, slot,
  			be32_to_cpu(part->start_block) * (secsize/512),
  			be32_to_cpu(part->block_count) * (secsize/512));
582940508   Rasmus Villemoes   block: Replace st...
84
  		if (!strncasecmp(part->type, "Linux_RAID", 10))
cc9106247   Cesar Eduardo Barros   fs/partitions: us...
85
  			state->parts[slot].flags = ADDPART_FLAG_RAID;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
  #ifdef CONFIG_PPC_PMAC
  		/*
  		 * If this is the first bootable partition, tell the
  		 * setup code, in case it wants to make this the root.
  		 */
e8222502e   Benjamin Herrenschmidt   [PATCH] powerpc: ...
91
  		if (machine_is(powermac)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
95
96
97
98
99
100
101
102
  			int goodness = 0;
  
  			mac_fix_string(part->processor, 16);
  			mac_fix_string(part->name, 32);
  			mac_fix_string(part->type, 32);					
  		    
  			if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
  			    && strcasecmp(part->processor, "powerpc") == 0)
  				goodness++;
  
  			if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
582940508   Rasmus Villemoes   block: Replace st...
103
  			    || (strncasecmp(part->type, "Linux", 5) == 0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
110
111
  			        && strcasecmp(part->type, "Linux_swap") != 0)) {
  				int i, l;
  
  				goodness++;
  				l = strlen(part->name);
  				if (strcmp(part->name, "/") == 0)
  					goodness++;
  				for (i = 0; i <= l - 4; ++i) {
582940508   Rasmus Villemoes   block: Replace st...
112
  					if (strncasecmp(part->name + i, "root",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
117
  						     4) == 0) {
  						goodness += 2;
  						break;
  					}
  				}
582940508   Rasmus Villemoes   block: Replace st...
118
  				if (strncasecmp(part->name, "swap", 4) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
  					goodness--;
  			}
  
  			if (goodness > found_root_goodness) {
fa7ea87a0   Timo Warns   fs/partitions: Va...
123
  				found_root = slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
126
127
  				found_root_goodness = goodness;
  			}
  		}
  #endif /* CONFIG_PPC_PMAC */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
  	}
  #ifdef CONFIG_PPC_PMAC
  	if (found_root_goodness)
1493bf217   Tejun Heo   block: use struct...
131
132
  		note_bootable_part(state->bdev->bd_dev, found_root,
  				   found_root_goodness);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
135
  #endif
  
  	put_dev_sector(sect);
9c867fbe0   Alexey Dobriyan   partitions: fix s...
136
137
  	strlcat(state->pp_buf, "
  ", PAGE_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
  	return 1;
  }