blob: a90732cc433d13fe9d3c1a087bd63247933211f0 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Lukasz Majewskif22b11c2012-08-06 14:41:07 +02002/*
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>
Lukasz Majewskif22b11c2012-08-06 14:41:07 +02008 */
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>
Stephen Warren6f12ebf2014-06-11 16:03:36 -060016#include <spi_flash.h>
Lukasz Majewskia6921ad2013-09-17 15:58:23 +020017#include <linux/usb/composite.h>
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020018
19enum dfu_device_type {
20 DFU_DEV_MMC = 1,
21 DFU_DEV_ONENAND,
22 DFU_DEV_NAND,
Afzal Mohammeda9479f02013-09-18 01:15:24 +053023 DFU_DEV_RAM,
Stephen Warren6f12ebf2014-06-11 16:03:36 -060024 DFU_DEV_SF,
Patrick Delaunay6015af22019-10-14 09:28:04 +020025 DFU_DEV_MTD,
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020026};
27
28enum dfu_layout {
29 DFU_RAW_ADDR = 1,
30 DFU_FS_FAT,
31 DFU_FS_EXT2,
32 DFU_FS_EXT3,
33 DFU_FS_EXT4,
Afzal Mohammeda9479f02013-09-18 01:15:24 +053034 DFU_RAM_ADDR,
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020035};
36
Afzal Mohammed5a127c82013-09-18 01:14:50 +053037enum dfu_op {
38 DFU_OP_READ = 1,
39 DFU_OP_WRITE,
Stephen Warren0e285b52014-06-11 12:47:27 -060040 DFU_OP_SIZE,
Afzal Mohammed5a127c82013-09-18 01:14:50 +053041};
42
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020043struct mmc_internal_data {
Stephen Warrendd648272014-06-11 16:03:33 -060044 int dev_num;
45
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020046 /* RAW programming */
47 unsigned int lba_start;
48 unsigned int lba_size;
49 unsigned int lba_blk_size;
50
Lukasz Majewskic8151b42014-05-09 16:58:15 +020051 /* eMMC HW partition access */
52 int hw_partition;
53
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020054 /* FAT/EXT */
55 unsigned int dev;
56 unsigned int part;
57};
58
Patrick Delaunay6015af22019-10-14 09:28:04 +020059struct mtd_internal_data {
60 struct mtd_info *info;
61
62 /* RAW programming */
63 u64 start;
64 u64 size;
Patrick Delaunayd5640f72019-10-14 09:28:05 +020065 /* for ubi partition */
66 unsigned int ubi;
Patrick Delaunay6015af22019-10-14 09:28:04 +020067};
68
Pantelis Antoniouc6631762013-03-14 05:32:52 +000069struct nand_internal_data {
70 /* RAW programming */
71 u64 start;
72 u64 size;
73
74 unsigned int dev;
75 unsigned int part;
Heiko Schocher815c30b2013-07-25 06:43:11 +020076 /* for nand/ubi use */
77 unsigned int ubi;
Pantelis Antoniouc6631762013-03-14 05:32:52 +000078};
79
Afzal Mohammeda9479f02013-09-18 01:15:24 +053080struct ram_internal_data {
81 void *start;
82 unsigned int size;
83};
84
Stephen Warren6f12ebf2014-06-11 16:03:36 -060085struct sf_internal_data {
86 struct spi_flash *dev;
87
88 /* RAW programming */
89 u64 start;
90 u64 size;
Patrick Delaunaycb986ba2019-10-14 09:28:00 +020091 /* for sf/ubi use */
92 unsigned int ubi;
Stephen Warren6f12ebf2014-06-11 16:03:36 -060093};
94
Tom Rinia24c3152013-03-14 05:32:49 +000095#define DFU_NAME_SIZE 32
Heiko Schochere7e75c72013-06-12 06:05:51 +020096#ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
97#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1024*1024*8) /* 8 MiB */
98#endif
Pantelis Antoniouea2453d2013-03-14 05:32:48 +000099#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
Lukasz Majewski7a813d52013-09-10 15:29:23 +0200100#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000101#endif
Lukasz Majewski33fac4a2013-12-09 16:20:14 +0100102#ifndef DFU_DEFAULT_POLL_TIMEOUT
103#define DFU_DEFAULT_POLL_TIMEOUT 0
104#endif
Heiko Schocher001a8312014-03-18 08:09:56 +0100105#ifndef DFU_MANIFEST_POLL_TIMEOUT
106#define DFU_MANIFEST_POLL_TIMEOUT DFU_DEFAULT_POLL_TIMEOUT
107#endif
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200108
109struct dfu_entity {
110 char name[DFU_NAME_SIZE];
111 int alt;
112 void *dev_private;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200113 enum dfu_device_type dev_type;
114 enum dfu_layout layout;
Stephen Warren7ac1b412014-06-11 16:03:34 -0600115 unsigned long max_buf_size;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200116
117 union {
118 struct mmc_internal_data mmc;
Patrick Delaunay6015af22019-10-14 09:28:04 +0200119 struct mtd_internal_data mtd;
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000120 struct nand_internal_data nand;
Afzal Mohammeda9479f02013-09-18 01:15:24 +0530121 struct ram_internal_data ram;
Stephen Warren6f12ebf2014-06-11 16:03:36 -0600122 struct sf_internal_data sf;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200123 } data;
124
Patrick Delaunay15970d82017-07-19 16:39:23 +0200125 int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
Stephen Warren0e285b52014-06-11 12:47:27 -0600126
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000127 int (*read_medium)(struct dfu_entity *dfu,
128 u64 offset, void *buf, long *len);
129
130 int (*write_medium)(struct dfu_entity *dfu,
131 u64 offset, void *buf, long *len);
132
133 int (*flush_medium)(struct dfu_entity *dfu);
Heiko Schocherfc25fa22014-04-11 07:59:47 +0200134 unsigned int (*poll_timeout)(struct dfu_entity *dfu);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200135
Stephen Warrencb7bd2e2014-06-11 16:03:35 -0600136 void (*free_entity)(struct dfu_entity *dfu);
137
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200138 struct list_head list;
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000139
140 /* on the fly state */
141 u32 crc;
142 u64 offset;
143 int i_blk_seq_num;
144 u8 *i_buf;
145 u8 *i_buf_start;
146 u8 *i_buf_end;
Patrick Delaunay15970d82017-07-19 16:39:23 +0200147 u64 r_left;
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000148 long b_left;
149
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000150 u32 bad_skip; /* for nand use */
151
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000152 unsigned int inited:1;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200153};
154
Przemyslaw Marczak899a5282015-02-17 12:24:11 +0100155#ifdef CONFIG_SET_DFU_ALT_INFO
156void set_dfu_alt_info(char *interface, char *devstr);
157#endif
Patrick Delaunay9ada6832019-10-14 09:28:01 +0200158int dfu_alt_init(int num, struct dfu_entity **dfu);
159int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s);
Stephen Warrendd648272014-06-11 16:03:33 -0600160int dfu_config_entities(char *s, char *interface, char *devstr);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200161void dfu_free_entities(void);
162void dfu_show_entities(void);
163int dfu_get_alt_number(void);
164const char *dfu_get_dev_type(enum dfu_device_type t);
165const char *dfu_get_layout(enum dfu_layout l);
166struct dfu_entity *dfu_get_entity(int alt);
167char *dfu_extract_token(char** e, int *n);
Lukasz Majewski6bed7ce2013-07-18 13:19:14 +0200168void dfu_trigger_reset(void);
Lukasz Majewskifed936e2013-10-08 14:30:38 +0200169int dfu_get_alt(char *name);
Stephen Warrendd648272014-06-11 16:03:33 -0600170int dfu_init_env_entities(char *interface, char *devstr);
Stephen Warren7ac1b412014-06-11 16:03:34 -0600171unsigned char *dfu_get_buf(struct dfu_entity *dfu);
Lukasz Majewskid4278262013-10-08 14:30:39 +0200172unsigned char *dfu_free_buf(void);
Lukasz Majewski4fb12782013-12-09 16:20:13 +0100173unsigned long dfu_get_buf_size(void);
Lukasz Majewski1cc03c52014-08-25 11:07:28 +0200174bool dfu_usb_get_reset(void);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200175
176int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
177int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
Heiko Schochera2199af2014-03-18 08:09:55 +0100178int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
Lukasz Majewski2092e462015-08-24 00:21:46 +0200179
Lukasz Majewskifc18f8d2016-01-28 16:14:49 +0100180/*
181 * dfu_defer_flush - pointer to store dfu_entity for deferred flashing.
182 * It should be NULL when not used.
183 */
184extern struct dfu_entity *dfu_defer_flush;
185/**
186 * dfu_get_defer_flush - get current value of dfu_defer_flush pointer
187 *
188 * @return - value of the dfu_defer_flush pointer
189 */
190static inline struct dfu_entity *dfu_get_defer_flush(void)
191{
192 return dfu_defer_flush;
193}
194
195/**
196 * dfu_set_defer_flush - set the dfu_defer_flush pointer
197 *
198 * @param dfu - pointer to the dfu_entity, which should be written
199 */
200static inline void dfu_set_defer_flush(struct dfu_entity *dfu)
201{
202 dfu_defer_flush = dfu;
203}
204
Lukasz Majewski2092e462015-08-24 00:21:46 +0200205/**
206 * dfu_write_from_mem_addr - write data from memory to DFU managed medium
207 *
208 * This function adds support for writing data starting from fixed memory
209 * address (like $loadaddr) to dfu managed medium (e.g. NAND, MMC, file system)
210 *
211 * @param dfu - dfu entity to which we want to store data
212 * @param buf - fixed memory addres from where data starts
213 * @param size - number of bytes to write
214 *
215 * @return - 0 on success, other value on failure
216 */
217int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size);
218
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200219/* Device specific */
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600220#if CONFIG_IS_ENABLED(DFU_MMC)
Stephen Warrendd648272014-06-11 16:03:33 -0600221extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200222#else
Stephen Warrendd648272014-06-11 16:03:33 -0600223static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr,
224 char *s)
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200225{
226 puts("MMC support not available!\n");
227 return -1;
228}
229#endif
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000230
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600231#if CONFIG_IS_ENABLED(DFU_NAND)
Stephen Warrendd648272014-06-11 16:03:33 -0600232extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr, char *s);
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000233#else
Stephen Warrendd648272014-06-11 16:03:33 -0600234static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr,
235 char *s)
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000236{
237 puts("NAND support not available!\n");
238 return -1;
239}
240#endif
241
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600242#if CONFIG_IS_ENABLED(DFU_RAM)
Stephen Warrendd648272014-06-11 16:03:33 -0600243extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s);
Afzal Mohammeda9479f02013-09-18 01:15:24 +0530244#else
Stephen Warrendd648272014-06-11 16:03:33 -0600245static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr,
246 char *s)
Afzal Mohammeda9479f02013-09-18 01:15:24 +0530247{
248 puts("RAM support not available!\n");
249 return -1;
250}
251#endif
252
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600253#if CONFIG_IS_ENABLED(DFU_SF)
Stephen Warren6f12ebf2014-06-11 16:03:36 -0600254extern int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s);
255#else
256static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
257 char *s)
258{
259 puts("SF support not available!\n");
260 return -1;
261}
262#endif
263
Patrick Delaunay6015af22019-10-14 09:28:04 +0200264#if CONFIG_IS_ENABLED(DFU_MTD)
265int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s);
266#else
267static inline int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr,
268 char *s)
269{
270 puts("MTD support not available!\n");
271 return -1;
272}
273#endif
274
Lukasz Majewski2d50d682015-08-24 00:21:45 +0200275/**
276 * dfu_tftp_write - Write TFTP data to DFU medium
277 *
278 * This function is storing data received via TFTP on DFU supported medium.
279 *
280 * @param dfu_entity_name - name of DFU entity to write
281 * @param addr - address of data buffer to write
282 * @param len - number of bytes
283 * @param interface - destination DFU medium (e.g. "mmc")
284 * @param devstring - instance number of destination DFU medium (e.g. "1")
285 *
286 * @return 0 on success, otherwise error code
287 */
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600288#if CONFIG_IS_ENABLED(DFU_TFTP)
Lukasz Majewski2d50d682015-08-24 00:21:45 +0200289int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len,
290 char *interface, char *devstring);
291#else
292static inline int dfu_tftp_write(char *dfu_entity_name, unsigned int addr,
293 unsigned int len, char *interface,
294 char *devstring)
295{
296 puts("TFTP write support for DFU not available!\n");
297 return -ENOSYS;
298}
299#endif
300
Lukasz Majewskia6921ad2013-09-17 15:58:23 +0200301int dfu_add(struct usb_configuration *c);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200302#endif /* __DFU_ENTITY_H_ */