19be96f3fSAl Viro /* 29be96f3fSAl Viro * fs/partitions/mac.c 39be96f3fSAl Viro * 49be96f3fSAl Viro * Code extracted from drivers/block/genhd.c 59be96f3fSAl Viro * Copyright (C) 1991-1998 Linus Torvalds 69be96f3fSAl Viro * Re-organised Feb 1998 Russell King 79be96f3fSAl Viro */ 89be96f3fSAl Viro 99be96f3fSAl Viro #include <linux/ctype.h> 109be96f3fSAl Viro #include "check.h" 119be96f3fSAl Viro #include "mac.h" 129be96f3fSAl Viro 139be96f3fSAl Viro #ifdef CONFIG_PPC_PMAC 149be96f3fSAl Viro #include <asm/machdep.h> 159be96f3fSAl Viro extern void note_bootable_part(dev_t dev, int part, int goodness); 169be96f3fSAl Viro #endif 179be96f3fSAl Viro 189be96f3fSAl Viro /* 199be96f3fSAl Viro * Code to understand MacOS partition tables. 209be96f3fSAl Viro */ 219be96f3fSAl Viro 229be96f3fSAl Viro static inline void mac_fix_string(char *stg, int len) 239be96f3fSAl Viro { 249be96f3fSAl Viro int i; 259be96f3fSAl Viro 269be96f3fSAl Viro for (i = len - 1; i >= 0 && stg[i] == ' '; i--) 279be96f3fSAl Viro stg[i] = 0; 289be96f3fSAl Viro } 299be96f3fSAl Viro 309be96f3fSAl Viro int mac_partition(struct parsed_partitions *state) 319be96f3fSAl Viro { 329be96f3fSAl Viro Sector sect; 339be96f3fSAl Viro unsigned char *data; 349be96f3fSAl Viro int slot, blocks_in_map; 359be96f3fSAl Viro unsigned secsize; 369be96f3fSAl Viro #ifdef CONFIG_PPC_PMAC 379be96f3fSAl Viro int found_root = 0; 389be96f3fSAl Viro int found_root_goodness = 0; 399be96f3fSAl Viro #endif 409be96f3fSAl Viro struct mac_partition *part; 419be96f3fSAl Viro struct mac_driver_desc *md; 429be96f3fSAl Viro 439be96f3fSAl Viro /* Get 0th block and look at the first partition map entry. */ 449be96f3fSAl Viro md = read_part_sector(state, 0, §); 459be96f3fSAl Viro if (!md) 469be96f3fSAl Viro return -1; 479be96f3fSAl Viro if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) { 489be96f3fSAl Viro put_dev_sector(sect); 499be96f3fSAl Viro return 0; 509be96f3fSAl Viro } 519be96f3fSAl Viro secsize = be16_to_cpu(md->block_size); 529be96f3fSAl Viro put_dev_sector(sect); 539be96f3fSAl Viro data = read_part_sector(state, secsize/512, §); 549be96f3fSAl Viro if (!data) 559be96f3fSAl Viro return -1; 569be96f3fSAl Viro part = (struct mac_partition *) (data + secsize%512); 579be96f3fSAl Viro if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) { 589be96f3fSAl Viro put_dev_sector(sect); 599be96f3fSAl Viro return 0; /* not a MacOS disk */ 609be96f3fSAl Viro } 619be96f3fSAl Viro blocks_in_map = be32_to_cpu(part->map_count); 629be96f3fSAl Viro if (blocks_in_map < 0 || blocks_in_map >= DISK_MAX_PARTS) { 639be96f3fSAl Viro put_dev_sector(sect); 649be96f3fSAl Viro return 0; 659be96f3fSAl Viro } 669be96f3fSAl Viro strlcat(state->pp_buf, " [mac]", PAGE_SIZE); 679be96f3fSAl Viro for (slot = 1; slot <= blocks_in_map; ++slot) { 689be96f3fSAl Viro int pos = slot * secsize; 699be96f3fSAl Viro put_dev_sector(sect); 709be96f3fSAl Viro data = read_part_sector(state, pos/512, §); 719be96f3fSAl Viro if (!data) 729be96f3fSAl Viro return -1; 739be96f3fSAl Viro part = (struct mac_partition *) (data + pos%512); 749be96f3fSAl Viro if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) 759be96f3fSAl Viro break; 769be96f3fSAl Viro put_partition(state, slot, 779be96f3fSAl Viro be32_to_cpu(part->start_block) * (secsize/512), 789be96f3fSAl Viro be32_to_cpu(part->block_count) * (secsize/512)); 799be96f3fSAl Viro 809be96f3fSAl Viro if (!strnicmp(part->type, "Linux_RAID", 10)) 819be96f3fSAl Viro state->parts[slot].flags = ADDPART_FLAG_RAID; 829be96f3fSAl Viro #ifdef CONFIG_PPC_PMAC 839be96f3fSAl Viro /* 849be96f3fSAl Viro * If this is the first bootable partition, tell the 859be96f3fSAl Viro * setup code, in case it wants to make this the root. 869be96f3fSAl Viro */ 879be96f3fSAl Viro if (machine_is(powermac)) { 889be96f3fSAl Viro int goodness = 0; 899be96f3fSAl Viro 909be96f3fSAl Viro mac_fix_string(part->processor, 16); 919be96f3fSAl Viro mac_fix_string(part->name, 32); 929be96f3fSAl Viro mac_fix_string(part->type, 32); 939be96f3fSAl Viro 949be96f3fSAl Viro if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE) 959be96f3fSAl Viro && strcasecmp(part->processor, "powerpc") == 0) 969be96f3fSAl Viro goodness++; 979be96f3fSAl Viro 989be96f3fSAl Viro if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0 999be96f3fSAl Viro || (strnicmp(part->type, "Linux", 5) == 0 1009be96f3fSAl Viro && strcasecmp(part->type, "Linux_swap") != 0)) { 1019be96f3fSAl Viro int i, l; 1029be96f3fSAl Viro 1039be96f3fSAl Viro goodness++; 1049be96f3fSAl Viro l = strlen(part->name); 1059be96f3fSAl Viro if (strcmp(part->name, "/") == 0) 1069be96f3fSAl Viro goodness++; 1079be96f3fSAl Viro for (i = 0; i <= l - 4; ++i) { 1089be96f3fSAl Viro if (strnicmp(part->name + i, "root", 1099be96f3fSAl Viro 4) == 0) { 1109be96f3fSAl Viro goodness += 2; 1119be96f3fSAl Viro break; 1129be96f3fSAl Viro } 1139be96f3fSAl Viro } 1149be96f3fSAl Viro if (strnicmp(part->name, "swap", 4) == 0) 1159be96f3fSAl Viro goodness--; 1169be96f3fSAl Viro } 1179be96f3fSAl Viro 1189be96f3fSAl Viro if (goodness > found_root_goodness) { 1199be96f3fSAl Viro found_root = slot; 1209be96f3fSAl Viro found_root_goodness = goodness; 1219be96f3fSAl Viro } 1229be96f3fSAl Viro } 1239be96f3fSAl Viro #endif /* CONFIG_PPC_PMAC */ 1249be96f3fSAl Viro } 1259be96f3fSAl Viro #ifdef CONFIG_PPC_PMAC 1269be96f3fSAl Viro if (found_root_goodness) 1279be96f3fSAl Viro note_bootable_part(state->bdev->bd_dev, found_root, 1289be96f3fSAl Viro found_root_goodness); 1299be96f3fSAl Viro #endif 1309be96f3fSAl Viro 1319be96f3fSAl Viro put_dev_sector(sect); 1329be96f3fSAl Viro strlcat(state->pp_buf, "\n", PAGE_SIZE); 1339be96f3fSAl Viro return 1; 1349be96f3fSAl Viro } 135