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 235a127c84SAfzal Mohammed static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, 24ea2453d5SPantelis Antoniou u64 offset, void *buf, long *len) 25cb383cd2SLukasz Majewski { 267da6fa27SPrzemyslaw Marczak struct mmc *mmc; 277d0b605aSŁukasz Majewski u32 blk_start, blk_count, n = 0; 28c8151b4aSLukasz Majewski int ret, part_num_bkp = 0; 29cb383cd2SLukasz Majewski 307da6fa27SPrzemyslaw Marczak mmc = find_mmc_device(dfu->data.mmc.dev_num); 317da6fa27SPrzemyslaw Marczak if (!mmc) { 327da6fa27SPrzemyslaw Marczak error("Device MMC %d - not found!", dfu->data.mmc.dev_num); 337da6fa27SPrzemyslaw Marczak return -ENODEV; 347da6fa27SPrzemyslaw Marczak } 357da6fa27SPrzemyslaw Marczak 36ea2453d5SPantelis Antoniou /* 37ea2453d5SPantelis Antoniou * We must ensure that we work in lba_blk_size chunks, so ALIGN 38ea2453d5SPantelis Antoniou * this value. 39ea2453d5SPantelis Antoniou */ 40ea2453d5SPantelis Antoniou *len = ALIGN(*len, dfu->data.mmc.lba_blk_size); 41ea2453d5SPantelis Antoniou 42ea2453d5SPantelis Antoniou blk_start = dfu->data.mmc.lba_start + 43ea2453d5SPantelis Antoniou (u32)lldiv(offset, dfu->data.mmc.lba_blk_size); 44ea2453d5SPantelis Antoniou blk_count = *len / dfu->data.mmc.lba_blk_size; 45ea2453d5SPantelis Antoniou if (blk_start + blk_count > 46ea2453d5SPantelis Antoniou dfu->data.mmc.lba_start + dfu->data.mmc.lba_size) { 47ea2453d5SPantelis Antoniou puts("Request would exceed designated area!\n"); 48ea2453d5SPantelis Antoniou return -EINVAL; 49ea2453d5SPantelis Antoniou } 50ea2453d5SPantelis Antoniou 51c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) { 52873cc1d7SStephen Warren part_num_bkp = mmc->block_dev.hwpart; 53*69f45cd5SSimon Glass ret = blk_select_hwpart_devnum(IF_TYPE_MMC, 54*69f45cd5SSimon Glass dfu->data.mmc.dev_num, 55873cc1d7SStephen Warren dfu->data.mmc.hw_partition); 56c8151b4aSLukasz Majewski if (ret) 57c8151b4aSLukasz Majewski return ret; 58c8151b4aSLukasz Majewski } 59c8151b4aSLukasz Majewski 607d0b605aSŁukasz Majewski debug("%s: %s dev: %d start: %d cnt: %d buf: 0x%p\n", __func__, 61dd64827eSStephen Warren op == DFU_OP_READ ? "MMC READ" : "MMC WRITE", 62dd64827eSStephen Warren dfu->data.mmc.dev_num, blk_start, blk_count, buf); 637d0b605aSŁukasz Majewski switch (op) { 647d0b605aSŁukasz Majewski case DFU_OP_READ: 657c4213f6SStephen Warren n = mmc->block_dev.block_read(&mmc->block_dev, blk_start, 667d0b605aSŁukasz Majewski blk_count, buf); 677d0b605aSŁukasz Majewski break; 687d0b605aSŁukasz Majewski case DFU_OP_WRITE: 697c4213f6SStephen Warren n = mmc->block_dev.block_write(&mmc->block_dev, blk_start, 707d0b605aSŁukasz Majewski blk_count, buf); 717d0b605aSŁukasz Majewski break; 727d0b605aSŁukasz Majewski default: 737d0b605aSŁukasz Majewski error("Operation not supported\n"); 747d0b605aSŁukasz Majewski } 75cb383cd2SLukasz Majewski 767d0b605aSŁukasz Majewski if (n != blk_count) { 777d0b605aSŁukasz Majewski error("MMC operation failed"); 78c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) 79*69f45cd5SSimon Glass blk_select_hwpart_devnum(IF_TYPE_MMC, 80*69f45cd5SSimon Glass dfu->data.mmc.dev_num, 81*69f45cd5SSimon Glass part_num_bkp); 827d0b605aSŁukasz Majewski return -EIO; 837d0b605aSŁukasz Majewski } 847d0b605aSŁukasz Majewski 85c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) { 86*69f45cd5SSimon Glass ret = blk_select_hwpart_devnum(IF_TYPE_MMC, 87*69f45cd5SSimon Glass dfu->data.mmc.dev_num, 88*69f45cd5SSimon Glass part_num_bkp); 89c8151b4aSLukasz Majewski if (ret) 90c8151b4aSLukasz Majewski return ret; 91c8151b4aSLukasz Majewski } 92c8151b4aSLukasz Majewski 937d0b605aSŁukasz Majewski return 0; 94cb383cd2SLukasz Majewski } 95cb383cd2SLukasz Majewski 96ea2453d5SPantelis Antoniou static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len) 97cb383cd2SLukasz Majewski { 98ea2453d5SPantelis Antoniou if (dfu_file_buf_len + *len > CONFIG_SYS_DFU_MAX_FILE_SIZE) { 99ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 100ea2453d5SPantelis Antoniou return -EINVAL; 101cb383cd2SLukasz Majewski } 102cb383cd2SLukasz Majewski 103ea2453d5SPantelis Antoniou /* Add to the current buffer. */ 104ea2453d5SPantelis Antoniou memcpy(dfu_file_buf + dfu_file_buf_len, buf, *len); 105ea2453d5SPantelis Antoniou dfu_file_buf_len += *len; 106ea2453d5SPantelis Antoniou 107ea2453d5SPantelis Antoniou return 0; 108cb383cd2SLukasz Majewski } 109cb383cd2SLukasz Majewski 1105a127c84SAfzal Mohammed static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu, 111cb383cd2SLukasz Majewski void *buf, long *len) 112cb383cd2SLukasz Majewski { 1130e285b50SStephen Warren const char *fsname, *opname; 114cb383cd2SLukasz Majewski char cmd_buf[DFU_CMD_BUF_SIZE]; 115cb383cd2SLukasz Majewski char *str_env; 116cb383cd2SLukasz Majewski int ret; 117cb383cd2SLukasz Majewski 11843e66272SŁukasz Majewski switch (dfu->layout) { 11943e66272SŁukasz Majewski case DFU_FS_FAT: 1200e285b50SStephen Warren fsname = "fat"; 12143e66272SŁukasz Majewski break; 12243e66272SŁukasz Majewski case DFU_FS_EXT4: 1230e285b50SStephen Warren fsname = "ext4"; 12443e66272SŁukasz Majewski break; 12543e66272SŁukasz Majewski default: 12643e66272SŁukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 12743e66272SŁukasz Majewski dfu_get_layout(dfu->layout)); 128ea2453d5SPantelis Antoniou return -1; 12943e66272SŁukasz Majewski } 130cb383cd2SLukasz Majewski 1310e285b50SStephen Warren switch (op) { 1320e285b50SStephen Warren case DFU_OP_READ: 1330e285b50SStephen Warren opname = "load"; 1340e285b50SStephen Warren break; 1350e285b50SStephen Warren case DFU_OP_WRITE: 1360e285b50SStephen Warren opname = "write"; 1370e285b50SStephen Warren break; 1380e285b50SStephen Warren case DFU_OP_SIZE: 1390e285b50SStephen Warren opname = "size"; 1400e285b50SStephen Warren break; 1410e285b50SStephen Warren default: 1420e285b50SStephen Warren return -1; 1430e285b50SStephen Warren } 1440e285b50SStephen Warren 1450e285b50SStephen Warren sprintf(cmd_buf, "%s%s mmc %d:%d", fsname, opname, 1460e285b50SStephen Warren dfu->data.mmc.dev, dfu->data.mmc.part); 1470e285b50SStephen Warren 1480e285b50SStephen Warren if (op != DFU_OP_SIZE) 149e621c7abSStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %p", buf); 1500e285b50SStephen Warren 1510e285b50SStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name); 1520e285b50SStephen Warren 15317eb1d8fSLukasz Majewski if (op == DFU_OP_WRITE) 15417eb1d8fSLukasz Majewski sprintf(cmd_buf + strlen(cmd_buf), " %lx", *len); 15517eb1d8fSLukasz Majewski 156cb383cd2SLukasz Majewski debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); 157cb383cd2SLukasz Majewski 158cb383cd2SLukasz Majewski ret = run_command(cmd_buf, 0); 159cb383cd2SLukasz Majewski if (ret) { 160cb383cd2SLukasz Majewski puts("dfu: Read error!\n"); 161cb383cd2SLukasz Majewski return ret; 162cb383cd2SLukasz Majewski } 163cb383cd2SLukasz Majewski 1640e285b50SStephen Warren if (op != DFU_OP_WRITE) { 165cb383cd2SLukasz Majewski str_env = getenv("filesize"); 166cb383cd2SLukasz Majewski if (str_env == NULL) { 167cb383cd2SLukasz Majewski puts("dfu: Wrong file size!\n"); 168cb383cd2SLukasz Majewski return -1; 169cb383cd2SLukasz Majewski } 170cb383cd2SLukasz Majewski *len = simple_strtoul(str_env, NULL, 16); 171cb383cd2SLukasz Majewski } 172cb383cd2SLukasz Majewski 173cb383cd2SLukasz Majewski return ret; 174cb383cd2SLukasz Majewski } 175cb383cd2SLukasz Majewski 176ea2453d5SPantelis Antoniou int dfu_write_medium_mmc(struct dfu_entity *dfu, 177ea2453d5SPantelis Antoniou u64 offset, void *buf, long *len) 178cb383cd2SLukasz Majewski { 179cb383cd2SLukasz Majewski int ret = -1; 180cb383cd2SLukasz Majewski 181cb383cd2SLukasz Majewski switch (dfu->layout) { 182cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 183ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_WRITE, dfu, offset, buf, len); 184cb383cd2SLukasz Majewski break; 185cb383cd2SLukasz Majewski case DFU_FS_FAT: 18643e66272SŁukasz Majewski case DFU_FS_EXT4: 187ea2453d5SPantelis Antoniou ret = mmc_file_buffer(dfu, buf, len); 188cb383cd2SLukasz Majewski break; 189cb383cd2SLukasz Majewski default: 190cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 191cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 192cb383cd2SLukasz Majewski } 193cb383cd2SLukasz Majewski 194cb383cd2SLukasz Majewski return ret; 195cb383cd2SLukasz Majewski } 196cb383cd2SLukasz Majewski 197ea2453d5SPantelis Antoniou int dfu_flush_medium_mmc(struct dfu_entity *dfu) 198ea2453d5SPantelis Antoniou { 199ea2453d5SPantelis Antoniou int ret = 0; 200ea2453d5SPantelis Antoniou 201ea2453d5SPantelis Antoniou if (dfu->layout != DFU_RAW_ADDR) { 202ea2453d5SPantelis Antoniou /* Do stuff here. */ 20341ac233cSPrzemyslaw Marczak ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf, 204ea2453d5SPantelis Antoniou &dfu_file_buf_len); 205ea2453d5SPantelis Antoniou 206ea2453d5SPantelis Antoniou /* Now that we're done */ 207ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 208ea2453d5SPantelis Antoniou } 209ea2453d5SPantelis Antoniou 210ea2453d5SPantelis Antoniou return ret; 211ea2453d5SPantelis Antoniou } 212ea2453d5SPantelis Antoniou 2130e285b50SStephen Warren long dfu_get_medium_size_mmc(struct dfu_entity *dfu) 2140e285b50SStephen Warren { 2150e285b50SStephen Warren int ret; 2160e285b50SStephen Warren long len; 2170e285b50SStephen Warren 2180e285b50SStephen Warren switch (dfu->layout) { 2190e285b50SStephen Warren case DFU_RAW_ADDR: 2200e285b50SStephen Warren return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; 2210e285b50SStephen Warren case DFU_FS_FAT: 2220e285b50SStephen Warren case DFU_FS_EXT4: 223411c5e57SStephen Warren dfu_file_buf_filled = -1; 2240e285b50SStephen Warren ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len); 2250e285b50SStephen Warren if (ret < 0) 2260e285b50SStephen Warren return ret; 227411c5e57SStephen Warren if (len > CONFIG_SYS_DFU_MAX_FILE_SIZE) 228411c5e57SStephen Warren return -1; 2290e285b50SStephen Warren return len; 2300e285b50SStephen Warren default: 2310e285b50SStephen Warren printf("%s: Layout (%s) not (yet) supported!\n", __func__, 2320e285b50SStephen Warren dfu_get_layout(dfu->layout)); 2330e285b50SStephen Warren return -1; 2340e285b50SStephen Warren } 2350e285b50SStephen Warren } 2360e285b50SStephen Warren 237411c5e57SStephen Warren static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf, 238411c5e57SStephen Warren long *len) 239411c5e57SStephen Warren { 240411c5e57SStephen Warren int ret; 241411c5e57SStephen Warren long file_len; 242411c5e57SStephen Warren 243411c5e57SStephen Warren if (dfu_file_buf_filled == -1) { 244411c5e57SStephen Warren ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len); 245411c5e57SStephen Warren if (ret < 0) 246411c5e57SStephen Warren return ret; 247411c5e57SStephen Warren dfu_file_buf_filled = file_len; 248411c5e57SStephen Warren } 249411c5e57SStephen Warren if (offset + *len > dfu_file_buf_filled) 250411c5e57SStephen Warren return -EINVAL; 251411c5e57SStephen Warren 252411c5e57SStephen Warren /* Add to the current buffer. */ 253411c5e57SStephen Warren memcpy(buf, dfu_file_buf + offset, *len); 254411c5e57SStephen Warren 255411c5e57SStephen Warren return 0; 256411c5e57SStephen Warren } 257411c5e57SStephen Warren 258ea2453d5SPantelis Antoniou int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, 259ea2453d5SPantelis Antoniou long *len) 260cb383cd2SLukasz Majewski { 261cb383cd2SLukasz Majewski int ret = -1; 262cb383cd2SLukasz Majewski 263cb383cd2SLukasz Majewski switch (dfu->layout) { 264cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 265ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_READ, dfu, offset, buf, len); 266cb383cd2SLukasz Majewski break; 267cb383cd2SLukasz Majewski case DFU_FS_FAT: 26843e66272SŁukasz Majewski case DFU_FS_EXT4: 269411c5e57SStephen Warren ret = mmc_file_unbuffer(dfu, offset, buf, len); 270cb383cd2SLukasz Majewski break; 271cb383cd2SLukasz Majewski default: 272cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 273cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 274cb383cd2SLukasz Majewski } 275cb383cd2SLukasz Majewski 276cb383cd2SLukasz Majewski return ret; 277cb383cd2SLukasz Majewski } 278cb383cd2SLukasz Majewski 27941ac233cSPrzemyslaw Marczak void dfu_free_entity_mmc(struct dfu_entity *dfu) 28041ac233cSPrzemyslaw Marczak { 28141ac233cSPrzemyslaw Marczak if (dfu_file_buf) { 28241ac233cSPrzemyslaw Marczak free(dfu_file_buf); 28341ac233cSPrzemyslaw Marczak dfu_file_buf = NULL; 28441ac233cSPrzemyslaw Marczak } 28541ac233cSPrzemyslaw Marczak } 28641ac233cSPrzemyslaw Marczak 287711b931fSMateusz Zalega /* 288711b931fSMateusz Zalega * @param s Parameter string containing space-separated arguments: 289711b931fSMateusz Zalega * 1st: 290711b931fSMateusz Zalega * raw (raw read/write) 291711b931fSMateusz Zalega * fat (files) 292711b931fSMateusz Zalega * ext4 (^) 293711b931fSMateusz Zalega * part (partition image) 294711b931fSMateusz Zalega * 2nd and 3rd: 295711b931fSMateusz Zalega * lba_start and lba_size, for raw write 296711b931fSMateusz Zalega * mmc_dev and mmc_part, for filesystems and part 297c8151b4aSLukasz Majewski * 4th (optional): 298c8151b4aSLukasz Majewski * mmcpart <num> (access to HW eMMC partitions) 299711b931fSMateusz Zalega */ 300dd64827eSStephen Warren int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s) 301cb383cd2SLukasz Majewski { 302711b931fSMateusz Zalega const char *entity_type; 303711b931fSMateusz Zalega size_t second_arg; 304711b931fSMateusz Zalega size_t third_arg; 305711b931fSMateusz Zalega 3061b6ca18bSPantelis Antoniou struct mmc *mmc; 307711b931fSMateusz Zalega 308711b931fSMateusz Zalega const char *argv[3]; 309711b931fSMateusz Zalega const char **parg = argv; 310711b931fSMateusz Zalega 311dd64827eSStephen Warren dfu->data.mmc.dev_num = simple_strtoul(devstr, NULL, 10); 312dd64827eSStephen Warren 313711b931fSMateusz Zalega for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) { 314711b931fSMateusz Zalega *parg = strsep(&s, " "); 315711b931fSMateusz Zalega if (*parg == NULL) { 316711b931fSMateusz Zalega error("Invalid number of arguments.\n"); 317711b931fSMateusz Zalega return -ENODEV; 318711b931fSMateusz Zalega } 319711b931fSMateusz Zalega } 320711b931fSMateusz Zalega 321711b931fSMateusz Zalega entity_type = argv[0]; 322b7d4259aSMateusz Zalega /* 323b7d4259aSMateusz Zalega * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8, 324b7d4259aSMateusz Zalega * with default 10. 325b7d4259aSMateusz Zalega */ 326b7d4259aSMateusz Zalega second_arg = simple_strtoul(argv[1], NULL, 0); 327b7d4259aSMateusz Zalega third_arg = simple_strtoul(argv[2], NULL, 0); 328711b931fSMateusz Zalega 329dd64827eSStephen Warren mmc = find_mmc_device(dfu->data.mmc.dev_num); 330711b931fSMateusz Zalega if (mmc == NULL) { 331dd64827eSStephen Warren error("Couldn't find MMC device no. %d.\n", 332dd64827eSStephen Warren dfu->data.mmc.dev_num); 333711b931fSMateusz Zalega return -ENODEV; 334711b931fSMateusz Zalega } 335711b931fSMateusz Zalega 336711b931fSMateusz Zalega if (mmc_init(mmc)) { 337711b931fSMateusz Zalega error("Couldn't init MMC device.\n"); 338711b931fSMateusz Zalega return -ENODEV; 339711b931fSMateusz Zalega } 340711b931fSMateusz Zalega 341c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = -EINVAL; 342711b931fSMateusz Zalega if (!strcmp(entity_type, "raw")) { 343711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 344711b931fSMateusz Zalega dfu->data.mmc.lba_start = second_arg; 345711b931fSMateusz Zalega dfu->data.mmc.lba_size = third_arg; 346711b931fSMateusz Zalega dfu->data.mmc.lba_blk_size = mmc->read_bl_len; 347c8151b4aSLukasz Majewski 348c8151b4aSLukasz Majewski /* 349c8151b4aSLukasz Majewski * Check for an extra entry at dfu_alt_info env variable 350c8151b4aSLukasz Majewski * specifying the mmc HW defined partition number 351c8151b4aSLukasz Majewski */ 352c8151b4aSLukasz Majewski if (s) 353c8151b4aSLukasz Majewski if (!strcmp(strsep(&s, " "), "mmcpart")) 354c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = 355c8151b4aSLukasz Majewski simple_strtoul(s, NULL, 0); 356c8151b4aSLukasz Majewski 357711b931fSMateusz Zalega } else if (!strcmp(entity_type, "part")) { 3581b6ca18bSPantelis Antoniou disk_partition_t partinfo; 3594101f687SSimon Glass struct blk_desc *blk_dev = &mmc->block_dev; 360711b931fSMateusz Zalega int mmcdev = second_arg; 361711b931fSMateusz Zalega int mmcpart = third_arg; 362cb383cd2SLukasz Majewski 3633e8bd469SSimon Glass if (part_get_info(blk_dev, mmcpart, &partinfo) != 0) { 364711b931fSMateusz Zalega error("Couldn't find part #%d on mmc device #%d\n", 365711b931fSMateusz Zalega mmcpart, mmcdev); 3661b6ca18bSPantelis Antoniou return -ENODEV; 3671b6ca18bSPantelis Antoniou } 3681b6ca18bSPantelis Antoniou 369711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 3701b6ca18bSPantelis Antoniou dfu->data.mmc.lba_start = partinfo.start; 3711b6ca18bSPantelis Antoniou dfu->data.mmc.lba_size = partinfo.size; 3721b6ca18bSPantelis Antoniou dfu->data.mmc.lba_blk_size = partinfo.blksz; 373711b931fSMateusz Zalega } else if (!strcmp(entity_type, "fat")) { 374711b931fSMateusz Zalega dfu->layout = DFU_FS_FAT; 375711b931fSMateusz Zalega } else if (!strcmp(entity_type, "ext4")) { 376711b931fSMateusz Zalega dfu->layout = DFU_FS_EXT4; 377cb383cd2SLukasz Majewski } else { 378711b931fSMateusz Zalega error("Memory layout (%s) not supported!\n", entity_type); 3791b6ca18bSPantelis Antoniou return -ENODEV; 380cb383cd2SLukasz Majewski } 381cb383cd2SLukasz Majewski 382711b931fSMateusz Zalega /* if it's NOT a raw write */ 383711b931fSMateusz Zalega if (strcmp(entity_type, "raw")) { 384711b931fSMateusz Zalega dfu->data.mmc.dev = second_arg; 385711b931fSMateusz Zalega dfu->data.mmc.part = third_arg; 38643e66272SŁukasz Majewski } 38743e66272SŁukasz Majewski 388711b931fSMateusz Zalega dfu->dev_type = DFU_DEV_MMC; 3890e285b50SStephen Warren dfu->get_medium_size = dfu_get_medium_size_mmc; 390cb383cd2SLukasz Majewski dfu->read_medium = dfu_read_medium_mmc; 391cb383cd2SLukasz Majewski dfu->write_medium = dfu_write_medium_mmc; 392ea2453d5SPantelis Antoniou dfu->flush_medium = dfu_flush_medium_mmc; 393ea2453d5SPantelis Antoniou dfu->inited = 0; 39441ac233cSPrzemyslaw Marczak dfu->free_entity = dfu_free_entity_mmc; 39541ac233cSPrzemyslaw Marczak 39641ac233cSPrzemyslaw Marczak /* Check if file buffer is ready */ 39741ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 39841ac233cSPrzemyslaw Marczak dfu_file_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, 39941ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 40041ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 40141ac233cSPrzemyslaw Marczak error("Could not memalign 0x%x bytes", 40241ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 40341ac233cSPrzemyslaw Marczak return -ENOMEM; 40441ac233cSPrzemyslaw Marczak } 40541ac233cSPrzemyslaw Marczak } 406cb383cd2SLukasz Majewski 407cb383cd2SLukasz Majewski return 0; 408cb383cd2SLukasz Majewski } 409