From patchwork Thu Jan 9 14:31:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mateusz Zalega X-Patchwork-Id: 308827 X-Patchwork-Delegate: promsoft@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id E968E2C00A5 for ; Fri, 10 Jan 2014 01:41:09 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B5DF74ABF7; Thu, 9 Jan 2014 15:40:51 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dWLKzS3pebgL; Thu, 9 Jan 2014 15:40:51 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3C4DF4AC3C; Thu, 9 Jan 2014 15:40:09 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BD04C4ABF8 for ; Thu, 9 Jan 2014 15:40:04 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VcP0YrDO7mJJ for ; Thu, 9 Jan 2014 15:40:01 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com [210.118.77.12]) by theia.denx.de (Postfix) with ESMTPS id 652014AB2C for ; Thu, 9 Jan 2014 15:39:50 +0100 (CET) Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MZ5007S91L7FCA0@mailout2.w1.samsung.com> for u-boot@lists.denx.de; Thu, 09 Jan 2014 14:29:31 +0000 (GMT) X-AuditID: cbfec7f4-b7f796d000005a13-2b-52ceb24d7d2e Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id A7.2D.23059.D42BEC25; Thu, 09 Jan 2014 14:29:33 +0000 (GMT) Received: from kernelpanic.DIGITAL.local ([106.120.53.14]) by eusync4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MZ5004DQ1L7WS60@eusync4.samsung.com>; Thu, 09 Jan 2014 14:29:33 +0000 (GMT) From: Mateusz Zalega To: u-boot@lists.denx.de Date: Thu, 09 Jan 2014 15:31:57 +0100 Message-id: <1389277919-15279-7-git-send-email-m.zalega@samsung.com> X-Mailer: git-send-email 1.8.2.1 In-reply-to: <1389277919-15279-1-git-send-email-m.zalega@samsung.com> References: <1389277919-15279-1-git-send-email-m.zalega@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrBJMWRmVeSWpSXmKPExsVy+t/xa7q+m84FGdx/K2lxtukNu8Xcd1OY LDqOtDBavN3bye7A4nH2zg5Gj74tqxgDmKK4bFJSczLLUov07RK4MlpvT2Qt+GVfserqT7YG xkXGXYycHBICJhIL5ixnh7DFJC7cW8/WxcjFISSwlFHiyLrrzBBOP5PEs4sdjCBVbALaEjf2 zgfrEBGQkPjVfxUszixQJfHozFGwuLCAsURnw15WEJtFQFViQfN/pi5GDg5eAReJH5crIJYp SBzfvg2slVPAVeJVTyOYLQRU0rjpL8sERt4FjAyrGEVTS5MLipPScw31ihNzi0vz0vWS83M3 MUJC48sOxsXHrA4xCnAwKvHwctSeDRJiTSwrrsw9xCjBwawkwmu84VyQEG9KYmVValF+fFFp TmrxIUYmDk6pBkYpzqtn9NVFGl8cZ9f1Y526ImT3B363C7ni06aX6i6dFfVyjv2c+ZlWH/+s vl24eontRM/Pyw82PDy5YknitgC5PZK1UlIFUocZ71irTWUoWGAuOrtmmkWSRlWk41ILFtPL LdcVa4/VMehk60pYPrvt/Xttbs+vpNLVUxd7nP6ox6d9amr2/ydKLMUZiYZazEXFiQBC0Cjq 6wEAAA== Cc: Kyungmin Park Subject: [U-Boot] [PATCH v3 7/9] dfu:mmc: raw data write fix X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de When user attempted to perform a raw write using DFU (vide dfu_fill_entity_mmc) with MMC interface not initialized before, get_mmc_blk_size() reported invalid (zero) block size - it wasn't possible to write ie. a new u-boot image. This commit fixes that by initializing device in get_mmc_blk_size() when needed. Tested on Samsung Goni. v2 changes: - code cleanup - minor dfu_alt_info format change v3 changes: - moved invalid block length check to mmc core - removed redundant 'has_init' check Change-Id: Icb50bb9f805a9a78848acd19f682fad474cb9082 Signed-off-by: Mateusz Zalega Signed-off-by: Kyungmin Park Reviewed-by: Lukasz Majewski Cc: Minkyu Kang --- drivers/dfu/dfu_mmc.c | 106 ++++++++++++++++++++++++++----------------- drivers/mmc/mmc.c | 13 ++++-- include/configs/am335x_evm.h | 8 ++-- include/configs/trats.h | 2 +- include/configs/trats2.h | 2 +- include/dfu.h | 5 -- 6 files changed, 80 insertions(+), 56 deletions(-) diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index f942758..075e4cd 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -168,66 +168,88 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, return ret; } +/* + * @param s Parameter string containing space-separated arguments: + * 1st: + * raw (raw read/write) + * fat (files) + * ext4 (^) + * part (partition image) + * 2nd and 3rd: + * lba_start and lba_size, for raw write + * mmc_dev and mmc_part, for filesystems and part + */ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) { - int dev, part; - struct mmc *mmc; - block_dev_desc_t *blk_dev; - disk_partition_t partinfo; - char *st; - - dfu->dev_type = DFU_DEV_MMC; - st = strsep(&s, " "); - if (!strcmp(st, "mmc")) { - dfu->layout = DFU_RAW_ADDR; - dfu->data.mmc.lba_start = simple_strtoul(s, &s, 16); - dfu->data.mmc.lba_size = simple_strtoul(++s, &s, 16); - dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num); - } else if (!strcmp(st, "fat")) { - dfu->layout = DFU_FS_FAT; - } else if (!strcmp(st, "ext4")) { - dfu->layout = DFU_FS_EXT4; - } else if (!strcmp(st, "part")) { + const char *argv[3]; + const char **parg = argv; + for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) { + *parg = strsep(&s, " "); + if (*parg == NULL) { + error("Invalid number of arguments.\n"); + return -ENODEV; + } + } - dfu->layout = DFU_RAW_ADDR; + const char *entity_type = argv[0]; + /* + * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8, + * with default 10. + */ + size_t second_arg = simple_strtoul(argv[1], NULL, 0); + size_t third_arg = simple_strtoul(argv[2], NULL, 0); - dev = simple_strtoul(s, &s, 10); - s++; - part = simple_strtoul(s, &s, 10); + struct mmc *mmc = find_mmc_device(dfu->dev_num); + if (mmc == NULL) { + error("Couldn't find MMC device no. %d.\n", dfu->dev_num); + return -ENODEV; + } - mmc = find_mmc_device(dev); - if (mmc == NULL || mmc_init(mmc)) { - printf("%s: could not find mmc device #%d!\n", - __func__, dev); - return -ENODEV; - } + if (mmc_init(mmc)) { + error("Couldn't init MMC device.\n"); + return -ENODEV; + } - blk_dev = &mmc->block_dev; - if (get_partition_info(blk_dev, part, &partinfo) != 0) { - printf("%s: could not find partition #%d on mmc device #%d!\n", - __func__, part, dev); + if (!strcmp(entity_type, "raw")) { + dfu->layout = DFU_RAW_ADDR; + dfu->data.mmc.lba_start = second_arg; + dfu->data.mmc.lba_size = third_arg; + dfu->data.mmc.lba_blk_size = mmc->read_bl_len; + } else if (!strcmp(entity_type, "part")) { + disk_partition_t partinfo; + block_dev_desc_t *blk_dev = &mmc->block_dev; + int mmcdev = second_arg; + int mmcpart = third_arg; + + if (get_partition_info(blk_dev, mmcpart, &partinfo) != 0) { + error("Couldn't find part #%d on mmc device #%d\n", + mmcpart, mmcdev); return -ENODEV; } - dfu->data.mmc.lba_start = partinfo.start; - dfu->data.mmc.lba_size = partinfo.size; - dfu->data.mmc.lba_blk_size = partinfo.blksz; - + dfu->layout = DFU_RAW_ADDR; + dfu->data.mmc.lba_start = partinfo.start; + dfu->data.mmc.lba_size = partinfo.size; + dfu->data.mmc.lba_blk_size = partinfo.blksz; + } else if (!strcmp(entity_type, "fat")) { + dfu->layout = DFU_FS_FAT; + } else if (!strcmp(entity_type, "ext4")) { + dfu->layout = DFU_FS_EXT4; } else { - printf("%s: Memory layout (%s) not supported!\n", __func__, st); + error("Memory layout (%s) not supported!\n", entity_type); return -ENODEV; } - if (dfu->layout == DFU_FS_EXT4 || dfu->layout == DFU_FS_FAT) { - dfu->data.mmc.dev = simple_strtoul(s, &s, 10); - dfu->data.mmc.part = simple_strtoul(++s, &s, 10); + /* if it's NOT a raw write */ + if (strcmp(entity_type, "raw")) { + dfu->data.mmc.dev = second_arg; + dfu->data.mmc.part = third_arg; } + dfu->dev_type = DFU_DEV_MMC; dfu->read_medium = dfu_read_medium_mmc; dfu->write_medium = dfu_write_medium_mmc; dfu->flush_medium = dfu_flush_medium_mmc; - - /* initial state */ dfu->inited = 0; return 0; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e1461a9..f2fa230 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "mmc_private.h" /* Set block count limit because of 16 bit register limit on some hardware*/ @@ -1266,17 +1267,23 @@ static int mmc_complete_init(struct mmc *mmc) int mmc_init(struct mmc *mmc) { + if (mmc->has_init) + return 0; + int err = IN_PROGRESS; unsigned start = get_timer(0); - if (mmc->has_init) - return 0; if (!mmc->init_in_progress) err = mmc_start_init(mmc); - if (!err || err == IN_PROGRESS) err = mmc_complete_init(mmc); + debug("%s: %d, time %lu\n", __func__, err, get_timer(start)); + + if (!mmc->read_bl_len || !mmc->write_bl_len) { + error("invalid block length\n"); + return -ENODEV; + } return err; } diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index 8af4d6a..d76962f 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -312,10 +312,10 @@ "boot part 0 1;" \ "rootfs part 0 2;" \ "MLO fat 0 1;" \ - "MLO.raw mmc 100 100;" \ - "u-boot.img.raw mmc 300 400;" \ - "spl-os-args.raw mmc 80 80;" \ - "spl-os-image.raw mmc 900 2000;" \ + "MLO.raw mmc 0x100 0x100;" \ + "u-boot.img.raw mmc 0x300 0x400;" \ + "spl-os-args.raw mmc 0x80 0x80;" \ + "spl-os-image.raw mmc 0x900 0x2000;" \ "spl-os-args fat 0 1;" \ "spl-os-image fat 0 1;" \ "u-boot.img fat 0 1;" \ diff --git a/include/configs/trats.h b/include/configs/trats.h index 6cd15c2..ed3b278 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -140,7 +140,7 @@ "name="PARTS_UMS",size=-,uuid=${uuid_gpt_"PARTS_UMS"}\0" \ #define CONFIG_DFU_ALT \ - "u-boot mmc 80 400;" \ + "u-boot raw 0x80 0x400;" \ "uImage ext4 0 2;" \ "exynos4210-trats.dtb ext4 0 2;" \ ""PARTS_ROOT" part 0 5\0" diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 5d86a3d..a22be63 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -169,7 +169,7 @@ "name="PARTS_UMS",size=-,uuid=${uuid_gpt_"PARTS_UMS"}\0" \ #define CONFIG_DFU_ALT \ - "u-boot mmc 80 800;" \ + "u-boot mmc 0x80 0x800;" \ "uImage ext4 0 2;" \ "exynos4412-trats2.dtb ext4 0 2;" \ ""PARTS_ROOT" part 0 5\0" diff --git a/include/dfu.h b/include/dfu.h index f973426..f2e83db 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -64,11 +64,6 @@ struct ram_internal_data { unsigned int size; }; -static inline unsigned int get_mmc_blk_size(int dev) -{ - return find_mmc_device(dev)->read_bl_len; -} - #define DFU_NAME_SIZE 32 #define DFU_CMD_BUF_SIZE 128 #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE