From patchwork Fri Aug 3 07:45:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?=C5=81ukasz_Majewski?= X-Patchwork-Id: 174913 X-Patchwork-Delegate: marek.vasut@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 0BB912C064A for ; Fri, 3 Aug 2012 17:46:48 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A4A24280C3; Fri, 3 Aug 2012 09:46:47 +0200 (CEST) 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 HMxtavUgF3VJ; Fri, 3 Aug 2012 09:46:47 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 191362809A; Fri, 3 Aug 2012 09:46:34 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E816628094 for ; Fri, 3 Aug 2012 09:46:30 +0200 (CEST) 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 sxrBJqX2jaDc for ; Fri, 3 Aug 2012 09:46:30 +0200 (CEST) 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 mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by theia.denx.de (Postfix) with ESMTP id 9EF9F280A4 for ; Fri, 3 Aug 2012 09:46:22 +0200 (CEST) Received: from epcpsbgm2.samsung.com (mailout3.samsung.com [203.254.224.33]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0M8600L4K5KFQ190@mailout3.samsung.com> for u-boot@lists.denx.de; Fri, 03 Aug 2012 16:46:13 +0900 (KST) X-AuditID: cbfee61b-b7f566d000005c8a-c1-501b81c5b90b Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id EB.CB.23690.5C18B105; Fri, 03 Aug 2012 16:46:13 +0900 (KST) Received: from mcdsrvbld02.digital.local ([106.116.37.23]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0M86007XZ5K6EG60@mmp1.samsung.com> for u-boot@lists.denx.de; Fri, 03 Aug 2012 16:46:13 +0900 (KST) From: Lukasz Majewski To: u-boot@lists.denx.de Date: Fri, 03 Aug 2012 09:45:36 +0200 Message-id: <1343979939-27880-5-git-send-email-l.majewski@samsung.com> X-Mailer: git-send-email 1.7.10 In-reply-to: <1343979939-27880-1-git-send-email-l.majewski@samsung.com> References: <1341308291-14663-1-git-send-email-l.majewski@samsung.com> <1343979939-27880-1-git-send-email-l.majewski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrMJMWRmVeSWpSXmKPExsVy+t9jAd2jjdIBBrP/SFu83dvJ7sDocfbO DsYAxigum5TUnMyy1CJ9uwSujHn/5Quu6VY8mLSCrYHxp0oXIyeHhICJxKdJy9ghbDGJC/fW s3UxcnEICSxilNh+q4cFwlnMJLFpwRewKjYBPYnPd58ygdgiAhISv/qvMoIUMQvMY5K4tnAG G0hCWMBF4vaW2cxdjBwcLAKqEvf2m4OEeQXcJCZ9/MsIsU1e4un9PrByTgF3iT8HHkEta2aU 2LnhEPMERt4FjAyrGEVTC5ILipPSc430ihNzi0vz0vWS83M3MYK9/kx6B+OqBotDjAIcjEo8 vEaS0gFCrIllxZW5hxglOJiVRHiP5QKFeFMSK6tSi/Lji0pzUosPMUpzsCiJ85p4f/UXEkhP LEnNTk0tSC2CyTJxcEo1MPKll8127vi38nPNb975DPMj91+P3rJo0kOR8I9Z+TMYucSTRXad 3tr/3qsy30g/d1rUXb1Kf6/XCe9DM1e/M5Cv2G/yYuEC4awklXVTL6TaJaZcX2OqfvV+2b8J jW6VsXKHJx3XDlR3mrByxS+mWUG5DpHvLjTOn/TdSujtKvbXNjXT7zqvqVRiKc5INNRiLipO BAAyku4B9gEAAA== X-TM-AS-MML: No Cc: Marek Vasut , Kyungmin Park , Tom Rini , Andy Fleming Subject: [U-Boot] [PATCH v4 4/7] dfu: MMC specific routines for DFU operation 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 Support for MMC storage devices to work with DFU framework. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut --- Changes for v2: - None Changes for v3: - Provide special abstraction layer (mmc_{block|file}_{read|write}) to alleviate switch to new device model (DM) - More verbose messages when not supported layout encountered - Calls to strncmp() replaced with strcmp() Changes for v4: - Remove superfluous memset() calls - Replace ALLOC_CACHE_ALIGN_BUFFER with plain table definition - Cosmetic changes with pointers definition --- drivers/dfu/Makefile | 1 + drivers/dfu/dfu_mmc.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 0 deletions(-) create mode 100644 drivers/dfu/dfu_mmc.c diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile index 7736485..7b717bc 100644 --- a/drivers/dfu/Makefile +++ b/drivers/dfu/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)libdfu.o COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o +COBJS-$(CONFIG_DFU_MMC) += dfu_mmc.o SRCS := $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c new file mode 100644 index 0000000..060145b --- /dev/null +++ b/drivers/dfu/dfu_mmc.c @@ -0,0 +1,162 @@ +/* + * dfu.c -- DFU back-end routines + * + * Copyright (C) 2012 Samsung Electronics + * author: Lukasz Majewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +enum dfu_mmc_op { + DFU_OP_READ = 1, + DFU_OP_WRITE, +}; + +static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu, + void *buf, long *len) +{ + char cmd_buf[DFU_CMD_BUF_SIZE]; + + sprintf(cmd_buf, "mmc %s 0x%x %x %x", + op == DFU_OP_READ ? "read" : "write", + (unsigned int) buf, + dfu->data.mmc.lba_start, + dfu->data.mmc.lba_size); + + if (op == DFU_OP_READ) + *len = dfu->data.mmc.lba_blk_size * dfu->data.mmc.lba_size; + + debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); + return run_command(cmd_buf, 0); +} + +static inline int mmc_block_write(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_block_op(DFU_OP_WRITE, dfu, buf, len); +} + +static inline int mmc_block_read(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_block_op(DFU_OP_READ, dfu, buf, len); +} + +static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu, + void *buf, long *len) +{ + char cmd_buf[DFU_CMD_BUF_SIZE]; + char *str_env; + int ret; + + sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx", + op == DFU_OP_READ ? "load" : "write", + dfu->data.mmc.dev, dfu->data.mmc.part, + (unsigned int) buf, dfu->name, *len); + + debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); + + ret = run_command(cmd_buf, 0); + if (ret) { + puts("dfu: Read error!\n"); + return ret; + } + + if (dfu->layout != DFU_RAW_ADDR) { + str_env = getenv("filesize"); + if (str_env == NULL) { + puts("dfu: Wrong file size!\n"); + return -1; + } + *len = simple_strtoul(str_env, NULL, 16); + } + + return ret; +} + +static inline int mmc_file_write(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_file_op(DFU_OP_WRITE, dfu, buf, len); +} + +static inline int mmc_file_read(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_file_op(DFU_OP_READ, dfu, buf, len); +} + +int dfu_write_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) +{ + int ret = -1; + + switch (dfu->layout) { + case DFU_RAW_ADDR: + ret = mmc_block_write(dfu, buf, len); + break; + case DFU_FS_FAT: + ret = mmc_file_write(dfu, buf, len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } + + return ret; +} + +int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) +{ + int ret = -1; + + switch (dfu->layout) { + case DFU_RAW_ADDR: + ret = mmc_block_read(dfu, buf, len); + break; + case DFU_FS_FAT: + ret = mmc_file_read(dfu, buf, len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } + + return ret; +} + +int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) +{ + 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; + dfu->data.mmc.dev = simple_strtoul(s, &s, 10); + dfu->data.mmc.part = simple_strtoul(++s, &s, 10); + } else { + printf("%s: Memory layout (%s) not supported!\n", __func__, st); + } + + dfu->read_medium = dfu_read_medium_mmc; + dfu->write_medium = dfu_write_medium_mmc; + + return 0; +}