u-boot/disk/part_mac.c
Simon Glass 96e5b03c8a dm: part: Convert partition API use to linker lists
We can use linker lists instead of explicitly declaring each function.
This makes the code shorter by avoiding switch() statements and lots of
header file declarations.

While this does clean up the code it introduces a few code issues with SPL.
SPL never needs to print partition information since this all happens from
commands. SPL mostly doesn't need to obtain information about a partition
either, except in a few cases. Add these cases so that the code will be
dropped from each partition driver when not needed. This avoids code bloat.

I think this is still a win, since it is not a bad thing to be explicit
about which features are used in SPL. But others may like to weigh in.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
2016-03-14 15:34:50 -06:00

247 lines
5.6 KiB
C

/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* 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 <memalign.h>
#include <ide.h>
#include "part_mac.h"
#ifdef HAVE_BLOCK_DEVICE
/* 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(struct blk_desc *dev_desc,
mac_driver_desc_t *ddb_p);
static int part_mac_read_pdb(struct blk_desc *dev_desc, int part,
mac_partition_t *pdb_p);
/*
* Test for a valid MAC partition
*/
static int test_part_mac(struct blk_desc *dev_desc)
{
ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
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, i, 1,
(ulong *)mpart) != 1) ||
(mpart->signature != MAC_PARTITION_MAGIC) ) {
return (-1);
}
/* update partition count */
n = mpart->map_count;
}
return (0);
}
static void print_part_mac(struct blk_desc *dev_desc)
{
ulong i, n;
ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
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, 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(struct blk_desc *dev_desc,
mac_driver_desc_t *ddb_p)
{
if (dev_desc->block_read(dev_desc, 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(struct blk_desc *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, 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 */
}
static int get_partition_info_mac(struct blk_desc *dev_desc, int part,
disk_partition_t *info)
{
ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
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);
}
U_BOOT_PART_TYPE(mac) = {
.name = "MAC",
.part_type = PART_TYPE_MAC,
.get_info = get_partition_info_mac,
.print = print_part_mac,
.test = test_part_mac,
};
#endif