diff options
Diffstat (limited to 'u-boot/disk/part_mac.c')
-rw-r--r-- | u-boot/disk/part_mac.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/u-boot/disk/part_mac.c b/u-boot/disk/part_mac.c new file mode 100644 index 0000000..bebe415 --- /dev/null +++ b/u-boot/disk/part_mac.c @@ -0,0 +1,256 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Support for harddisk partitions. + * + * To be compatible with LinuxPPC and Apple we use the standard Apple + * SCSI disk partitioning scheme. For more information see: + * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92 + */ + +#include <common.h> +#include <command.h> +#include <ide.h> +#include "part_mac.h" + +#if defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_MG_DISK) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_SATA) || \ + defined(CONFIG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) + +/* stdlib.h causes some compatibility problems; should fixe these! -- wd */ +#ifndef __ldiv_t_defined +typedef struct { + long int quot; /* Quotient */ + long int rem; /* Remainder */ +} ldiv_t; +extern ldiv_t ldiv (long int __numer, long int __denom); +# define __ldiv_t_defined 1 +#endif + + +static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p); +static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p); + +/* + * Test for a valid MAC partition + */ +int test_part_mac (block_dev_desc_t *dev_desc) +{ + mac_driver_desc_t ddesc; + mac_partition_t mpart; + ulong i, n; + + if (part_mac_read_ddb (dev_desc, &ddesc)) { + /* error reading Driver Desriptor Block, or no valid Signature */ + return (-1); + } + + n = 1; /* assuming at least one partition */ + for (i=1; i<=n; ++i) { + if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) || + (mpart.signature != MAC_PARTITION_MAGIC) ) { + return (-1); + } + /* update partition count */ + n = mpart.map_count; + } + return (0); +} + + +void print_part_mac (block_dev_desc_t *dev_desc) +{ + ulong i, n; + mac_driver_desc_t ddesc; + mac_partition_t mpart; + ldiv_t mb, gb; + + if (part_mac_read_ddb (dev_desc, &ddesc)) { + /* error reading Driver Desriptor Block, or no valid Signature */ + return; + } + + n = ddesc.blk_count; + + mb = ldiv(n, ((1024 * 1024) / ddesc.blk_size)); /* MB */ + /* round to 1 digit */ + mb.rem *= 10 * ddesc.blk_size; + mb.rem += 512 * 1024; + mb.rem /= 1024 * 1024; + + gb = ldiv(10 * mb.quot + mb.rem, 10240); + gb.rem += 512; + gb.rem /= 1024; + + + printf ("Block Size=%d, Number of Blocks=%d, " + "Total Capacity: %ld.%ld MB = %ld.%ld GB\n" + "DeviceType=0x%x, DeviceId=0x%x\n\n" + " #: type name" + " length base (size)\n", + ddesc.blk_size, + ddesc.blk_count, + mb.quot, mb.rem, gb.quot, gb.rem, + ddesc.dev_type, ddesc.dev_id + ); + + n = 1; /* assuming at least one partition */ + for (i=1; i<=n; ++i) { + ulong bytes; + char c; + + printf ("%4ld: ", i); + if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) { + printf ("** Can't read Partition Map on %d:%ld **\n", + dev_desc->dev, i); + return; + } + + if (mpart.signature != MAC_PARTITION_MAGIC) { + printf ("** Bad Signature on %d:%ld - " + "expected 0x%04x, got 0x%04x\n", + dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature); + return; + } + + /* update partition count */ + n = mpart.map_count; + + c = 'k'; + bytes = mpart.block_count; + bytes /= (1024 / ddesc.blk_size); /* kB; assumes blk_size == 512 */ + if (bytes >= 1024) { + bytes >>= 10; + c = 'M'; + } + if (bytes >= 1024) { + bytes >>= 10; + c = 'G'; + } + + printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n", + mpart.type, + mpart.name, + mpart.block_count, + mpart.start_block, + bytes, c + ); + } + + return; +} + + +/* + * Read Device Descriptor Block + */ +static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p) +{ + if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) { + printf ("** Can't read Driver Desriptor Block **\n"); + return (-1); + } + + if (ddb_p->signature != MAC_DRIVER_MAGIC) { +#if 0 + printf ("** Bad Signature: expected 0x%04x, got 0x%04x\n", + MAC_DRIVER_MAGIC, ddb_p->signature); +#endif + return (-1); + } + return (0); +} + +/* + * Read Partition Descriptor Block + */ +static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p) +{ + int n = 1; + + for (;;) { + /* + * We must always read the descritpor block for + * partition 1 first since this is the only way to + * know how many partitions we have. + */ + if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) { + printf ("** Can't read Partition Map on %d:%d **\n", + dev_desc->dev, n); + return (-1); + } + + if (pdb_p->signature != MAC_PARTITION_MAGIC) { + printf ("** Bad Signature on %d:%d: " + "expected 0x%04x, got 0x%04x\n", + dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature); + return (-1); + } + + if (n == part) + return (0); + + if ((part < 1) || (part > pdb_p->map_count)) { + printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n", + dev_desc->dev, part, + dev_desc->dev, + dev_desc->dev, pdb_p->map_count); + return (-1); + } + + /* update partition count */ + n = part; + } + + /* NOTREACHED */ +} + +int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) +{ + mac_driver_desc_t ddesc; + mac_partition_t mpart; + + if (part_mac_read_ddb (dev_desc, &ddesc)) { + return (-1); + } + + info->blksz = ddesc.blk_size; + + if (part_mac_read_pdb (dev_desc, part, &mpart)) { + return (-1); + } + + info->start = mpart.start_block; + info->size = mpart.block_count; + memcpy (info->type, mpart.type, sizeof(info->type)); + memcpy (info->name, mpart.name, sizeof(info->name)); + + return (0); +} + +#endif |