]> git.ipfire.org Git - thirdparty/u-boot.git/blob - include/dfu.h
Convert CONFIG_CMD_MMC to Kconfig
[thirdparty/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 DFU_DEV_VIRT,
27 };
28
29 enum dfu_layout {
30 DFU_RAW_ADDR = 1,
31 DFU_FS_FAT,
32 DFU_FS_EXT2,
33 DFU_FS_EXT3,
34 DFU_FS_EXT4,
35 DFU_RAM_ADDR,
36 };
37
38 enum dfu_op {
39 DFU_OP_READ = 1,
40 DFU_OP_WRITE,
41 DFU_OP_SIZE,
42 };
43
44 struct mmc_internal_data {
45 int dev_num;
46
47 /* RAW programming */
48 unsigned int lba_start;
49 unsigned int lba_size;
50 unsigned int lba_blk_size;
51
52 /* eMMC HW partition access */
53 int hw_partition;
54
55 /* FAT/EXT */
56 unsigned int dev;
57 unsigned int part;
58 };
59
60 struct mtd_internal_data {
61 struct mtd_info *info;
62
63 /* RAW programming */
64 u64 start;
65 u64 size;
66 /* for ubi partition */
67 unsigned int ubi;
68 };
69
70 struct nand_internal_data {
71 /* RAW programming */
72 u64 start;
73 u64 size;
74
75 unsigned int dev;
76 unsigned int part;
77 /* for nand/ubi use */
78 unsigned int ubi;
79 };
80
81 struct ram_internal_data {
82 void *start;
83 unsigned int size;
84 };
85
86 struct sf_internal_data {
87 struct spi_flash *dev;
88
89 /* RAW programming */
90 u64 start;
91 u64 size;
92 /* for sf/ubi use */
93 unsigned int ubi;
94 };
95
96 struct virt_internal_data {
97 int dev_num;
98 };
99
100 #define DFU_NAME_SIZE 32
101 #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
102 #define CONFIG_SYS_DFU_DATA_BUF_SIZE (1024*1024*8) /* 8 MiB */
103 #endif
104 #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
105 #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
106 #endif
107 #ifndef DFU_DEFAULT_POLL_TIMEOUT
108 #define DFU_DEFAULT_POLL_TIMEOUT 0
109 #endif
110 #ifndef DFU_MANIFEST_POLL_TIMEOUT
111 #define DFU_MANIFEST_POLL_TIMEOUT DFU_DEFAULT_POLL_TIMEOUT
112 #endif
113
114 struct dfu_entity {
115 char name[DFU_NAME_SIZE];
116 int alt;
117 void *dev_private;
118 enum dfu_device_type dev_type;
119 enum dfu_layout layout;
120 unsigned long max_buf_size;
121
122 union {
123 struct mmc_internal_data mmc;
124 struct mtd_internal_data mtd;
125 struct nand_internal_data nand;
126 struct ram_internal_data ram;
127 struct sf_internal_data sf;
128 struct virt_internal_data virt;
129 } data;
130
131 int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
132
133 int (*read_medium)(struct dfu_entity *dfu,
134 u64 offset, void *buf, long *len);
135
136 int (*write_medium)(struct dfu_entity *dfu,
137 u64 offset, void *buf, long *len);
138
139 int (*flush_medium)(struct dfu_entity *dfu);
140 unsigned int (*poll_timeout)(struct dfu_entity *dfu);
141
142 void (*free_entity)(struct dfu_entity *dfu);
143
144 struct list_head list;
145
146 /* on the fly state */
147 u32 crc;
148 u64 offset;
149 int i_blk_seq_num;
150 u8 *i_buf;
151 u8 *i_buf_start;
152 u8 *i_buf_end;
153 u64 r_left;
154 long b_left;
155
156 u32 bad_skip; /* for nand use */
157
158 unsigned int inited:1;
159 };
160
161 #ifdef CONFIG_SET_DFU_ALT_INFO
162 /**
163 * set_dfu_alt_info() - set dfu_alt_info environment variable
164 *
165 * If CONFIG_SET_DFU_ALT_INFO=y, this board specific function is called to set
166 * environment variable dfu_alt_info.
167 *
168 * @interface: dfu interface, e.g. "mmc" or "nand"
169 * @devstr: device number as string
170 */
171 void set_dfu_alt_info(char *interface, char *devstr);
172 #endif
173
174 /**
175 * dfu_alt_init() - initialize buffer for dfu entities
176 *
177 * @num: number of entities
178 * @dfu: on return allocated buffer
179 * Return: 0 on success
180 */
181 int dfu_alt_init(int num, struct dfu_entity **dfu);
182
183 /**
184 * dfu_alt_add() - add alternate to dfu entity buffer
185 *
186 * @dfu: dfu entity
187 * @interface: dfu interface, e.g. "mmc" or "nand"
188 * @devstr: device number as string
189 * @s: string description of alternate
190 * Return: 0 on success
191 */
192 int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s);
193
194 /**
195 * dfu_config_entities() - initialize dfu entitities from envirionment
196 *
197 * Initialize the list of dfu entities from environment variable dfu_alt_info.
198 * The list must be freed by calling dfu_free_entities(). This function bypasses
199 * set_dfu_alt_info(). So typically you should use dfu_init_env_entities()
200 * instead.
201 *
202 * See function :c:func:`dfu_free_entities`
203 * See function :c:func:`dfu_init_env_entities`
204 *
205 * @s: string with alternates
206 * @interface: interface, e.g. "mmc" or "nand"
207 * @devstr: device number as string
208 * Return: 0 on success, a negative error code otherwise
209 */
210 int dfu_config_entities(char *s, char *interface, char *devstr);
211
212 /**
213 * dfu_free_entities() - free the list of dfu entities
214 *
215 * Free the internal list of dfu entities.
216 *
217 * See function :c:func:`dfu_init_env_entities`
218 */
219 void dfu_free_entities(void);
220
221 /**
222 * dfu_show_entities() - print DFU alt settings list
223 */
224 void dfu_show_entities(void);
225
226 /**
227 * dfu_get_alt_number() - get number of alternates
228 *
229 * Return: number of alternates in the dfu entities list
230 */
231 int dfu_get_alt_number(void);
232
233 /**
234 * dfu_get_dev_type() - get string representation for dfu device type
235 *
236 * @type: device type
237 * Return: string representation for device type
238 */
239 const char *dfu_get_dev_type(enum dfu_device_type type);
240
241 /**
242 * dfu_get_layout() - get string describing layout
243 *
244 * Internally layouts are represented by enum dfu_device_type values. This
245 * function translates an enum value to a human readable string, e.g. DFU_FS_FAT
246 * is translated to "FAT".
247 *
248 * @layout: layout
249 * Result: string representation for the layout
250 */
251 const char *dfu_get_layout(enum dfu_layout layout);
252
253 /**
254 * dfu_get_entity() - get dfu entity for an alternate id
255 *
256 * @alt: alternate id
257 * Return: dfu entity
258 */
259 struct dfu_entity *dfu_get_entity(int alt);
260
261 char *dfu_extract_token(char** e, int *n);
262
263 /**
264 * dfu_get_alt() - get alternate id for filename
265 *
266 * Environment variable dfu_alt_info defines the write destinations (alternates)
267 * for different filenames. This function get the index of the alternate for
268 * a filename. If an absolute filename is provided (starting with '/'), the
269 * directory path is ignored.
270 *
271 * @name: filename
272 * Return: id of the alternate or negative error number (-ENODEV)
273 */
274 int dfu_get_alt(char *name);
275
276 /**
277 * dfu_init_env_entities() - initialize dfu entitities from envirionment
278 *
279 * Initialize the list of dfu entities from environment variable dfu_alt_info.
280 * The list must be freed by calling dfu_free_entities().
281 * @interface and @devstr are used to select the relevant set of alternates
282 * from environment variable dfu_alt_info.
283 *
284 * If environment variable dfu_alt_info specifies the interface and the device,
285 * use NULL for @interface and @devstr.
286 *
287 * See function :c:func:`dfu_free_entities`
288 *
289 * @interface: interface, e.g. "mmc" or "nand"
290 * @devstr: device number as string
291 * Return: 0 on success, a negative error code otherwise
292 */
293 int dfu_init_env_entities(char *interface, char *devstr);
294
295 unsigned char *dfu_get_buf(struct dfu_entity *dfu);
296 unsigned char *dfu_free_buf(void);
297 unsigned long dfu_get_buf_size(void);
298 bool dfu_usb_get_reset(void);
299
300 #ifdef CONFIG_DFU_TIMEOUT
301 unsigned long dfu_get_timeout(void);
302 void dfu_set_timeout(unsigned long);
303 #endif
304
305 /**
306 * dfu_read() - read from dfu entity
307 *
308 * The block sequence number @blk_seq_num is a 16 bit counter that must be
309 * incremented with each call for the same dfu entity @de.
310 *
311 * @de: dfu entity
312 * @buf: buffer
313 * @size: size of buffer
314 * @blk_seq_num: block sequence number
315 * Return: 0 for success, -1 for error
316 */
317 int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
318
319 /**
320 * dfu_write() - write to dfu entity
321 *
322 * Write the contents of a buffer @buf to the dfu entity @de. After writing
323 * the last block call dfu_flush(). If a file is already loaded completely
324 * into memory it is preferable to use dfu_write_from_mem_addr() which takes
325 * care of blockwise transfer and flushing.
326 *
327 * The block sequence number @blk_seq_num is a 16 bit counter that must be
328 * incremented with each call for the same dfu entity @de.
329 *
330 * See function :c:func:`dfu_flush`
331 * See function :c:func:`dfu_write_from_mem_addr`
332 *
333 * @de: dfu entity
334 * @buf: buffer
335 * @size: size of buffer
336 * @blk_seq_num: block sequence number
337 * Return: 0 for success, -1 for error
338 */
339 int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
340
341 /**
342 * dfu_flush() - flush to dfu entity
343 *
344 * This function has to be called after writing the last block to the dfu
345 * entity @de.
346 *
347 * The block sequence number @blk_seq_num is a 16 bit counter that must be
348 * incremented with each call for the same dfu entity @de.
349 *
350 * See function :c:func:`dfu_write`
351 *
352 * @de: dfu entity
353 * @buf: ignored
354 * @size: ignored
355 * @blk_seq_num: block sequence number of last write - ignored
356 * Return: 0 for success, -1 for error
357 */
358 int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
359
360 /**
361 * dfu_initiated_callback() - weak callback called on DFU transaction start
362 *
363 * It is a callback function called by DFU stack when a DFU transaction is
364 * initiated. This function allows to manage some board specific behavior on
365 * DFU targets.
366 *
367 * @dfu: pointer to the dfu_entity, which should be initialized
368 */
369 void dfu_initiated_callback(struct dfu_entity *dfu);
370
371 /**
372 * dfu_flush_callback() - weak callback called at the end of the DFU write
373 *
374 * It is a callback function called by DFU stack after DFU manifestation.
375 * This function allows to manage some board specific behavior on DFU targets
376 *
377 * @dfu: pointer to the dfu_entity, which should be flushed
378 */
379 void dfu_flush_callback(struct dfu_entity *dfu);
380
381 int dfu_transaction_initiate(struct dfu_entity *dfu, bool read);
382 void dfu_transaction_cleanup(struct dfu_entity *dfu);
383
384 /*
385 * dfu_defer_flush - pointer to store dfu_entity for deferred flashing.
386 * It should be NULL when not used.
387 */
388 extern struct dfu_entity *dfu_defer_flush;
389
390 /**
391 * dfu_get_defer_flush() - get current value of dfu_defer_flush pointer
392 *
393 * Return: value of the dfu_defer_flush pointer
394 */
395 static inline struct dfu_entity *dfu_get_defer_flush(void)
396 {
397 return dfu_defer_flush;
398 }
399
400 /**
401 * dfu_set_defer_flush() - set the dfu_defer_flush pointer
402 *
403 * @dfu: pointer to the dfu_entity, which should be written
404 */
405 static inline void dfu_set_defer_flush(struct dfu_entity *dfu)
406 {
407 dfu_defer_flush = dfu;
408 }
409
410 /**
411 * dfu_write_from_mem_addr() - write data from memory to DFU managed medium
412 *
413 * This function adds support for writing data starting from fixed memory
414 * address (like $loadaddr) to dfu managed medium (e.g. NAND, MMC, file system)
415 *
416 * @dfu: dfu entity to which we want to store data
417 * @buf: fixed memory address from where data starts
418 * @size: number of bytes to write
419 *
420 * Return: 0 on success, other value on failure
421 */
422 int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size);
423
424 /* Device specific */
425 #if CONFIG_IS_ENABLED(DFU_MMC)
426 extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s);
427 #else
428 static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr,
429 char *s)
430 {
431 puts("MMC support not available!\n");
432 return -1;
433 }
434 #endif
435
436 #if CONFIG_IS_ENABLED(DFU_NAND)
437 extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr, char *s);
438 #else
439 static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr,
440 char *s)
441 {
442 puts("NAND support not available!\n");
443 return -1;
444 }
445 #endif
446
447 #if CONFIG_IS_ENABLED(DFU_RAM)
448 extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s);
449 #else
450 static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr,
451 char *s)
452 {
453 puts("RAM support not available!\n");
454 return -1;
455 }
456 #endif
457
458 #if CONFIG_IS_ENABLED(DFU_SF)
459 extern int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s);
460 #else
461 static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
462 char *s)
463 {
464 puts("SF support not available!\n");
465 return -1;
466 }
467 #endif
468
469 #if CONFIG_IS_ENABLED(DFU_MTD)
470 int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s);
471 #else
472 static inline int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr,
473 char *s)
474 {
475 puts("MTD support not available!\n");
476 return -1;
477 }
478 #endif
479
480 #ifdef CONFIG_DFU_VIRT
481 int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, char *s);
482 int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset,
483 void *buf, long *len);
484 int dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size);
485 int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
486 void *buf, long *len);
487 #else
488 static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr,
489 char *s)
490 {
491 puts("VIRT support not available!\n");
492 return -1;
493 }
494 #endif
495
496 /**
497 * dfu_tftp_write() - write TFTP data to DFU medium
498 *
499 * This function is storing data received via TFTP on DFU supported medium.
500 *
501 * @dfu_entity_name: name of DFU entity to write
502 * @addr: address of data buffer to write
503 * @len: number of bytes
504 * @interface: destination DFU medium (e.g. "mmc")
505 * @devstring: instance number of destination DFU medium (e.g. "1")
506 *
507 * Return: 0 on success, otherwise error code
508 */
509 #if CONFIG_IS_ENABLED(DFU_TFTP)
510 int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len,
511 char *interface, char *devstring);
512 #else
513 static inline int dfu_tftp_write(char *dfu_entity_name, unsigned int addr,
514 unsigned int len, char *interface,
515 char *devstring)
516 {
517 puts("TFTP write support for DFU not available!\n");
518 return -ENOSYS;
519 }
520 #endif
521
522 int dfu_add(struct usb_configuration *c);
523 #endif /* __DFU_ENTITY_H_ */