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