dfu: add backend for MTD device
[platform/kernel/u-boot.git] / include / dfu.h
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * dfu.h - DFU flashable area description
4  *
5  * Copyright (C) 2012 Samsung Electronics
6  * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7  *          Lukasz Majewski <l.majewski@samsung.com>
8  */
9
10 #ifndef __DFU_ENTITY_H_
11 #define __DFU_ENTITY_H_
12
13 #include <common.h>
14 #include <linux/list.h>
15 #include <mmc.h>
16 #include <spi_flash.h>
17 #include <linux/usb/composite.h>
18
19 enum dfu_device_type {
20         DFU_DEV_MMC = 1,
21         DFU_DEV_ONENAND,
22         DFU_DEV_NAND,
23         DFU_DEV_RAM,
24         DFU_DEV_SF,
25         DFU_DEV_MTD,
26 };
27
28 enum dfu_layout {
29         DFU_RAW_ADDR = 1,
30         DFU_FS_FAT,
31         DFU_FS_EXT2,
32         DFU_FS_EXT3,
33         DFU_FS_EXT4,
34         DFU_RAM_ADDR,
35 };
36
37 enum dfu_op {
38         DFU_OP_READ = 1,
39         DFU_OP_WRITE,
40         DFU_OP_SIZE,
41 };
42
43 struct mmc_internal_data {
44         int dev_num;
45
46         /* RAW programming */
47         unsigned int lba_start;
48         unsigned int lba_size;
49         unsigned int lba_blk_size;
50
51         /* eMMC HW partition access */
52         int hw_partition;
53
54         /* FAT/EXT */
55         unsigned int dev;
56         unsigned int part;
57 };
58
59 struct mtd_internal_data {
60         struct mtd_info *info;
61
62         /* RAW programming */
63         u64 start;
64         u64 size;
65 };
66
67 struct nand_internal_data {
68         /* RAW programming */
69         u64 start;
70         u64 size;
71
72         unsigned int dev;
73         unsigned int part;
74         /* for nand/ubi use */
75         unsigned int ubi;
76 };
77
78 struct ram_internal_data {
79         void            *start;
80         unsigned int    size;
81 };
82
83 struct sf_internal_data {
84         struct spi_flash *dev;
85
86         /* RAW programming */
87         u64 start;
88         u64 size;
89         /* for sf/ubi use */
90         unsigned int ubi;
91 };
92
93 #define DFU_NAME_SIZE                   32
94 #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
95 #define CONFIG_SYS_DFU_DATA_BUF_SIZE            (1024*1024*8)   /* 8 MiB */
96 #endif
97 #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
98 #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
99 #endif
100 #ifndef DFU_DEFAULT_POLL_TIMEOUT
101 #define DFU_DEFAULT_POLL_TIMEOUT 0
102 #endif
103 #ifndef DFU_MANIFEST_POLL_TIMEOUT
104 #define DFU_MANIFEST_POLL_TIMEOUT       DFU_DEFAULT_POLL_TIMEOUT
105 #endif
106
107 struct dfu_entity {
108         char                    name[DFU_NAME_SIZE];
109         int                     alt;
110         void                    *dev_private;
111         enum dfu_device_type    dev_type;
112         enum dfu_layout         layout;
113         unsigned long           max_buf_size;
114
115         union {
116                 struct mmc_internal_data mmc;
117                 struct mtd_internal_data mtd;
118                 struct nand_internal_data nand;
119                 struct ram_internal_data ram;
120                 struct sf_internal_data sf;
121         } data;
122
123         int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
124
125         int (*read_medium)(struct dfu_entity *dfu,
126                         u64 offset, void *buf, long *len);
127
128         int (*write_medium)(struct dfu_entity *dfu,
129                         u64 offset, void *buf, long *len);
130
131         int (*flush_medium)(struct dfu_entity *dfu);
132         unsigned int (*poll_timeout)(struct dfu_entity *dfu);
133
134         void (*free_entity)(struct dfu_entity *dfu);
135
136         struct list_head list;
137
138         /* on the fly state */
139         u32 crc;
140         u64 offset;
141         int i_blk_seq_num;
142         u8 *i_buf;
143         u8 *i_buf_start;
144         u8 *i_buf_end;
145         u64 r_left;
146         long b_left;
147
148         u32 bad_skip;   /* for nand use */
149
150         unsigned int inited:1;
151 };
152
153 #ifdef CONFIG_SET_DFU_ALT_INFO
154 void set_dfu_alt_info(char *interface, char *devstr);
155 #endif
156 int dfu_alt_init(int num, struct dfu_entity **dfu);
157 int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s);
158 int dfu_config_entities(char *s, char *interface, char *devstr);
159 void dfu_free_entities(void);
160 void dfu_show_entities(void);
161 int dfu_get_alt_number(void);
162 const char *dfu_get_dev_type(enum dfu_device_type t);
163 const char *dfu_get_layout(enum dfu_layout l);
164 struct dfu_entity *dfu_get_entity(int alt);
165 char *dfu_extract_token(char** e, int *n);
166 void dfu_trigger_reset(void);
167 int dfu_get_alt(char *name);
168 int dfu_init_env_entities(char *interface, char *devstr);
169 unsigned char *dfu_get_buf(struct dfu_entity *dfu);
170 unsigned char *dfu_free_buf(void);
171 unsigned long dfu_get_buf_size(void);
172 bool dfu_usb_get_reset(void);
173
174 int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
175 int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
176 int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
177
178 /*
179  * dfu_defer_flush - pointer to store dfu_entity for deferred flashing.
180  *                   It should be NULL when not used.
181  */
182 extern struct dfu_entity *dfu_defer_flush;
183 /**
184  * dfu_get_defer_flush - get current value of dfu_defer_flush pointer
185  *
186  * @return - value of the dfu_defer_flush pointer
187  */
188 static inline struct dfu_entity *dfu_get_defer_flush(void)
189 {
190         return dfu_defer_flush;
191 }
192
193 /**
194  * dfu_set_defer_flush - set the dfu_defer_flush pointer
195  *
196  * @param dfu - pointer to the dfu_entity, which should be written
197  */
198 static inline void dfu_set_defer_flush(struct dfu_entity *dfu)
199 {
200         dfu_defer_flush = dfu;
201 }
202
203 /**
204  * dfu_write_from_mem_addr - write data from memory to DFU managed medium
205  *
206  * This function adds support for writing data starting from fixed memory
207  * address (like $loadaddr) to dfu managed medium (e.g. NAND, MMC, file system)
208  *
209  * @param dfu - dfu entity to which we want to store data
210  * @param buf - fixed memory addres from where data starts
211  * @param size - number of bytes to write
212  *
213  * @return - 0 on success, other value on failure
214  */
215 int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size);
216
217 /* Device specific */
218 #if CONFIG_IS_ENABLED(DFU_MMC)
219 extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s);
220 #else
221 static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr,
222                                       char *s)
223 {
224         puts("MMC support not available!\n");
225         return -1;
226 }
227 #endif
228
229 #if CONFIG_IS_ENABLED(DFU_NAND)
230 extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr, char *s);
231 #else
232 static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr,
233                                        char *s)
234 {
235         puts("NAND support not available!\n");
236         return -1;
237 }
238 #endif
239
240 #if CONFIG_IS_ENABLED(DFU_RAM)
241 extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s);
242 #else
243 static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr,
244                                       char *s)
245 {
246         puts("RAM support not available!\n");
247         return -1;
248 }
249 #endif
250
251 #if CONFIG_IS_ENABLED(DFU_SF)
252 extern int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s);
253 #else
254 static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
255                                      char *s)
256 {
257         puts("SF support not available!\n");
258         return -1;
259 }
260 #endif
261
262 #if CONFIG_IS_ENABLED(DFU_MTD)
263 int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s);
264 #else
265 static inline int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr,
266                                       char *s)
267 {
268         puts("MTD support not available!\n");
269         return -1;
270 }
271 #endif
272
273 /**
274  * dfu_tftp_write - Write TFTP data to DFU medium
275  *
276  * This function is storing data received via TFTP on DFU supported medium.
277  *
278  * @param dfu_entity_name - name of DFU entity to write
279  * @param addr - address of data buffer to write
280  * @param len - number of bytes
281  * @param interface - destination DFU medium (e.g. "mmc")
282  * @param devstring - instance number of destination DFU medium (e.g. "1")
283  *
284  * @return 0 on success, otherwise error code
285  */
286 #if CONFIG_IS_ENABLED(DFU_TFTP)
287 int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len,
288                    char *interface, char *devstring);
289 #else
290 static inline int dfu_tftp_write(char *dfu_entity_name, unsigned int addr,
291                                  unsigned int len, char *interface,
292                                  char *devstring)
293 {
294         puts("TFTP write support for DFU not available!\n");
295         return -ENOSYS;
296 }
297 #endif
298
299 int dfu_add(struct usb_configuration *c);
300 #endif /* __DFU_ENTITY_H_ */