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; 53873cc1d7SStephen Warren ret = mmc_select_hwpart(dfu->data.mmc.dev_num, 54873cc1d7SStephen Warren dfu->data.mmc.hw_partition); 55c8151b4aSLukasz Majewski if (ret) 56c8151b4aSLukasz Majewski return ret; 57c8151b4aSLukasz Majewski } 58c8151b4aSLukasz Majewski 597d0b605aSŁukasz Majewski debug("%s: %s dev: %d start: %d cnt: %d buf: 0x%p\n", __func__, 60dd64827eSStephen Warren op == DFU_OP_READ ? "MMC READ" : "MMC WRITE", 61dd64827eSStephen Warren dfu->data.mmc.dev_num, blk_start, blk_count, buf); 627d0b605aSŁukasz Majewski switch (op) { 637d0b605aSŁukasz Majewski case DFU_OP_READ: 647c4213f6SStephen Warren n = mmc->block_dev.block_read(&mmc->block_dev, blk_start, 657d0b605aSŁukasz Majewski blk_count, buf); 667d0b605aSŁukasz Majewski break; 677d0b605aSŁukasz Majewski case DFU_OP_WRITE: 687c4213f6SStephen Warren n = mmc->block_dev.block_write(&mmc->block_dev, blk_start, 697d0b605aSŁukasz Majewski blk_count, 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) 78873cc1d7SStephen Warren mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp); 797d0b605aSŁukasz Majewski return -EIO; 807d0b605aSŁukasz Majewski } 817d0b605aSŁukasz Majewski 82c8151b4aSLukasz Majewski if (dfu->data.mmc.hw_partition >= 0) { 83873cc1d7SStephen Warren ret = mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp); 84c8151b4aSLukasz Majewski if (ret) 85c8151b4aSLukasz Majewski return ret; 86c8151b4aSLukasz Majewski } 87c8151b4aSLukasz Majewski 887d0b605aSŁukasz Majewski return 0; 89cb383cd2SLukasz Majewski } 90cb383cd2SLukasz Majewski 91ea2453d5SPantelis Antoniou static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len) 92cb383cd2SLukasz Majewski { 93ea2453d5SPantelis Antoniou if (dfu_file_buf_len + *len > CONFIG_SYS_DFU_MAX_FILE_SIZE) { 94ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 95ea2453d5SPantelis Antoniou return -EINVAL; 96cb383cd2SLukasz Majewski } 97cb383cd2SLukasz Majewski 98ea2453d5SPantelis Antoniou /* Add to the current buffer. */ 99ea2453d5SPantelis Antoniou memcpy(dfu_file_buf + dfu_file_buf_len, buf, *len); 100ea2453d5SPantelis Antoniou dfu_file_buf_len += *len; 101ea2453d5SPantelis Antoniou 102ea2453d5SPantelis Antoniou return 0; 103cb383cd2SLukasz Majewski } 104cb383cd2SLukasz Majewski 1055a127c84SAfzal Mohammed static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu, 106cb383cd2SLukasz Majewski void *buf, long *len) 107cb383cd2SLukasz Majewski { 1080e285b50SStephen Warren const char *fsname, *opname; 109cb383cd2SLukasz Majewski char cmd_buf[DFU_CMD_BUF_SIZE]; 110cb383cd2SLukasz Majewski char *str_env; 111cb383cd2SLukasz Majewski int ret; 112cb383cd2SLukasz Majewski 11343e66272SŁukasz Majewski switch (dfu->layout) { 11443e66272SŁukasz Majewski case DFU_FS_FAT: 1150e285b50SStephen Warren fsname = "fat"; 11643e66272SŁukasz Majewski break; 11743e66272SŁukasz Majewski case DFU_FS_EXT4: 1180e285b50SStephen Warren fsname = "ext4"; 11943e66272SŁukasz Majewski break; 12043e66272SŁukasz Majewski default: 12143e66272SŁukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 12243e66272SŁukasz Majewski dfu_get_layout(dfu->layout)); 123ea2453d5SPantelis Antoniou return -1; 12443e66272SŁukasz Majewski } 125cb383cd2SLukasz Majewski 1260e285b50SStephen Warren switch (op) { 1270e285b50SStephen Warren case DFU_OP_READ: 1280e285b50SStephen Warren opname = "load"; 1290e285b50SStephen Warren break; 1300e285b50SStephen Warren case DFU_OP_WRITE: 1310e285b50SStephen Warren opname = "write"; 1320e285b50SStephen Warren break; 1330e285b50SStephen Warren case DFU_OP_SIZE: 1340e285b50SStephen Warren opname = "size"; 1350e285b50SStephen Warren break; 1360e285b50SStephen Warren default: 1370e285b50SStephen Warren return -1; 1380e285b50SStephen Warren } 1390e285b50SStephen Warren 1400e285b50SStephen Warren sprintf(cmd_buf, "%s%s mmc %d:%d", fsname, opname, 1410e285b50SStephen Warren dfu->data.mmc.dev, dfu->data.mmc.part); 1420e285b50SStephen Warren 1430e285b50SStephen Warren if (op != DFU_OP_SIZE) 144e621c7abSStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %p", buf); 1450e285b50SStephen Warren 1460e285b50SStephen Warren sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name); 1470e285b50SStephen Warren 14817eb1d8fSLukasz Majewski if (op == DFU_OP_WRITE) 14917eb1d8fSLukasz Majewski sprintf(cmd_buf + strlen(cmd_buf), " %lx", *len); 15017eb1d8fSLukasz Majewski 151cb383cd2SLukasz Majewski debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); 152cb383cd2SLukasz Majewski 153cb383cd2SLukasz Majewski ret = run_command(cmd_buf, 0); 154cb383cd2SLukasz Majewski if (ret) { 155cb383cd2SLukasz Majewski puts("dfu: Read error!\n"); 156cb383cd2SLukasz Majewski return ret; 157cb383cd2SLukasz Majewski } 158cb383cd2SLukasz Majewski 1590e285b50SStephen Warren if (op != DFU_OP_WRITE) { 160cb383cd2SLukasz Majewski str_env = getenv("filesize"); 161cb383cd2SLukasz Majewski if (str_env == NULL) { 162cb383cd2SLukasz Majewski puts("dfu: Wrong file size!\n"); 163cb383cd2SLukasz Majewski return -1; 164cb383cd2SLukasz Majewski } 165cb383cd2SLukasz Majewski *len = simple_strtoul(str_env, NULL, 16); 166cb383cd2SLukasz Majewski } 167cb383cd2SLukasz Majewski 168cb383cd2SLukasz Majewski return ret; 169cb383cd2SLukasz Majewski } 170cb383cd2SLukasz Majewski 171ea2453d5SPantelis Antoniou int dfu_write_medium_mmc(struct dfu_entity *dfu, 172ea2453d5SPantelis Antoniou u64 offset, void *buf, long *len) 173cb383cd2SLukasz Majewski { 174cb383cd2SLukasz Majewski int ret = -1; 175cb383cd2SLukasz Majewski 176cb383cd2SLukasz Majewski switch (dfu->layout) { 177cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 178ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_WRITE, dfu, offset, buf, len); 179cb383cd2SLukasz Majewski break; 180cb383cd2SLukasz Majewski case DFU_FS_FAT: 18143e66272SŁukasz Majewski case DFU_FS_EXT4: 182ea2453d5SPantelis Antoniou ret = mmc_file_buffer(dfu, buf, len); 183cb383cd2SLukasz Majewski break; 184cb383cd2SLukasz Majewski default: 185cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 186cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 187cb383cd2SLukasz Majewski } 188cb383cd2SLukasz Majewski 189cb383cd2SLukasz Majewski return ret; 190cb383cd2SLukasz Majewski } 191cb383cd2SLukasz Majewski 192ea2453d5SPantelis Antoniou int dfu_flush_medium_mmc(struct dfu_entity *dfu) 193ea2453d5SPantelis Antoniou { 194ea2453d5SPantelis Antoniou int ret = 0; 195ea2453d5SPantelis Antoniou 196ea2453d5SPantelis Antoniou if (dfu->layout != DFU_RAW_ADDR) { 197ea2453d5SPantelis Antoniou /* Do stuff here. */ 19841ac233cSPrzemyslaw Marczak ret = mmc_file_op(DFU_OP_WRITE, dfu, dfu_file_buf, 199ea2453d5SPantelis Antoniou &dfu_file_buf_len); 200ea2453d5SPantelis Antoniou 201ea2453d5SPantelis Antoniou /* Now that we're done */ 202ea2453d5SPantelis Antoniou dfu_file_buf_len = 0; 203ea2453d5SPantelis Antoniou } 204ea2453d5SPantelis Antoniou 205ea2453d5SPantelis Antoniou return ret; 206ea2453d5SPantelis Antoniou } 207ea2453d5SPantelis Antoniou 2080e285b50SStephen Warren long dfu_get_medium_size_mmc(struct dfu_entity *dfu) 2090e285b50SStephen Warren { 2100e285b50SStephen Warren int ret; 2110e285b50SStephen Warren long len; 2120e285b50SStephen Warren 2130e285b50SStephen Warren switch (dfu->layout) { 2140e285b50SStephen Warren case DFU_RAW_ADDR: 2150e285b50SStephen Warren return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; 2160e285b50SStephen Warren case DFU_FS_FAT: 2170e285b50SStephen Warren case DFU_FS_EXT4: 218411c5e57SStephen Warren dfu_file_buf_filled = -1; 2190e285b50SStephen Warren ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len); 2200e285b50SStephen Warren if (ret < 0) 2210e285b50SStephen Warren return ret; 222411c5e57SStephen Warren if (len > CONFIG_SYS_DFU_MAX_FILE_SIZE) 223411c5e57SStephen Warren return -1; 2240e285b50SStephen Warren return len; 2250e285b50SStephen Warren default: 2260e285b50SStephen Warren printf("%s: Layout (%s) not (yet) supported!\n", __func__, 2270e285b50SStephen Warren dfu_get_layout(dfu->layout)); 2280e285b50SStephen Warren return -1; 2290e285b50SStephen Warren } 2300e285b50SStephen Warren } 2310e285b50SStephen Warren 232411c5e57SStephen Warren static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf, 233411c5e57SStephen Warren long *len) 234411c5e57SStephen Warren { 235411c5e57SStephen Warren int ret; 236411c5e57SStephen Warren long file_len; 237411c5e57SStephen Warren 238411c5e57SStephen Warren if (dfu_file_buf_filled == -1) { 239411c5e57SStephen Warren ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len); 240411c5e57SStephen Warren if (ret < 0) 241411c5e57SStephen Warren return ret; 242411c5e57SStephen Warren dfu_file_buf_filled = file_len; 243411c5e57SStephen Warren } 244411c5e57SStephen Warren if (offset + *len > dfu_file_buf_filled) 245411c5e57SStephen Warren return -EINVAL; 246411c5e57SStephen Warren 247411c5e57SStephen Warren /* Add to the current buffer. */ 248411c5e57SStephen Warren memcpy(buf, dfu_file_buf + offset, *len); 249411c5e57SStephen Warren 250411c5e57SStephen Warren return 0; 251411c5e57SStephen Warren } 252411c5e57SStephen Warren 253ea2453d5SPantelis Antoniou int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, 254ea2453d5SPantelis Antoniou long *len) 255cb383cd2SLukasz Majewski { 256cb383cd2SLukasz Majewski int ret = -1; 257cb383cd2SLukasz Majewski 258cb383cd2SLukasz Majewski switch (dfu->layout) { 259cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 260ea2453d5SPantelis Antoniou ret = mmc_block_op(DFU_OP_READ, dfu, offset, buf, len); 261cb383cd2SLukasz Majewski break; 262cb383cd2SLukasz Majewski case DFU_FS_FAT: 26343e66272SŁukasz Majewski case DFU_FS_EXT4: 264411c5e57SStephen Warren ret = mmc_file_unbuffer(dfu, offset, buf, len); 265cb383cd2SLukasz Majewski break; 266cb383cd2SLukasz Majewski default: 267cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 268cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 269cb383cd2SLukasz Majewski } 270cb383cd2SLukasz Majewski 271cb383cd2SLukasz Majewski return ret; 272cb383cd2SLukasz Majewski } 273cb383cd2SLukasz Majewski 27441ac233cSPrzemyslaw Marczak void dfu_free_entity_mmc(struct dfu_entity *dfu) 27541ac233cSPrzemyslaw Marczak { 27641ac233cSPrzemyslaw Marczak if (dfu_file_buf) { 27741ac233cSPrzemyslaw Marczak free(dfu_file_buf); 27841ac233cSPrzemyslaw Marczak dfu_file_buf = NULL; 27941ac233cSPrzemyslaw Marczak } 28041ac233cSPrzemyslaw Marczak } 28141ac233cSPrzemyslaw Marczak 282711b931fSMateusz Zalega /* 283711b931fSMateusz Zalega * @param s Parameter string containing space-separated arguments: 284711b931fSMateusz Zalega * 1st: 285711b931fSMateusz Zalega * raw (raw read/write) 286711b931fSMateusz Zalega * fat (files) 287711b931fSMateusz Zalega * ext4 (^) 288711b931fSMateusz Zalega * part (partition image) 289711b931fSMateusz Zalega * 2nd and 3rd: 290711b931fSMateusz Zalega * lba_start and lba_size, for raw write 291711b931fSMateusz Zalega * mmc_dev and mmc_part, for filesystems and part 292c8151b4aSLukasz Majewski * 4th (optional): 293c8151b4aSLukasz Majewski * mmcpart <num> (access to HW eMMC partitions) 294711b931fSMateusz Zalega */ 295dd64827eSStephen Warren int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s) 296cb383cd2SLukasz Majewski { 297711b931fSMateusz Zalega const char *entity_type; 298711b931fSMateusz Zalega size_t second_arg; 299711b931fSMateusz Zalega size_t third_arg; 300711b931fSMateusz Zalega 3011b6ca18bSPantelis Antoniou struct mmc *mmc; 302711b931fSMateusz Zalega 303711b931fSMateusz Zalega const char *argv[3]; 304711b931fSMateusz Zalega const char **parg = argv; 305711b931fSMateusz Zalega 306dd64827eSStephen Warren dfu->data.mmc.dev_num = simple_strtoul(devstr, NULL, 10); 307dd64827eSStephen Warren 308711b931fSMateusz Zalega for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) { 309711b931fSMateusz Zalega *parg = strsep(&s, " "); 310711b931fSMateusz Zalega if (*parg == NULL) { 311711b931fSMateusz Zalega error("Invalid number of arguments.\n"); 312711b931fSMateusz Zalega return -ENODEV; 313711b931fSMateusz Zalega } 314711b931fSMateusz Zalega } 315711b931fSMateusz Zalega 316711b931fSMateusz Zalega entity_type = argv[0]; 317b7d4259aSMateusz Zalega /* 318b7d4259aSMateusz Zalega * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8, 319b7d4259aSMateusz Zalega * with default 10. 320b7d4259aSMateusz Zalega */ 321b7d4259aSMateusz Zalega second_arg = simple_strtoul(argv[1], NULL, 0); 322b7d4259aSMateusz Zalega third_arg = simple_strtoul(argv[2], NULL, 0); 323711b931fSMateusz Zalega 324dd64827eSStephen Warren mmc = find_mmc_device(dfu->data.mmc.dev_num); 325711b931fSMateusz Zalega if (mmc == NULL) { 326dd64827eSStephen Warren error("Couldn't find MMC device no. %d.\n", 327dd64827eSStephen Warren dfu->data.mmc.dev_num); 328711b931fSMateusz Zalega return -ENODEV; 329711b931fSMateusz Zalega } 330711b931fSMateusz Zalega 331711b931fSMateusz Zalega if (mmc_init(mmc)) { 332711b931fSMateusz Zalega error("Couldn't init MMC device.\n"); 333711b931fSMateusz Zalega return -ENODEV; 334711b931fSMateusz Zalega } 335711b931fSMateusz Zalega 336c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = -EINVAL; 337711b931fSMateusz Zalega if (!strcmp(entity_type, "raw")) { 338711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 339711b931fSMateusz Zalega dfu->data.mmc.lba_start = second_arg; 340711b931fSMateusz Zalega dfu->data.mmc.lba_size = third_arg; 341711b931fSMateusz Zalega dfu->data.mmc.lba_blk_size = mmc->read_bl_len; 342c8151b4aSLukasz Majewski 343c8151b4aSLukasz Majewski /* 344c8151b4aSLukasz Majewski * Check for an extra entry at dfu_alt_info env variable 345c8151b4aSLukasz Majewski * specifying the mmc HW defined partition number 346c8151b4aSLukasz Majewski */ 347c8151b4aSLukasz Majewski if (s) 348c8151b4aSLukasz Majewski if (!strcmp(strsep(&s, " "), "mmcpart")) 349c8151b4aSLukasz Majewski dfu->data.mmc.hw_partition = 350c8151b4aSLukasz Majewski simple_strtoul(s, NULL, 0); 351c8151b4aSLukasz Majewski 352711b931fSMateusz Zalega } else if (!strcmp(entity_type, "part")) { 3531b6ca18bSPantelis Antoniou disk_partition_t partinfo; 3544101f687SSimon Glass struct blk_desc *blk_dev = &mmc->block_dev; 355711b931fSMateusz Zalega int mmcdev = second_arg; 356711b931fSMateusz Zalega int mmcpart = third_arg; 357cb383cd2SLukasz Majewski 358*3e8bd469SSimon Glass if (part_get_info(blk_dev, mmcpart, &partinfo) != 0) { 359711b931fSMateusz Zalega error("Couldn't find part #%d on mmc device #%d\n", 360711b931fSMateusz Zalega mmcpart, mmcdev); 3611b6ca18bSPantelis Antoniou return -ENODEV; 3621b6ca18bSPantelis Antoniou } 3631b6ca18bSPantelis Antoniou 364711b931fSMateusz Zalega dfu->layout = DFU_RAW_ADDR; 3651b6ca18bSPantelis Antoniou dfu->data.mmc.lba_start = partinfo.start; 3661b6ca18bSPantelis Antoniou dfu->data.mmc.lba_size = partinfo.size; 3671b6ca18bSPantelis Antoniou dfu->data.mmc.lba_blk_size = partinfo.blksz; 368711b931fSMateusz Zalega } else if (!strcmp(entity_type, "fat")) { 369711b931fSMateusz Zalega dfu->layout = DFU_FS_FAT; 370711b931fSMateusz Zalega } else if (!strcmp(entity_type, "ext4")) { 371711b931fSMateusz Zalega dfu->layout = DFU_FS_EXT4; 372cb383cd2SLukasz Majewski } else { 373711b931fSMateusz Zalega error("Memory layout (%s) not supported!\n", entity_type); 3741b6ca18bSPantelis Antoniou return -ENODEV; 375cb383cd2SLukasz Majewski } 376cb383cd2SLukasz Majewski 377711b931fSMateusz Zalega /* if it's NOT a raw write */ 378711b931fSMateusz Zalega if (strcmp(entity_type, "raw")) { 379711b931fSMateusz Zalega dfu->data.mmc.dev = second_arg; 380711b931fSMateusz Zalega dfu->data.mmc.part = third_arg; 38143e66272SŁukasz Majewski } 38243e66272SŁukasz Majewski 383711b931fSMateusz Zalega dfu->dev_type = DFU_DEV_MMC; 3840e285b50SStephen Warren dfu->get_medium_size = dfu_get_medium_size_mmc; 385cb383cd2SLukasz Majewski dfu->read_medium = dfu_read_medium_mmc; 386cb383cd2SLukasz Majewski dfu->write_medium = dfu_write_medium_mmc; 387ea2453d5SPantelis Antoniou dfu->flush_medium = dfu_flush_medium_mmc; 388ea2453d5SPantelis Antoniou dfu->inited = 0; 38941ac233cSPrzemyslaw Marczak dfu->free_entity = dfu_free_entity_mmc; 39041ac233cSPrzemyslaw Marczak 39141ac233cSPrzemyslaw Marczak /* Check if file buffer is ready */ 39241ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 39341ac233cSPrzemyslaw Marczak dfu_file_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, 39441ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 39541ac233cSPrzemyslaw Marczak if (!dfu_file_buf) { 39641ac233cSPrzemyslaw Marczak error("Could not memalign 0x%x bytes", 39741ac233cSPrzemyslaw Marczak CONFIG_SYS_DFU_MAX_FILE_SIZE); 39841ac233cSPrzemyslaw Marczak return -ENOMEM; 39941ac233cSPrzemyslaw Marczak } 40041ac233cSPrzemyslaw Marczak } 401cb383cd2SLukasz Majewski 402cb383cd2SLukasz Majewski return 0; 403cb383cd2SLukasz Majewski } 404