diff options
Diffstat (limited to 'disk/part_mac.c')
| -rw-r--r-- | disk/part_mac.c | 251 | 
1 files changed, 251 insertions, 0 deletions
| diff --git a/disk/part_mac.c b/disk/part_mac.c new file mode 100644 index 000000000..ee9d170b7 --- /dev/null +++ b/disk/part_mac.c @@ -0,0 +1,251 @@ +/* + * (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 <cmd_disk.h> +#include "part_mac.h" + +#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_MAC_PARTITION) + +/* 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	/* (CONFIG_COMMANDS & CFG_CMD_IDE) && CONFIG_MAC_PARTITION */ |