From patchwork Wed Aug 6 23:55:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Rae X-Patchwork-Id: 35009 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f200.google.com (mail-ob0-f200.google.com [209.85.214.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9367B21137 for ; Wed, 6 Aug 2014 23:54:54 +0000 (UTC) Received: by mail-ob0-f200.google.com with SMTP id nu7sf13208862obb.3 for ; Wed, 06 Aug 2014 16:54:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:content-type :content-transfer-encoding; bh=z8Cr7SJ/9hYlaYMRmrsPZZKyc0V2Pi1RyjC6PV/E7y4=; b=RxKFR49eV3MhtM/NDTc2YToHrScg89SnFOs4xCa+e+ge8nS3i2Yv51KpcohUGbAHR3 bcXBU6GVoBUY+IZEwy3E/FJyKBvh1uNkGEc7c6JQTjZd9f1wL2GoNhFGwG+Zb0a/GFNI OePqTid8B2aLVbV3PeNQ78SB+w9rqE77i2qjeZSon7gEdS4Qm8G+i6v6oSYlGU1ERlz6 7Rp6gszJxh6iVtDodMSimv4fKv5g1eHXbGAJf+UqzR/J9Jadp5TudhMzhX7YjPyMdy6F zfd4b+vo6hnq/Qexops0/WA8I1om1kioRiNWshEySF4qDQRFZVNZThFrm7uApdYV2AA0 NXUw== X-Gm-Message-State: ALoCoQkz/IkR0fvZsOW3gBEwNtY9VsXSWBrYBszKMzCKbpSYIZejlzMQFL3gOLFWkjxo2NbRhzmV X-Received: by 10.42.35.142 with SMTP id q14mr8028638icd.6.1407369294174; Wed, 06 Aug 2014 16:54:54 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.51.78 with SMTP id t72ls404408qga.87.gmail; Wed, 06 Aug 2014 16:54:54 -0700 (PDT) X-Received: by 10.52.137.2 with SMTP id qe2mr11450973vdb.11.1407369294076; Wed, 06 Aug 2014 16:54:54 -0700 (PDT) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by mx.google.com with ESMTPS id fy20si1103694vec.33.2014.08.06.16.54.54 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 06 Aug 2014 16:54:54 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.173 as permitted sender) client-ip=209.85.220.173; Received: by mail-vc0-f173.google.com with SMTP id hy10so5107135vcb.4 for ; Wed, 06 Aug 2014 16:54:54 -0700 (PDT) X-Received: by 10.52.227.72 with SMTP id ry8mr3435532vdc.64.1407369293952; Wed, 06 Aug 2014 16:54:53 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp67006vcb; Wed, 6 Aug 2014 16:54:53 -0700 (PDT) X-Received: by 10.180.20.40 with SMTP id k8mr55388763wie.38.1407369292857; Wed, 06 Aug 2014 16:54:52 -0700 (PDT) Received: from theia.denx.de (theia.denx.de. [85.214.87.163]) by mx.google.com with ESMTP id gh8si13337602wib.53.2014.08.06.16.54.52 for ; Wed, 06 Aug 2014 16:54:52 -0700 (PDT) Received-SPF: none (google.com: u-boot-bounces@lists.denx.de does not designate permitted sender hosts) client-ip=85.214.87.163; Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id AABE7A75D3; Thu, 7 Aug 2014 01:54:48 +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 vYjrwozk91lE; Thu, 7 Aug 2014 01:54:48 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4D3ABA7603; Thu, 7 Aug 2014 01:54:26 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9F569A7602 for ; Thu, 7 Aug 2014 01:54:24 +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 9TiGKODlOpzi for ; Thu, 7 Aug 2014 01:54:23 +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 mail-gw3-out.broadcom.com (mail-gw3-out.broadcom.com [216.31.210.64]) by theia.denx.de (Postfix) with ESMTP id 086E9A75D3 for ; Thu, 7 Aug 2014 01:54:09 +0200 (CEST) X-IronPort-AV: E=Sophos;i="5.01,814,1400050800"; d="scan'208";a="41559430" Received: from irvexchcas06.broadcom.com (HELO IRVEXCHCAS06.corp.ad.broadcom.com) ([10.9.208.53]) by mail-gw3-out.broadcom.com with ESMTP; 06 Aug 2014 17:06:21 -0700 Received: from IRVEXCHSMTP2.corp.ad.broadcom.com (10.9.207.52) by IRVEXCHCAS06.corp.ad.broadcom.com (10.9.208.53) with Microsoft SMTP Server (TLS) id 14.3.174.1; Wed, 6 Aug 2014 16:54:07 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP2.corp.ad.broadcom.com (10.9.207.52) with Microsoft SMTP Server id 14.3.174.1; Wed, 6 Aug 2014 16:54:07 -0700 Received: from mail.broadcom.com (lbrmn-vmlnx03.ric.broadcom.com [10.136.4.105]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id E5A029F9F7; Wed, 6 Aug 2014 16:54:05 -0700 (PDT) From: Steve Rae To: Rob Herring , Sebastian Siewior Date: Wed, 6 Aug 2014 16:55:13 -0700 Message-ID: <1407369313-13815-6-git-send-email-srae@broadcom.com> X-Mailer: git-send-email 1.8.5 In-Reply-To: <1407369313-13815-1-git-send-email-srae@broadcom.com> References: <1407369313-13815-1-git-send-email-srae@broadcom.com> MIME-Version: 1.0 Cc: Marek Vasut , Steve Rae , Pantelis Antoniou , u-boot@lists.denx.de, Tom Rini Subject: [U-Boot] [PATCH v4 5/5] usb/gadget: fastboot: implement sparse format X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: srae@broadcom.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.173 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 - add capability to "fastboot flash" with sparse format images Signed-off-by: Steve Rae --- I suspect that the "sparse image" handling (ie. the "while (remaining_chunks)" loop) has been implemented elsewhere -- I need help finding the original code to determine any licensing issues.... Thanks, Steve Changes in v4: - rearranged "sparse format" support in this patchset, in order to isolate... Changes in v3: None Changes in v2: None common/fb_mmc.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/common/fb_mmc.c b/common/fb_mmc.c index f42a115..306c102 100644 --- a/common/fb_mmc.c +++ b/common/fb_mmc.c @@ -1,5 +1,6 @@ /* - * Copyright 2014 Broadcom Corporation. + * Copyright TODO + * Portions Copyright 2014 Broadcom Corporation. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -7,6 +8,7 @@ #include #include #include +#include /* The 64 defined bytes plus \0 */ #define RESPONSE_LEN (64 + 1) @@ -19,6 +21,108 @@ static void fastboot_resp(const char *s) response_str[RESPONSE_LEN - 1] = '\0'; } +static int is_sparse_image(void *buf) +{ + sparse_header_t *s_header = (sparse_header_t *)buf; + + if ((le32_to_cpu(s_header->magic) == SPARSE_HEADER_MAGIC) && + (le16_to_cpu(s_header->major_version) == 1)) + return 1; + + return 0; +} + +static void write_sparse_image(block_dev_desc_t *dev_desc, + disk_partition_t *info, const char *part_name, + void *buffer, unsigned int download_bytes) +{ + lbaint_t blk; + lbaint_t blkcnt; + lbaint_t blks; + sparse_header_t *s_header = (sparse_header_t *)buffer; + chunk_header_t *c_header; + void *buf; + uint32_t blk_sz; + uint32_t remaining_chunks; + uint32_t bytes_written = 0; + + blk_sz = le32_to_cpu(s_header->blk_sz); + + /* verify s_header->blk_sz is exact multiple of info->blksz */ + if (blk_sz != (blk_sz & ~(info->blksz - 1))) { + printf("%s: Sparse image block size issue [%u]\n", + __func__, blk_sz); + fastboot_resp("FAILsparse image block size issue"); + return; + } + + if ((le32_to_cpu(s_header->total_blks) * blk_sz) > + (info->size * info->blksz)) { + printf("%s: Sparse image is too large for the partition\n", + __func__); + fastboot_resp("FAILsparse image is too large"); + return; + } + + puts("Flashing Sparse Image\n"); + + remaining_chunks = le32_to_cpu(s_header->total_chunks); + c_header = (chunk_header_t *)(buffer + + le16_to_cpu(s_header->file_hdr_sz)); + blk = info->start; + while (remaining_chunks) { + blkcnt = + (le32_to_cpu(c_header->chunk_sz) * blk_sz) / info->blksz; + + switch (le16_to_cpu(c_header->chunk_type)) { + case CHUNK_TYPE_RAW: + buf = (void *)c_header + + le16_to_cpu(s_header->chunk_hdr_sz); + + if (blk + blkcnt > info->start + info->size) { + printf( + "%s: Request would exceed partition size!\n", + __func__); + fastboot_resp( + "FAILRequest would exceed partition size!"); + return; + } + + blks = dev_desc->block_write(dev_desc->dev, blk, blkcnt, + buf); + if (blks != blkcnt) { + printf("%s: Write failed " LBAFU "\n", + __func__, blks); + fastboot_resp("FAILwrite failure"); + return; + } + + bytes_written += blkcnt * info->blksz; + break; + + case CHUNK_TYPE_FILL: + case CHUNK_TYPE_DONT_CARE: + case CHUNK_TYPE_CRC32: + /* do nothing */ + break; + + default: + /* error */ + printf("%s: Unknown chunk type\n", __func__); + fastboot_resp("FAILunknown chunk type in sparse image"); + return; + } + + blk += blkcnt; + c_header = (chunk_header_t *)((void *)c_header + + le32_to_cpu(c_header->total_sz)); + remaining_chunks--; + } + + printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name); + fastboot_resp("OKAY"); +} + static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info, const char *part_name, void *buffer, unsigned int download_bytes) @@ -77,6 +181,11 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer, return; } - write_raw_image(dev_desc, &info, cmd, download_buffer, - download_bytes); + if (is_sparse_image(download_buffer)) { + write_sparse_image(dev_desc, &info, cmd, download_buffer, + download_bytes); + } else { + write_raw_image(dev_desc, &info, cmd, download_buffer, + download_bytes); + } }