mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 21:21:37 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-usb
This commit is contained in:
commit
7a7ffedabd
15 changed files with 317 additions and 105 deletions
9
README
9
README
|
@ -1773,6 +1773,15 @@ The following options need to be configured:
|
|||
regarding the non-volatile storage device. Define this to
|
||||
the eMMC device that fastboot should use to store the image.
|
||||
|
||||
CONFIG_FASTBOOT_GPT_NAME
|
||||
The fastboot "flash" command supports writing the downloaded
|
||||
image to the Protective MBR and the Primary GUID Partition
|
||||
Table. (Additionally, this downloaded image is post-processed
|
||||
to generate and write the Backup GUID Partition Table.)
|
||||
This occurs when the specified "partition name" on the
|
||||
"fastboot flash" command line matches this value.
|
||||
Default is GPT_ENTRY_NAME (currently "gpt") if undefined.
|
||||
|
||||
- Journaling Flash filesystem support:
|
||||
CONFIG_JFFS2_NAND, CONFIG_JFFS2_NAND_OFF, CONFIG_JFFS2_NAND_SIZE,
|
||||
CONFIG_JFFS2_NAND_DEV
|
||||
|
|
|
@ -38,10 +38,10 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
|
||||
int controller_index = simple_strtoul(usb_controller, NULL, 0);
|
||||
board_usb_init(controller_index, USB_INIT_DEVICE);
|
||||
dfu_clear_detach();
|
||||
g_dnl_clear_detach();
|
||||
g_dnl_register("usb_dnl_dfu");
|
||||
while (1) {
|
||||
if (dfu_detach()) {
|
||||
if (g_dnl_detach()) {
|
||||
/*
|
||||
* Check if USB bus reset is performed after detach,
|
||||
* which indicates that -R switch has been passed to
|
||||
|
@ -74,7 +74,7 @@ done:
|
|||
if (dfu_reset)
|
||||
run_command("reset", 0);
|
||||
|
||||
dfu_clear_detach();
|
||||
g_dnl_clear_detach();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -15,17 +15,21 @@ static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||
{
|
||||
int ret;
|
||||
|
||||
g_dnl_clear_detach();
|
||||
ret = g_dnl_register("usb_dnl_fastboot");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
while (1) {
|
||||
if (g_dnl_detach())
|
||||
break;
|
||||
if (ctrlc())
|
||||
break;
|
||||
usb_gadget_handle_interrupts();
|
||||
}
|
||||
|
||||
g_dnl_unregister();
|
||||
g_dnl_clear_detach();
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,17 @@
|
|||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <fb_mmc.h>
|
||||
#include <part.h>
|
||||
#include <aboot.h>
|
||||
#include <sparse_format.h>
|
||||
|
||||
#ifndef CONFIG_FASTBOOT_GPT_NAME
|
||||
#define CONFIG_FASTBOOT_GPT_NAME GPT_ENTRY_NAME
|
||||
#endif
|
||||
|
||||
/* The 64 defined bytes plus the '\0' */
|
||||
#define RESPONSE_LEN (64 + 1)
|
||||
|
||||
|
@ -62,7 +67,6 @@ static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info,
|
|||
void fb_mmc_flash_write(const char *cmd, void *download_buffer,
|
||||
unsigned int download_bytes, char *response)
|
||||
{
|
||||
int ret;
|
||||
block_dev_desc_t *dev_desc;
|
||||
disk_partition_t info;
|
||||
|
||||
|
@ -76,8 +80,24 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
|
|||
return;
|
||||
}
|
||||
|
||||
ret = get_partition_info_efi_by_name(dev_desc, cmd, &info);
|
||||
if (ret) {
|
||||
if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
|
||||
printf("%s: updating MBR, Primary and Backup GPT(s)\n",
|
||||
__func__);
|
||||
if (is_valid_gpt_buf(dev_desc, download_buffer)) {
|
||||
printf("%s: invalid GPT - refusing to write to flash\n",
|
||||
__func__);
|
||||
fastboot_fail("invalid GPT partition");
|
||||
return;
|
||||
}
|
||||
if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
|
||||
printf("%s: writing GPT partitions failed\n", __func__);
|
||||
fastboot_fail("writing GPT partitions failed");
|
||||
return;
|
||||
}
|
||||
printf("........ success\n");
|
||||
fastboot_okay("");
|
||||
return;
|
||||
} else if (get_partition_info_efi_by_name(dev_desc, cmd, &info)) {
|
||||
error("cannot find partition: '%s'\n", cmd);
|
||||
fastboot_fail("cannot find partition");
|
||||
return;
|
||||
|
|
268
disk/part_efi.c
268
disk/part_efi.c
|
@ -69,6 +69,107 @@ static inline int is_bootable(gpt_entry *p)
|
|||
sizeof(efi_guid_t));
|
||||
}
|
||||
|
||||
static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
|
||||
lbaint_t lastlba)
|
||||
{
|
||||
uint32_t crc32_backup = 0;
|
||||
uint32_t calc_crc32;
|
||||
|
||||
/* Check the GPT header signature */
|
||||
if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE) {
|
||||
printf("%s signature is wrong: 0x%llX != 0x%llX\n",
|
||||
"GUID Partition Table Header",
|
||||
le64_to_cpu(gpt_h->signature),
|
||||
GPT_HEADER_SIGNATURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check the GUID Partition Table CRC */
|
||||
memcpy(&crc32_backup, &gpt_h->header_crc32, sizeof(crc32_backup));
|
||||
memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32));
|
||||
|
||||
calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
|
||||
le32_to_cpu(gpt_h->header_size));
|
||||
|
||||
memcpy(&gpt_h->header_crc32, &crc32_backup, sizeof(crc32_backup));
|
||||
|
||||
if (calc_crc32 != le32_to_cpu(crc32_backup)) {
|
||||
printf("%s CRC is wrong: 0x%x != 0x%x\n",
|
||||
"GUID Partition Table Header",
|
||||
le32_to_cpu(crc32_backup), calc_crc32);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the my_lba entry points to the LBA that contains the GPT
|
||||
*/
|
||||
if (le64_to_cpu(gpt_h->my_lba) != lba) {
|
||||
printf("GPT: my_lba incorrect: %llX != " LBAF "\n",
|
||||
le64_to_cpu(gpt_h->my_lba),
|
||||
lba);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the first_usable_lba and that the last_usable_lba are
|
||||
* within the disk.
|
||||
*/
|
||||
if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) {
|
||||
printf("GPT: first_usable_lba incorrect: %llX > " LBAF "\n",
|
||||
le64_to_cpu(gpt_h->first_usable_lba), lastlba);
|
||||
return -1;
|
||||
}
|
||||
if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) {
|
||||
printf("GPT: last_usable_lba incorrect: %llX > " LBAF "\n",
|
||||
le64_to_cpu(gpt_h->last_usable_lba), lastlba);
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: "
|
||||
LBAF "\n", le64_to_cpu(gpt_h->first_usable_lba),
|
||||
le64_to_cpu(gpt_h->last_usable_lba), lastlba);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
|
||||
{
|
||||
uint32_t calc_crc32;
|
||||
|
||||
/* Check the GUID Partition Table Entry Array CRC */
|
||||
calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
|
||||
le32_to_cpu(gpt_h->num_partition_entries) *
|
||||
le32_to_cpu(gpt_h->sizeof_partition_entry));
|
||||
|
||||
if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) {
|
||||
printf("%s: 0x%x != 0x%x\n",
|
||||
"GUID Partition Table Entry Array CRC is wrong",
|
||||
le32_to_cpu(gpt_h->partition_entry_array_crc32),
|
||||
calc_crc32);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void prepare_backup_gpt_header(gpt_header *gpt_h)
|
||||
{
|
||||
uint32_t calc_crc32;
|
||||
uint64_t val;
|
||||
|
||||
/* recalculate the values for the Backup GPT Header */
|
||||
val = le64_to_cpu(gpt_h->my_lba);
|
||||
gpt_h->my_lba = gpt_h->alternate_lba;
|
||||
gpt_h->alternate_lba = cpu_to_le64(val);
|
||||
gpt_h->partition_entry_lba =
|
||||
cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
|
||||
gpt_h->header_crc32 = 0;
|
||||
|
||||
calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
|
||||
le32_to_cpu(gpt_h->header_size));
|
||||
gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EFI_PARTITION
|
||||
/*
|
||||
* Public Functions (include/part.h)
|
||||
|
@ -259,7 +360,6 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
|
|||
const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
|
||||
* sizeof(gpt_entry)), dev_desc);
|
||||
u32 calc_crc32;
|
||||
u64 val;
|
||||
|
||||
debug("max lba: %x\n", (u32) dev_desc->lba);
|
||||
/* Setup the Protective MBR */
|
||||
|
@ -284,15 +384,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
|
|||
!= pte_blk_cnt)
|
||||
goto err;
|
||||
|
||||
/* recalculate the values for the Backup GPT Header */
|
||||
val = le64_to_cpu(gpt_h->my_lba);
|
||||
gpt_h->my_lba = gpt_h->alternate_lba;
|
||||
gpt_h->alternate_lba = cpu_to_le64(val);
|
||||
gpt_h->header_crc32 = 0;
|
||||
|
||||
calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
|
||||
le32_to_cpu(gpt_h->header_size));
|
||||
gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
|
||||
prepare_backup_gpt_header(gpt_h);
|
||||
|
||||
if (dev_desc->block_write(dev_desc->dev,
|
||||
(lbaint_t)le64_to_cpu(gpt_h->last_usable_lba)
|
||||
|
@ -455,6 +547,97 @@ err:
|
|||
free(gpt_h);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int is_valid_gpt_buf(block_dev_desc_t *dev_desc, void *buf)
|
||||
{
|
||||
gpt_header *gpt_h;
|
||||
gpt_entry *gpt_e;
|
||||
|
||||
/* determine start of GPT Header in the buffer */
|
||||
gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
|
||||
dev_desc->blksz);
|
||||
if (validate_gpt_header(gpt_h, GPT_PRIMARY_PARTITION_TABLE_LBA,
|
||||
dev_desc->lba))
|
||||
return -1;
|
||||
|
||||
/* determine start of GPT Entries in the buffer */
|
||||
gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
|
||||
dev_desc->blksz);
|
||||
if (validate_gpt_entries(gpt_h, gpt_e))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_mbr_and_gpt_partitions(block_dev_desc_t *dev_desc, void *buf)
|
||||
{
|
||||
gpt_header *gpt_h;
|
||||
gpt_entry *gpt_e;
|
||||
int gpt_e_blk_cnt;
|
||||
lbaint_t lba;
|
||||
int cnt;
|
||||
|
||||
if (is_valid_gpt_buf(dev_desc, buf))
|
||||
return -1;
|
||||
|
||||
/* determine start of GPT Header in the buffer */
|
||||
gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
|
||||
dev_desc->blksz);
|
||||
|
||||
/* determine start of GPT Entries in the buffer */
|
||||
gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
|
||||
dev_desc->blksz);
|
||||
gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) *
|
||||
le32_to_cpu(gpt_h->sizeof_partition_entry)),
|
||||
dev_desc);
|
||||
|
||||
/* write MBR */
|
||||
lba = 0; /* MBR is always at 0 */
|
||||
cnt = 1; /* MBR (1 block) */
|
||||
if (dev_desc->block_write(dev_desc->dev, lba, cnt, buf) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "MBR", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write Primary GPT */
|
||||
lba = GPT_PRIMARY_PARTITION_TABLE_LBA;
|
||||
cnt = 1; /* GPT Header (1 block) */
|
||||
if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_h) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "Primary GPT Header", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lba = le64_to_cpu(gpt_h->partition_entry_lba);
|
||||
cnt = gpt_e_blk_cnt;
|
||||
if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_e) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "Primary GPT Entries", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
prepare_backup_gpt_header(gpt_h);
|
||||
|
||||
/* write Backup GPT */
|
||||
lba = le64_to_cpu(gpt_h->partition_entry_lba);
|
||||
cnt = gpt_e_blk_cnt;
|
||||
if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_e) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "Backup GPT Entries", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lba = le64_to_cpu(gpt_h->my_lba);
|
||||
cnt = 1; /* GPT Header (1 block) */
|
||||
if (dev_desc->block_write(dev_desc->dev, lba, cnt, gpt_h) != cnt) {
|
||||
printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
|
||||
__func__, "Backup GPT Header", cnt, lba);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -511,10 +694,6 @@ static int is_pmbr_valid(legacy_mbr * mbr)
|
|||
static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba,
|
||||
gpt_header *pgpt_head, gpt_entry **pgpt_pte)
|
||||
{
|
||||
u32 crc32_backup = 0;
|
||||
u32 calc_crc32;
|
||||
u64 lastlba;
|
||||
|
||||
if (!dev_desc || !pgpt_head) {
|
||||
printf("%s: Invalid Argument(s)\n", __func__);
|
||||
return 0;
|
||||
|
@ -527,55 +706,8 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Check the GPT header signature */
|
||||
if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
|
||||
printf("GUID Partition Table Header signature is wrong:"
|
||||
"0x%llX != 0x%llX\n",
|
||||
le64_to_cpu(pgpt_head->signature),
|
||||
GPT_HEADER_SIGNATURE);
|
||||
if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the GUID Partition Table CRC */
|
||||
memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup));
|
||||
memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
|
||||
|
||||
calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
|
||||
le32_to_cpu(pgpt_head->header_size));
|
||||
|
||||
memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup));
|
||||
|
||||
if (calc_crc32 != le32_to_cpu(crc32_backup)) {
|
||||
printf("GUID Partition Table Header CRC is wrong:"
|
||||
"0x%x != 0x%x\n",
|
||||
le32_to_cpu(crc32_backup), calc_crc32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check that the my_lba entry points to the LBA that contains the GPT */
|
||||
if (le64_to_cpu(pgpt_head->my_lba) != lba) {
|
||||
printf("GPT: my_lba incorrect: %llX != %" PRIX64 "\n",
|
||||
le64_to_cpu(pgpt_head->my_lba),
|
||||
lba);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the first_usable_lba and last_usable_lba are within the disk. */
|
||||
lastlba = (u64)dev_desc->lba;
|
||||
if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) {
|
||||
printf("GPT: first_usable_lba incorrect: %llX > %" PRIX64 "\n",
|
||||
le64_to_cpu(pgpt_head->first_usable_lba), lastlba);
|
||||
return 0;
|
||||
}
|
||||
if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) {
|
||||
printf("GPT: last_usable_lba incorrect: %llX > %" PRIX64 "\n",
|
||||
le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %"
|
||||
PRIX64 "\n", le64_to_cpu(pgpt_head->first_usable_lba),
|
||||
le64_to_cpu(pgpt_head->last_usable_lba), lastlba);
|
||||
|
||||
/* Read and allocate Partition Table Entries */
|
||||
*pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
|
||||
|
@ -584,17 +716,7 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Check the GUID Partition Table Entry Array CRC */
|
||||
calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
|
||||
le32_to_cpu(pgpt_head->num_partition_entries) *
|
||||
le32_to_cpu(pgpt_head->sizeof_partition_entry));
|
||||
|
||||
if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) {
|
||||
printf("GUID Partition Table Entry Array CRC is wrong:"
|
||||
"0x%x != 0x%x\n",
|
||||
le32_to_cpu(pgpt_head->partition_entry_array_crc32),
|
||||
calc_crc32);
|
||||
|
||||
if (validate_gpt_entries(pgpt_head, *pgpt_pte)) {
|
||||
free(*pgpt_pte);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
static bool dfu_detach_request;
|
||||
static LIST_HEAD(dfu_list);
|
||||
static int dfu_alt_num;
|
||||
static int alt_num_cnt;
|
||||
|
@ -39,21 +38,6 @@ __weak bool dfu_usb_get_reset(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool dfu_detach(void)
|
||||
{
|
||||
return dfu_detach_request;
|
||||
}
|
||||
|
||||
void dfu_trigger_detach(void)
|
||||
{
|
||||
dfu_detach_request = true;
|
||||
}
|
||||
|
||||
void dfu_clear_detach(void)
|
||||
{
|
||||
dfu_detach_request = false;
|
||||
}
|
||||
|
||||
static int dfu_find_alt_num(const char *s)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -111,8 +95,12 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu)
|
|||
return dfu_buf;
|
||||
|
||||
s = getenv("dfu_bufsiz");
|
||||
dfu_buf_size = s ? (unsigned long)simple_strtol(s, NULL, 16) :
|
||||
CONFIG_SYS_DFU_DATA_BUF_SIZE;
|
||||
if (s)
|
||||
dfu_buf_size = (unsigned long)simple_strtol(s, NULL, 0);
|
||||
|
||||
if (!s || !dfu_buf_size)
|
||||
dfu_buf_size = CONFIG_SYS_DFU_DATA_BUF_SIZE;
|
||||
|
||||
if (dfu->max_buf_size && dfu_buf_size > dfu->max_buf_size)
|
||||
dfu_buf_size = dfu->max_buf_size;
|
||||
|
||||
|
|
|
@ -40,10 +40,16 @@ static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part)
|
|||
static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
|
||||
u64 offset, void *buf, long *len)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(dfu->data.mmc.dev_num);
|
||||
struct mmc *mmc;
|
||||
u32 blk_start, blk_count, n = 0;
|
||||
int ret, part_num_bkp = 0;
|
||||
|
||||
mmc = find_mmc_device(dfu->data.mmc.dev_num);
|
||||
if (!mmc) {
|
||||
error("Device MMC %d - not found!", dfu->data.mmc.dev_num);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* We must ensure that we work in lba_blk_size chunks, so ALIGN
|
||||
* this value.
|
||||
|
|
|
@ -1062,7 +1062,6 @@ static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep)
|
|||
if ((epstatus & epctrl) & USBA_RX_BK_RDY) {
|
||||
DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name);
|
||||
receive_data(ep);
|
||||
usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ static int state_dfu_idle(struct f_dfu *f_dfu,
|
|||
to_runtime_mode(f_dfu);
|
||||
f_dfu->dfu_state = DFU_STATE_appIDLE;
|
||||
|
||||
dfu_trigger_detach();
|
||||
g_dnl_trigger_detach();
|
||||
break;
|
||||
default:
|
||||
f_dfu->dfu_state = DFU_STATE_dfuERROR;
|
||||
|
|
|
@ -480,6 +480,17 @@ static void cb_boot(struct usb_ep *ep, struct usb_request *req)
|
|||
fastboot_tx_write_str("OKAY");
|
||||
}
|
||||
|
||||
static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
g_dnl_trigger_detach();
|
||||
}
|
||||
|
||||
static void cb_continue(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
fastboot_func->in_req->complete = do_exit_on_complete;
|
||||
fastboot_tx_write_str("OKAY");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FASTBOOT_FLASH
|
||||
static void cb_flash(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
|
@ -520,6 +531,9 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = {
|
|||
}, {
|
||||
.cmd = "boot",
|
||||
.cb = cb_boot,
|
||||
}, {
|
||||
.cmd = "continue",
|
||||
.cb = cb_continue,
|
||||
},
|
||||
#ifdef CONFIG_FASTBOOT_FLASH
|
||||
{
|
||||
|
|
|
@ -205,12 +205,24 @@ static long long int download_head(unsigned long long total,
|
|||
|
||||
static int download_tail(long long int left, int cnt)
|
||||
{
|
||||
struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
|
||||
void *transfer_buffer = dfu_get_buf(dfu_entity);
|
||||
struct dfu_entity *dfu_entity;
|
||||
void *transfer_buffer;
|
||||
int ret;
|
||||
|
||||
debug("%s: left: %llu cnt: %d\n", __func__, left, cnt);
|
||||
|
||||
dfu_entity = dfu_get_entity(alt_setting_num);
|
||||
if (!dfu_entity) {
|
||||
error("Alt setting: %d entity not found!\n", alt_setting_num);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
transfer_buffer = dfu_get_buf(dfu_entity);
|
||||
if (!transfer_buffer) {
|
||||
error("Transfer buffer not allocated!");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (left) {
|
||||
ret = dfu_write(dfu_entity, transfer_buffer, left, cnt++);
|
||||
if (ret) {
|
||||
|
|
|
@ -163,6 +163,23 @@ __weak int g_dnl_board_usb_cable_connected(void)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static bool g_dnl_detach_request;
|
||||
|
||||
bool g_dnl_detach(void)
|
||||
{
|
||||
return g_dnl_detach_request;
|
||||
}
|
||||
|
||||
void g_dnl_trigger_detach(void)
|
||||
{
|
||||
g_dnl_detach_request = true;
|
||||
}
|
||||
|
||||
void g_dnl_clear_detach(void)
|
||||
{
|
||||
g_dnl_detach_request = false;
|
||||
}
|
||||
|
||||
static int g_dnl_get_bcd_device_number(struct usb_composite_dev *cdev)
|
||||
{
|
||||
struct usb_gadget *gadget = cdev->gadget;
|
||||
|
|
|
@ -150,9 +150,6 @@ struct dfu_entity *dfu_get_entity(int alt);
|
|||
char *dfu_extract_token(char** e, int *n);
|
||||
void dfu_trigger_reset(void);
|
||||
int dfu_get_alt(char *name);
|
||||
bool dfu_detach(void);
|
||||
void dfu_trigger_detach(void);
|
||||
void dfu_clear_detach(void);
|
||||
int dfu_init_env_entities(char *interface, char *devstr);
|
||||
unsigned char *dfu_get_buf(struct dfu_entity *dfu);
|
||||
unsigned char *dfu_free_buf(void);
|
||||
|
|
|
@ -39,4 +39,8 @@ int g_dnl_register(const char *s);
|
|||
void g_dnl_unregister(void);
|
||||
void g_dnl_set_serialnumber(char *);
|
||||
|
||||
bool g_dnl_detach(void);
|
||||
void g_dnl_trigger_detach(void);
|
||||
void g_dnl_clear_detach(void);
|
||||
|
||||
#endif /* __G_DOWNLOAD_H_ */
|
||||
|
|
|
@ -244,6 +244,26 @@ int gpt_fill_header(block_dev_desc_t *dev_desc, gpt_header *gpt_h,
|
|||
*/
|
||||
int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
|
||||
disk_partition_t *partitions, const int parts_count);
|
||||
|
||||
/**
|
||||
* is_valid_gpt_buf() - Ensure that the Primary GPT information is valid
|
||||
*
|
||||
* @param dev_desc - block device descriptor
|
||||
* @param buf - buffer which contains the MBR and Primary GPT info
|
||||
*
|
||||
* @return - '0' on success, otherwise error
|
||||
*/
|
||||
int is_valid_gpt_buf(block_dev_desc_t *dev_desc, void *buf);
|
||||
|
||||
/**
|
||||
* write_mbr_and_gpt_partitions() - write MBR, Primary GPT and Backup GPT
|
||||
*
|
||||
* @param dev_desc - block device descriptor
|
||||
* @param buf - buffer which contains the MBR and Primary GPT info
|
||||
*
|
||||
* @return - '0' on success, otherwise error
|
||||
*/
|
||||
int write_mbr_and_gpt_partitions(block_dev_desc_t *dev_desc, void *buf);
|
||||
#endif
|
||||
|
||||
#endif /* _PART_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue