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 (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p);
  36static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p);
  37
  38/*
  39 * Test for a valid MAC partition
  40 */
  41int test_part_mac (block_dev_desc_t *dev_desc)
  42{
  43        ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
  44        ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
  45        ulong i, n;
  46
  47        if (part_mac_read_ddb (dev_desc, ddesc)) {
  48                /* error reading Driver Desriptor Block, or no valid Signature */
  49                return (-1);
  50        }
  51
  52        n = 1;  /* assuming at least one partition */
  53        for (i=1; i<=n; ++i) {
  54                if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)mpart) != 1) ||
  55                    (mpart->signature != MAC_PARTITION_MAGIC) ) {
  56                        return (-1);
  57                }
  58                /* update partition count */
  59                n = mpart->map_count;
  60        }
  61        return (0);
  62}
  63
  64
  65void print_part_mac (block_dev_desc_t *dev_desc)
  66{
  67        ulong i, n;
  68        ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
  69        ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
  70        ldiv_t mb, gb;
  71
  72        if (part_mac_read_ddb (dev_desc, ddesc)) {
  73                /* error reading Driver Desriptor Block, or no valid Signature */
  74                return;
  75        }
  76
  77        n  = ddesc->blk_count;
  78
  79        mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */
  80        /* round to 1 digit */
  81        mb.rem *= 10 * ddesc->blk_size;
  82        mb.rem += 512 * 1024;
  83        mb.rem /= 1024 * 1024;
  84
  85        gb = ldiv(10 * mb.quot + mb.rem, 10240);
  86        gb.rem += 512;
  87        gb.rem /= 1024;
  88
  89
  90        printf ("Block Size=%d, Number of Blocks=%d, "
  91                "Total Capacity: %ld.%ld MB = %ld.%ld GB\n"
  92                "DeviceType=0x%x, DeviceId=0x%x\n\n"
  93                "   #:                 type name"
  94                "                   length   base       (size)\n",
  95                ddesc->blk_size,
  96                ddesc->blk_count,
  97                mb.quot, mb.rem, gb.quot, gb.rem,
  98                ddesc->dev_type, ddesc->dev_id
  99                );
 100
 101        n = 1;  /* assuming at least one partition */
 102        for (i=1; i<=n; ++i) {
 103                ulong bytes;
 104                char c;
 105
 106                printf ("%4ld: ", i);
 107                if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)mpart) != 1) {
 108                        printf ("** Can't read Partition Map on %d:%ld **\n",
 109                                dev_desc->dev, i);
 110                        return;
 111                }
 112
 113                if (mpart->signature != MAC_PARTITION_MAGIC) {
 114                        printf ("** Bad Signature on %d:%ld - "
 115                                "expected 0x%04x, got 0x%04x\n",
 116                                dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart->signature);
 117                        return;
 118                }
 119
 120                /* update partition count */
 121                n = mpart->map_count;
 122
 123                c      = 'k';
 124                bytes  = mpart->block_count;
 125                bytes /= (1024 / ddesc->blk_size);  /* kB; assumes blk_size == 512 */
 126                if (bytes >= 1024) {
 127                        bytes >>= 10;
 128                        c = 'M';
 129                }
 130                if (bytes >= 1024) {
 131                        bytes >>= 10;
 132                        c = 'G';
 133                }
 134
 135                printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n",
 136                        mpart->type,
 137                        mpart->name,
 138                        mpart->block_count,
 139                        mpart->start_block,
 140                        bytes, c
 141                        );
 142        }
 143
 144        return;
 145}
 146
 147
 148/*
 149 * Read Device Descriptor Block
 150 */
 151static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p)
 152{
 153        if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) {
 154                printf ("** Can't read Driver Desriptor Block **\n");
 155                return (-1);
 156        }
 157
 158        if (ddb_p->signature != MAC_DRIVER_MAGIC) {
 159#if 0
 160                printf ("** Bad Signature: expected 0x%04x, got 0x%04x\n",
 161                        MAC_DRIVER_MAGIC, ddb_p->signature);
 162#endif
 163                return (-1);
 164        }
 165        return (0);
 166}
 167
 168/*
 169 * Read Partition Descriptor Block
 170 */
 171static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p)
 172{
 173        int n = 1;
 174
 175        for (;;) {
 176                /*
 177                 * We must always read the descritpor block for
 178                 * partition 1 first since this is the only way to
 179                 * know how many partitions we have.
 180                 */
 181                if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) {
 182                        printf ("** Can't read Partition Map on %d:%d **\n",
 183                                dev_desc->dev, n);
 184                        return (-1);
 185                }
 186
 187                if (pdb_p->signature != MAC_PARTITION_MAGIC) {
 188                        printf ("** Bad Signature on %d:%d: "
 189                                "expected 0x%04x, got 0x%04x\n",
 190                                dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature);
 191                        return (-1);
 192                }
 193
 194                if (n == part)
 195                        return (0);
 196
 197                if ((part < 1) || (part > pdb_p->map_count)) {
 198                        printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n",
 199                                dev_desc->dev, part,
 200                                dev_desc->dev,
 201                                dev_desc->dev, pdb_p->map_count);
 202                        return (-1);
 203                }
 204
 205                /* update partition count */
 206                n = part;
 207        }
 208
 209        /* NOTREACHED */
 210}
 211
 212int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
 213{
 214        ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
 215        ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
 216
 217        if (part_mac_read_ddb (dev_desc, ddesc)) {
 218                return (-1);
 219        }
 220
 221        info->blksz = ddesc->blk_size;
 222
 223        if (part_mac_read_pdb (dev_desc, part, mpart)) {
 224                return (-1);
 225        }
 226
 227        info->start = mpart->start_block;
 228        info->size  = mpart->block_count;
 229        memcpy (info->type, mpart->type, sizeof(info->type));
 230        memcpy (info->name, mpart->name, sizeof(info->name));
 231
 232        return (0);
 233}
 234
 235#endif
 236