X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fdfu%2Fdfu_mmc.c;h=926ccbd2ef5e9eac95d2083f6047c9abcee2ef0a;hb=664ee4c995c82b357a328da94880e37e7abb0a09;hp=fd865e11212e13ec9dce85de6a210cf880646919;hpb=a538ae997ae4cb375ba5362b50ba3f5b35f9519b;p=u-boot diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index fd865e1121..926ccbd2ef 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -18,23 +18,7 @@ static unsigned char *dfu_file_buf; static long dfu_file_buf_len; - -static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part) -{ - int ret; - - if (part == mmc->part_num) - return 0; - - ret = mmc_switch_part(dfu->data.mmc.dev_num, part); - if (ret) { - error("Cannot switch to partition %d\n", part); - return ret; - } - mmc->part_num = part; - - return 0; -} +static long dfu_file_buf_filled; static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, u64 offset, void *buf, long *len) @@ -65,8 +49,10 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, } if (dfu->data.mmc.hw_partition >= 0) { - part_num_bkp = mmc->part_num; - ret = mmc_access_part(dfu, mmc, dfu->data.mmc.hw_partition); + part_num_bkp = mmc_get_blk_desc(mmc)->hwpart; + ret = blk_select_hwpart_devnum(IF_TYPE_MMC, + dfu->data.mmc.dev_num, + dfu->data.mmc.hw_partition); if (ret) return ret; } @@ -76,12 +62,11 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, dfu->data.mmc.dev_num, blk_start, blk_count, buf); switch (op) { case DFU_OP_READ: - n = mmc->block_dev.block_read(dfu->data.mmc.dev_num, blk_start, - blk_count, buf); + n = blk_dread(mmc_get_blk_desc(mmc), blk_start, blk_count, buf); break; case DFU_OP_WRITE: - n = mmc->block_dev.block_write(dfu->data.mmc.dev_num, blk_start, - blk_count, buf); + n = blk_dwrite(mmc_get_blk_desc(mmc), blk_start, blk_count, + buf); break; default: error("Operation not supported\n"); @@ -90,12 +75,16 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, if (n != blk_count) { error("MMC operation failed"); if (dfu->data.mmc.hw_partition >= 0) - mmc_access_part(dfu, mmc, part_num_bkp); + blk_select_hwpart_devnum(IF_TYPE_MMC, + dfu->data.mmc.dev_num, + part_num_bkp); return -EIO; } if (dfu->data.mmc.hw_partition >= 0) { - ret = mmc_access_part(dfu, mmc, part_num_bkp); + ret = blk_select_hwpart_devnum(IF_TYPE_MMC, + dfu->data.mmc.dev_num, + part_num_bkp); if (ret) return ret; } @@ -156,7 +145,7 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu, dfu->data.mmc.dev, dfu->data.mmc.part); if (op != DFU_OP_SIZE) - sprintf(cmd_buf + strlen(cmd_buf), " 0x%x", (unsigned int)buf); + sprintf(cmd_buf + strlen(cmd_buf), " %p", buf); sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name); @@ -230,9 +219,12 @@ long dfu_get_medium_size_mmc(struct dfu_entity *dfu) return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; case DFU_FS_FAT: case DFU_FS_EXT4: + dfu_file_buf_filled = -1; ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len); if (ret < 0) return ret; + if (len > CONFIG_SYS_DFU_MAX_FILE_SIZE) + return -1; return len; default: printf("%s: Layout (%s) not (yet) supported!\n", __func__, @@ -241,6 +233,27 @@ long dfu_get_medium_size_mmc(struct dfu_entity *dfu) } } +static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf, + long *len) +{ + int ret; + long file_len; + + if (dfu_file_buf_filled == -1) { + ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len); + if (ret < 0) + return ret; + dfu_file_buf_filled = file_len; + } + if (offset + *len > dfu_file_buf_filled) + return -EINVAL; + + /* Add to the current buffer. */ + memcpy(buf, dfu_file_buf + offset, *len); + + return 0; +} + int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, long *len) { @@ -252,7 +265,7 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, break; case DFU_FS_FAT: case DFU_FS_EXT4: - ret = mmc_file_op(DFU_OP_READ, dfu, buf, len); + ret = mmc_file_unbuffer(dfu, offset, buf, len); break; default: printf("%s: Layout (%s) not (yet) supported!\n", __func__, @@ -342,11 +355,11 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s) } else if (!strcmp(entity_type, "part")) { disk_partition_t partinfo; - block_dev_desc_t *blk_dev = &mmc->block_dev; + struct blk_desc *blk_dev = mmc_get_blk_desc(mmc); int mmcdev = second_arg; int mmcpart = third_arg; - if (get_partition_info(blk_dev, mmcpart, &partinfo) != 0) { + if (part_get_info(blk_dev, mmcpart, &partinfo) != 0) { error("Couldn't find part #%d on mmc device #%d\n", mmcpart, mmcdev); return -ENODEV;