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 #include #include @@ -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 #include #include +#include #include "part_dos.h" #include @@ -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 #include #include +#include #include #include @@ -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 #include #include +#include #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 #include "part_mac.h" #include +#include /* 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); };