diff options
| -rw-r--r-- | README | 6 | ||||
| -rw-r--r-- | drivers/dfu/Makefile | 1 | ||||
| -rw-r--r-- | drivers/dfu/dfu.c | 7 | ||||
| -rw-r--r-- | drivers/dfu/dfu_ram.c | 77 | ||||
| -rw-r--r-- | include/dfu.h | 18 | 
5 files changed, 107 insertions, 2 deletions
| @@ -1409,6 +1409,12 @@ The following options need to be configured:  		CONFIG_DFU_NAND  		This enables support for exposing NAND devices via DFU. +		CONFIG_DFU_RAM +		This enables support for exposing RAM via DFU. +		Note: DFU spec refer to non-volatile memory usage, but +		allow usages beyond the scope of spec - here RAM usage, +		one that would help mostly the developer. +  		CONFIG_SYS_DFU_DATA_BUF_SIZE  		Dfu transfer uses a buffer before writing data to the  		raw storage device. Make the size (in bytes) of this buffer diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile index fca370ae0..de9e44e1e 100644 --- a/drivers/dfu/Makefile +++ b/drivers/dfu/Makefile @@ -12,6 +12,7 @@ LIB	= $(obj)libdfu.o  COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o  COBJS-$(CONFIG_DFU_MMC) += dfu_mmc.o  COBJS-$(CONFIG_DFU_NAND) += dfu_nand.o +COBJS-$(CONFIG_DFU_RAM) += dfu_ram.o  SRCS    := $(COBJS-y:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS-y)) diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 689f5dbde..56b21c78a 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -348,6 +348,9 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,  	} else if (strcmp(interface, "nand") == 0) {  		if (dfu_fill_entity_nand(dfu, s))  			return -1; +	} else if (strcmp(interface, "ram") == 0) { +		if (dfu_fill_entity_ram(dfu, s)) +			return -1;  	} else {  		printf("%s: Device %s not (yet) supported!\n",  		       __func__,  interface); @@ -397,14 +400,14 @@ int dfu_config_entities(char *env, char *interface, int num)  const char *dfu_get_dev_type(enum dfu_device_type t)  { -	const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND" }; +	const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM" };  	return dev_t[t];  }  const char *dfu_get_layout(enum dfu_layout l)  {  	const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2", -					   "EXT3", "EXT4" }; +					   "EXT3", "EXT4", "RAM_ADDR" };  	return dfu_layout[l];  } diff --git a/drivers/dfu/dfu_ram.c b/drivers/dfu/dfu_ram.c new file mode 100644 index 000000000..335a8e1f2 --- /dev/null +++ b/drivers/dfu/dfu_ram.c @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2013 + * Afzal Mohammed <afzal.mohd.ma@gmail.com> + * + * Reference: dfu_mmc.c + * Copyright (C) 2012 Samsung Electronics + * author: Lukasz Majewski <l.majewski@samsung.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <dfu.h> + +static int dfu_transfer_medium_ram(enum dfu_op op, struct dfu_entity *dfu, +				   u64 offset, void *buf, long *len) +{ +	if (dfu->layout != DFU_RAM_ADDR) { +		error("unsupported layout: %s\n", dfu_get_layout(dfu->layout)); +		return  -EINVAL; +	} + +	if (offset > dfu->data.ram.size) { +		error("request exceeds allowed area\n"); +		return -EINVAL; +	} + +	if (op == DFU_OP_WRITE) +		memcpy(dfu->data.ram.start + offset, buf, *len); +	else +		memcpy(buf, dfu->data.ram.start + offset, *len); + +	return 0; +} + +static int dfu_write_medium_ram(struct dfu_entity *dfu, u64 offset, +				void *buf, long *len) +{ +	return dfu_transfer_medium_ram(DFU_OP_WRITE, dfu, offset, buf, len); +} + +static int dfu_read_medium_ram(struct dfu_entity *dfu, u64 offset, +			       void *buf, long *len) +{ +	if (!*len) { +		*len = dfu->data.ram.size; +		return 0; +	} + +	return dfu_transfer_medium_ram(DFU_OP_READ, dfu, offset, buf, len); +} + +int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s) +{ +	char *st; + +	dfu->dev_type = DFU_DEV_RAM; +	st = strsep(&s, " "); +	if (strcmp(st, "ram")) { +		error("unsupported device: %s\n", st); +		return -ENODEV; +	} + +	dfu->layout = DFU_RAM_ADDR; +	dfu->data.ram.start = (void *)simple_strtoul(s, &s, 16); +	s++; +	dfu->data.ram.size = simple_strtoul(s, &s, 16); + +	dfu->write_medium = dfu_write_medium_ram; +	dfu->read_medium = dfu_read_medium_ram; + +	dfu->inited = 0; + +	return 0; +} diff --git a/include/dfu.h b/include/dfu.h index 6a3e253b1..6f4bba455 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -19,6 +19,7 @@ enum dfu_device_type {  	DFU_DEV_MMC = 1,  	DFU_DEV_ONENAND,  	DFU_DEV_NAND, +	DFU_DEV_RAM,  };  enum dfu_layout { @@ -27,6 +28,7 @@ enum dfu_layout {  	DFU_FS_EXT2,  	DFU_FS_EXT3,  	DFU_FS_EXT4, +	DFU_RAM_ADDR,  };  enum dfu_op { @@ -56,6 +58,11 @@ struct nand_internal_data {  	unsigned int ubi;  }; +struct ram_internal_data { +	void		*start; +	unsigned int	size; +}; +  static inline unsigned int get_mmc_blk_size(int dev)  {  	return find_mmc_device(dev)->read_bl_len; @@ -81,6 +88,7 @@ struct dfu_entity {  	union {  		struct mmc_internal_data mmc;  		struct nand_internal_data nand; +		struct ram_internal_data ram;  	} data;  	int (*read_medium)(struct dfu_entity *dfu, @@ -143,4 +151,14 @@ static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)  }  #endif +#ifdef CONFIG_DFU_RAM +extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s); +#else +static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s) +{ +	puts("RAM support not available!\n"); +	return -1; +} +#endif +  #endif /* __DFU_ENTITY_H_ */ |