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 9 #include <linux/ctype.h> 10 #include "check.h" 11 #include "mac.h" 12 13 #ifdef CONFIG_PPC_PMAC 14 #include <asm/machdep.h> 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) 31 { 32 Sector sect; 33 unsigned char *data; 34 int slot, blocks_in_map; 35 unsigned secsize; 36 #ifdef CONFIG_PPC_PMAC 37 int found_root = 0; 38 int found_root_goodness = 0; 39 #endif 40 struct mac_partition *part; 41 struct mac_driver_desc *md; 42 43 /* Get 0th block and look at the first partition map entry. */ 44 md = read_part_sector(state, 0, §); 45 if (!md) 46 return -1; 47 if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) { 48 put_dev_sector(sect); 49 return 0; 50 } 51 secsize = be16_to_cpu(md->block_size); 52 put_dev_sector(sect); 53 data = read_part_sector(state, secsize/512, §); 54 if (!data) 55 return -1; 56 part = (struct mac_partition *) (data + secsize%512); 57 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) { 58 put_dev_sector(sect); 59 return 0; /* not a MacOS disk */ 60 } 61 blocks_in_map = be32_to_cpu(part->map_count); 62 if (blocks_in_map < 0 || blocks_in_map >= DISK_MAX_PARTS) { 63 put_dev_sector(sect); 64 return 0; 65 } 66 67 if (blocks_in_map >= state->limit) 68 blocks_in_map = state->limit - 1; 69 70 strlcat(state->pp_buf, " [mac]", PAGE_SIZE); 71 for (slot = 1; slot <= blocks_in_map; ++slot) { 72 int pos = slot * secsize; 73 put_dev_sector(sect); 74 data = read_part_sector(state, pos/512, §); 75 if (!data) 76 return -1; 77 part = (struct mac_partition *) (data + pos%512); 78 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) 79 break; 80 put_partition(state, slot, 81 be32_to_cpu(part->start_block) * (secsize/512), 82 be32_to_cpu(part->block_count) * (secsize/512)); 83 84 if (!strncasecmp(part->type, "Linux_RAID", 10)) 85 state->parts[slot].flags = ADDPART_FLAG_RAID; 86 #ifdef CONFIG_PPC_PMAC 87 /* 88 * If this is the first bootable partition, tell the 89 * setup code, in case it wants to make this the root. 90 */ 91 if (machine_is(powermac)) { 92 int goodness = 0; 93 94 mac_fix_string(part->processor, 16); 95 mac_fix_string(part->name, 32); 96 mac_fix_string(part->type, 32); 97 98 if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE) 99 && strcasecmp(part->processor, "powerpc") == 0) 100 goodness++; 101 102 if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0 103 || (strncasecmp(part->type, "Linux", 5) == 0 104 && strcasecmp(part->type, "Linux_swap") != 0)) { 105 int i, l; 106 107 goodness++; 108 l = strlen(part->name); 109 if (strcmp(part->name, "/") == 0) 110 goodness++; 111 for (i = 0; i <= l - 4; ++i) { 112 if (strncasecmp(part->name + i, "root", 113 4) == 0) { 114 goodness += 2; 115 break; 116 } 117 } 118 if (strncasecmp(part->name, "swap", 4) == 0) 119 goodness--; 120 } 121 122 if (goodness > found_root_goodness) { 123 found_root = slot; 124 found_root_goodness = goodness; 125 } 126 } 127 #endif /* CONFIG_PPC_PMAC */ 128 } 129 #ifdef CONFIG_PPC_PMAC 130 if (found_root_goodness) 131 note_bootable_part(state->bdev->bd_dev, found_root, 132 found_root_goodness); 133 #endif 134 135 put_dev_sector(sect); 136 strlcat(state->pp_buf, "\n", PAGE_SIZE); 137 return 1; 138 } 139