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