From patchwork Wed Mar 27 10:34:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Shivamurthy Shastri (sshivamurthy)" X-Patchwork-Id: 10873223 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E54C6186E for ; Wed, 27 Mar 2019 10:34:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CFC5D28715 for ; Wed, 27 Mar 2019 10:34:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C425F288A9; Wed, 27 Mar 2019 10:34:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06FFA28715 for ; Wed, 27 Mar 2019 10:34:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726241AbfC0Ke1 (ORCPT ); Wed, 27 Mar 2019 06:34:27 -0400 Received: from mailout.micron.com ([137.201.242.129]:37278 "EHLO mailout.micron.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727936AbfC0Ke1 (ORCPT ); Wed, 27 Mar 2019 06:34:27 -0400 Received: from mail.micron.com (bowex17f.micron.com [137.201.21.111]) by mailout.micron.com (8.14.4/8.14.6) with ESMTP id x2RAYIa9028739; Wed, 27 Mar 2019 04:34:18 -0600 Received: from BOWEX36H.micron.com (137.201.84.179) by BOWEX17F.micron.com (137.201.21.111) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 27 Mar 2019 04:34:17 -0600 Received: from NAM03-BY2-obe.outbound.protection.outlook.com (137.201.84.23) by BOWEX36H.micron.com (137.201.84.179) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Wed, 27 Mar 2019 04:34:17 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=micron.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zLBFnmNv03rCQ0LjCdAWA8z9Rvfo0dGpf63+a4jGyN4=; b=SZxON6quSq6CUek2jzdEPpT3zqEf+AogN+OpmWbnD8a9XTGOTP01Z9jaxQRTIzX1iXnm4+yxdOvlbIKerXBYJ1LaIAK42I665wF3qByuIHSwl8+VVzGm/LIjwzWokARhqrpSEW1wH2F3Wc72Cf2B6BmCwWz69JS8dDoJL7hoSuU= Received: from MN2PR08MB5951.namprd08.prod.outlook.com (20.179.85.220) by MN2PR08MB5790.namprd08.prod.outlook.com (20.179.86.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1750.16; Wed, 27 Mar 2019 10:34:14 +0000 Received: from MN2PR08MB5951.namprd08.prod.outlook.com ([fe80::c561:284f:9768:a4af]) by MN2PR08MB5951.namprd08.prod.outlook.com ([fe80::c561:284f:9768:a4af%7]) with mapi id 15.20.1730.019; Wed, 27 Mar 2019 10:34:14 +0000 From: "Shivamurthy Shastri (sshivamurthy)" To: Yaniv Agman , Avi Shchislowski , Chris Ball , "linux-mmc@vger.kernel.org" Subject: [PATCH] mmc-utils: enable CMD25 as optional for FFU Thread-Topic: [PATCH] mmc-utils: enable CMD25 as optional for FFU Thread-Index: AdTkgfFzccQpUW3JRRGHIpNJYXGs/w== Date: Wed, 27 Mar 2019 10:34:14 +0000 Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=sshivamurthy@micron.com; x-originating-ip: [165.225.81.69] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: d84c2931-fdb4-4efd-722f-08d6b29fc250 x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(7168020)(4627221)(201703031133081)(201702281549075)(8990200)(5600127)(711020)(4605104)(2017052603328)(7153060)(7193020);SRVR:MN2PR08MB5790; x-ms-traffictypediagnostic: MN2PR08MB5790:|MN2PR08MB5790: x-microsoft-antispam-prvs: x-forefront-prvs: 0989A7979C x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(346002)(39860400002)(136003)(366004)(396003)(376002)(189003)(199004)(186003)(52536014)(25786009)(26005)(256004)(316002)(6436002)(71200400001)(5660300002)(74316002)(66066001)(106356001)(105586002)(71190400001)(14444005)(86362001)(33656002)(1691005)(102836004)(478600001)(305945005)(7736002)(2501003)(14454004)(55016002)(476003)(99286004)(55236004)(486006)(9686003)(110136005)(6116002)(3846002)(8676002)(81166006)(81156014)(68736007)(7696005)(6506007)(97736004)(2906002)(8936002)(53936002);DIR:OUT;SFP:1101;SCL:1;SRVR:MN2PR08MB5790;H:MN2PR08MB5951.namprd08.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: micron.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: UbT4FTCWy3vlkzZBDbCXLb+jYoqj0wyu7bRtSAI0my5/si25AdGZWsl2Xbw3VQdU9uc7z9NQF215nivDLXhlfGXMYaL3NOb1HFraogY0zYfODHkaXPPUvgNSbdzQJaRkTLl316aJban5HWOSnspgXZyACINyVG6Y5wq/wz8UEIADp2a/djzQx2eh6E40P2qUhPR+EdD5jeqwuRkJjU6L97UuRxcMT+Db8p+6I13n+2lxh6YeYkqCmm3LBZsEZTHiv/zxosQTa5xR3Wln8yfpmPYcOR/1oyLHD09MHSsKu3McpQT37XP7LVLoCzdx2jZ+AaGnwP0BHMC+aD+tjJOKSPTItdk0+OAgIjMS96J7QqPwvmE8VZ6Jd5wFDrBNOVYPGPUG/pj5qMcTva9RCOivPHBAHsyWEJ7G0oUClZoNCy0= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: d84c2931-fdb4-4efd-722f-08d6b29fc250 X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Mar 2019 10:34:14.8369 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f38a5ecd-2813-4862-b11b-ac1d563c806f X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR08MB5790 X-OriginatorOrg: micron.com X-TM-AS-Product-Ver: SMEX-12.0.0.1782-8.200.1013-24514.005 X-TM-AS-Result: No--1.769900-0.000000-31 X-TM-AS-MatchedID: 702358-705102-703720-700756-708712-700016-188019-706290-7 07451-700324-706249-702143-702762-703523-700648-704473-106640-701017-703529 -700398-847298-702898-700264-700008-705450-137717-703712-702609-707654-7065 92-704930-148004-148007-148020-148050-42000-42003-63 X-TM-AS-User-Approved-Sender: Yes X-TM-AS-User-Blocked-Sender: No X-MT-CheckInternalSenderRule: True X-Scanned-By: MIMEDefang 2.78 on 137.201.130.65 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP As per specification, the host can use either CMD24 or CMD25 for the FFU. CMD25 is better option as it can program the firmware image in one go. CMD25 is enabled as optional and user can use this by giving optional parameter '-c'. Example: mmc ffu -c Signed-off-by: Shivamurthy Shastri --- mmc.c | 5 +- mmc.h | 1 + mmc_cmds.c | 140 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 100 insertions(+), 46 deletions(-) diff --git a/mmc.c b/mmc.c index 50c9c9e..4e850ed 100644 --- a/mmc.c +++ b/mmc.c @@ -211,8 +211,9 @@ static struct Command commands[] = { NULL }, { do_ffu, -2, - "ffu", " \n" - "Run Field Firmware Update with on .\n", + "ffu", "[-c] \n" + "Run Field Firmware Update with on .\n" + "'-c' is required to select CMD25 for FFU.\n", NULL }, { 0, 0, 0, 0 } diff --git a/mmc.h b/mmc.h index 285c1f1..9bfdd8a 100644 --- a/mmc.h +++ b/mmc.h @@ -25,6 +25,7 @@ /* From kernel linux/mmc/mmc.h */ #define MMC_SWITCH 6 /* ac [31:0] See below R1b */ #define MMC_SEND_EXT_CSD 8 /* adtc R1 */ +#define MMC_STOP_TRANSMISSION 12 /* ac R1b */ #define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ #define R1_SWITCH_ERROR (1 << 7) /* sx, c */ #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ diff --git a/mmc_cmds.c b/mmc_cmds.c index 19a9da1..0da6ad8 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -2403,6 +2403,62 @@ int do_cache_dis(int nargs, char **argv) return do_cache_ctrl(0, nargs, argv); } +static void prepare_ffu_multi_cmd(struct mmc_ioc_multi_cmd *multi_cmd, + int enable_cmd25, __u32 arg, __u32 sect_size, + __u32 blocks, __u8 *buf) +{ + /* prepare multi_cmd to be sent */ + multi_cmd->num_of_cmds = enable_cmd25 ? 4 : 3; + + /* put device into ffu mode */ + multi_cmd->cmds[0].opcode = MMC_SWITCH; + multi_cmd->cmds[0].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_MODE_CONFIG << 16) | + (EXT_CSD_FFU_MODE << 8) | + EXT_CSD_CMD_SET_NORMAL; + multi_cmd->cmds[0].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + multi_cmd->cmds[0].write_flag = 1; + + /* send image chunk */ + multi_cmd->cmds[1].opcode = enable_cmd25 ? MMC_WRITE_MULTIPLE_BLOCK + : MMC_WRITE_BLOCK; + multi_cmd->cmds[1].blksz = sect_size; + multi_cmd->cmds[1].blocks = blocks; + multi_cmd->cmds[1].arg = arg; + multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + multi_cmd->cmds[1].write_flag = 1; + mmc_ioc_cmd_set_data(multi_cmd->cmds[1], buf); + + if (enable_cmd25) { + /* stop the device after transmission */ + multi_cmd->cmds[2].opcode = MMC_STOP_TRANSMISSION; + multi_cmd->cmds[2].arg = 0; + multi_cmd->cmds[2].flags = MMC_RSP_SPI_R1B | + MMC_RSP_R1B | MMC_CMD_AC; + multi_cmd->cmds[2].write_flag = 1; + + /* return device into normal mode */ + multi_cmd->cmds[3].opcode = MMC_SWITCH; + multi_cmd->cmds[3].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_MODE_CONFIG << 16) | + (EXT_CSD_NORMAL_MODE << 8) | + EXT_CSD_CMD_SET_NORMAL; + multi_cmd->cmds[3].flags = MMC_RSP_SPI_R1B | + MMC_RSP_R1B | MMC_CMD_AC; + multi_cmd->cmds[3].write_flag = 1; + } else { + /* return device into normal mode */ + multi_cmd->cmds[2].opcode = MMC_SWITCH; + multi_cmd->cmds[2].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_MODE_CONFIG << 16) | + (EXT_CSD_NORMAL_MODE << 8) | + EXT_CSD_CMD_SET_NORMAL; + multi_cmd->cmds[2].flags = MMC_RSP_SPI_R1B | + MMC_RSP_R1B | MMC_CMD_AC; + multi_cmd->cmds[2].write_flag = 1; + } +} + int do_ffu(int nargs, char **argv) { #ifndef MMC_IOC_MULTI_CMD @@ -2414,37 +2470,41 @@ int do_ffu(int nargs, char **argv) int sect_done = 0, retry = 3, ret = -EINVAL; unsigned int sect_size; __u8 ext_csd[512]; - __u8 *buf; + __u8 *buf = NULL; __u32 arg; off_t fw_size; ssize_t chunk_size; char *device; - struct mmc_ioc_multi_cmd *multi_cmd; + struct mmc_ioc_multi_cmd *multi_cmd = NULL; + int c = 0, enable_cmd25 = 0; + __u32 blocks = 1; - if (nargs != 3) { - fprintf(stderr, "Usage: ffu \n"); + if (nargs < 3) { + fprintf(stderr, "Usage: ffu [-c] \n"); exit(1); } - device = argv[2]; + device = argv[nargs - 1]; dev_fd = open(device, O_RDWR); if (dev_fd < 0) { perror("device open failed"); exit(1); } - img_fd = open(argv[1], O_RDONLY); + img_fd = open(argv[nargs - 2], O_RDONLY); if (img_fd < 0) { perror("image open failed"); close(dev_fd); exit(1); } - buf = malloc(512); - multi_cmd = calloc(1, sizeof(struct mmc_ioc_multi_cmd) + - 3 * sizeof(struct mmc_ioc_cmd)); - if (!buf || !multi_cmd) { - perror("failed to allocate memory"); - goto out; + while ((c = getopt(nargs, argv, "c")) != -1) { + switch (c) { + case 'c': + enable_cmd25 = 1; + break; + default: + break; + } } ret = read_extcsd(dev_fd, ext_csd); @@ -2471,58 +2531,47 @@ int do_ffu(int nargs, char **argv) } fw_size = lseek(img_fd, 0, SEEK_END); - if (fw_size == 0) { fprintf(stderr, "Firmware image is empty"); goto out; } + /* allocate maximum required */ + buf = malloc(fw_size); + multi_cmd = calloc(1, sizeof(struct mmc_ioc_multi_cmd) + + 4 * sizeof(struct mmc_ioc_cmd)); + if (!buf || !multi_cmd) { + perror("failed to allocate memory"); + goto out; + } + sect_size = (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 0) ? 512 : 4096; if (fw_size % sect_size) { fprintf(stderr, "Firmware data size (%jd) is not aligned!\n", (intmax_t)fw_size); goto out; } + /* calculate required fw blocks for CMD25 */ + if (enable_cmd25) + blocks = fw_size / sect_size; + /* set CMD ARG */ arg = ext_csd[EXT_CSD_FFU_ARG_0] | ext_csd[EXT_CSD_FFU_ARG_1] << 8 | ext_csd[EXT_CSD_FFU_ARG_2] << 16 | ext_csd[EXT_CSD_FFU_ARG_3] << 24; - /* prepare multi_cmd to be sent */ - multi_cmd->num_of_cmds = 3; - - /* put device into ffu mode */ - multi_cmd->cmds[0].opcode = MMC_SWITCH; - multi_cmd->cmds[0].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (EXT_CSD_MODE_CONFIG << 16) | - (EXT_CSD_FFU_MODE << 8) | - EXT_CSD_CMD_SET_NORMAL; - multi_cmd->cmds[0].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - multi_cmd->cmds[0].write_flag = 1; - - /* send image chunk */ - multi_cmd->cmds[1].opcode = MMC_WRITE_BLOCK; - multi_cmd->cmds[1].blksz = sect_size; - multi_cmd->cmds[1].blocks = 1; - multi_cmd->cmds[1].arg = arg; - multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - multi_cmd->cmds[1].write_flag = 1; - mmc_ioc_cmd_set_data(multi_cmd->cmds[1], buf); - - /* return device into normal mode */ - multi_cmd->cmds[2].opcode = MMC_SWITCH; - multi_cmd->cmds[2].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (EXT_CSD_MODE_CONFIG << 16) | - (EXT_CSD_NORMAL_MODE << 8) | - EXT_CSD_CMD_SET_NORMAL; - multi_cmd->cmds[2].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - multi_cmd->cmds[2].write_flag = 1; + /* prepare multi_cmd for FFU based on cmd to be used */ + prepare_ffu_multi_cmd(multi_cmd, enable_cmd25, + arg, sect_size, blocks, buf); do_retry: /* read firmware chunk */ lseek(img_fd, 0, SEEK_SET); - chunk_size = read(img_fd, buf, 512); + if (enable_cmd25) + chunk_size = read(img_fd, buf, fw_size); + else + chunk_size = read(img_fd, buf, 512); while (chunk_size > 0) { /* send ioctl with multi-cmd */ @@ -2531,7 +2580,10 @@ do_retry: if (ret) { perror("Multi-cmd ioctl"); /* In case multi-cmd ioctl failed before exiting from ffu mode */ - ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[2]); + if (enable_cmd25) + ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[3]); + else + ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[2]); goto out; }