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