summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/bcb.c177
-rw-r--r--drivers/usb/gadget/bcb.h38
-rw-r--r--drivers/usb/gadget/bootctrl.c214
-rw-r--r--drivers/usb/gadget/bootctrl.h24
-rw-r--r--drivers/usb/gadget/command.c105
-rw-r--r--drivers/usb/gadget/f_fastboot.c6
7 files changed, 353 insertions, 212 deletions
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 8e9732a..ad9804a 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -21,6 +21,7 @@ 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
+obj-$(CONFIG_BCB_SUPPORT) += command.o bcb.o
endif
ifdef CONFIG_USB_ETHER
obj-y += ether.o
diff --git a/drivers/usb/gadget/bcb.c b/drivers/usb/gadget/bcb.c
new file mode 100644
index 0000000..f6ccf91
--- /dev/null
+++ b/drivers/usb/gadget/bcb.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "bcb.h"
+#include "bootctrl.h"
+#include <linux/stat.h>
+#include <linux/types.h>
+#include <common.h>
+#include <g_dnl.h>
+static unsigned int g_mmc_id;
+void set_mmc_id(unsigned int id)
+{
+ g_mmc_id = id;
+}
+#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */
+static ulong get_block_size(char *ifname, int dev, int part)
+{
+ block_dev_desc_t *dev_desc = NULL;
+ disk_partition_t part_info;
+
+ dev_desc = get_dev(ifname, dev);
+ if (dev_desc == NULL) {
+ printf("Block device %s %d not supported\n", ifname, dev);
+ return 0;
+ }
+
+ if (get_partition_info(dev_desc, part, &part_info)) {
+ printf("Cannot find partition %d\n", part);
+ return 0;
+ }
+
+ return part_info.blksz;
+}
+
+static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char *ep;
+ block_dev_desc_t *dev_desc = NULL;
+ int dev;
+ int part = 0;
+ disk_partition_t part_info;
+ ulong offset = 0u;
+ ulong limit = 0u;
+ void *addr;
+ uint blk;
+ uint cnt;
+
+ if (argc != 6) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ dev = (int)simple_strtoul(argv[2], &ep, 16);
+ if (*ep) {
+ if (*ep != ':') {
+ printf("Invalid block device %s\n", argv[2]);
+ return 1;
+ }
+ part = (int)simple_strtoul(++ep, NULL, 16);
+ }
+
+ dev_desc = get_dev(argv[1], dev);
+ if (dev_desc == NULL) {
+ printf("Block device %s %d not supported\n", argv[1], dev);
+ return 1;
+ }
+
+ addr = (void *)simple_strtoul(argv[3], NULL, 16);
+ blk = simple_strtoul(argv[4], NULL, 16);
+ cnt = simple_strtoul(argv[5], NULL, 16);
+
+ if (part != 0) {
+ if (get_partition_info(dev_desc, part, &part_info)) {
+ printf("Cannot find partition %d\n", part);
+ return 1;
+ }
+ offset = part_info.start;
+ limit = part_info.size;
+ } else {
+ /* Largest address not available in block_dev_desc_t. */
+ limit = ~0;
+ }
+
+ if (cnt + blk > limit) {
+ printf("Write out of range\n");
+ return 1;
+ }
+
+ if (dev_desc->block_write(dev, offset + blk, cnt, addr) < 0) {
+ printf("Error writing blocks\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ write, 6, 0, do_write,
+ "write binary data to a partition",
+ "<interface> <dev[:part]> addr blk# cnt"
+);
+
+int rw_block(bool bread, char **ppblock,
+ uint *pblksize, char *pblock_write, uint offset, uint size)
+{
+ int ret;
+ char *argv[6];
+ char addr_str[20];
+ char cnt_str[8];
+ char devpart_str[8];
+ char block_begin_str[8];
+ ulong blk_size = 0;
+ uint blk_begin = 0;
+ uint blk_end = 0;
+ uint block_cnt = 0;
+ char *p_block = NULL;
+
+ if (bread && ((ppblock == NULL) || (pblksize == NULL)))
+ return -1;
+
+ if (!bread && (pblock_write == NULL))
+ return -1;
+
+ blk_size = get_block_size("mmc", g_mmc_id,
+ CONFIG_ANDROID_MISC_PARTITION_MMC);
+ if (blk_size == 0) {
+ printf("rw_block, get_block_size return 0\n");
+ return -1;
+ }
+
+ blk_begin = offset/blk_size;
+ blk_end = (offset + size)/blk_size;
+ block_cnt = 1 + (blk_end - blk_begin);
+
+
+ sprintf(devpart_str, "0x%x:0x%x", g_mmc_id,
+ CONFIG_ANDROID_MISC_PARTITION_MMC);
+ sprintf(block_begin_str, "0x%x", blk_begin);
+ sprintf(cnt_str, "0x%x", block_cnt);
+
+ argv[0] = "rw"; /* not care */
+ argv[1] = "mmc";
+ argv[2] = devpart_str;
+ argv[3] = addr_str;
+ argv[4] = block_begin_str;
+ argv[5] = cnt_str;
+
+ if (bread) {
+ p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt);
+ if (NULL == p_block) {
+ printf("rw_block, memalign %d bytes failed\n",
+ (int)(blk_size * block_cnt));
+ return -1;
+ }
+ sprintf(addr_str, "0x%x", (unsigned int)p_block);
+ ret = do_raw_read(NULL, 0, 6, argv);
+ if (ret) {
+ free(p_block);
+ printf("do_raw_read failed, ret %d\n", ret);
+ return -1;
+ }
+
+ *ppblock = p_block;
+ *pblksize = (uint)blk_size;
+ } else {
+ sprintf(addr_str, "0x%x", (unsigned int)pblock_write);
+ ret = do_write(NULL, 0, 6, argv);
+ if (ret) {
+ printf("do_write failed, ret %d\n", ret);
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/drivers/usb/gadget/bcb.h b/drivers/usb/gadget/bcb.h
new file mode 100644
index 0000000..2512a7f
--- /dev/null
+++ b/drivers/usb/gadget/bcb.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef BCB_H
+#define BCB_H
+#include <linux/types.h>
+#include <linux/stat.h>
+/* keep same as bootable/recovery/bootloader.h */
+struct bootloader_message {
+ char command[32];
+ char status[32];
+ char recovery[768];
+
+ /* The 'recovery' field used to be 1024 bytes. It has only ever
+ been used to store the recovery command line, so 768 bytes
+ should be plenty. We carve off the last 256 bytes to store the
+ stage string (for multistage packages) and possible future
+ expansion. */
+ char stage[32];
+ char slot_suffix[32];
+ char reserved[192];
+};
+
+/* start from bootloader_message.slot_suffix[BOOTCTRL_IDX] */
+#define BOOTCTRL_IDX 0
+#define MISC_COMMAND_IDX 0
+#define BOOTCTRL_OFFSET \
+ (u32)(&(((struct bootloader_message *)0)->slot_suffix[BOOTCTRL_IDX]))
+#define MISC_COMMAND \
+ (u32)(&(((struct bootloader_message *)0)->command[MISC_COMMAND_IDX]))
+int rw_block(bool bread, char **ppblock,
+ uint *pblksize, char *pblock_write, uint offset, uint size);
+
+void set_mmc_id(unsigned int id);
+#endif
diff --git a/drivers/usb/gadget/bootctrl.c b/drivers/usb/gadget/bootctrl.c
index 653c00c..21a7aee 100644
--- a/drivers/usb/gadget/bootctrl.c
+++ b/drivers/usb/gadget/bootctrl.c
@@ -10,46 +10,6 @@
#include "bootctrl.h"
#include <linux/types.h>
#include <linux/stat.h>
-
-#define SLOT_NUM (unsigned int)2
-
-/* keep same as bootable/recovery/bootloader.h */
-struct bootloader_message {
- char command[32];
- char status[32];
- char recovery[768];
-
- /* The 'recovery' field used to be 1024 bytes. It has only ever
- been used to store the recovery command line, so 768 bytes
- should be plenty. We carve off the last 256 bytes to store the
- stage string (for multistage packages) and possible future
- expansion. */
- char stage[32];
- char slot_suffix[32];
- char reserved[192];
-};
-
-/* start from bootloader_message.slot_suffix[BOOTCTRL_IDX] */
-#define BOOTCTRL_IDX 0
-#define BOOTCTRL_OFFSET \
- (u32)(&(((struct bootloader_message *)0)->slot_suffix[BOOTCTRL_IDX]))
-#define CRC_DATA_OFFSET \
- (uint32_t)(&(((struct boot_ctl *)0)->a_slot_meta[0]))
-
-struct slot_meta {
- u8 bootsuc:1;
- u8 tryremain:3;
- u8 priority:4;
-};
-
-struct boot_ctl {
- char magic[4]; /* "\0FSL" */
- u32 crc;
- struct slot_meta a_slot_meta[SLOT_NUM];
- u8 recovery_tryremain;
-};
-
-static unsigned int g_mmc_id;
static unsigned int g_slot_selected;
static const char *g_slot_suffix[SLOT_NUM] = {"_a", "_b"};
@@ -62,10 +22,6 @@ static int strcmp_l1(const char *s1, const char *s2)
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)
{
@@ -112,98 +68,7 @@ static unsigned int slot_find(struct boot_ctl *ptbootctl)
return slot;
}
-static ulong get_block_size(char *ifname, int dev, int part)
-{
- block_dev_desc_t *dev_desc = NULL;
- disk_partition_t part_info;
-
- dev_desc = get_dev(ifname, dev);
- if (dev_desc == NULL) {
- printf("Block device %s %d not supported\n", ifname, dev);
- return 0;
- }
-
- if (get_partition_info(dev_desc, part, &part_info)) {
- printf("Cannot find partition %d\n", part);
- return 0;
- }
-
- return part_info.blksz;
-}
-
-#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */
-static int rw_block(bool bread, char **ppblock,
- uint *pblksize, char *pblock_write)
-{
- int ret;
- char *argv[6];
- char addr_str[20];
- char cnt_str[8];
- char devpart_str[8];
- char block_begin_str[8];
- ulong blk_size = 0;
- uint blk_begin = 0;
- uint blk_end = 0;
- uint block_cnt = 0;
- char *p_block = NULL;
- if (bread && ((ppblock == NULL) || (pblksize == NULL)))
- return -1;
-
- if (!bread && (pblock_write == NULL))
- return -1;
-
- blk_size = get_block_size("mmc", g_mmc_id,
- CONFIG_ANDROID_MISC_PARTITION_MMC);
- if (blk_size == 0) {
- printf("rw_block, get_block_size return 0\n");
- return -1;
- }
-
- blk_begin = BOOTCTRL_OFFSET/blk_size;
- blk_end = (BOOTCTRL_OFFSET + sizeof(struct boot_ctl) - 1)/blk_size;
- block_cnt = 1 + (blk_end - blk_begin);
-
- sprintf(devpart_str, "0x%x:0x%x", g_mmc_id,
- CONFIG_ANDROID_MISC_PARTITION_MMC);
- sprintf(block_begin_str, "0x%x", blk_begin);
- sprintf(cnt_str, "0x%x", block_cnt);
-
- argv[0] = "rw"; /* not care */
- argv[1] = "mmc";
- argv[2] = devpart_str;
- argv[3] = addr_str;
- argv[4] = block_begin_str;
- argv[5] = cnt_str;
-
- if (bread) {
- p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt);
- if (NULL == p_block) {
- printf("rw_block, memalign %d bytes failed\n",
- (int)(blk_size * block_cnt));
- return -1;
- }
- sprintf(addr_str, "0x%x", (unsigned int)p_block);
- ret = do_raw_read(NULL, 0, 6, argv);
- if (ret) {
- free(p_block);
- printf("do_raw_read failed, ret %d\n", ret);
- return -1;
- }
-
- *ppblock = p_block;
- *pblksize = (uint)blk_size;
- } else {
- sprintf(addr_str, "0x%x", (unsigned int)pblock_write);
- ret = do_write(NULL, 0, 6, argv);
- if (ret) {
- printf("do_write failed, ret %d\n", ret);
- return -1;
- }
- }
-
- return 0;
-}
static int read_bootctl(struct boot_ctl *ptbootctl)
{
@@ -216,8 +81,8 @@ static int read_bootctl(struct boot_ctl *ptbootctl)
if (ptbootctl == NULL)
return -1;
-
- ret = rw_block(true, &p_block, &blk_size, NULL);
+ ret = rw_block(true, &p_block, &blk_size, NULL,
+ BOOTCTRL_OFFSET, sizeof(struct boot_ctl));
if (ret) {
printf("read_bootctl, rw_block read failed\n");
return -1;
@@ -264,22 +129,22 @@ static int write_bootctl(struct boot_ctl *ptbootctl)
ptbootctl->crc = crc32(0, (unsigned char *)ptbootctl + CRC_DATA_OFFSET,
sizeof(struct boot_ctl) - CRC_DATA_OFFSET);
- ret = rw_block(true, &p_block, &blk_size, NULL);
+ ret = rw_block(true, &p_block, &blk_size, NULL,
+ BOOTCTRL_OFFSET, sizeof(struct boot_ctl));
if (ret) {
printf("write_bootctl, rw_block read failed\n");
return -1;
}
-
offset_in_block = BOOTCTRL_OFFSET%blk_size;
memcpy(p_block + offset_in_block, ptbootctl, sizeof(struct boot_ctl));
- ret = rw_block(false, NULL, NULL, p_block);
+ ret = rw_block(false, NULL, NULL, p_block,
+ BOOTCTRL_OFFSET, sizeof(struct boot_ctl));
if (ret) {
free(p_block);
printf("write_bootctl, rw_block write failed\n");
return -1;
}
-
free(p_block);
return 0;
}
@@ -479,70 +344,3 @@ void cb_set_active(struct usb_ep *ep, struct usb_request *req)
return;
}
-static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- char *ep;
- block_dev_desc_t *dev_desc = NULL;
- int dev;
- int part = 0;
- disk_partition_t part_info;
- ulong offset = 0u;
- ulong limit = 0u;
- void *addr;
- uint blk;
- uint cnt;
-
- if (argc != 6) {
- cmd_usage(cmdtp);
- return 1;
- }
-
- dev = (int)simple_strtoul(argv[2], &ep, 16);
- if (*ep) {
- if (*ep != ':') {
- printf("Invalid block device %s\n", argv[2]);
- return 1;
- }
- part = (int)simple_strtoul(++ep, NULL, 16);
- }
-
- dev_desc = get_dev(argv[1], dev);
- if (dev_desc == NULL) {
- printf("Block device %s %d not supported\n", argv[1], dev);
- return 1;
- }
-
- addr = (void *)simple_strtoul(argv[3], NULL, 16);
- blk = simple_strtoul(argv[4], NULL, 16);
- cnt = simple_strtoul(argv[5], NULL, 16);
-
- if (part != 0) {
- if (get_partition_info(dev_desc, part, &part_info)) {
- printf("Cannot find partition %d\n", part);
- return 1;
- }
- offset = part_info.start;
- limit = part_info.size;
- } else {
- /* Largest address not available in block_dev_desc_t. */
- limit = ~0;
- }
-
- if (cnt + blk > limit) {
- printf("Write out of range\n");
- return 1;
- }
-
- if (dev_desc->block_write(dev, offset + blk, cnt, addr) < 0) {
- printf("Error writing blocks\n");
- return 1;
- }
-
- return 0;
-}
-
-U_BOOT_CMD(
- write, 6, 0, do_write,
- "write binary data to a partition",
- "<interface> <dev[:part]> addr blk# cnt"
-);
diff --git a/drivers/usb/gadget/bootctrl.h b/drivers/usb/gadget/bootctrl.h
index 2153103..7712f75 100644
--- a/drivers/usb/gadget/bootctrl.h
+++ b/drivers/usb/gadget/bootctrl.h
@@ -7,11 +7,31 @@
#ifndef BOOTCTRL_H
#define BOOTCTRL_H
-void set_mmc_id(unsigned int id);
+#include <common.h>
+#include <g_dnl.h>
+#include <linux/types.h>
+#include <linux/stat.h>
+#include "bcb.h"
+
+#define SLOT_NUM (unsigned int)2
+#define CRC_DATA_OFFSET \
+ (uint32_t)(&(((struct boot_ctl *)0)->a_slot_meta[0]))
+
+struct slot_meta {
+ u8 bootsuc:1;
+ u8 tryremain:3;
+ u8 priority:4;
+};
+
+struct boot_ctl {
+ char magic[4]; /* "\0FSL" */
+ u32 crc;
+ struct slot_meta a_slot_meta[SLOT_NUM];
+ u8 recovery_tryremain;
+};
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/command.c b/drivers/usb/gadget/command.c
new file mode 100644
index 0000000..3af3fcf
--- /dev/null
+++ b/drivers/usb/gadget/command.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <g_dnl.h>
+#include "bcb.h"
+
+#ifndef CONFIG_FASTBOOT_STORAGE_NAND
+static char command[32];
+static int read_command(char *command)
+{
+ int ret = 0;
+ char *p_block = NULL;
+ uint offset_in_block = 0;
+ uint blk_size = 0;
+
+ if (command == NULL)
+ return -1;
+
+ ret = rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32);
+ if (ret) {
+ printf("read_bootctl, rw_block read failed\n");
+ return -1;
+ }
+
+ offset_in_block = MISC_COMMAND%blk_size;
+ memcpy(command, p_block + offset_in_block, 32);
+
+ return 0;
+}
+static int write_command(char *bcb_command)
+{
+ int ret = 0;
+ char *p_block = NULL;
+ uint offset_in_block = 0;
+ uint blk_size = 0;
+
+ if (bcb_command == NULL)
+ return -1;
+
+
+ ret = rw_block(true, &p_block, &blk_size, NULL, MISC_COMMAND, 32);
+ if (ret) {
+ printf("write_bootctl, rw_block read failed\n");
+ return -1;
+ }
+
+ offset_in_block = MISC_COMMAND%blk_size;
+ memcpy(p_block + offset_in_block, bcb_command, 32);
+
+ ret = rw_block(false, NULL, NULL, p_block, MISC_COMMAND, 32);
+ if (ret) {
+ free(p_block);
+ printf("write_bootctl, rw_block write failed\n");
+ return -1;
+ }
+
+ free(p_block);
+ return 0;
+}
+
+int recovery_check_and_clean_command(void)
+{
+ int ret;
+ ret = read_command(command);
+ if (ret < 0) {
+ printf("read command failed\n");
+ return 0;
+ }
+ if (!strcmp(command, "boot-recovery")) {
+ memset(command, 0, 32);
+ write_command(command);
+ return 1;
+ }
+ return 0;
+}
+int fastboot_check_and_clean_command(void)
+{
+ int ret;
+ ret = read_command(command);
+ if (ret < 0) {
+ printf("read command failed\n");
+ return 0;
+ }
+ if (!strcmp(command, "boot-bootloader")) {
+ memset(command, 0, 32);
+ write_command(command);
+ return 1;
+ }
+
+ return 0;
+}
+#else
+int recovery_check_and_clean_command(void)
+{
+ return 0;
+}
+int fastboot_check_and_clean_command(void)
+{
+ return 0;
+}
+#endif
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index fb2d11c..d641ebd 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -41,7 +41,9 @@
#ifdef CONFIG_BRILLO_SUPPORT
#include "bootctrl.h"
#endif
-
+#ifdef CONFIG_BCB_SUPPORT
+#include "bcb.h"
+#endif
#define FASTBOOT_VERSION "0.4"
#define FASTBOOT_INTERFACE_CLASS 0xff
@@ -1099,7 +1101,7 @@ 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
+#ifdef CONFIG_BCB_SUPPORT
set_mmc_id(fastboot_devinfo.dev_id);
#endif
}