summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorfang hui <hui.fang@nxp.com>2016-04-11 15:18:40 +0800
committerfang hui <hui.fang@nxp.com>2016-04-11 15:22:26 +0800
commita652b49194132ea2f9b7f0aabd3623f49ea4a89e (patch)
tree76b7fbe369f5571abfdabc79b54f86289cb0cde7 /drivers/usb
parent0abc9c182c24f88522bd74fa1b53cd2fa3477184 (diff)
downloadu-boot-imx-a652b49194132ea2f9b7f0aabd3623f49ea4a89e.zip
u-boot-imx-a652b49194132ea2f9b7f0aabd3623f49ea4a89e.tar.gz
u-boot-imx-a652b49194132ea2f9b7f0aabd3623f49ea4a89e.tar.bz2
MA-7251 - [evk_6ul]: Support boot conctrol for brillo
brillo need bootlader support boot control. bootlader can choose which slot(partition) to boot based on it's tactic. The commit support boot control for evk6ul Signed-off-by: fang hui <hui.fang@nxp.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/bootctrl.c393
-rw-r--r--drivers/usb/gadget/bootctrl.h17
-rw-r--r--drivers/usb/gadget/f_fastboot.c143
4 files changed, 530 insertions, 24 deletions
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 4869867..8e9732a 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
obj-$(CONFIG_DFU_FUNCTION) += f_dfu.o
obj-$(CONFIG_USB_GADGET_MASS_STORAGE) += f_mass_storage.o
obj-$(CONFIG_CMD_FASTBOOT) += f_fastboot.o
+obj-$(CONFIG_BRILLO_SUPPORT) += bootctrl.o
endif
ifdef CONFIG_USB_ETHER
obj-y += ether.o
diff --git a/drivers/usb/gadget/bootctrl.c b/drivers/usb/gadget/bootctrl.c
new file mode 100644
index 0000000..bb54ebc
--- /dev/null
+++ b/drivers/usb/gadget/bootctrl.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <g_dnl.h>
+#include <fsl_fastboot.h>
+#include <ext_common.h>
+#include "bootctrl.h"
+
+#define SLOT_NUM (unsigned int)2
+#define META_FILE "slotmeta.data"
+#define META_BAK_FILE ".slotmeta.data.bak"
+#define META_FILE_ABS_PATH "/slotmeta.data"
+#define META_BAK_FILE_ABS_PATH "/.slotmeta.data.bak"
+
+struct slot_meta {
+ unsigned int priority;
+ unsigned int tryremain;
+ unsigned int bootsuc;
+ unsigned int reserved[4];
+};
+
+struct boot_ctl {
+ unsigned int crc;
+ unsigned int recovery_tryremain;
+ struct slot_meta a_slot_meta[SLOT_NUM];
+ unsigned int reserved[4];
+};
+
+
+static unsigned int g_mmc_id;
+static unsigned int g_slot_selected;
+static const char *g_slot_suffix[SLOT_NUM] = {"_a", "_b"};
+
+static int strcmp_l1(const char *s1, const char *s2)
+{
+ if (!s1 || !s2)
+ return -1;
+ return strncmp(s1, s2, strlen(s1));
+}
+
+void set_mmc_id(unsigned int id)
+{
+ g_mmc_id = id;
+}
+
+static void dump_slotmeta(struct boot_ctl *ptbootctl)
+{
+ int i;
+
+ if (ptbootctl == NULL)
+ return;
+
+ printf("RecoveryTryRemain %d, crc %u\n",
+ ptbootctl->recovery_tryremain, ptbootctl->crc);
+
+ for (i = 0; i < SLOT_NUM; i++) {
+ printf("slot %d: pri %d, try %d, suc %d\n", i,
+ ptbootctl->a_slot_meta[i].priority,
+ ptbootctl->a_slot_meta[i].tryremain,
+ ptbootctl->a_slot_meta[i].bootsuc);
+ }
+
+ return;
+}
+
+const char *get_slot_suffix(void)
+{
+ return g_slot_suffix[g_slot_selected];
+}
+
+static unsigned int slot_find(struct boot_ctl *ptbootctl)
+{
+ unsigned int max_pri = 0;
+ unsigned int slot = -1;
+ int i;
+
+ for (i = 0; i < SLOT_NUM; i++) {
+ struct slot_meta *pslot_meta = &(ptbootctl->a_slot_meta[i]);
+ if ((pslot_meta->priority > max_pri) &&
+ ((pslot_meta->bootsuc > 0) ||
+ (pslot_meta->tryremain > 0))) {
+ max_pri = pslot_meta->priority;
+ slot = i;
+ printf("select_slot slot %d\n", slot);
+ }
+ }
+
+ return slot;
+}
+static int read_bootctl(struct boot_ctl *ptbootctl)
+{
+ int ret;
+ char *argv[6];
+ char addr_str[20];
+ char len_str[8];
+ char devpart_str[8];
+ unsigned int crc;
+ int load_count = 0;
+ char *pmeta_file = META_FILE;
+
+ if (ptbootctl == NULL)
+ return -1;
+
+ sprintf(len_str, "0x%x", sizeof(struct boot_ctl));
+ sprintf(addr_str, "0x%x", (unsigned int)ptbootctl);
+ sprintf(devpart_str, "%d:%d", g_mmc_id,
+ CONFIG_ANDROID_SLOTMETA_PARTITION_MMC);
+
+load_meta:
+ argv[0] = "ext4load";
+ argv[1] = "mmc";
+ argv[2] = devpart_str;
+ argv[3] = addr_str;
+ argv[4] = pmeta_file;
+ argv[5] = len_str;
+
+ ret = do_ext4_load(NULL, 0, 5, argv);
+ if (ret) {
+ printf("do_ext4_load %s failed, ret %d\n", pmeta_file, ret);
+ return -1;
+ }
+
+ /* check crc, if faled, load backup meta data */
+ crc = crc32(0, (unsigned char *)ptbootctl + 4,
+ sizeof(struct boot_ctl) - 4);
+ if (crc != ptbootctl->crc) {
+ printf("%s, crc check failed, caculated %d, read %d\n",
+ pmeta_file, crc, ptbootctl->crc);
+
+ if (load_count == 0) {
+ load_count++;
+ pmeta_file = META_BAK_FILE;
+ printf("load backup meta %s\n", pmeta_file);
+ goto load_meta;
+ }
+ return -1;
+ }
+
+ /* use backup meta to recover */
+ if (load_count > 0) {
+ printf("use backup meta to recover\n");
+ argv[0] = "ext4write";
+ argv[4] = META_FILE_ABS_PATH;
+ do_ext4_write(NULL, 0, 6, argv);
+ }
+
+ return 0;
+}
+
+static int write_bootctl(struct boot_ctl *ptbootctl)
+{
+ int ret = 0;
+ char *argv[6];
+ char addr_str[20];
+ char len_str[8];
+ char devpart_str[8];
+
+ if (ptbootctl == NULL)
+ return -1;
+
+ ptbootctl->crc = crc32(0, (unsigned char *)ptbootctl + 4,
+ sizeof(struct boot_ctl) - 4);
+
+ sprintf(len_str, "0x%x", sizeof(struct boot_ctl));
+ sprintf(addr_str, "0x%x", (unsigned int)ptbootctl);
+ sprintf(devpart_str, "%d:%d", g_mmc_id,
+ CONFIG_ANDROID_SLOTMETA_PARTITION_MMC);
+
+ argv[0] = "ext4write";
+ argv[1] = "mmc";
+ argv[2] = devpart_str;
+ argv[3] = addr_str;
+ argv[4] = META_FILE_ABS_PATH;
+ argv[5] = len_str;
+
+
+ /* write back t_bootctl */
+ ret = do_ext4_write(NULL, 0, 6, argv);
+ if (ret) {
+ printf("!!! do_ext4_write %s failed, ret %d\n", argv[4], ret);
+ return ret;
+ }
+
+ /* back up */
+ argv[4] = META_BAK_FILE_ABS_PATH;
+ ret = do_ext4_write(NULL, 0, 6, argv);
+ if (ret) {
+ printf("!!! do_ext4_write %s failed, ret %d\n", argv[4], ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+
+char *select_slot(void)
+{
+ int i = 0;
+ int ret = 0;
+ unsigned int slot;
+ struct boot_ctl t_bootctl;
+ bool b_need_write = false;
+
+ ret = read_bootctl(&t_bootctl);
+ if (ret) {
+ printf("read_bootctl failed, ret %d\n", ret);
+ return NULL;
+ }
+
+ dump_slotmeta(&t_bootctl);
+
+ slot = slot_find(&t_bootctl);
+ if (slot >= SLOT_NUM) {
+ printf("!!! select_slot, no valid slot\n");
+ return NULL;
+ }
+
+ /* invalid slot, set priority to 0 */
+ for (i = 0; i < SLOT_NUM; i++) {
+ struct slot_meta *pslot_meta = &(t_bootctl.a_slot_meta[i]);
+ if ((pslot_meta->bootsuc == 0) &&
+ (pslot_meta->tryremain == 0) &&
+ (pslot_meta->priority > 0)) {
+ pslot_meta->priority = 0;
+ b_need_write = true;
+ }
+ }
+
+ if (t_bootctl.recovery_tryremain != 7) {
+ b_need_write = true;
+ t_bootctl.recovery_tryremain = 7;
+ }
+
+ if ((t_bootctl.a_slot_meta[slot].bootsuc == 0) &&
+ (t_bootctl.a_slot_meta[slot].tryremain > 0)) {
+ b_need_write = true;
+ t_bootctl.a_slot_meta[slot].tryremain--;
+ }
+
+ if (b_need_write) {
+ ret = write_bootctl(&t_bootctl);
+ if (ret)
+ printf("!!! write_bootctl failed, ret %d\n", ret);
+ }
+
+ g_slot_selected = slot;
+
+ if (slot == 0)
+ return FASTBOOT_PARTITION_BOOT_A;
+ else
+ return FASTBOOT_PARTITION_BOOT_B;
+}
+
+static unsigned int slotidx_from_suffix(char *suffix)
+{
+ unsigned int slot = -1;
+
+ if (!strcmp(suffix, "_a"))
+ slot = 0;
+ else if (!strcmp(suffix, "_b"))
+ slot = 1;
+
+ return slot;
+}
+
+bool is_sotvar(char *cmd)
+{
+ if (!strcmp_l1("has-slot:", cmd) ||
+ !strcmp_l1("slot-successful:", cmd) ||
+ !strcmp_l1("slot-suffixes", cmd) ||
+ !strcmp_l1("current-slot", cmd) ||
+ !strcmp_l1("slot-unbootable:", cmd) ||
+ !strcmp_l1("slot-retry-count:", cmd)) {
+ return true;
+ }
+
+ return false;
+}
+
+void get_slotvar(char *cmd, char *response, size_t chars_left)
+{
+ int ret;
+ struct boot_ctl t_bootctl;
+ memset(&t_bootctl, 0, sizeof(t_bootctl));
+
+ ret = read_bootctl(&t_bootctl);
+ if (ret) {
+ error("get_slotvar, read_bootctl failed\n");
+ strcpy(response, "get_slotvar read_bootctl failed");
+ return;
+ }
+
+ if (!strcmp_l1("has-slot:", cmd)) {
+ char *ptnname = NULL;
+ ptnname = strchr(cmd, ':') + 1;
+ if (!strcmp(ptnname, "system") || !strcmp(ptnname, "boot"))
+ strncat(response, "yes", chars_left);
+ else
+ strncat(response, "no", chars_left);
+ } else if (!strcmp_l1("current-slot", cmd)) {
+ unsigned int slot = slot_find(&t_bootctl);
+ if (slot < SLOT_NUM)
+ strncat(response, g_slot_suffix[slot], chars_left);
+ else
+ strncat(response, "no valid slot", chars_left);
+ } else if (!strcmp_l1("slot-suffixes", cmd)) {
+ strncat(response, "_a,_b", chars_left);
+ } else if (!strcmp_l1("slot-successful:", cmd)) {
+ char *suffix = strchr(cmd, ':') + 1;
+ unsigned int slot = slotidx_from_suffix(suffix);
+ if (slot >= SLOT_NUM) {
+ strncat(response, "no such slot", chars_left);
+ } else {
+ bool suc = t_bootctl.a_slot_meta[slot].bootsuc;
+ strncat(response, suc ? "yes" : "no", chars_left);
+ }
+ } else if (!strcmp_l1("slot-unbootable:", cmd)) {
+ char *suffix = strchr(cmd, ':') + 1;
+ unsigned int slot = slotidx_from_suffix(suffix);
+ if (slot >= SLOT_NUM) {
+ strncat(response, "no such slot", chars_left);
+ } else {
+ unsigned int pri = t_bootctl.a_slot_meta[slot].priority;
+ strncat(response, pri ? "no" : "yes", chars_left);
+ }
+ } else if (!strcmp_l1("slot-retry-count:", cmd)) {
+ char *suffix = strchr(cmd, ':') + 1;
+ unsigned int slot = slotidx_from_suffix(suffix);
+ if (slot >= SLOT_NUM)
+ strncat(response, "no such slot", chars_left);
+ else
+ sprintf(response, "OKAY%d",
+ t_bootctl.a_slot_meta[slot].tryremain);
+ } else {
+ strncat(response, "no such slot command", chars_left);
+ }
+
+ return;
+}
+
+
+void cb_set_active(struct usb_ep *ep, struct usb_request *req)
+{
+ int ret;
+ int i;
+ unsigned int slot = 0;
+ char *cmd = req->buf;
+ struct boot_ctl t_bootctl;
+
+ memset(&t_bootctl, 0, sizeof(t_bootctl));
+
+ strsep(&cmd, ":");
+ if (!cmd) {
+ error("missing slot suffix\n");
+ fastboot_tx_write_str("FAILmissing slot suffix");
+ return;
+ }
+
+ slot = slotidx_from_suffix(cmd);
+ if (slot >= SLOT_NUM) {
+ fastboot_tx_write_str("FAILerr slot suffix");
+ return;
+ }
+
+ ret = read_bootctl(&t_bootctl);
+ if (ret)
+ fastboot_tx_write_str("FAILReadBootCtl failed");
+
+ t_bootctl.a_slot_meta[slot].bootsuc = 0;
+ t_bootctl.a_slot_meta[slot].priority = 15;
+ t_bootctl.a_slot_meta[slot].tryremain = 7;
+
+ /* low other slot priority */
+ for (i = 0; i < SLOT_NUM; i++) {
+ if (i == slot)
+ continue;
+
+ if (t_bootctl.a_slot_meta[i].priority >= 15)
+ t_bootctl.a_slot_meta[i].priority = 14;
+ }
+
+ ret = write_bootctl(&t_bootctl);
+ if (ret)
+ fastboot_tx_write_str("write_bootctl failed");
+ else
+ fastboot_tx_write_str("OKAY");
+
+ return;
+}
diff --git a/drivers/usb/gadget/bootctrl.h b/drivers/usb/gadget/bootctrl.h
new file mode 100644
index 0000000..2153103
--- /dev/null
+++ b/drivers/usb/gadget/bootctrl.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef BOOTCTRL_H
+#define BOOTCTRL_H
+
+void set_mmc_id(unsigned int id);
+char *select_slot(void);
+bool is_sotvar(char *cmd);
+void get_slotvar(char *cmd, char *response, size_t chars_left);
+void cb_set_active(struct usb_ep *ep, struct usb_request *req);
+const char *get_slot_suffix(void);
+
+#endif
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 88c648f..400f941 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -36,6 +36,10 @@
#endif
#endif
+#ifdef CONFIG_BRILLO_SUPPORT
+#include "bootctrl.h"
+#endif
+
#define FASTBOOT_VERSION "0.4"
#define FASTBOOT_INTERFACE_CLASS 0xff
@@ -155,13 +159,19 @@ static struct usb_gadget_strings *fastboot_strings[] = {
/*pentry index internally*/
enum {
- PTN_MBR_INDEX = 0,
- PTN_BOOTLOADER_INDEX,
- PTN_KERNEL_INDEX,
- PTN_URAMDISK_INDEX,
- PTN_SYSTEM_INDEX,
- PTN_RECOVERY_INDEX,
- PTN_DATA_INDEX
+ PTN_MBR_INDEX = 0,
+ PTN_BOOTLOADER_INDEX,
+ PTN_KERNEL_INDEX,
+ PTN_URAMDISK_INDEX,
+ PTN_SYSTEM_INDEX,
+ PTN_RECOVERY_INDEX,
+ PTN_DATA_INDEX,
+#ifdef CONFIG_BRILLO_SUPPORT
+ PTN_KERNEL_B_INDEX,
+ PTN_SYSTEM_B_INDEX,
+ PTN_SLOTMETA_INDEX,
+#endif
+ PTN_NUM
};
static unsigned int download_bytes_unpadded;
@@ -811,10 +821,19 @@ static void process_flash_sata(const char *cmdbuf, char *response)
#if defined(CONFIG_FASTBOOT_STORAGE_MMC)
static int is_sparse_partition(struct fastboot_ptentry *ptn)
{
+#ifdef CONFIG_BRILLO_SUPPORT
+ if (ptn && (!strncmp(ptn->name, FASTBOOT_PARTITION_SYSTEM_A,
+ strlen(FASTBOOT_PARTITION_SYSTEM_A)) ||
+ !strncmp(ptn->name, FASTBOOT_PARTITION_SYSTEM_B,
+ strlen(FASTBOOT_PARTITION_SYSTEM_B)) ||
+ !strncmp(ptn->name, FASTBOOT_PARTITION_DATA,
+ strlen(FASTBOOT_PARTITION_DATA)))) {
+#else
if (ptn && (!strncmp(ptn->name,
FASTBOOT_PARTITION_SYSTEM, strlen(FASTBOOT_PARTITION_SYSTEM))
|| !strncmp(ptn->name,
FASTBOOT_PARTITION_DATA, strlen(FASTBOOT_PARTITION_DATA)))) {
+#endif
printf("support sparse flash partition for %s\n", ptn->name);
return 1;
} else
@@ -1078,6 +1097,9 @@ static int _fastboot_setup_dev(void)
} else if (!strncmp(fastboot_env, "mmc", 3)) {
fastboot_devinfo.type = DEV_MMC;
fastboot_devinfo.dev_id = _fastboot_get_mmc_no(fastboot_env);
+#ifdef CONFIG_BRILLO_SUPPORT
+ set_mmc_id(fastboot_devinfo.dev_id);
+#endif
}
} else {
return 1;
@@ -1131,7 +1153,7 @@ static int _fastboot_parts_load_from_ptable(void)
struct mmc *mmc;
block_dev_desc_t *dev_desc;
- struct fastboot_ptentry ptable[PTN_DATA_INDEX + 1];
+ struct fastboot_ptentry ptable[PTN_NUM];
/* sata case in env */
if (fastboot_devinfo.type == DEV_SATA) {
@@ -1178,7 +1200,7 @@ static int _fastboot_parts_load_from_ptable(void)
}
memset((char *)ptable, 0,
- sizeof(struct fastboot_ptentry) * (PTN_DATA_INDEX + 1));
+ sizeof(struct fastboot_ptentry) * (PTN_NUM));
/* MBR */
strcpy(ptable[PTN_MBR_INDEX].name, "mbr");
ptable[PTN_MBR_INDEX].start = ANDROID_MBR_OFFSET / dev_desc->blksz;
@@ -1192,24 +1214,75 @@ static int _fastboot_parts_load_from_ptable(void)
ANDROID_BOOTLOADER_SIZE / dev_desc->blksz;
ptable[PTN_BOOTLOADER_INDEX].partition_id = boot_partition;
+#ifdef CONFIG_BRILLO_SUPPORT
_fastboot_parts_add_ptable_entry(PTN_KERNEL_INDEX,
- CONFIG_ANDROID_BOOT_PARTITION_MMC,
- user_partition,
- FASTBOOT_PARTITION_BOOT , dev_desc, ptable);
+ CONFIG_ANDROID_BOOT_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_BOOT_A,
+ dev_desc, ptable);
+
+ _fastboot_parts_add_ptable_entry(PTN_RECOVERY_INDEX,
+ CONFIG_ANDROID_RECOVERY_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_RECOVERY,
+ dev_desc, ptable);
+
+ _fastboot_parts_add_ptable_entry(PTN_SYSTEM_INDEX,
+ CONFIG_ANDROID_SYSTEM_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_SYSTEM_A,
+ dev_desc, ptable);
+
+ _fastboot_parts_add_ptable_entry(PTN_DATA_INDEX,
+ CONFIG_ANDROID_DATA_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_DATA,
+ dev_desc, ptable);
+
+ _fastboot_parts_add_ptable_entry(PTN_KERNEL_B_INDEX,
+ CONFIG_ANDROID_BOOT_B_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_BOOT_B,
+ dev_desc, ptable);
+
+ _fastboot_parts_add_ptable_entry(PTN_SYSTEM_B_INDEX,
+ CONFIG_ANDROID_SYSTEM_B_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_SYSTEM_B,
+ dev_desc, ptable);
+
+ _fastboot_parts_add_ptable_entry(PTN_SLOTMETA_INDEX,
+ CONFIG_ANDROID_SLOTMETA_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_SLOTMETA,
+ dev_desc, ptable);
+#else
+ _fastboot_parts_add_ptable_entry(PTN_KERNEL_INDEX,
+ CONFIG_ANDROID_BOOT_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_BOOT,
+ dev_desc, ptable);
+
_fastboot_parts_add_ptable_entry(PTN_RECOVERY_INDEX,
- CONFIG_ANDROID_RECOVERY_PARTITION_MMC,
- user_partition,
- FASTBOOT_PARTITION_RECOVERY, dev_desc, ptable);
+ CONFIG_ANDROID_RECOVERY_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_RECOVERY,
+ dev_desc, ptable);
+
_fastboot_parts_add_ptable_entry(PTN_SYSTEM_INDEX,
- CONFIG_ANDROID_SYSTEM_PARTITION_MMC,
- user_partition,
- FASTBOOT_PARTITION_SYSTEM, dev_desc, ptable);
+ CONFIG_ANDROID_SYSTEM_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_SYSTEM,
+ dev_desc, ptable);
+
_fastboot_parts_add_ptable_entry(PTN_DATA_INDEX,
- CONFIG_ANDROID_DATA_PARTITION_MMC,
- user_partition,
- FASTBOOT_PARTITION_DATA, dev_desc, ptable);
+ CONFIG_ANDROID_DATA_PARTITION_MMC,
+ user_partition,
+ FASTBOOT_PARTITION_DATA,
+ dev_desc, ptable);
+#endif
- for (i = 0; i <= PTN_DATA_INDEX; i++)
+ for (i = 0; i < PTN_NUM; i++)
fastboot_flash_add_ptn(&ptable[i]);
return 0;
@@ -1553,7 +1626,16 @@ int do_boota(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc > 2)
ptn = argv[2];
-
+#ifdef CONFIG_BRILLO_SUPPORT
+ else {
+ ptn = select_slot();
+ if (ptn == NULL) {
+ printf("no valid slot found, enter to recovery\n");
+ ptn = "recovery";
+ }
+ printf("use slot %s\n", ptn);
+ }
+#endif
if (mmcc != -1) {
#ifdef CONFIG_MMC
struct fastboot_ptentry *pte;
@@ -1997,7 +2079,7 @@ static int fastboot_tx_write(const char *buffer, unsigned int buffer_size)
return 0;
}
-static int fastboot_tx_write_str(const char *buffer)
+int fastboot_tx_write_str(const char *buffer)
{
return fastboot_tx_write(buffer, strlen(buffer));
}
@@ -2037,6 +2119,13 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
return;
}
+#ifdef CONFIG_BRILLO_SUPPORT
+ if (is_sotvar(cmd)) {
+ get_slotvar(cmd, response, chars_left);
+ fastboot_tx_write_str(response);
+ return;
+ }
+#endif
if (!strcmp_l1("version", cmd)) {
strncat(response, FASTBOOT_VERSION, chars_left);
} else if (!strcmp_l1("bootloader-version", cmd)) {
@@ -2361,6 +2450,12 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = {
.cmd = "oem",
.cb = cb_oem,
},
+#ifdef CONFIG_BRILLO_SUPPORT
+ {
+ .cmd = "set_active",
+ .cb = cb_set_active,
+ },
+#endif
};
static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)