uboot/disk/part_mac.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2000
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 */
   6
   7/*
   8 * Support for harddisk partitions.
   9 *
  10 * To be compatible with LinuxPPC and Apple we use the standard Apple
  11 * SCSI disk partitioning scheme. For more information see:
  12 * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
  13 */
  14
  15#include <common.h>
  16#include <command.h>
  17#include <log.h>
  18#include <memalign.h>
  19#include <ide.h>
  20#include "part_mac.h"
  21#include <part.h>
  22
  23#ifdef CONFIG_HAVE_BLOCK_DEVICE
  24
  25/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
  26#ifndef __ldiv_t_defined
  27typedef struct {
  28        long int quot;          /* Quotient     */
  29        long int rem;           /* Remainder    */
  30} ldiv_t;
  31extern ldiv_t ldiv (long int __numer, long int __denom);
  32# define __ldiv_t_defined       1
  33#endif
  34
  35
  36static int part_mac_read_ddb(struct blk_desc *dev_desc,
  37                             mac_driver_desc_t *ddb_p);
  38static int part_mac_read_pdb(struct blk_desc *dev_desc, int part,
  39                             mac_partition_t *pdb_p);
  40
  41/*
  42 * Test for a valid MAC partition
  43 */
  44static int part_test_mac(struct blk_desc *dev_desc)
  45{
  46        ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
  47        ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
  48        ulong i, n;
  49
  50        if (part_mac_read_ddb (dev_desc, ddesc)) {
  51                /*
  52                 * error reading Driver Descriptor Block,
  53                 * or no valid Signature
  54                 */
  55                return (-1);
  56        }
  57
  58        n = 1;  /* assuming at least one partition */
  59        for (i=1; i<=n; ++i) {
  60                if ((blk_dread(dev_desc, i, 1, (ulong *)mpart) != 1) ||
  61                    (mpart->signature != MAC_PARTITION_MAGIC) ) {
  62                        return (-1);
  63                }
  64                /* update partition count */
  65                n = mpart->map_count;
  66        }
  67        return (0);
  68}
  69
  70static void part_print_mac(struct blk_desc *dev_desc)
  71{
  72        ulong i, n;
  73        ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
  74        ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
  75        ldiv_t mb, gb;
  76
  77        if (part_mac_read_ddb (dev_desc, ddesc)) {
  78                /*
  79                 * error reading Driver Descriptor Block,
  80                 * or no valid Signature
  81                 */
  82                return;
  83        }
  84
  85        n  = ddesc->blk_count;
  86
  87        mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */
  88        /* round to 1 digit */
  89        mb.rem *= 10 * ddesc->blk_size;
  90        mb.rem += 512 * 1024;
  91        mb.rem /= 1024 * 1024;
  92
  93        gb = ldiv(10 * mb.quot + mb.rem, 10240);
  94        gb.rem += 512;
  95        gb.rem /= 1024;
  96
  97
  98        printf ("Block Size=%d, Number of Blocks=%d, "
  99                "Total Capacity: %ld.%ld MB = %ld.%ld GB\n"
 100                "DeviceType=0x%x, DeviceId=0x%x\n\n"
 101                "   #:                 type name"
 102                "                   length   base       (size)\n",
 103                ddesc->blk_size,
 104                ddesc->blk_count,
 105                mb.quot, mb.rem, gb.quot, gb.rem,
 106                ddesc->dev_type, ddesc->dev_id
 107                );
 108
 109        n = 1;  /* assuming at least one partition */
 110        for (i=1; i<=n; ++i) {
 111                ulong bytes;
 112                char c;
 113
 114                printf ("%4ld: ", i);
 115                if (blk_dread(dev_desc, i, 1, (ulong *)mpart) != 1) {
 116                        printf ("** Can't read Partition Map on %d:%ld **\n",
 117                                dev_desc->devnum, i);
 118                        return;
 119                }
 120
 121                if (mpart->signature != MAC_PARTITION_MAGIC) {
 122                        printf("** Bad Signature on %d:%ld - expected 0x%04x, got 0x%04x\n",
 123                               dev_desc->devnum, i, MAC_PARTITION_MAGIC,
 124                               mpart->signature);
 125                        return;
 126                }
 127
 128                /* update partition count */
 129                n = mpart->map_count;
 130
 131                c      = 'k';
 132                bytes  = mpart->block_count;
 133                bytes /= (1024 / ddesc->blk_size);  /* kB; assumes blk_size == 512 */
 134                if (bytes >= 1024) {
 135                        bytes >>= 10;
 136                        c = 'M';
 137                }
 138                if (bytes >= 1024) {
 139                        bytes >>= 10;
 140                        c = 'G';
 141                }
 142
 143                printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n",
 144                        mpart->type,
 145                        mpart->name,
 146                        mpart->block_count,
 147                        mpart->start_block,
 148                        bytes, c
 149                        );
 150        }
 151
 152        return;
 153}
 154
 155
 156/*
 157 * Read Device Descriptor Block
 158 */
 159static int part_mac_read_ddb(struct blk_desc *dev_desc,
 160                             mac_driver_desc_t *ddb_p)
 161{
 162        if (blk_dread(dev_desc, 0, 1, (ulong *)ddb_p) != 1) {
 163                debug("** Can't read Driver Descriptor Block **\n");
 164                return (-1);
 165        }
 166
 167        if (ddb_p->signature != MAC_DRIVER_MAGIC) {
 168                return (-1);
 169        }
 170        return (0);
 171}
 172
 173/*
 174 * Read Partition Descriptor Block
 175 */
 176static int part_mac_read_pdb(struct blk_desc *dev_desc, int part,
 177                             mac_partition_t *pdb_p)
 178{
 179        int n = 1;
 180
 181        for (;;) {
 182                /*
 183                 * We must always read the descritpor block for
 184                 * partition 1 first since this is the only way to
 185                 * know how many partitions we have.
 186                 */
 187                if (blk_dread(dev_desc, n, 1, (ulong *)pdb_p) != 1) {
 188                        printf ("** Can't read Partition Map on %d:%d **\n",
 189                                dev_desc->devnum, n);
 190                        return (-1);
 191                }
 192
 193                if (pdb_p->signature != MAC_PARTITION_MAGIC) {
 194                        printf("** Bad Signature on %d:%d: expected 0x%04x, got 0x%04x\n",
 195                               dev_desc->devnum, n, MAC_PARTITION_MAGIC,
 196                               pdb_p->signature);
 197                        return (-1);
 198                }
 199
 200                if (n == part)
 201                        return (0);
 202
 203                if ((part < 1) || (part > pdb_p->map_count)) {
 204                        printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n",
 205                                dev_desc->devnum, part,
 206                                dev_desc->devnum,
 207                                dev_desc->devnum, pdb_p->map_count);
 208                        return (-1);
 209                }
 210
 211                /* update partition count */
 212                n = part;
 213        }
 214
 215        /* NOTREACHED */
 216}
 217
 218static int part_get_info_mac(struct blk_desc *dev_desc, int part,
 219                                  struct disk_partition *info)
 220{
 221        ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
 222        ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
 223
 224        if (part_mac_read_ddb (dev_desc, ddesc)) {
 225                return (-1);
 226        }
 227
 228        info->blksz = ddesc->blk_size;
 229
 230        if (part_mac_read_pdb (dev_desc, part, mpart)) {
 231                return (-1);
 232        }
 233
 234        info->start = mpart->start_block;
 235        info->size  = mpart->block_count;
 236        memcpy (info->type, mpart->type, sizeof(info->type));
 237        memcpy (info->name, mpart->name, sizeof(info->name));
 238
 239        return (0);
 240}
 241
 242U_BOOT_PART_TYPE(mac) = {
 243        .name           = "MAC",
 244        .part_type      = PART_TYPE_MAC,
 245        .max_entries    = MAC_ENTRY_NUMBERS,
 246        .get_info       = part_get_info_mac,
 247        .print          = part_print_mac,
 248        .test           = part_test_mac,
 249};
 250#endif
 251