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) { 52797d1b9dSSimon Glass part_num_bkp = mmc_get_blk_desc(mmc)->hwpart; 5369f45cd5SSimon Glass ret = blk_select_hwpart_devnum(IF_TYPE_MMC, 5469f45cd5SSimon 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: 65797d1b9dSSimon Glass n = blk_dread(mmc_get_blk_desc(mmc), blk_start, blk_count, buf); 667d0b605aSŁukasz Majewski break; 677d0b605aSŁukasz Majewski case DFU_OP_WRITE: 68797d1b9dSSimon Glass n = blk_dwrite(mmc_get_blk_desc(mmc), blk_start, blk_count, 69797d1b9dSSimon Glass buf); 707d0b605aSŁukasz Majewski break; 717d0b605aSŁukasz Majewski default: 727d0b605aSŁukasz Majewski error("Operation not supported\n"); 737d0b605aSŁukasz Majewski } 74cb383cd2SLukasz Majewski 757d0b605aSŁukasz Majewski if (n != blk_count) { 767d0b605aSŁukasz Majewski error("MMC operation failed"); 77c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) 7869f45cd5SSimon Glass blk_select_hwpart_devnum(IF_TYPE_MMC, 7969f45cd5SSimon Glass dfu->data.mmc.dev_num, 8069f45cd5SSimon Glass part_num_bkp); 817d0b605aSŁukasz Majewski return -EIO; 827d0b605aSŁukasz Majewski } 837d0b605aSŁukasz Majewski 84c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) { 8569f45cd5SSimon Glass ret = blk_select_hwpart_devnum(IF_TYPE_MMC, 8669f45cd5SSimon Glass dfu->data.mmc.dev_num, 8769f45cd5SSimon Glass part_num_bkp); 88c8151b4aSLukasz Majewski if (ret) 89c8151b4aSLukasz Majewski return ret; 90c8151b4aSLukasz Majewski } 91c8151b4aSLukasz Majewski 927d0b605aSŁukasz Majewski return 0; 93cb383cd2SLukasz Majewski } 94cb383cd2SLukasz Majewski 95ea2453d5SPantelis Antoniou static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len) 96cb383cd2SLukasz Majewski { 97ea2453d5SPantelis Antoniou if (dfu_file_buf_len + *len > CONFIG_SYS_DFU_MAX_FILE_SIZE) { 98ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 99ea2453d5SPantelis Antoniou return -EINVAL; 100cb383cd2SLukasz Majewski } 101cb383cd2SLukasz Majewski 102ea2453d5SPantelis Antoniou /* Add to the current buffer. */ 103ea2453d5SPantelis Antoniou memcpy(dfu_file_buf + dfu_file_buf_len, buf, *len); 104ea2453d5SPantelis Antoniou dfu_file_buf_len += *len; 105ea2453d5SPantelis Antoniou 106ea2453d5SPantelis Antoniou return 0; 107cb383cd2SLukasz Majewski } 108cb383cd2SLukasz Majewski 1095a127c84SAfzal Mohammed static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu, 110cb383cd2SLukasz Majewski void *buf, long *len) 111cb383cd2SLukasz Majewski { 1120e285b50SStephen Warren const char *fsname, *opname; 113cb383cd2SLukasz Majewski char cmd_buf[DFU_CMD_BUF_SIZE]; 114cb383cd2SLukasz Majewski char *str_env; 115cb383cd2SLukasz Majewski int ret; 116cb383cd2SLukasz Majewski 11743e66272SŁukasz Majewski switch (dfu->layout) { 11843e66272SŁukasz Majewski case DFU_FS_FAT: 1190e285b50SStephen Warren fsname = "fat"; 12043e66272SŁukasz Majewski break; 12143e66272SŁukasz Majewski case DFU_FS_EXT4: 1220e285b50SStephen Warren fsname = "ext4"; 12343e66272SŁukasz Majewski break; 12443e66272SŁukasz Majewski default: 12543e66272SŁukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 12643e66272SŁukasz Majewski dfu_get_layout(dfu->layout)); 127ea2453d5SPantelis Antoniou return -1; 12843e66272SŁukasz Majewski } 129cb383cd2SLukasz Majewski 1300e285b50SStephen Warren switch (op) { 1310e285b50SStephen Warren case DFU_OP_READ: 1320e285b50SStephen Warren opname = "load"; 1330e285b50SStephen Warren break; 1340e285b50SStephen Warren case DFU_OP_WRITE: 1350e285b50SStephen Warren opname = "write"; 1360e285b50SStephen Warren break; 1370e285b50SStephen Warren case DFU_OP_SIZE: 1380e285b50SStephen Warren opname = "size"; 1390e285b50SStephen Warren break; 1400e285b50SStephen Warren default: 1410e285b50SStephen Warren return -1; 1420e285b50SStephen Warren } 1430e285b50SStephen Warren 1440e285b50SStephen Warren sprintf(cmd_buf, "%s%s mmc %d:%d", fsname, opname, 1450e285b50SStephen Warren dfu->data.mmc.dev, dfu->data.mmc.part); 1460e285b50SStephen Warren 1470e285b50SStephen Warren if (op != DFU_OP_SIZE) 148e621c7abSStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %p", buf); 1490e285b50SStephen Warren 1500e285b50SStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name); 1510e285b50SStephen Warren 15217eb1d8fSLukasz Majewski if (op == DFU_OP_WRITE) 15317eb1d8fSLukasz Majewski sprintf(cmd_buf + strlen(cmd_buf), " %lx", *len); 15417eb1d8fSLukasz Majewski 155cb383cd2SLukasz Majewski debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); 156cb383cd2SLukasz Majewski 157cb383cd2SLukasz Majewski ret = run_command(cmd_buf, 0); 158cb383cd2SLukasz Majewski if (ret) { 159cb383cd2SLukasz Majewski puts("dfu: Read error!\n"); 160cb383cd2SLukasz Majewski return ret; 161cb383cd2SLukasz Majewski } 162cb383cd2SLukasz Majewski 1630e285b50SStephen Warren if (op != DFU_OP_WRITE) { 164cb383cd2SLukasz Majewski str_env = getenv("filesize"); 165cb383cd2SLukasz Majewski if (str_env == NULL) { 166cb383cd2SLukasz Majewski puts("dfu: Wrong file size!\n"); 167cb383cd2SLukasz Majewski return -1; 168cb383cd2SLukasz Majewski } 169cb383cd2SLukasz Majewski *len = simple_strtoul(str_env, NULL, 16); 170cb383cd2SLukasz Majewski } 171cb383cd2SLukasz Majewski 172cb383cd2SLukasz Majewski return ret; 173cb383cd2SLukasz Majewski } 174cb383cd2SLukasz Majewski 175ea2453d5SPantelis Antoniou int dfu_write_medium_mmc(struct dfu_entity *dfu, 176ea2453d5SPantelis Antoniou u64 offset, void *buf, long *len) 177cb383cd2SLukasz Majewski { 178cb383cd2SLukasz Majewski int ret = -1; 179cb383cd2SLukasz Majewski 180cb383cd2SLukasz Majewski switch (dfu->layout) { 181cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 182ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_WRITE, dfu, offset, buf, len); 183cb383cd2SLukasz Majewski break; 184cb383cd2SLukasz Majewski case DFU_FS_FAT: 18543e66272SŁukasz Majewski case DFU_FS_EXT4: 186ea2453d5SPantelis Antoniou ret = mmc_file_buffer(dfu, buf, len); 187cb383cd2SLukasz Majewski break; 188cb383cd2SLukasz Majewski default: 189cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 190cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 191cb383cd2SLukasz Majewski } 192cb383cd2SLukasz Majewski 193cb383cd2SLukasz Majewski return ret; 194cb383cd2SLukasz Majewski } 195cb383cd2SLukasz Majewski 196ea2453d5SPantelis Antoniou int dfu_flush_medium_mmc(struct dfu_entity *dfu) 197ea2453d5SPantelis Antoniou { 198ea2453d5SPantelis Antoniou int ret = 0; 199ea2453d5SPantelis Antoniou 200ea2453d5SPantelis Antoniou if (dfu->layout != DFU_RAW_ADDR) { 201ea2453d5SPantelis Antoniou /* Do stuff here. */ 20241ac233cSPrzemyslaw Marczak ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf, 203ea2453d5SPantelis Antoniou &dfu_file_buf_len); 204ea2453d5SPantelis Antoniou 205ea2453d5SPantelis Antoniou /* Now that we're done */ 206ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 207ea2453d5SPantelis Antoniou } 208ea2453d5SPantelis Antoniou 209ea2453d5SPantelis Antoniou return ret; 210ea2453d5SPantelis Antoniou } 211ea2453d5SPantelis Antoniou 212*4de51201SPatrick Delaunay int dfu_get_medium_size_mmc(struct dfu_entity *dfu, long *size) 2130e285b50SStephen Warren { 2140e285b50SStephen Warren int ret; 2150e285b50SStephen Warren 2160e285b50SStephen Warren switch (dfu->layout) { 2170e285b50SStephen Warren case DFU_RAW_ADDR: 218*4de51201SPatrick Delaunay *size = dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; 219*4de51201SPatrick Delaunay return 0; 2200e285b50SStephen Warren case DFU_FS_FAT: 2210e285b50SStephen Warren case DFU_FS_EXT4: 222411c5e57SStephen Warren dfu_file_buf_filled = -1; 223*4de51201SPatrick Delaunay ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, size); 2240e285b50SStephen Warren if (ret < 0) 2250e285b50SStephen Warren return ret; 226*4de51201SPatrick Delaunay if (*size > CONFIG_SYS_DFU_MAX_FILE_SIZE) 227411c5e57SStephen Warren return -1; 228*4de51201SPatrick Delaunay return 0; 2290e285b50SStephen Warren default: 2300e285b50SStephen Warren printf("%s: Layout (%s) not (yet) supported!\n", __func__, 2310e285b50SStephen Warren dfu_get_layout(dfu->layout)); 2320e285b50SStephen Warren return -1; 2330e285b50SStephen Warren } 2340e285b50SStephen Warren } 2350e285b50SStephen Warren 236411c5e57SStephen Warren static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf, 237411c5e57SStephen Warren long *len) 238411c5e57SStephen Warren { 239411c5e57SStephen Warren int ret; 240411c5e57SStephen Warren long file_len; 241411c5e57SStephen Warren 242411c5e57SStephen Warren if (dfu_file_buf_filled == -1) { 243411c5e57SStephen Warren ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len); 244411c5e57SStephen Warren if (ret < 0) 245411c5e57SStephen Warren return ret; 246411c5e57SStephen Warren dfu_file_buf_filled = file_len; 247411c5e57SStephen Warren } 248411c5e57SStephen Warren if (offset + *len > dfu_file_buf_filled) 249411c5e57SStephen Warren return -EINVAL; 250411c5e57SStephen Warren 251411c5e57SStephen Warren /* Add to the current buffer. */ 252411c5e57SStephen Warren memcpy(buf, dfu_file_buf + offset, *len); 253411c5e57SStephen Warren 254411c5e57SStephen Warren return 0; 255411c5e57SStephen Warren } 256411c5e57SStephen Warren 257ea2453d5SPantelis Antoniou int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, 258ea2453d5SPantelis Antoniou long *len) 259cb383cd2SLukasz Majewski { 260cb383cd2SLukasz Majewski int ret = -1; 261cb383cd2SLukasz Majewski 262cb383cd2SLukasz Majewski switch (dfu->layout) { 263cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 264ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_READ, dfu, offset, buf, len); 265cb383cd2SLukasz Majewski break; 266cb383cd2SLukasz Majewski case DFU_FS_FAT: 26743e66272SŁukasz Majewski case DFU_FS_EXT4: 268411c5e57SStephen Warren ret = mmc_file_unbuffer(dfu, offset, buf, len); 269cb383cd2SLukasz Majewski break; 270cb383cd2SLukasz Majewski default: 271cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 272cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 273cb383cd2SLukasz Majewski } 274cb383cd2SLukasz Majewski 275cb383cd2SLukasz Majewski return ret; 276cb383cd2SLukasz Majewski } 277cb383cd2SLukasz Majewski 27841ac233cSPrzemyslaw Marczak void dfu_free_entity_mmc(struct dfu_entity *dfu) 27941ac233cSPrzemyslaw Marczak { 28041ac233cSPrzemyslaw Marczak if (dfu_file_buf) { 28141ac233cSPrzemyslaw Marczak free(dfu_file_buf); 28241ac233cSPrzemyslaw Marczak dfu_file_buf = NULL; 28341ac233cSPrzemyslaw Marczak } 28441ac233cSPrzemyslaw Marczak } 28541ac233cSPrzemyslaw Marczak 286711b931fSMateusz Zalega /* 287711b931fSMateusz Zalega * @param s Parameter string containing space-separated arguments: 288711b931fSMateusz Zalega * 1st: 289711b931fSMateusz Zalega * raw (raw read/write) 290711b931fSMateusz Zalega * fat (files) 291711b931fSMateusz Zalega * ext4 (^) 292711b931fSMateusz Zalega * part (partition image) 293711b931fSMateusz Zalega * 2nd and 3rd: 294711b931fSMateusz Zalega * lba_start and lba_size, for raw write 295711b931fSMateusz Zalega * mmc_dev and mmc_part, for filesystems and part 296c8151b4aSLukasz Majewski * 4th (optional): 297c8151b4aSLukasz Majewski * mmcpart <num> (access to HW eMMC partitions) 298711b931fSMateusz Zalega */ 299dd64827eSStephen Warren int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s) 300cb383cd2SLukasz Majewski { 301711b931fSMateusz Zalega const char *entity_type; 302711b931fSMateusz Zalega size_t second_arg; 303711b931fSMateusz Zalega size_t third_arg; 304711b931fSMateusz Zalega 3051b6ca18bSPantelis Antoniou struct mmc *mmc; 306711b931fSMateusz Zalega 307711b931fSMateusz Zalega const char *argv[3]; 308711b931fSMateusz Zalega const char **parg = argv; 309711b931fSMateusz Zalega 310dd64827eSStephen Warren dfu->data.mmc.dev_num = simple_strtoul(devstr, NULL, 10); 311dd64827eSStephen Warren 312711b931fSMateusz Zalega for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) { 313711b931fSMateusz Zalega *parg = strsep(&s, " "); 314711b931fSMateusz Zalega if (*parg == NULL) { 315711b931fSMateusz Zalega error("Invalid number of arguments.\n"); 316711b931fSMateusz Zalega return -ENODEV; 317711b931fSMateusz Zalega } 318711b931fSMateusz Zalega } 319711b931fSMateusz Zalega 320711b931fSMateusz Zalega entity_type = argv[0]; 321b7d4259aSMateusz Zalega /* 322b7d4259aSMateusz Zalega * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8, 323b7d4259aSMateusz Zalega * with default 10. 324b7d4259aSMateusz Zalega */ 325b7d4259aSMateusz Zalega second_arg = simple_strtoul(argv[1], NULL, 0); 326b7d4259aSMateusz Zalega third_arg = simple_strtoul(argv[2], NULL, 0); 327711b931fSMateusz Zalega 328dd64827eSStephen Warren mmc = find_mmc_device(dfu->data.mmc.dev_num); 329711b931fSMateusz Zalega if (mmc == NULL) { 330dd64827eSStephen Warren error("Couldn't find MMC device no. %d.\n", 331dd64827eSStephen Warren dfu->data.mmc.dev_num); 332711b931fSMateusz Zalega return -ENODEV; 333711b931fSMateusz Zalega } 334711b931fSMateusz Zalega 335711b931fSMateusz Zalega if (mmc_init(mmc)) { 336711b931fSMateusz Zalega error("Couldn't init MMC device.\n"); 337711b931fSMateusz Zalega return -ENODEV; 338711b931fSMateusz Zalega } 339711b931fSMateusz Zalega 340c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = -EINVAL; 341711b931fSMateusz Zalega if (!strcmp(entity_type, "raw")) { 342711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 343711b931fSMateusz Zalega dfu->data.mmc.lba_start = second_arg; 344711b931fSMateusz Zalega dfu->data.mmc.lba_size = third_arg; 345711b931fSMateusz Zalega dfu->data.mmc.lba_blk_size = mmc->read_bl_len; 346c8151b4aSLukasz Majewski 347c8151b4aSLukasz Majewski /* 348c8151b4aSLukasz Majewski * Check for an extra entry at dfu_alt_info env variable 349c8151b4aSLukasz Majewski * specifying the mmc HW defined partition number 350c8151b4aSLukasz Majewski */ 351c8151b4aSLukasz Majewski if (s) 352c8151b4aSLukasz Majewski if (!strcmp(strsep(&s, " "), "mmcpart")) 353c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = 354c8151b4aSLukasz Majewski simple_strtoul(s, NULL, 0); 355c8151b4aSLukasz Majewski 356711b931fSMateusz Zalega } else if (!strcmp(entity_type, "part")) { 3571b6ca18bSPantelis Antoniou disk_partition_t partinfo; 358797d1b9dSSimon Glass struct blk_desc *blk_dev = mmc_get_blk_desc(mmc); 359711b931fSMateusz Zalega int mmcdev = second_arg; 360711b931fSMateusz Zalega int mmcpart = third_arg; 361cb383cd2SLukasz Majewski 3623e8bd469SSimon Glass if (part_get_info(blk_dev, mmcpart, &partinfo) != 0) { 363711b931fSMateusz Zalega error("Couldn't find part #%d on mmc device #%d\n", 364711b931fSMateusz Zalega mmcpart, mmcdev); 3651b6ca18bSPantelis Antoniou return -ENODEV; 3661b6ca18bSPantelis Antoniou } 3671b6ca18bSPantelis Antoniou 368711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 3691b6ca18bSPantelis Antoniou dfu->data.mmc.lba_start = partinfo.start; 3701b6ca18bSPantelis Antoniou dfu->data.mmc.lba_size = partinfo.size; 3711b6ca18bSPantelis Antoniou dfu->data.mmc.lba_blk_size = partinfo.blksz; 372711b931fSMateusz Zalega } else if (!strcmp(entity_type, "fat")) { 373711b931fSMateusz Zalega dfu->layout = DFU_FS_FAT; 374711b931fSMateusz Zalega } else if (!strcmp(entity_type, "ext4")) { 375711b931fSMateusz Zalega dfu->layout = DFU_FS_EXT4; 376cb383cd2SLukasz Majewski } else { 377711b931fSMateusz Zalega error("Memory layout (%s) not supported!\n", entity_type); 3781b6ca18bSPantelis Antoniou return -ENODEV; 379cb383cd2SLukasz Majewski } 380cb383cd2SLukasz Majewski 381711b931fSMateusz Zalega /* if it's NOT a raw write */ 382711b931fSMateusz Zalega if (strcmp(entity_type, "raw")) { 383711b931fSMateusz Zalega dfu->data.mmc.dev = second_arg; 384711b931fSMateusz Zalega dfu->data.mmc.part = third_arg; 38543e66272SŁukasz Majewski } 38643e66272SŁukasz Majewski 387711b931fSMateusz Zalega dfu->dev_type = DFU_DEV_MMC; 3880e285b50SStephen Warren dfu->get_medium_size = dfu_get_medium_size_mmc; 389cb383cd2SLukasz Majewski dfu->read_medium = dfu_read_medium_mmc; 390cb383cd2SLukasz Majewski dfu->write_medium = dfu_write_medium_mmc; 391ea2453d5SPantelis Antoniou dfu->flush_medium = dfu_flush_medium_mmc; 392ea2453d5SPantelis Antoniou dfu->inited = 0; 39341ac233cSPrzemyslaw Marczak dfu->free_entity = dfu_free_entity_mmc; 39441ac233cSPrzemyslaw Marczak 39541ac233cSPrzemyslaw Marczak /* Check if file buffer is ready */ 39641ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 39741ac233cSPrzemyslaw Marczak dfu_file_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, 39841ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 39941ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 40041ac233cSPrzemyslaw Marczak error("Could not memalign 0x%x bytes", 40141ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 40241ac233cSPrzemyslaw Marczak return -ENOMEM; 40341ac233cSPrzemyslaw Marczak } 40441ac233cSPrzemyslaw Marczak } 405cb383cd2SLukasz Majewski 406cb383cd2SLukasz Majewski return 0; 407cb383cd2SLukasz Majewski } 408