1*cb383cd2SLukasz Majewski /* 2*cb383cd2SLukasz Majewski * dfu.c -- DFU back-end routines 3*cb383cd2SLukasz Majewski * 4*cb383cd2SLukasz Majewski * Copyright (C) 2012 Samsung Electronics 5*cb383cd2SLukasz Majewski * author: Lukasz Majewski <l.majewski@samsung.com> 6*cb383cd2SLukasz Majewski * 7*cb383cd2SLukasz Majewski * This program is free software; you can redistribute it and/or modify 8*cb383cd2SLukasz Majewski * it under the terms of the GNU General Public License as published by 9*cb383cd2SLukasz Majewski * the Free Software Foundation; either version 2 of the License, or 10*cb383cd2SLukasz Majewski * (at your option) any later version. 11*cb383cd2SLukasz Majewski * 12*cb383cd2SLukasz Majewski * This program is distributed in the hope that it will be useful, 13*cb383cd2SLukasz Majewski * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*cb383cd2SLukasz Majewski * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*cb383cd2SLukasz Majewski * GNU General Public License for more details. 16*cb383cd2SLukasz Majewski * 17*cb383cd2SLukasz Majewski * You should have received a copy of the GNU General Public License 18*cb383cd2SLukasz Majewski * along with this program; if not, write to the Free Software 19*cb383cd2SLukasz Majewski * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20*cb383cd2SLukasz Majewski */ 21*cb383cd2SLukasz Majewski 22*cb383cd2SLukasz Majewski #include <common.h> 23*cb383cd2SLukasz Majewski #include <malloc.h> 24*cb383cd2SLukasz Majewski #include <dfu.h> 25*cb383cd2SLukasz Majewski 26*cb383cd2SLukasz Majewski enum dfu_mmc_op { 27*cb383cd2SLukasz Majewski DFU_OP_READ = 1, 28*cb383cd2SLukasz Majewski DFU_OP_WRITE, 29*cb383cd2SLukasz Majewski }; 30*cb383cd2SLukasz Majewski 31*cb383cd2SLukasz Majewski static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu, 32*cb383cd2SLukasz Majewski void *buf, long *len) 33*cb383cd2SLukasz Majewski { 34*cb383cd2SLukasz Majewski char cmd_buf[DFU_CMD_BUF_SIZE]; 35*cb383cd2SLukasz Majewski 36*cb383cd2SLukasz Majewski sprintf(cmd_buf, "mmc %s 0x%x %x %x", 37*cb383cd2SLukasz Majewski op == DFU_OP_READ ? "read" : "write", 38*cb383cd2SLukasz Majewski (unsigned int) buf, 39*cb383cd2SLukasz Majewski dfu->data.mmc.lba_start, 40*cb383cd2SLukasz Majewski dfu->data.mmc.lba_size); 41*cb383cd2SLukasz Majewski 42*cb383cd2SLukasz Majewski if (op == DFU_OP_READ) 43*cb383cd2SLukasz Majewski *len = dfu->data.mmc.lba_blk_size * dfu->data.mmc.lba_size; 44*cb383cd2SLukasz Majewski 45*cb383cd2SLukasz Majewski debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); 46*cb383cd2SLukasz Majewski return run_command(cmd_buf, 0); 47*cb383cd2SLukasz Majewski } 48*cb383cd2SLukasz Majewski 49*cb383cd2SLukasz Majewski static inline int mmc_block_write(struct dfu_entity *dfu, void *buf, long *len) 50*cb383cd2SLukasz Majewski { 51*cb383cd2SLukasz Majewski return mmc_block_op(DFU_OP_WRITE, dfu, buf, len); 52*cb383cd2SLukasz Majewski } 53*cb383cd2SLukasz Majewski 54*cb383cd2SLukasz Majewski static inline int mmc_block_read(struct dfu_entity *dfu, void *buf, long *len) 55*cb383cd2SLukasz Majewski { 56*cb383cd2SLukasz Majewski return mmc_block_op(DFU_OP_READ, dfu, buf, len); 57*cb383cd2SLukasz Majewski } 58*cb383cd2SLukasz Majewski 59*cb383cd2SLukasz Majewski static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu, 60*cb383cd2SLukasz Majewski void *buf, long *len) 61*cb383cd2SLukasz Majewski { 62*cb383cd2SLukasz Majewski char cmd_buf[DFU_CMD_BUF_SIZE]; 63*cb383cd2SLukasz Majewski char *str_env; 64*cb383cd2SLukasz Majewski int ret; 65*cb383cd2SLukasz Majewski 66*cb383cd2SLukasz Majewski sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx", 67*cb383cd2SLukasz Majewski op == DFU_OP_READ ? "load" : "write", 68*cb383cd2SLukasz Majewski dfu->data.mmc.dev, dfu->data.mmc.part, 69*cb383cd2SLukasz Majewski (unsigned int) buf, dfu->name, *len); 70*cb383cd2SLukasz Majewski 71*cb383cd2SLukasz Majewski debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); 72*cb383cd2SLukasz Majewski 73*cb383cd2SLukasz Majewski ret = run_command(cmd_buf, 0); 74*cb383cd2SLukasz Majewski if (ret) { 75*cb383cd2SLukasz Majewski puts("dfu: Read error!\n"); 76*cb383cd2SLukasz Majewski return ret; 77*cb383cd2SLukasz Majewski } 78*cb383cd2SLukasz Majewski 79*cb383cd2SLukasz Majewski if (dfu->layout != DFU_RAW_ADDR) { 80*cb383cd2SLukasz Majewski str_env = getenv("filesize"); 81*cb383cd2SLukasz Majewski if (str_env == NULL) { 82*cb383cd2SLukasz Majewski puts("dfu: Wrong file size!\n"); 83*cb383cd2SLukasz Majewski return -1; 84*cb383cd2SLukasz Majewski } 85*cb383cd2SLukasz Majewski *len = simple_strtoul(str_env, NULL, 16); 86*cb383cd2SLukasz Majewski } 87*cb383cd2SLukasz Majewski 88*cb383cd2SLukasz Majewski return ret; 89*cb383cd2SLukasz Majewski } 90*cb383cd2SLukasz Majewski 91*cb383cd2SLukasz Majewski static inline int mmc_file_write(struct dfu_entity *dfu, void *buf, long *len) 92*cb383cd2SLukasz Majewski { 93*cb383cd2SLukasz Majewski return mmc_file_op(DFU_OP_WRITE, dfu, buf, len); 94*cb383cd2SLukasz Majewski } 95*cb383cd2SLukasz Majewski 96*cb383cd2SLukasz Majewski static inline int mmc_file_read(struct dfu_entity *dfu, void *buf, long *len) 97*cb383cd2SLukasz Majewski { 98*cb383cd2SLukasz Majewski return mmc_file_op(DFU_OP_READ, dfu, buf, len); 99*cb383cd2SLukasz Majewski } 100*cb383cd2SLukasz Majewski 101*cb383cd2SLukasz Majewski int dfu_write_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) 102*cb383cd2SLukasz Majewski { 103*cb383cd2SLukasz Majewski int ret = -1; 104*cb383cd2SLukasz Majewski 105*cb383cd2SLukasz Majewski switch (dfu->layout) { 106*cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 107*cb383cd2SLukasz Majewski ret = mmc_block_write(dfu, buf, len); 108*cb383cd2SLukasz Majewski break; 109*cb383cd2SLukasz Majewski case DFU_FS_FAT: 110*cb383cd2SLukasz Majewski ret = mmc_file_write(dfu, buf, len); 111*cb383cd2SLukasz Majewski break; 112*cb383cd2SLukasz Majewski default: 113*cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 114*cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 115*cb383cd2SLukasz Majewski } 116*cb383cd2SLukasz Majewski 117*cb383cd2SLukasz Majewski return ret; 118*cb383cd2SLukasz Majewski } 119*cb383cd2SLukasz Majewski 120*cb383cd2SLukasz Majewski int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) 121*cb383cd2SLukasz Majewski { 122*cb383cd2SLukasz Majewski int ret = -1; 123*cb383cd2SLukasz Majewski 124*cb383cd2SLukasz Majewski switch (dfu->layout) { 125*cb383cd2SLukasz Majewski case DFU_RAW_ADDR: 126*cb383cd2SLukasz Majewski ret = mmc_block_read(dfu, buf, len); 127*cb383cd2SLukasz Majewski break; 128*cb383cd2SLukasz Majewski case DFU_FS_FAT: 129*cb383cd2SLukasz Majewski ret = mmc_file_read(dfu, buf, len); 130*cb383cd2SLukasz Majewski break; 131*cb383cd2SLukasz Majewski default: 132*cb383cd2SLukasz Majewski printf("%s: Layout (%s) not (yet) supported!\n", __func__, 133*cb383cd2SLukasz Majewski dfu_get_layout(dfu->layout)); 134*cb383cd2SLukasz Majewski } 135*cb383cd2SLukasz Majewski 136*cb383cd2SLukasz Majewski return ret; 137*cb383cd2SLukasz Majewski } 138*cb383cd2SLukasz Majewski 139*cb383cd2SLukasz Majewski int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) 140*cb383cd2SLukasz Majewski { 141*cb383cd2SLukasz Majewski char *st; 142*cb383cd2SLukasz Majewski 143*cb383cd2SLukasz Majewski dfu->dev_type = DFU_DEV_MMC; 144*cb383cd2SLukasz Majewski st = strsep(&s, " "); 145*cb383cd2SLukasz Majewski if (!strcmp(st, "mmc")) { 146*cb383cd2SLukasz Majewski dfu->layout = DFU_RAW_ADDR; 147*cb383cd2SLukasz Majewski dfu->data.mmc.lba_start = simple_strtoul(s, &s, 16); 148*cb383cd2SLukasz Majewski dfu->data.mmc.lba_size = simple_strtoul(++s, &s, 16); 149*cb383cd2SLukasz Majewski dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num); 150*cb383cd2SLukasz Majewski } else if (!strcmp(st, "fat")) { 151*cb383cd2SLukasz Majewski dfu->layout = DFU_FS_FAT; 152*cb383cd2SLukasz Majewski dfu->data.mmc.dev = simple_strtoul(s, &s, 10); 153*cb383cd2SLukasz Majewski dfu->data.mmc.part = simple_strtoul(++s, &s, 10); 154*cb383cd2SLukasz Majewski } else { 155*cb383cd2SLukasz Majewski printf("%s: Memory layout (%s) not supported!\n", __func__, st); 156*cb383cd2SLukasz Majewski } 157*cb383cd2SLukasz Majewski 158*cb383cd2SLukasz Majewski dfu->read_medium = dfu_read_medium_mmc; 159*cb383cd2SLukasz Majewski dfu->write_medium = dfu_write_medium_mmc; 160*cb383cd2SLukasz Majewski 161*cb383cd2SLukasz Majewski return 0; 162*cb383cd2SLukasz Majewski } 163