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 strlcat(state->pp_buf, " [mac]", PAGE_SIZE); 67 for (slot = 1; slot <= blocks_in_map; ++slot) { 68 int pos = slot * secsize; 69 put_dev_sector(sect); 70 data = read_part_sector(state, pos/512, §); 71 if (!data) 72 return -1; 73 part = (struct mac_partition *) (data + pos%512); 74 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) 75 break; 76 put_partition(state, slot, 77 be32_to_cpu(part->start_block) * (secsize/512), 78 be32_to_cpu(part->block_count) * (secsize/512)); 79 80 if (!strnicmp(part->type, "Linux_RAID", 10)) 81 state->parts[slot].flags = ADDPART_FLAG_RAID; 82 #ifdef CONFIG_PPC_PMAC 83 /* 84 * If this is the first bootable partition, tell the 85 * setup code, in case it wants to make this the root. 86 */ 87 if (machine_is(powermac)) { 88 int goodness = 0; 89 90 mac_fix_string(part->processor, 16); 91 mac_fix_string(part->name, 32); 92 mac_fix_string(part->type, 32); 93 94 if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE) 95 && strcasecmp(part->processor, "powerpc") == 0) 96 goodness++; 97 98 if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0 99 || (strnicmp(part->type, "Linux", 5) == 0 100 && strcasecmp(part->type, "Linux_swap") != 0)) { 101 int i, l; 102 103 goodness++; 104 l = strlen(part->name); 105 if (strcmp(part->name, "/") == 0) 106 goodness++; 107 for (i = 0; i <= l - 4; ++i) { 108 if (strnicmp(part->name + i, "root", 109 4) == 0) { 110 goodness += 2; 111 break; 112 } 113 } 114 if (strnicmp(part->name, "swap", 4) == 0) 115 goodness--; 116 } 117 118 if (goodness > found_root_goodness) { 119 found_root = slot; 120 found_root_goodness = goodness; 121 } 122 } 123 #endif /* CONFIG_PPC_PMAC */ 124 } 125 #ifdef CONFIG_PPC_PMAC 126 if (found_root_goodness) 127 note_bootable_part(state->bdev->bd_dev, found_root, 128 found_root_goodness); 129 #endif 130 131 put_dev_sector(sect); 132 strlcat(state->pp_buf, "\n", PAGE_SIZE); 133 return 1; 134 } 135