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