#include <fat.h>
#include <mmc.h>
-static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE)
- dfu_file_buf[CONFIG_SYS_DFU_MAX_FILE_SIZE];
+static unsigned char *dfu_file_buf;
static long dfu_file_buf_len;
+static long dfu_file_buf_filled;
static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part)
{
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);
if (dfu->layout != DFU_RAW_ADDR) {
/* Do stuff here. */
- ret = mmc_file_op(DFU_OP_WRITE, dfu, &dfu_file_buf,
+ ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf,
&dfu_file_buf_len);
/* Now that we're done */
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__,
}
}
+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)
{
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__,
return ret;
}
+void dfu_free_entity_mmc(struct dfu_entity *dfu)
+{
+ if (dfu_file_buf) {
+ free(dfu_file_buf);
+ dfu_file_buf = NULL;
+ }
+}
+
/*
* @param s Parameter string containing space-separated arguments:
* 1st:
dfu->write_medium = dfu_write_medium_mmc;
dfu->flush_medium = dfu_flush_medium_mmc;
dfu->inited = 0;
+ dfu->free_entity = dfu_free_entity_mmc;
+
+ /* Check if file buffer is ready */
+ if (!dfu_file_buf) {
+ dfu_file_buf = memalign(CONFIG_SYS_CACHELINE_SIZE,
+ CONFIG_SYS_DFU_MAX_FILE_SIZE);
+ if (!dfu_file_buf) {
+ error("Could not memalign 0x%x bytes",
+ CONFIG_SYS_DFU_MAX_FILE_SIZE);
+ return -ENOMEM;
+ }
+ }
return 0;
}