diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/board_f.c | 6 | ||||
-rw-r--r-- | common/board_r.c | 1 | ||||
-rw-r--r-- | common/cmd_aes.c | 89 | ||||
-rw-r--r-- | common/cmd_bootm.c | 2 | ||||
-rw-r--r-- | common/cmd_dfu.c | 3 | ||||
-rw-r--r-- | common/cmd_fdos.c | 124 | ||||
-rw-r--r-- | common/cmd_fdt.c | 42 | ||||
-rw-r--r-- | common/cmd_gpio.c | 7 | ||||
-rw-r--r-- | common/cmd_thordown.c | 3 | ||||
-rw-r--r-- | common/cmd_usb_mass_storage.c | 10 | ||||
-rw-r--r-- | common/ddr_spd.c | 45 | ||||
-rw-r--r-- | common/env_common.c | 79 | ||||
-rw-r--r-- | common/env_dataflash.c | 17 | ||||
-rw-r--r-- | common/env_eeprom.c | 12 | ||||
-rw-r--r-- | common/env_fat.c | 12 | ||||
-rw-r--r-- | common/env_flash.c | 24 | ||||
-rw-r--r-- | common/env_mmc.c | 12 | ||||
-rw-r--r-- | common/env_nand.c | 13 | ||||
-rw-r--r-- | common/env_nvram.c | 12 | ||||
-rw-r--r-- | common/env_onenand.c | 13 | ||||
-rw-r--r-- | common/env_sf.c | 24 | ||||
-rw-r--r-- | common/env_ubi.c | 27 | ||||
-rw-r--r-- | common/fdt_support.c | 132 | ||||
-rw-r--r-- | common/hash.c | 116 | ||||
-rw-r--r-- | common/image-fit.c | 5 | ||||
-rw-r--r-- | common/image-sig.c | 63 | ||||
-rw-r--r-- | common/main.c | 6 | ||||
-rw-r--r-- | common/spl/spl_nand.c | 2 | ||||
-rw-r--r-- | common/usb_kbd.c | 36 |
30 files changed, 650 insertions, 288 deletions
diff --git a/common/Makefile b/common/Makefile index cecd81a9a0..7c853ae442 100644 --- a/common/Makefile +++ b/common/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o # command +obj-$(CONFIG_CMD_AES) += cmd_aes.o obj-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o obj-$(CONFIG_SOURCE) += cmd_source.o obj-$(CONFIG_CMD_SOURCE) += cmd_source.o diff --git a/common/board_f.c b/common/board_f.c index f285bad538..cbdf06f812 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -173,7 +173,7 @@ static int announce_dram_init(void) return 0; } -#ifdef CONFIG_PPC +#if defined(CONFIG_MIPS) || defined(CONFIG_PPC) static int init_func_ram(void) { #ifdef CONFIG_BOARD_TYPES @@ -819,7 +819,7 @@ static init_fnc_t init_sequence_f[] = { /* TODO: can we rename this to timer_init()? */ init_timebase, #endif -#ifdef CONFIG_ARM +#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) timer_init, /* initialize timer */ #endif #ifdef CONFIG_SYS_ALLOC_DPRAM @@ -889,7 +889,7 @@ static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_ARM dram_init, /* configure available RAM banks */ #endif -#ifdef CONFIG_PPC +#if defined(CONFIG_MIPS) || defined(CONFIG_PPC) init_func_ram, #endif #ifdef CONFIG_POST diff --git a/common/board_r.c b/common/board_r.c index 8629a656c2..d1f0aa9b1a 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -528,6 +528,7 @@ static int show_model_r(void) # else checkboard(); # endif + return 0; } #endif diff --git a/common/cmd_aes.c b/common/cmd_aes.c new file mode 100644 index 0000000000..76da3efffe --- /dev/null +++ b/common/cmd_aes.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 Marek Vasut <marex@denx.de> + * + * Command for en/de-crypting block of memory with AES-128-CBC cipher. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <environment.h> +#include <aes.h> +#include <malloc.h> +#include <asm/byteorder.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * do_aes() - Handle the "aes" command-line command + * @cmdtp: Command data struct pointer + * @flag: Command flag + * @argc: Command-line argument count + * @argv: Array of command-line arguments + * + * Returns zero on success, CMD_RET_USAGE in case of misuse and negative + * on error. + */ +static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + uint32_t key_addr, src_addr, dst_addr, len; + uint8_t *key_ptr, *src_ptr, *dst_ptr; + uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; + uint32_t aes_blocks; + int enc; + + if (argc != 6) + return CMD_RET_USAGE; + + if (!strncmp(argv[1], "enc", 3)) + enc = 1; + else if (!strncmp(argv[1], "dec", 3)) + enc = 0; + else + return CMD_RET_USAGE; + + key_addr = simple_strtoul(argv[2], NULL, 16); + src_addr = simple_strtoul(argv[3], NULL, 16); + dst_addr = simple_strtoul(argv[4], NULL, 16); + len = simple_strtoul(argv[5], NULL, 16); + + key_ptr = (uint8_t *)key_addr; + src_ptr = (uint8_t *)src_addr; + dst_ptr = (uint8_t *)dst_addr; + + /* First we expand the key. */ + aes_expand_key(key_ptr, key_exp); + + /* Calculate the number of AES blocks to encrypt. */ + aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH); + + if (enc) + aes_cbc_encrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks); + else + aes_cbc_decrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks); + + return 0; +} + +/***************************************************/ +#ifdef CONFIG_SYS_LONGHELP +static char aes_help_text[] = + "enc key src dst len - Encrypt block of data $len bytes long\n" + " at address $src using a key at address\n" + " $key and store the result at address\n" + " $dst. The $len size must be multiple of\n" + " 16 bytes and $key must be 16 bytes long.\n" + "aes dec key src dst len - Decrypt block of data $len bytes long\n" + " at address $src using a key at address\n" + " $key and store the result at address\n" + " $dst. The $len size must be multiple of\n" + " 16 bytes and $key must be 16 bytes long."; +#endif + +U_BOOT_CMD( + aes, 6, 1, do_aes, + "AES 128 CBC encryption", + aes_help_text +); diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9751edc907..c243a5bd78 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -453,7 +453,7 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, #endif /* CONFIG_LZMA */ #ifdef CONFIG_LZO case IH_COMP_LZO: { - size_t size; + size_t size = unc_len; printf(" Uncompressing %s ... ", type_name); diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c index 5547678208..a03538dabb 100644 --- a/common/cmd_dfu.c +++ b/common/cmd_dfu.c @@ -22,7 +22,6 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *interface = argv[2]; char *devstring = argv[3]; - char *s = "dfu"; int ret, i = 0; ret = dfu_init_env_entities(interface, simple_strtoul(devstring, @@ -38,7 +37,7 @@ 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); - g_dnl_register(s); + g_dnl_register("usb_dnl_dfu"); while (1) { if (dfu_reset()) /* diff --git a/common/cmd_fdos.c b/common/cmd_fdos.c deleted file mode 100644 index 69303255ff..0000000000 --- a/common/cmd_fdos.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Dos floppy support - */ - -#include <common.h> -#include <config.h> -#include <command.h> -#include <fdc.h> - -/*----------------------------------------------------------------------------- - * do_fdosboot -- - *----------------------------------------------------------------------------- - */ -int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - char *name; - char *ep; - int size; - int drive = CONFIG_SYS_FDC_DRIVE_NUMBER; - - /* pre-set load_addr */ - if ((ep = getenv("loadaddr")) != NULL) { - load_addr = simple_strtoul(ep, NULL, 16); - } - - /* pre-set Boot file name */ - if ((name = getenv("bootfile")) == NULL) { - name = "uImage"; - } - - switch (argc) { - case 1: - break; - case 2: - /* only one arg - accept two forms: - * just load address, or just boot file name. - * The latter form must be written "filename" here. - */ - if (argv[1][0] == '"') { /* just boot filename */ - name = argv [1]; - } else { /* load address */ - load_addr = simple_strtoul(argv[1], NULL, 16); - } - break; - case 3: - load_addr = simple_strtoul(argv[1], NULL, 16); - name = argv [2]; - break; - default: - return CMD_RET_USAGE; - } - - /* Init physical layer */ - if (!fdc_fdos_init (drive)) { - return (-1); - } - - /* Open file */ - if (dos_open (name) < 0) { - printf ("Unable to open %s\n", name); - return 1; - } - if ((size = dos_read (load_addr)) < 0) { - printf ("boot error\n"); - return 1; - } - flush_cache (load_addr, size); - - setenv_hex("filesize", size); - - printf("Floppy DOS load complete: %d bytes loaded to 0x%lx\n", - size, load_addr); - - return bootm_maybe_autostart(cmdtp, argv[0]); -} - -/*----------------------------------------------------------------------------- - * do_fdosls -- - *----------------------------------------------------------------------------- - */ -int do_fdosls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - char *path = ""; - int drive = CONFIG_SYS_FDC_DRIVE_NUMBER; - - switch (argc) { - case 1: - break; - case 2: - path = argv [1]; - break; - } - - /* Init physical layer */ - if (!fdc_fdos_init (drive)) { - return (-1); - } - /* Open directory */ - if (dos_open (path) < 0) { - printf ("Unable to open %s\n", path); - return 1; - } - return (dos_dir ()); -} - -U_BOOT_CMD( - fdosboot, 3, 0, do_fdosboot, - "boot from a dos floppy file", - "[loadAddr] [filename]" -); - -U_BOOT_CMD( - fdosls, 2, 0, do_fdosls, - "list files in a directory", - "[directory]" -); diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 3a9edd6468..a6744ed9c2 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -570,7 +570,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ft_board_setup(working_fdt, gd->bd); #endif /* Create a chosen node */ - else if (argv[1][0] == 'c') { + else if (strncmp(argv[1], "cho", 3) == 0) { unsigned long initrd_start = 0, initrd_end = 0; if ((argc != 2) && (argc != 4)) @@ -583,6 +583,41 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) fdt_chosen(working_fdt, 1); fdt_initrd(working_fdt, initrd_start, initrd_end, 1); + +#if defined(CONFIG_FIT_SIGNATURE) + } else if (strncmp(argv[1], "che", 3) == 0) { + int cfg_noffset; + int ret; + unsigned long addr; + struct fdt_header *blob; + + if (!working_fdt) + return CMD_RET_FAILURE; + + if (argc > 2) { + addr = simple_strtoul(argv[2], NULL, 16); + blob = map_sysmem(addr, 0); + } else { + blob = (struct fdt_header *)gd->fdt_blob; + } + if (!fdt_valid(&blob)) + return 1; + + gd->fdt_blob = blob; + cfg_noffset = fit_conf_get_node(working_fdt, NULL); + if (!cfg_noffset) { + printf("Could not find configuration node: %s\n", + fdt_strerror(cfg_noffset)); + return CMD_RET_FAILURE; + } + + ret = fit_config_verify(working_fdt, cfg_noffset); + if (ret == 1) + return CMD_RET_SUCCESS; + else + return CMD_RET_FAILURE; +#endif + } /* resize the fdt */ else if (strncmp(argv[1], "re", 2) == 0) { @@ -992,6 +1027,11 @@ static char fdt_help_text[] = "fdt rsvmem delete <index> - Delete a mem reserves\n" "fdt chosen [<start> <end>] - Add/update the /chosen branch in the tree\n" " <start>/<end> - initrd start/end addr\n" +#if defined(CONFIG_FIT_SIGNATURE) + "fdt checksign [<addr>] - check FIT signature\n" + " <start> - addr of key blob\n" + " default gd->fdt_blob\n" +#endif "NOTE: Dereference aliases by omiting the leading '/', " "e.g. fdt print ethernet0."; #endif diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 778aa5f098..aff044518f 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -11,9 +11,10 @@ #include <dm.h> #include <asm/gpio.h> -#ifndef name_to_gpio -#define name_to_gpio(name) simple_strtoul(name, NULL, 10) -#endif +int __weak name_to_gpio(const char *name) +{ + return simple_strtoul(name, NULL, 10); +} enum gpio_cmd { GPIO_INPUT, diff --git a/common/cmd_thordown.c b/common/cmd_thordown.c index c4b3511458..2dd750928e 100644 --- a/common/cmd_thordown.c +++ b/common/cmd_thordown.c @@ -22,7 +22,6 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *interface = argv[2]; char *devstring = argv[3]; - const char *s = "thor"; int ret; puts("TIZEN \"THOR\" Downloader\n"); @@ -40,7 +39,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) goto exit; } - g_dnl_register(s); + g_dnl_register("usb_dnl_thor"); ret = thor_init(); if (ret) { diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index 5f557d5f85..d8d9efd4f6 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -40,15 +40,19 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } - g_dnl_register("ums"); + g_dnl_register("usb_dnl_ums"); /* Timeout unit: seconds */ int cable_ready_timeout = UMS_CABLE_READY_TIMEOUT; - if (!usb_cable_connected()) { + if (!g_dnl_board_usb_cable_connected()) { + /* + * Won't execute if we don't know whether the cable is + * connected. + */ puts("Please connect USB cable.\n"); - while (!usb_cable_connected()) { + while (!g_dnl_board_usb_cable_connected()) { if (ctrlc()) { puts("\rCTRL+C - Operation aborted.\n"); goto exit; diff --git a/common/ddr_spd.c b/common/ddr_spd.c index 7a388bb9fa..438e71afd2 100644 --- a/common/ddr_spd.c +++ b/common/ddr_spd.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Freescale Semiconductor, Inc. + * Copyright 2008-2014 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -116,3 +116,46 @@ ddr3_spd_check(const ddr3_spd_eeprom_t *spd) return 1; } } + +unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd) +{ + char *p = (char *)spd; + int csum16; + int len; + char crc_lsb; /* byte 126 */ + char crc_msb; /* byte 127 */ + + len = 126; + csum16 = crc16(p, len); + + crc_lsb = (char) (csum16 & 0xff); + crc_msb = (char) (csum16 >> 8); + + if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb) { + printf("SPD checksum unexpected.\n" + "Checksum lsb in SPD = %02X, computed SPD = %02X\n" + "Checksum msb in SPD = %02X, computed SPD = %02X\n", + spd->crc[0], crc_lsb, spd->crc[1], crc_msb); + return 1; + } + + p = (char *)((ulong)spd + 128); + len = 126; + csum16 = crc16(p, len); + + crc_lsb = (char) (csum16 & 0xff); + crc_msb = (char) (csum16 >> 8); + + if (spd->mod_section.uc[126] != crc_lsb || + spd->mod_section.uc[127] != crc_msb) { + printf("SPD checksum unexpected.\n" + "Checksum lsb in SPD = %02X, computed SPD = %02X\n" + "Checksum msb in SPD = %02X, computed SPD = %02X\n", + spd->mod_section.uc[126], + crc_lsb, spd->mod_section.uc[127], + crc_msb); + return 1; + } + + return 0; +} diff --git a/common/env_common.c b/common/env_common.c index c0bfc2f5db..cd7b4cd1df 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -140,6 +140,52 @@ int set_default_vars(int nvars, char * const vars[]) H_NOCLEAR | H_INTERACTIVE, nvars, vars); } +#ifdef CONFIG_ENV_AES +#include <aes.h> +/** + * env_aes_cbc_get_key() - Get AES-128-CBC key for the environment + * + * This function shall return 16-byte array containing AES-128 key used + * to encrypt and decrypt the environment. This function must be overriden + * by the implementer as otherwise the environment encryption will not + * work. + */ +__weak uint8_t *env_aes_cbc_get_key(void) +{ + return NULL; +} + +static int env_aes_cbc_crypt(env_t *env, const int enc) +{ + unsigned char *data = env->data; + uint8_t *key; + uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; + uint32_t aes_blocks; + + key = env_aes_cbc_get_key(); + if (!key) + return -EINVAL; + + /* First we expand the key. */ + aes_expand_key(key, key_exp); + + /* Calculate the number of AES blocks to encrypt. */ + aes_blocks = ENV_SIZE / AES_KEY_LENGTH; + + if (enc) + aes_cbc_encrypt_blocks(key_exp, data, data, aes_blocks); + else + aes_cbc_decrypt_blocks(key_exp, data, data, aes_blocks); + + return 0; +} +#else +static inline int env_aes_cbc_crypt(env_t *env, const int enc) +{ + return 0; +} +#endif + /* * Check if CRC is valid and (if yes) import the environment. * Note that "buf" may or may not be aligned. @@ -147,6 +193,7 @@ int set_default_vars(int nvars, char * const vars[]) int env_import(const char *buf, int check) { env_t *ep = (env_t *)buf; + int ret; if (check) { uint32_t crc; @@ -159,6 +206,14 @@ int env_import(const char *buf, int check) } } + /* Decrypt the env if desired. */ + ret = env_aes_cbc_crypt(ep, 0); + if (ret) { + error("Failed to decrypt env!\n"); + set_default_env("!import failed"); + return ret; + } + if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0, NULL)) { gd->flags |= GD_FLG_ENV_READY; @@ -172,6 +227,30 @@ int env_import(const char *buf, int check) return 0; } +/* Emport the environment and generate CRC for it. */ +int env_export(env_t *env_out) +{ + char *res; + ssize_t len; + int ret; + + res = (char *)env_out->data; + len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + + /* Encrypt the env if desired. */ + ret = env_aes_cbc_crypt(env_out, 1); + if (ret) + return ret; + + env_out->crc = crc32(0, env_out->data, ENV_SIZE); + + return 0; +} + void env_relocate(void) { #if defined(CONFIG_NEEDS_MANUAL_RELOC) diff --git a/common/env_dataflash.c b/common/env_dataflash.c index b53b87e958..034e323169 100644 --- a/common/env_dataflash.c +++ b/common/env_dataflash.c @@ -56,17 +56,12 @@ void env_relocate_spec(void) int saveenv(void) { - env_t env_new; - ssize_t len; - char *res; - - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_t env_new; + int ret; + + ret = env_export(&env_new); + if (ret) + return ret; return write_dataflash(CONFIG_ENV_ADDR, (unsigned long)&env_new, diff --git a/common/env_eeprom.c b/common/env_eeprom.c index 0db2bb63fe..490ac731b3 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -98,8 +98,6 @@ void env_relocate_spec(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; int rc; unsigned int off = CONFIG_ENV_OFFSET; #ifdef CONFIG_ENV_OFFSET_REDUND @@ -109,13 +107,9 @@ int saveenv(void) BUG_ON(env_ptr != NULL); - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + rc = env_export(&env_new); + if (rc) + return rc; #ifdef CONFIG_ENV_OFFSET_REDUND if (gd->env_valid == 1) { diff --git a/common/env_fat.c b/common/env_fat.c index 708fd13dc7..aad0487c32 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -37,19 +37,14 @@ int env_init(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; int err; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } + err = env_export(&env_new); + if (err) + return err; #ifdef CONFIG_MMC if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) { @@ -79,7 +74,6 @@ int saveenv(void) return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)); if (err == -1) { printf("\n** Unable to write \"%s\" from %s%d:%d **\n", diff --git a/common/env_flash.c b/common/env_flash.c index 7d5a4cfc8a..004e8849a7 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -106,8 +106,7 @@ int env_init(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res, *saved_data = NULL; + char *saved_data = NULL; char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; int rc = 1; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE @@ -125,13 +124,9 @@ int saveenv(void) if (flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new)) goto done; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - goto done; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + rc = env_export(&env_new); + if (rc) + return rc; env_new.flags = new_flag; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE @@ -229,9 +224,8 @@ int env_init(void) int saveenv(void) { env_t env_new; - ssize_t len; int rc = 1; - char *res, *saved_data = NULL; + char *saved_data = NULL; #if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE ulong up_data = 0; @@ -258,13 +252,9 @@ int saveenv(void) if (flash_sect_protect(0, (long)flash_addr, end_addr)) goto done; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); + rc = env_export(&env_new); + if (rc) goto done; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); puts("Erasing Flash..."); if (flash_sect_erase((long)flash_addr, end_addr)) diff --git a/common/env_mmc.c b/common/env_mmc.c index f47bd77725..7da10e61af 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -129,8 +129,6 @@ static unsigned char env_flags; int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); u32 offset; int ret, copy = 0; @@ -138,15 +136,9 @@ int saveenv(void) if (init_mmc_for_env(mmc)) return 1; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - ret = 1; + ret = env_export(env_new); + if (ret) goto fini; - } - - env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); #ifdef CONFIG_ENV_OFFSET_REDUND env_new->flags = ++env_flags; /* increase the serial */ diff --git a/common/env_nand.c b/common/env_nand.c index 695a9eebb0..5a734a9321 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -181,8 +181,6 @@ int saveenv(void) { int ret = 0; ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; int env_idx = 0; static const struct env_location location[] = { { @@ -207,13 +205,10 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); + ret = env_export(env_new); + if (ret) + return ret; + #ifdef CONFIG_ENV_OFFSET_REDUND env_new->flags = ++env_flags; /* increase the serial */ env_idx = (gd->env_valid == 1); diff --git a/common/env_nvram.c b/common/env_nvram.c index 0866cde924..524f07d5f8 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -69,17 +69,11 @@ void env_relocate_spec(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; int rcode = 0; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + rcode = env_export(&env_new); + if (rcode) + return rcode; #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE); diff --git a/common/env_onenand.c b/common/env_onenand.c index 4b44632180..cc3d670de8 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -66,8 +66,7 @@ void env_relocate_spec(void) int saveenv(void) { env_t env_new; - ssize_t len; - char *res; + int ret; struct mtd_info *mtd = &onenand_mtd; #ifdef CONFIG_ENV_ADDR_FLEX struct onenand_chip *this = &onenand_chip; @@ -78,13 +77,9 @@ int saveenv(void) .callback = NULL, }; - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + ret = env_export(&env_new); + if (ret) + return ret; instr.len = CONFIG_ENV_SIZE; #ifdef CONFIG_ENV_ADDR_FLEX diff --git a/common/env_sf.c b/common/env_sf.c index be270f21bc..37ab13ae17 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -47,8 +47,7 @@ static struct spi_flash *env_flash; int saveenv(void) { env_t env_new; - ssize_t len; - char *res, *saved_buffer = NULL, flag = OBSOLETE_FLAG; + char *saved_buffer = NULL, flag = OBSOLETE_FLAG; u32 saved_size, saved_offset, sector = 1; int ret; @@ -62,13 +61,9 @@ int saveenv(void) } } - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + ret = env_export(&env_new); + if (ret) + return ret; env_new.flags = ACTIVE_FLAG; if (gd->env_valid == 1) { @@ -225,10 +220,9 @@ out: int saveenv(void) { u32 saved_size, saved_offset, sector = 1; - char *res, *saved_buffer = NULL; + char *saved_buffer = NULL; int ret = 1; env_t env_new; - ssize_t len; if (!env_flash) { env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, @@ -260,13 +254,9 @@ int saveenv(void) sector++; } - res = (char *)&env_new.data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); + ret = env_export(&env_new); + if (ret) goto done; - } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, diff --git a/common/env_ubi.c b/common/env_ubi.c index c0828a47d3..77bbfa6ef4 100644 --- a/common/env_ubi.c +++ b/common/env_ubi.c @@ -37,15 +37,11 @@ static unsigned char env_flags; int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; + int ret; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } + ret = env_export(env_new); + if (ret) + return ret; if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { printf("\n** Cannot find mtd partition \"%s\"\n", @@ -53,7 +49,6 @@ int saveenv(void) return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); env_new->flags = ++env_flags; /* increase the serial */ if (gd->env_valid == 1) { @@ -86,15 +81,11 @@ int saveenv(void) int saveenv(void) { ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); - ssize_t len; - char *res; + int ret; - res = (char *)&env_new->data; - len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); - if (len < 0) { - error("Cannot export environment: errno = %d\n", errno); - return 1; - } + ret = env_export(env_new); + if (ret) + return ret; if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { printf("\n** Cannot find mtd partition \"%s\"\n", @@ -102,8 +93,6 @@ int saveenv(void) return 1; } - env_new->crc = crc32(0, env_new->data, ENV_SIZE); - if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, CONFIG_ENV_SIZE)) { printf("\n** Unable to write env to %s:%s **\n", diff --git a/common/fdt_support.c b/common/fdt_support.c index f9f358e7e8..fcd252336c 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -50,6 +50,37 @@ static void write_cell(u8 *addr, u64 val, int size) } /** + * fdt_getprop_u32_default_node - Return a node's property or a default + * + * @fdt: ptr to device tree + * @off: offset of node + * @cell: cell offset in property + * @prop: property name + * @dflt: default value if the property isn't found + * + * Convenience function to return a node's property or a default value if + * the property doesn't exist. + */ +u32 fdt_getprop_u32_default_node(const void *fdt, int off, int cell, + const char *prop, const u32 dflt) +{ + const fdt32_t *val; + int len; + + val = fdt_getprop(fdt, off, prop, &len); + + /* Check if property exists */ + if (!val) + return dflt; + + /* Check if property is long enough */ + if (len < ((cell + 1) * sizeof(uint32_t))) + return dflt; + + return fdt32_to_cpu(*val); +} + +/** * fdt_getprop_u32_default - Find a node and return it's property or a default * * @fdt: ptr to device tree @@ -63,18 +94,13 @@ static void write_cell(u8 *addr, u64 val, int size) u32 fdt_getprop_u32_default(const void *fdt, const char *path, const char *prop, const u32 dflt) { - const fdt32_t *val; int off; off = fdt_path_offset(fdt, path); if (off < 0) return dflt; - val = fdt_getprop(fdt, off, prop, NULL); - if (val) - return fdt32_to_cpu(*val); - else - return dflt; + return fdt_getprop_u32_default_node(fdt, off, 0, prop, dflt); } /** @@ -1409,3 +1435,97 @@ u64 fdt_get_base_address(void *fdt, int node) return prop ? fdt_translate_address(fdt, node, prop + naddr) : 0; } + +/* + * Read a property of size <prop_len>. Currently only supports 1 or 2 cells. + */ +static int fdt_read_prop(const fdt32_t *prop, int prop_len, int cell_off, + uint64_t *val, int cells) +{ + const fdt32_t *prop32 = &prop[cell_off]; + const fdt64_t *prop64 = (const fdt64_t *)&prop[cell_off]; + + if ((cell_off + cells) > prop_len) + return -FDT_ERR_NOSPACE; + + switch (cells) { + case 1: + *val = fdt32_to_cpu(*prop32); + break; + case 2: + *val = fdt64_to_cpu(*prop64); + break; + default: + return -FDT_ERR_NOSPACE; + } + + return 0; +} + +/** + * fdt_read_range - Read a node's n'th range property + * + * @fdt: ptr to device tree + * @node: offset of node + * @n: range index + * @child_addr: pointer to storage for the "child address" field + * @addr: pointer to storage for the CPU view translated physical start + * @len: pointer to storage for the range length + * + * Convenience function that reads and interprets a specific range out of + * a number of the "ranges" property array. + */ +int fdt_read_range(void *fdt, int node, int n, uint64_t *child_addr, + uint64_t *addr, uint64_t *len) +{ + int pnode = fdt_parent_offset(fdt, node); + const fdt32_t *ranges; + int pacells; + int acells; + int scells; + int ranges_len; + int cell = 0; + int r = 0; + + /* + * The "ranges" property is an array of + * { <child address> <parent address> <size in child address space> } + * + * All 3 elements can span a diffent number of cells. Fetch their size. + */ + pacells = fdt_getprop_u32_default_node(fdt, pnode, 0, "#address-cells", 1); + acells = fdt_getprop_u32_default_node(fdt, node, 0, "#address-cells", 1); + scells = fdt_getprop_u32_default_node(fdt, node, 0, "#size-cells", 1); + + /* Now try to get the ranges property */ + ranges = fdt_getprop(fdt, node, "ranges", &ranges_len); + if (!ranges) + return -FDT_ERR_NOTFOUND; + ranges_len /= sizeof(uint32_t); + + /* Jump to the n'th entry */ + cell = n * (pacells + acells + scells); + + /* Read <child address> */ + if (child_addr) { + r = fdt_read_prop(ranges, ranges_len, cell, child_addr, + acells); + if (r) + return r; + } + cell += acells; + + /* Read <parent address> */ + if (addr) + *addr = fdt_translate_address(fdt, node, ranges + cell); + cell += pacells; + + /* Read <size in child address space> */ + if (len) { + r = fdt_read_prop(ranges, ranges_len, cell, len, scells); + if (r) + return r; + } + + return 0; +} diff --git a/common/hash.c b/common/hash.c index 872cd85428..7627b84b45 100644 --- a/common/hash.c +++ b/common/hash.c @@ -12,6 +12,7 @@ #include <common.h> #include <command.h> +#include <malloc.h> #include <hw_sha.h> #include <hash.h> #include <sha1.h> @@ -19,6 +20,88 @@ #include <asm/io.h> #include <asm/errno.h> +#ifdef CONFIG_CMD_SHA1SUM +static int hash_init_sha1(struct hash_algo *algo, void **ctxp) +{ + sha1_context *ctx = malloc(sizeof(sha1_context)); + sha1_starts(ctx); + *ctxp = ctx; + return 0; +} + +static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf, + unsigned int size, int is_last) +{ + sha1_update((sha1_context *)ctx, buf, size); + return 0; +} + +static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf, + int size) +{ + if (size < algo->digest_size) + return -1; + + sha1_finish((sha1_context *)ctx, dest_buf); + free(ctx); + return 0; +} +#endif + +#ifdef CONFIG_SHA256 +static int hash_init_sha256(struct hash_algo *algo, void **ctxp) +{ + sha256_context *ctx = malloc(sizeof(sha256_context)); + sha256_starts(ctx); + *ctxp = ctx; + return 0; +} + +static int hash_update_sha256(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, int is_last) +{ + sha256_update((sha256_context *)ctx, buf, size); + return 0; +} + +static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void + *dest_buf, int size) +{ + if (size < algo->digest_size) + return -1; + + sha256_finish((sha256_context *)ctx, dest_buf); + free(ctx); + return 0; +} +#endif + +static int hash_init_crc32(struct hash_algo *algo, void **ctxp) +{ + uint32_t *ctx = malloc(sizeof(uint32_t)); + *ctx = 0; + *ctxp = ctx; + return 0; +} + +static int hash_update_crc32(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, int is_last) +{ + *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size); + return 0; +} + +static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf, + int size) +{ + if (size < algo->digest_size) + return -1; + + *((uint32_t *)dest_buf) = *((uint32_t *)ctx); + free(ctx); + return 0; +} + /* * These are the hash algorithms we support. Chips which support accelerated * crypto could perhaps add named version of these algorithms here. Note that @@ -53,6 +136,9 @@ static struct hash_algo hash_algo[] = { SHA1_SUM_LEN, sha1_csum_wd, CHUNKSZ_SHA1, + hash_init_sha1, + hash_update_sha1, + hash_finish_sha1, }, #define MULTI_HASH #endif @@ -62,6 +148,9 @@ static struct hash_algo hash_algo[] = { SHA256_SUM_LEN, sha256_csum_wd, CHUNKSZ_SHA256, + hash_init_sha256, + hash_update_sha256, + hash_finish_sha256, }, #define MULTI_HASH #endif @@ -70,6 +159,9 @@ static struct hash_algo hash_algo[] = { 4, crc32_wd_buf, CHUNKSZ_CRC32, + hash_init_crc32, + hash_update_crc32, + hash_finish_crc32, }, }; @@ -204,16 +296,19 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum, return 0; } -static struct hash_algo *find_hash_algo(const char *name) +int hash_lookup_algo(const char *algo_name, struct hash_algo **algop) { int i; for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { - if (!strcmp(name, hash_algo[i].name)) - return &hash_algo[i]; + if (!strcmp(algo_name, hash_algo[i].name)) { + *algop = &hash_algo[i]; + return 0; + } } - return NULL; + debug("Unknown hash algorithm '%s'\n", algo_name); + return -EPROTONOSUPPORT; } static void show_hash(struct hash_algo *algo, ulong addr, ulong len, @@ -230,12 +325,12 @@ int hash_block(const char *algo_name, const void *data, unsigned int len, uint8_t *output, int *output_size) { struct hash_algo *algo; + int ret; + + ret = hash_lookup_algo(algo_name, &algo); + if (ret) + return ret; - algo = find_hash_algo(algo_name); - if (!algo) { - debug("Unknown hash algorithm '%s'\n", algo_name); - return -EPROTONOSUPPORT; - } if (output_size && *output_size < algo->digest_size) { debug("Output buffer size %d too small (need %d bytes)", *output_size, algo->digest_size); @@ -265,8 +360,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, u8 vsum[HASH_MAX_DIGEST_SIZE]; void *buf; - algo = find_hash_algo(algo_name); - if (!algo) { + if (hash_lookup_algo(algo_name, &algo)) { printf("Unknown hash algorithm '%s'\n", algo_name); return CMD_RET_USAGE; } diff --git a/common/image-fit.c b/common/image-fit.c index b94a3fe86d..77f32bce31 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -22,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR; #include <bootstage.h> #include <sha1.h> +#include <sha256.h> #include <u-boot/crc.h> #include <u-boot/md5.h> @@ -882,6 +883,10 @@ int calculate_hash(const void *data, int data_len, const char *algo, sha1_csum_wd((unsigned char *)data, data_len, (unsigned char *)value, CHUNKSZ_SHA1); *value_len = 20; + } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) { + sha256_csum_wd((unsigned char *)data, data_len, + (unsigned char *)value, CHUNKSZ_SHA256); + *value_len = SHA256_SUM_LEN; } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) { md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5); *value_len = 16; diff --git a/common/image-sig.c b/common/image-sig.c index 973b06d505..72284eb1d1 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -14,16 +14,79 @@ DECLARE_GLOBAL_DATA_PTR; #endif /* !USE_HOSTCC*/ #include <image.h> #include <rsa.h> +#include <rsa-checksum.h> #define IMAGE_MAX_HASHED_NODES 100 +#ifdef USE_HOSTCC +void *host_blob; +void image_set_host_blob(void *blob) +{ + host_blob = blob; +} +void *image_get_host_blob(void) +{ + return host_blob; +} +#endif + +struct checksum_algo checksum_algos[] = { + { + "sha1", + SHA1_SUM_LEN, + RSA2048_BYTES, +#if IMAGE_ENABLE_SIGN + EVP_sha1, +#endif + sha1_calculate, + padding_sha1_rsa2048, + }, + { + "sha256", + SHA256_SUM_LEN, + RSA2048_BYTES, +#if IMAGE_ENABLE_SIGN + EVP_sha256, +#endif + sha256_calculate, + padding_sha256_rsa2048, + }, + { + "sha256", + SHA256_SUM_LEN, + RSA4096_BYTES, +#if IMAGE_ENABLE_SIGN + EVP_sha256, +#endif + sha256_calculate, + padding_sha256_rsa4096, + } + +}; + struct image_sig_algo image_sig_algos[] = { { "sha1,rsa2048", rsa_sign, rsa_add_verify_data, rsa_verify, + &checksum_algos[0], + }, + { + "sha256,rsa2048", + rsa_sign, + rsa_add_verify_data, + rsa_verify, + &checksum_algos[1], + }, + { + "sha256,rsa4096", + rsa_sign, + rsa_add_verify_data, + rsa_verify, + &checksum_algos[2], } + }; struct image_sig_algo *image_get_sig_algo(const char *name) diff --git a/common/main.c b/common/main.c index 8b6f274fa2..e54f63b956 100644 --- a/common/main.c +++ b/common/main.c @@ -427,6 +427,12 @@ void main_loop(void) bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); +#ifndef CONFIG_SYS_GENERIC_BOARD + puts("Warning: Your board does not use generic board. Please read\n"); + puts("doc/README.generic-board and take action. Boards not\n"); + puts("upgraded by the late 2014 may break or be removed.\n"); +#endif + #ifdef CONFIG_MODEM_SUPPORT debug("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init); if (do_mdm_init) { diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index 9da021862e..062461b2b6 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -76,7 +76,7 @@ void spl_nand_load_image(void) #endif /* Load u-boot */ nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + sizeof(*header), (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, spl_image.size, (void *)spl_image.load_addr); diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 1ad67caf13..0b77c16c5f 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -91,6 +91,12 @@ static const unsigned char usb_kbd_arrow[] = { #define USB_KBD_LEDMASK \ (USB_KBD_NUMLOCK | USB_KBD_CAPSLOCK | USB_KBD_SCROLLLOCK) +/* + * USB Keyboard reports are 8 bytes in boot protocol. + * Appendix B of HID Device Class Definition 1.11 + */ +#define USB_KBD_BOOT_REPORT_SIZE 8 + struct usb_kbd_pdata { uint32_t repeat_delay; @@ -99,7 +105,7 @@ struct usb_kbd_pdata { uint8_t usb_kbd_buffer[USB_KBD_BUFFER_LEN]; uint8_t *new; - uint8_t old[8]; + uint8_t old[USB_KBD_BOOT_REPORT_SIZE]; uint8_t flags; }; @@ -131,7 +137,8 @@ void usb_kbd_generic_poll(void) /* Submit a interrupt transfer request */ maxp = usb_maxpacket(usb_kbd_dev, pipe); usb_submit_int_msg(usb_kbd_dev, pipe, data->new, - maxp > 8 ? 8 : maxp, ep->bInterval); + min(maxp, USB_KBD_BOOT_REPORT_SIZE), + ep->bInterval); } /* Puts character in the queue and sets up the in and out pointer. */ @@ -266,8 +273,11 @@ static uint32_t usb_kbd_service_key(struct usb_device *dev, int i, int up) old = data->old; } - if ((old[i] > 3) && (memscan(new + 2, old[i], 6) == new + 8)) + if ((old[i] > 3) && + (memscan(new + 2, old[i], USB_KBD_BOOT_REPORT_SIZE - 2) == + new + USB_KBD_BOOT_REPORT_SIZE)) { res |= usb_kbd_translate(data, old[i], data->new[0], up); + } return res; } @@ -285,7 +295,7 @@ static int usb_kbd_irq_worker(struct usb_device *dev) else if ((data->new[0] == LEFT_CNTR) || (data->new[0] == RIGHT_CNTR)) data->flags |= USB_KBD_CTRL; - for (i = 2; i < 8; i++) { + for (i = 2; i < USB_KBD_BOOT_REPORT_SIZE; i++) { res |= usb_kbd_service_key(dev, i, 0); res |= usb_kbd_service_key(dev, i, 1); } @@ -297,7 +307,7 @@ static int usb_kbd_irq_worker(struct usb_device *dev) if (res == 1) usb_kbd_setled(dev); - memcpy(data->old, data->new, 8); + memcpy(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE); return 1; } @@ -305,7 +315,8 @@ static int usb_kbd_irq_worker(struct usb_device *dev) /* Keyboard interrupt handler */ static int usb_kbd_irq(struct usb_device *dev) { - if ((dev->irq_status != 0) || (dev->irq_act_len != 8)) { + if ((dev->irq_status != 0) || + (dev->irq_act_len != USB_KBD_BOOT_REPORT_SIZE)) { debug("USB KBD: Error %lX, len %d\n", dev->irq_status, dev->irq_act_len); return 1; @@ -333,7 +344,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) /* Submit a interrupt transfer request */ maxp = usb_maxpacket(dev, pipe); usb_submit_int_msg(dev, pipe, &data->new[0], - maxp > 8 ? 8 : maxp, ep->bInterval); + min(maxp, USB_KBD_BOOT_REPORT_SIZE), + ep->bInterval); usb_kbd_irq_worker(dev); #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) @@ -341,8 +353,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev) struct usb_kbd_pdata *data = dev->privptr; iface = &dev->config.if_desc[0]; usb_get_report(dev, iface->desc.bInterfaceNumber, - 1, 0, data->new, sizeof(data->new)); - if (memcmp(data->old, data->new, sizeof(data->new))) + 1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE); + if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE)) usb_kbd_irq_worker(dev); #endif } @@ -441,7 +453,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) memset(data, 0, sizeof(struct usb_kbd_pdata)); /* allocate input buffer aligned and sized to USB DMA alignment */ - data->new = memalign(USB_DMA_MINALIGN, roundup(8, USB_DMA_MINALIGN)); + data->new = memalign(USB_DMA_MINALIGN, + roundup(USB_KBD_BOOT_REPORT_SIZE, USB_DMA_MINALIGN)); /* Insert private data into USB device structure */ dev->privptr = data; @@ -459,7 +472,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0); debug("USB KBD: enable interrupt pipe...\n"); - if (usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp, + if (usb_submit_int_msg(dev, pipe, data->new, + min(maxp, USB_KBD_BOOT_REPORT_SIZE), ep->bInterval) < 0) { printf("Failed to get keyboard state from device %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); |