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