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> 15extern void note_bootable_part(dev_t dev, int part, int goodness); 16#endif 17 18/* 19 * Code to understand MacOS partition tables. 20 */ 21 22static 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 30int mac_partition(struct parsed_partitions *state) 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 = read_part_sector(state, 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_part_sector(state, 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 strlcat(state->pp_buf, " [mac]", PAGE_SIZE); 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_part_sector(state, 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 77 if (!strnicmp(part->type, "Linux_RAID", 10)) 78 state->parts[slot].flags = ADDPART_FLAG_RAID; 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 */ 84 if (machine_is(powermac)) { 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(state->bdev->bd_dev, found_root, 127 found_root_goodness); 128#endif 129 130 put_dev_sector(sect); 131 strlcat(state->pp_buf, "\n", PAGE_SIZE); 132 return 1; 133} 134