Message ID | 1341308291-14663-4-git-send-email-l.majewski@samsung.com |
---|---|
State | Changes Requested |
Headers | show |
Dear Lukasz Majewski, > New, separate driver at ./drivers/dfu has been added. It allows platform > and storage independent operation of DFU. > > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > Cc: Marek Vasut <marex@denx.de> > --- [...] > +#include <common.h> > +#include <malloc.h> > +#include <mmc.h> > +#include <fat.h> > +#include <dfu.h> > +#include <linux/list.h> > +#include <linux/compiler.h> > + > +static LIST_HEAD(dfu_list); > +static int dfu_alt_num; > + > +static int dfu_find_alt_num(char *s) > +{ > + int i = 0; > + > + for (; *s; s++) > + if (*s == ';') > + i++; > + > + return ++i; > +} > + > +static char *dfu_extract_entity(char** env) > +{ > + char *s = *env; > + > + strsep(env, ";"); > + return s; > +} Shall we not make these all generic? They seem to be quite helpful components. > + > +char *dfu_extract_token(char** e, int *n) > +{ > + char *st = *e; > + > + debug("%s: %s\n", __func__, st); > + > + strsep(e, " "); > + *n = *e - st; > + > + return st; > +} > + > +static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) > + dfu_buf[DFU_DATA_BUF_SIZE]; Can we not stack-allocate it with ALLOC_CACHE_ALIGN_BUFFER()? [...] > diff --git a/include/dfu.h b/include/dfu.h > new file mode 100644 > index 0000000..f7d823b > --- /dev/null > +++ b/include/dfu.h [...] > +struct dfu_entity { > + char name[DFU_NAME_SIZE]; > + int alt; > + void *dev_private; > + int dev_num; > + enum dfu_device_type dev_type; > + enum dfu_layout layout; > + > + union { > + struct mmc_internal_data mmc; This union seems redundant ;-) [...]
Hi Marek, > Dear Lukasz Majewski, > > > New, separate driver at ./drivers/dfu has been added. It allows > > platform and storage independent operation of DFU. > > > > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com> > > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > > Cc: Marek Vasut <marex@denx.de> > > --- > > [...] > > > +#include <common.h> > > +#include <malloc.h> > > +#include <mmc.h> > > +#include <fat.h> > > +#include <dfu.h> > > +#include <linux/list.h> > > +#include <linux/compiler.h> > > + > > +static LIST_HEAD(dfu_list); > > +static int dfu_alt_num; > > + > > +static int dfu_find_alt_num(char *s) > > +{ > > + int i = 0; > > + > > + for (; *s; s++) > > + if (*s == ';') > > + i++; > > + > > + return ++i; > > +} > > + > > +static char *dfu_extract_entity(char** env) > > +{ > > + char *s = *env; > > + > > + strsep(env, ";"); > > + return s; > > +} > > Shall we not make these all generic? They seem to be quite helpful > components. It is a good topic for a discussion if those functions shall be moved to ./lib/string.c. I regarded them as a "little" helper functions for parsing DFU alt setting env variable. Those are very short and build with methods exported from string.c > > > + > > +char *dfu_extract_token(char** e, int *n) > > +{ > > + char *st = *e; > > + > > + debug("%s: %s\n", __func__, st); > > + > > + strsep(e, " "); > > + *n = *e - st; > > + > > + return st; > > +} > > + > > +static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) > > + dfu_buf[DFU_DATA_BUF_SIZE]; > > Can we not stack-allocate it with ALLOC_CACHE_ALIGN_BUFFER()? The dfu_buf is 4 MiB (this is the size of DFU_DATA_BUF_SIZE). I don't think, that allocating it on the stack (for stack allocation the ALLOC_CACHE_ALIGN_BUFFER() is designed) is a good idea. > > [...] > > > diff --git a/include/dfu.h b/include/dfu.h > > new file mode 100644 > > index 0000000..f7d823b > > --- /dev/null > > +++ b/include/dfu.h > > [...] > > > +struct dfu_entity { > > + char name[DFU_NAME_SIZE]; > > + int alt; > > + void *dev_private; > > + int dev_num; > > + enum dfu_device_type dev_type; > > + enum dfu_layout layout; > > + > > + union { > > + struct mmc_internal_data mmc; > > This union seems redundant ;-) Good point :-), but I predict, that DFU will be used to program other memory types (OneNAND, or NAND). To support those, one needs to extend the union with e.g struct onenand_internal_data onenand. Since we don't have so many memory types, I think that union usage is acceptable. > > [...]
Dear Lukasz Majewski, > Hi Marek, > > > Dear Lukasz Majewski, > > > > > New, separate driver at ./drivers/dfu has been added. It allows > > > platform and storage independent operation of DFU. > > > > > > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com> > > > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > > > Cc: Marek Vasut <marex@denx.de> > > > --- > > > > [...] > > > > > +#include <common.h> > > > +#include <malloc.h> > > > +#include <mmc.h> > > > +#include <fat.h> > > > +#include <dfu.h> > > > +#include <linux/list.h> > > > +#include <linux/compiler.h> > > > + > > > +static LIST_HEAD(dfu_list); > > > +static int dfu_alt_num; > > > + > > > +static int dfu_find_alt_num(char *s) > > > +{ > > > + int i = 0; > > > + > > > + for (; *s; s++) > > > + if (*s == ';') > > > + i++; > > > + > > > + return ++i; > > > +} > > > + > > > +static char *dfu_extract_entity(char** env) > > > +{ > > > + char *s = *env; > > > + > > > + strsep(env, ";"); > > > + return s; > > > +} > > > > Shall we not make these all generic? They seem to be quite helpful > > components. > > It is a good topic for a discussion if those functions shall be moved > to ./lib/string.c. > I regarded them as a "little" helper functions for parsing DFU alt > setting env variable. Those are very short and build with methods > exported from string.c Good point > > > + > > > +char *dfu_extract_token(char** e, int *n) > > > +{ > > > + char *st = *e; > > > + > > > + debug("%s: %s\n", __func__, st); > > > + > > > + strsep(e, " "); > > > + *n = *e - st; > > > + > > > + return st; > > > +} > > > + > > > +static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) > > > + dfu_buf[DFU_DATA_BUF_SIZE]; > > > > Can we not stack-allocate it with ALLOC_CACHE_ALIGN_BUFFER()? > > The dfu_buf is 4 MiB (this is the size of DFU_DATA_BUF_SIZE). I don't > think, that allocating it on the stack (for stack allocation the > ALLOC_CACHE_ALIGN_BUFFER() is designed) is a good idea. Heh, agreed :-) > > [...] > > > > > diff --git a/include/dfu.h b/include/dfu.h > > > new file mode 100644 > > > index 0000000..f7d823b > > > --- /dev/null > > > +++ b/include/dfu.h > > > > [...] > > > > > +struct dfu_entity { > > > + char name[DFU_NAME_SIZE]; > > > + int alt; > > > + void *dev_private; > > > + int dev_num; > > > + enum dfu_device_type dev_type; > > > + enum dfu_layout layout; > > > + > > > + union { > > > + struct mmc_internal_data mmc; > > > > This union seems redundant ;-) > > Good point :-), but I predict, that DFU will be used to program other > memory types (OneNAND, or NAND). To support those, one needs to extend > the union with e.g struct onenand_internal_data onenand. > > Since we don't have so many memory types, I think that union usage is > acceptable. And will those pieces be implemented any soon ? :) > > [...] Best regards, Marek Vasut
Hi Marek, > Dear Lukasz Majewski, > > > Hi Marek, > > > > > Dear Lukasz Majewski, > > > > > > > New, separate driver at ./drivers/dfu has been added. It allows > > > > platform and storage independent operation of DFU. > > > > > > > > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com> > > > > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > > > > Cc: Marek Vasut <marex@denx.de> > > > > --- > > > > > > [...] > > > > > > > +#include <common.h> > > > > +#include <malloc.h> > > > > +#include <mmc.h> > > > > +#include <fat.h> > > > > +#include <dfu.h> > > > > +#include <linux/list.h> > > > > +#include <linux/compiler.h> > > > > + > > > > +static LIST_HEAD(dfu_list); > > > > +static int dfu_alt_num; > > > > + > > > > +static int dfu_find_alt_num(char *s) > > > > +{ > > > > + int i = 0; > > > > + > > > > + for (; *s; s++) > > > > + if (*s == ';') > > > > + i++; > > > > + > > > > + return ++i; > > > > +} > > > > + > > > > +static char *dfu_extract_entity(char** env) > > > > +{ > > > > + char *s = *env; > > > > + > > > > + strsep(env, ";"); > > > > + return s; > > > > +} > > > > > > Shall we not make these all generic? They seem to be quite helpful > > > components. > > > > It is a good topic for a discussion if those functions shall be > > moved to ./lib/string.c. > > I regarded them as a "little" helper functions for parsing DFU alt > > setting env variable. Those are very short and build with methods > > exported from string.c > > Good point > > > > > + > > > > +char *dfu_extract_token(char** e, int *n) > > > > +{ > > > > + char *st = *e; > > > > + > > > > + debug("%s: %s\n", __func__, st); > > > > + > > > > + strsep(e, " "); > > > > + *n = *e - st; > > > > + > > > > + return st; > > > > +} > > > > + > > > > +static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) > > > > + > > > > dfu_buf[DFU_DATA_BUF_SIZE]; > > > > > > Can we not stack-allocate it with ALLOC_CACHE_ALIGN_BUFFER()? > > > > The dfu_buf is 4 MiB (this is the size of DFU_DATA_BUF_SIZE). I > > don't think, that allocating it on the stack (for stack allocation > > the ALLOC_CACHE_ALIGN_BUFFER() is designed) is a good idea. > > Heh, agreed :-) > > > > [...] > > > > > > > diff --git a/include/dfu.h b/include/dfu.h > > > > new file mode 100644 > > > > index 0000000..f7d823b > > > > --- /dev/null > > > > +++ b/include/dfu.h > > > > > > [...] > > > > > > > +struct dfu_entity { > > > > + char name[DFU_NAME_SIZE]; > > > > + int alt; > > > > + void *dev_private; > > > > + int dev_num; > > > > + enum dfu_device_type dev_type; > > > > + enum dfu_layout layout; > > > > + > > > > + union { > > > > + struct mmc_internal_data mmc; > > > > > > This union seems redundant ;-) > > > > Good point :-), but I predict, that DFU will be used to program > > other memory types (OneNAND, or NAND). To support those, one needs > > to extend the union with e.g struct onenand_internal_data onenand. > > > > Since we don't have so many memory types, I think that union usage > > is acceptable. > > And will those pieces be implemented any soon ? :) :-). Since I'm the OneNAND custodian I shall keep in the back of my head, that support for this memory is important :-) > > > > [...] > > Best regards, > Marek Vasut
Dear Lukasz Majewski, [...] > > > > And will those pieces be implemented any soon ? :) > : > :-). Since I'm the OneNAND custodian I shall keep in the back of my > > head, that support for this memory is important :-) Good, will look forward to it :) Best regards, Marek Vasut
On Tuesday 03 July 2012 05:38:07 Lukasz Majewski wrote: > + puts("UPLOAD ... done\n"); > + puts("Ctrl+C to exit ...\n"); combine into a single puts() ? > +static int dfu_fill_entity(struct dfu_entity *dfu, char* s, int alt, > + char *interface, int num) > +{ > + char *st = NULL; > + int n = 0; > + > + debug("%s: %s interface: %s num: %d\n", __func__, s, interface, num); > + > + st = dfu_extract_token(&s, &n); > + strncpy((char *) &dfu->name, st, n); what's with the pointless cast ? just do: strncpy(dfu->name, st, n); also, "n" here is wrong. it should be sizeof(dfu->name), not (presumably) the length of st. considering this is the 2nd time i noticed this bug in the dfu patchset, you might want to do a grep on your patches to see if your other string related usage is wrong. > +void dfu_free_entities(void) > +{ > + struct dfu_entity *dfu = NULL, *p = NULL; no point in assigning to NULL here > +static char *dfu_get_dev_type(enum dfu_device_type t) static const char *... > +{ > + static char *dev_t[] = {NULL, "MMC", "ONENAND", "NAND" }; static const char * const dev_t[] = {...} > +static char *dfu_get_layout(enum dfu_device_type l) static const char *... > +{ > + static char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT" }; static const char * const dfu_layout[] = {...} > +void dfu_show_entities(void) > +{ > + struct dfu_entity *dfu = NULL; no point in assigning to NULL > +struct dfu_entity *dfu_get_entity(int alt) > +{ > + struct dfu_entity *dfu = NULL; no point in assigning to NULL -mike
Dear Mike Frysinger, > On Tuesday 03 July 2012 05:38:07 Lukasz Majewski wrote: > > + puts("UPLOAD ... done\n"); > > + puts("Ctrl+C to exit ...\n"); > > combine into a single puts() ? Ok, will be done > > > +static int dfu_fill_entity(struct dfu_entity *dfu, char* s, int > > alt, > > + char *interface, int num) > > +{ > > + char *st = NULL; > > + int n = 0; > > + > > + debug("%s: %s interface: %s num: %d\n", __func__, s, > > interface, num); + > > + st = dfu_extract_token(&s, &n); > > + strncpy((char *) &dfu->name, st, n); > > what's with the pointless cast ? just do: > strncpy(dfu->name, st, n); Yes, you are right. > > also, "n" here is wrong. it should be sizeof(dfu->name), not > (presumably) the length of st. considering this is the 2nd time i > noticed this bug in the dfu patchset, you might want to do a grep on > your patches to see if your other string related usage is wrong. I will double-check the string operations. > > > +void dfu_free_entities(void) > > +{ > > + struct dfu_entity *dfu = NULL, *p = NULL; > > no point in assigning to NULL here Will remove. > > > +static char *dfu_get_dev_type(enum dfu_device_type t) > > static const char *... Will correct. > > > +{ > > + static char *dev_t[] = {NULL, "MMC", "ONENAND", "NAND" }; > > static const char * const dev_t[] = {...} Ok > > > +static char *dfu_get_layout(enum dfu_device_type l) > > static const char *... > Ok > > +{ > > + static char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", > > "EXT" }; > > static const char * const dfu_layout[] = {...} > OK > > +void dfu_show_entities(void) > > +{ > > + struct dfu_entity *dfu = NULL; > > no point in assigning to NULL OK > > > +struct dfu_entity *dfu_get_entity(int alt) > > +{ > > + struct dfu_entity *dfu = NULL; > > no point in assigning to NULL OK > -mike
diff --git a/Makefile b/Makefile index 0197239..c37dcf3 100644 --- a/Makefile +++ b/Makefile @@ -271,6 +271,7 @@ LIBS += drivers/pci/libpci.o LIBS += drivers/pcmcia/libpcmcia.o LIBS += drivers/power/libpower.o LIBS += drivers/spi/libspi.o +LIBS += drivers/dfu/libdfu.o ifeq ($(CPU),mpc83xx) LIBS += drivers/qe/libqe.o LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile new file mode 100644 index 0000000..7736485 --- /dev/null +++ b/drivers/dfu/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2012 Samsung Electronics +# Lukasz Majewski <l.majewski@samsung.com> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libdfu.o + +COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c new file mode 100644 index 0000000..63733fb --- /dev/null +++ b/drivers/dfu/dfu.c @@ -0,0 +1,259 @@ +/* + * dfu.c -- DFU back-end routines + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com> + * Lukasz Majewski <l.majewski@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> +#include <mmc.h> +#include <fat.h> +#include <dfu.h> +#include <linux/list.h> +#include <linux/compiler.h> + +static LIST_HEAD(dfu_list); +static int dfu_alt_num; + +static int dfu_find_alt_num(char *s) +{ + int i = 0; + + for (; *s; s++) + if (*s == ';') + i++; + + return ++i; +} + +static char *dfu_extract_entity(char** env) +{ + char *s = *env; + + strsep(env, ";"); + return s; +} + +char *dfu_extract_token(char** e, int *n) +{ + char *st = *e; + + debug("%s: %s\n", __func__, st); + + strsep(e, " "); + *n = *e - st; + + return st; +} + +static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) + dfu_buf[DFU_DATA_BUF_SIZE]; + +int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) +{ + static unsigned char *i_buf; + static int i_blk_seq_num; + long w_size = 0; + int ret = 0; + + debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n", + __func__, dfu->name, buf, size, blk_seq_num, i_buf); + + if (blk_seq_num == 0) { + memset(dfu_buf, '\0', sizeof(dfu_buf)); + i_buf = dfu_buf; + i_blk_seq_num = 0; + } + + if (i_blk_seq_num++ != blk_seq_num) { + printf("%s: Wrong sequence number! [%d] [%d]\n", + __func__, i_blk_seq_num, blk_seq_num); + return -1; + } + + memcpy(i_buf, buf, size); + i_buf += size; + + if (size == 0) { + /* Integrity check (if needed) */ + debug("%s: %s %d [B] CRC32: 0x%x\n", __func__, dfu->name, + i_buf - dfu_buf, crc32(0, dfu_buf, i_buf - dfu_buf)); + + w_size = i_buf - dfu_buf; + ret = dfu->write_medium(dfu, dfu_buf, &w_size); + if (ret) + debug("%s: Write error!\n", __func__); + + i_blk_seq_num = 0; + i_buf = NULL; + return ret; + } + + return ret; +} + +int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) +{ + static unsigned char *i_buf; + static int i_blk_seq_num; + static long r_size; + static u32 crc; + int ret = 0; + + debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n", + __func__, dfu->name, buf, size, blk_seq_num, i_buf); + + if (blk_seq_num == 0) { + i_buf = dfu_buf; + memset(dfu_buf, '\0', sizeof(dfu_buf)); + ret = dfu->read_medium(dfu, i_buf, &r_size); + debug("%s: %s %ld [B]\n", __func__, dfu->name, r_size); + i_blk_seq_num = 0; + /* Integrity check (if needed) */ + crc = crc32(0, dfu_buf, r_size); + } + + if (i_blk_seq_num++ != blk_seq_num) { + printf("%s: Wrong sequence number! [%d] [%d]\n", + __func__, i_blk_seq_num, blk_seq_num); + return -1; + } + + if (r_size >= size) { + memcpy(buf, i_buf, size); + i_buf += size; + r_size -= size; + return size; + } else { + memcpy(buf, i_buf, r_size); + i_buf += r_size; + debug("%s: %s CRC32: 0x%x\n", __func__, dfu->name, crc); + puts("UPLOAD ... done\n"); + puts("Ctrl+C to exit ...\n"); + + i_buf = NULL; + i_blk_seq_num = 0; + crc = 0; + return r_size; + } + return ret; +} + +static int dfu_fill_entity(struct dfu_entity *dfu, char* s, int alt, + char *interface, int num) +{ + char *st = NULL; + int n = 0; + + debug("%s: %s interface: %s num: %d\n", __func__, s, interface, num); + + st = dfu_extract_token(&s, &n); + strncpy((char *) &dfu->name, st, n); + + dfu->dev_num = num; + dfu->alt = alt; + + /* Specific for mmc device */ + if (strcmp(interface, "mmc") == 0) { + if (dfu_fill_entity_mmc(dfu, s)) + return -1; + } else { + printf("dfu: Device %s not supported\n", interface); + return -1; + } + + return 0; +} + +int dfu_config_entities(char *env, char *interface, int num) +{ + struct dfu_entity *dfu; + int i, ret; + char *s; + + dfu_alt_num = dfu_find_alt_num(env); + debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num); + + for (i = 0; i < dfu_alt_num; i++) { + dfu = calloc(sizeof(struct dfu_entity), 1); + + s = dfu_extract_entity(&env); + ret = dfu_fill_entity(dfu, s, i, interface, num); + if (ret) + return -1; + + list_add_tail(&dfu->list, &dfu_list); + } + + return 0; +} + +void dfu_free_entities(void) +{ + struct dfu_entity *dfu = NULL, *p = NULL; + + list_for_each_entry_safe_reverse(dfu, p, &dfu_list, list) { + list_del(&dfu->list); + free(dfu); + } + + INIT_LIST_HEAD(&dfu_list); +} + +static char *dfu_get_dev_type(enum dfu_device_type t) +{ + static char *dev_t[] = {NULL, "MMC", "ONENAND", "NAND" }; + return dev_t[t]; +} + +static char *dfu_get_layout(enum dfu_device_type l) +{ + static char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT" }; + return dfu_layout[l]; +} + +void dfu_show_entities(void) +{ + struct dfu_entity *dfu = NULL; + + puts("DFU alt settings list:\n"); + + list_for_each_entry(dfu, &dfu_list, list) { + printf("dev: %s alt: %d name: %s layout: %s\n", + dfu_get_dev_type(dfu->dev_type), dfu->alt, + dfu->name, dfu_get_layout(dfu->layout)); + } +} + +int dfu_get_alt_number(void) +{ + return dfu_alt_num; +} + +struct dfu_entity *dfu_get_entity(int alt) +{ + struct dfu_entity *dfu = NULL; + + list_for_each_entry(dfu, &dfu_list, list) { + if (dfu->alt == alt) + return dfu; + } + + return NULL; +} diff --git a/include/dfu.h b/include/dfu.h new file mode 100644 index 0000000..f7d823b --- /dev/null +++ b/include/dfu.h @@ -0,0 +1,99 @@ +/* + * dfu.h - DFU flashable area description + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com> + * Lukasz Majewski <l.majewski@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __DFU_ENTITY_H_ +#define __DFU_ENTITY_H_ + +#include <common.h> +#include <linux/list.h> +#include <mmc.h> + +enum dfu_device_type { + MMC = 1, + ONENAND, + NAND +}; + +enum dfu_layout { + RAW_ADDR = 1, + FAT, + EXT, +}; + +struct mmc_internal_data { + /* RAW programming */ + unsigned int lba_start; + unsigned int lba_size; + unsigned int lba_blk_size; + + /* FAT/EXT */ + unsigned int dev; + unsigned int part; +}; + +static inline unsigned int get_mmc_blk_size(int dev) +{ + return find_mmc_device(dev)->read_bl_len; +} + +#define DFU_NAME_SIZE 32 +#define DFU_CMD_BUF_SIZE 128 +#define DFU_DATA_BUF_SIZE (1024*1024*4) /* 4 MiB */ + +struct dfu_entity { + char name[DFU_NAME_SIZE]; + int alt; + void *dev_private; + int dev_num; + enum dfu_device_type dev_type; + enum dfu_layout layout; + + union { + struct mmc_internal_data mmc; + } data; + + int (*read_medium)(struct dfu_entity *dfu, void *buf, long *len); + int (*write_medium)(struct dfu_entity *dfu, void *buf, long *len); + + struct list_head list; +}; + +int dfu_config_entities(char *s, char *interface, int num); +void dfu_free_entities(void); +void dfu_show_entities(void); +int dfu_get_alt_number(void); +struct dfu_entity *dfu_get_entity(int alt); +char *dfu_extract_token(char** e, int *n); + +int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); +int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num); +/* Device specific */ +#ifdef CONFIG_DFU_MMC +extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char* s); +#else +static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char* s) +{ + puts("MMC support not available!\n"); + return -1; +} +#endif +#endif /* __DFU_ENTITY_H_ */