forked from Minki/linux
582940508b
The kernel used to contain two functions for length-delimited, case-insensitive string comparison, strnicmp with correct semantics and a slightly buggy strncasecmp. The latter is the POSIX name, so strnicmp was renamed to strncasecmp, and strnicmp made into a wrapper for the new strncasecmp to avoid breaking existing users. To allow the compat wrapper strnicmp to be removed at some point in the future, and to avoid the extra indirection cost, do s/strnicmp/strncasecmp/g. Cc: Jens Axboe <axboe@kernel.dk> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Signed-off-by: Jens Axboe <axboe@fb.com>
139 lines
3.4 KiB
C
139 lines
3.4 KiB
C
/*
|
|
* fs/partitions/mac.c
|
|
*
|
|
* Code extracted from drivers/block/genhd.c
|
|
* Copyright (C) 1991-1998 Linus Torvalds
|
|
* Re-organised Feb 1998 Russell King
|
|
*/
|
|
|
|
#include <linux/ctype.h>
|
|
#include "check.h"
|
|
#include "mac.h"
|
|
|
|
#ifdef CONFIG_PPC_PMAC
|
|
#include <asm/machdep.h>
|
|
extern void note_bootable_part(dev_t dev, int part, int goodness);
|
|
#endif
|
|
|
|
/*
|
|
* Code to understand MacOS partition tables.
|
|
*/
|
|
|
|
static inline void mac_fix_string(char *stg, int len)
|
|
{
|
|
int i;
|
|
|
|
for (i = len - 1; i >= 0 && stg[i] == ' '; i--)
|
|
stg[i] = 0;
|
|
}
|
|
|
|
int mac_partition(struct parsed_partitions *state)
|
|
{
|
|
Sector sect;
|
|
unsigned char *data;
|
|
int slot, blocks_in_map;
|
|
unsigned secsize;
|
|
#ifdef CONFIG_PPC_PMAC
|
|
int found_root = 0;
|
|
int found_root_goodness = 0;
|
|
#endif
|
|
struct mac_partition *part;
|
|
struct mac_driver_desc *md;
|
|
|
|
/* Get 0th block and look at the first partition map entry. */
|
|
md = read_part_sector(state, 0, §);
|
|
if (!md)
|
|
return -1;
|
|
if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
|
|
put_dev_sector(sect);
|
|
return 0;
|
|
}
|
|
secsize = be16_to_cpu(md->block_size);
|
|
put_dev_sector(sect);
|
|
data = read_part_sector(state, secsize/512, §);
|
|
if (!data)
|
|
return -1;
|
|
part = (struct mac_partition *) (data + secsize%512);
|
|
if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
|
|
put_dev_sector(sect);
|
|
return 0; /* not a MacOS disk */
|
|
}
|
|
blocks_in_map = be32_to_cpu(part->map_count);
|
|
if (blocks_in_map < 0 || blocks_in_map >= DISK_MAX_PARTS) {
|
|
put_dev_sector(sect);
|
|
return 0;
|
|
}
|
|
|
|
if (blocks_in_map >= state->limit)
|
|
blocks_in_map = state->limit - 1;
|
|
|
|
strlcat(state->pp_buf, " [mac]", PAGE_SIZE);
|
|
for (slot = 1; slot <= blocks_in_map; ++slot) {
|
|
int pos = slot * secsize;
|
|
put_dev_sector(sect);
|
|
data = read_part_sector(state, pos/512, §);
|
|
if (!data)
|
|
return -1;
|
|
part = (struct mac_partition *) (data + pos%512);
|
|
if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
|
|
break;
|
|
put_partition(state, slot,
|
|
be32_to_cpu(part->start_block) * (secsize/512),
|
|
be32_to_cpu(part->block_count) * (secsize/512));
|
|
|
|
if (!strncasecmp(part->type, "Linux_RAID", 10))
|
|
state->parts[slot].flags = ADDPART_FLAG_RAID;
|
|
#ifdef CONFIG_PPC_PMAC
|
|
/*
|
|
* If this is the first bootable partition, tell the
|
|
* setup code, in case it wants to make this the root.
|
|
*/
|
|
if (machine_is(powermac)) {
|
|
int goodness = 0;
|
|
|
|
mac_fix_string(part->processor, 16);
|
|
mac_fix_string(part->name, 32);
|
|
mac_fix_string(part->type, 32);
|
|
|
|
if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
|
|
&& strcasecmp(part->processor, "powerpc") == 0)
|
|
goodness++;
|
|
|
|
if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
|
|
|| (strncasecmp(part->type, "Linux", 5) == 0
|
|
&& strcasecmp(part->type, "Linux_swap") != 0)) {
|
|
int i, l;
|
|
|
|
goodness++;
|
|
l = strlen(part->name);
|
|
if (strcmp(part->name, "/") == 0)
|
|
goodness++;
|
|
for (i = 0; i <= l - 4; ++i) {
|
|
if (strncasecmp(part->name + i, "root",
|
|
4) == 0) {
|
|
goodness += 2;
|
|
break;
|
|
}
|
|
}
|
|
if (strncasecmp(part->name, "swap", 4) == 0)
|
|
goodness--;
|
|
}
|
|
|
|
if (goodness > found_root_goodness) {
|
|
found_root = slot;
|
|
found_root_goodness = goodness;
|
|
}
|
|
}
|
|
#endif /* CONFIG_PPC_PMAC */
|
|
}
|
|
#ifdef CONFIG_PPC_PMAC
|
|
if (found_root_goodness)
|
|
note_bootable_part(state->bdev->bd_dev, found_root,
|
|
found_root_goodness);
|
|
#endif
|
|
|
|
put_dev_sector(sect);
|
|
strlcat(state->pp_buf, "\n", PAGE_SIZE);
|
|
return 1;
|
|
}
|