diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 6842aef420f42d848d30789be55047ce12c6c58d..8f5915e49ca5e386f16d4778ef19a6cb0c399088 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -338,17 +338,6 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 		dfu->r_left = dfu->get_medium_size(dfu);
 		if (dfu->r_left < 0)
 			return dfu->r_left;
-		switch (dfu->layout) {
-		case DFU_RAW_ADDR:
-		case DFU_RAM_ADDR:
-			break;
-		default:
-			if (dfu->r_left > dfu_buf_size) {
-				printf("%s: File too big for buffer\n",
-				       __func__);
-				return -EOVERFLOW;
-			}
-		}
 
 		debug("%s: %s %ld [B]\n", __func__, dfu->name, dfu->r_left);
 
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 2a780f7b5d31ec7008e5ebde915b5a0ca3f083e4..5a9fb4a6e24780ed3fda556ca522cd697d5f90dc 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -18,6 +18,7 @@
 
 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)
 {
@@ -230,9 +231,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 +245,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 +277,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__,