summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--disk/part.c184
-rw-r--r--disk/part_amiga.c16
-rw-r--r--disk/part_dos.c9
-rw-r--r--disk/part_efi.c15
-rw-r--r--disk/part_iso.c16
-rw-r--r--disk/part_mac.c16
-rw-r--r--include/part.h79
7 files changed, 162 insertions, 173 deletions
diff --git a/disk/part.c b/disk/part.c
index 255ee7959f..978b85c6eb 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <command.h>
+#include <errno.h>
#include <ide.h>
#include <malloc.h>
#include <part.h>
@@ -58,6 +59,22 @@ static const struct block_drvr block_drvr[] = {
DECLARE_GLOBAL_DATA_PTR;
#ifdef HAVE_BLOCK_DEVICE
+static struct part_driver *part_driver_lookup_type(int part_type)
+{
+ struct part_driver *drv =
+ ll_entry_start(struct part_driver, part_driver);
+ const int n_ents = ll_entry_count(struct part_driver, part_driver);
+ struct part_driver *entry;
+
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ if (part_type == entry->part_type)
+ return entry;
+ }
+
+ /* Not found */
+ return NULL;
+}
+
static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
{
const struct block_drvr *drvr = block_drvr;
@@ -252,53 +269,31 @@ void dev_print (struct blk_desc *dev_desc)
void init_part(struct blk_desc *dev_desc)
{
-#ifdef CONFIG_ISO_PARTITION
- if (test_part_iso(dev_desc) == 0) {
- dev_desc->part_type = PART_TYPE_ISO;
- return;
- }
-#endif
+ struct part_driver *drv =
+ ll_entry_start(struct part_driver, part_driver);
+ const int n_ents = ll_entry_count(struct part_driver, part_driver);
+ struct part_driver *entry;
-#ifdef CONFIG_MAC_PARTITION
- if (test_part_mac(dev_desc) == 0) {
- dev_desc->part_type = PART_TYPE_MAC;
- return;
- }
-#endif
-
-/* must be placed before DOS partition detection */
-#ifdef CONFIG_EFI_PARTITION
- if (test_part_efi(dev_desc) == 0) {
- dev_desc->part_type = PART_TYPE_EFI;
- return;
- }
-#endif
-
-#ifdef CONFIG_DOS_PARTITION
- if (test_part_dos(dev_desc) == 0) {
- dev_desc->part_type = PART_TYPE_DOS;
- return;
- }
-#endif
-
-#ifdef CONFIG_AMIGA_PARTITION
- if (test_part_amiga(dev_desc) == 0) {
- dev_desc->part_type = PART_TYPE_AMIGA;
- return;
- }
-#endif
dev_desc->part_type = PART_TYPE_UNKNOWN;
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ int ret;
+
+ ret = entry->test(dev_desc);
+ debug("%s: try '%s': ret=%d\n", __func__, entry->name, ret);
+ if (!ret) {
+ dev_desc->part_type = entry->part_type;
+ break;
+ }
+ }
}
-
+static void print_part_header(const char *type, struct blk_desc *dev_desc)
+{
#if defined(CONFIG_MAC_PARTITION) || \
defined(CONFIG_DOS_PARTITION) || \
defined(CONFIG_ISO_PARTITION) || \
defined(CONFIG_AMIGA_PARTITION) || \
defined(CONFIG_EFI_PARTITION)
-
-static void print_part_header(const char *type, struct blk_desc *dev_desc)
-{
puts ("\nPartition Map for ");
switch (dev_desc->if_type) {
case IF_TYPE_IDE:
@@ -331,54 +326,24 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc)
}
printf (" device %d -- Partition Type: %s\n\n",
dev_desc->dev, type);
-}
-
#endif /* any CONFIG_..._PARTITION */
+}
void print_part(struct blk_desc *dev_desc)
{
+ struct part_driver *drv;
- switch (dev_desc->part_type) {
-#ifdef CONFIG_MAC_PARTITION
- case PART_TYPE_MAC:
- PRINTF ("## Testing for valid MAC partition ##\n");
- print_part_header ("MAC", dev_desc);
- print_part_mac (dev_desc);
- return;
-#endif
-#ifdef CONFIG_DOS_PARTITION
- case PART_TYPE_DOS:
- PRINTF ("## Testing for valid DOS partition ##\n");
- print_part_header ("DOS", dev_desc);
- print_part_dos (dev_desc);
- return;
-#endif
-
-#ifdef CONFIG_ISO_PARTITION
- case PART_TYPE_ISO:
- PRINTF ("## Testing for valid ISO Boot partition ##\n");
- print_part_header ("ISO", dev_desc);
- print_part_iso (dev_desc);
- return;
-#endif
-
-#ifdef CONFIG_AMIGA_PARTITION
- case PART_TYPE_AMIGA:
- PRINTF ("## Testing for a valid Amiga partition ##\n");
- print_part_header ("AMIGA", dev_desc);
- print_part_amiga (dev_desc);
- return;
-#endif
-
-#ifdef CONFIG_EFI_PARTITION
- case PART_TYPE_EFI:
- PRINTF ("## Testing for valid EFI partition ##\n");
- print_part_header ("EFI", dev_desc);
- print_part_efi (dev_desc);
+ drv = part_driver_lookup_type(dev_desc->part_type);
+ if (!drv) {
+ printf("## Unknown partition table type %x\n",
+ dev_desc->part_type);
return;
-#endif
}
- puts ("## Unknown partition table\n");
+
+ PRINTF("## Testing for valid %s partition ##\n", drv->name);
+ print_part_header(drv->name, dev_desc);
+ if (drv->print)
+ drv->print(dev_desc);
}
#endif /* HAVE_BLOCK_DEVICE */
@@ -387,6 +352,7 @@ int get_partition_info(struct blk_desc *dev_desc, int part,
disk_partition_t *info)
{
#ifdef HAVE_BLOCK_DEVICE
+ struct part_driver *drv;
#ifdef CONFIG_PARTITION_UUIDS
/* The common case is no UUID support */
@@ -396,53 +362,19 @@ int get_partition_info(struct blk_desc *dev_desc, int part,
info->type_guid[0] = 0;
#endif
- switch (dev_desc->part_type) {
-#ifdef CONFIG_MAC_PARTITION
- case PART_TYPE_MAC:
- if (get_partition_info_mac(dev_desc, part, info) == 0) {
- PRINTF("## Valid MAC partition found ##\n");
- return 0;
- }
- break;
-#endif
-
-#ifdef CONFIG_DOS_PARTITION
- case PART_TYPE_DOS:
- if (get_partition_info_dos(dev_desc, part, info) == 0) {
- PRINTF("## Valid DOS partition found ##\n");
- return 0;
- }
- break;
-#endif
-
-#ifdef CONFIG_ISO_PARTITION
- case PART_TYPE_ISO:
- if (get_partition_info_iso(dev_desc, part, info) == 0) {
- PRINTF("## Valid ISO boot partition found ##\n");
- return 0;
- }
- break;
-#endif
-
-#ifdef CONFIG_AMIGA_PARTITION
- case PART_TYPE_AMIGA:
- if (get_partition_info_amiga(dev_desc, part, info) == 0) {
- PRINTF("## Valid Amiga partition found ##\n");
- return 0;
- }
- break;
-#endif
-
-#ifdef CONFIG_EFI_PARTITION
- case PART_TYPE_EFI:
- if (get_partition_info_efi(dev_desc, part, info) == 0) {
- PRINTF("## Valid EFI partition found ##\n");
- return 0;
- }
- break;
-#endif
- default:
- break;
+ drv = part_driver_lookup_type(dev_desc->part_type);
+ if (!drv) {
+ debug("## Unknown partition table type %x\n",
+ dev_desc->part_type);
+ return -EPROTONOSUPPORT;
+ }
+ if (!drv->get_info) {
+ PRINTF("## Driver %s does not have the get_info() method\n");
+ return -ENOSYS;
+ }
+ if (drv->get_info(dev_desc, part, info) == 0) {
+ PRINTF("## Valid %s partition found ##\n", drv->name);
+ return 0;
}
#endif /* HAVE_BLOCK_DEVICE */
diff --git a/disk/part_amiga.c b/disk/part_amiga.c
index 5702c95782..0f569f0c9b 100644
--- a/disk/part_amiga.c
+++ b/disk/part_amiga.c
@@ -207,7 +207,7 @@ struct bootcode_block *get_bootcode(struct blk_desc *dev_desc)
* Test if the given partition has an Amiga partition table/Rigid
* Disk block
*/
-int test_part_amiga(struct blk_desc *dev_desc)
+static int test_part_amiga(struct blk_desc *dev_desc)
{
struct rigid_disk_block *rdb;
struct bootcode_block *bootcode;
@@ -291,8 +291,8 @@ static struct partition_block *find_partition(struct blk_desc *dev_desc,
/*
* Get info about a partition
*/
-int get_partition_info_amiga(struct blk_desc *dev_desc, int part,
- disk_partition_t *info)
+static int get_partition_info_amiga(struct blk_desc *dev_desc, int part,
+ disk_partition_t *info)
{
struct partition_block *p = find_partition(dev_desc, part-1);
struct amiga_part_geometry *g;
@@ -319,7 +319,7 @@ int get_partition_info_amiga(struct blk_desc *dev_desc, int part,
return 0;
}
-void print_part_amiga(struct blk_desc *dev_desc)
+static void print_part_amiga(struct blk_desc *dev_desc)
{
struct rigid_disk_block *rdb;
struct bootcode_block *boot;
@@ -379,4 +379,12 @@ void print_part_amiga(struct blk_desc *dev_desc)
}
}
+U_BOOT_PART_TYPE(amiga) = {
+ .name = "AMIGA",
+ .part_type = PART_TYPE_AMIGA,
+ .get_info = get_partition_info_amiga,
+ .print = print_part_amiga,
+ .test = test_part_amiga,
+};
+
#endif
diff --git a/disk/part_dos.c b/disk/part_dos.c
index ea0315ca07..7567ed3b29 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
}
-int test_part_dos(struct blk_desc *dev_desc)
+static int test_part_dos(struct blk_desc *dev_desc)
{
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
@@ -295,5 +295,12 @@ int get_partition_info_dos(struct blk_desc *dev_desc, int part,
return get_partition_info_extended(dev_desc, 0, 0, 1, part, info, 0);
}
+U_BOOT_PART_TYPE(dos) = {
+ .name = "DOS",
+ .part_type = PART_TYPE_DOS,
+ .get_info = part_get_info_ptr(get_partition_info_dos),
+ .print = part_print_ptr(print_part_dos),
+ .test = test_part_dos,
+};
#endif
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 7bd840f18c..3471b755e1 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -319,7 +319,7 @@ int get_partition_info_efi_by_name(struct blk_desc *dev_desc,
return -2;
}
-int test_part_efi(struct blk_desc *dev_desc)
+static int test_part_efi(struct blk_desc *dev_desc)
{
ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
@@ -953,4 +953,17 @@ static int is_pte_valid(gpt_entry * pte)
return 1;
}
}
+
+/*
+ * Add an 'a_' prefix so it comes before 'dos' in the linker list. We need to
+ * check EFI first, since a DOS partition is often used as a 'protective MBR'
+ * with EFI.
+ */
+U_BOOT_PART_TYPE(a_efi) = {
+ .name = "EFI",
+ .part_type = PART_TYPE_EFI,
+ .get_info = part_get_info_ptr(get_partition_info_efi),
+ .print = part_print_ptr(print_part_efi),
+ .test = test_part_efi,
+};
#endif
diff --git a/disk/part_iso.c b/disk/part_iso.c
index 2984df510c..1d72d236ce 100644
--- a/disk/part_iso.c
+++ b/disk/part_iso.c
@@ -217,14 +217,13 @@ found:
return 0;
}
-int get_partition_info_iso(struct blk_desc *dev_desc, int part_num,
- disk_partition_t *info)
+static int get_partition_info_iso(struct blk_desc *dev_desc, int part_num,
+ disk_partition_t *info)
{
return(get_partition_info_iso_verb(dev_desc, part_num, info, 1));
}
-
-void print_part_iso(struct blk_desc *dev_desc)
+static void print_part_iso(struct blk_desc *dev_desc)
{
disk_partition_t info;
int i;
@@ -241,11 +240,18 @@ void print_part_iso(struct blk_desc *dev_desc)
} while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);
}
-int test_part_iso(struct blk_desc *dev_desc)
+static int test_part_iso(struct blk_desc *dev_desc)
{
disk_partition_t info;
return(get_partition_info_iso_verb(dev_desc,0,&info,0));
}
+U_BOOT_PART_TYPE(iso) = {
+ .name = "ISO",
+ .part_type = PART_TYPE_ISO,
+ .get_info = get_partition_info_iso,
+ .print = print_part_iso,
+ .test = test_part_iso,
+};
#endif
diff --git a/disk/part_mac.c b/disk/part_mac.c
index ae83495f31..3fb3b161ae 100644
--- a/disk/part_mac.c
+++ b/disk/part_mac.c
@@ -40,7 +40,7 @@ static int part_mac_read_pdb(struct blk_desc *dev_desc, int part,
/*
* Test for a valid MAC partition
*/
-int test_part_mac(struct blk_desc *dev_desc)
+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);
@@ -64,8 +64,7 @@ int test_part_mac(struct blk_desc *dev_desc)
return (0);
}
-
-void print_part_mac(struct blk_desc *dev_desc)
+static void print_part_mac(struct blk_desc *dev_desc)
{
ulong i, n;
ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
@@ -214,8 +213,8 @@ static int part_mac_read_pdb(struct blk_desc *dev_desc, int part,
/* NOTREACHED */
}
-int get_partition_info_mac(struct blk_desc *dev_desc, int part,
- disk_partition_t *info)
+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);
@@ -238,4 +237,11 @@ int get_partition_info_mac(struct blk_desc *dev_desc, int part,
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
diff --git a/include/part.h b/include/part.h
index 6197101a96..544b0563a7 100644
--- a/include/part.h
+++ b/include/part.h
@@ -195,43 +195,62 @@ static inline int blk_get_device_part_str(const char *ifname,
{ *dev_desc = NULL; return -1; }
#endif
-#ifdef CONFIG_MAC_PARTITION
-/* disk/part_mac.c */
-int get_partition_info_mac(struct blk_desc *dev_desc, int part,
- disk_partition_t *info);
-void print_part_mac(struct blk_desc *dev_desc);
-int test_part_mac(struct blk_desc *dev_desc);
+/*
+ * We don't support printing partition information in SPL and only support
+ * getting partition information in a few cases.
+ */
+#ifdef CONFIG_SPL_BUILD
+# define part_print_ptr(x) NULL
+# if defined(CONFIG_SPL_EXT_SUPPORT) || \
+ defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
+# define part_get_info_ptr(x) x
+# else
+# define part_get_info_ptr(x) NULL
+# endif
+#else
+#define part_print_ptr(x) x
+#define part_get_info_ptr(x) x
#endif
-#ifdef CONFIG_DOS_PARTITION
-/* disk/part_dos.c */
-int get_partition_info_dos(struct blk_desc *dev_desc, int part,
- disk_partition_t *info);
-void print_part_dos(struct blk_desc *dev_desc);
-int test_part_dos(struct blk_desc *dev_desc);
-#endif
-#ifdef CONFIG_ISO_PARTITION
-/* disk/part_iso.c */
-int get_partition_info_iso(struct blk_desc *dev_desc, int part,
- disk_partition_t *info);
-void print_part_iso(struct blk_desc *dev_desc);
-int test_part_iso(struct blk_desc *dev_desc);
-#endif
+struct part_driver {
+ const char *name;
+ int part_type;
-#ifdef CONFIG_AMIGA_PARTITION
-/* disk/part_amiga.c */
-int get_partition_info_amiga(struct blk_desc *dev_desc, int part,
- disk_partition_t *info);
-void print_part_amiga(struct blk_desc *dev_desc);
-int test_part_amiga(struct blk_desc *dev_desc);
-#endif
+ /**
+ * get_info() - Get information about a partition
+ *
+ * @dev_desc: Block device descriptor
+ * @part: Partition number (1 = first)
+ * @info: Returns partition information
+ */
+ int (*get_info)(struct blk_desc *dev_desc, int part,
+ disk_partition_t *info);
+
+ /**
+ * print() - Print partition information
+ *
+ * @dev_desc: Block device descriptor
+ */
+ void (*print)(struct blk_desc *dev_desc);
+
+ /**
+ * test() - Test if a device contains this partition type
+ *
+ * @dev_desc: Block device descriptor
+ * @return 0 if the block device appears to contain this partition
+ * type, -ve if not
+ */
+ int (*test)(struct blk_desc *dev_desc);
+};
+
+/* Declare a new U-Boot partition 'driver' */
+#define U_BOOT_PART_TYPE(__name) \
+ ll_entry_declare(struct part_driver, __name, part_driver)
#ifdef CONFIG_EFI_PARTITION
#include <part_efi.h>
/* disk/part_efi.c */
-int get_partition_info_efi(struct blk_desc *dev_desc, int part,
- disk_partition_t *info);
/**
* get_partition_info_efi_by_name() - Find the specified GPT partition table entry
*
@@ -243,8 +262,6 @@ int get_partition_info_efi(struct blk_desc *dev_desc, int part,
*/
int get_partition_info_efi_by_name(struct blk_desc *dev_desc,
const char *name, disk_partition_t *info);
-void print_part_efi(struct blk_desc *dev_desc);
-int test_part_efi(struct blk_desc *dev_desc);
/**
* write_gpt_table() - Write the GUID Partition Table to disk