1cb383cd2SLukasz Majewski /* 2cb383cd2SLukasz Majewski * dfu.c -- DFU back-end routines 3cb383cd2SLukasz Majewski * 4cb383cd2SLukasz Majewski * Copyright (C) 2012 Samsung Electronics 5cb383cd2SLukasz Majewski * author: Lukasz Majewski <l.majewski@samsung.com> 6cb383cd2SLukasz Majewski * 71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 8cb383cd2SLukasz Majewski */ 9cb383cd2SLukasz Majewski 10cb383cd2SLukasz Majewski #include <common.h> 11cb383cd2SLukasz Majewski #include <malloc.h> 121b6ca18bSPantelis Antoniou #include <errno.h> 13ea2453d5SPantelis Antoniou #include <div64.h> 14cb383cd2SLukasz Majewski #include <dfu.h> 150e285b50SStephen Warren #include <ext4fs.h> 160e285b50SStephen Warren #include <fat.h> 177d0b605aSŁukasz Majewski #include <mmc.h> 18cb383cd2SLukasz Majewski 1941ac233cSPrzemyslaw Marczak static unsigned char *dfu_file_buf; 20ea2453d5SPantelis Antoniou static long dfu_file_buf_len; 21411c5e57SStephen Warren static long dfu_file_buf_filled; 22ea2453d5SPantelis Antoniou 23c8151b4aSLukasz Majewski static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part) 24c8151b4aSLukasz Majewski { 25c8151b4aSLukasz Majewski int ret; 26c8151b4aSLukasz Majewski 27c8151b4aSLukasz Majewski if (part == mmc->part_num) 28c8151b4aSLukasz Majewski return 0; 29c8151b4aSLukasz Majewski 30dd64827eSStephen Warren ret = mmc_switch_part(dfu->data.mmc.dev_num, part); 31c8151b4aSLukasz Majewski if (ret) { 32c8151b4aSLukasz Majewski error("Cannot switch to partition %d\n", part); 33c8151b4aSLukasz Majewski return ret; 34c8151b4aSLukasz Majewski } 35c8151b4aSLukasz Majewski mmc->part_num = part; 36c8151b4aSLukasz Majewski 37c8151b4aSLukasz Majewski return 0; 38c8151b4aSLukasz Majewski } 39c8151b4aSLukasz Majewski 405a127c84SAfzal Mohammed static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, 41ea2453d5SPantelis Antoniou u64 offset, void *buf, long *len) 42cb383cd2SLukasz Majewski { 437da6fa27SPrzemyslaw Marczak struct mmc *mmc; 447d0b605aSŁukasz Majewski u32 blk_start, blk_count, n = 0; 45c8151b4aSLukasz Majewski int ret, part_num_bkp = 0; 46cb383cd2SLukasz Majewski 477da6fa27SPrzemyslaw Marczak mmc = find_mmc_device(dfu->data.mmc.dev_num); 487da6fa27SPrzemyslaw Marczak if (!mmc) { 497da6fa27SPrzemyslaw Marczak error("Device MMC %d - not found!", dfu->data.mmc.dev_num); 507da6fa27SPrzemyslaw Marczak return -ENODEV; 517da6fa27SPrzemyslaw Marczak } 527da6fa27SPrzemyslaw Marczak 53ea2453d5SPantelis Antoniou /* 54ea2453d5SPantelis Antoniou * We must ensure that we work in lba_blk_size chunks, so ALIGN 55ea2453d5SPantelis Antoniou * this value. 56ea2453d5SPantelis Antoniou */ 57ea2453d5SPantelis Antoniou *len = ALIGN(*len, dfu->data.mmc.lba_blk_size); 58ea2453d5SPantelis Antoniou 59ea2453d5SPantelis Antoniou blk_start = dfu->data.mmc.lba_start + 60ea2453d5SPantelis Antoniou (u32)lldiv(offset, dfu->data.mmc.lba_blk_size); 61ea2453d5SPantelis Antoniou blk_count = *len / dfu->data.mmc.lba_blk_size; 62ea2453d5SPantelis Antoniou if (blk_start + blk_count > 63ea2453d5SPantelis Antoniou dfu->data.mmc.lba_start + dfu->data.mmc.lba_size) { 64ea2453d5SPantelis Antoniou puts("Request would exceed designated area!\n"); 65ea2453d5SPantelis Antoniou return -EINVAL; 66ea2453d5SPantelis Antoniou } 67ea2453d5SPantelis Antoniou 68c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) { 69c8151b4aSLukasz Majewski part_num_bkp = mmc->part_num; 70c8151b4aSLukasz Majewski ret = mmc_access_part(dfu, mmc, dfu->data.mmc.hw_partition); 71c8151b4aSLukasz Majewski if (ret) 72c8151b4aSLukasz Majewski return ret; 73c8151b4aSLukasz Majewski } 74c8151b4aSLukasz Majewski 757d0b605aSŁukasz Majewski debug("%s: %s dev: %d start: %d cnt: %d buf: 0x%p\n", __func__, 76dd64827eSStephen Warren op == DFU_OP_READ ? "MMC READ" : "MMC WRITE", 77dd64827eSStephen Warren dfu->data.mmc.dev_num, blk_start, blk_count, buf); 787d0b605aSŁukasz Majewski switch (op) { 797d0b605aSŁukasz Majewski case DFU_OP_READ: 80*7c4213f6SStephen Warren n = mmc->block_dev.block_read(&mmc->block_dev, blk_start, 817d0b605aSŁukasz Majewski blk_count, buf); 827d0b605aSŁukasz Majewski break; 837d0b605aSŁukasz Majewski case DFU_OP_WRITE: 84*7c4213f6SStephen Warren n = mmc->block_dev.block_write(&mmc->block_dev, blk_start, 857d0b605aSŁukasz Majewski blk_count, buf); 867d0b605aSŁukasz Majewski break; 877d0b605aSŁukasz Majewski default: 887d0b605aSŁukasz Majewski error("Operation not supported\n"); 897d0b605aSŁukasz Majewski } 90cb383cd2SLukasz Majewski 917d0b605aSŁukasz Majewski if (n != blk_count) { 927d0b605aSŁukasz Majewski error("MMC operation failed"); 93c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) 94c8151b4aSLukasz Majewski mmc_access_part(dfu, mmc, part_num_bkp); 957d0b605aSŁukasz Majewski return -EIO; 967d0b605aSŁukasz Majewski } 977d0b605aSŁukasz Majewski 98c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) { 99c8151b4aSLukasz Majewski ret = mmc_access_part(dfu, mmc, part_num_bkp); 100c8151b4aSLukasz Majewski if (ret) 101c8151b4aSLukasz Majewski return ret; 102c8151b4aSLukasz Majewski } 103c8151b4aSLukasz Majewski 1047d0b605aSŁukasz Majewski return 0; 105cb383cd2SLukasz Majewski } 106cb383cd2SLukasz Majewski 107ea2453d5SPantelis Antoniou static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len) 108cb383cd2SLukasz Majewski { 109ea2453d5SPantelis Antoniou if (dfu_file_buf_len + *len > CONFIG_SYS_DFU_MAX_FILE_SIZE) { 110ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 111ea2453d5SPantelis Antoniou return -EINVAL; 112cb383cd2SLukasz Majewski } 113cb383cd2SLukasz Majewski 114ea2453d5SPantelis Antoniou /* Add to the current buffer. */ 115ea2453d5SPantelis Antoniou memcpy(dfu_file_buf + dfu_file_buf_len, buf, *len); 116ea2453d5SPantelis Antoniou dfu_file_buf_len += *len; 117ea2453d5SPantelis Antoniou 118ea2453d5SPantelis Antoniou return 0; 119cb383cd2SLukasz Majewski } 120cb383cd2SLukasz Majewski 1215a127c84SAfzal Mohammed static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu, 122cb383cd2SLukasz Majewski void *buf, long *len) 123cb383cd2SLukasz Majewski { 1240e285b50SStephen Warren const char *fsname, *opname; 125cb383cd2SLukasz Majewski char cmd_buf[DFU_CMD_BUF_SIZE]; 126cb383cd2SLukasz Majewski char *str_env; 127cb383cd2SLukasz Majewski int ret; 128cb383cd2SLukasz Majewski 12943e66272SŁukasz Majewski switch (dfu->layout) { 13043e66272SŁukasz Majewski case DFU_FS_FAT: 1310e285b50SStephen Warren fsname = "fat"; 13243e66272SŁukasz Majewski break; 13343e66272SŁukasz Majewski case DFU_FS_EXT4: 1340e285b50SStephen Warren fsname = "ext4"; 13543e66272SŁukasz Majewski break; 13643e66272SŁukasz Majewski default: 13743e66272SŁukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 13843e66272SŁukasz Majewski dfu_get_layout(dfu->layout)); 139ea2453d5SPantelis Antoniou return -1; 14043e66272SŁukasz Majewski } 141cb383cd2SLukasz Majewski 1420e285b50SStephen Warren switch (op) { 1430e285b50SStephen Warren case DFU_OP_READ: 1440e285b50SStephen Warren opname = "load"; 1450e285b50SStephen Warren break; 1460e285b50SStephen Warren case DFU_OP_WRITE: 1470e285b50SStephen Warren opname = "write"; 1480e285b50SStephen Warren break; 1490e285b50SStephen Warren case DFU_OP_SIZE: 1500e285b50SStephen Warren opname = "size"; 1510e285b50SStephen Warren break; 1520e285b50SStephen Warren default: 1530e285b50SStephen Warren return -1; 1540e285b50SStephen Warren } 1550e285b50SStephen Warren 1560e285b50SStephen Warren sprintf(cmd_buf, "%s%s mmc %d:%d", fsname, opname, 1570e285b50SStephen Warren dfu->data.mmc.dev, dfu->data.mmc.part); 1580e285b50SStephen Warren 1590e285b50SStephen Warren if (op != DFU_OP_SIZE) 160e621c7abSStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %p", buf); 1610e285b50SStephen Warren 1620e285b50SStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name); 1630e285b50SStephen Warren 16417eb1d8fSLukasz Majewski if (op == DFU_OP_WRITE) 16517eb1d8fSLukasz Majewski sprintf(cmd_buf + strlen(cmd_buf), " %lx", *len); 16617eb1d8fSLukasz Majewski 167cb383cd2SLukasz Majewski debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); 168cb383cd2SLukasz Majewski 169cb383cd2SLukasz Majewski ret = run_command(cmd_buf, 0); 170cb383cd2SLukasz Majewski if (ret) { 171cb383cd2SLukasz Majewski puts("dfu: Read error!\n"); 172cb383cd2SLukasz Majewski return ret; 173cb383cd2SLukasz Majewski } 174cb383cd2SLukasz Majewski 1750e285b50SStephen Warren if (op != DFU_OP_WRITE) { 176cb383cd2SLukasz Majewski str_env = getenv("filesize"); 177cb383cd2SLukasz Majewski if (str_env == NULL) { 178cb383cd2SLukasz Majewski puts("dfu: Wrong file size!\n"); 179cb383cd2SLukasz Majewski return -1; 180cb383cd2SLukasz Majewski } 181cb383cd2SLukasz Majewski *len = simple_strtoul(str_env, NULL, 16); 182cb383cd2SLukasz Majewski } 183cb383cd2SLukasz Majewski 184cb383cd2SLukasz Majewski return ret; 185cb383cd2SLukasz Majewski } 186cb383cd2SLukasz Majewski 187ea2453d5SPantelis Antoniou int dfu_write_medium_mmc(struct dfu_entity *dfu, 188ea2453d5SPantelis Antoniou u64 offset, void *buf, long *len) 189cb383cd2SLukasz Majewski { 190cb383cd2SLukasz Majewski int ret = -1; 191cb383cd2SLukasz Majewski 192cb383cd2SLukasz Majewski switch (dfu->layout) { 193cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 194ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_WRITE, dfu, offset, buf, len); 195cb383cd2SLukasz Majewski break; 196cb383cd2SLukasz Majewski case DFU_FS_FAT: 19743e66272SŁukasz Majewski case DFU_FS_EXT4: 198ea2453d5SPantelis Antoniou ret = mmc_file_buffer(dfu, buf, len); 199cb383cd2SLukasz Majewski break; 200cb383cd2SLukasz Majewski default: 201cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 202cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 203cb383cd2SLukasz Majewski } 204cb383cd2SLukasz Majewski 205cb383cd2SLukasz Majewski return ret; 206cb383cd2SLukasz Majewski } 207cb383cd2SLukasz Majewski 208ea2453d5SPantelis Antoniou int dfu_flush_medium_mmc(struct dfu_entity *dfu) 209ea2453d5SPantelis Antoniou { 210ea2453d5SPantelis Antoniou int ret = 0; 211ea2453d5SPantelis Antoniou 212ea2453d5SPantelis Antoniou if (dfu->layout != DFU_RAW_ADDR) { 213ea2453d5SPantelis Antoniou /* Do stuff here. */ 21441ac233cSPrzemyslaw Marczak ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf, 215ea2453d5SPantelis Antoniou &dfu_file_buf_len); 216ea2453d5SPantelis Antoniou 217ea2453d5SPantelis Antoniou /* Now that we're done */ 218ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 219ea2453d5SPantelis Antoniou } 220ea2453d5SPantelis Antoniou 221ea2453d5SPantelis Antoniou return ret; 222ea2453d5SPantelis Antoniou } 223ea2453d5SPantelis Antoniou 2240e285b50SStephen Warren long dfu_get_medium_size_mmc(struct dfu_entity *dfu) 2250e285b50SStephen Warren { 2260e285b50SStephen Warren int ret; 2270e285b50SStephen Warren long len; 2280e285b50SStephen Warren 2290e285b50SStephen Warren switch (dfu->layout) { 2300e285b50SStephen Warren case DFU_RAW_ADDR: 2310e285b50SStephen Warren return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; 2320e285b50SStephen Warren case DFU_FS_FAT: 2330e285b50SStephen Warren case DFU_FS_EXT4: 234411c5e57SStephen Warren dfu_file_buf_filled = -1; 2350e285b50SStephen Warren ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len); 2360e285b50SStephen Warren if (ret < 0) 2370e285b50SStephen Warren return ret; 238411c5e57SStephen Warren if (len > CONFIG_SYS_DFU_MAX_FILE_SIZE) 239411c5e57SStephen Warren return -1; 2400e285b50SStephen Warren return len; 2410e285b50SStephen Warren default: 2420e285b50SStephen Warren printf("%s: Layout (%s) not (yet) supported!\n", __func__, 2430e285b50SStephen Warren dfu_get_layout(dfu->layout)); 2440e285b50SStephen Warren return -1; 2450e285b50SStephen Warren } 2460e285b50SStephen Warren } 2470e285b50SStephen Warren 248411c5e57SStephen Warren static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf, 249411c5e57SStephen Warren long *len) 250411c5e57SStephen Warren { 251411c5e57SStephen Warren int ret; 252411c5e57SStephen Warren long file_len; 253411c5e57SStephen Warren 254411c5e57SStephen Warren if (dfu_file_buf_filled == -1) { 255411c5e57SStephen Warren ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len); 256411c5e57SStephen Warren if (ret < 0) 257411c5e57SStephen Warren return ret; 258411c5e57SStephen Warren dfu_file_buf_filled = file_len; 259411c5e57SStephen Warren } 260411c5e57SStephen Warren if (offset + *len > dfu_file_buf_filled) 261411c5e57SStephen Warren return -EINVAL; 262411c5e57SStephen Warren 263411c5e57SStephen Warren /* Add to the current buffer. */ 264411c5e57SStephen Warren memcpy(buf, dfu_file_buf + offset, *len); 265411c5e57SStephen Warren 266411c5e57SStephen Warren return 0; 267411c5e57SStephen Warren } 268411c5e57SStephen Warren 269ea2453d5SPantelis Antoniou int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, 270ea2453d5SPantelis Antoniou long *len) 271cb383cd2SLukasz Majewski { 272cb383cd2SLukasz Majewski int ret = -1; 273cb383cd2SLukasz Majewski 274cb383cd2SLukasz Majewski switch (dfu->layout) { 275cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 276ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_READ, dfu, offset, buf, len); 277cb383cd2SLukasz Majewski break; 278cb383cd2SLukasz Majewski case DFU_FS_FAT: 27943e66272SŁukasz Majewski case DFU_FS_EXT4: 280411c5e57SStephen Warren ret = mmc_file_unbuffer(dfu, offset, buf, len); 281cb383cd2SLukasz Majewski break; 282cb383cd2SLukasz Majewski default: 283cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 284cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 285cb383cd2SLukasz Majewski } 286cb383cd2SLukasz Majewski 287cb383cd2SLukasz Majewski return ret; 288cb383cd2SLukasz Majewski } 289cb383cd2SLukasz Majewski 29041ac233cSPrzemyslaw Marczak void dfu_free_entity_mmc(struct dfu_entity *dfu) 29141ac233cSPrzemyslaw Marczak { 29241ac233cSPrzemyslaw Marczak if (dfu_file_buf) { 29341ac233cSPrzemyslaw Marczak free(dfu_file_buf); 29441ac233cSPrzemyslaw Marczak dfu_file_buf = NULL; 29541ac233cSPrzemyslaw Marczak } 29641ac233cSPrzemyslaw Marczak } 29741ac233cSPrzemyslaw Marczak 298711b931fSMateusz Zalega /* 299711b931fSMateusz Zalega * @param s Parameter string containing space-separated arguments: 300711b931fSMateusz Zalega * 1st: 301711b931fSMateusz Zalega * raw (raw read/write) 302711b931fSMateusz Zalega * fat (files) 303711b931fSMateusz Zalega * ext4 (^) 304711b931fSMateusz Zalega * part (partition image) 305711b931fSMateusz Zalega * 2nd and 3rd: 306711b931fSMateusz Zalega * lba_start and lba_size, for raw write 307711b931fSMateusz Zalega * mmc_dev and mmc_part, for filesystems and part 308c8151b4aSLukasz Majewski * 4th (optional): 309c8151b4aSLukasz Majewski * mmcpart <num> (access to HW eMMC partitions) 310711b931fSMateusz Zalega */ 311dd64827eSStephen Warren int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s) 312cb383cd2SLukasz Majewski { 313711b931fSMateusz Zalega const char *entity_type; 314711b931fSMateusz Zalega size_t second_arg; 315711b931fSMateusz Zalega size_t third_arg; 316711b931fSMateusz Zalega 3171b6ca18bSPantelis Antoniou struct mmc *mmc; 318711b931fSMateusz Zalega 319711b931fSMateusz Zalega const char *argv[3]; 320711b931fSMateusz Zalega const char **parg = argv; 321711b931fSMateusz Zalega 322dd64827eSStephen Warren dfu->data.mmc.dev_num = simple_strtoul(devstr, NULL, 10); 323dd64827eSStephen Warren 324711b931fSMateusz Zalega for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) { 325711b931fSMateusz Zalega *parg = strsep(&s, " "); 326711b931fSMateusz Zalega if (*parg == NULL) { 327711b931fSMateusz Zalega error("Invalid number of arguments.\n"); 328711b931fSMateusz Zalega return -ENODEV; 329711b931fSMateusz Zalega } 330711b931fSMateusz Zalega } 331711b931fSMateusz Zalega 332711b931fSMateusz Zalega entity_type = argv[0]; 333b7d4259aSMateusz Zalega /* 334b7d4259aSMateusz Zalega * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8, 335b7d4259aSMateusz Zalega * with default 10. 336b7d4259aSMateusz Zalega */ 337b7d4259aSMateusz Zalega second_arg = simple_strtoul(argv[1], NULL, 0); 338b7d4259aSMateusz Zalega third_arg = simple_strtoul(argv[2], NULL, 0); 339711b931fSMateusz Zalega 340dd64827eSStephen Warren mmc = find_mmc_device(dfu->data.mmc.dev_num); 341711b931fSMateusz Zalega if (mmc == NULL) { 342dd64827eSStephen Warren error("Couldn't find MMC device no. %d.\n", 343dd64827eSStephen Warren dfu->data.mmc.dev_num); 344711b931fSMateusz Zalega return -ENODEV; 345711b931fSMateusz Zalega } 346711b931fSMateusz Zalega 347711b931fSMateusz Zalega if (mmc_init(mmc)) { 348711b931fSMateusz Zalega error("Couldn't init MMC device.\n"); 349711b931fSMateusz Zalega return -ENODEV; 350711b931fSMateusz Zalega } 351711b931fSMateusz Zalega 352c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = -EINVAL; 353711b931fSMateusz Zalega if (!strcmp(entity_type, "raw")) { 354711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 355711b931fSMateusz Zalega dfu->data.mmc.lba_start = second_arg; 356711b931fSMateusz Zalega dfu->data.mmc.lba_size = third_arg; 357711b931fSMateusz Zalega dfu->data.mmc.lba_blk_size = mmc->read_bl_len; 358c8151b4aSLukasz Majewski 359c8151b4aSLukasz Majewski /* 360c8151b4aSLukasz Majewski * Check for an extra entry at dfu_alt_info env variable 361c8151b4aSLukasz Majewski * specifying the mmc HW defined partition number 362c8151b4aSLukasz Majewski */ 363c8151b4aSLukasz Majewski if (s) 364c8151b4aSLukasz Majewski if (!strcmp(strsep(&s, " "), "mmcpart")) 365c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = 366c8151b4aSLukasz Majewski simple_strtoul(s, NULL, 0); 367c8151b4aSLukasz Majewski 368711b931fSMateusz Zalega } else if (!strcmp(entity_type, "part")) { 3691b6ca18bSPantelis Antoniou disk_partition_t partinfo; 370711b931fSMateusz Zalega block_dev_desc_t *blk_dev = &mmc->block_dev; 371711b931fSMateusz Zalega int mmcdev = second_arg; 372711b931fSMateusz Zalega int mmcpart = third_arg; 373cb383cd2SLukasz Majewski 374711b931fSMateusz Zalega if (get_partition_info(blk_dev, mmcpart, &partinfo) != 0) { 375711b931fSMateusz Zalega error("Couldn't find part #%d on mmc device #%d\n", 376711b931fSMateusz Zalega mmcpart, mmcdev); 3771b6ca18bSPantelis Antoniou return -ENODEV; 3781b6ca18bSPantelis Antoniou } 3791b6ca18bSPantelis Antoniou 380711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 3811b6ca18bSPantelis Antoniou dfu->data.mmc.lba_start = partinfo.start; 3821b6ca18bSPantelis Antoniou dfu->data.mmc.lba_size = partinfo.size; 3831b6ca18bSPantelis Antoniou dfu->data.mmc.lba_blk_size = partinfo.blksz; 384711b931fSMateusz Zalega } else if (!strcmp(entity_type, "fat")) { 385711b931fSMateusz Zalega dfu->layout = DFU_FS_FAT; 386711b931fSMateusz Zalega } else if (!strcmp(entity_type, "ext4")) { 387711b931fSMateusz Zalega dfu->layout = DFU_FS_EXT4; 388cb383cd2SLukasz Majewski } else { 389711b931fSMateusz Zalega error("Memory layout (%s) not supported!\n", entity_type); 3901b6ca18bSPantelis Antoniou return -ENODEV; 391cb383cd2SLukasz Majewski } 392cb383cd2SLukasz Majewski 393711b931fSMateusz Zalega /* if it's NOT a raw write */ 394711b931fSMateusz Zalega if (strcmp(entity_type, "raw")) { 395711b931fSMateusz Zalega dfu->data.mmc.dev = second_arg; 396711b931fSMateusz Zalega dfu->data.mmc.part = third_arg; 39743e66272SŁukasz Majewski } 39843e66272SŁukasz Majewski 399711b931fSMateusz Zalega dfu->dev_type = DFU_DEV_MMC; 4000e285b50SStephen Warren dfu->get_medium_size = dfu_get_medium_size_mmc; 401cb383cd2SLukasz Majewski dfu->read_medium = dfu_read_medium_mmc; 402cb383cd2SLukasz Majewski dfu->write_medium = dfu_write_medium_mmc; 403ea2453d5SPantelis Antoniou dfu->flush_medium = dfu_flush_medium_mmc; 404ea2453d5SPantelis Antoniou dfu->inited = 0; 40541ac233cSPrzemyslaw Marczak dfu->free_entity = dfu_free_entity_mmc; 40641ac233cSPrzemyslaw Marczak 40741ac233cSPrzemyslaw Marczak /* Check if file buffer is ready */ 40841ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 40941ac233cSPrzemyslaw Marczak dfu_file_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, 41041ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 41141ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 41241ac233cSPrzemyslaw Marczak error("Could not memalign 0x%x bytes", 41341ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 41441ac233cSPrzemyslaw Marczak return -ENOMEM; 41541ac233cSPrzemyslaw Marczak } 41641ac233cSPrzemyslaw Marczak } 417cb383cd2SLukasz Majewski 418cb383cd2SLukasz Majewski return 0; 419cb383cd2SLukasz Majewski } 420