linux/fs/partitions/mac.c
<<
>>
Prefs
   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, struct block_device *bdev)
  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 = (struct mac_driver_desc *) read_dev_sector(bdev, 0, &sect);
  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_dev_sector(bdev, secsize/512, &sect);
  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        printk(" [mac]");
  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_dev_sector(bdev, pos/512, &sect);
  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 = 1;
  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(bdev->bd_dev, found_root, found_root_goodness);
 127#endif
 128
 129        put_dev_sector(sect);
 130        printk("\n");
 131        return 1;
 132}
 133