From patchwork Fri Jan 30 11:54:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dileep Katta X-Patchwork-Id: 44040 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f197.google.com (mail-lb0-f197.google.com [209.85.217.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4F36B2410D for ; Fri, 30 Jan 2015 11:55:17 +0000 (UTC) Received: by mail-lb0-f197.google.com with SMTP id b6sf598450lbj.0 for ; Fri, 30 Jan 2015 03:55:14 -0800 (PST) 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:cc:subject :precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=jKOz4toCoy14fEnJGjh5wbAtaimMfghwvkw9OH5cErM=; b=ENe6f4xykpVAd8rxSwyMhrEYLQRlp0XyHjKYnLXGTD8M36Mfks81satI8MT/a/WTyF tJ7YmqDS9WTcTw6p5oWBAYk+3SmBwGKG+BDo8er4l/KhO+E5s/B0Ep6RMcceneTzc9Yy JJB3GN21AJEMMcpC+NcpGveJ4RrYN2+Fj5A8wJgC1eaLN8BTBSxu3rdHyZw4AQDmnenY QfjkG0mLv/b3EbXPB2s7Lrp/Mq/aCXHmkv8cDDytptUPXlLDKxl6NFRIkcdhRbWTdvyM 8ktt3agN96K5TZxVwDj3K324yfUe4gxb0eM3yB/CKGwhaNqBYHMyVh066pbYpGYcU3Yg gTWQ== X-Gm-Message-State: ALoCoQmrEBYOVJD54hXrgMTs8Zdp4fY14kfwIF8xddISQKzRgDkrQAXrk9LRxnPvApRQzP0w3UUz X-Received: by 10.152.37.71 with SMTP id w7mr766317laj.5.1422618913741; Fri, 30 Jan 2015 03:55:13 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.234.5 with SMTP id ua5ls348549lac.68.gmail; Fri, 30 Jan 2015 03:55:13 -0800 (PST) X-Received: by 10.112.67.41 with SMTP id k9mr6008907lbt.35.1422618913576; Fri, 30 Jan 2015 03:55:13 -0800 (PST) Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com. [209.85.217.172]) by mx.google.com with ESMTPS id l3si6792525lag.2.2015.01.30.03.55.13 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 30 Jan 2015 03:55:13 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 as permitted sender) client-ip=209.85.217.172; Received: by mail-lb0-f172.google.com with SMTP id l4so36011003lbv.3 for ; Fri, 30 Jan 2015 03:55:13 -0800 (PST) X-Received: by 10.152.23.195 with SMTP id o3mr6078142laf.70.1422618913018; Fri, 30 Jan 2015 03:55:13 -0800 (PST) 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.112.35.133 with SMTP id h5csp257048lbj; Fri, 30 Jan 2015 03:55:11 -0800 (PST) X-Received: by 10.180.160.194 with SMTP id xm2mr3982537wib.77.1422618911664; Fri, 30 Jan 2015 03:55:11 -0800 (PST) Received: from theia.denx.de (theia.denx.de. [85.214.87.163]) by mx.google.com with ESMTP id f4si20324316wjy.26.2015.01.30.03.55.10; Fri, 30 Jan 2015 03:55:11 -0800 (PST) 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 904144A032; Fri, 30 Jan 2015 12:55:10 +0100 (CET) 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 yXbbl29fOIgv; Fri, 30 Jan 2015 12:55:10 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1B2374A02C; Fri, 30 Jan 2015 12:55:10 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 68BAE4A02E for ; Fri, 30 Jan 2015 12:55:05 +0100 (CET) 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 6_z4Hy1oHV1g for ; Fri, 30 Jan 2015 12:55:05 +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 mail-we0-f181.google.com (mail-we0-f181.google.com [74.125.82.181]) by theia.denx.de (Postfix) with ESMTPS id 310084A02A for ; Fri, 30 Jan 2015 12:55:02 +0100 (CET) Received: by mail-we0-f181.google.com with SMTP id k48so26720683wev.12 for ; Fri, 30 Jan 2015 03:55:02 -0800 (PST) X-Received: by 10.194.103.228 with SMTP id fz4mr11363422wjb.82.1422618901966; Fri, 30 Jan 2015 03:55:01 -0800 (PST) Received: from T440p.hotspot.s-bit.nl ([109.236.130.7]) by mx.google.com with ESMTPSA id n3sm14594089wja.36.2015.01.30.03.55.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 30 Jan 2015 03:55:01 -0800 (PST) From: Dileep Katta To: u-boot@lists.denx.de, srae@broadcom.com, rob.herring@linaro.org, trini@ti.com, wd@denx.de Date: Fri, 30 Jan 2015 12:54:51 +0100 Message-Id: <1422618891-15613-1-git-send-email-dileep.katta@linaro.org> X-Mailer: git-send-email 1.8.3.2 Cc: Dileep Katta Subject: [U-Boot] [PATCH v1 1/1] fastboot: oem format command implementation X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: dileep.katta@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 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 This is the Modified version of http://patchwork.ozlabs.org/patch/388084/ - As flash support is already in mainline, it is removed - 'oem' command support is present - 'oem format' command is implemented - Handled review comments of the original patch Signed-off-by: Dileep Katta --- common/cmd_fastboot.c | 4 + common/cmd_mmc.c | 2 +- disk/Makefile | 1 + disk/part_fastboot.c | 363 ++++++++++++++++++++++++++++++++++++++++ doc/README.android-fastboot | 5 +- drivers/usb/gadget/f_fastboot.c | 85 ++++++++++ include/usb/fastboot.h | 108 ++++++++++++ 7 files changed, 564 insertions(+), 4 deletions(-) create mode 100644 disk/part_fastboot.c create mode 100644 include/usb/fastboot.h diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c index b72f4f3..efdf461 100644 --- a/common/cmd_fastboot.c +++ b/common/cmd_fastboot.c @@ -10,12 +10,16 @@ #include #include #include +#include static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { int ret; g_dnl_clear_detach(); +#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV + board_partition_init(); +#endif ret = g_dnl_register("usb_dnl_fastboot"); if (ret) return ret; diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 4e28c9d..0ce747b 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -809,7 +809,7 @@ static cmd_tbl_t cmd_mmc[] = { U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""), }; -static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { cmd_tbl_t *cp; diff --git a/disk/Makefile b/disk/Makefile index 6970cec..4969656 100644 --- a/disk/Makefile +++ b/disk/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_DOS_PARTITION) += part_dos.o obj-$(CONFIG_ISO_PARTITION) += part_iso.o obj-$(CONFIG_AMIGA_PARTITION) += part_amiga.o obj-$(CONFIG_EFI_PARTITION) += part_efi.o +obj-$(CONFIG_FASTBOOT_FLASH_MMC_DEV) +=part_fastboot.o diff --git a/disk/part_fastboot.c b/disk/part_fastboot.c new file mode 100644 index 0000000..adf37af --- /dev/null +++ b/disk/part_fastboot.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2013 Texas Instruments + * + * Author : Pankaj Bharadiya + * + * Tom Rix and Sitara 2011 u-boot by + * Mohammed Afzal M A + * + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Copyright 2014 Linaro, Ltd. + * Dileep Katta + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EFI_VERSION 0x00010000 +#define EFI_ENTRIES 128 +#define EFI_NAMELEN 36 + +struct partition_emmc { + const char *name; + unsigned size_kb; +}; + +/* eMMC partition layout (All sizes are in kB) + * Modify the below partition table to change the GPT configuration. + * The entry for each partition can be modified as per the requirement. + */ +static struct partition_emmc partitions[] = { + { "-", 128 }, /* Master Boot Record and GUID Partition Table */ + { "spl", 128 }, /* First stage bootloader */ + { "bootloader", 512 }, /* Second stage bootloader */ + { "misc", 128 }, /* Rserved for internal purpose */ + { "-", 128 }, /* Reserved */ + { "recovery", 8*1024 }, /* Recovery partition */ + { "boot", 8*1024 }, /* Partition contains kernel + ramdisk images */ + { "system", 256*1024 }, /* Android file system */ + { "cache", 256*1024 }, /* Store Application Cache */ + { "userdata", 256*1024 }, /* User data */ + { "media", 0 }, /* Media files */ + { 0, 0 }, +}; + + +static const u8 partition_type[16] = { + 0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44, + 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7, +}; + +static const u8 random_uuid[16] = { + 0xff, 0x1f, 0xf2, 0xf9, 0xd4, 0xa8, 0x0e, 0x5f, + 0x97, 0x46, 0x59, 0x48, 0x69, 0xae, 0xc3, 0x4e, +}; + +struct efi_entry { + u8 type_uuid[16]; + u8 uniq_uuid[16]; + u64 first_lba; + u64 last_lba; + u64 attr; + u16 name[EFI_NAMELEN]; +}; + +struct efi_header { + u8 magic[8]; + + u32 version; + u32 header_sz; + + u32 crc32; + u32 reserved; + + u64 header_lba; + u64 backup_lba; + u64 first_lba; + u64 last_lba; + + u8 volume_uuid[16]; + + u64 entries_lba; + + u32 entries_count; + u32 entries_size; + u32 entries_crc32; +} __packed; + +struct ptable { + u8 mbr[512]; + union { + struct efi_header header; + u8 block[512]; + }; + struct efi_entry entry[EFI_ENTRIES]; +}; + +static void init_mbr(u8 *mbr, u32 blocks) +{ + mbr[0x1be] = 0x00; /* nonbootable */ + mbr[0x1bf] = 0xFF; /* bogus CHS */ + mbr[0x1c0] = 0xFF; + mbr[0x1c1] = 0xFF; + + mbr[0x1c2] = 0xEE; /* GPT partition */ + mbr[0x1c3] = 0xFF; /* bogus CHS */ + mbr[0x1c4] = 0xFF; + mbr[0x1c5] = 0xFF; + + mbr[0x1c6] = 0x01; /* start */ + mbr[0x1c7] = 0x00; + mbr[0x1c8] = 0x00; + mbr[0x1c9] = 0x00; + + memcpy(mbr + 0x1ca, &blocks, sizeof(u32)); + + mbr[0x1fe] = 0x55; + mbr[0x1ff] = 0xaa; +} + + +static void start_ptbl(struct ptable *ptbl, unsigned blocks) +{ + struct efi_header *hdr = &ptbl->header; + + memset(ptbl, 0, sizeof(*ptbl)); + + init_mbr(ptbl->mbr, blocks - 1); + + memcpy(hdr->magic, "EFI PART", 8); + hdr->version = EFI_VERSION; + hdr->header_sz = sizeof(struct efi_header); + hdr->header_lba = 1; + hdr->backup_lba = blocks - 1; + hdr->first_lba = 34; + hdr->last_lba = blocks - 1; + memcpy(hdr->volume_uuid, random_uuid, 16); + hdr->entries_lba = 2; + hdr->entries_count = EFI_ENTRIES; + hdr->entries_size = sizeof(struct efi_entry); +} + +static void end_ptbl(struct ptable *ptbl) +{ + struct efi_header *hdr = &ptbl->header; + u32 n; + + /* Get the initial checksum by passing buf as NULL */ + n = crc32(0, NULL, 0); + n = crc32(n, (void *)ptbl->entry, sizeof(ptbl->entry)); + hdr->entries_crc32 = n; + + n = crc32(0, (void *)&ptbl->header, sizeof(ptbl->header)); + hdr->crc32 = n; +} + +int add_ptn(struct ptable *ptbl, u64 first, u64 last, const char *name) +{ + struct efi_header *hdr = &ptbl->header; + struct efi_entry *entry = ptbl->entry; + unsigned n; + + if (first < 34) { + printf("partition '%s' overlaps partition table\n", name); + return -1; + } + + if (last > hdr->last_lba) { + printf("partition '%s' does not fit\n", name); + return -1; + } + for (n = 0; n < EFI_ENTRIES; n++, entry++) { + if (entry->last_lba) + continue; + memcpy(entry->type_uuid, partition_type, 16); + memcpy(entry->uniq_uuid, random_uuid, 16); + entry->uniq_uuid[0] = n; + entry->first_lba = first; + entry->last_lba = last; + for (n = 0; (n < EFI_NAMELEN) && *name; n++) + entry->name[n] = *name++; + return 0; + } + printf("out of partition table entries\n"); + return -1; +} + +void import_efi_partition(struct efi_entry *entry) +{ + struct fastboot_ptentry e; + int n; + if (memcmp(entry->type_uuid, partition_type, sizeof(partition_type))) + return; + for (n = 0; n < (sizeof(e.name)-1); n++) + e.name[n] = entry->name[n]; + e.name[n] = 0; + e.start = entry->first_lba; + e.length = (entry->last_lba - entry->first_lba + 1) * 512; + e.flags = 0; + + if (!strcmp(e.name, "environment")) + e.flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_ENV; + fastboot_flash_add_ptn(&e); + + if (e.length > 0x100000) + printf("%8d %7dM %s\n", e.start, e.length/0x100000, e.name); + else + printf("%8d %7dK %s\n", e.start, e.length/0x400, e.name); +} + +static int load_ptbl(void) +{ + u64 ptbl_sectors = 0; + int i = 0, r = 0; + + struct ptable gpt[sizeof(struct ptable)]; + struct mmc *mmc = NULL; + + mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV); + if (mmc == NULL) { + printf("No MMC in slot 1\n"); + return -1; + } + + int gpt_size = sizeof(struct ptable); + + ptbl_sectors = (u64)(gpt_size / MMCSD_SECTOR_SIZE); + + r = mmc->block_dev.block_read(1, 0, ptbl_sectors, (void *)gpt); + if (r == -1) { + printf("error reading GPT\n"); + goto fail; + } + + if (memcmp(gpt->header.magic, "EFI PART", 8)) { + printf("efi partition table not found\n"); + r = -1; + goto fail; + } + + for (i = 0; i < EFI_ENTRIES; i++) + import_efi_partition(&gpt->entry[i]); + +fail: + return r; +} + +int board_mmc_fbtptn_init(void) +{ + char *mmc_init[2] = {"mmc", "rescan",}; + char dev[2]; + char *mmc_dev[3] = {"mmc", "dev", dev}; + unsigned fb_mmcdev = CONFIG_FASTBOOT_FLASH_MMC_DEV; + + sprintf(dev, "0x%x", fb_mmcdev); + + if (do_mmcops(NULL, 0, 3, mmc_dev)) { + printf("MMC DEV: %d selection FAILED!\n", fb_mmcdev); + return -1; + } + + if (do_mmcops(NULL, 0, 2, mmc_init)) { + printf("FAIL:Init of MMC card\n"); + return -1; + } + + return load_ptbl(); +} + + +static struct ptable the_ptable; + +int do_format(void) +{ + struct ptable *ptbl = &the_ptable; + struct mmc *mmc = NULL; + unsigned blocks; + unsigned next; + unsigned sz; + int n; + unsigned fb_mmcdev = CONFIG_FASTBOOT_FLASH_MMC_DEV; + + /* get mmc info */ + mmc = find_mmc_device(fb_mmcdev); + if (mmc == 0) { + printf("no mmc device at slot %d", fb_mmcdev); + return -1; + } + + mmc->has_init = 0; + if (mmc_init(mmc)) { + printf("\n mmc init FAILED"); + return -1; + } + + printf("\nmmc capacity is: %llu", mmc->capacity); + printf("\nmmc: number of blocks:0x%lx", mmc->block_dev.lba); + printf("\nmmc: block size:0x%lx", mmc->block_dev.blksz); + + blocks = mmc->block_dev.lba; + + start_ptbl(ptbl, blocks); + n = 0; + next = 0; + for (n = 0, next = 0; partitions[n].name; n++) { + /* below line change size from KB to no of blocks */ + sz = partitions[n].size_kb*2; + if (!strcmp(partitions[n].name, "-")) { + next += sz; + continue; + } + if (sz == 0) + sz = blocks - next; + if (add_ptn(ptbl, next, next + sz - 1, partitions[n].name)) + return -1; + next += sz; + } + end_ptbl(ptbl); + + fastboot_flash_reset_ptn(); + + char *mmc_write[5] = {"mmc", "write", NULL, NULL, NULL}; + char source[32], dest[32], length[32]; + + char dev[2]; + char *mmc_dev[3] = {"mmc", "dev", NULL}; + + mmc_dev[2] = dev; + sprintf(dev, "0x%x", fb_mmcdev); + + if (do_mmcops(NULL, 0, 3, mmc_dev)) { + printf("MMC DEV: %d selection FAILED!\n", fb_mmcdev); + return -1; + } + + mmc_write[2] = source; + mmc_write[3] = dest; + mmc_write[4] = length; + + sprintf(source, "%p", (void *)ptbl); + sprintf(dest, "0x%x", 0x00); + sprintf(length, "0x%x", (sizeof(struct ptable)/512)+1); + + if (do_mmcops(NULL, 0, 5, mmc_write)) { + printf("mbr write FAILED!\n"); + return -1; + } + + printf("\nnew partition table:\n"); + load_ptbl(); + + return 0; +} diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot index 1677609..77cce8e 100644 --- a/doc/README.android-fastboot +++ b/doc/README.android-fastboot @@ -6,9 +6,8 @@ Overview The protocol that is used over USB is described in README.android-fastboot-protocol in same directory. -The current implementation does not yet support the erase command or the -"oem format" command, and there is minimal support for the flash command; -it only supports eMMC devices. +The current implementation does not yet support the erase command, and +there is minimal support for the flash command;it only supports eMMC devices. Client installation =================== diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 310175a..76ccc55 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -23,6 +23,8 @@ #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV #include #endif +#include +#include #define FASTBOOT_VERSION "0.4" @@ -39,6 +41,12 @@ #define EP_BUFFER_SIZE 4096 +/* To support the Android-style naming of flash */ +#define MAX_PTN 16 +static struct fastboot_ptentry ptable[MAX_PTN]; +static unsigned int pcount; +/* static int static_pcount = -1; */ + struct f_fastboot { struct usb_function usb_function; @@ -123,6 +131,33 @@ static struct usb_gadget_strings *fastboot_strings[] = { static void rx_handler_command(struct usb_ep *ep, struct usb_request *req); +/* Android style flash utilties */ +void fastboot_flash_reset_ptn(void) +{ +#ifdef DEBUG + printf("fastboot flash reset partition..!!"); +#endif + pcount = 0; +} + +void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn) +{ + if (pcount < MAX_PTN) { + memcpy((ptable + pcount), ptn, sizeof(*ptn)); + pcount++; + } +} + +void fastboot_flash_dump_ptn(void) +{ + unsigned int n; + for (n = 0; n < pcount; n++) { + struct fastboot_ptentry *ptn = ptable + n; + printf("ptn %d name='%s'", n, ptn->name); + printf(" start=%d len=%d\n", ptn->start, ptn->length); + } +} + static void fastboot_complete(struct usb_ep *ep, struct usb_request *req) { int status = req->status; @@ -312,6 +347,21 @@ static int fastboot_tx_write_str(const char *buffer) return fastboot_tx_write(buffer, strlen(buffer)); } +struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name) +{ + unsigned int n; + + for (n = 0; n < pcount; n++) { + /* Make sure a substring is not accepted */ + if (strlen(name) == strlen(ptable[n].name)) { + if (0 == strcmp(ptable[n].name, name)) + return ptable + n; + } + } + return 0; +} + + static void compl_do_reset(struct usb_ep *ep, struct usb_request *req) { do_reset(NULL, 0, 0, NULL); @@ -513,6 +563,27 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req) } #endif +#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV +int fastboot_oem(const char *cmd) +{ + if (!strcmp(cmd, "format")) + return do_format(); + return -1; +} + +static void cb_oem(struct usb_ep *ep, struct usb_request *req) +{ + char *cmd = req->buf; + + int r = fastboot_oem(cmd + 4); + if (r < 0) { + fastboot_tx_write_str("FAIL"); + } else { + fastboot_tx_write_str("OKAY"); + } +} +#endif + struct cmd_dispatch_info { char *cmd; void (*cb)(struct usb_ep *ep, struct usb_request *req); @@ -541,6 +612,12 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = { .cb = cb_flash, }, #endif +#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV + { + .cmd = "oem", + .cb = cb_oem, + }, +#endif }; static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) @@ -576,3 +653,11 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) usb_ep_queue(ep, req, 0); } } + +#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV +int board_partition_init(void) +{ + board_mmc_fbtptn_init(); + return 1; +} +#endif diff --git a/include/usb/fastboot.h b/include/usb/fastboot.h new file mode 100644 index 0000000..8fee6fc --- /dev/null +++ b/include/usb/fastboot.h @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2008 - 2009 + * Windriver, + * Tom Rix + * + * Copyright (c) 2011 Sebastian Andrzej Siewior + * + * + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Copyright 2014 Linaro, Ltd. + * Dileep Katta + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef FASTBOOT_H +#define FASTBOOT_H + +#include +#include +#include +#include +#include + +#ifdef CONFIG_CMD_FASTBOOT + +/* Android-style flash naming */ + +/* flash partitions are defined in blocks (flash erase units) */ +struct fastboot_ptentry { + /* The logical name for this partition, null terminated */ + char name[16]; + /* start wrt the nand part, must be multiple of nand block size */ + unsigned int start; + /* length of the partition, must be multiple of nand block size */ + unsigned int length; + /* + * Controls the details of how operations are done on the partition + * See the FASTBOOT_PTENTRY_FLAGS_*'s defined below + */ + unsigned int flags; +}; + +/* + * Lower byte shows if the read/write/erase operation is repeated. + * The base address is incremented. Either 0 or 1 is ok for a default + */ + +#define FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK(n) (n & 0x0f) +#define FASTBOOT_PTENTRY_FLAGS_REPEAT_4 0x00000004 + +/* + * Writes happen a block at a time. If the write fails, go to next block + * NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set + */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK 0x00000010 + +/* + * Find a contiguous block big enough for a the whole file + * NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set + */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK 0x00000020 + +/* + * Following definitions are to set the ECC to software/Hardware + * before writing. HW and SW ECC should not both be set. + */ + + +#define FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC 0x00000040 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC 0x00000080 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH4_ECC 0x00000100 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH8_ECC 0x00000200 +#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH16_ECC 0x00000400 + +/* Write the file with write.i */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_I 0x00000800 + +/* Write the file with write.jffs2 */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_JFFS2 0x00001000 + +/* + * Write the file as a series of variable/value pairs + * using the setenv and saveenv commands + */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_ENV 0x00002000 + + +/* The Android-style flash handling */ + +/* tools to populate and query the partition table */ +void fastboot_flash_add_ptn(struct fastboot_ptentry *ptn); +struct fastboot_ptentry *fastboot_flash_find_ptn(const char *name); +struct fastboot_ptentry *fastboot_flash_get_ptn(unsigned n); +unsigned int fastboot_flash_get_ptn_count(void); +void fastboot_flash_dump_ptn(void); +int fastboot_oem(const char *cmd); +int do_format(void); +int board_mmc_fbtptn_init(void); +void fastboot_flash_reset_ptn(void); +int board_partition_init(void); + +int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); + +#endif +#endif