
From: Simon Glass <sjg@chromium.org> The logic for part_init() is not ideal, since it silently ignores read errors. Each partition type tries to read the disk and presumably fails as well. No error is reported, however, so there is no indication that anything is wrong. Update the function to return an error, and update each of the probe functions to do the same, trying to minimise changes. Signed-off-by: Simon Glass <sjg@chromium.org> --- disk/part.c | 23 +++++++++++++++++------ disk/part_amiga.c | 2 +- disk/part_dos.c | 13 ++++++++----- disk/part_efi.c | 12 +++++++++--- disk/part_iso.c | 16 ++++++++++++++-- disk/part_mac.c | 16 ++++++++++++++-- drivers/block/blk-uclass.c | 3 ++- include/part.h | 15 ++++++++++++--- 8 files changed, 77 insertions(+), 23 deletions(-) diff --git a/disk/part.c b/disk/part.c index 3aab99b069b..d922fddb415 100644 --- a/disk/part.c +++ b/disk/part.c @@ -4,6 +4,8 @@ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ +#define LOG_CATEGORY UCLASS_PARTITION + #include <blk.h> #include <command.h> #include <env.h> @@ -276,33 +278,42 @@ void dev_print(struct blk_desc *desc) } } -void part_init(struct blk_desc *desc) +int part_init(struct blk_desc *desc) { 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; + int ret; blkcache_invalidate(desc->uclass_id, desc->devnum); if (desc->part_type != PART_TYPE_UNKNOWN) { for (entry = drv; entry != drv + n_ents; entry++) { - if (entry->part_type == desc->part_type && !entry->test(desc)) - return; + if (entry->part_type != desc->part_type) + continue; + ret = entry->test(desc); + log_debug("try '%s': ret=%d\n", entry->name, ret); + if (ret == -EIO) + return ret; } } desc->part_type = PART_TYPE_UNKNOWN; for (entry = drv; entry != drv + n_ents; entry++) { - int ret; - ret = entry->test(desc); - debug("%s: try '%s': ret=%d\n", __func__, entry->name, ret); + log_debug("try '%s': ret=%d\n", entry->name, ret); + if (ret == -EIO) + return ret; if (!ret) { desc->part_type = entry->part_type; break; } } + if (ret) + return -ENOENT; + + return 0; } static void print_part_header(const char *type, struct blk_desc *desc) diff --git a/disk/part_amiga.c b/disk/part_amiga.c index 5b8ae5762d3..8921db6495b 100644 --- a/disk/part_amiga.c +++ b/disk/part_amiga.c @@ -227,7 +227,7 @@ static int part_test_amiga(struct blk_desc *desc) else { PRINTF("part_test_amiga: no RDB found\n"); - return -1; + return -ENOENT; } } diff --git a/disk/part_dos.c b/disk/part_dos.c index 96f748702fd..c99138bfb0f 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -20,6 +20,7 @@ #include <vsprintf.h> #include <asm/unaligned.h> #include <linux/compiler.h> +#include <linux/err.h> #include "part_dos.h" #include <part.h> @@ -103,12 +104,14 @@ static int part_test_dos(struct blk_desc *desc) #ifndef CONFIG_XPL_BUILD ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, DIV_ROUND_UP(desc->blksz, sizeof(legacy_mbr))); + long ret; - if (blk_dread(desc, 0, 1, (ulong *)mbr) != 1) - return -1; + ret = blk_dread(desc, 0, 1, (ulong *)mbr); + if (IS_ERR_VALUE(ret)) + return ret; if (test_block_type((unsigned char *)mbr) != DOS_MBR) - return -1; + return -ENOENT; if (desc->sig_type == SIG_TYPE_NONE && mbr->unique_mbr_signature) { desc->sig_type = SIG_TYPE_MBR; @@ -118,10 +121,10 @@ static int part_test_dos(struct blk_desc *desc) ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, desc->blksz); if (blk_dread(desc, 0, 1, (ulong *)buffer) != 1) - return -1; + return -EIO; if (test_block_type(buffer) != DOS_MBR) - return -1; + return -ENOENT; #endif return 0; diff --git a/disk/part_efi.c b/disk/part_efi.c index 932d058c184..fef62689648 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -28,6 +28,7 @@ #include <dm/ofnode.h> #include <linux/compiler.h> #include <linux/ctype.h> +#include <linux/err.h> #include <linux/printk.h> #include <u-boot/crc.h> @@ -315,10 +316,14 @@ static int __maybe_unused part_get_info_efi(struct blk_desc *desc, int part, static int part_test_efi(struct blk_desc *desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, desc->blksz); + long ret; /* Read legacy MBR from block 0 and validate it */ - if ((blk_dread(desc, 0, 1, (ulong *)legacymbr) != 1) - || (is_pmbr_valid(legacymbr) != 1)) { + ret = blk_dread(desc, 0, 1, (ulong *)legacymbr); + if (IS_ERR_VALUE(ret)) + return ret; + + if (ret != 1 || is_pmbr_valid(legacymbr) != 1) { /* * TegraPT is compatible with EFI part, but it * cannot pass the Protective MBR check. Skip it @@ -330,8 +335,9 @@ static int part_test_efi(struct blk_desc *desc) desc->uclass_id == UCLASS_MMC && !desc->devnum) return 0; - return -1; + return -ENOENT; } + return 0; } diff --git a/disk/part_iso.c b/disk/part_iso.c index 6e05b2feffb..3a159f1d023 100644 --- a/disk/part_iso.c +++ b/disk/part_iso.c @@ -9,6 +9,7 @@ #include <part.h> #include <asm/cache.h> #include <asm/unaligned.h> +#include <linux/err.h> #include "part_iso.h" /* #define ISO_PART_DEBUG */ @@ -56,13 +57,17 @@ int part_get_info_iso_verb(struct blk_desc *desc, int part_num, iso_pri_rec_t *ppr = (iso_pri_rec_t *)tmpbuf; /* primary desc */ iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf; iso_init_def_entry_t *pide; + long ret; if (desc->blksz != CD_SECTSIZE && desc->blksz != 512) return -1; /* the first sector (sector 0x10) must be a primary volume desc */ blkaddr=PVD_OFFSET; - if (iso_dread(desc, PVD_OFFSET, 1, (ulong *)tmpbuf) != 1) + ret = iso_dread(desc, PVD_OFFSET, 1, (ulong *)tmpbuf); + if (IS_ERR_VALUE(ret)) + return ret; + if (ret != 1) return -1; if(ppr->desctype!=0x01) { if(verb) @@ -226,8 +231,15 @@ static void part_print_iso(struct blk_desc *desc) static int part_test_iso(struct blk_desc *desc) { struct disk_partition info; + int ret; - return part_get_info_iso_verb(desc, 1, &info, 0); + ret = part_get_info_iso_verb(desc, 1, &info, 0); + if (ret == -1) + return -ENOENT; + else if (ret) + return ret; + + return 0; } U_BOOT_PART_TYPE(iso) = { diff --git a/disk/part_mac.c b/disk/part_mac.c index 21c85942fd8..93b54df0d39 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -18,6 +18,7 @@ #include <ide.h> #include "part_mac.h" #include <part.h> +#include <linux/err.h> /* stdlib.h causes some compatibility problems; should fixe these! -- wd */ #ifndef __ldiv_t_defined @@ -41,8 +42,13 @@ static int part_test_mac(struct blk_desc *desc) ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); ulong i, n; + long ret; - if (part_mac_read_ddb(desc, ddesc)) { + ret = part_mac_read_ddb(desc, ddesc); + if (ret && ret != -1) + return ret; + + if (ret) { /* * error reading Driver Descriptor Block, * or no valid Signature @@ -151,7 +157,13 @@ static void part_print_mac(struct blk_desc *desc) */ static int part_mac_read_ddb(struct blk_desc *desc, mac_driver_desc_t *ddb_p) { - if (blk_dread(desc, 0, 1, (ulong *)ddb_p) != 1) { + long ret; + + ret = blk_dread(desc, 0, 1, (ulong *)ddb_p); + if (IS_ERR_VALUE(ret)) + return ret; + + if (ret != 1) { debug("** Can't read Driver Descriptor Block **\n"); return (-1); } diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index f06b2ce3887..0a69dccde84 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -855,7 +855,8 @@ static int blk_post_probe(struct udevice *dev) if (CONFIG_IS_ENABLED(PARTITIONS) && blk_enabled()) { struct blk_desc *desc = dev_get_uclass_plat(dev); - part_init(desc); + if (part_init(desc) == -EIO) + log_warning("Error reading from device\n"); if (desc->part_type != PART_TYPE_UNKNOWN && part_create_block_devices(dev)) diff --git a/include/part.h b/include/part.h index 0fd7c18d6b6..70cb430a0ff 100644 --- a/include/part.h +++ b/include/part.h @@ -232,7 +232,15 @@ int part_get_info_whole_disk(struct blk_desc *desc, struct disk_partition *info); void part_print(struct blk_desc *desc); -void part_init(struct blk_desc *desc); + +/** + * part_init() - Try to find a partition table on a block device + * + * @desc: Block descriptor to check + * Return 0 if found, -ENOENT if not, -EIO if a read failed + */ +int part_init(struct blk_desc *desc); + void dev_print(struct blk_desc *desc); /** @@ -370,7 +378,7 @@ static inline int part_get_info_whole_disk(struct blk_desc *desc, struct disk_partition *info) { return -1; } static inline void part_print(struct blk_desc *desc) {} -static inline void part_init(struct blk_desc *desc) {} +static inline int part_init(struct blk_desc *desc) { return 0; } static inline void dev_print(struct blk_desc *desc) {} static inline int blk_get_device_by_str(const char *ifname, const char *dev_str, struct blk_desc **desc) @@ -488,7 +496,8 @@ struct part_driver { * @test.desc: Block device descriptor * @test.Return: * 0 if the block device appears to contain this partition type, - * -ve if not + * -ENOENT if not, -EIO if there was an I/O error, other value if some + * other error occurred */ int (*test)(struct blk_desc *desc); }; -- 2.43.0