X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=board%2Fkaro%2Fcommon%2Fmmc.c;h=6143e1575649dac9f7af379a836ed0ea4c4340e8;hb=01ced72cdb2dde4d334069f6170abf0f27b56dbc;hp=635220e24bf733c9d8a06df47696376a6e3c311a;hpb=10113154efb97566a3e2f7af991bed838388c9c0;p=karo-tx-uboot.git diff --git a/board/karo/common/mmc.c b/board/karo/common/mmc.c index 635220e24b..6143e15756 100644 --- a/board/karo/common/mmc.c +++ b/board/karo/common/mmc.c @@ -13,55 +13,36 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * -*/ + */ #include #include #include #include -//#include #include #include +#include +#include +#include #include #include #include -#include #include "karo.h" -#define CONFIG_MMC_BOOT_DEV 0 - DECLARE_GLOBAL_DATA_PTR; -static void __maybe_unused memdmp(void *addr, size_t len) -{ - size_t i; - - for (i = 0; i < len; i+= 16) { - size_t j; - u32 *wp = addr + i; - - debug("%p: ", addr + i); - for (j = 0; j < 4; j++) { - debug(" %08x", wp[j]); - } - debug("\n"); - } -} - #define MAX_SEARCH_PARTITIONS 16 -static int find_efi_partition(const char *ifname, int devno, const char *part_str, - block_dev_desc_t **dev_desc, - disk_partition_t *info) +static int find_partitions(const char *ifname, int devno, int fstype, + block_dev_desc_t **dev_desc, disk_partition_t *info) { int ret = -1; char *dup_str = NULL; int p; int part; block_dev_desc_t *dd; - -printf("Searching for partition '%s'\n", part_str); + char dev_part_str[16]; dd = get_dev(ifname, devno); if (!dd || dd->type == DEV_TYPE_UNKNOWN) { @@ -75,8 +56,8 @@ printf("Searching for partition '%s'\n", part_str); * or user requested partition 0 (entire device). */ if (dd->part_type == PART_TYPE_UNKNOWN) { - printf("** No partition table - %s %d **\n", ifname, - devno); + printf("** No partition table on device %s %d **\n", + ifname, devno); goto cleanup; } @@ -86,18 +67,20 @@ printf("Searching for partition '%s'\n", part_str); if (ret) continue; - if (strcmp((char *)info->name, part_str) == 0) { + if (fat_register_device(dd, p) == 0) { part = p; dd->log2blksz = LOG2(dd->blksz); break; } } if (!part) { - printf("** No valid partitions found **\n"); + printf("** No valid partition on device %s %d **\n", + ifname, devno); ret = -1; goto cleanup; } - + snprintf(dev_part_str, sizeof(dev_part_str), "%d:%d", devno, part); + fs_set_blk_dev(ifname, dev_part_str, fstype); ret = part; *dev_desc = dd; @@ -106,13 +89,41 @@ cleanup: return ret; } +static int karo_mmc_find_part(struct mmc *mmc, const char *part, int devno, + disk_partition_t *part_info) +{ + int ret; + block_dev_desc_t *mmc_dev; + +#if defined(CONFIG_SYS_DTB_OFFSET) && defined(CONFIG_SYS_MMC_ENV_PART) + if (strcmp(part, "dtb") == 0) { + const int partnum = CONFIG_SYS_MMC_ENV_PART; + + part_info->blksz = mmc->read_bl_len; + part_info->start = CONFIG_SYS_DTB_OFFSET / part_info->blksz; + part_info->size = CONFIG_SYS_DTB_PART_SIZE / part_info->blksz; + printf("Using virtual partition %s(%d) ["LBAF".."LBAF"]\n", + part, partnum, part_info->start, + part_info->start + part_info->size - 1); + return partnum; + } +#endif + ret = find_partitions("mmc", devno, FS_TYPE_FAT, &mmc_dev, part_info); + if (ret < 0) { + printf("No (e)MMC partition found: %d\n", ret); + return ret; + } + return 0; +} + int karo_load_mmc_part(const char *part, void *addr, size_t len) { int ret; struct mmc *mmc; disk_partition_t part_info; - int devno = CONFIG_MMC_BOOT_DEV; - uint blk_start, blk_cnt; + int devno = CONFIG_SYS_MMC_ENV_DEV; + lbaint_t blk_cnt; + int partnum; mmc = find_mmc_device(devno); if (!mmc) { @@ -120,46 +131,56 @@ int karo_load_mmc_part(const char *part, void *addr, size_t len) return -ENODEV; } - mmc_init(mmc); + if (mmc_init(mmc)) { + printf("Failed to init MMC device %d\n", devno); + return -EIO; + } -// mmc_boot_part_access(mmc, 1, part_num, part_num); -#if 1 - block_dev_desc_t *mmc_dev; + blk_cnt = DIV_ROUND_UP(len, mmc->read_bl_len); - ret = find_efi_partition("mmc", devno, part, &mmc_dev, &part_info); - if (ret < 0) { - printf("eMMC partition '%s' not found: %d\n", part, ret); - goto out; - } - mmc_switch_part(devno, ret); + partnum = karo_mmc_find_part(mmc, part, devno, &part_info); + if (partnum > 0) { + if (part_info.start + blk_cnt < part_info.start) { + printf("%s: given length 0x%08x exceeds size of partition\n", + __func__, len); + return -EINVAL; + } + if (part_info.start + blk_cnt > mmc->block_dev.lba) + blk_cnt = mmc->block_dev.lba - part_info.start; - blk_start = 0; - blk_cnt = DIV_ROUND_UP(len, part_info.blksz); + mmc_switch_part(devno, partnum); - printf("Using mmc%d blksz %lu blks %lu\n", devno, - mmc_dev->blksz, mmc_dev->lba); -#endif - debug("Found partition '%s': offset=%08x size=%08lx\n", - part, blk_start, part_info.size); - if (part_info.size < blk_cnt) { - printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %lu blocks\n", - part, len, part_info.size * mmc->read_bl_len); - blk_cnt = part_info.size; - } + memset(addr, 0xee, len); - debug("Reading %u blks from MMC partition '%s' offset %u to %p\n", - blk_cnt, part, blk_start, addr); - ret = mmc->block_dev.block_read(devno, blk_start, blk_cnt, addr); - if (ret == 0) { - printf("Failed to read MMC partition %s\n", part); + debug("Reading 0x"LBAF" blks from MMC partition %d offset 0x"LBAF" to %p\n", + blk_cnt, partnum, part_info.start, addr); + ret = mmc->block_dev.block_read(devno, part_info.start, blk_cnt, addr); + if (ret == 0) { + printf("Failed to read MMC partition %s\n", part); + ret = -EIO; + goto out; + } + debug("Read %u (%u) byte from partition '%s' @ offset 0x"LBAF"\n", + ret * mmc->read_bl_len, len, part, part_info.start); + } else if (partnum == 0) { + loff_t len_read; + + debug("Trying to read (%u) byte from file '%s' in mmc partition %d\n", + len, part, partnum); + ret = fs_read(part, (ulong)addr, 0, len, &len_read); + if (ret < 0) { + printf("Failed to read %u byte from %s in mmc partition %d; err: %d\n", + len, part, partnum, ret); + goto out; + } + debug("Read %llu bytes from %s\n", len_read, part); + } else { + ret = partnum; goto out; } - debug("Read %u byte from partition '%s' @ offset %08x\n", - ret * mmc->read_bl_len, part, blk_start); - memdmp(addr, 512); ret = 0; out: -// mmc_boot_part_access(mmc, 1, part_num, 0); - mmc_switch_part(devno, 0); - return ret; + if (partnum > 0) + mmc_switch_part(devno, 0); + return ret < 0 ? ret : 0; }