root/block/partitions/mac.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mac_fix_string
  2. mac_partition

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  fs/partitions/mac.c
   4  *
   5  *  Code extracted from drivers/block/genhd.c
   6  *  Copyright (C) 1991-1998  Linus Torvalds
   7  *  Re-organised Feb 1998 Russell King
   8  */
   9 
  10 #include <linux/ctype.h>
  11 #include "check.h"
  12 #include "mac.h"
  13 
  14 #ifdef CONFIG_PPC_PMAC
  15 #include <asm/machdep.h>
  16 extern void note_bootable_part(dev_t dev, int part, int goodness);
  17 #endif
  18 
  19 /*
  20  * Code to understand MacOS partition tables.
  21  */
  22 
  23 static inline void mac_fix_string(char *stg, int len)
  24 {
  25         int i;
  26 
  27         for (i = len - 1; i >= 0 && stg[i] == ' '; i--)
  28                 stg[i] = 0;
  29 }
  30 
  31 int mac_partition(struct parsed_partitions *state)
  32 {
  33         Sector sect;
  34         unsigned char *data;
  35         int slot, blocks_in_map;
  36         unsigned secsize, datasize, partoffset;
  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, &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         datasize = round_down(secsize, 512);
  55         data = read_part_sector(state, datasize / 512, &sect);
  56         if (!data)
  57                 return -1;
  58         partoffset = secsize % 512;
  59         if (partoffset + sizeof(*part) > datasize)
  60                 return -1;
  61         part = (struct mac_partition *) (data + partoffset);
  62         if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
  63                 put_dev_sector(sect);
  64                 return 0;               /* not a MacOS disk */
  65         }
  66         blocks_in_map = be32_to_cpu(part->map_count);
  67         if (blocks_in_map < 0 || blocks_in_map >= DISK_MAX_PARTS) {
  68                 put_dev_sector(sect);
  69                 return 0;
  70         }
  71 
  72         if (blocks_in_map >= state->limit)
  73                 blocks_in_map = state->limit - 1;
  74 
  75         strlcat(state->pp_buf, " [mac]", PAGE_SIZE);
  76         for (slot = 1; slot <= blocks_in_map; ++slot) {
  77                 int pos = slot * secsize;
  78                 put_dev_sector(sect);
  79                 data = read_part_sector(state, pos/512, &sect);
  80                 if (!data)
  81                         return -1;
  82                 part = (struct mac_partition *) (data + pos%512);
  83                 if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
  84                         break;
  85                 put_partition(state, slot,
  86                         be32_to_cpu(part->start_block) * (secsize/512),
  87                         be32_to_cpu(part->block_count) * (secsize/512));
  88 
  89                 if (!strncasecmp(part->type, "Linux_RAID", 10))
  90                         state->parts[slot].flags = ADDPART_FLAG_RAID;
  91 #ifdef CONFIG_PPC_PMAC
  92                 /*
  93                  * If this is the first bootable partition, tell the
  94                  * setup code, in case it wants to make this the root.
  95                  */
  96                 if (machine_is(powermac)) {
  97                         int goodness = 0;
  98 
  99                         mac_fix_string(part->processor, 16);
 100                         mac_fix_string(part->name, 32);
 101                         mac_fix_string(part->type, 32);                                 
 102                     
 103                         if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
 104                             && strcasecmp(part->processor, "powerpc") == 0)
 105                                 goodness++;
 106 
 107                         if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
 108                             || (strncasecmp(part->type, "Linux", 5) == 0
 109                                 && strcasecmp(part->type, "Linux_swap") != 0)) {
 110                                 int i, l;
 111 
 112                                 goodness++;
 113                                 l = strlen(part->name);
 114                                 if (strcmp(part->name, "/") == 0)
 115                                         goodness++;
 116                                 for (i = 0; i <= l - 4; ++i) {
 117                                         if (strncasecmp(part->name + i, "root",
 118                                                      4) == 0) {
 119                                                 goodness += 2;
 120                                                 break;
 121                                         }
 122                                 }
 123                                 if (strncasecmp(part->name, "swap", 4) == 0)
 124                                         goodness--;
 125                         }
 126 
 127                         if (goodness > found_root_goodness) {
 128                                 found_root = slot;
 129                                 found_root_goodness = goodness;
 130                         }
 131                 }
 132 #endif /* CONFIG_PPC_PMAC */
 133         }
 134 #ifdef CONFIG_PPC_PMAC
 135         if (found_root_goodness)
 136                 note_bootable_part(state->bdev->bd_dev, found_root,
 137                                    found_root_goodness);
 138 #endif
 139 
 140         put_dev_sector(sect);
 141         strlcat(state->pp_buf, "\n", PAGE_SIZE);
 142         return 1;
 143 }

/* [<][>][^][v][top][bottom][index][help] */