diff options
394 files changed, 5501 insertions, 4624 deletions
@@ -3494,6 +3494,10 @@ FIT uImage format: without a fastmap. default: 0 + CONFIG_MTD_UBI_FM_DEBUG + Enable UBI fastmap debug + default: 0 + - UBIFS support CONFIG_CMD_UBIFS diff --git a/arch/Kconfig b/arch/Kconfig index 4f738195d85..25dcf4a1a3b 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -24,6 +24,7 @@ config ARM select CREATE_ARCH_SYMLINK select HAVE_PRIVATE_LIBGCC if !ARM64 select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD select SUPPORT_OF_CONTROL config AVR32 @@ -63,6 +64,10 @@ config NIOS2 bool "Nios II architecture" select HAVE_GENERIC_BOARD select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL + select OF_CONTROL + select DM + select CPU config OPENRISC bool "OpenRISC architecture" @@ -71,6 +76,7 @@ config PPC bool "PowerPC architecture" select HAVE_PRIVATE_LIBGCC select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD select SUPPORT_OF_CONTROL config SANDBOX diff --git a/arch/arm/include/asm/arch-lpc32xx/config.h b/arch/arm/include/asm/arch-lpc32xx/config.h index 2d082ef40d8..845ba4f6064 100644 --- a/arch/arm/include/asm/arch-lpc32xx/config.h +++ b/arch/arm/include/asm/arch-lpc32xx/config.h @@ -9,7 +9,6 @@ #ifndef _LPC32XX_CONFIG_H #define _LPC32XX_CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD /* Basic CPU architecture */ #define CONFIG_ARCH_CPU_INIT diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index 4c3a94af572..80548ebbf6d 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -82,31 +82,11 @@ ENTRY(_main) #else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ #endif - mov r2, sp - sub sp, sp, #GD_SIZE /* allocate one GD above SP */ -#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ - mov r3, sp - bic r3, r3, #7 - mov sp, r3 -#else - bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ -#endif - mov r9, sp /* GD is above SP */ - mov r1, sp + mov r0, sp + bl board_init_f_mem + mov sp, r0 + mov r0, #0 -clr_gd: - cmp r1, r2 /* while not at end of GD */ -#if defined(CONFIG_CPU_V7M) - itt lo -#endif - strlo r0, [r1] /* clear 32-bit GD word */ - addlo r1, r1, #4 /* move to next */ - blo clr_gd -#if defined(CONFIG_SYS_MALLOC_F_LEN) - sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN - str sp, [r9, #GD_MALLOC_BASE] -#endif - /* mov r0, #0 not needed due to above code */ bl board_init_f #if ! defined(CONFIG_SPL_BUILD) diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 8b34e04dada..cef1c7171c6 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -74,19 +74,10 @@ ENTRY(_main) #else ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) #endif - sub x18, x0, #GD_SIZE /* allocate one GD above SP */ - bic x18, x18, #0x7 /* 8-byte alignment for GD */ -zero_gd: - sub x0, x0, #0x8 - str xzr, [x0] - cmp x0, x18 - b.gt zero_gd -#if defined(CONFIG_SYS_MALLOC_F_LEN) - ldr x0, =CONFIG_SYS_MALLOC_F_LEN - sub x0, x18, x0 - str x0, [x18, #GD_MALLOC_BASE] -#endif bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */ + bl board_init_f_mem + mov sp, x0 + mov x0, #0 bl board_init_f diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c index e7df6d3d7b1..7bdac3b12d9 100644 --- a/arch/arm/mach-zynq/spl.c +++ b/arch/arm/mach-zynq/spl.c @@ -20,7 +20,6 @@ void board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - preloader_console_init(); arch_cpu_init(); board_init_r(NULL, 0); } @@ -28,6 +27,7 @@ void board_init_f(ulong dummy) #ifdef CONFIG_SPL_BOARD_INIT void spl_board_init(void) { + preloader_console_init(); board_init(); } #endif diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 953d3a15eef..14f46a8f046 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -25,6 +25,7 @@ _start: addi r8, r0, __end mts rslr, r8 + /* TODO: Redo this code to call board_init_f_mem() */ #if defined(CONFIG_SPL_BUILD) addi r1, r0, CONFIG_SPL_STACK_ADDR mts rshr, r1 @@ -141,6 +142,7 @@ _start: ori r12, r12, 0x1a0 mts rmsr, r12 + /* TODO: Redo this code to call board_init_f_mem() */ clear_bss: /* clear BSS segments */ addi r5, r0, __bss_start diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index 8ae7f6edd37..bb4fb2ac3a5 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -4,15 +4,11 @@ menu "Nios II architecture" config SYS_ARCH default "nios2" -choice - prompt "Target select" - optional - -config TARGET_NIOS2_GENERIC - bool "Support nios2-generic" - -endchoice - -source "board/altera/nios2-generic/Kconfig" +config SYS_CONFIG_NAME + string "Board header file" + help + This option should contain the base name of board header file. + The header file include/configs/<CONFIG_SYS_CONFIG_NAME>.h + should be included from include/config.h. endmenu diff --git a/arch/nios2/cpu/Makefile b/arch/nios2/cpu/Makefile index 3fe7847160d..185ca3cdb76 100644 --- a/arch/nios2/cpu/Makefile +++ b/arch/nios2/cpu/Makefile @@ -7,5 +7,5 @@ extra-y = start.o obj-y = exceptions.o -obj-y += cpu.o interrupts.o sysid.o traps.o +obj-y += cpu.o interrupts.o traps.o obj-y += fdt.o diff --git a/arch/nios2/cpu/cpu.c b/arch/nios2/cpu/cpu.c index 39ae97221c2..ff0fa20798f 100644 --- a/arch/nios2/cpu/cpu.c +++ b/arch/nios2/cpu/cpu.c @@ -6,25 +6,18 @@ */ #include <common.h> -#include <asm/nios2.h> +#include <cpu.h> +#include <dm.h> +#include <errno.h> #include <asm/cache.h> DECLARE_GLOBAL_DATA_PTR; -#if defined (CONFIG_SYS_NIOS_SYSID_BASE) -extern void display_sysid (void); -#endif /* CONFIG_SYS_NIOS_SYSID_BASE */ - #ifdef CONFIG_DISPLAY_CPUINFO int print_cpuinfo(void) { - printf ("CPU : Nios-II\n"); -#if !defined(CONFIG_SYS_NIOS_SYSID_BASE) - printf ("SYSID : <unknown>\n"); -#else - display_sysid (); -#endif - return (0); + printf("CPU: Nios-II\n"); + return 0; } #endif /* CONFIG_DISPLAY_CPUINFO */ @@ -32,29 +25,120 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { disable_interrupts(); /* indirect call to go beyond 256MB limitation of toolchain */ - nios2_callr(CONFIG_SYS_RESET_ADDR); + nios2_callr(gd->arch.reset_addr); return 0; } -int dcache_status(void) +/* + * COPY EXCEPTION TRAMPOLINE -- copy the tramp to the + * exception address. Define CONFIG_ROM_STUBS to prevent + * the copy (e.g. exception in flash or in other + * softare/firmware component). + */ +#ifndef CONFIG_ROM_STUBS +static void copy_exception_trampoline(void) { - return 1; + extern int _except_start, _except_end; + void *except_target = (void *)gd->arch.exception_addr; + + if (&_except_start != except_target) { + memcpy(except_target, &_except_start, + &_except_end - &_except_start); + flush_cache(gd->arch.exception_addr, + &_except_end - &_except_start); + } } +#endif -void dcache_enable(void) +int arch_cpu_init_dm(void) { - flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE); + struct udevice *dev; + int ret; + + ret = uclass_first_device(UCLASS_CPU, &dev); + if (ret) + return ret; + if (!dev) + return -ENODEV; + + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; +#ifndef CONFIG_ROM_STUBS + copy_exception_trampoline(); +#endif + + return 0; } -void dcache_disable(void) +static int altera_nios2_get_desc(struct udevice *dev, char *buf, int size) { - flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE); + const char *cpu_name = "Nios-II"; + + if (size < strlen(cpu_name)) + return -ENOSPC; + strcpy(buf, cpu_name); + + return 0; } -int arch_cpu_init(void) +static int altera_nios2_get_info(struct udevice *dev, struct cpu_info *info) { - gd->cpu_clk = CONFIG_SYS_CLK_FREQ; - gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + info->cpu_freq = gd->cpu_clk; + info->features = (1 << CPU_FEAT_L1_CACHE) | + (gd->arch.has_mmu ? (1 << CPU_FEAT_MMU) : 0); return 0; } + +static int altera_nios2_get_count(struct udevice *dev) +{ + return 1; +} + +static int altera_nios2_probe(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + + gd->cpu_clk = fdtdec_get_int(blob, node, + "clock-frequency", 0); + gd->arch.dcache_line_size = fdtdec_get_int(blob, node, + "dcache-line-size", 0); + gd->arch.icache_line_size = fdtdec_get_int(blob, node, + "icache-line-size", 0); + gd->arch.dcache_size = fdtdec_get_int(blob, node, + "dcache-size", 0); + gd->arch.icache_size = fdtdec_get_int(blob, node, + "icache-size", 0); + gd->arch.reset_addr = fdtdec_get_int(blob, node, + "altr,reset-addr", 0); + gd->arch.exception_addr = fdtdec_get_int(blob, node, + "altr,exception-addr", 0); + gd->arch.has_initda = fdtdec_get_int(blob, node, + "altr,has-initda", 0); + gd->arch.has_mmu = fdtdec_get_int(blob, node, + "altr,has-mmu", 0); + gd->arch.io_region_base = gd->arch.has_mmu ? 0xe0000000 : 0x8000000; + + return 0; +} + +static const struct cpu_ops altera_nios2_ops = { + .get_desc = altera_nios2_get_desc, + .get_info = altera_nios2_get_info, + .get_count = altera_nios2_get_count, +}; + +static const struct udevice_id altera_nios2_ids[] = { + { .compatible = "altr,nios2-1.0" }, + { .compatible = "altr,nios2-1.1" }, + { } +}; + +U_BOOT_DRIVER(altera_nios2) = { + .name = "altera_nios2", + .id = UCLASS_CPU, + .of_match = altera_nios2_ids, + .probe = altera_nios2_probe, + .ops = &altera_nios2_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/arch/nios2/cpu/interrupts.c b/arch/nios2/cpu/interrupts.c index 9d7e193e284..1599674353c 100644 --- a/arch/nios2/cpu/interrupts.c +++ b/arch/nios2/cpu/interrupts.c @@ -8,43 +8,14 @@ * SPDX-License-Identifier: GPL-2.0+ */ - +#include <common.h> +#include <command.h> #include <asm/nios2.h> #include <asm/types.h> #include <asm/io.h> #include <asm/ptrace.h> -#include <common.h> -#include <command.h> -#include <watchdog.h> -#ifdef CONFIG_STATUS_LED -#include <status_led.h> -#endif - -typedef volatile struct { - unsigned status; /* Timer status reg */ - unsigned control; /* Timer control reg */ - unsigned periodl; /* Timeout period low */ - unsigned periodh; /* Timeout period high */ - unsigned snapl; /* Snapshot low */ - unsigned snaph; /* Snapshot high */ -} nios_timer_t; - -/* status register */ -#define NIOS_TIMER_TO (1 << 0) /* Timeout */ -#define NIOS_TIMER_RUN (1 << 1) /* Timer running */ - -/* control register */ -#define NIOS_TIMER_ITO (1 << 0) /* Timeout int ena */ -#define NIOS_TIMER_CONT (1 << 1) /* Continuous mode */ -#define NIOS_TIMER_START (1 << 2) /* Start timer */ -#define NIOS_TIMER_STOP (1 << 3) /* Stop timer */ - -#if defined(CONFIG_SYS_NIOS_TMRBASE) && !defined(CONFIG_SYS_NIOS_TMRIRQ) -#error CONFIG_SYS_NIOS_TMRIRQ not defined (see documentation) -#endif - -/****************************************************************************/ +/*************************************************************************/ struct irq_action { interrupt_handler_t *handler; void *arg; @@ -53,111 +24,6 @@ struct irq_action { static struct irq_action vecs[32]; -/*************************************************************************/ -volatile ulong timestamp = 0; - -void reset_timer (void) -{ - nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; - - /* From Embedded Peripherals Handbook: - * - * "When the hardware is configured with Writeable period - * disabled, writing to one of the period_n registers causes - * the counter to reset to the fixed Timeout Period specified - * at system generation time." - * - * Here we force a reload to prevent early timeouts from - * get_timer() when the interrupt period is greater than - * than 1 msec. - * - * Simply write to periodl with its own value to force an - * internal counter reload, THEN reset the timestamp. - */ - writel (readl (&tmr->periodl), &tmr->periodl); - timestamp = 0; - - /* From Embedded Peripherals Handbook: - * - * "Writing to one of the period_n registers stops the internal - * counter, except when the hardware is configured with Start/Stop - * control bits off. If Start/Stop control bits is off, writing - * either register does not stop the counter." - * - * In order to accomodate either configuration, the control - * register is re-written. If the counter is stopped, it will - * be restarted. If it is running, the write is essentially - * a nop. - */ - writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, - &tmr->control); - -} - -ulong get_timer (ulong base) -{ - WATCHDOG_RESET (); - return (timestamp - base); -} - -/* - * This function is derived from Blackfin code (read timebase as long long). - * On Nios2 it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from Blackfin code. - * On Nios2 it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} - -/* The board must handle this interrupt if a timer is not - * provided. - */ -#if defined(CONFIG_SYS_NIOS_TMRBASE) -void tmr_isr (void *arg) -{ - nios_timer_t *tmr = (nios_timer_t *)arg; - /* Interrupt is cleared by writing anything to the - * status register. - */ - writel (0, &tmr->status); - timestamp += CONFIG_SYS_NIOS_TMRMS; -#ifdef CONFIG_STATUS_LED - status_led_tick(timestamp); -#endif -} - -static void tmr_init (void) -{ - nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE; - - writel (0, &tmr->status); - writel (0, &tmr->control); - writel (NIOS_TIMER_STOP, &tmr->control); - -#if defined(CONFIG_SYS_NIOS_TMRCNT) - writel (CONFIG_SYS_NIOS_TMRCNT & 0xffff, &tmr->periodl); - writel ((CONFIG_SYS_NIOS_TMRCNT >> 16) & 0xffff, &tmr->periodh); -#endif - writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START, - &tmr->control); - irq_install_handler (CONFIG_SYS_NIOS_TMRIRQ, tmr_isr, (void *)tmr); -} - -#endif /* CONFIG_SYS_NIOS_TMRBASE */ - -/*************************************************************************/ int disable_interrupts (void) { int val = rdctl (CTL_STATUS); @@ -245,10 +111,6 @@ int interrupt_init (void) vecs[i].count = 0; } -#if defined(CONFIG_SYS_NIOS_TMRBASE) - tmr_init (); -#endif - enable_interrupts (); return (0); } diff --git a/arch/nios2/cpu/start.S b/arch/nios2/cpu/start.S index 6af9b4e9433..8758e7e847a 100644 --- a/arch/nios2/cpu/start.S +++ b/arch/nios2/cpu/start.S @@ -9,30 +9,38 @@ #include <config.h> #include <version.h> -/************************************************************************* - * RESTART - ************************************************************************/ +/* + * icache and dcache configuration used only for start.S. + * the values are chosen so that it will work for all configuration. + */ +#define ICACHE_LINE_SIZE 32 /* fixed 32 */ +#define ICACHE_SIZE_MAX 0x10000 /* 64k max */ +#define DCACHE_LINE_SIZE_MIN 4 /* 4, 16, 32 */ +#define DCACHE_SIZE_MAX 0x10000 /* 64k max */ + /* RESTART */ .text - .global _start + .global _start, _except_start, _except_end _start: wrctl status, r0 /* Disable interrupts */ - /* ICACHE INIT -- only the icache line at the reset address + /* + * ICACHE INIT -- only the icache line at the reset address * is invalidated at reset. So the init must stay within * the cache line size (8 words). If GERMS is used, we'll * just be invalidating the cache a second time. If cache * is not implemented initi behaves as nop. */ - ori r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE) - movhi r5, %hi(CONFIG_SYS_ICACHE_SIZE) - ori r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE) + ori r4, r0, %lo(ICACHE_LINE_SIZE) + movhi r5, %hi(ICACHE_SIZE_MAX) + ori r5, r5, %lo(ICACHE_SIZE_MAX) 0: initi r5 sub r5, r5, r4 bgt r5, r0, 0b br _except_end /* Skip the tramp */ - /* EXCEPTION TRAMPOLINE -- the following gets copied + /* + * EXCEPTION TRAMPOLINE -- the following gets copied * to the exception address (below), but is otherwise at the * default exception vector offset (0x0020). */ @@ -42,24 +50,26 @@ _except_start: jmp et _except_end: - /* INTERRUPTS -- for now, all interrupts masked and globally + /* + * INTERRUPTS -- for now, all interrupts masked and globally * disabled. */ wrctl ienable, r0 /* All disabled */ - /* DCACHE INIT -- if dcache not implemented, initd behaves as + /* + * DCACHE INIT -- if dcache not implemented, initd behaves as * nop. */ - movhi r4, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE) - movhi r5, %hi(CONFIG_SYS_DCACHE_SIZE) - ori r5, r5, %lo(CONFIG_SYS_DCACHE_SIZE) + ori r4, r0, %lo(DCACHE_LINE_SIZE_MIN) + movhi r5, %hi(DCACHE_SIZE_MAX) + ori r5, r5, %lo(DCACHE_SIZE_MAX) mov r6, r0 1: initd 0(r6) add r6, r6, r4 bltu r6, r5, 1b - /* RELOCATE CODE, DATA & COMMAND TABLE -- the following code + /* + * RELOCATE CODE, DATA & COMMAND TABLE -- the following code * assumes code, data and the command table are all * contiguous. This lets us relocate everything as a single * block. Make sure the linker script matches this ;-) @@ -73,8 +83,9 @@ _cur: movhi r5, %hi(_cur - _start) ori r5, r5, %lo(_start) /* r5 <- linked _start */ beq r4, r5, 3f - movhi r6, %hi(_edata) - ori r6, r6, %lo(_edata) + movhi r6, %hi(CONFIG_SYS_MONITOR_LEN) + ori r6, r6, %lo(CONFIG_SYS_MONITOR_LEN) + add r6, r6, r5 2: ldwio r7, 0(r4) addi r4, r4, 4 stwio r7, 0(r5) @@ -82,50 +93,13 @@ _cur: movhi r5, %hi(_cur - _start) bne r5, r6, 2b 3: - /* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent - * and between __bss_start and __bss_end. - */ - movhi r5, %hi(__bss_start) - ori r5, r5, %lo(__bss_start) - movhi r6, %hi(__bss_end) - ori r6, r6, %lo(__bss_end) - beq r5, r6, 5f - -4: stwio r0, 0(r5) - addi r5, r5, 4 - bne r5, r6, 4b -5: - /* JUMP TO RELOC ADDR */ movhi r4, %hi(_reloc) ori r4, r4, %lo(_reloc) jmp r4 _reloc: - /* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the - * exception address. Define CONFIG_ROM_STUBS to prevent - * the copy (e.g. exception in flash or in other - * softare/firmware component). - */ -#if !defined(CONFIG_ROM_STUBS) - movhi r4, %hi(_except_start) - ori r4, r4, %lo(_except_start) - movhi r5, %hi(_except_end) - ori r5, r5, %lo(_except_end) - movhi r6, %hi(CONFIG_SYS_EXCEPTION_ADDR) - ori r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR) - beq r4, r6, 7f /* Skip if at proper addr */ - -6: ldwio r7, 0(r4) - stwio r7, 0(r6) - addi r4, r4, 4 - addi r6, r6, 4 - bne r4, r5, 6b -7: -#endif - - /* STACK INIT -- zero top two words for call back chain. - */ + /* STACK INIT -- zero top two words for call back chain. */ movhi sp, %hi(CONFIG_SYS_INIT_SP) ori sp, sp, %lo(CONFIG_SYS_INIT_SP) addi sp, sp, -8 @@ -133,80 +107,64 @@ _reloc: stw r0, 4(sp) mov fp, sp - /* - * Call board_init_f -- never returns - */ + /* Allocate and zero GD, update SP */ + mov r4, sp + movhi r2, %hi(board_init_f_mem@h) + ori r2, r2, %lo(board_init_f_mem@h) + callr r2 + + /* Update stack- and frame-pointers */ + mov sp, r2 + mov fp, sp + + /* Call board_init_f -- never returns */ mov r4, r0 movhi r2, %hi(board_init_f@h) ori r2, r2, %lo(board_init_f@h) callr r2 - /* NEVER RETURNS -- but branch to the _start just + /* + * NEVER RETURNS -- but branch to the _start just * in case ;-) */ br _start - - -/* - * relocate_code -- Nios2 handles the relocation above. But - * the generic board code monkeys with the heap, stack, etc. - * (it makes some assumptions that may not be appropriate - * for Nios). Nevertheless, we capitulate here. - * - * We'll call the board_init_r from here since this isn't - * supposed to return. - * - * void relocate_code (ulong sp, gd_t *global_data, - * ulong reloc_addr) - * __attribute__ ((noreturn)); - */ + /* + * relocate_code -- Nios2 handles the relocation above. But + * the generic board code monkeys with the heap, stack, etc. + * (it makes some assumptions that may not be appropriate + * for Nios). Nevertheless, we capitulate here. + * + * We'll call the board_init_r from here since this isn't + * supposed to return. + * + * void relocate_code (ulong sp, gd_t *global_data, + * ulong reloc_addr) + * __attribute__ ((noreturn)); + */ .text .global relocate_code relocate_code: mov sp, r4 /* Set the new sp */ mov r4, r5 - movhi r8, %hi(board_init_r@h) - ori r8, r8, %lo(board_init_r@h) - callr r8 - ret -/* - * dly_clks -- Nios2 (like Nios1) doesn't have a timebase in - * the core. For simple delay loops, we do our best by counting - * instruction cycles. - * - * Instruction performance varies based on the core. For cores - * with icache and static/dynamic branch prediction (II/f, II/s): - * - * Normal ALU (e.g. add, cmp, etc): 1 cycle - * Branch (correctly predicted, taken): 2 cycles - * Negative offset is predicted (II/s). - * - * For cores without icache and no branch prediction (II/e): - * - * Normal ALU (e.g. add, cmp, etc): 6 cycles - * Branch (no prediction): 6 cycles - * - * For simplicity, if an instruction cache is implemented we - * assume II/f or II/s. Otherwise, we use the II/e. - * - */ - .globl dly_clks + /* + * ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent + * and between __bss_start and __bss_end. + */ + movhi r5, %hi(__bss_start) + ori r5, r5, %lo(__bss_start) + movhi r6, %hi(__bss_end) + ori r6, r6, %lo(__bss_end) + beq r5, r6, 5f -dly_clks: +4: stwio r0, 0(r5) + addi r5, r5, 4 + bne r5, r6, 4b +5: -#if (CONFIG_SYS_ICACHE_SIZE > 0) - subi r4, r4, 3 /* 3 clocks/loop */ -#else - subi r4, r4, 12 /* 12 clocks/loop */ -#endif - bge r4, r0, dly_clks + movhi r8, %hi(board_init_r@h) + ori r8, r8, %lo(board_init_r@h) + callr r8 ret - - .data - .globl version_string - -version_string: - .ascii U_BOOT_VERSION_STRING, "\0" diff --git a/arch/nios2/cpu/sysid.c b/arch/nios2/cpu/sysid.c deleted file mode 100644 index 50819b24249..00000000000 --- a/arch/nios2/cpu/sysid.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * (C) Copyright 2004, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> - -#if defined (CONFIG_SYS_NIOS_SYSID_BASE) - -#include <command.h> -#include <asm/io.h> -#include <linux/time.h> - -typedef volatile struct { - unsigned id; /* The system build id */ - unsigned timestamp; /* Timestamp */ -} nios_sysid_t; - -void display_sysid (void) -{ - nios_sysid_t *sysid = (nios_sysid_t *)CONFIG_SYS_NIOS_SYSID_BASE; - struct tm t; - char asc[32]; - time_t stamp; - - stamp = readl (&sysid->timestamp); - localtime_r (&stamp, &t); - asctime_r (&t, asc); - printf ("SYSID : %08lx, %s", readl (&sysid->id), asc); - -} - -int do_sysid (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - display_sysid (); - return (0); -} - -U_BOOT_CMD( - sysid, 1, 1, do_sysid, - "display Nios-II system id", - "" -); -#endif /* CONFIG_SYS_NIOS_SYSID_BASE */ diff --git a/arch/nios2/cpu/u-boot.lds b/arch/nios2/cpu/u-boot.lds index 6e174be2c0c..3bd3f2c520b 100644 --- a/arch/nios2/cpu/u-boot.lds +++ b/arch/nios2/cpu/u-boot.lds @@ -50,9 +50,11 @@ SECTIONS *(.gnu.linkonce.d*) } - . = ALIGN(16); - _gp = .; /* Global pointer addr */ - PROVIDE (gp = .); + /* + * gp - Since we don't use gp for small data with option "-G0", + * we will use gp as global data pointer. The _gp location is + * not needed. + */ .sdata : { @@ -65,6 +67,12 @@ SECTIONS _edata = .; PROVIDE (edata = .); + /* + * _end - This is end of u-boot.bin image. + * dtb will be appended here to make u-boot-dtb.bin + */ + _end = .; + /* UNINIT DATA - Small uninitialized data is first so it's * adjacent to sdata and can be referenced via gp. The normal * bss follows. We keep it adjacent to simplify init code. diff --git a/arch/nios2/dts/.gitignore b/arch/nios2/dts/.gitignore new file mode 100644 index 00000000000..b60ed208c77 --- /dev/null +++ b/arch/nios2/dts/.gitignore @@ -0,0 +1 @@ +*.dtb diff --git a/arch/nios2/dts/3c120_devboard.dts b/arch/nios2/dts/3c120_devboard.dts new file mode 100644 index 00000000000..a3cfacb98ab --- /dev/null +++ b/arch/nios2/dts/3c120_devboard.dts @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * This file is generated by sopc2dts. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/ { + model = "altr,qsys_ghrd_3c120"; + compatible = "altr,qsys_ghrd_3c120"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu: cpu@0x0 { + device_type = "cpu"; + compatible = "altr,nios2-1.0"; + reg = <0x00000000>; + interrupt-controller; + #interrupt-cells = <1>; + clock-frequency = <125000000>; + dcache-line-size = <32>; + icache-line-size = <32>; + dcache-size = <32768>; + icache-size = <32768>; + altr,implementation = "fast"; + altr,pid-num-bits = <8>; + altr,tlb-num-ways = <16>; + altr,tlb-num-entries = <128>; + altr,tlb-ptr-sz = <7>; + altr,has-div = <1>; + altr,has-mul = <1>; + altr,reset-addr = <0xc2800000>; + altr,fast-tlb-miss-addr = <0xc7fff400>; + altr,exception-addr = <0xd0000020>; + altr,has-initda = <1>; + altr,has-mmu = <1>; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x10000000 0x08000000>, + <0x07fff400 0x00000400>; + }; + + sopc@0 { + device_type = "soc"; + ranges; + #address-cells = <1>; + #size-cells = <1>; + compatible = "altr,avalon", "simple-bus"; + bus-frequency = <125000000>; + + pb_cpu_to_io: bridge@0x8000000 { + compatible = "simple-bus"; + reg = <0x08000000 0x00800000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x00002000 0x08002000 0x00002000>, + <0x00004000 0x08004000 0x00000400>, + <0x00004400 0x08004400 0x00000040>, + <0x00004800 0x08004800 0x00000040>, + <0x00004c80 0x08004c80 0x00000020>, + <0x00004cc0 0x08004cc0 0x00000010>, + <0x00004ce0 0x08004ce0 0x00000010>, + <0x00004d00 0x08004d00 0x00000010>, + <0x00004d40 0x08004d40 0x00000008>, + <0x00004d50 0x08004d50 0x00000008>, + <0x00008000 0x08008000 0x00000020>, + <0x00400000 0x08400000 0x00000020>; + + timer_1ms: timer@0x400000 { + compatible = "altr,timer-1.0"; + reg = <0x00400000 0x00000020>; + interrupt-parent = <&cpu>; + interrupts = <11>; + clock-frequency = <125000000>; + }; + + timer_0: timer@0x8000 { + compatible = "altr,timer-1.0"; + reg = < 0x00008000 0x00000020 >; + interrupt-parent = < &cpu >; + interrupts = < 5 >; + clock-frequency = < 125000000 >; + }; + + sysid: sysid@0x4d40 { + compatible = "altr,sysid-1.0"; + reg = <0x00004d40 0x00000008>; + }; + + jtag_uart: serial@0x4d50 { + compatible = "altr,juart-1.0"; + reg = <0x00004d50 0x00000008>; + interrupt-parent = <&cpu>; + interrupts = <1>; + }; + + tse_mac: ethernet@0x4000 { + compatible = "altr,tse-1.0"; + reg = <0x00004000 0x00000400>, + <0x00004400 0x00000040>, + <0x00004800 0x00000040>, + <0x00002000 0x00002000>; + reg-names = "control_port", "rx_csr", "tx_csr", "s1"; + interrupt-parent = <&cpu>; + interrupts = <2 3>; + interrupt-names = "rx_irq", "tx_irq"; + rx-fifo-depth = <8192>; + tx-fifo-depth = <8192>; + max-frame-size = <1518>; + local-mac-address = [ 00 00 00 00 00 00 ]; + phy-mode = "rgmii-id"; + phy-handle = <&phy0>; + tse_mac_mdio: mdio { + compatible = "altr,tse-mdio"; + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@18 { + reg = <18>; + device_type = "ethernet-phy"; + }; + }; + }; + + uart: serial@0x4c80 { + compatible = "altr,uart-1.0"; + reg = <0x00004c80 0x00000020>; + interrupt-parent = <&cpu>; + interrupts = <10>; + current-speed = <115200>; + clock-frequency = <62500000>; + }; + + user_led_pio_8out: gpio@0x4cc0 { + compatible = "altr,pio-1.0"; + reg = <0x00004cc0 0x00000010>; + resetvalue = <255>; + altr,gpio-bank-width = <8>; + #gpio-cells = <2>; + gpio-controller; + gpio-bank-name = "led"; + }; + + user_dipsw_pio_8in: gpio@0x4ce0 { + compatible = "altr,pio-1.0"; + reg = <0x00004ce0 0x00000010>; + interrupt-parent = <&cpu>; + interrupts = <8>; + edge_type = <2>; + level_trigger = <0>; + resetvalue = <0>; + altr,gpio-bank-width = <8>; + #gpio-cells = <2>; + gpio-controller; + gpio-bank-name = "dipsw"; + }; + + user_pb_pio_4in: gpio@0x4d00 { + compatible = "altr,pio-1.0"; + reg = <0x00004d00 0x00000010>; + interrupt-parent = <&cpu>; + interrupts = <9>; + edge_type = <2>; + level_trigger = <0>; + resetvalue = <0>; + altr,gpio-bank-width = <4>; + #gpio-cells = <2>; + gpio-controller; + gpio-bank-name = "pb"; + }; + }; + + cfi_flash_64m: flash@0x0 { + compatible = "cfi-flash"; + reg = <0x00000000 0x04000000>; + bank-width = <2>; + device-width = <1>; + #address-cells = <1>; + #size-cells = <1>; + + partition@800000 { + reg = <0x00800000 0x01e00000>; + label = "JFFS2 Filesystem"; + }; + }; + }; + + chosen { + bootargs = "debug console=ttyJ0,115200"; + stdout-path = &jtag_uart; + }; +}; diff --git a/arch/nios2/dts/Makefile b/arch/nios2/dts/Makefile new file mode 100644 index 00000000000..b40eca9e0af --- /dev/null +++ b/arch/nios2/dts/Makefile @@ -0,0 +1,11 @@ +dtb-y += $(CONFIG_DEFAULT_DEVICE_TREE:"%"=%).dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/arch/nios2/dts/include/dt-bindings b/arch/nios2/dts/include/dt-bindings new file mode 120000 index 00000000000..0cecb3d0805 --- /dev/null +++ b/arch/nios2/dts/include/dt-bindings @@ -0,0 +1 @@ +../../../../include/dt-bindings
\ No newline at end of file diff --git a/arch/nios2/include/asm/cache.h b/arch/nios2/include/asm/cache.h index 9b87c9f755f..dde43cd6fc7 100644 --- a/arch/nios2/include/asm/cache.h +++ b/arch/nios2/include/asm/cache.h @@ -8,18 +8,11 @@ #ifndef __ASM_NIOS2_CACHE_H_ #define __ASM_NIOS2_CACHE_H_ -extern void flush_dcache (unsigned long start, unsigned long size); -extern void flush_icache (unsigned long start, unsigned long size); - /* - * Valid L1 data cache line sizes for the NIOS2 architecture are 4, 16, and 32 - * bytes. If the board configuration has not specified one we default to the - * largest of these values for alignment of DMA buffers. + * Valid L1 data cache line sizes for the NIOS2 architecture are 4, + * 16, and 32 bytes. We default to the largest of these values for + * alignment of DMA buffers. */ -#ifdef CONFIG_SYS_CACHELINE_SIZE -#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE -#else #define ARCH_DMA_MINALIGN 32 -#endif #endif /* __ASM_NIOS2_CACHE_H_ */ diff --git a/arch/nios2/include/asm/config.h b/arch/nios2/include/asm/config.h index 9c13848ea2b..cd297347894 100644 --- a/arch/nios2/include/asm/config.h +++ b/arch/nios2/include/asm/config.h @@ -7,6 +7,4 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ -#define CONFIG_SYS_GENERIC_GLOBAL_DATA - #endif diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h index 1350e3b96fd..1562d35f0dc 100644 --- a/arch/nios2/include/asm/dma-mapping.h +++ b/arch/nios2/include/asm/dma-mapping.h @@ -1,23 +1,24 @@ #ifndef __ASM_NIOS2_DMA_MAPPING_H #define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <memalign.h> +#include <asm/io.h> + +/* + * dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. - * - * IO_REGION_BASE should be defined in board config header file - * 0x80000000 for nommu, 0xe0000000 for mmu */ - static inline void *dma_alloc_coherent(size_t len, unsigned long *handle) { - void *addr = malloc(len + CONFIG_SYS_DCACHELINE_SIZE); + unsigned long addr = (unsigned long)malloc_cache_aligned(len); + if (!addr) - return 0; - flush_dcache((unsigned long)addr, len + CONFIG_SYS_DCACHELINE_SIZE); - *handle = ((unsigned long)addr + - (CONFIG_SYS_DCACHELINE_SIZE - 1)) & - ~(CONFIG_SYS_DCACHELINE_SIZE - 1) & ~(IO_REGION_BASE); - return (void *)(*handle | IO_REGION_BASE); -} + return NULL; + + invalidate_dcache_range(addr, addr + len); + if (handle) + *handle = addr; + return ioremap(addr, len); +} #endif /* __ASM_NIOS2_DMA_MAPPING_H */ diff --git a/arch/nios2/include/asm/global_data.h b/arch/nios2/include/asm/global_data.h index 580b0199bb8..d6a2cfab4f9 100644 --- a/arch/nios2/include/asm/global_data.h +++ b/arch/nios2/include/asm/global_data.h @@ -9,6 +9,15 @@ /* Architecture-specific global data */ struct arch_global_data { + u32 dcache_line_size; + u32 icache_line_size; + u32 dcache_size; + u32 icache_size; + u32 reset_addr; + u32 exception_addr; + int has_initda; + int has_mmu; + u32 io_region_base; }; #include <asm-generic/global_data.h> diff --git a/arch/nios2/include/asm/gpio.h b/arch/nios2/include/asm/gpio.h index 908381f5f7b..306ab4c9f2a 100644 --- a/arch/nios2/include/asm/gpio.h +++ b/arch/nios2/include/asm/gpio.h @@ -1,79 +1 @@ -/* - * nios2 gpio driver - * - * This gpio core is described in http://nioswiki.com/GPIO - * bit[0] data - * bit[1] output enable - * - * When CONFIG_SYS_GPIO_BASE is not defined, the board may either - * provide its own driver or the altera_pio driver may be used. - * - * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _ASM_NIOS2_GPIO_H_ -#define _ASM_NIOS2_GPIO_H_ - -#ifdef CONFIG_SYS_GPIO_BASE -#include <asm/io.h> - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return 0; -} - -static inline int gpio_free(unsigned gpio) -{ - return 0; -} - -static inline int gpio_direction_input(unsigned gpio) -{ - writel(1, CONFIG_SYS_GPIO_BASE + (gpio << 2)); - return 0; -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2)); - return 0; -} - -static inline int gpio_get_value(unsigned gpio) -{ - return readl(CONFIG_SYS_GPIO_BASE + (gpio << 2)); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2)); -} - -static inline int gpio_is_valid(int number) -{ - return ((unsigned)number) < CONFIG_SYS_GPIO_WIDTH; -} -#else -#ifdef CONFIG_ALTERA_PIO -extern int altera_pio_init(u32 base, u8 width, char iot, - u32 rstval, u32 negmask, - const char *label); - -extern void altera_pio_info(void); -#define gpio_status() altera_pio_info() -#endif - -extern int gpio_request(unsigned gpio, const char *label); -extern int gpio_free(unsigned gpio); -extern int gpio_direction_input(unsigned gpio); -extern int gpio_direction_output(unsigned gpio, int value); -extern int gpio_get_value(unsigned gpio); -extern void gpio_set_value(unsigned gpio, int value); -extern int gpio_is_valid(int number); -#endif /* CONFIG_SYS_GPIO_BASE */ - -#endif /* _ASM_NIOS2_GPIO_H_ */ +#include <asm-generic/gpio.h> diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h index 69ab23e5f0a..e7da35b0c9e 100644 --- a/arch/nios2/include/asm/io.h +++ b/arch/nios2/include/asm/io.h @@ -39,12 +39,18 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) static inline phys_addr_t virt_to_phys(void * vaddr) { - return (phys_addr_t)(vaddr); + DECLARE_GLOBAL_DATA_PTR; + if (gd->arch.has_mmu) + return (phys_addr_t)vaddr & 0x1fffffff; + else + return (phys_addr_t)vaddr & 0x7fffffff; } -extern unsigned char inb (unsigned char *port); -extern unsigned short inw (unsigned short *port); -extern unsigned inl (unsigned port); +static inline void *ioremap(unsigned long physaddr, unsigned long size) +{ + DECLARE_GLOBAL_DATA_PTR; + return (void *)(gd->arch.io_region_base | physaddr); +} #define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v)) #define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v)) @@ -111,4 +117,59 @@ static inline void outsl (unsigned long port, const void *src, unsigned long cou while (count--) outl (*p++, port); } +/* + * Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define out_arch(type,endian,a,v) __raw_write##type(cpu_to_##endian(v),a) +#define in_arch(type,endian,a) endian##_to_cpu(__raw_read##type(a)) + +#define out_le32(a,v) out_arch(l,le32,a,v) +#define out_le16(a,v) out_arch(w,le16,a,v) + +#define in_le32(a) in_arch(l,le32,a) +#define in_le16(a) in_arch(w,le16,a) + +#define out_be32(a,v) out_arch(l,be32,a,v) +#define out_be16(a,v) out_arch(w,be16,a,v) + +#define in_be32(a) in_arch(l,be32,a) +#define in_be16(a) in_arch(w,be16,a) + +#define out_8(a,v) __raw_writeb(v,a) +#define in_8(a) __raw_readb(a) + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + #endif /* __ASM_NIOS2_IO_H_ */ diff --git a/arch/nios2/include/asm/psr.h b/arch/nios2/include/asm/psr.h deleted file mode 100644 index 3ebb2a011e5..00000000000 --- a/arch/nios2/include/asm/psr.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * (C) Copyright 2004, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_NIOS2_PSR_H_ -#define __ASM_NIOS2_PSR_H_ - - -#endif /* __ASM_NIOS2_PSR_H_ */ diff --git a/arch/nios2/include/asm/sections.h b/arch/nios2/include/asm/sections.h index f0da75dcf3e..2b8c5160388 100644 --- a/arch/nios2/include/asm/sections.h +++ b/arch/nios2/include/asm/sections.h @@ -1,11 +1 @@ -/* - * Copyright (c) 2012 The Chromium OS Authors. - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_NIOS2_SECTIONS_H -#define __ASM_NIOS2_SECTIONS_H - #include <asm-generic/sections.h> - -#endif diff --git a/arch/nios2/include/asm/system.h b/arch/nios2/include/asm/system.h index 6213a16eda9..b15853563e2 100644 --- a/arch/nios2/include/asm/system.h +++ b/arch/nios2/include/asm/system.h @@ -45,4 +45,6 @@ "callr %0" \ : : "r" (addr)) +void display_sysid(void); + #endif /* __ASM_NIOS2_SYSTEM_H */ diff --git a/arch/nios2/include/asm/unaligned.h b/arch/nios2/include/asm/unaligned.h index 779117c4bce..6cecbbb2111 100644 --- a/arch/nios2/include/asm/unaligned.h +++ b/arch/nios2/include/asm/unaligned.h @@ -1,6 +1 @@ -#ifndef _ASM_NIOS2_UNALIGNED_H -#define _ASM_NIOS2_UNALIGNED_H - #include <asm-generic/unaligned.h> - -#endif /* _ASM_NIOS2_UNALIGNED_H */ diff --git a/arch/nios2/lib/Makefile b/arch/nios2/lib/Makefile index 079378a9056..e35d2e92a29 100644 --- a/arch/nios2/lib/Makefile +++ b/arch/nios2/lib/Makefile @@ -8,4 +8,3 @@ obj-y += cache.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += libgcc.o -obj-y += time.o diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index c730a3fd08b..4e5c269193d 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -6,9 +6,6 @@ */ #include <common.h> -#include <command.h> -#include <asm/byteorder.h> -#include <asm/cache.h> #define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */ @@ -40,8 +37,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima /* flushes data and instruction caches before calling the kernel */ disable_interrupts(); - flush_dcache((ulong)kernel, CONFIG_SYS_DCACHE_SIZE); - flush_icache((ulong)kernel, CONFIG_SYS_ICACHE_SIZE); + flush_dcache_all(); debug("bootargs=%s @ 0x%lx\n", commandline, (ulong)&commandline); debug("initrd=0x%lx-0x%lx\n", (ulong)initrd_start, (ulong)initrd_end); diff --git a/arch/nios2/lib/cache.S b/arch/nios2/lib/cache.S deleted file mode 100644 index 683f005994b..00000000000 --- a/arch/nios2/lib/cache.S +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) Copyright 2004, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> - - .text - - .global flush_dcache - -flush_dcache: - add r5, r5, r4 - movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE) -0: flushd 0(r4) - add r4, r4, r8 - bltu r4, r5, 0b - ret - - - .global flush_icache - -flush_icache: - add r5, r5, r4 - movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE) -1: flushi r4 - add r4, r4, r8 - bltu r4, r5, 1b - ret - - .global flush_dcache_range - -flush_dcache_range: - movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE) -0: flushd 0(r4) - add r4, r4, r8 - bltu r4, r5, 0b - ret - - .global flush_cache - -flush_cache: - add r5, r5, r4 - mov r9, r4 - mov r10, r5 - - movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE) -0: flushd 0(r4) - add r4, r4, r8 - bltu r4, r5, 0b - - mov r4, r9 - mov r5, r10 - movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE) - ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE) -1: flushi r4 - add r4, r4, r8 - bltu r4, r5, 1b - - sync - flushp - ret diff --git a/arch/nios2/lib/cache.c b/arch/nios2/lib/cache.c new file mode 100644 index 00000000000..7c74e1adfed --- /dev/null +++ b/arch/nios2/lib/cache.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> + * Copyright (C) 2009, Wind River Systems Inc + * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/cache.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void __flush_dcache(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.dcache_line_size - 1); + end += (gd->arch.dcache_line_size - 1); + end &= ~(gd->arch.dcache_line_size - 1); + + for (addr = start; addr < end; addr += gd->arch.dcache_line_size) { + __asm__ __volatile__ (" flushda 0(%0)\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } +} + +static void __flush_dcache_all(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.dcache_line_size - 1); + end += (gd->arch.dcache_line_size - 1); + end &= ~(gd->arch.dcache_line_size - 1); + + if (end > start + gd->arch.dcache_size) + end = start + gd->arch.dcache_size; + + for (addr = start; addr < end; addr += gd->arch.dcache_line_size) { + __asm__ __volatile__ (" flushd 0(%0)\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } +} + +static void __invalidate_dcache(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.dcache_line_size - 1); + end += (gd->arch.dcache_line_size - 1); + end &= ~(gd->arch.dcache_line_size - 1); + + for (addr = start; addr < end; addr += gd->arch.dcache_line_size) { + __asm__ __volatile__ (" initda 0(%0)\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } +} + +static void __flush_icache(unsigned long start, unsigned long end) +{ + unsigned long addr; + + start &= ~(gd->arch.icache_line_size - 1); + end += (gd->arch.icache_line_size - 1); + end &= ~(gd->arch.icache_line_size - 1); + + if (end > start + gd->arch.icache_size) + end = start + gd->arch.icache_size; + + for (addr = start; addr < end; addr += gd->arch.icache_line_size) { + __asm__ __volatile__ (" flushi %0\n" + : /* Outputs */ + : /* Inputs */ "r"(addr) + /* : No clobber */); + } + __asm__ __volatile(" flushp\n"); +} + +void flush_dcache_all(void) +{ + __flush_dcache_all(0, gd->arch.dcache_size); + __flush_icache(0, gd->arch.icache_size); +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ + if (gd->arch.has_initda) + __flush_dcache(start, end); + else + __flush_dcache_all(start, end); +} + +void flush_cache(unsigned long start, unsigned long size) +{ + if (gd->arch.has_initda) + __flush_dcache(start, start + size); + else + __flush_dcache_all(start, start + size); + __flush_icache(start, start + size); +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ + if (gd->arch.has_initda) + __invalidate_dcache(start, end); + else + __flush_dcache_all(start, end); +} + +int dcache_status(void) +{ + return 1; +} + +void dcache_enable(void) +{ + flush_dcache_all(); +} + +void dcache_disable(void) +{ + flush_dcache_all(); +} diff --git a/arch/nios2/lib/time.c b/arch/nios2/lib/time.c deleted file mode 100644 index d39604579c1..00000000000 --- a/arch/nios2/lib/time.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * (C) Copyright 2003, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <watchdog.h> - - -extern void dly_clks( unsigned long ticks ); - -void __udelay(unsigned long usec) -{ - /* The Nios core doesn't have a timebase, so we do our - * best for now and call a low-level loop that counts - * cpu clocks. - */ - unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec; - dly_clks (cnt); -} diff --git a/board/altera/common/cfide.c b/board/altera/common/cfide.c deleted file mode 100644 index 40d6a12b55a..00000000000 --- a/board/altera/common/cfide.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Altera CF drvier - * - * (C) Copyright 2010, Thomas Chou <thomas@wytron.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <common.h> -#include <asm/io.h> - -#if defined(CONFIG_IDE_RESET) && defined(CONFIG_SYS_CF_CTL_BASE) -/* ide_set_reset for Altera CF interface */ -#define ALTERA_CF_CTL_STATUS 0 -#define ALTERA_CF_IDE_CTL 4 -#define ALTERA_CF_CTL_STATUS_PRESENT_MSK (0x1) -#define ALTERA_CF_CTL_STATUS_POWER_MSK (0x2) -#define ALTERA_CF_CTL_STATUS_RESET_MSK (0x4) -#define ALTERA_CF_CTL_STATUS_IRQ_EN_MSK (0x8) -#define ALTERA_CF_IDE_CTL_IRQ_EN_MSK (0x1) - -void ide_set_reset(int idereset) -{ - int i; - writel(idereset ? ALTERA_CF_CTL_STATUS_RESET_MSK : - ALTERA_CF_CTL_STATUS_POWER_MSK, - CONFIG_SYS_CF_CTL_BASE + ALTERA_CF_CTL_STATUS); - /* wait 500 ms for power to stabilize */ - for (i = 0; i < 500; i++) - udelay(1000); -} -#endif diff --git a/board/altera/nios2-generic/Kconfig b/board/altera/nios2-generic/Kconfig deleted file mode 100644 index cd3d0980a7a..00000000000 --- a/board/altera/nios2-generic/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -if TARGET_NIOS2_GENERIC - -config SYS_BOARD - default "nios2-generic" - -config SYS_VENDOR - default "altera" - -config SYS_CONFIG_NAME - default "nios2-generic" - -endif diff --git a/board/altera/nios2-generic/MAINTAINERS b/board/altera/nios2-generic/MAINTAINERS deleted file mode 100644 index 9cbcba983b7..00000000000 --- a/board/altera/nios2-generic/MAINTAINERS +++ /dev/null @@ -1,6 +0,0 @@ -NIOS2-GENERIC BOARD -M: Scott McNutt <smcnutt@psyent.com> -S: Maintained -F: board/altera/nios2-generic/ -F: include/configs/nios2-generic.h -F: configs/nios2-generic_defconfig diff --git a/board/altera/nios2-generic/Makefile b/board/altera/nios2-generic/Makefile deleted file mode 100644 index 5e4192c1e77..00000000000 --- a/board/altera/nios2-generic/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# (C) Copyright 2001-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# (C) Copyright 2010, Thomas Chou <thomas@wytron.com.tw> -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y := nios2-generic.o -obj-$(CONFIG_CMD_IDE) += ../common/cfide.o diff --git a/board/altera/nios2-generic/config.mk b/board/altera/nios2-generic/config.mk deleted file mode 100644 index a6735251957..00000000000 --- a/board/altera/nios2-generic/config.mk +++ /dev/null @@ -1,12 +0,0 @@ -# -# (C) Copyright 2005, Psyent Corporation <www.psyent.com> -# Scott McNutt <smcnutt@psyent.com> -# -# SPDX-License-Identifier: GPL-2.0+ -# - -PLATFORM_CPPFLAGS += -mno-hw-div -mno-hw-mul - -ifeq ($(debug),1) -PLATFORM_CPPFLAGS += -DDEBUG -endif diff --git a/board/altera/nios2-generic/custom_fpga.h b/board/altera/nios2-generic/custom_fpga.h deleted file mode 100644 index cf75d356483..00000000000 --- a/board/altera/nios2-generic/custom_fpga.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This header is generated by sopc2dts - * Sopc2dts is written by Walter Goossens <waltergoossens@home.nl> - * in cooperation with the nios2 community <Nios2-dev@sopc.et.ntust.edu.tw> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _CUSTOM_FPGA_H_ -#define _CUSTOM_FPGA_H_ - -/* generated from qsys_ghrd_3c120.sopcinfo */ - -/* Dumping slaves of cpu.data_master */ - -/* cpu.jtag_debug_module is a altera_nios2_qsys */ -#define CONFIG_SYS_CLK_FREQ 125000000 -#define CONFIG_SYS_DCACHE_SIZE 32768 -#define CONFIG_SYS_DCACHELINE_SIZE 32 -#define CONFIG_SYS_ICACHELINE_SIZE 32 -#define CONFIG_SYS_EXCEPTION_ADDR 0xd0000020 -#define CONFIG_SYS_ICACHE_SIZE 32768 -#define CONFIG_SYS_RESET_ADDR 0xc2800000 -#define IO_REGION_BASE 0xE0000000 - -/* pb_cpu_to_ddr2_bot.s0 is a altera_avalon_mm_bridge */ -/* Dumping slaves of pb_cpu_to_ddr2_bot.m0 */ - -/* ddr2_bot.s1 is a altmemddr2 */ -#define CONFIG_SYS_SDRAM_BASE 0xD0000000 -#define CONFIG_SYS_SDRAM_SIZE 0x08000000 - -/* pb_cpu_to_io.s0 is a altera_avalon_mm_bridge */ -/* Dumping slaves of pb_cpu_to_io.m0 */ - -/* timer_1ms.s1 is a altera_avalon_timer */ -#define CONFIG_SYS_TIMER_IRQ 11 -#define CONFIG_SYS_TIMER_FREQ 125000000 -#define CONFIG_SYS_TIMER_BASE 0xE8400000 - -/* sysid.control_slave is a altera_avalon_sysid_qsys */ -#define CONFIG_SYS_SYSID_BASE 0xE8004D40 - -/* jtag_uart.avalon_jtag_slave is a altera_avalon_jtag_uart */ -#define CONFIG_SYS_JTAG_UART_BASE 0xE8004D50 - -/* tse_mac.control_port is a triple_speed_ethernet */ -#define CONFIG_SYS_ALTERA_TSE_RX_FIFO 2048 -#define CONFIG_SYS_ALTERA_TSE_SGDMA_TX_BASE 0xE8004800 -#define CONFIG_SYS_ALTERA_TSE_SGDMA_RX_BASE 0xE8004400 -#define CONFIG_SYS_ALTERA_TSE_TX_FIFO 2048 -#define CONFIG_SYS_ALTERA_TSE_DESC_SIZE 0x00002000 -#define CONFIG_SYS_ALTERA_TSE_MAC_BASE 0xE8004000 -#define CONFIG_SYS_ALTERA_TSE_DESC_BASE 0xE8002000 -#define CONFIG_ALTERA_TSE -#define CONFIG_MII -#define CONFIG_CMD_MII -#define CONFIG_SYS_ALTERA_TSE_PHY_ADDR 18 -#define CONFIG_SYS_ALTERA_TSE_FLAGS 1 - -/* uart.s1 is a altera_avalon_uart */ -#define CONFIG_SYS_UART_BAUD 115200 -#define CONFIG_SYS_UART_BASE 0xE8004C80 -#define CONFIG_SYS_UART_FREQ 62500000 - -/* user_led_pio_8out.s1 is a altera_avalon_pio */ -#define USER_LED_PIO_8OUT_BASE 0xE8004CC0 - -/* user_dipsw_pio_8in.s1 is a altera_avalon_pio */ -#define USER_DIPSW_PIO_8IN_BASE 0xE8004CE0 -#define USER_DIPSW_PIO_8IN_IRQ 8 - -/* user_pb_pio_4in.s1 is a altera_avalon_pio */ -#define USER_PB_PIO_4IN_BASE 0xE8004D00 -#define USER_PB_PIO_4IN_IRQ 9 - -/* cfi_flash_64m.uas is a altera_generic_tristate_controller */ -#define CFI_FLASH_64M_BASE 0xE0000000 - -/* ext_flash.s1 is a altera_avalon_cfi_flash */ -#define CONFIG_SYS_FLASH_BASE CFI_FLASH_64M_BASE -#define CONFIG_FLASH_CFI_DRIVER -#define CONFIG_SYS_CFI_FLASH_STATUS_POLL /* fix amd flash issue */ -#define CONFIG_SYS_FLASH_CFI -#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE -#define CONFIG_SYS_FLASH_PROTECTION -#define CONFIG_SYS_MAX_FLASH_BANKS 1 -#define CONFIG_SYS_MAX_FLASH_SECT 512 - -#endif /* _CUSTOM_FPGA_H_ */ diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c deleted file mode 100644 index 834cbeb2d5e..00000000000 --- a/board/altera/nios2-generic/nios2-generic.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2005, Psyent Corporation <www.psyent.com> - * Scott McNutt <smcnutt@psyent.com> - * (C) Copyright 2010, Thomas Chou <thomas@wytron.com.tw> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <netdev.h> -#if defined(CONFIG_CFI_FLASH_MTD) -#include <mtd/cfi_flash.h> -#endif -#include <asm/io.h> -#include <asm/gpio.h> - -#if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR) && \ - defined(CONFIG_CFI_FLASH_MTD) -static void __early_flash_cmd_reset(void) -{ - /* reset flash before we read env */ - writeb(AMD_CMD_RESET, CONFIG_ENV_ADDR); - writeb(FLASH_CMD_RESET, CONFIG_ENV_ADDR); -} -void early_flash_cmd_reset(void) - __attribute__((weak,alias("__early_flash_cmd_reset"))); -#endif - -int board_early_init_f(void) -{ -#ifdef CONFIG_ALTERA_PIO -#ifdef LED_PIO_BASE - altera_pio_init(LED_PIO_BASE, LED_PIO_WIDTH, 'o', - LED_PIO_RSTVAL, (1 << LED_PIO_WIDTH) - 1, - "led"); -#endif -#endif -#if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR) && \ - defined(CONFIG_CFI_FLASH_MTD) - early_flash_cmd_reset(); -#endif - return 0; -} - -int checkboard(void) -{ - printf("BOARD : %s\n", CONFIG_BOARD_NAME); - return 0; -} - -phys_size_t initdram(int board_type) -{ - return 0; -} - -#ifdef CONFIG_CMD_NET -int board_eth_init(bd_t *bis) -{ - int rc = 0; -#ifdef CONFIG_SMC91111 - rc += smc91111_initialize(0, CONFIG_SMC91111_BASE); -#endif -#ifdef CONFIG_DRIVER_DM9000 - rc += dm9000_initialize(bis); -#endif -#ifdef CONFIG_ALTERA_TSE - rc += altera_tse_initialize(0, - CONFIG_SYS_ALTERA_TSE_MAC_BASE, - CONFIG_SYS_ALTERA_TSE_SGDMA_RX_BASE, - CONFIG_SYS_ALTERA_TSE_SGDMA_TX_BASE, -#if defined(CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_BASE) && \ - (CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_SIZE > 0) - CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_BASE, - CONFIG_SYS_ALTERA_TSE_SGDMA_DESC_SIZE); -#else - 0, - 0); -#endif -#endif -#ifdef CONFIG_ETHOC - rc += ethoc_initialize(0, CONFIG_SYS_ETHOC_BASE); -#endif - return rc; -} -#endif diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 942badb0873..6451d1d916b 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -242,10 +242,23 @@ static void set_usbethaddr(void) return; } +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +static void set_board_info(void) +{ + char str_rev[11]; + sprintf(str_rev, "0x%X", rpi_board_rev); + setenv("board_rev", str_rev); + setenv("board_name", models[rpi_board_rev].name); +} +#endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */ + int misc_init_r(void) { set_fdtfile(); set_usbethaddr(); +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + set_board_info(); +#endif return 0; } diff --git a/board/samsung/origen/tools/mkorigenspl.c b/board/samsung/origen/tools/mkorigenspl.c index 3ed20efce35..8b0c3ac4bd5 100644 --- a/board/samsung/origen/tools/mkorigenspl.c +++ b/board/samsung/origen/tools/mkorigenspl.c @@ -52,7 +52,7 @@ int main(int argc, char **argv) } ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM); - if (ifd < 0) { + if (ofd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", argv[0], argv[2], strerror(errno)); if (ifd) diff --git a/board/samsung/smdkv310/tools/mksmdkv310spl.c b/board/samsung/smdkv310/tools/mksmdkv310spl.c index 9a64ca6ad6e..ea61635db5e 100644 --- a/board/samsung/smdkv310/tools/mksmdkv310spl.c +++ b/board/samsung/smdkv310/tools/mksmdkv310spl.c @@ -50,7 +50,7 @@ int main(int argc, char **argv) } ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM); - if (ifd < 0) { + if (ofd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", argv[0], argv[2], strerror(errno)); if (ifd) diff --git a/common/Makefile b/common/Makefile index 8c7775a783a..d986cde7b93 100644 --- a/common/Makefile +++ b/common/Makefile @@ -7,6 +7,7 @@ # core ifndef CONFIG_SPL_BUILD +obj-y += init/ obj-y += main.o obj-y += exports.o obj-y += hash.o diff --git a/common/board_f.c b/common/board_f.c index 613332e1dc3..486e828fe8a 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -806,7 +806,7 @@ static init_fnc_t init_sequence_f[] = { #if defined(CONFIG_BOARD_POSTCLK_INIT) board_postclk_init, #endif -#ifdef CONFIG_FSL_ESDHC +#ifdef CONFIG_FSL_CLK get_clocks, #endif #ifdef CONFIG_M68K @@ -1030,32 +1030,3 @@ void board_init_f_r(void) hang(); } #endif /* CONFIG_X86 */ - -/* Unfortunately x86 can't compile this code as gd cannot be assigned */ -#ifndef CONFIG_X86 -__weak void arch_setup_gd(struct global_data *gd_ptr) -{ - gd = gd_ptr; -} -#endif /* !CONFIG_X86 */ - -ulong board_init_f_mem(ulong top) -{ - struct global_data *gd_ptr; - - /* Leave space for the stack we are running with now */ - top -= 0x40; - - top -= sizeof(struct global_data); - top = ALIGN(top, 16); - gd_ptr = (struct global_data *)top; - memset(gd_ptr, '\0', sizeof(*gd)); - arch_setup_gd(gd_ptr); - -#ifdef CONFIG_SYS_MALLOC_F_LEN - top -= CONFIG_SYS_MALLOC_F_LEN; - gd->malloc_base = top; -#endif - - return top; -} diff --git a/common/board_r.c b/common/board_r.c index 0a4dfe49720..c4fd3eaf8cc 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -290,6 +290,9 @@ static int initr_dm(void) /* Save the pre-reloc driver model and start a new one */ gd->dm_root_f = gd->dm_root; gd->dm_root = NULL; +#ifdef CONFIG_TIMER + gd->timer = NULL; +#endif return dm_init_and_scan(false); } #endif @@ -544,11 +547,14 @@ static int initr_kgdb(void) } #endif -#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) +#if defined(CONFIG_STATUS_LED) static int initr_status_led(void) { +#if defined(STATUS_LED_BOOT) status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); - +#else + status_led_init(); +#endif return 0; } #endif @@ -835,7 +841,7 @@ init_fnc_t init_sequence_r[] = { || defined(CONFIG_M68K) timer_init, /* initialize timer */ #endif -#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) +#if defined(CONFIG_STATUS_LED) initr_status_led, #endif /* PPC has a udelay(20) here dating from 2002. Why? */ diff --git a/common/cmd_itest.c b/common/cmd_itest.c index 76af62b46ee..596341c9635 100644 --- a/common/cmd_itest.c +++ b/common/cmd_itest.c @@ -15,6 +15,9 @@ #include <common.h> #include <config.h> #include <command.h> +#include <mapmem.h> + +#include <asm/io.h> #define EQ 0 #define NE 1 @@ -49,16 +52,24 @@ static const op_tbl_t op_table [] = { static long evalexp(char *s, int w) { long l = 0; - long *p; + unsigned long addr; + void *buf; /* if the parameter starts with a * then assume is a pointer to the value we want */ if (s[0] == '*') { - p = (long *)simple_strtoul(&s[1], NULL, 16); + addr = simple_strtoul(&s[1], NULL, 16); + buf = map_physmem(addr, w, MAP_WRBACK); + if (!buf) { + puts("Failed to map physical memory\n"); + return 0; + } switch (w) { - case 1: return((long)(*(unsigned char *)p)); - case 2: return((long)(*(unsigned short *)p)); - case 4: return(*p); + case 1: l = (long)(*(unsigned char *)buf); + case 2: l = (long)(*(unsigned short *)buf); + case 4: l = (long)(*(unsigned long *)buf); } + unmap_physmem(buf, w); + return l; } else { l = simple_strtoul(s, NULL, 16); } diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 0460b4cc56f..753a4dba3d7 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -255,7 +255,7 @@ static int ubi_remove_vol(char *volume) return 0; out_err: - ubi_err("cannot remove volume %s, error %d", volume, err); + ubi_err(ubi, "cannot remove volume %s, error %d", volume, err); if (err < 0) err = -err; return err; @@ -284,8 +284,8 @@ static int ubi_volume_continue_write(char *volume, void *buf, size_t size) return -err; if (err) { - ubi_warn("volume %d on UBI device %d is corrupted", - vol->vol_id, ubi->ubi_num); + ubi_warn(ubi, "volume %d on UBI device %d is corrupt", + vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } diff --git a/common/cmd_ubifs.c b/common/cmd_ubifs.c index 8e9a4e5038d..5e9d357cd7d 100644 --- a/common/cmd_ubifs.c +++ b/common/cmd_ubifs.c @@ -15,8 +15,7 @@ #include <common.h> #include <config.h> #include <command.h> - -#include "../fs/ubifs/ubifs.h" +#include <ubifs_uboot.h> static int ubifs_initialized; static int ubifs_mounted; @@ -54,14 +53,7 @@ int ubifs_is_mounted(void) void cmd_ubifs_umount(void) { - - if (ubifs_sb) { - printf("Unmounting UBIFS volume %s!\n", - ((struct ubifs_info *)(ubifs_sb->s_fs_info))->vi.name); - ubifs_umount(ubifs_sb->s_fs_info); - } - - ubifs_sb = NULL; + uboot_ubifs_umount(); ubifs_mounted = 0; ubifs_initialized = 0; } diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 8b8645c9e13..d033c15b629 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -88,7 +88,8 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) image_print_contents(hdr); #endif - if (!image_check_type(hdr, IH_TYPE_MULTI)) { + if (!image_check_type(hdr, IH_TYPE_MULTI) && + !image_check_type(hdr, IH_TYPE_SCRIPT)) { printf("Wrong Image Type for %s command\n", cmdtp->name); return 1; diff --git a/common/image.c b/common/image.c index e6071099d63..85c4f39cdf5 100644 --- a/common/image.c +++ b/common/image.c @@ -913,7 +913,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, * Look for an Android boot image. */ buf = map_sysmem(images->os.start, 0); - if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) + if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) select = argv[0]; #endif diff --git a/common/init/Makefile b/common/init/Makefile new file mode 100644 index 00000000000..4902635f535 --- /dev/null +++ b/common/init/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += board_init.o diff --git a/common/init/board_init.c b/common/init/board_init.c new file mode 100644 index 00000000000..e74b63b8a87 --- /dev/null +++ b/common/init/board_init.c @@ -0,0 +1,60 @@ +/* + * Code shared between SPL and U-Boot proper + * + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * It isn't trivial to figure out whether memcpy() exists. The arch-specific + * memcpy() is not normally available in SPL due to code size. + */ +#if !defined(CONFIG_SPL_BUILD) || \ + (defined(CONFIG_SPL_LIBGENERIC_SUPPORT) && \ + !defined(CONFIG_USE_ARCH_MEMSET)) +#define _USE_MEMCPY +#endif + +/* Unfortunately x86 can't compile this code as gd cannot be assigned */ +#ifndef CONFIG_X86 +__weak void arch_setup_gd(struct global_data *gd_ptr) +{ + gd = gd_ptr; +} +#endif /* !CONFIG_X86 */ + +ulong board_init_f_mem(ulong top) +{ + struct global_data *gd_ptr; +#ifndef _USE_MEMCPY + int *ptr; +#endif + + /* Leave space for the stack we are running with now */ + top -= 0x40; + + top -= sizeof(struct global_data); + top = ALIGN(top, 16); + gd_ptr = (struct global_data *)top; +#ifdef _USE_MEMCPY + memset(gd_ptr, '\0', sizeof(*gd)); +#else + for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); ) + *ptr++ = 0; +#endif + arch_setup_gd(gd_ptr); + +#if defined(CONFIG_SYS_MALLOC_F) && \ + (!defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYS_SPL_MALLOC_START)) + top -= CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_base = top; +#endif + + return top; +} diff --git a/configs/nios2-generic_defconfig b/configs/nios2-generic_defconfig index 573a0847b2e..fbc27ea17f0 100644 --- a/configs/nios2-generic_defconfig +++ b/configs/nios2-generic_defconfig @@ -1,9 +1,26 @@ CONFIG_NIOS2=y -CONFIG_TARGET_NIOS2_GENERIC=y +CONFIG_SYS_CONFIG_NAME="nios2-generic" +CONFIG_DM_SERIAL=y +CONFIG_DM_GPIO=y +CONFIG_DEFAULT_DEVICE_TREE="3c120_devboard" +CONFIG_HUSH_PARSER=y +CONFIG_CMD_CPU=y # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_IMLS is not set # CONFIG_CMD_XIMG is not set # CONFIG_CMD_FPGA is not set # CONFIG_CMD_ITEST is not set # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y # CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_ALTERA_PIO=y +CONFIG_MISC=y +CONFIG_ALTERA_SYSID=y +CONFIG_DM_ETH=y +CONFIG_ALTERA_TSE=y +CONFIG_ALTERA_JTAG_UART=y +CONFIG_ALTERA_JTAG_UART_BYPASS=y +CONFIG_TIMER=y +CONFIG_ALTERA_TIMER=y diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig index a6757acc023..e9c32095df9 100644 --- a/configs/zynq_microzed_defconfig +++ b/configs/zynq_microzed_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_MICROZED=y CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed" CONFIG_SPL=y diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig index 8a388f36d21..0abb7a85a20 100644 --- a/configs/zynq_zc702_defconfig +++ b/configs/zynq_zc702_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" CONFIG_SPL=y CONFIG_FIT=y diff --git a/configs/zynq_zc706_defconfig b/configs/zynq_zc706_defconfig index f1009eebd30..d67f507390b 100644 --- a/configs/zynq_zc706_defconfig +++ b/configs/zynq_zc706_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZC706=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706" CONFIG_SPL=y diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig index 6465040698a..37c249fbdaa 100644 --- a/configs/zynq_zc70x_defconfig +++ b/configs/zynq_zc70x_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZC70X=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" CONFIG_SPL=y diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index cafbb0991c5..0e826bb6fcb 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010" CONFIG_SPL=y diff --git a/configs/zynq_zc770_xm011_defconfig b/configs/zynq_zc770_xm011_defconfig index e6e1c3085b2..46d043b40e7 100644 --- a/configs/zynq_zc770_xm011_defconfig +++ b/configs/zynq_zc770_xm011_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm011" CONFIG_SPL=y diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig index 9a440097f48..34d479fe3fb 100644 --- a/configs/zynq_zc770_xm012_defconfig +++ b/configs/zynq_zc770_xm012_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012" CONFIG_SPL=y diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig index 95e32a525c4..c59599f7f7a 100644 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013" CONFIG_SPL=y diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index 43520d0fff6..886b4a5bdb0 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZED=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zed" CONFIG_SPL=y diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig index 46379e51395..77b94097fe0 100644 --- a/configs/zynq_zybo_defconfig +++ b/configs/zynq_zybo_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_ZYNQ=y -# CONFIG_SYS_MALLOC_F is not set CONFIG_TARGET_ZYNQ_ZYBO=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo" CONFIG_SPL=y diff --git a/disk/part.c b/disk/part.c index 43485c9148b..e57a252d948 100644 --- a/disk/part.c +++ b/disk/part.c @@ -10,6 +10,7 @@ #include <ide.h> #include <malloc.h> #include <part.h> +#include <ubifs_uboot.h> #undef PART_DEBUG @@ -511,6 +512,11 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, int part; disk_partition_t tmpinfo; +#if defined CONFIG_SANDBOX && defined CONFIG_CMD_UBIFS +#error Only one of CONFIG_SANDBOX and CONFIG_CMD_UBIFS may be selected +#endif + +#ifdef CONFIG_SANDBOX /* * Special-case a pseudo block device "hostfs", to allow access to the * host's own filesystem. @@ -529,6 +535,29 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, return 0; } +#endif + +#ifdef CONFIG_CMD_UBIFS + /* + * Special-case ubi, ubi goes through a mtd, rathen then through + * a regular block device. + */ + if (0 == strcmp(ifname, "ubi")) { + if (!ubifs_is_mounted()) { + printf("UBIFS not mounted, use ubifsmount to mount volume first!\n"); + return -1; + } + + *dev_desc = NULL; + memset(info, 0, sizeof(*info)); + strcpy((char *)info->type, BOOT_PART_TYPE); + strcpy((char *)info->name, "UBI"); +#ifdef CONFIG_PARTITION_UUIDS + info->uuid[0] = 0; +#endif + return 0; + } +#endif /* If no dev_part_str, use bootdevice environment variable */ if (!dev_part_str || !strlen(dev_part_str) || diff --git a/doc/README.nios2 b/doc/README.nios2 new file mode 100644 index 00000000000..2dab7d12e46 --- /dev/null +++ b/doc/README.nios2 @@ -0,0 +1,95 @@ +Nios II is a 32-bit embedded-processor architecture designed +specifically for the Altera family of FPGAs. + +Please refer to the link for more information on Nios II, +https://www.altera.com/products/processors/overview.html + +Please refer to the link for Linux port and toolchains, +http://rocketboards.org/foswiki/view/Documentation/NiosIILinuxUserManual + +The Nios II port of u-boot is controlled by device tree. Please check +out doc/README.fdt-control. + +To add a new board/configuration (eg, mysystem) to u-boot, you will need +three files. + +1. The device tree source which describes the hardware, dts file. + arch/nios2/dts/mysystem.dts + +2. Default configuration of Kconfig, defconfig file. + configs/mysystem_defconfig + +3. The legacy board header file. + include/configs/mysystem.h + +The device tree source must be generated from your qsys/sopc design +using the sopc2dts tool. Then modified to fit your configuration. Please +find the sopc2dts download and usage at the wiki, +http://www.alterawiki.com/wiki/Sopc2dts + +$ java -jar sopc2dts.jar --force-altr -i mysystem.sopcinfo -o mysystem.dts + +You will need to add additional properties to the dts. Please find an +example at, arch/nios2/dts/3c120_devboard.dts. + +1. Add "stdout-path=..." property with your serial path to the chosen +node, like this, + chosen { + stdout-path = &jtag_uart; + }; + +2. If you use SPI/EPCS or I2C, you will need to add aliases to number +the sequence of these devices, like this, + aliases { + spi0 = &epcs_controller; + }; + +Next, you will need a default config file. You may start with +nios2-generic_defconfig, modify the options and save it. + +$ make nios2-generic_defconfig +$ make menuconfig +$ make savedefconfig +$ cp defconfig configs/mysystem_defconfig + +You will need to change the names of board header file and device tree, +and select the drivers with menuconfig. + +Nios II architecture ---> + (mysystem) Board header file +Device Tree Control ---> + (mysystem) Default Device Tree for DT control + +There is a selection of "Provider of DTB for DT control" in the Device +Tree Control menu. + +( ) Separate DTB for DT control, will cat the dtb to end of u-boot +binary, output u-boot-dtb.bin. This should be used for production. +If you use boot copier, like EPCS boot copier, make sure the copier +copies all the u-boot-dtb.bin, not just u-boot.bin. + +( ) Embedded DTB for DT control, will include the dtb inside the u-boot +binary. This is handy for development, eg, using gdb or nios2-download. + +The last thing, legacy board header file describes those config options +not covered in Kconfig yet. You may copy it from nios2-generic.h. + +$ cp include/configs/nios2-generic.h include/configs/mysystem.h + +Please change the SDRAM base and size to match your board. The base +should be cached virtual address, for Nios II with MMU it is 0xCxxx_xxxx +to 0xDxxx_xxxx. + +#define CONFIG_SYS_SDRAM_BASE 0xD0000000 +#define CONFIG_SYS_SDRAM_SIZE 0x08000000 + +You will need to change the environment variables location and setting, +too. You may change other configs to fit your board. + +After all these changes, you may build and test. + +$ export CROSS_COMPILE=nios2-elf- (or nios2-linux-gnu-) +$ make mysystem_defconfig +$ make + +Enjoy! diff --git a/doc/device-tree-bindings/cpu/nios2.txt b/doc/device-tree-bindings/cpu/nios2.txt new file mode 100644 index 00000000000..0ed2f44bcf2 --- /dev/null +++ b/doc/device-tree-bindings/cpu/nios2.txt @@ -0,0 +1,54 @@ +* Nios II Processor Binding + +This binding specifies what properties available in the device tree +representation of a Nios II Processor Core. + +Users can use sopc2dts tool for generating device tree sources (dts) from a +Qsys system. See more detail in: http://www.alterawiki.com/wiki/Sopc2dts + +Required properties: + +- compatible: Compatible property value should be "altr,nios2-1.0" or + "altr,nios2-1.1". +- reg: Contains CPU index. +- clock-frequency: Contains the clock frequency for CPU, in Hz. +- dcache-line-size: Contains data cache line size. +- icache-line-size: Contains instruction line size. +- dcache-size: Contains data cache size. +- icache-size: Contains instruction cache size. +- altr,reset-addr: Specifies CPU reset address +- altr,exception-addr: Specifies CPU exception address + +Optional properties: +- altr,has-initda: Specifies CPU support initda instruction, should be 1. +- altr,has-mmu: Specifies CPU support MMU support. +- altr,has-mul: Specifies CPU hardware multipy support. +- altr,has-div: Specifies CPU hardware divide support +- altr,implementation: Nios II core implementation, this should be "fast"; + +Example: + +cpu@0x0 { + device_type = "cpu"; + compatible = "altr,nios2-1.0"; + reg = <0>; + interrupt-controller; + #interrupt-cells = <1>; + clock-frequency = <125000000>; + dcache-line-size = <32>; + icache-line-size = <32>; + dcache-size = <32768>; + icache-size = <32768>; + altr,implementation = "fast"; + altr,pid-num-bits = <8>; + altr,tlb-num-ways = <16>; + altr,tlb-num-entries = <128>; + altr,tlb-ptr-sz = <7>; + altr,has-div = <1>; + altr,has-mul = <1>; + altr,reset-addr = <0xc2800000>; + altr,fast-tlb-miss-addr = <0xc7fff400>; + altr,exception-addr = <0xd0000020>; + altr,has-initda = <1>; + altr,has-mmu = <1>; +}; diff --git a/doc/device-tree-bindings/gpio/altera_pio.txt b/doc/device-tree-bindings/gpio/altera_pio.txt new file mode 100644 index 00000000000..cf71eb28248 --- /dev/null +++ b/doc/device-tree-bindings/gpio/altera_pio.txt @@ -0,0 +1,28 @@ +Altera GPIO controller bindings + +Required properties: +- compatible: + - "altr,pio-1.0" +- reg: Physical base address and length of the controller's registers. + +Optional properties: +- altr,gpio-bank-width: Width of the GPIO bank. This defines how many pins the + GPIO device has. Ranges between 1-32. Optional and defaults to 32 if not + specified. +- gpio-bank-name: bank name attached to this device. + +Example: + +user_led_pio_8out: gpio@0x4cc0 { + compatible = "altr,pio-1.0"; + reg = <0x00004cc0 0x00000010>; + resetvalue = <255>; + altr,gpio-bank-width = <8>; + #gpio-cells = <2>; + gpio-controller; + gpio-bank-name = "led"; +}; + +In this example, the gpio can be accessed as led[0..7] using gpio command of +u-boot. +==> gpio clear led0 diff --git a/doc/device-tree-bindings/misc/altera_sysid.txt b/doc/device-tree-bindings/misc/altera_sysid.txt new file mode 100644 index 00000000000..54462eb5ef8 --- /dev/null +++ b/doc/device-tree-bindings/misc/altera_sysid.txt @@ -0,0 +1,4 @@ +Altera sysid + +Required properties: +- compatible : should be "altr,sysid-1.0" diff --git a/doc/device-tree-bindings/net/altera_tse.txt b/doc/device-tree-bindings/net/altera_tse.txt new file mode 100644 index 00000000000..cb190df65fa --- /dev/null +++ b/doc/device-tree-bindings/net/altera_tse.txt @@ -0,0 +1,112 @@ +* Altera Triple-Speed Ethernet MAC driver (TSE) + +Required properties: +- compatible: Should be "altr,tse-1.0" for legacy SGDMA based TSE, and should + be "altr,tse-msgdma-1.0" for the preferred MSGDMA based TSE. +- reg: Address and length of the register set for the device. It contains + the information of registers in the same order as described by reg-names +- reg-names: Should contain the reg names + "control_port": MAC configuration space region + "tx_csr": xDMA Tx dispatcher control and status space region + "tx_desc": MSGDMA Tx dispatcher descriptor space region + "rx_csr" : xDMA Rx dispatcher control and status space region + "rx_desc": MSGDMA Rx dispatcher descriptor space region + "rx_resp": MSGDMA Rx dispatcher response space region + "s1": SGDMA descriptor memory +- interrupts: Should contain the TSE interrupts and it's mode. +- interrupt-names: Should contain the interrupt names + "rx_irq": xDMA Rx dispatcher interrupt + "tx_irq": xDMA Tx dispatcher interrupt +- rx-fifo-depth: MAC receive FIFO buffer depth in bytes +- tx-fifo-depth: MAC transmit FIFO buffer depth in bytes +- phy-mode: See ethernet.txt in the same directory. +- phy-handle: See ethernet.txt in the same directory. +- phy-addr: See ethernet.txt in the same directory. A configuration should + include phy-handle or phy-addr. +- altr,has-supplementary-unicast: + If present, TSE supports additional unicast addresses. + Otherwise additional unicast addresses are not supported. +- altr,has-hash-multicast-filter: + If present, TSE supports a hash based multicast filter. + Otherwise, hash-based multicast filtering is not supported. + +- mdio device tree subnode: When the TSE has a phy connected to its local + mdio, there must be device tree subnode with the following + required properties: + + - compatible: Must be "altr,tse-mdio". + - #address-cells: Must be <1>. + - #size-cells: Must be <0>. + + For each phy on the mdio bus, there must be a node with the following + fields: + + - reg: phy id used to communicate to phy. + - device_type: Must be "ethernet-phy". + +Optional properties: +- local-mac-address: See ethernet.txt in the same directory. +- max-frame-size: See ethernet.txt in the same directory. + +Example: + + tse_sub_0_eth_tse_0: ethernet@0x1,00000000 { + compatible = "altr,tse-msgdma-1.0"; + reg = <0x00000001 0x00000000 0x00000400>, + <0x00000001 0x00000460 0x00000020>, + <0x00000001 0x00000480 0x00000020>, + <0x00000001 0x000004A0 0x00000008>, + <0x00000001 0x00000400 0x00000020>, + <0x00000001 0x00000420 0x00000020>; + reg-names = "control_port", "rx_csr", "rx_desc", "rx_resp", "tx_csr", "tx_desc"; + interrupt-parent = <&hps_0_arm_gic_0>; + interrupts = <0 41 4>, <0 40 4>; + interrupt-names = "rx_irq", "tx_irq"; + rx-fifo-depth = <2048>; + tx-fifo-depth = <2048>; + address-bits = <48>; + max-frame-size = <1500>; + local-mac-address = [ 00 00 00 00 00 00 ]; + phy-mode = "gmii"; + altr,has-supplementary-unicast; + altr,has-hash-multicast-filter; + phy-handle = <&phy0>; + mdio { + compatible = "altr,tse-mdio"; + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { + reg = <0x0>; + device_type = "ethernet-phy"; + }; + + phy1: ethernet-phy@1 { + reg = <0x1>; + device_type = "ethernet-phy"; + }; + + }; + }; + + tse_sub_1_eth_tse_0: ethernet@0x1,00001000 { + compatible = "altr,tse-msgdma-1.0"; + reg = <0x00000001 0x00001000 0x00000400>, + <0x00000001 0x00001460 0x00000020>, + <0x00000001 0x00001480 0x00000020>, + <0x00000001 0x000014A0 0x00000008>, + <0x00000001 0x00001400 0x00000020>, + <0x00000001 0x00001420 0x00000020>; + reg-names = "control_port", "rx_csr", "rx_desc", "rx_resp", "tx_csr", "tx_desc"; + interrupt-parent = <&hps_0_arm_gic_0>; + interrupts = <0 43 4>, <0 42 4>; + interrupt-names = "rx_irq", "tx_irq"; + rx-fifo-depth = <2048>; + tx-fifo-depth = <2048>; + address-bits = <48>; + max-frame-size = <1500>; + local-mac-address = [ 00 00 00 00 00 00 ]; + phy-mode = "gmii"; + altr,has-supplementary-unicast; + altr,has-hash-multicast-filter; + phy-handle = <&phy1>; + }; diff --git a/doc/device-tree-bindings/serial/altera_jtaguart.txt b/doc/device-tree-bindings/serial/altera_jtaguart.txt new file mode 100644 index 00000000000..97c7062c5f5 --- /dev/null +++ b/doc/device-tree-bindings/serial/altera_jtaguart.txt @@ -0,0 +1,4 @@ +Altera JTAG UART + +Required properties: +- compatible : should be "altr,juart-1.0" diff --git a/doc/device-tree-bindings/serial/altera_uart.txt b/doc/device-tree-bindings/serial/altera_uart.txt new file mode 100644 index 00000000000..ebac3f5c186 --- /dev/null +++ b/doc/device-tree-bindings/serial/altera_uart.txt @@ -0,0 +1,7 @@ +Altera UART + +Required properties: +- compatible : should be "altr,uart-1.0" + +Optional properties: +- clock-frequency : frequency of the clock input to the UART diff --git a/doc/device-tree-bindings/spi/spi_altera.txt b/doc/device-tree-bindings/spi/spi_altera.txt new file mode 100644 index 00000000000..de4fae8318f --- /dev/null +++ b/doc/device-tree-bindings/spi/spi_altera.txt @@ -0,0 +1,4 @@ +Altera SPI + +Required properties: +- compatible : should be "altr,spi-1.0". diff --git a/doc/device-tree-bindings/timer/altera_timer.txt b/doc/device-tree-bindings/timer/altera_timer.txt new file mode 100644 index 00000000000..904a5846d7a --- /dev/null +++ b/doc/device-tree-bindings/timer/altera_timer.txt @@ -0,0 +1,19 @@ +Altera Timer + +Required properties: + +- compatible : should be "altr,timer-1.0" +- reg : Specifies base physical address and size of the registers. +- interrupt-parent: phandle of the interrupt controller +- interrupts : Should contain the timer interrupt number +- clock-frequency : The frequency of the clock that drives the counter, in Hz. + +Example: + +timer { + compatible = "altr,timer-1.0"; + reg = <0x00400000 0x00000020>; + interrupt-parent = <&cpu>; + interrupts = <11>; + clock-frequency = <125000000>; +}; diff --git a/drivers/Kconfig b/drivers/Kconfig index c02f3231e07..ba88b5ea371 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -58,6 +58,8 @@ source "drivers/spi/Kconfig" source "drivers/thermal/Kconfig" +source "drivers/timer/Kconfig" + source "drivers/tpm/Kconfig" source "drivers/usb/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 1a30ad1d147..4f49bfddb86 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -48,6 +48,7 @@ obj-y += pcmcia/ obj-y += dfu/ obj-y += rtc/ obj-y += sound/ +obj-y += timer/ obj-y += tpm/ obj-y += twserial/ obj-y += video/ diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index ef57a89ea2f..9e494713fbc 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -14,6 +14,13 @@ config DM_GPIO particular GPIOs that they provide. The uclass interface is defined in include/asm-generic/gpio.h. +config ALTERA_PIO + bool "Altera PIO driver" + depends on DM_GPIO + help + Select this to enable PIO for Altera devices. Please find + details on the "Embedded Peripherals IP User Guide" of Altera. + config DWAPB_GPIO bool "DWAPB GPIO driver" depends on DM && DM_GPIO diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c index 3ca590700c4..7ceb80e9510 100644 --- a/drivers/gpio/altera_pio.c +++ b/drivers/gpio/altera_pio.c @@ -1,286 +1,122 @@ /* - * Driver for Altera's PIO ip core - * + * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> * Copyright (C) 2011 Missing Link Electronics * Joachim Foerster <joachim@missinglinkelectronics.com> * * SPDX-License-Identifier: GPL-2.0+ - * - * To use this driver, in your board's config. header: - * #define CONFIG_ALTERA_PIO - * #define CONFIG_SYS_ALTERA_PIO_NUM <number-of-pio-cores> - * #define CONFIG_SYS_ALTERA_PIO_GPIO_NUM <total-number-of-gpios> - * And in your board's early setup routine: - * altera_pio_init(<baseaddr>, <width>, 'i'|'o'|'t', - * <reset-value>, <neg-mask>, "label"); - * - 'i'|'o'|'t': PIO is input-only/output-only/tri-state - * - <reset-value>: for correct initial status display, output-only - * - <neg-mask> is meant to be used to in cases of active-low - * GPIOs, such as LEDs and buttons (on/pressed == 0). Each bit - * which is 1 in <neg-mask> inverts the corresponding GPIO's value - * before set/after get. So: gpio_set_value(gpio, 1) => LED on . - * - * Do NOT define CONFIG_SYS_GPIO_BASE ! - * - * Optionally, in your board's config. header: - * - To force a GPIO numbering scheme like in Linux ... - * #define CONFIG_GPIO_DOWNTO_NUMBERING - * ... starting with 255 (default) - * #define CONFIG_GPIO_DOWNTO_MAX 255 */ #include <common.h> +#include <dm.h> +#include <errno.h> +#include <malloc.h> +#include <fdtdec.h> #include <asm/io.h> #include <asm/gpio.h> -#ifdef CONFIG_GPIO_DOWNTO_NUMBERING -#ifndef CONFIG_GPIO_DOWNTO_MAX -#define CONFIG_GPIO_DOWNTO_MAX 255 -#endif -#endif - -#define ALTERA_PIO_DATA 0x0 -#define ALTERA_PIO_DIR 0x4 - -#define GPIO_LABEL_SIZE 9 +DECLARE_GLOBAL_DATA_PTR; +struct altera_pio_regs { + u32 data; /* Data register */ + u32 direction; /* Direction register */ +}; -static struct altera_pio { - u32 base; - u8 width; - char iot; - u32 negmask; - u32 sh_data; - u32 sh_dir; - int gidx; - char label[GPIO_LABEL_SIZE]; -} pios[CONFIG_SYS_ALTERA_PIO_NUM]; +struct altera_pio_platdata { + struct altera_pio_regs *regs; + int gpio_count; + const char *bank_name; +}; -static int pio_num; - -static struct altera_pio_gpio { - unsigned num; - struct altera_pio *pio; - char reqlabel[GPIO_LABEL_SIZE]; -} gpios[CONFIG_SYS_ALTERA_PIO_GPIO_NUM]; - -static int pio_gpio_num; - - -static int altera_pio_gidx(unsigned gpio) +static int altera_pio_direction_input(struct udevice *dev, unsigned pin) { - int i; + struct altera_pio_platdata *plat = dev_get_platdata(dev); + struct altera_pio_regs *const regs = plat->regs; - for (i = 0; i < pio_gpio_num; ++i) { - if (gpio == gpios[i].num) - break; - } - if (i >= pio_gpio_num) - return -1; - return i; -} + clrbits_le32(®s->direction, 1 << pin); -static struct altera_pio *altera_pio_get_and_mask(unsigned gpio, u32 *mask) -{ - int gidx = altera_pio_gidx(gpio); - if (gidx < 0) - return NULL; - if (mask) - *mask = 1 << (gidx - gpios[gidx].pio->gidx); - return gpios[gidx].pio; + return 0; } -#define altera_pio_use_gidx(_gidx, _reqlabel) \ - { strncpy(gpios[_gidx].reqlabel, _reqlabel, GPIO_LABEL_SIZE); } -#define altera_pio_unuse_gidx(_gidx) { gpios[_gidx].reqlabel[0] = '\0'; } -#define altera_pio_is_gidx_used(_gidx) (gpios[_gidx].reqlabel[0] != '\0') - -static int altera_pio_gpio_init(struct altera_pio *pio, u8 width) +static int altera_pio_direction_output(struct udevice *dev, unsigned pin, + int val) { - u8 gidx = pio_gpio_num; - int i; - - if (!width) - return -1; - if ((pio_gpio_num + width) > CONFIG_SYS_ALTERA_PIO_GPIO_NUM) - return -1; - - for (i = 0; i < width; ++i) { -#ifdef CONFIG_GPIO_DOWNTO_NUMBERING - gpios[pio_gpio_num + i].num = \ - CONFIG_GPIO_DOWNTO_MAX + 1 - gidx - width + i; -#else - gpios[pio_gpio_num + i].num = pio_gpio_num + i; -#endif - gpios[pio_gpio_num + i].pio = pio; - altera_pio_unuse_gidx(pio_gpio_num + i); - } - pio_gpio_num += width; - return gidx; -} + struct altera_pio_platdata *plat = dev_get_platdata(dev); + struct altera_pio_regs *const regs = plat->regs; -int altera_pio_init(u32 base, u8 width, char iot, u32 rstval, u32 negmask, - const char *label) -{ - if (pio_num >= CONFIG_SYS_ALTERA_PIO_NUM) - return -1; + if (val) + setbits_le32(®s->data, 1 << pin); + else + clrbits_le32(®s->data, 1 << pin); + /* change the data first, then the direction. to avoid glitch */ + setbits_le32(®s->direction, 1 << pin); - pios[pio_num].base = base; - pios[pio_num].width = width; - pios[pio_num].iot = iot; - switch (iot) { - case 'i': - /* input only */ - pios[pio_num].sh_dir = 0; - pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA); - break; - case 'o': - /* output only */ - pios[pio_num].sh_dir = 0xffffffff & ((1 << width) - 1); - pios[pio_num].sh_data = rstval; - break; - case 't': - /* bidir, tri-state */ - pios[pio_num].sh_dir = readl(base + ALTERA_PIO_DIR); - pios[pio_num].sh_data = readl(base + ALTERA_PIO_DATA); - break; - default: - return -1; - } - pios[pio_num].negmask = negmask & ((1 << width) - 1); - pios[pio_num].gidx = altera_pio_gpio_init(&pios[pio_num], width); - if (pios[pio_num].gidx < 0) - return -1; - strncpy(pios[pio_num].label, label, GPIO_LABEL_SIZE); - return pio_num++; + return 0; } -void altera_pio_info(void) +static int altera_pio_get_value(struct udevice *dev, unsigned pin) { - int i; - int j; - int gidx; - u32 mask; + struct altera_pio_platdata *plat = dev_get_platdata(dev); + struct altera_pio_regs *const regs = plat->regs; - for (i = 0; i < pio_num; ++i) { - printf("Altera PIO % 2d, @0x%08x, " - "width: %u, label: %s\n", - i, pios[i].base, pios[i].width, pios[i].label); - gidx = pios[i].gidx; - for (j = gidx; j < (gidx + pios[i].width); ++j) { - mask = 1 << (j - gidx); - printf("\tGPIO % 4d: %s %s [%c] %s\n", - gpios[j].num, - gpios[j].pio->sh_dir & mask ? "out" : " in", - gpio_get_value(gpios[j].num) ? "set" : "clr", - altera_pio_is_gidx_used(j) ? 'x' : ' ', - gpios[j].reqlabel); - } - } + return readl(®s->data) & (1 << pin); } -int gpio_request(unsigned gpio, const char *label) +static int altera_pio_set_value(struct udevice *dev, unsigned pin, int val) { - int gidx = altera_pio_gidx(gpio); - if (gidx < 0) - return gidx; - if (altera_pio_is_gidx_used(gidx)) - return -1; - - altera_pio_use_gidx(gidx, label); - return 0; -} + struct altera_pio_platdata *plat = dev_get_platdata(dev); + struct altera_pio_regs *const regs = plat->regs; -int gpio_free(unsigned gpio) -{ - int gidx = altera_pio_gidx(gpio); - if (gidx < 0) - return gidx; - if (!altera_pio_is_gidx_used(gidx)) - return -1; + if (val) + setbits_le32(®s->data, 1 << pin); + else + clrbits_le32(®s->data, 1 << pin); - altera_pio_unuse_gidx(gidx); return 0; } -int gpio_direction_input(unsigned gpio) +static int altera_pio_probe(struct udevice *dev) { - u32 mask; - struct altera_pio *pio; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct altera_pio_platdata *plat = dev_get_platdata(dev); - pio = altera_pio_get_and_mask(gpio, &mask); - if (!pio) - return -1; - if (pio->iot == 'o') - return -1; + uc_priv->gpio_count = plat->gpio_count; + uc_priv->bank_name = plat->bank_name; - writel(pio->sh_dir &= ~mask, pio->base + ALTERA_PIO_DIR); return 0; } -int gpio_direction_output(unsigned gpio, int value) +static int altera_pio_ofdata_to_platdata(struct udevice *dev) { - u32 mask; - struct altera_pio *pio; + struct altera_pio_platdata *plat = dev_get_platdata(dev); - pio = altera_pio_get_and_mask(gpio, &mask); - if (!pio) - return -1; - if (pio->iot == 'i') - return -1; + plat->regs = ioremap(dev_get_addr(dev), + sizeof(struct altera_pio_regs)); + plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "altr,gpio-bank-width", 32); + plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset, + "gpio-bank-name", NULL); - value = (pio->negmask & mask) ? !value : value; - if (value) - pio->sh_data |= mask; - else - pio->sh_data &= ~mask; - writel(pio->sh_data, pio->base + ALTERA_PIO_DATA); - writel(pio->sh_dir |= mask, pio->base + ALTERA_PIO_DIR); return 0; } -int gpio_get_value(unsigned gpio) -{ - u32 mask; - struct altera_pio *pio; - u32 val; - - pio = altera_pio_get_and_mask(gpio, &mask); - if (!pio) - return -1; - - if ((pio->sh_dir & mask) || (pio->iot == 'o')) - val = pio->sh_data & mask; - else - val = readl(pio->base + ALTERA_PIO_DATA) & mask; - return (pio->negmask & mask) ? !val : val; -} - -void gpio_set_value(unsigned gpio, int value) -{ - u32 mask; - struct altera_pio *pio; - - pio = altera_pio_get_and_mask(gpio, &mask); - if (!pio) - return; - if (pio->iot == 'i') - return; - - value = (pio->negmask & mask) ? !value : value; - if (value) - pio->sh_data |= mask; - else - pio->sh_data &= ~mask; - writel(pio->sh_data, pio->base + ALTERA_PIO_DATA); - return; -} - -int gpio_is_valid(int number) -{ - int gidx = altera_pio_gidx(number); - - if (gidx < 0) - return 1; - return 0; -} +static const struct dm_gpio_ops altera_pio_ops = { + .direction_input = altera_pio_direction_input, + .direction_output = altera_pio_direction_output, + .get_value = altera_pio_get_value, + .set_value = altera_pio_set_value, +}; + +static const struct udevice_id altera_pio_ids[] = { + { .compatible = "altr,pio-1.0" }, + { } +}; + +U_BOOT_DRIVER(altera_pio) = { + .name = "altera_pio", + .id = UCLASS_GPIO, + .of_match = altera_pio_ids, + .ops = &altera_pio_ops, + .ofdata_to_platdata = altera_pio_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct altera_pio_platdata), + .probe = altera_pio_probe, +}; diff --git a/drivers/hwmon/lm81.c b/drivers/hwmon/lm81.c index c1fc42a8332..bcc8d3293b5 100644 --- a/drivers/hwmon/lm81.c +++ b/drivers/hwmon/lm81.c @@ -90,7 +90,7 @@ int dtt_init_one(int sensor) if (adr < 0) return 1; rev = dtt_read (sensor, DTT_REV); - if (adr < 0) + if (rev < 0) return 1; debug ("DTT: Found LM81@%x Rev: %d\n", adr, rev); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 8b38a84de66..101a6195580 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -4,6 +4,22 @@ menu "Multifunction device drivers" +config MISC + bool "Enable Driver Model for Misc drivers" + depends on DM + help + Enable driver model for miscellaneous devices. This class is + used only for those do not fit other more general classes. A + set of generic read, write and ioctl methods may be used to + access the device. + +config ALTERA_SYSID + bool "Altera Sysid support" + depends on MISC + help + Select this to enable a sysid for Altera devices. Please find + details on the "Embedded Peripherals IP User Guide" of Altera. + config CMD_CROS_EC bool "Enable crosec command" depends on CROS_EC diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 8d0fc3c5cbc..aa137f50ea3 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -5,7 +5,9 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_MISC) += misc-uclass.o obj-$(CONFIG_ALI152X) += ali512x.o +obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o obj-$(CONFIG_DS4510) += ds4510.o obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o obj-$(CONFIG_CROS_EC) += cros_ec.o diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c new file mode 100644 index 00000000000..249b273fb3b --- /dev/null +++ b/drivers/misc/altera_sysid.c @@ -0,0 +1,101 @@ +/* + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <dm.h> +#include <errno.h> +#include <misc.h> +#include <linux/time.h> +#include <asm/io.h> + +struct altera_sysid_regs { + u32 id; /* The system build id */ + u32 timestamp; /* Timestamp */ +}; + +struct altera_sysid_platdata { + struct altera_sysid_regs *regs; +}; + +void display_sysid(void) +{ + struct udevice *dev; + u32 sysid[2]; + struct tm t; + char asc[32]; + time_t stamp; + int ret; + + /* the first misc device will be used */ + ret = uclass_first_device(UCLASS_MISC, &dev); + if (ret) + return; + if (!dev) + return; + ret = misc_read(dev, 0, &sysid, sizeof(sysid)); + if (ret) + return; + + stamp = sysid[1]; + localtime_r(&stamp, &t); + asctime_r(&t, asc); + printf("SYSID: %08x, %s", sysid[0], asc); +} + +int do_sysid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + display_sysid(); + return 0; +} + +U_BOOT_CMD( + sysid, 1, 1, do_sysid, + "display Nios-II system id", + "" +); + +static int altera_sysid_read(struct udevice *dev, + int offset, void *buf, int size) +{ + struct altera_sysid_platdata *plat = dev->platdata; + struct altera_sysid_regs *const regs = plat->regs; + u32 *sysid = buf; + + sysid[0] = readl(®s->id); + sysid[1] = readl(®s->timestamp); + + return 0; +} + +static int altera_sysid_ofdata_to_platdata(struct udevice *dev) +{ + struct altera_sysid_platdata *plat = dev_get_platdata(dev); + + plat->regs = ioremap(dev_get_addr(dev), + sizeof(struct altera_sysid_regs)); + + return 0; +} + +static const struct misc_ops altera_sysid_ops = { + .read = altera_sysid_read, +}; + +static const struct udevice_id altera_sysid_ids[] = { + { .compatible = "altr,sysid-1.0", }, + { } +}; + +U_BOOT_DRIVER(altera_sysid) = { + .name = "altera_sysid", + .id = UCLASS_MISC, + .of_match = altera_sysid_ids, + .ofdata_to_platdata = altera_sysid_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct altera_sysid_platdata), + .ops = &altera_sysid_ops, +}; diff --git a/drivers/misc/gpio_led.c b/drivers/misc/gpio_led.c index 3e95727d798..164c30db382 100644 --- a/drivers/misc/gpio_led.c +++ b/drivers/misc/gpio_led.c @@ -51,3 +51,57 @@ void __led_toggle(led_id_t mask) { gpio_set_value(mask, !gpio_get_value(mask)); } + +#ifdef CONFIG_GPIO_LED_STUBS + +/* 'generic' override of colored LED stubs, to use GPIO functions instead */ + +#ifdef STATUS_LED_RED +void red_led_on(void) +{ + __led_set(STATUS_LED_RED, STATUS_LED_ON); +} + +void red_led_off(void) +{ + __led_set(STATUS_LED_RED, STATUS_LED_OFF); +} +#endif + +#ifdef STATUS_LED_GREEN +void green_led_on(void) +{ + __led_set(STATUS_LED_GREEN, STATUS_LED_ON); +} + +void green_led_off(void) +{ + __led_set(STATUS_LED_GREEN, STATUS_LED_OFF); +} +#endif + +#ifdef STATUS_LED_YELLOW +void yellow_led_on(void) +{ + __led_set(STATUS_LED_YELLOW, STATUS_LED_ON); +} + +void yellow_led_off(void) +{ + __led_set(STATUS_LED_YELLOW, STATUS_LED_OFF); +} +#endif + +#ifdef STATUS_LED_BLUE +void blue_led_on(void) +{ + __led_set(STATUS_LED_BLUE, STATUS_LED_ON); +} + +void blue_led_off(void) +{ + __led_set(STATUS_LED_BLUE, STATUS_LED_OFF); +} +#endif + +#endif /* CONFIG_GPIO_LED_STUBS */ diff --git a/drivers/misc/misc-uclass.c b/drivers/misc/misc-uclass.c new file mode 100644 index 00000000000..13a6ea508b1 --- /dev/null +++ b/drivers/misc/misc-uclass.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <misc.h> + +/* + * Implement a miscellaneous uclass for those do not fit other more + * general classes. A set of generic read, write and ioctl methods may + * be used to access the device. + */ + +int misc_read(struct udevice *dev, int offset, void *buf, int size) +{ + const struct misc_ops *ops = device_get_ops(dev); + + if (!ops->read) + return -ENOSYS; + + return ops->read(dev, offset, buf, size); +} + +int misc_write(struct udevice *dev, int offset, void *buf, int size) +{ + const struct misc_ops *ops = device_get_ops(dev); + + if (!ops->write) + return -ENOSYS; + + return ops->write(dev, offset, buf, size); +} + +int misc_ioctl(struct udevice *dev, unsigned long request, void *buf) +{ + const struct misc_ops *ops = device_get_ops(dev); + + if (!ops->ioctl) + return -ENOSYS; + + return ops->ioctl(dev, request, buf); +} + +UCLASS_DRIVER(misc) = { + .id = UCLASS_MISC, + .name = "misc", +}; diff --git a/drivers/misc/pca9551_led.c b/drivers/misc/pca9551_led.c index d4034f6735b..4da031985f7 100644 --- a/drivers/misc/pca9551_led.c +++ b/drivers/misc/pca9551_led.c @@ -116,8 +116,12 @@ static int pca9551_led_set_blink_rate(int idx, struct pca9551_blink_rate rate) } /* - * Functions referenced by cmd_led.c + * Functions referenced by cmd_led.c or status_led.c */ +void __led_init(led_id_t id, int state) +{ +} + void __led_set(led_id_t mask, int state) { if (state == STATUS_LED_OFF) diff --git a/drivers/misc/status_led.c b/drivers/misc/status_led.c index 9869d98c10c..31e88319d15 100644 --- a/drivers/misc/status_led.c +++ b/drivers/misc/status_led.c @@ -73,7 +73,7 @@ led_dev_t led_dev[] = { static int status_led_init_done = 0; -static void status_led_init (void) +void status_led_init(void) { led_dev_t *ld; int i; diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 1bdbfa71d91..90fb74a5c96 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -172,6 +172,7 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) /** * validate_vid_hdr - check volume identifier header. + * @ubi: UBI device description object * @vid_hdr: the volume identifier header to check * @av: information about the volume this logical eraseblock belongs to * @pnum: physical eraseblock number the VID header came from @@ -184,7 +185,8 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) * information in the VID header is consistent to the information in other VID * headers of the same volume. */ -static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, +static int validate_vid_hdr(const struct ubi_device *ubi, + const struct ubi_vid_hdr *vid_hdr, const struct ubi_ainf_volume *av, int pnum) { int vol_type = vid_hdr->vol_type; @@ -202,7 +204,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, */ if (vol_id != av->vol_id) { - ubi_err("inconsistent vol_id"); + ubi_err(ubi, "inconsistent vol_id"); goto bad; } @@ -212,17 +214,17 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, av_vol_type = UBI_VID_DYNAMIC; if (vol_type != av_vol_type) { - ubi_err("inconsistent vol_type"); + ubi_err(ubi, "inconsistent vol_type"); goto bad; } if (used_ebs != av->used_ebs) { - ubi_err("inconsistent used_ebs"); + ubi_err(ubi, "inconsistent used_ebs"); goto bad; } if (data_pad != av->data_pad) { - ubi_err("inconsistent data_pad"); + ubi_err(ubi, "inconsistent data_pad"); goto bad; } } @@ -230,7 +232,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, return 0; bad: - ubi_err("inconsistent VID header at PEB %d", pnum); + ubi_err(ubi, "inconsistent VID header at PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); ubi_dump_av(av); return -EINVAL; @@ -332,7 +334,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, * support these images anymore. Well, those images still work, * but only if no unclean reboots happened. */ - ubi_err("unsupported on-flash UBI format"); + ubi_err(ubi, "unsupported on-flash UBI format"); return -EINVAL; } @@ -373,7 +375,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, if (err == UBI_IO_BITFLIPS) bitflips = 1; else { - ubi_err("VID of PEB %d header is bad, but it was OK earlier, err %d", + ubi_err(ubi, "VID of PEB %d header is bad, but it was OK earlier, err %d", pnum, err); if (err > 0) err = -EIO; @@ -404,7 +406,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, second_is_newer = !second_is_newer; } else { dbg_bld("PEB %d CRC is OK", pnum); - bitflips = !!err; + bitflips |= !!err; } mutex_unlock(&ubi->buf_mutex); @@ -503,7 +505,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * logical eraseblocks because there was an unclean reboot. */ if (aeb->sqnum == sqnum && sqnum != 0) { - ubi_err("two LEBs with same sequence number %llu", + ubi_err(ubi, "two LEBs with same sequence number %llu", sqnum); ubi_dump_aeb(aeb, 0); ubi_dump_vid_hdr(vid_hdr); @@ -523,7 +525,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * This logical eraseblock is newer than the one * found earlier. */ - err = validate_vid_hdr(vid_hdr, av, pnum); + err = validate_vid_hdr(ubi, vid_hdr, av, pnum); if (err) return err; @@ -561,7 +563,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * attaching information. */ - err = validate_vid_hdr(vid_hdr, av, pnum); + err = validate_vid_hdr(ubi, vid_hdr, av, pnum); if (err) return err; @@ -664,7 +666,8 @@ static int early_erase_peb(struct ubi_device *ubi, * Erase counter overflow. Upgrade UBI and use 64-bit * erase counters internally. */ - ubi_err("erase counter overflow at PEB %d, EC %d", pnum, ec); + ubi_err(ubi, "erase counter overflow at PEB %d, EC %d", + pnum, ec); return -EINVAL; } @@ -732,7 +735,7 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, return aeb; } - ubi_err("no free eraseblocks"); + ubi_err(ubi, "no free eraseblocks"); return ERR_PTR(-ENOSPC); } @@ -781,9 +784,9 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) goto out_unlock; - ubi_err("PEB %d contains corrupted VID header, and the data does not contain all 0xFF", + ubi_err(ubi, "PEB %d contains corrupted VID header, and the data does not contain all 0xFF", pnum); - ubi_err("this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); + ubi_err(ubi, "this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); ubi_dump_vid_hdr(vid_hdr); pr_err("hexdump of PEB %d offset %d, length %d", pnum, ubi->leb_start, ubi->leb_size); @@ -855,7 +858,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, bitflips = 1; break; default: - ubi_err("'ubi_io_read_ec_hdr()' returned unknown code %d", err); + ubi_err(ubi, "'ubi_io_read_ec_hdr()' returned unknown code %d", + err); return -EINVAL; } @@ -864,7 +868,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, /* Make sure UBI version is OK */ if (ech->version != UBI_VERSION) { - ubi_err("this UBI version is %d, image version is %d", + ubi_err(ubi, "this UBI version is %d, image version is %d", UBI_VERSION, (int)ech->version); return -EINVAL; } @@ -878,7 +882,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, * flash. Upgrade UBI and use 64-bit erase counters * internally. */ - ubi_err("erase counter overflow, max is %d", + ubi_err(ubi, "erase counter overflow, max is %d", UBI_MAX_ERASECOUNTER); ubi_dump_ec_hdr(ech); return -EINVAL; @@ -899,7 +903,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, if (!ubi->image_seq) ubi->image_seq = image_seq; if (image_seq && ubi->image_seq != image_seq) { - ubi_err("bad image sequence number %d in PEB %d, expected %d", + ubi_err(ubi, "bad image sequence number %d in PEB %d, expected %d", image_seq, pnum, ubi->image_seq); ubi_dump_ec_hdr(ech); return -EINVAL; @@ -977,7 +981,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return err; goto adjust_mean_ec; default: - ubi_err("'ubi_io_read_vid_hdr()' returned unknown code %d", + ubi_err(ubi, "'ubi_io_read_vid_hdr()' returned unknown code %d", err); return -EINVAL; } @@ -995,7 +999,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, case UBI_COMPAT_DELETE: if (vol_id != UBI_FM_SB_VOLUME_ID && vol_id != UBI_FM_DATA_VOLUME_ID) { - ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it", + ubi_msg(ubi, "\"delete\" compatible internal volume %d:%d found, will remove it", vol_id, lnum); } err = add_to_list(ai, pnum, vol_id, lnum, @@ -1005,13 +1009,13 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return 0; case UBI_COMPAT_RO: - ubi_msg("read-only compatible internal volume %d:%d found, switch to read-only mode", + ubi_msg(ubi, "read-only compatible internal volume %d:%d found, switch to read-only mode", vol_id, lnum); ubi->ro_mode = 1; break; case UBI_COMPAT_PRESERVE: - ubi_msg("\"preserve\" compatible internal volume %d:%d found", + ubi_msg(ubi, "\"preserve\" compatible internal volume %d:%d found", vol_id, lnum); err = add_to_list(ai, pnum, vol_id, lnum, ec, 0, &ai->alien); @@ -1020,14 +1024,14 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return 0; case UBI_COMPAT_REJECT: - ubi_err("incompatible internal volume %d:%d found", + ubi_err(ubi, "incompatible internal volume %d:%d found", vol_id, lnum); return -EINVAL; } } if (ec_err) - ubi_warn("valid VID header but corrupted EC header at PEB %d", + ubi_warn(ubi, "valid VID header but corrupted EC header at PEB %d", pnum); err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips); if (err) @@ -1071,7 +1075,7 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) * with the flash HW or driver. */ if (ai->corr_peb_count) { - ubi_err("%d PEBs are corrupted and preserved", + ubi_err(ubi, "%d PEBs are corrupted and preserved", ai->corr_peb_count); pr_err("Corrupted PEBs are:"); list_for_each_entry(aeb, &ai->corr, u.list) @@ -1083,7 +1087,7 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) * otherwise, only print a warning. */ if (ai->corr_peb_count >= max_corr) { - ubi_err("too many corrupted PEBs, refusing"); + ubi_err(ubi, "too many corrupted PEBs, refusing"); return -EINVAL; } } @@ -1106,11 +1110,11 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) */ if (ai->maybe_bad_peb_count <= 2) { ai->is_empty = 1; - ubi_msg("empty MTD device detected"); + ubi_msg(ubi, "empty MTD device detected"); get_random_bytes(&ubi->image_seq, sizeof(ubi->image_seq)); } else { - ubi_err("MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it"); + ubi_err(ubi, "MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it"); return -EINVAL; } @@ -1244,7 +1248,7 @@ static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, goto out_vidh; } - ubi_msg("scanning is finished"); + ubi_msg(ubi, "scanning is finished"); /* Calculate mean erase counter */ if (ai->ec_count) @@ -1293,6 +1297,30 @@ out_ech: return err; } +static struct ubi_attach_info *alloc_ai(void) +{ + struct ubi_attach_info *ai; + + ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); + if (!ai) + return ai; + + INIT_LIST_HEAD(&ai->corr); + INIT_LIST_HEAD(&ai->free); + INIT_LIST_HEAD(&ai->erase); + INIT_LIST_HEAD(&ai->alien); + ai->volumes = RB_ROOT; + ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", + sizeof(struct ubi_ainf_peb), + 0, 0, NULL); + if (!ai->aeb_slab_cache) { + kfree(ai); + ai = NULL; + } + + return ai; +} + #ifdef CONFIG_MTD_UBI_FASTMAP /** @@ -1305,7 +1333,7 @@ out_ech: * UBI_NO_FASTMAP denotes that no fastmap was found. * UBI_BAD_FASTMAP denotes that the found fastmap was invalid. */ -static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) +static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai) { int err, pnum, fm_anchor = -1; unsigned long long max_sqnum = 0; @@ -1326,7 +1354,7 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) cond_resched(); dbg_gen("process PEB %d", pnum); - err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum); + err = scan_peb(ubi, *ai, pnum, &vol_id, &sqnum); if (err < 0) goto out_vidh; @@ -1342,7 +1370,12 @@ static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) if (fm_anchor < 0) return UBI_NO_FASTMAP; - return ubi_scan_fastmap(ubi, ai, fm_anchor); + destroy_ai(*ai); + *ai = alloc_ai(); + if (!*ai) + return -ENOMEM; + + return ubi_scan_fastmap(ubi, *ai, fm_anchor); out_vidh: ubi_free_vid_hdr(ubi, vidh); @@ -1354,30 +1387,6 @@ out: #endif -static struct ubi_attach_info *alloc_ai(const char *slab_name) -{ - struct ubi_attach_info *ai; - - ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); - if (!ai) - return ai; - - INIT_LIST_HEAD(&ai->corr); - INIT_LIST_HEAD(&ai->free); - INIT_LIST_HEAD(&ai->erase); - INIT_LIST_HEAD(&ai->alien); - ai->volumes = RB_ROOT; - ai->aeb_slab_cache = kmem_cache_create(slab_name, - sizeof(struct ubi_ainf_peb), - 0, 0, NULL); - if (!ai->aeb_slab_cache) { - kfree(ai); - ai = NULL; - } - - return ai; -} - /** * ubi_attach - attach an MTD device. * @ubi: UBI device descriptor @@ -1391,7 +1400,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) int err; struct ubi_attach_info *ai; - ai = alloc_ai("ubi_aeb_slab_cache"); + ai = alloc_ai(); if (!ai) return -ENOMEM; @@ -1405,11 +1414,11 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) if (force_scan) err = scan_all(ubi, ai, 0); else { - err = scan_fast(ubi, ai); - if (err > 0) { + err = scan_fast(ubi, &ai); + if (err > 0 || mtd_is_eccerr(err)) { if (err != UBI_NO_FASTMAP) { destroy_ai(ai); - ai = alloc_ai("ubi_aeb_slab_cache2"); + ai = alloc_ai(); if (!ai) return -ENOMEM; @@ -1445,10 +1454,10 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) goto out_wl; #ifdef CONFIG_MTD_UBI_FASTMAP - if (ubi->fm && ubi_dbg_chk_gen(ubi)) { + if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) { struct ubi_attach_info *scan_ai; - scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); + scan_ai = alloc_ai(); if (!scan_ai) { err = -ENOMEM; goto out_wl; @@ -1511,37 +1520,37 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) vols_found += 1; if (ai->is_empty) { - ubi_err("bad is_empty flag"); + ubi_err(ubi, "bad is_empty flag"); goto bad_av; } if (av->vol_id < 0 || av->highest_lnum < 0 || av->leb_count < 0 || av->vol_type < 0 || av->used_ebs < 0 || av->data_pad < 0 || av->last_data_size < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto bad_av; } if (av->vol_id >= UBI_MAX_VOLUMES && av->vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("bad vol_id"); + ubi_err(ubi, "bad vol_id"); goto bad_av; } if (av->vol_id > ai->highest_vol_id) { - ubi_err("highest_vol_id is %d, but vol_id %d is there", + ubi_err(ubi, "highest_vol_id is %d, but vol_id %d is there", ai->highest_vol_id, av->vol_id); goto out; } if (av->vol_type != UBI_DYNAMIC_VOLUME && av->vol_type != UBI_STATIC_VOLUME) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto bad_av; } if (av->data_pad > ubi->leb_size / 2) { - ubi_err("bad data_pad"); + ubi_err(ubi, "bad data_pad"); goto bad_av; } @@ -1553,48 +1562,48 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) leb_count += 1; if (aeb->pnum < 0 || aeb->ec < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto bad_aeb; } if (aeb->ec < ai->min_ec) { - ubi_err("bad ai->min_ec (%d), %d found", + ubi_err(ubi, "bad ai->min_ec (%d), %d found", ai->min_ec, aeb->ec); goto bad_aeb; } if (aeb->ec > ai->max_ec) { - ubi_err("bad ai->max_ec (%d), %d found", + ubi_err(ubi, "bad ai->max_ec (%d), %d found", ai->max_ec, aeb->ec); goto bad_aeb; } if (aeb->pnum >= ubi->peb_count) { - ubi_err("too high PEB number %d, total PEBs %d", + ubi_err(ubi, "too high PEB number %d, total PEBs %d", aeb->pnum, ubi->peb_count); goto bad_aeb; } if (av->vol_type == UBI_STATIC_VOLUME) { if (aeb->lnum >= av->used_ebs) { - ubi_err("bad lnum or used_ebs"); + ubi_err(ubi, "bad lnum or used_ebs"); goto bad_aeb; } } else { if (av->used_ebs != 0) { - ubi_err("non-zero used_ebs"); + ubi_err(ubi, "non-zero used_ebs"); goto bad_aeb; } } if (aeb->lnum > av->highest_lnum) { - ubi_err("incorrect highest_lnum or lnum"); + ubi_err(ubi, "incorrect highest_lnum or lnum"); goto bad_aeb; } } if (av->leb_count != leb_count) { - ubi_err("bad leb_count, %d objects in the tree", + ubi_err(ubi, "bad leb_count, %d objects in the tree", leb_count); goto bad_av; } @@ -1605,13 +1614,13 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) aeb = last_aeb; if (aeb->lnum != av->highest_lnum) { - ubi_err("bad highest_lnum"); + ubi_err(ubi, "bad highest_lnum"); goto bad_aeb; } } if (vols_found != ai->vols_found) { - ubi_err("bad ai->vols_found %d, should be %d", + ubi_err(ubi, "bad ai->vols_found %d, should be %d", ai->vols_found, vols_found); goto out; } @@ -1628,7 +1637,8 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) err = ubi_io_read_vid_hdr(ubi, aeb->pnum, vidh, 1); if (err && err != UBI_IO_BITFLIPS) { - ubi_err("VID header is not OK (%d)", err); + ubi_err(ubi, "VID header is not OK (%d)", + err); if (err > 0) err = -EIO; return err; @@ -1637,37 +1647,37 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) vol_type = vidh->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; if (av->vol_type != vol_type) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto bad_vid_hdr; } if (aeb->sqnum != be64_to_cpu(vidh->sqnum)) { - ubi_err("bad sqnum %llu", aeb->sqnum); + ubi_err(ubi, "bad sqnum %llu", aeb->sqnum); goto bad_vid_hdr; } if (av->vol_id != be32_to_cpu(vidh->vol_id)) { - ubi_err("bad vol_id %d", av->vol_id); + ubi_err(ubi, "bad vol_id %d", av->vol_id); goto bad_vid_hdr; } if (av->compat != vidh->compat) { - ubi_err("bad compat %d", vidh->compat); + ubi_err(ubi, "bad compat %d", vidh->compat); goto bad_vid_hdr; } if (aeb->lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad lnum %d", aeb->lnum); + ubi_err(ubi, "bad lnum %d", aeb->lnum); goto bad_vid_hdr; } if (av->used_ebs != be32_to_cpu(vidh->used_ebs)) { - ubi_err("bad used_ebs %d", av->used_ebs); + ubi_err(ubi, "bad used_ebs %d", av->used_ebs); goto bad_vid_hdr; } if (av->data_pad != be32_to_cpu(vidh->data_pad)) { - ubi_err("bad data_pad %d", av->data_pad); + ubi_err(ubi, "bad data_pad %d", av->data_pad); goto bad_vid_hdr; } } @@ -1676,12 +1686,13 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) continue; if (av->highest_lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad highest_lnum %d", av->highest_lnum); + ubi_err(ubi, "bad highest_lnum %d", av->highest_lnum); goto bad_vid_hdr; } if (av->last_data_size != be32_to_cpu(vidh->data_size)) { - ubi_err("bad last_data_size %d", av->last_data_size); + ubi_err(ubi, "bad last_data_size %d", + av->last_data_size); goto bad_vid_hdr; } } @@ -1722,7 +1733,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) err = 0; for (pnum = 0; pnum < ubi->peb_count; pnum++) if (!buf[pnum]) { - ubi_err("PEB %d is not referred", pnum); + ubi_err(ubi, "PEB %d is not referred", pnum); err = 1; } @@ -1732,18 +1743,18 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) return 0; bad_aeb: - ubi_err("bad attaching information about LEB %d", aeb->lnum); + ubi_err(ubi, "bad attaching information about LEB %d", aeb->lnum); ubi_dump_aeb(aeb, 0); ubi_dump_av(av); goto out; bad_av: - ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_err(ubi, "bad attaching information about volume %d", av->vol_id); ubi_dump_av(av); goto out; bad_vid_hdr: - ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_err(ubi, "bad attaching information about volume %d", av->vol_id); ubi_dump_av(av); ubi_dump_vid_hdr(vidh); diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 290d524b1be..f0a3b679422 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -80,6 +80,7 @@ static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES]; #ifdef CONFIG_MTD_UBI_FASTMAP /* UBI module parameter to enable fastmap automatically on non-fastmap images */ static bool fm_autoconvert; +static bool fm_debug; #endif #else #ifdef CONFIG_MTD_UBI_FASTMAP @@ -87,10 +88,12 @@ static bool fm_autoconvert; #define CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT 0 #endif static bool fm_autoconvert = CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT; +#if !defined(CONFIG_MTD_UBI_FM_DEBUG) +#define CONFIG_MTD_UBI_FM_DEBUG 0 +#endif +static bool fm_debug = CONFIG_MTD_UBI_FM_DEBUG; #endif #endif -/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ -struct class *ubi_class; /* Slab cache for wear-leveling entries */ struct kmem_cache *ubi_wl_entry_slab; @@ -110,7 +113,7 @@ static struct ubi_device *ubi_devices[UBI_MAX_DEVICES]; #else struct ubi_device *ubi_devices[UBI_MAX_DEVICES]; #endif - + #ifndef __UBOOT__ /* Serializes UBI devices creations and removals */ DEFINE_MUTEX(ubi_devices_mutex); @@ -126,8 +129,17 @@ static ssize_t ubi_version_show(struct class *class, } /* UBI version attribute ('/<sysfs>/class/ubi/version') */ -static struct class_attribute ubi_version = - __ATTR(version, S_IRUGO, ubi_version_show, NULL); +static struct class_attribute ubi_class_attrs[] = { + __ATTR(version, S_IRUGO, ubi_version_show, NULL), + __ATTR_NULL +}; + +/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ +struct class ubi_class = { + .name = UBI_NAME_STR, + .owner = THIS_MODULE, + .class_attrs = ubi_class_attrs, +}; static ssize_t dev_attribute_show(struct device *dev, struct device_attribute *attr, char *buf); @@ -169,23 +181,22 @@ static struct device_attribute dev_mtd_num = */ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype) { + int ret; struct ubi_notification nt; ubi_do_get_device_info(ubi, &nt.di); ubi_do_get_volume_info(ubi, vol, &nt.vi); -#ifdef CONFIG_MTD_UBI_FASTMAP switch (ntype) { case UBI_VOLUME_ADDED: case UBI_VOLUME_REMOVED: case UBI_VOLUME_RESIZED: case UBI_VOLUME_RENAMED: - if (ubi_update_fastmap(ubi)) { - ubi_err("Unable to update fastmap!"); - ubi_ro_mode(ubi); - } + ret = ubi_update_fastmap(ubi); + if (ret) + ubi_msg(ubi, "Unable to write a new fastmap: %i", ret); } -#endif + return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt); } @@ -406,6 +417,22 @@ static ssize_t dev_attribute_show(struct device *dev, return ret; } +static struct attribute *ubi_dev_attrs[] = { + &dev_eraseblock_size.attr, + &dev_avail_eraseblocks.attr, + &dev_total_eraseblocks.attr, + &dev_volumes_count.attr, + &dev_max_ec.attr, + &dev_reserved_for_bad.attr, + &dev_bad_peb_count.attr, + &dev_max_vol_count.attr, + &dev_min_io_size.attr, + &dev_bgt_enabled.attr, + &dev_mtd_num.attr, + NULL +}; +ATTRIBUTE_GROUPS(ubi_dev); + static void dev_release(struct device *dev) { struct ubi_device *ubi = container_of(dev, struct ubi_device, dev); @@ -428,45 +455,15 @@ static int ubi_sysfs_init(struct ubi_device *ubi, int *ref) ubi->dev.release = dev_release; ubi->dev.devt = ubi->cdev.dev; - ubi->dev.class = ubi_class; + ubi->dev.class = &ubi_class; + ubi->dev.groups = ubi_dev_groups; dev_set_name(&ubi->dev, UBI_NAME_STR"%d", ubi->ubi_num); err = device_register(&ubi->dev); if (err) return err; *ref = 1; - err = device_create_file(&ubi->dev, &dev_eraseblock_size); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_avail_eraseblocks); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_total_eraseblocks); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_volumes_count); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_max_ec); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_reserved_for_bad); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_bad_peb_count); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_max_vol_count); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_min_io_size); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_bgt_enabled); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_mtd_num); - return err; + return 0; } /** @@ -475,17 +472,6 @@ static int ubi_sysfs_init(struct ubi_device *ubi, int *ref) */ static void ubi_sysfs_close(struct ubi_device *ubi) { - device_remove_file(&ubi->dev, &dev_mtd_num); - device_remove_file(&ubi->dev, &dev_bgt_enabled); - device_remove_file(&ubi->dev, &dev_min_io_size); - device_remove_file(&ubi->dev, &dev_max_vol_count); - device_remove_file(&ubi->dev, &dev_bad_peb_count); - device_remove_file(&ubi->dev, &dev_reserved_for_bad); - device_remove_file(&ubi->dev, &dev_max_ec); - device_remove_file(&ubi->dev, &dev_volumes_count); - device_remove_file(&ubi->dev, &dev_total_eraseblocks); - device_remove_file(&ubi->dev, &dev_avail_eraseblocks); - device_remove_file(&ubi->dev, &dev_eraseblock_size); device_unregister(&ubi->dev); } #endif @@ -541,7 +527,7 @@ static int uif_init(struct ubi_device *ubi, int *ref) */ err = alloc_chrdev_region(&dev, 0, ubi->vtbl_slots + 1, ubi->ubi_name); if (err) { - ubi_err("cannot register UBI character devices"); + ubi_err(ubi, "cannot register UBI character devices"); return err; } @@ -552,7 +538,7 @@ static int uif_init(struct ubi_device *ubi, int *ref) err = cdev_add(&ubi->cdev, dev, 1); if (err) { - ubi_err("cannot add character device"); + ubi_err(ubi, "cannot add character device"); goto out_unreg; } @@ -564,7 +550,7 @@ static int uif_init(struct ubi_device *ubi, int *ref) if (ubi->volumes[i]) { err = ubi_add_volume(ubi, ubi->volumes[i]); if (err) { - ubi_err("cannot add volume %d", i); + ubi_err(ubi, "cannot add volume %d", i); goto out_volumes; } } @@ -580,7 +566,8 @@ out_sysfs: cdev_del(&ubi->cdev); out_unreg: unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); - ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); + ubi_err(ubi, "cannot initialize UBI %s, error %d", + ubi->ubi_name, err); return err; } @@ -674,7 +661,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) * guess we should just pick the largest region. But this is * not implemented. */ - ubi_err("multiple regions, not implemented"); + ubi_err(ubi, "multiple regions, not implemented"); return -EINVAL; } @@ -709,7 +696,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) * which allows us to avoid costly division operations. */ if (!is_power_of_2(ubi->min_io_size)) { - ubi_err("min. I/O unit (%d) is not power of 2", + ubi_err(ubi, "min. I/O unit (%d) is not power of 2", ubi->min_io_size); return -EINVAL; } @@ -726,7 +713,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) if (ubi->max_write_size < ubi->min_io_size || ubi->max_write_size % ubi->min_io_size || !is_power_of_2(ubi->max_write_size)) { - ubi_err("bad write buffer size %d for %d min. I/O unit", + ubi_err(ubi, "bad write buffer size %d for %d min. I/O unit", ubi->max_write_size, ubi->min_io_size); return -EINVAL; } @@ -763,7 +750,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) /* The shift must be aligned to 32-bit boundary */ if (ubi->vid_hdr_shift % 4) { - ubi_err("unaligned VID header shift %d", + ubi_err(ubi, "unaligned VID header shift %d", ubi->vid_hdr_shift); return -EINVAL; } @@ -773,7 +760,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || ubi->leb_start & (ubi->min_io_size - 1)) { - ubi_err("bad VID header (%d) or data offsets (%d)", + ubi_err(ubi, "bad VID header (%d) or data offsets (%d)", ubi->vid_hdr_offset, ubi->leb_start); return -EINVAL; } @@ -793,14 +780,14 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) * read-only mode. */ if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) { - ubi_warn("EC and VID headers are in the same minimal I/O unit, switch to read-only mode"); + ubi_warn(ubi, "EC and VID headers are in the same minimal I/O unit, switch to read-only mode"); ubi->ro_mode = 1; } ubi->leb_size = ubi->peb_size - ubi->leb_start; if (!(ubi->mtd->flags & MTD_WRITEABLE)) { - ubi_msg("MTD device %d is write-protected, attach in read-only mode", + ubi_msg(ubi, "MTD device %d is write-protected, attach in read-only mode", ubi->mtd->index); ubi->ro_mode = 1; } @@ -833,7 +820,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) int err, old_reserved_pebs = vol->reserved_pebs; if (ubi->ro_mode) { - ubi_warn("skip auto-resize because of R/O mode"); + ubi_warn(ubi, "skip auto-resize because of R/O mode"); return 0; } @@ -854,21 +841,22 @@ static int autoresize(struct ubi_device *ubi, int vol_id) vtbl_rec = ubi->vtbl[vol_id]; err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) - ubi_err("cannot clean auto-resize flag for volume %d", + ubi_err(ubi, "cannot clean auto-resize flag for volume %d", vol_id); } else { desc.vol = vol; err = ubi_resize_volume(&desc, old_reserved_pebs + ubi->avail_pebs); if (err) - ubi_err("cannot auto-resize volume %d", vol_id); + ubi_err(ubi, "cannot auto-resize volume %d", + vol_id); } if (err) return err; - ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, - vol->name, old_reserved_pebs, vol->reserved_pebs); + ubi_msg(ubi, "volume %d (\"%s\") re-sized from %d to %d LEBs", + vol_id, vol->name, old_reserved_pebs, vol->reserved_pebs); return 0; } @@ -909,7 +897,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, for (i = 0; i < UBI_MAX_DEVICES; i++) { ubi = ubi_devices[i]; if (ubi && mtd->index == ubi->mtd->index) { - ubi_err("mtd%d is already attached to ubi%d", + ubi_err(ubi, "mtd%d is already attached to ubi%d", mtd->index, i); return -EEXIST; } @@ -924,7 +912,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, * no sense to attach emulated MTD devices, so we prohibit this. */ if (mtd->type == MTD_UBIVOLUME) { - ubi_err("refuse attaching mtd%d - it is already emulated on top of UBI", + ubi_err(ubi, "refuse attaching mtd%d - it is already emulated on top of UBI", mtd->index); return -EINVAL; } @@ -935,7 +923,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!ubi_devices[ubi_num]) break; if (ubi_num == UBI_MAX_DEVICES) { - ubi_err("only %d UBI devices may be created", + ubi_err(ubi, "only %d UBI devices may be created", UBI_MAX_DEVICES); return -ENFILE; } @@ -945,7 +933,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, /* Make sure ubi_num is not busy */ if (ubi_devices[ubi_num]) { - ubi_err("ubi%d already exists", ubi_num); + ubi_err(ubi, "already exists"); return -EEXIST; } } @@ -969,21 +957,24 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, */ ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE); - if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE) - ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE; + ubi->fm_pool.max_size = max(ubi->fm_pool.max_size, + UBI_FM_MIN_POOL_SIZE); - ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE; + ubi->fm_wl_pool.max_size = ubi->fm_pool.max_size / 2; ubi->fm_disabled = !fm_autoconvert; + if (fm_debug) + ubi_enable_dbg_chk_fastmap(ubi); if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) { - ubi_err("More than %i PEBs are needed for fastmap, sorry.", + ubi_err(ubi, "More than %i PEBs are needed for fastmap, sorry.", UBI_FM_MAX_START); ubi->fm_disabled = 1; } - ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size); - ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); + ubi_msg(ubi, "default fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg(ubi, "default fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); #else ubi->fm_disabled = 1; #endif @@ -991,10 +982,10 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, mutex_init(&ubi->ckvol_mutex); mutex_init(&ubi->device_mutex); spin_lock_init(&ubi->volumes_lock); - mutex_init(&ubi->fm_mutex); - init_rwsem(&ubi->fm_sem); + init_rwsem(&ubi->fm_protect); + init_rwsem(&ubi->fm_eba_sem); - ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); + ubi_msg(ubi, "attaching mtd%d", mtd->index); err = io_init(ubi, max_beb_per1024); if (err) @@ -1013,7 +1004,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, #endif err = ubi_attach(ubi, 0); if (err) { - ubi_err("failed to attach mtd%d, error %d", mtd->index, err); + ubi_err(ubi, "failed to attach mtd%d, error %d", + mtd->index, err); goto out_free; } @@ -1034,28 +1026,28 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->bgt_thread = kthread_create(ubi_thread, ubi, "%s", ubi->bgt_name); if (IS_ERR(ubi->bgt_thread)) { err = PTR_ERR(ubi->bgt_thread); - ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name, - err); + ubi_err(ubi, "cannot spawn \"%s\", error %d", + ubi->bgt_name, err); goto out_debugfs; } - ubi_msg("attached mtd%d (name \"%s\", size %llu MiB) to ubi%d", - mtd->index, mtd->name, ubi->flash_size >> 20, ubi_num); - ubi_msg("PEB size: %d bytes (%d KiB), LEB size: %d bytes", + ubi_msg(ubi, "attached mtd%d (name \"%s\", size %llu MiB)", + mtd->index, mtd->name, ubi->flash_size >> 20); + ubi_msg(ubi, "PEB size: %d bytes (%d KiB), LEB size: %d bytes", ubi->peb_size, ubi->peb_size >> 10, ubi->leb_size); - ubi_msg("min./max. I/O unit sizes: %d/%d, sub-page size %d", + ubi_msg(ubi, "min./max. I/O unit sizes: %d/%d, sub-page size %d", ubi->min_io_size, ubi->max_write_size, ubi->hdrs_min_io_size); - ubi_msg("VID header offset: %d (aligned %d), data offset: %d", + ubi_msg(ubi, "VID header offset: %d (aligned %d), data offset: %d", ubi->vid_hdr_offset, ubi->vid_hdr_aloffset, ubi->leb_start); - ubi_msg("good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d", + ubi_msg(ubi, "good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d", ubi->good_peb_count, ubi->bad_peb_count, ubi->corr_peb_count); - ubi_msg("user volume: %d, internal volumes: %d, max. volumes count: %d", + ubi_msg(ubi, "user volume: %d, internal volumes: %d, max. volumes count: %d", ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT, ubi->vtbl_slots); - ubi_msg("max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", + ubi_msg(ubi, "max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD, ubi->image_seq); - ubi_msg("available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", + ubi_msg(ubi, "available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); /* @@ -1064,7 +1056,20 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, */ spin_lock(&ubi->wl_lock); ubi->thread_enabled = 1; +#ifndef __UBOOT__ wake_up_process(ubi->bgt_thread); +#else + /* + * U-Boot special: We have no bgt_thread in U-Boot! + * So just call do_work() here directly. + */ + err = do_work(ubi); + if (err) { + ubi_err(ubi, "%s: work failed with error code %d", + ubi->bgt_name, err); + } +#endif + spin_unlock(&ubi->wl_lock); ubi_devices[ubi_num] = ubi; @@ -1124,7 +1129,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) return -EBUSY; } /* This may only happen if there is a bug */ - ubi_err("%s reference count %d, destroy anyway", + ubi_err(ubi, "%s reference count %d, destroy anyway", ubi->ubi_name, ubi->ref_count); } ubi_devices[ubi_num] = NULL; @@ -1132,11 +1137,14 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_assert(ubi_num == ubi->ubi_num); ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); - ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); + ubi_msg(ubi, "detaching mtd%d", ubi->mtd->index); #ifdef CONFIG_MTD_UBI_FASTMAP /* If we don't write a new fastmap at detach time we lose all - * EC updates that have been made since the last written fastmap. */ - ubi_update_fastmap(ubi); + * EC updates that have been made since the last written fastmap. + * In case of fastmap debugging we omit the update to simulate an + * unclean shutdown. */ + if (!ubi_dbg_chk_fastmap(ubi)) + ubi_update_fastmap(ubi); #endif /* * Before freeing anything, we have to stop the background thread to @@ -1160,7 +1168,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) put_mtd_device(ubi->mtd); vfree(ubi->peb_buf); vfree(ubi->fm_buf); - ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); + ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index); put_device(&ubi->dev); return 0; } @@ -1185,9 +1193,9 @@ static struct mtd_info * __init open_mtd_by_chdev(const char *mtd_dev) return ERR_PTR(err); /* MTD device number is defined by the major / minor numbers */ - major = imajor(path.dentry->d_inode); - minor = iminor(path.dentry->d_inode); - mode = path.dentry->d_inode->i_mode; + major = imajor(d_backing_inode(path.dentry)); + minor = iminor(d_backing_inode(path.dentry)); + mode = d_backing_inode(path.dentry)->i_mode; path_put(&path); if (major != MTD_CHAR_MAJOR || !S_ISCHR(mode)) return ERR_PTR(-EINVAL); @@ -1250,28 +1258,20 @@ int ubi_init(void) BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); if (mtd_devs > UBI_MAX_DEVICES) { - ubi_err("too many MTD devices, maximum is %d", UBI_MAX_DEVICES); + pr_err("UBI error: too many MTD devices, maximum is %d", + UBI_MAX_DEVICES); return -EINVAL; } /* Create base sysfs directory and sysfs files */ - ubi_class = class_create(THIS_MODULE, UBI_NAME_STR); - if (IS_ERR(ubi_class)) { - err = PTR_ERR(ubi_class); - ubi_err("cannot create UBI class"); - goto out; - } - - err = class_create_file(ubi_class, &ubi_version); - if (err) { - ubi_err("cannot create sysfs file"); - goto out_class; - } + err = class_register(&ubi_class); + if (err < 0) + return err; err = misc_register(&ubi_ctrl_cdev); if (err) { - ubi_err("cannot register device"); - goto out_version; + pr_err("UBI error: cannot register device"); + goto out; } ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", @@ -1297,7 +1297,8 @@ int ubi_init(void) mtd = open_mtd_device(p->name); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - ubi_err("cannot open mtd %s, error %d", p->name, err); + pr_err("UBI error: cannot open mtd %s, error %d", + p->name, err); /* See comment below re-ubi_is_module(). */ if (ubi_is_module()) goto out_detach; @@ -1309,7 +1310,8 @@ int ubi_init(void) p->vid_hdr_offs, p->max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) { - ubi_err("cannot attach mtd%d", mtd->index); + pr_err("UBI error: cannot attach mtd%d", + mtd->index); put_mtd_device(mtd); /* @@ -1332,7 +1334,7 @@ int ubi_init(void) err = ubiblock_init(); if (err) { - ubi_err("block: cannot initialize, error %d", err); + pr_err("UBI error: block: cannot initialize, error %d", err); /* See comment above re-ubi_is_module(). */ if (ubi_is_module()) @@ -1353,16 +1355,13 @@ out_slab: kmem_cache_destroy(ubi_wl_entry_slab); out_dev_unreg: misc_deregister(&ubi_ctrl_cdev); -out_version: - class_remove_file(ubi_class, &ubi_version); -out_class: - class_destroy(ubi_class); out: #ifdef __UBOOT__ /* Reset any globals that the driver depends on being zeroed */ mtd_devs = 0; #endif - ubi_err("cannot initialize UBI, error %d", err); + class_unregister(&ubi_class); + pr_err("UBI error: cannot initialize UBI, error %d", err); return err; } late_initcall(ubi_init); @@ -1386,8 +1385,7 @@ void ubi_exit(void) ubi_debugfs_exit(); kmem_cache_destroy(ubi_wl_entry_slab); misc_deregister(&ubi_ctrl_cdev); - class_remove_file(ubi_class, &ubi_version); - class_destroy(ubi_class); + class_unregister(&ubi_class); #ifdef __UBOOT__ /* Reset any globals that the driver depends on being zeroed */ mtd_devs = 0; @@ -1409,7 +1407,7 @@ static int __init bytes_str_to_int(const char *str) result = simple_strtoul(str, &endp, 0); if (str == endp || result >= INT_MAX) { - ubi_err("incorrect bytes count: \"%s\"\n", str); + pr_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1425,7 +1423,7 @@ static int __init bytes_str_to_int(const char *str) case '\0': break; default: - ubi_err("incorrect bytes count: \"%s\"\n", str); + pr_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1467,15 +1465,15 @@ int ubi_mtd_param_parse(const char *val, struct kernel_param *kp) return -EINVAL; if (mtd_devs == UBI_MAX_DEVICES) { - ubi_err("too many parameters, max. is %d\n", - UBI_MAX_DEVICES); + pr_err("UBI error: too many parameters, max. is %d\n", + UBI_MAX_DEVICES); return -EINVAL; } len = strnlen(val, MTD_PARAM_LEN_MAX); if (len == MTD_PARAM_LEN_MAX) { - ubi_err("parameter \"%s\" is too long, max. is %d\n", - val, MTD_PARAM_LEN_MAX); + pr_err("UBI error: parameter \"%s\" is too long, max. is %d\n", + val, MTD_PARAM_LEN_MAX); return -EINVAL; } @@ -1494,7 +1492,7 @@ int ubi_mtd_param_parse(const char *val, struct kernel_param *kp) tokens[i] = strsep(&pbuf, ","); if (pbuf) { - ubi_err("too many arguments at \"%s\"\n", val); + pr_err("UBI error: too many arguments at \"%s\"\n", val); return -EINVAL; } @@ -1514,8 +1512,8 @@ int ubi_mtd_param_parse(const char *val, struct kernel_param *kp) int err = kstrtoint(token, 10, &p->max_beb_per1024); if (err) { - ubi_err("bad value for max_beb_per1024 parameter: %s", - token); + pr_err("UBI error: bad value for max_beb_per1024 parameter: %s", + token); return -EINVAL; } } @@ -1525,7 +1523,8 @@ int ubi_mtd_param_parse(const char *val, struct kernel_param *kp) int err = kstrtoint(token, 10, &p->ubi_num); if (err) { - ubi_err("bad value for ubi_num parameter: %s", token); + pr_err("UBI error: bad value for ubi_num parameter: %s", + token); return -EINVAL; } } else @@ -1552,6 +1551,8 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa #ifdef CONFIG_MTD_UBI_FASTMAP module_param(fm_autoconvert, bool, 0644); MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); +module_param(fm_debug, bool, 0); +MODULE_PARM_DESC(fm_debug, "Set this parameter to enable fastmap debugging by default. Warning, this will make fastmap slow!"); #endif MODULE_VERSION(__stringify(UBI_VERSION)); MODULE_DESCRIPTION("UBI - Unsorted Block Images"); diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 6dcc4e4844b..c35c85b18c6 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -33,12 +33,12 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) return; err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err && err != -EUCLEAN) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes", + ubi_err(ubi, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes", err, len, pnum, offset, read); goto out; } - ubi_msg("dumping %d bytes of data from PEB %d, offset %d", + ubi_msg(ubi, "dumping %d bytes of data from PEB %d, offset %d", len, pnum, offset); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); out: @@ -229,8 +229,8 @@ int ubi_debugfs_init(void) if (IS_ERR_OR_NULL(dfs_rootdir)) { int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); - ubi_err("cannot create \"ubi\" debugfs directory, error %d\n", - err); + pr_err("UBI error: cannot create \"ubi\" debugfs directory, error %d\n", + err); return err; } @@ -254,7 +254,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf, struct dentry *dent = file->f_path.dentry; struct ubi_device *ubi; struct ubi_debug_info *d; - char buf[3]; + char buf[8]; int val; ubi = ubi_get_device(ubi_num); @@ -266,12 +266,30 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf, val = d->chk_gen; else if (dent == d->dfs_chk_io) val = d->chk_io; + else if (dent == d->dfs_chk_fastmap) + val = d->chk_fastmap; else if (dent == d->dfs_disable_bgt) val = d->disable_bgt; else if (dent == d->dfs_emulate_bitflips) val = d->emulate_bitflips; else if (dent == d->dfs_emulate_io_failures) val = d->emulate_io_failures; + else if (dent == d->dfs_emulate_power_cut) { + snprintf(buf, sizeof(buf), "%u\n", d->emulate_power_cut); + count = simple_read_from_buffer(user_buf, count, ppos, + buf, strlen(buf)); + goto out; + } else if (dent == d->dfs_power_cut_min) { + snprintf(buf, sizeof(buf), "%u\n", d->power_cut_min); + count = simple_read_from_buffer(user_buf, count, ppos, + buf, strlen(buf)); + goto out; + } else if (dent == d->dfs_power_cut_max) { + snprintf(buf, sizeof(buf), "%u\n", d->power_cut_max); + count = simple_read_from_buffer(user_buf, count, ppos, + buf, strlen(buf)); + goto out; + } else { count = -EINVAL; goto out; @@ -300,7 +318,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, struct ubi_device *ubi; struct ubi_debug_info *d; size_t buf_size; - char buf[8]; + char buf[8] = {0}; int val; ubi = ubi_get_device(ubi_num); @@ -314,6 +332,21 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, goto out; } + if (dent == d->dfs_power_cut_min) { + if (kstrtouint(buf, 0, &d->power_cut_min) != 0) + count = -EINVAL; + goto out; + } else if (dent == d->dfs_power_cut_max) { + if (kstrtouint(buf, 0, &d->power_cut_max) != 0) + count = -EINVAL; + goto out; + } else if (dent == d->dfs_emulate_power_cut) { + if (kstrtoint(buf, 0, &val) != 0) + count = -EINVAL; + d->emulate_power_cut = val; + goto out; + } + if (buf[0] == '1') val = 1; else if (buf[0] == '0') @@ -327,6 +360,8 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, d->chk_gen = val; else if (dent == d->dfs_chk_io) d->chk_io = val; + else if (dent == d->dfs_chk_fastmap) + d->chk_fastmap = val; else if (dent == d->dfs_disable_bgt) d->disable_bgt = val; else if (dent == d->dfs_emulate_bitflips) @@ -397,6 +432,13 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) goto out_remove; d->dfs_chk_io = dent; + fname = "chk_fastmap"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_chk_fastmap = dent; + fname = "tst_disable_bgt"; dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, &dfs_fops); @@ -418,13 +460,34 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) goto out_remove; d->dfs_emulate_io_failures = dent; + fname = "tst_emulate_power_cut"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_emulate_power_cut = dent; + + fname = "tst_emulate_power_cut_min"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_power_cut_min = dent; + + fname = "tst_emulate_power_cut_max"; + dent = debugfs_create_file(fname, S_IWUSR, d->dfs_dir, (void *)ubi_num, + &dfs_fops); + if (IS_ERR_OR_NULL(dent)) + goto out_remove; + d->dfs_power_cut_max = dent; + return 0; out_remove: debugfs_remove_recursive(d->dfs_dir); out: err = dent ? PTR_ERR(dent) : -ENODEV; - ubi_err("cannot create \"%s\" debugfs file or directory, error %d\n", + ubi_err(ubi, "cannot create \"%s\" debugfs file or directory, error %d\n", fname, err); return err; } @@ -438,6 +501,39 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi) if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove_recursive(ubi->dbg.dfs_dir); } + +/** + * ubi_dbg_power_cut - emulate a power cut if it is time to do so + * @ubi: UBI device description object + * @caller: Flags set to indicate from where the function is being called + * + * Returns non-zero if a power cut was emulated, zero if not. + */ +int ubi_dbg_power_cut(struct ubi_device *ubi, int caller) +{ + unsigned int range; + + if ((ubi->dbg.emulate_power_cut & caller) == 0) + return 0; + + if (ubi->dbg.power_cut_counter == 0) { + ubi->dbg.power_cut_counter = ubi->dbg.power_cut_min; + + if (ubi->dbg.power_cut_max > ubi->dbg.power_cut_min) { + range = ubi->dbg.power_cut_max - ubi->dbg.power_cut_min; + ubi->dbg.power_cut_counter += prandom_u32() % range; + } + return 0; + } + + ubi->dbg.power_cut_counter--; + if (ubi->dbg.power_cut_counter) + return 0; + + ubi_msg(ubi, "XXXXXXXXXXXXXXX emulating a power cut XXXXXXXXXXXXXXXX"); + ubi_ro_mode(ubi); + return 1; +} #else int ubi_debugfs_init(void) { @@ -456,4 +552,9 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) void ubi_debugfs_exit_dev(struct ubi_device *ubi) { } + +int ubi_dbg_power_cut(struct ubi_device *ubi, int caller) +{ + return 0; +} #endif diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index bfa9dfb42bd..d8d824e4879 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -117,4 +117,16 @@ static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi) { return ubi->dbg.chk_gen; } + +static inline int ubi_dbg_chk_fastmap(const struct ubi_device *ubi) +{ + return ubi->dbg.chk_fastmap; +} + +static inline void ubi_enable_dbg_chk_fastmap(struct ubi_device *ubi) +{ + ubi->dbg.chk_fastmap = 1; +} + +int ubi_dbg_power_cut(struct ubi_device *ubi, int caller); #endif /* !__UBI_DEBUG_H__ */ diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index fce0ff8bdf0..6a78f672cde 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -333,9 +333,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); - down_read(&ubi->fm_sem); + down_read(&ubi->fm_eba_sem); vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; - up_read(&ubi->fm_sem); + up_read(&ubi->fm_eba_sem); err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); out_unlock: @@ -415,11 +415,13 @@ retry: */ if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_BAD_HDR) { - ubi_warn("corrupted VID header at PEB %d, LEB %d:%d", + ubi_warn(ubi, "corrupted VID header at PEB %d, LEB %d:%d", pnum, vol_id, lnum); err = -EBADMSG; - } else + } else { + err = -EINVAL; ubi_ro_mode(ubi); + } } goto out_free; } else if (err == UBI_IO_BITFLIPS) @@ -434,15 +436,14 @@ retry: err = ubi_io_read_data(ubi, buf, pnum, offset, len); if (err) { - if (err == UBI_IO_BITFLIPS) { + if (err == UBI_IO_BITFLIPS) scrub = 1; - err = 0; - } else if (mtd_is_eccerr(err)) { + else if (mtd_is_eccerr(err)) { if (vol->vol_type == UBI_DYNAMIC_VOLUME) goto out_unlock; scrub = 1; if (!check) { - ubi_msg("force data checking"); + ubi_msg(ubi, "force data checking"); check = 1; goto retry; } @@ -453,7 +454,7 @@ retry: if (check) { uint32_t crc1 = crc32(UBI_CRC32_INIT, buf, len); if (crc1 != crc) { - ubi_warn("CRC error: calculated %#08x, must be %#08x", + ubi_warn(ubi, "CRC error: calculated %#08x, must be %#08x", crc1, crc); err = -EBADMSG; goto out_unlock; @@ -473,6 +474,63 @@ out_unlock: return err; } +#ifndef __UBOOT__ +/** + * ubi_eba_read_leb_sg - read data into a scatter gather list. + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * @sgl: UBI scatter gather list to store the read data + * @offset: offset from where to read + * @len: how many bytes to read + * @check: data CRC check flag + * + * This function works exactly like ubi_eba_read_leb(). But instead of + * storing the read data into a buffer it writes to an UBI scatter gather + * list. + */ +int ubi_eba_read_leb_sg(struct ubi_device *ubi, struct ubi_volume *vol, + struct ubi_sgl *sgl, int lnum, int offset, int len, + int check) +{ + int to_read; + int ret; + struct scatterlist *sg; + + for (;;) { + ubi_assert(sgl->list_pos < UBI_MAX_SG_COUNT); + sg = &sgl->sg[sgl->list_pos]; + if (len < sg->length - sgl->page_pos) + to_read = len; + else + to_read = sg->length - sgl->page_pos; + + ret = ubi_eba_read_leb(ubi, vol, lnum, + sg_virt(sg) + sgl->page_pos, offset, + to_read, check); + if (ret < 0) + return ret; + + offset += to_read; + len -= to_read; + if (!len) { + sgl->page_pos += to_read; + if (sgl->page_pos == sg->length) { + sgl->list_pos++; + sgl->page_pos = 0; + } + + break; + } + + sgl->list_pos++; + sgl->page_pos = 0; + } + + return ret; +} +#endif + /** * recover_peb - recover from write failure. * @ubi: UBI device description object @@ -504,22 +562,27 @@ retry: new_pnum = ubi_wl_get_peb(ubi); if (new_pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); + up_read(&ubi->fm_eba_sem); return new_pnum; } - ubi_msg("recover PEB %d, move data to PEB %d", pnum, new_pnum); + ubi_msg(ubi, "recover PEB %d, move data to PEB %d", + pnum, new_pnum); err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); if (err && err != UBI_IO_BITFLIPS) { if (err > 0) err = -EIO; + up_read(&ubi->fm_eba_sem); goto out_put; } vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); - if (err) + if (err) { + up_read(&ubi->fm_eba_sem); goto write_error; + } data_size = offset + len; mutex_lock(&ubi->buf_mutex); @@ -528,8 +591,10 @@ retry: /* Read everything before the area where the write failure happened */ if (offset > 0) { err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset); - if (err && err != UBI_IO_BITFLIPS) + if (err && err != UBI_IO_BITFLIPS) { + up_read(&ubi->fm_eba_sem); goto out_unlock; + } } memcpy(ubi->peb_buf + offset, buf, len); @@ -537,18 +602,18 @@ retry: err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); if (err) { mutex_unlock(&ubi->buf_mutex); + up_read(&ubi->fm_eba_sem); goto write_error; } mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); - down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = new_pnum; - up_read(&ubi->fm_sem); + up_read(&ubi->fm_eba_sem); ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); - ubi_msg("data was successfully recovered"); + ubi_msg(ubi, "data was successfully recovered"); return 0; out_unlock: @@ -563,13 +628,13 @@ write_error: * Bad luck? This physical eraseblock is bad too? Crud. Let's try to * get another one. */ - ubi_warn("failed to write to PEB %d", new_pnum); + ubi_warn(ubi, "failed to write to PEB %d", new_pnum); ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); if (++tries > UBI_IO_RETRIES) { ubi_free_vid_hdr(ubi, vid_hdr); return err; } - ubi_msg("try again"); + ubi_msg(ubi, "try again"); goto retry; } @@ -607,7 +672,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, err = ubi_io_write_data(ubi, buf, pnum, offset, len); if (err) { - ubi_warn("failed to write data to PEB %d", pnum); + ubi_warn(ubi, "failed to write data to PEB %d", pnum); if (err == -EIO && ubi->bad_allowed) err = recover_peb(ubi, pnum, vol_id, lnum, buf, offset, len); @@ -640,6 +705,7 @@ retry: if (pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); + up_read(&ubi->fm_eba_sem); return pnum; } @@ -648,23 +714,24 @@ retry: err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); if (err) { - ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", vol_id, lnum, pnum); + up_read(&ubi->fm_eba_sem); goto write_error; } if (len) { err = ubi_io_write_data(ubi, buf, pnum, offset, len); if (err) { - ubi_warn("failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", len, offset, vol_id, lnum, pnum); + up_read(&ubi->fm_eba_sem); goto write_error; } } - down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; - up_read(&ubi->fm_sem); + up_read(&ubi->fm_eba_sem); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -692,7 +759,7 @@ write_error: } vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); - ubi_msg("try another PEB"); + ubi_msg(ubi, "try another PEB"); goto retry; } @@ -761,6 +828,7 @@ retry: if (pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); + up_read(&ubi->fm_eba_sem); return pnum; } @@ -769,22 +837,23 @@ retry: err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); if (err) { - ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", vol_id, lnum, pnum); + up_read(&ubi->fm_eba_sem); goto write_error; } err = ubi_io_write_data(ubi, buf, pnum, 0, len); if (err) { - ubi_warn("failed to write %d bytes of data to PEB %d", + ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", len, pnum); + up_read(&ubi->fm_eba_sem); goto write_error; } ubi_assert(vol->eba_tbl[lnum] < 0); - down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; - up_read(&ubi->fm_sem); + up_read(&ubi->fm_eba_sem); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -812,7 +881,7 @@ write_error: } vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); - ubi_msg("try another PEB"); + ubi_msg(ubi, "try another PEB"); goto retry; } @@ -836,7 +905,7 @@ write_error: int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, const void *buf, int len) { - int err, pnum, tries = 0, vol_id = vol->vol_id; + int err, pnum, old_pnum, tries = 0, vol_id = vol->vol_id; struct ubi_vid_hdr *vid_hdr; uint32_t crc; @@ -879,6 +948,7 @@ retry: pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { err = pnum; + up_read(&ubi->fm_eba_sem); goto out_leb_unlock; } @@ -887,28 +957,30 @@ retry: err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); if (err) { - ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + ubi_warn(ubi, "failed to write VID header to LEB %d:%d, PEB %d", vol_id, lnum, pnum); + up_read(&ubi->fm_eba_sem); goto write_error; } err = ubi_io_write_data(ubi, buf, pnum, 0, len); if (err) { - ubi_warn("failed to write %d bytes of data to PEB %d", + ubi_warn(ubi, "failed to write %d bytes of data to PEB %d", len, pnum); + up_read(&ubi->fm_eba_sem); goto write_error; } - if (vol->eba_tbl[lnum] >= 0) { - err = ubi_wl_put_peb(ubi, vol_id, lnum, vol->eba_tbl[lnum], 0); + old_pnum = vol->eba_tbl[lnum]; + vol->eba_tbl[lnum] = pnum; + up_read(&ubi->fm_eba_sem); + + if (old_pnum >= 0) { + err = ubi_wl_put_peb(ubi, vol_id, lnum, old_pnum, 0); if (err) goto out_leb_unlock; } - down_read(&ubi->fm_sem); - vol->eba_tbl[lnum] = pnum; - up_read(&ubi->fm_sem); - out_leb_unlock: leb_write_unlock(ubi, vol_id, lnum); out_mutex: @@ -934,7 +1006,7 @@ write_error: } vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); - ubi_msg("try another PEB"); + ubi_msg(ubi, "try another PEB"); goto retry; } @@ -1057,7 +1129,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, dbg_wl("read %d bytes of data", aldata_size); err = ubi_io_read_data(ubi, ubi->peb_buf, from, 0, aldata_size); if (err && err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading data from PEB %d", + ubi_warn(ubi, "error %d while reading data from PEB %d", err, from); err = MOVE_SOURCE_RD_ERR; goto out_unlock_buf; @@ -1107,7 +1179,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1); if (err) { if (err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading VID header back from PEB %d", + ubi_warn(ubi, "error %d while reading VID header back from PEB %d", err, to); if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; @@ -1134,7 +1206,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading data back from PEB %d", + ubi_warn(ubi, "error %d while reading data back from PEB %d", err, to); if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; @@ -1146,7 +1218,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) { - ubi_warn("read data back from PEB %d and it is different", + ubi_warn(ubi, "read data back from PEB %d and it is different", to); err = -EINVAL; goto out_unlock_buf; @@ -1154,9 +1226,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } ubi_assert(vol->eba_tbl[lnum] == from); - down_read(&ubi->fm_sem); + down_read(&ubi->fm_eba_sem); vol->eba_tbl[lnum] = to; - up_read(&ubi->fm_sem); + up_read(&ubi->fm_eba_sem); out_unlock_buf: mutex_unlock(&ubi->buf_mutex); @@ -1199,10 +1271,10 @@ static void print_rsvd_warning(struct ubi_device *ubi, return; } - ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d, need %d", + ubi_warn(ubi, "cannot reserve enough PEBs for bad PEB handling, reserved %d, need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); if (ubi->corr_peb_count) - ubi_warn("%d PEBs are corrupted and not used", + ubi_warn(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); } @@ -1280,7 +1352,7 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, fm_eba[i][j] == UBI_LEB_UNMAPPED) continue; - ubi_err("LEB:%i:%i is PEB:%i instead of %i!", + ubi_err(ubi, "LEB:%i:%i is PEB:%i instead of %i!", vol->vol_id, i, fm_eba[i][j], scan_eba[i][j]); ubi_assert(0); @@ -1355,15 +1427,16 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai) * during re-size. */ ubi_move_aeb_to_list(av, aeb, &ai->erase); - vol->eba_tbl[aeb->lnum] = aeb->pnum; + else + vol->eba_tbl[aeb->lnum] = aeb->pnum; } } if (ubi->avail_pebs < EBA_RESERVED_PEBS) { - ubi_err("no enough physical eraseblocks (%d, need %d)", + ubi_err(ubi, "no enough physical eraseblocks (%d, need %d)", ubi->avail_pebs, EBA_RESERVED_PEBS); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); err = -ENOSPC; goto out_free; diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c new file mode 100644 index 00000000000..a33d4063e06 --- /dev/null +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2012 Linutronix GmbH + * Copyright (c) 2014 sigma star gmbh + * Author: Richard Weinberger <richard@nod.at> + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ + +/** + * update_fastmap_work_fn - calls ubi_update_fastmap from a work queue + * @wrk: the work description object + */ +#ifndef __UBOOT__ +static void update_fastmap_work_fn(struct work_struct *wrk) +#else +void update_fastmap_work_fn(struct ubi_device *ubi) +#endif +{ +#ifndef __UBOOT__ + struct ubi_device *ubi = container_of(wrk, struct ubi_device, fm_work); +#endif + + ubi_update_fastmap(ubi); + spin_lock(&ubi->wl_lock); + ubi->fm_work_scheduled = 0; + spin_unlock(&ubi->wl_lock); +} + +/** + * find_anchor_wl_entry - find wear-leveling entry to used as anchor PEB. + * @root: the RB-tree where to look for + */ +static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root) +{ + struct rb_node *p; + struct ubi_wl_entry *e, *victim = NULL; + int max_ec = UBI_MAX_ERASECOUNTER; + + ubi_rb_for_each_entry(p, e, root, u.rb) { + if (e->pnum < UBI_FM_MAX_START && e->ec < max_ec) { + victim = e; + max_ec = e->ec; + } + } + + return victim; +} + +/** + * return_unused_pool_pebs - returns unused PEB to the free tree. + * @ubi: UBI device description object + * @pool: fastmap pool description object + */ +static void return_unused_pool_pebs(struct ubi_device *ubi, + struct ubi_fm_pool *pool) +{ + int i; + struct ubi_wl_entry *e; + + for (i = pool->used; i < pool->size; i++) { + e = ubi->lookuptbl[pool->pebs[i]]; + wl_tree_add(e, &ubi->free); + ubi->free_count++; + } +} + +static int anchor_pebs_avalible(struct rb_root *root) +{ + struct rb_node *p; + struct ubi_wl_entry *e; + + ubi_rb_for_each_entry(p, e, root, u.rb) + if (e->pnum < UBI_FM_MAX_START) + return 1; + + return 0; +} + +/** + * ubi_wl_get_fm_peb - find a physical erase block with a given maximal number. + * @ubi: UBI device description object + * @anchor: This PEB will be used as anchor PEB by fastmap + * + * The function returns a physical erase block with a given maximal number + * and removes it from the wl subsystem. + * Must be called with wl_lock held! + */ +struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor) +{ + struct ubi_wl_entry *e = NULL; + + if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1)) + goto out; + + if (anchor) + e = find_anchor_wl_entry(&ubi->free); + else + e = find_mean_wl_entry(ubi, &ubi->free); + + if (!e) + goto out; + + self_check_in_wl_tree(ubi, e, &ubi->free); + + /* remove it from the free list, + * the wl subsystem does no longer know this erase block */ + rb_erase(&e->u.rb, &ubi->free); + ubi->free_count--; +out: + return e; +} + +/** + * ubi_refill_pools - refills all fastmap PEB pools. + * @ubi: UBI device description object + */ +void ubi_refill_pools(struct ubi_device *ubi) +{ + struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; + struct ubi_fm_pool *pool = &ubi->fm_pool; + struct ubi_wl_entry *e; + int enough; + + spin_lock(&ubi->wl_lock); + + return_unused_pool_pebs(ubi, wl_pool); + return_unused_pool_pebs(ubi, pool); + + wl_pool->size = 0; + pool->size = 0; + + for (;;) { + enough = 0; + if (pool->size < pool->max_size) { + if (!ubi->free.rb_node) + break; + + e = wl_get_wle(ubi); + if (!e) + break; + + pool->pebs[pool->size] = e->pnum; + pool->size++; + } else + enough++; + + if (wl_pool->size < wl_pool->max_size) { + if (!ubi->free.rb_node || + (ubi->free_count - ubi->beb_rsvd_pebs < 5)) + break; + + e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); + self_check_in_wl_tree(ubi, e, &ubi->free); + rb_erase(&e->u.rb, &ubi->free); + ubi->free_count--; + + wl_pool->pebs[wl_pool->size] = e->pnum; + wl_pool->size++; + } else + enough++; + + if (enough == 2) + break; + } + + wl_pool->used = 0; + pool->used = 0; + + spin_unlock(&ubi->wl_lock); +} + +/** + * ubi_wl_get_peb - get a physical eraseblock. + * @ubi: UBI device description object + * + * This function returns a physical eraseblock in case of success and a + * negative error code in case of failure. + * Returns with ubi->fm_eba_sem held in read mode! + */ +int ubi_wl_get_peb(struct ubi_device *ubi) +{ + int ret, retried = 0; + struct ubi_fm_pool *pool = &ubi->fm_pool; + struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; + +again: + down_read(&ubi->fm_eba_sem); + spin_lock(&ubi->wl_lock); + + /* We check here also for the WL pool because at this point we can + * refill the WL pool synchronous. */ + if (pool->used == pool->size || wl_pool->used == wl_pool->size) { + spin_unlock(&ubi->wl_lock); + up_read(&ubi->fm_eba_sem); + ret = ubi_update_fastmap(ubi); + if (ret) { + ubi_msg(ubi, "Unable to write a new fastmap: %i", ret); + down_read(&ubi->fm_eba_sem); + return -ENOSPC; + } + down_read(&ubi->fm_eba_sem); + spin_lock(&ubi->wl_lock); + } + + if (pool->used == pool->size) { + spin_unlock(&ubi->wl_lock); + if (retried) { + ubi_err(ubi, "Unable to get a free PEB from user WL pool"); + ret = -ENOSPC; + goto out; + } + retried = 1; + up_read(&ubi->fm_eba_sem); + goto again; + } + + ubi_assert(pool->used < pool->size); + ret = pool->pebs[pool->used++]; + prot_queue_add(ubi, ubi->lookuptbl[ret]); + spin_unlock(&ubi->wl_lock); +out: + return ret; +} + +/* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system. + * + * @ubi: UBI device description object + */ +static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) +{ + struct ubi_fm_pool *pool = &ubi->fm_wl_pool; + int pnum; + + if (pool->used == pool->size) { +#ifndef __UBOOT__ + /* We cannot update the fastmap here because this + * function is called in atomic context. + * Let's fail here and refill/update it as soon as possible. */ + if (!ubi->fm_work_scheduled) { + ubi->fm_work_scheduled = 1; + schedule_work(&ubi->fm_work); + } + return NULL; +#else + /* + * No work queues in U-Boot, we must do this immediately + */ + update_fastmap_work_fn(ubi); +#endif + } + + pnum = pool->pebs[pool->used++]; + return ubi->lookuptbl[pnum]; +} + +/** + * ubi_ensure_anchor_pebs - schedule wear-leveling to produce an anchor PEB. + * @ubi: UBI device description object + */ +int ubi_ensure_anchor_pebs(struct ubi_device *ubi) +{ + struct ubi_work *wrk; + + spin_lock(&ubi->wl_lock); + if (ubi->wl_scheduled) { + spin_unlock(&ubi->wl_lock); + return 0; + } + ubi->wl_scheduled = 1; + spin_unlock(&ubi->wl_lock); + + wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + if (!wrk) { + spin_lock(&ubi->wl_lock); + ubi->wl_scheduled = 0; + spin_unlock(&ubi->wl_lock); + return -ENOMEM; + } + + wrk->anchor = 1; + wrk->func = &wear_leveling_worker; + schedule_ubi_work(ubi, wrk); + return 0; +} + +/** + * ubi_wl_put_fm_peb - returns a PEB used in a fastmap to the wear-leveling + * sub-system. + * see: ubi_wl_put_peb() + * + * @ubi: UBI device description object + * @fm_e: physical eraseblock to return + * @lnum: the last used logical eraseblock number for the PEB + * @torture: if this physical eraseblock has to be tortured + */ +int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e, + int lnum, int torture) +{ + struct ubi_wl_entry *e; + int vol_id, pnum = fm_e->pnum; + + dbg_wl("PEB %d", pnum); + + ubi_assert(pnum >= 0); + ubi_assert(pnum < ubi->peb_count); + + spin_lock(&ubi->wl_lock); + e = ubi->lookuptbl[pnum]; + + /* This can happen if we recovered from a fastmap the very + * first time and writing now a new one. In this case the wl system + * has never seen any PEB used by the original fastmap. + */ + if (!e) { + e = fm_e; + ubi_assert(e->ec >= 0); + ubi->lookuptbl[pnum] = e; + } + + spin_unlock(&ubi->wl_lock); + + vol_id = lnum ? UBI_FM_DATA_VOLUME_ID : UBI_FM_SB_VOLUME_ID; + return schedule_erase(ubi, e, vol_id, lnum, torture); +} + +/** + * ubi_is_erase_work - checks whether a work is erase work. + * @wrk: The work object to be checked + */ +int ubi_is_erase_work(struct ubi_work *wrk) +{ + return wrk->func == erase_worker; +} + +static void ubi_fastmap_close(struct ubi_device *ubi) +{ + int i; + +#ifndef __UBOOT__ + flush_work(&ubi->fm_work); +#else + update_fastmap_work_fn(ubi); +#endif + return_unused_pool_pebs(ubi, &ubi->fm_pool); + return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); + + if (ubi->fm) { + for (i = 0; i < ubi->fm->used_blocks; i++) + kfree(ubi->fm->e[i]); + } + kfree(ubi->fm); +} + +/** + * may_reserve_for_fm - tests whether a PEB shall be reserved for fastmap. + * See find_mean_wl_entry() + * + * @ubi: UBI device description object + * @e: physical eraseblock to return + * @root: RB tree to test against. + */ +static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi, + struct ubi_wl_entry *e, + struct rb_root *root) { + if (e && !ubi->fm_disabled && !ubi->fm && + e->pnum < UBI_FM_MAX_START) + e = rb_entry(rb_next(root->rb_node), + struct ubi_wl_entry, u.rb); + + return e; +} diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index a2166e431c2..f824ec8b293 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012 Linutronix GmbH + * Copyright (c) 2014 sigma star gmbh * Author: Richard Weinberger <richard@nod.at> * * SPDX-License-Identifier: GPL-2.0+ @@ -19,6 +20,69 @@ #include "ubi.h" /** + * init_seen - allocate memory for used for debugging. + * @ubi: UBI device description object + */ +static inline int *init_seen(struct ubi_device *ubi) +{ + int *ret; + + if (!ubi_dbg_chk_fastmap(ubi)) + return NULL; + + ret = kcalloc(ubi->peb_count, sizeof(int), GFP_KERNEL); + if (!ret) + return ERR_PTR(-ENOMEM); + + return ret; +} + +/** + * free_seen - free the seen logic integer array. + * @seen: integer array of @ubi->peb_count size + */ +static inline void free_seen(int *seen) +{ + kfree(seen); +} + +/** + * set_seen - mark a PEB as seen. + * @ubi: UBI device description object + * @pnum: The PEB to be makred as seen + * @seen: integer array of @ubi->peb_count size + */ +static inline void set_seen(struct ubi_device *ubi, int pnum, int *seen) +{ + if (!ubi_dbg_chk_fastmap(ubi) || !seen) + return; + + seen[pnum] = 1; +} + +/** + * self_check_seen - check whether all PEB have been seen by fastmap. + * @ubi: UBI device description object + * @seen: integer array of @ubi->peb_count size + */ +static int self_check_seen(struct ubi_device *ubi, int *seen) +{ + int pnum, ret = 0; + + if (!ubi_dbg_chk_fastmap(ubi) || !seen) + return 0; + + for (pnum = 0; pnum < ubi->peb_count; pnum++) { + if (!seen[pnum] && ubi->lookuptbl[pnum]) { + ubi_err(ubi, "self-check failed for PEB %d, fastmap didn't see it", pnum); + ret = -EINVAL; + } + } + + return ret; +} + +/** * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device. * @ubi: UBI device description object */ @@ -26,12 +90,13 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi) { size_t size; - size = sizeof(struct ubi_fm_hdr) + \ - sizeof(struct ubi_fm_scan_pool) + \ - sizeof(struct ubi_fm_scan_pool) + \ - (ubi->peb_count * sizeof(struct ubi_fm_ec)) + \ - (sizeof(struct ubi_fm_eba) + \ - (ubi->peb_count * sizeof(__be32))) + \ + size = sizeof(struct ubi_fm_sb) + + sizeof(struct ubi_fm_hdr) + + sizeof(struct ubi_fm_scan_pool) + + sizeof(struct ubi_fm_scan_pool) + + (ubi->peb_count * sizeof(struct ubi_fm_ec)) + + (sizeof(struct ubi_fm_eba) + + (ubi->peb_count * sizeof(__be32))) + sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES; return roundup(size, ubi->leb_size); } @@ -129,22 +194,25 @@ static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id, if (vol_id > av->vol_id) p = &(*p)->rb_left; - else if (vol_id > av->vol_id) + else if (vol_id < av->vol_id) p = &(*p)->rb_right; + else + return ERR_PTR(-EINVAL); } av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); if (!av) goto out; - av->highest_lnum = av->leb_count = 0; + av->highest_lnum = av->leb_count = av->used_ebs = 0; av->vol_id = vol_id; - av->used_ebs = used_ebs; av->data_pad = data_pad; av->last_data_size = last_eb_bytes; av->compat = 0; av->vol_type = vol_type; av->root = RB_ROOT; + if (av->vol_type == UBI_STATIC_VOLUME) + av->used_ebs = used_ebs; dbg_bld("found volume (ID %i)", vol_id); @@ -250,7 +318,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai, list_add_tail(&victim->u.list, &ai->erase); if (av->highest_lnum == be32_to_cpu(new_vh->lnum)) - av->last_data_size = \ + av->last_data_size = be32_to_cpu(new_vh->data_size); dbg_bld("vol %i: AEB %i's PEB %i is the newer", @@ -331,7 +399,8 @@ static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai, if (found) av = tmp_av; else { - ubi_err("orphaned volume in fastmap pool!"); + ubi_err(ubi, "orphaned volume in fastmap pool!"); + kmem_cache_free(ai->aeb_slab_cache, new_aeb); return UBI_BAD_FASTMAP; } @@ -362,6 +431,7 @@ static void unmap_peb(struct ubi_attach_info *ai, int pnum) aeb = rb_entry(node2, struct ubi_ainf_peb, u.rb); if (aeb->pnum == pnum) { rb_erase(&aeb->u.rb, &av->root); + av->leb_count--; kmem_cache_free(ai->aeb_slab_cache, aeb); return; } @@ -376,7 +446,6 @@ static void unmap_peb(struct ubi_attach_info *ai, int pnum) * @pebs: an array of all PEB numbers in the to be scanned pool * @pool_size: size of the pool (number of entries in @pebs) * @max_sqnum: pointer to the maximal sequence number - * @eba_orphans: list of PEBs which need to be scanned * @free: list of PEBs which are most likely free (and go into @ai->free) * * Returns 0 on success, if the pool is unusable UBI_BAD_FASTMAP is returned. @@ -384,18 +453,18 @@ static void unmap_peb(struct ubi_attach_info *ai, int pnum) */ #ifndef __UBOOT__ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, - int *pebs, int pool_size, unsigned long long *max_sqnum, - struct list_head *eba_orphans, struct list_head *freef) + __be32 *pebs, int pool_size, unsigned long long *max_sqnum, + struct list_head *free) #else static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, __be32 *pebs, int pool_size, unsigned long long *max_sqnum, - struct list_head *eba_orphans, struct list_head *freef) + struct list_head *free) #endif { struct ubi_vid_hdr *vh; struct ubi_ec_hdr *ech; - struct ubi_ainf_peb *new_aeb, *tmp_aeb; - int i, pnum, err, found_orphan, ret = 0; + struct ubi_ainf_peb *new_aeb; + int i, pnum, err, ret = 0; ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); if (!ech) @@ -420,18 +489,18 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, pnum = be32_to_cpu(pebs[i]); if (ubi_io_is_bad(ubi, pnum)) { - ubi_err("bad PEB in fastmap pool!"); + ubi_err(ubi, "bad PEB in fastmap pool!"); ret = UBI_BAD_FASTMAP; goto out; } err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); if (err && err != UBI_IO_BITFLIPS) { - ubi_err("unable to read EC header! PEB:%i err:%i", + ubi_err(ubi, "unable to read EC header! PEB:%i err:%i", pnum, err); ret = err > 0 ? UBI_BAD_FASTMAP : err; goto out; - } else if (ret == UBI_IO_BITFLIPS) + } else if (err == UBI_IO_BITFLIPS) scrub = 1; /* @@ -441,7 +510,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, image_seq = be32_to_cpu(ech->image_seq); if (image_seq && (image_seq != ubi->image_seq)) { - ubi_err("bad image seq: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad image seq: 0x%x, expected: 0x%x", be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto out; @@ -453,9 +522,9 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, unmap_peb(ai, pnum); dbg_bld("Adding PEB to free: %i", pnum); if (err == UBI_IO_FF_BITFLIPS) - add_aeb(ai, freef, pnum, ec, 1); + add_aeb(ai, free, pnum, ec, 1); else - add_aeb(ai, freef, pnum, ec, 0); + add_aeb(ai, free, pnum, ec, 0); continue; } else if (err == 0 || err == UBI_IO_BITFLIPS) { dbg_bld("Found non empty PEB:%i in pool", pnum); @@ -463,18 +532,6 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, if (err == UBI_IO_BITFLIPS) scrub = 1; - found_orphan = 0; - list_for_each_entry(tmp_aeb, eba_orphans, u.list) { - if (tmp_aeb->pnum == pnum) { - found_orphan = 1; - break; - } - } - if (found_orphan) { - list_del(&tmp_aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); - } - new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); if (!new_aeb) { @@ -499,7 +556,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, } } else { /* We are paranoid and fall back to scanning mode */ - ubi_err("fastmap pool PEBs contains damaged PEBs!"); + ubi_err(ubi, "fastmap pool PEBs contains damaged PEBs!"); ret = err > 0 ? UBI_BAD_FASTMAP : err; goto out; } @@ -549,13 +606,12 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, struct ubi_fastmap_layout *fm) { - struct list_head used, eba_orphans, freef; + struct list_head used, free; struct ubi_ainf_volume *av; struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb; - struct ubi_ec_hdr *ech; struct ubi_fm_sb *fmsb; struct ubi_fm_hdr *fmhdr; - struct ubi_fm_scan_pool *fmpl1, *fmpl2; + struct ubi_fm_scan_pool *fmpl, *fmpl_wl; struct ubi_fm_ec *fmec; struct ubi_fm_volhdr *fmvhdr; struct ubi_fm_eba *fm_eba; @@ -565,23 +621,9 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, void *fm_raw = ubi->fm_buf; INIT_LIST_HEAD(&used); - INIT_LIST_HEAD(&freef); - INIT_LIST_HEAD(&eba_orphans); - INIT_LIST_HEAD(&ai->corr); - INIT_LIST_HEAD(&ai->free); - INIT_LIST_HEAD(&ai->erase); - INIT_LIST_HEAD(&ai->alien); - ai->volumes = RB_ROOT; + INIT_LIST_HEAD(&free); ai->min_ec = UBI_MAX_ERASECOUNTER; - ai->aeb_slab_cache = kmem_cache_create("ubi_ainf_peb_slab", - sizeof(struct ubi_ainf_peb), - 0, 0, NULL); - if (!ai->aeb_slab_cache) { - ret = -ENOMEM; - goto fail; - } - fmsb = (struct ubi_fm_sb *)(fm_raw); ai->max_sqnum = fmsb->sqnum; fm_pos += sizeof(struct ubi_fm_sb); @@ -594,56 +636,57 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, goto fail_bad; if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) { - ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad fastmap header magic: 0x%x, expected: 0x%x", be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC); goto fail_bad; } - fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); - fm_pos += sizeof(*fmpl1); + fmpl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl); if (fm_pos >= fm_size) goto fail_bad; - if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) { - ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", - be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC); + if (be32_to_cpu(fmpl->magic) != UBI_FM_POOL_MAGIC) { + ubi_err(ubi, "bad fastmap pool magic: 0x%x, expected: 0x%x", + be32_to_cpu(fmpl->magic), UBI_FM_POOL_MAGIC); goto fail_bad; } - fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); - fm_pos += sizeof(*fmpl2); + fmpl_wl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl_wl); if (fm_pos >= fm_size) goto fail_bad; - if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) { - ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", - be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC); + if (be32_to_cpu(fmpl_wl->magic) != UBI_FM_POOL_MAGIC) { + ubi_err(ubi, "bad fastmap WL pool magic: 0x%x, expected: 0x%x", + be32_to_cpu(fmpl_wl->magic), UBI_FM_POOL_MAGIC); goto fail_bad; } - pool_size = be16_to_cpu(fmpl1->size); - wl_pool_size = be16_to_cpu(fmpl2->size); - fm->max_pool_size = be16_to_cpu(fmpl1->max_size); - fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size); + pool_size = be16_to_cpu(fmpl->size); + wl_pool_size = be16_to_cpu(fmpl_wl->size); + fm->max_pool_size = be16_to_cpu(fmpl->max_size); + fm->max_wl_pool_size = be16_to_cpu(fmpl_wl->max_size); if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) { - ubi_err("bad pool size: %i", pool_size); + ubi_err(ubi, "bad pool size: %i", pool_size); goto fail_bad; } if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) { - ubi_err("bad WL pool size: %i", wl_pool_size); + ubi_err(ubi, "bad WL pool size: %i", wl_pool_size); goto fail_bad; } if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE || fm->max_pool_size < 0) { - ubi_err("bad maximal pool size: %i", fm->max_pool_size); + ubi_err(ubi, "bad maximal pool size: %i", fm->max_pool_size); goto fail_bad; } if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE || fm->max_wl_pool_size < 0) { - ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size); + ubi_err(ubi, "bad maximal WL pool size: %i", + fm->max_wl_pool_size); goto fail_bad; } @@ -702,8 +745,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, goto fail_bad; if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) { - ubi_err("bad fastmap vol header magic: 0x%x, " \ - "expected: 0x%x", + ubi_err(ubi, "bad fastmap vol header magic: 0x%x, expected: 0x%x", be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC); goto fail_bad; } @@ -716,6 +758,11 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (!av) goto fail_bad; + if (PTR_ERR(av) == -EINVAL) { + ubi_err(ubi, "volume (ID %i) already exists", + fmvhdr->vol_id); + goto fail_bad; + } ai->vols_found++; if (ai->highest_vol_id < be32_to_cpu(fmvhdr->vol_id)) @@ -728,8 +775,7 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, goto fail_bad; if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) { - ubi_err("bad fastmap EBA header magic: 0x%x, " \ - "expected: 0x%x", + ubi_err(ubi, "bad fastmap EBA header magic: 0x%x, expected: 0x%x", be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC); goto fail_bad; } @@ -748,28 +794,9 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, } } - /* This can happen if a PEB is already in an EBA known - * by this fastmap but the PEB itself is not in the used - * list. - * In this case the PEB can be within the fastmap pool - * or while writing the fastmap it was in the protection - * queue. - */ if (!aeb) { - aeb = kmem_cache_alloc(ai->aeb_slab_cache, - GFP_KERNEL); - if (!aeb) { - ret = -ENOMEM; - - goto fail; - } - - aeb->lnum = j; - aeb->pnum = be32_to_cpu(fm_eba->pnum[j]); - aeb->ec = -1; - aeb->scrub = aeb->copy_flag = aeb->sqnum = 0; - list_add_tail(&aeb->u.list, &eba_orphans); - continue; + ubi_err(ubi, "PEB %i is in EBA but not in used list", pnum); + goto fail_bad; } aeb->lnum = j; @@ -782,61 +809,26 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, dbg_bld("inserting PEB:%i (LEB %i) to vol %i", aeb->pnum, aeb->lnum, av->vol_id); } - - ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); - if (!ech) { - ret = -ENOMEM; - goto fail; - } - - list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, - u.list) { - int err; - - if (ubi_io_is_bad(ubi, tmp_aeb->pnum)) { - ubi_err("bad PEB in fastmap EBA orphan list"); - ret = UBI_BAD_FASTMAP; - kfree(ech); - goto fail; - } - - err = ubi_io_read_ec_hdr(ubi, tmp_aeb->pnum, ech, 0); - if (err && err != UBI_IO_BITFLIPS) { - ubi_err("unable to read EC header! PEB:%i " \ - "err:%i", tmp_aeb->pnum, err); - ret = err > 0 ? UBI_BAD_FASTMAP : err; - kfree(ech); - - goto fail; - } else if (err == UBI_IO_BITFLIPS) - tmp_aeb->scrub = 1; - - tmp_aeb->ec = be64_to_cpu(ech->ec); - assign_aeb_to_av(ai, tmp_aeb, av); - } - - kfree(ech); } - ret = scan_pool(ubi, ai, fmpl1->pebs, pool_size, &max_sqnum, - &eba_orphans, &freef); + ret = scan_pool(ubi, ai, fmpl->pebs, pool_size, &max_sqnum, &free); if (ret) goto fail; - ret = scan_pool(ubi, ai, fmpl2->pebs, wl_pool_size, &max_sqnum, - &eba_orphans, &freef); + ret = scan_pool(ubi, ai, fmpl_wl->pebs, wl_pool_size, &max_sqnum, &free); if (ret) goto fail; if (max_sqnum > ai->max_sqnum) ai->max_sqnum = max_sqnum; - list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &freef, u.list) + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) list_move_tail(&tmp_aeb->u.list, &ai->free); - ubi_assert(list_empty(&used)); - ubi_assert(list_empty(&eba_orphans)); - ubi_assert(list_empty(&freef)); + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) + list_move_tail(&tmp_aeb->u.list, &ai->erase); + + ubi_assert(list_empty(&free)); /* * If fastmap is leaking PEBs (must not happen), raise a @@ -865,11 +857,7 @@ fail: list_del(&tmp_aeb->u.list); kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); } - list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { - list_del(&tmp_aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); - } - list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &freef, u.list) { + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { list_del(&tmp_aeb->u.list); kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); } @@ -899,7 +887,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, __be32 crc, tmp_crc; unsigned long long sqnum = 0; - mutex_lock(&ubi->fm_mutex); + down_write(&ubi->fm_protect); memset(ubi->fm_buf, 0, ubi->fm_size); fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL); @@ -922,14 +910,14 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, fm->to_be_tortured[0] = 1; if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) { - ubi_err("bad super block magic: 0x%x, expected: 0x%x", + ubi_err(ubi, "bad super block magic: 0x%x, expected: 0x%x", be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } if (fmsb->version != UBI_FM_FMT_VERSION) { - ubi_err("bad fastmap version: %i, expected: %i", + ubi_err(ubi, "bad fastmap version: %i, expected: %i", fmsb->version, UBI_FM_FMT_VERSION); ret = UBI_BAD_FASTMAP; goto free_fm_sb; @@ -937,15 +925,16 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, used_blocks = be32_to_cpu(fmsb->used_blocks); if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) { - ubi_err("number of fastmap blocks is invalid: %i", used_blocks); + ubi_err(ubi, "number of fastmap blocks is invalid: %i", + used_blocks); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } fm_size = ubi->leb_size * used_blocks; if (fm_size != ubi->fm_size) { - ubi_err("bad fastmap size: %zi, expected: %zi", fm_size, - ubi->fm_size); + ubi_err(ubi, "bad fastmap size: %zi, expected: %zi", + fm_size, ubi->fm_size); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } @@ -974,7 +963,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i EC (PEB: %i)", + ubi_err(ubi, "unable to read fastmap block# %i EC (PEB: %i)", i, pnum); if (ret > 0) ret = UBI_BAD_FASTMAP; @@ -991,7 +980,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, * we shouldn't fail if image_seq == 0. */ if (image_seq && (image_seq != ubi->image_seq)) { - ubi_err("wrong image seq:%d instead of %d", + ubi_err(ubi, "wrong image seq:%d instead of %d", be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto free_hdr; @@ -999,15 +988,14 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i (PEB: %i)", + ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i)", i, pnum); goto free_hdr; } if (i == 0) { if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) { - ubi_err("bad fastmap anchor vol_id: 0x%x," \ - " expected: 0x%x", + ubi_err(ubi, "bad fastmap anchor vol_id: 0x%x, expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_SB_VOLUME_ID); ret = UBI_BAD_FASTMAP; @@ -1015,8 +1003,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, } } else { if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) { - ubi_err("bad fastmap data vol_id: 0x%x," \ - " expected: 0x%x", + ubi_err(ubi, "bad fastmap data vol_id: 0x%x, expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_DATA_VOLUME_ID); ret = UBI_BAD_FASTMAP; @@ -1030,7 +1017,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum, ubi->leb_start, ubi->leb_size); if (ret && ret != UBI_IO_BITFLIPS) { - ubi_err("unable to read fastmap block# %i (PEB: %i, " \ + ubi_err(ubi, "unable to read fastmap block# %i (PEB: %i, " "err: %i)", i, pnum, ret); goto free_hdr; } @@ -1044,8 +1031,9 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, fmsb2->data_crc = 0; crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size); if (crc != tmp_crc) { - ubi_err("fastmap data CRC is invalid"); - ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc); + ubi_err(ubi, "fastmap data CRC is invalid"); + ubi_err(ubi, "CRC should be: 0x%x, calc: 0x%x", + tmp_crc, crc); ret = UBI_BAD_FASTMAP; goto free_hdr; } @@ -1081,17 +1069,18 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ubi->fm = fm; ubi->fm_pool.max_size = ubi->fm->max_pool_size; ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size; - ubi_msg("attached by fastmap"); - ubi_msg("fastmap pool size: %d", ubi->fm_pool.max_size); - ubi_msg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); + ubi_msg(ubi, "attached by fastmap"); + ubi_msg(ubi, "fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg(ubi, "fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); ubi->fm_disabled = 0; ubi_free_vid_hdr(ubi, vh); kfree(ech); out: - mutex_unlock(&ubi->fm_mutex); + up_write(&ubi->fm_protect); if (ret == UBI_BAD_FASTMAP) - ubi_err("Attach by fastmap failed, doing a full scan!"); + ubi_err(ubi, "Attach by fastmap failed, doing a full scan!"); return ret; free_hdr: @@ -1117,17 +1106,18 @@ static int ubi_write_fastmap(struct ubi_device *ubi, void *fm_raw; struct ubi_fm_sb *fmsb; struct ubi_fm_hdr *fmh; - struct ubi_fm_scan_pool *fmpl1, *fmpl2; + struct ubi_fm_scan_pool *fmpl, *fmpl_wl; struct ubi_fm_ec *fec; struct ubi_fm_volhdr *fvh; struct ubi_fm_eba *feba; - struct rb_node *node; struct ubi_wl_entry *wl_e; struct ubi_volume *vol; struct ubi_vid_hdr *avhdr, *dvhdr; struct ubi_work *ubi_wrk; + struct rb_node *tmp_rb; int ret, i, j, free_peb_count, used_peb_count, vol_count; int scrub_peb_count, erase_peb_count; + int *seen_pebs = NULL; fm_raw = ubi->fm_buf; memset(ubi->fm_buf, 0, ubi->fm_size); @@ -1144,6 +1134,12 @@ static int ubi_write_fastmap(struct ubi_device *ubi, goto out_kfree; } + seen_pebs = init_seen(ubi); + if (IS_ERR(seen_pebs)) { + ret = PTR_ERR(seen_pebs); + goto out_kfree; + } + spin_lock(&ubi->volumes_lock); spin_lock(&ubi->wl_lock); @@ -1168,29 +1164,33 @@ static int ubi_write_fastmap(struct ubi_device *ubi, erase_peb_count = 0; vol_count = 0; - fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); - fm_pos += sizeof(*fmpl1); - fmpl1->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); - fmpl1->size = cpu_to_be16(ubi->fm_pool.size); - fmpl1->max_size = cpu_to_be16(ubi->fm_pool.max_size); + fmpl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl); + fmpl->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); + fmpl->size = cpu_to_be16(ubi->fm_pool.size); + fmpl->max_size = cpu_to_be16(ubi->fm_pool.max_size); - for (i = 0; i < ubi->fm_pool.size; i++) - fmpl1->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]); + for (i = 0; i < ubi->fm_pool.size; i++) { + fmpl->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]); + set_seen(ubi, ubi->fm_pool.pebs[i], seen_pebs); + } - fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); - fm_pos += sizeof(*fmpl2); - fmpl2->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); - fmpl2->size = cpu_to_be16(ubi->fm_wl_pool.size); - fmpl2->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size); + fmpl_wl = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl_wl); + fmpl_wl->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); + fmpl_wl->size = cpu_to_be16(ubi->fm_wl_pool.size); + fmpl_wl->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size); - for (i = 0; i < ubi->fm_wl_pool.size; i++) - fmpl2->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]); + for (i = 0; i < ubi->fm_wl_pool.size; i++) { + fmpl_wl->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]); + set_seen(ubi, ubi->fm_wl_pool.pebs[i], seen_pebs); + } - for (node = rb_first(&ubi->free); node; node = rb_next(node)) { - wl_e = rb_entry(node, struct ubi_wl_entry, u.rb); + ubi_for_each_free_peb(ubi, wl_e, tmp_rb) { fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); fec->pnum = cpu_to_be32(wl_e->pnum); + set_seen(ubi, wl_e->pnum, seen_pebs); fec->ec = cpu_to_be32(wl_e->ec); free_peb_count++; @@ -1199,11 +1199,23 @@ static int ubi_write_fastmap(struct ubi_device *ubi, } fmh->free_peb_count = cpu_to_be32(free_peb_count); - for (node = rb_first(&ubi->used); node; node = rb_next(node)) { - wl_e = rb_entry(node, struct ubi_wl_entry, u.rb); + ubi_for_each_used_peb(ubi, wl_e, tmp_rb) { + fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + + fec->pnum = cpu_to_be32(wl_e->pnum); + set_seen(ubi, wl_e->pnum, seen_pebs); + fec->ec = cpu_to_be32(wl_e->ec); + + used_peb_count++; + fm_pos += sizeof(*fec); + ubi_assert(fm_pos <= ubi->fm_size); + } + + ubi_for_each_protected_peb(ubi, i, wl_e) { fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); fec->pnum = cpu_to_be32(wl_e->pnum); + set_seen(ubi, wl_e->pnum, seen_pebs); fec->ec = cpu_to_be32(wl_e->ec); used_peb_count++; @@ -1212,11 +1224,11 @@ static int ubi_write_fastmap(struct ubi_device *ubi, } fmh->used_peb_count = cpu_to_be32(used_peb_count); - for (node = rb_first(&ubi->scrub); node; node = rb_next(node)) { - wl_e = rb_entry(node, struct ubi_wl_entry, u.rb); + ubi_for_each_scrub_peb(ubi, wl_e, tmp_rb) { fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); fec->pnum = cpu_to_be32(wl_e->pnum); + set_seen(ubi, wl_e->pnum, seen_pebs); fec->ec = cpu_to_be32(wl_e->ec); scrub_peb_count++; @@ -1234,6 +1246,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); fec->pnum = cpu_to_be32(wl_e->pnum); + set_seen(ubi, wl_e->pnum, seen_pebs); fec->ec = cpu_to_be32(wl_e->ec); erase_peb_count++; @@ -1287,12 +1300,13 @@ static int ubi_write_fastmap(struct ubi_device *ubi, dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum); ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr); if (ret) { - ubi_err("unable to write vid_hdr to fastmap SB!"); + ubi_err(ubi, "unable to write vid_hdr to fastmap SB!"); goto out_kfree; } for (i = 0; i < new_fm->used_blocks; i++) { fmsb->block_loc[i] = cpu_to_be32(new_fm->e[i]->pnum); + set_seen(ubi, new_fm->e[i]->pnum, seen_pebs); fmsb->block_ec[i] = cpu_to_be32(new_fm->e[i]->ec); } @@ -1307,7 +1321,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum)); ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr); if (ret) { - ubi_err("unable to write vid_hdr to PEB %i!", + ubi_err(ubi, "unable to write vid_hdr to PEB %i!", new_fm->e[i]->pnum); goto out_kfree; } @@ -1317,7 +1331,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size), new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size); if (ret) { - ubi_err("unable to write fastmap to PEB %i!", + ubi_err(ubi, "unable to write fastmap to PEB %i!", new_fm->e[i]->pnum); goto out_kfree; } @@ -1326,11 +1340,13 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ubi_assert(new_fm); ubi->fm = new_fm; + ret = self_check_seen(ubi, seen_pebs); dbg_bld("fastmap written!"); out_kfree: ubi_free_vid_hdr(ubi, avhdr); ubi_free_vid_hdr(ubi, dvhdr); + free_seen(seen_pebs); out: return ret; } @@ -1385,31 +1401,87 @@ out: /** * invalidate_fastmap - destroys a fastmap. * @ubi: UBI device object - * @fm: the fastmap to be destroyed * + * This function ensures that upon next UBI attach a full scan + * is issued. We need this if UBI is about to write a new fastmap + * but is unable to do so. In this case we have two options: + * a) Make sure that the current fastmap will not be usued upon + * attach time and contine or b) fall back to RO mode to have the + * current fastmap in a valid state. * Returns 0 on success, < 0 indicates an internal error. */ -static int invalidate_fastmap(struct ubi_device *ubi, - struct ubi_fastmap_layout *fm) +static int invalidate_fastmap(struct ubi_device *ubi) { int ret; - struct ubi_vid_hdr *vh; + struct ubi_fastmap_layout *fm; + struct ubi_wl_entry *e; + struct ubi_vid_hdr *vh = NULL; - ret = erase_block(ubi, fm->e[0]->pnum); - if (ret < 0) - return ret; + if (!ubi->fm) + return 0; + + ubi->fm = NULL; + + ret = -ENOMEM; + fm = kzalloc(sizeof(*fm), GFP_KERNEL); + if (!fm) + goto out; vh = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID); if (!vh) - return -ENOMEM; + goto out_free_fm; - /* deleting the current fastmap SB is not enough, an old SB may exist, - * so create a (corrupted) SB such that fastmap will find it and fall - * back to scanning mode in any case */ + ret = -ENOSPC; + e = ubi_wl_get_fm_peb(ubi, 1); + if (!e) + goto out_free_fm; + + /* + * Create fake fastmap such that UBI will fall back + * to scanning mode. + */ vh->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); - ret = ubi_io_write_vid_hdr(ubi, fm->e[0]->pnum, vh); + ret = ubi_io_write_vid_hdr(ubi, e->pnum, vh); + if (ret < 0) { + ubi_wl_put_fm_peb(ubi, e, 0, 0); + goto out_free_fm; + } + + fm->used_blocks = 1; + fm->e[0] = e; + + ubi->fm = fm; +out: + ubi_free_vid_hdr(ubi, vh); return ret; + +out_free_fm: + kfree(fm); + goto out; +} + +/** + * return_fm_pebs - returns all PEBs used by a fastmap back to the + * WL sub-system. + * @ubi: UBI device object + * @fm: fastmap layout object + */ +static void return_fm_pebs(struct ubi_device *ubi, + struct ubi_fastmap_layout *fm) +{ + int i; + + if (!fm) + return; + + for (i = 0; i < fm->used_blocks; i++) { + if (fm->e[i]) { + ubi_wl_put_fm_peb(ubi, fm->e[i], i, + fm->to_be_tortured[i]); + fm->e[i] = NULL; + } + } } /** @@ -1421,50 +1493,37 @@ static int invalidate_fastmap(struct ubi_device *ubi, */ int ubi_update_fastmap(struct ubi_device *ubi) { - int ret, i; + int ret, i, j; struct ubi_fastmap_layout *new_fm, *old_fm; struct ubi_wl_entry *tmp_e; - mutex_lock(&ubi->fm_mutex); + down_write(&ubi->fm_protect); ubi_refill_pools(ubi); if (ubi->ro_mode || ubi->fm_disabled) { - mutex_unlock(&ubi->fm_mutex); + up_write(&ubi->fm_protect); return 0; } ret = ubi_ensure_anchor_pebs(ubi); if (ret) { - mutex_unlock(&ubi->fm_mutex); + up_write(&ubi->fm_protect); return ret; } new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL); if (!new_fm) { - mutex_unlock(&ubi->fm_mutex); + up_write(&ubi->fm_protect); return -ENOMEM; } new_fm->used_blocks = ubi->fm_size / ubi->leb_size; - - for (i = 0; i < new_fm->used_blocks; i++) { - new_fm->e[i] = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); - if (!new_fm->e[i]) { - while (i--) - kfree(new_fm->e[i]); - - kfree(new_fm); - mutex_unlock(&ubi->fm_mutex); - return -ENOMEM; - } - } - old_fm = ubi->fm; ubi->fm = NULL; if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) { - ubi_err("fastmap too large"); + ubi_err(ubi, "fastmap too large"); ret = -ENOSPC; goto err; } @@ -1474,37 +1533,49 @@ int ubi_update_fastmap(struct ubi_device *ubi) tmp_e = ubi_wl_get_fm_peb(ubi, 0); spin_unlock(&ubi->wl_lock); - if (!tmp_e && !old_fm) { - int j; - ubi_err("could not get any free erase block"); - - for (j = 1; j < i; j++) - ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); - - ret = -ENOSPC; - goto err; - } else if (!tmp_e && old_fm) { - ret = erase_block(ubi, old_fm->e[i]->pnum); - if (ret < 0) { - int j; - - for (j = 1; j < i; j++) - ubi_wl_put_fm_peb(ubi, new_fm->e[j], - j, 0); + if (!tmp_e) { + if (old_fm && old_fm->e[i]) { + ret = erase_block(ubi, old_fm->e[i]->pnum); + if (ret < 0) { + ubi_err(ubi, "could not erase old fastmap PEB"); + + for (j = 1; j < i; j++) { + ubi_wl_put_fm_peb(ubi, new_fm->e[j], + j, 0); + new_fm->e[j] = NULL; + } + goto err; + } + new_fm->e[i] = old_fm->e[i]; + old_fm->e[i] = NULL; + } else { + ubi_err(ubi, "could not get any free erase block"); + + for (j = 1; j < i; j++) { + ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); + new_fm->e[j] = NULL; + } - ubi_err("could not erase old fastmap PEB"); + ret = -ENOSPC; goto err; } - - new_fm->e[i]->pnum = old_fm->e[i]->pnum; - new_fm->e[i]->ec = old_fm->e[i]->ec; } else { - new_fm->e[i]->pnum = tmp_e->pnum; - new_fm->e[i]->ec = tmp_e->ec; + new_fm->e[i] = tmp_e; - if (old_fm) + if (old_fm && old_fm->e[i]) { ubi_wl_put_fm_peb(ubi, old_fm->e[i], i, old_fm->to_be_tortured[i]); + old_fm->e[i] = NULL; + } + } + } + + /* Old fastmap is larger than the new one */ + if (old_fm && new_fm->used_blocks < old_fm->used_blocks) { + for (i = new_fm->used_blocks; i < old_fm->used_blocks; i++) { + ubi_wl_put_fm_peb(ubi, old_fm->e[i], i, + old_fm->to_be_tortured[i]); + old_fm->e[i] = NULL; } } @@ -1517,67 +1588,67 @@ int ubi_update_fastmap(struct ubi_device *ubi) if (!tmp_e) { ret = erase_block(ubi, old_fm->e[0]->pnum); if (ret < 0) { - int i; - ubi_err("could not erase old anchor PEB"); + ubi_err(ubi, "could not erase old anchor PEB"); - for (i = 1; i < new_fm->used_blocks; i++) + for (i = 1; i < new_fm->used_blocks; i++) { ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0); + new_fm->e[i] = NULL; + } goto err; } - - new_fm->e[0]->pnum = old_fm->e[0]->pnum; + new_fm->e[0] = old_fm->e[0]; new_fm->e[0]->ec = ret; + old_fm->e[0] = NULL; } else { /* we've got a new anchor PEB, return the old one */ ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0, old_fm->to_be_tortured[0]); - - new_fm->e[0]->pnum = tmp_e->pnum; - new_fm->e[0]->ec = tmp_e->ec; + new_fm->e[0] = tmp_e; + old_fm->e[0] = NULL; } } else { if (!tmp_e) { - int i; - ubi_err("could not find any anchor PEB"); + ubi_err(ubi, "could not find any anchor PEB"); - for (i = 1; i < new_fm->used_blocks; i++) + for (i = 1; i < new_fm->used_blocks; i++) { ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0); + new_fm->e[i] = NULL; + } ret = -ENOSPC; goto err; } - - new_fm->e[0]->pnum = tmp_e->pnum; - new_fm->e[0]->ec = tmp_e->ec; + new_fm->e[0] = tmp_e; } down_write(&ubi->work_sem); - down_write(&ubi->fm_sem); + down_write(&ubi->fm_eba_sem); ret = ubi_write_fastmap(ubi, new_fm); - up_write(&ubi->fm_sem); + up_write(&ubi->fm_eba_sem); up_write(&ubi->work_sem); if (ret) goto err; out_unlock: - mutex_unlock(&ubi->fm_mutex); + up_write(&ubi->fm_protect); kfree(old_fm); return ret; err: - kfree(new_fm); - - ubi_warn("Unable to write new fastmap, err=%i", ret); + ubi_warn(ubi, "Unable to write new fastmap, err=%i", ret); - ret = 0; - if (old_fm) { - ret = invalidate_fastmap(ubi, old_fm); - if (ret < 0) - ubi_err("Unable to invalidiate current fastmap!"); - else if (ret) - ret = 0; + ret = invalidate_fastmap(ubi); + if (ret < 0) { + ubi_err(ubi, "Unable to invalidiate current fastmap!"); + ubi_ro_mode(ubi); + } else { + return_fm_pebs(ubi, old_fm); + return_fm_pebs(ubi, new_fm); + ret = 0; } + + kfree(new_fm); goto out_unlock; } diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 0e2e9335fe5..d1bdec38379 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -169,19 +169,20 @@ retry: * enabled. A corresponding message will be printed * later, when it is has been scrubbed. */ - ubi_msg("fixable bit-flip detected at PEB %d", pnum); + ubi_msg(ubi, "fixable bit-flip detected at PEB %d", + pnum); ubi_assert(len == read); return UBI_IO_BITFLIPS; } if (retries++ < UBI_IO_RETRIES) { - ubi_warn("error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry", + ubi_warn(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry", err, errstr, len, pnum, offset, read); yield(); goto retry; } - ubi_err("error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes", + ubi_err(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes", err, errstr, len, pnum, offset, read); dump_stack(); @@ -238,7 +239,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, ubi_assert(len > 0 && len % ubi->hdrs_min_io_size == 0); if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -265,7 +266,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, } if (ubi_dbg_is_write_failure(ubi)) { - ubi_err("cannot write %d bytes to PEB %d:%d (emulated)", + ubi_err(ubi, "cannot write %d bytes to PEB %d:%d (emulated)", len, pnum, offset); dump_stack(); return -EIO; @@ -274,7 +275,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, addr = (loff_t)pnum * ubi->peb_size + offset; err = mtd_write(ubi->mtd, addr, len, &written, buf); if (err) { - ubi_err("error %d while writing %d bytes to PEB %d:%d, written %zd bytes", + ubi_err(ubi, "error %d while writing %d bytes to PEB %d:%d, written %zd bytes", err, len, pnum, offset, written); dump_stack(); ubi_dump_flash(ubi, pnum, offset, len); @@ -330,7 +331,7 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum) ubi_assert(pnum >= 0 && pnum < ubi->peb_count); if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -347,12 +348,12 @@ retry: err = mtd_erase(ubi->mtd, &ei); if (err) { if (retries++ < UBI_IO_RETRIES) { - ubi_warn("error %d while erasing PEB %d, retry", + ubi_warn(ubi, "error %d while erasing PEB %d, retry", err, pnum); yield(); goto retry; } - ubi_err("cannot erase PEB %d, error %d", pnum, err); + ubi_err(ubi, "cannot erase PEB %d, error %d", pnum, err); dump_stack(); return err; } @@ -360,17 +361,18 @@ retry: err = wait_event_interruptible(wq, ei.state == MTD_ERASE_DONE || ei.state == MTD_ERASE_FAILED); if (err) { - ubi_err("interrupted PEB %d erasure", pnum); + ubi_err(ubi, "interrupted PEB %d erasure", pnum); return -EINTR; } if (ei.state == MTD_ERASE_FAILED) { if (retries++ < UBI_IO_RETRIES) { - ubi_warn("error while erasing PEB %d, retry", pnum); + ubi_warn(ubi, "error while erasing PEB %d, retry", + pnum); yield(); goto retry; } - ubi_err("cannot erase PEB %d", pnum); + ubi_err(ubi, "cannot erase PEB %d", pnum); dump_stack(); return -EIO; } @@ -380,7 +382,7 @@ retry: return err; if (ubi_dbg_is_erase_failure(ubi)) { - ubi_err("cannot erase PEB %d (emulated)", pnum); + ubi_err(ubi, "cannot erase PEB %d (emulated)", pnum); return -EIO; } @@ -403,7 +405,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) { int err, i, patt_count; - ubi_msg("run torture test for PEB %d", pnum); + ubi_msg(ubi, "run torture test for PEB %d", pnum); patt_count = ARRAY_SIZE(patterns); ubi_assert(patt_count > 0); @@ -420,7 +422,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) err = ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->peb_size); if (err == 0) { - ubi_err("erased PEB %d, but a non-0xFF byte found", + ubi_err(ubi, "erased PEB %d, but a non-0xFF byte found", pnum); err = -EIO; goto out; @@ -440,7 +442,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) err = ubi_check_pattern(ubi->peb_buf, patterns[i], ubi->peb_size); if (err == 0) { - ubi_err("pattern %x checking failed for PEB %d", + ubi_err(ubi, "pattern %x checking failed for PEB %d", patterns[i], pnum); err = -EIO; goto out; @@ -448,7 +450,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) } err = patt_count; - ubi_msg("PEB %d passed torture test, do not mark it as bad", pnum); + ubi_msg(ubi, "PEB %d passed torture test, do not mark it as bad", pnum); out: mutex_unlock(&ubi->buf_mutex); @@ -458,7 +460,7 @@ out: * has not passed because it happened on a freshly erased * physical eraseblock which means something is wrong with it. */ - ubi_err("read problems on freshly erased PEB %d, must be bad", + ubi_err(ubi, "read problems on freshly erased PEB %d, must be bad", pnum); err = -EIO; } @@ -534,7 +536,7 @@ error: * it. Supposedly the flash media or the driver is screwed up, so * return an error. */ - ubi_err("cannot invalidate PEB %d, write returned %d", pnum, err); + ubi_err(ubi, "cannot invalidate PEB %d, write returned %d", pnum, err); ubi_dump_flash(ubi, pnum, 0, ubi->peb_size); return -EIO; } @@ -566,7 +568,7 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) return err; if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -608,7 +610,7 @@ int ubi_io_is_bad(const struct ubi_device *ubi, int pnum) ret = mtd_block_isbad(mtd, (loff_t)pnum * ubi->peb_size); if (ret < 0) - ubi_err("error %d while checking if PEB %d is bad", + ubi_err(ubi, "error %d while checking if PEB %d is bad", ret, pnum); else if (ret) dbg_io("PEB %d is bad", pnum); @@ -634,7 +636,7 @@ int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum) ubi_assert(pnum >= 0 && pnum < ubi->peb_count); if (ubi->ro_mode) { - ubi_err("read-only mode"); + ubi_err(ubi, "read-only mode"); return -EROFS; } @@ -643,7 +645,7 @@ int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum) err = mtd_block_markbad(mtd, (loff_t)pnum * ubi->peb_size); if (err) - ubi_err("cannot mark PEB %d bad, error %d", pnum, err); + ubi_err(ubi, "cannot mark PEB %d bad, error %d", pnum, err); return err; } @@ -666,32 +668,32 @@ static int validate_ec_hdr(const struct ubi_device *ubi, leb_start = be32_to_cpu(ec_hdr->data_offset); if (ec_hdr->version != UBI_VERSION) { - ubi_err("node with incompatible UBI version found: this UBI version is %d, image version is %d", + ubi_err(ubi, "node with incompatible UBI version found: this UBI version is %d, image version is %d", UBI_VERSION, (int)ec_hdr->version); goto bad; } if (vid_hdr_offset != ubi->vid_hdr_offset) { - ubi_err("bad VID header offset %d, expected %d", + ubi_err(ubi, "bad VID header offset %d, expected %d", vid_hdr_offset, ubi->vid_hdr_offset); goto bad; } if (leb_start != ubi->leb_start) { - ubi_err("bad data offset %d, expected %d", + ubi_err(ubi, "bad data offset %d, expected %d", leb_start, ubi->leb_start); goto bad; } if (ec < 0 || ec > UBI_MAX_ERASECOUNTER) { - ubi_err("bad erase counter %lld", ec); + ubi_err(ubi, "bad erase counter %lld", ec); goto bad; } return 0; bad: - ubi_err("bad EC header"); + ubi_err(ubi, "bad EC header"); ubi_dump_ec_hdr(ec_hdr); dump_stack(); return 1; @@ -757,7 +759,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { /* The physical eraseblock is supposedly empty */ if (verbose) - ubi_warn("no EC header found at PEB %d, only 0xFF bytes", + ubi_warn(ubi, "no EC header found at PEB %d, only 0xFF bytes", pnum); dbg_bld("no EC header found at PEB %d, only 0xFF bytes", pnum); @@ -772,7 +774,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, * 0xFF bytes. Report that the header is corrupted. */ if (verbose) { - ubi_warn("bad magic number at PEB %d: %08x instead of %08x", + ubi_warn(ubi, "bad magic number at PEB %d: %08x instead of %08x", pnum, magic, UBI_EC_HDR_MAGIC); ubi_dump_ec_hdr(ec_hdr); } @@ -786,7 +788,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (hdr_crc != crc) { if (verbose) { - ubi_warn("bad EC header CRC at PEB %d, calculated %#08x, read %#08x", + ubi_warn(ubi, "bad EC header CRC at PEB %d, calculated %#08x, read %#08x", pnum, crc, hdr_crc); ubi_dump_ec_hdr(ec_hdr); } @@ -802,7 +804,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, /* And of course validate what has just been read from the media */ err = validate_ec_hdr(ubi, ec_hdr); if (err) { - ubi_err("validation failed for PEB %d", pnum); + ubi_err(ubi, "validation failed for PEB %d", pnum); return -EINVAL; } @@ -849,6 +851,9 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, if (err) return err; + if (ubi_dbg_power_cut(ubi, POWER_CUT_EC_WRITE)) + return -EROFS; + err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize); return err; } @@ -876,40 +881,40 @@ static int validate_vid_hdr(const struct ubi_device *ubi, int usable_leb_size = ubi->leb_size - data_pad; if (copy_flag != 0 && copy_flag != 1) { - ubi_err("bad copy_flag"); + ubi_err(ubi, "bad copy_flag"); goto bad; } if (vol_id < 0 || lnum < 0 || data_size < 0 || used_ebs < 0 || data_pad < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto bad; } if (vol_id >= UBI_MAX_VOLUMES && vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("bad vol_id"); + ubi_err(ubi, "bad vol_id"); goto bad; } if (vol_id < UBI_INTERNAL_VOL_START && compat != 0) { - ubi_err("bad compat"); + ubi_err(ubi, "bad compat"); goto bad; } if (vol_id >= UBI_INTERNAL_VOL_START && compat != UBI_COMPAT_DELETE && compat != UBI_COMPAT_RO && compat != UBI_COMPAT_PRESERVE && compat != UBI_COMPAT_REJECT) { - ubi_err("bad compat"); + ubi_err(ubi, "bad compat"); goto bad; } if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto bad; } if (data_pad >= ubi->leb_size / 2) { - ubi_err("bad data_pad"); + ubi_err(ubi, "bad data_pad"); goto bad; } @@ -921,45 +926,45 @@ static int validate_vid_hdr(const struct ubi_device *ubi, * mapped logical eraseblocks. */ if (used_ebs == 0) { - ubi_err("zero used_ebs"); + ubi_err(ubi, "zero used_ebs"); goto bad; } if (data_size == 0) { - ubi_err("zero data_size"); + ubi_err(ubi, "zero data_size"); goto bad; } if (lnum < used_ebs - 1) { if (data_size != usable_leb_size) { - ubi_err("bad data_size"); + ubi_err(ubi, "bad data_size"); goto bad; } } else if (lnum == used_ebs - 1) { if (data_size == 0) { - ubi_err("bad data_size at last LEB"); + ubi_err(ubi, "bad data_size at last LEB"); goto bad; } } else { - ubi_err("too high lnum"); + ubi_err(ubi, "too high lnum"); goto bad; } } else { if (copy_flag == 0) { if (data_crc != 0) { - ubi_err("non-zero data CRC"); + ubi_err(ubi, "non-zero data CRC"); goto bad; } if (data_size != 0) { - ubi_err("non-zero data_size"); + ubi_err(ubi, "non-zero data_size"); goto bad; } } else { if (data_size == 0) { - ubi_err("zero data_size of copy"); + ubi_err(ubi, "zero data_size of copy"); goto bad; } } if (used_ebs != 0) { - ubi_err("bad used_ebs"); + ubi_err(ubi, "bad used_ebs"); goto bad; } } @@ -967,7 +972,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi, return 0; bad: - ubi_err("bad VID header"); + ubi_err(ubi, "bad VID header"); ubi_dump_vid_hdr(vid_hdr); dump_stack(); return 1; @@ -1012,7 +1017,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { if (verbose) - ubi_warn("no VID header found at PEB %d, only 0xFF bytes", + ubi_warn(ubi, "no VID header found at PEB %d, only 0xFF bytes", pnum); dbg_bld("no VID header found at PEB %d, only 0xFF bytes", pnum); @@ -1023,7 +1028,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, } if (verbose) { - ubi_warn("bad magic number at PEB %d: %08x instead of %08x", + ubi_warn(ubi, "bad magic number at PEB %d: %08x instead of %08x", pnum, magic, UBI_VID_HDR_MAGIC); ubi_dump_vid_hdr(vid_hdr); } @@ -1037,7 +1042,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (hdr_crc != crc) { if (verbose) { - ubi_warn("bad CRC at PEB %d, calculated %#08x, read %#08x", + ubi_warn(ubi, "bad CRC at PEB %d, calculated %#08x, read %#08x", pnum, crc, hdr_crc); ubi_dump_vid_hdr(vid_hdr); } @@ -1051,7 +1056,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, err = validate_vid_hdr(ubi, vid_hdr); if (err) { - ubi_err("validation failed for PEB %d", pnum); + ubi_err(ubi, "validation failed for PEB %d", pnum); return -EINVAL; } @@ -1096,6 +1101,9 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, if (err) return err; + if (ubi_dbg_power_cut(ubi, POWER_CUT_VID_WRITE)) + return -EROFS; + p = (char *)vid_hdr - ubi->vid_hdr_shift; err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset, ubi->vid_hdr_alsize); @@ -1121,7 +1129,7 @@ static int self_check_not_bad(const struct ubi_device *ubi, int pnum) if (!err) return err; - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); dump_stack(); return err > 0 ? -EINVAL : err; } @@ -1146,14 +1154,14 @@ static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, magic = be32_to_cpu(ec_hdr->magic); if (magic != UBI_EC_HDR_MAGIC) { - ubi_err("bad magic %#08x, must be %#08x", + ubi_err(ubi, "bad magic %#08x, must be %#08x", magic, UBI_EC_HDR_MAGIC); goto fail; } err = validate_ec_hdr(ubi, ec_hdr); if (err) { - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); goto fail; } @@ -1193,8 +1201,9 @@ static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); if (hdr_crc != crc) { - ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "bad CRC, calculated %#08x, read %#08x", + crc, hdr_crc); + ubi_err(ubi, "self-check failed for PEB %d", pnum); ubi_dump_ec_hdr(ec_hdr); dump_stack(); err = -EINVAL; @@ -1228,21 +1237,21 @@ static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, magic = be32_to_cpu(vid_hdr->magic); if (magic != UBI_VID_HDR_MAGIC) { - ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", + ubi_err(ubi, "bad VID header magic %#08x at PEB %d, must be %#08x", magic, pnum, UBI_VID_HDR_MAGIC); goto fail; } err = validate_vid_hdr(ubi, vid_hdr); if (err) { - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); goto fail; } return err; fail: - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); dump_stack(); return -EINVAL; @@ -1280,9 +1289,9 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); if (hdr_crc != crc) { - ubi_err("bad VID header CRC at PEB %d, calculated %#08x, read %#08x", + ubi_err(ubi, "bad VID header CRC at PEB %d, calculated %#08x, read %#08x", pnum, crc, hdr_crc); - ubi_err("self-check failed for PEB %d", pnum); + ubi_err(ubi, "self-check failed for PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); dump_stack(); err = -EINVAL; @@ -1321,7 +1330,7 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); if (!buf1) { - ubi_err("cannot allocate memory to check writes"); + ubi_err(ubi, "cannot allocate memory to check writes"); return 0; } @@ -1339,14 +1348,15 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, if (c == c1) continue; - ubi_err("self-check failed for PEB %d:%d, len %d", + ubi_err(ubi, "self-check failed for PEB %d:%d, len %d", pnum, offset, len); - ubi_msg("data differ at position %d", i); - ubi_msg("hex dump of the original buffer from %d to %d", + ubi_msg(ubi, "data differ at position %d", i); + dump_len = max_t(int, 128, len - i); + ubi_msg(ubi, "hex dump of the original buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf + i, dump_len, 1); - ubi_msg("hex dump of the read buffer from %d to %d", + ubi_msg(ubi, "hex dump of the read buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf1 + i, dump_len, 1); @@ -1386,20 +1396,20 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); if (!buf) { - ubi_err("cannot allocate memory to check for 0xFFs"); + ubi_err(ubi, "cannot allocate memory to check for 0xFFs"); return 0; } err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err && !mtd_is_bitflip(err)) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes", + ubi_err(ubi, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes", err, len, pnum, offset, read); goto error; } err = ubi_check_pattern(buf, 0xFF, len); if (err == 0) { - ubi_err("flash region at PEB %d:%d, length %d does not contain all 0xFF bytes", + ubi_err(ubi, "flash region at PEB %d:%d, length %d does not contain all 0xFF bytes", pnum, offset, len); goto fail; } @@ -1408,8 +1418,8 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) return 0; fail: - ubi_err("self-check failed for PEB %d", pnum); - ubi_msg("hex dump of the %d-%d region", offset, offset + len); + ubi_err(ubi, "self-check failed for PEB %d", pnum); + ubi_msg(ubi, "hex dump of the %d-%d region", offset, offset + len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); err = -EINVAL; error: diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index fd2bbd64f13..06b93147f1c 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -132,7 +132,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) return ERR_PTR(-EINVAL); if (mode != UBI_READONLY && mode != UBI_READWRITE && - mode != UBI_EXCLUSIVE) + mode != UBI_EXCLUSIVE && mode != UBI_METAONLY) return ERR_PTR(-EINVAL); /* @@ -177,10 +177,17 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) break; case UBI_EXCLUSIVE: - if (vol->exclusive || vol->writers || vol->readers) + if (vol->exclusive || vol->writers || vol->readers || + vol->metaonly) goto out_unlock; vol->exclusive = 1; break; + + case UBI_METAONLY: + if (vol->metaonly || vol->exclusive) + goto out_unlock; + vol->metaonly = 1; + break; } get_device(&vol->dev); vol->ref_count += 1; @@ -199,7 +206,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) return ERR_PTR(err); } if (err == 1) { - ubi_warn("volume %d on UBI device %d is corrupted", + ubi_warn(ubi, "volume %d on UBI device %d is corrupted", vol_id, ubi->ubi_num); vol->corrupted = 1; } @@ -216,7 +223,7 @@ out_free: kfree(desc); out_put_ubi: ubi_put_device(ubi); - ubi_err("cannot open device %d, volume %d, error %d", + ubi_err(ubi, "cannot open device %d, volume %d, error %d", ubi_num, vol_id, err); return ERR_PTR(err); } @@ -303,7 +310,7 @@ struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode) if (error) return ERR_PTR(error); - inode = path.dentry->d_inode; + inode = d_backing_inode(path.dentry); mod = inode->i_mode; ubi_num = ubi_major2num(imajor(inode)); vol_id = iminor(inode) - 1; @@ -340,6 +347,10 @@ void ubi_close_volume(struct ubi_volume_desc *desc) break; case UBI_EXCLUSIVE: vol->exclusive = 0; + break; + case UBI_METAONLY: + vol->metaonly = 0; + break; } vol->ref_count -= 1; spin_unlock(&ubi->volumes_lock); @@ -352,6 +363,43 @@ void ubi_close_volume(struct ubi_volume_desc *desc) EXPORT_SYMBOL_GPL(ubi_close_volume); /** + * leb_read_sanity_check - does sanity checks on read requests. + * @desc: volume descriptor + * @lnum: logical eraseblock number to read from + * @offset: offset within the logical eraseblock to read from + * @len: how many bytes to read + * + * This function is used by ubi_leb_read() and ubi_leb_read_sg() + * to perform sanity checks. + */ +static int leb_read_sanity_check(struct ubi_volume_desc *desc, int lnum, + int offset, int len) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + int vol_id = vol->vol_id; + + if (vol_id < 0 || vol_id >= ubi->vtbl_slots || lnum < 0 || + lnum >= vol->used_ebs || offset < 0 || len < 0 || + offset + len > vol->usable_leb_size) + return -EINVAL; + + if (vol->vol_type == UBI_STATIC_VOLUME) { + if (vol->used_ebs == 0) + /* Empty static UBI volume */ + return 0; + if (lnum == vol->used_ebs - 1 && + offset + len > vol->last_eb_bytes) + return -EINVAL; + } + + if (vol->upd_marker) + return -EBADF; + + return 0; +} + +/** * ubi_leb_read - read data. * @desc: volume descriptor * @lnum: logical eraseblock number to read from @@ -387,28 +435,16 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, dbg_gen("read %d bytes from LEB %d:%d:%d", len, vol_id, lnum, offset); - if (vol_id < 0 || vol_id >= ubi->vtbl_slots || lnum < 0 || - lnum >= vol->used_ebs || offset < 0 || len < 0 || - offset + len > vol->usable_leb_size) - return -EINVAL; - - if (vol->vol_type == UBI_STATIC_VOLUME) { - if (vol->used_ebs == 0) - /* Empty static UBI volume */ - return 0; - if (lnum == vol->used_ebs - 1 && - offset + len > vol->last_eb_bytes) - return -EINVAL; - } + err = leb_read_sanity_check(desc, lnum, offset, len); + if (err < 0) + return err; - if (vol->upd_marker) - return -EBADF; if (len == 0) return 0; err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check); if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) { - ubi_warn("mark volume %d as corrupted", vol_id); + ubi_warn(ubi, "mark volume %d as corrupted", vol_id); vol->corrupted = 1; } @@ -416,6 +452,47 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, } EXPORT_SYMBOL_GPL(ubi_leb_read); +#ifndef __UBOOT__ +/** + * ubi_leb_read_sg - read data into a scatter gather list. + * @desc: volume descriptor + * @lnum: logical eraseblock number to read from + * @buf: buffer where to store the read data + * @offset: offset within the logical eraseblock to read from + * @len: how many bytes to read + * @check: whether UBI has to check the read data's CRC or not. + * + * This function works exactly like ubi_leb_read_sg(). But instead of + * storing the read data into a buffer it writes to an UBI scatter gather + * list. + */ +int ubi_leb_read_sg(struct ubi_volume_desc *desc, int lnum, struct ubi_sgl *sgl, + int offset, int len, int check) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + int err, vol_id = vol->vol_id; + + dbg_gen("read %d bytes from LEB %d:%d:%d", len, vol_id, lnum, offset); + + err = leb_read_sanity_check(desc, lnum, offset, len); + if (err < 0) + return err; + + if (len == 0) + return 0; + + err = ubi_eba_read_leb_sg(ubi, vol, sgl, lnum, offset, len, check); + if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) { + ubi_warn(ubi, "mark volume %d as corrupted", vol_id); + vol->corrupted = 1; + } + + return err; +} +EXPORT_SYMBOL_GPL(ubi_leb_read_sg); +#endif + /** * ubi_leb_write - write data. * @desc: volume descriptor diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index 49530b7448f..504865b8e6e 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -63,6 +63,8 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id) for (i = 0; i < vol->used_ebs; i++) { int size; + cond_resched(); + if (i == vol->used_ebs - 1) size = vol->last_eb_bytes; else @@ -100,7 +102,7 @@ void ubi_update_reserved(struct ubi_device *ubi) ubi->avail_pebs -= need; ubi->rsvd_pebs += need; ubi->beb_rsvd_pebs += need; - ubi_msg("reserved more %d PEBs for bad PEB handling", need); + ubi_msg(ubi, "reserved more %d PEBs for bad PEB handling", need); } /** @@ -117,7 +119,7 @@ void ubi_calculate_reserved(struct ubi_device *ubi) ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count; if (ubi->beb_rsvd_level < 0) { ubi->beb_rsvd_level = 0; - ubi_warn("number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)", + ubi_warn(ubi, "number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)", ubi->bad_peb_count, ubi->bad_peb_limit); } } diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 2809805c2c0..83345cd42c1 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h @@ -395,8 +395,6 @@ struct ubi_vtbl_record { #define UBI_FM_MIN_POOL_SIZE 8 #define UBI_FM_MAX_POOL_SIZE 256 -#define UBI_FM_WL_POOL_SIZE 25 - /** * struct ubi_fm_sb - UBI fastmap super block * @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC) diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 754b3371d25..540f721e1ba 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -43,17 +43,18 @@ /* Normal UBI messages */ #ifdef CONFIG_UBI_SILENCE_MSG -#define ubi_msg(fmt, ...) +#define ubi_msg(ubi, fmt, ...) #else -#define ubi_msg(fmt, ...) printk(KERN_NOTICE "UBI: " fmt "\n", ##__VA_ARGS__) +#define ubi_msg(ubi, fmt, ...) printk(UBI_NAME_STR "%d: " fmt "\n", \ + ubi->ubi_num, ##__VA_ARGS__) #endif /* UBI warning messages */ -#define ubi_warn(fmt, ...) pr_warn("UBI warning: %s: " fmt "\n", \ - __func__, ##__VA_ARGS__) +#define ubi_warn(ubi, fmt, ...) pr_warn(UBI_NAME_STR "%d warning: %s: " fmt "\n", \ + ubi->ubi_num, __func__, ##__VA_ARGS__) /* UBI error messages */ -#define ubi_err(fmt, ...) pr_err("UBI error: %s: " fmt "\n", \ - __func__, ##__VA_ARGS__) +#define ubi_err(ubi, fmt, ...) pr_err(UBI_NAME_STR "%d error: %s: " fmt "\n", \ + ubi->ubi_num, __func__, ##__VA_ARGS__) /* Background thread name pattern */ #define UBI_BGT_NAME_PATTERN "ubi_bgt%dd" @@ -147,6 +148,17 @@ enum { UBI_BAD_FASTMAP, }; +/* + * Flags for emulate_power_cut in ubi_debug_info + * + * POWER_CUT_EC_WRITE: Emulate a power cut when writing an EC header + * POWER_CUT_VID_WRITE: Emulate a power cut when writing a VID header + */ +enum { + POWER_CUT_EC_WRITE = 0x01, + POWER_CUT_VID_WRITE = 0x02, +}; + /** * struct ubi_wl_entry - wear-leveling entry. * @u.rb: link in the corresponding (free/used) RB-tree @@ -257,6 +269,7 @@ struct ubi_fm_pool { * @readers: number of users holding this volume in read-only mode * @writers: number of users holding this volume in read-write mode * @exclusive: whether somebody holds this volume in exclusive mode + * @metaonly: whether somebody is altering only meta data of this volume * * @reserved_pebs: how many physical eraseblocks are reserved for this volume * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) @@ -305,6 +318,7 @@ struct ubi_volume { int readers; int writers; int exclusive; + int metaonly; int reserved_pebs; int vol_type; @@ -339,7 +353,8 @@ struct ubi_volume { /** * struct ubi_volume_desc - UBI volume descriptor returned when it is opened. * @vol: reference to the corresponding volume description object - * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, or %UBI_EXCLUSIVE) + * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, %UBI_EXCLUSIVE + * or %UBI_METAONLY) */ struct ubi_volume_desc { struct ubi_volume *vol; @@ -353,30 +368,48 @@ struct ubi_wl_entry; * * @chk_gen: if UBI general extra checks are enabled * @chk_io: if UBI I/O extra checks are enabled + * @chk_fastmap: if UBI fastmap extra checks are enabled * @disable_bgt: disable the background task for testing purposes * @emulate_bitflips: emulate bit-flips for testing purposes * @emulate_io_failures: emulate write/erase failures for testing purposes + * @emulate_power_cut: emulate power cut for testing purposes + * @power_cut_counter: count down for writes left until emulated power cut + * @power_cut_min: minimum number of writes before emulating a power cut + * @power_cut_max: maximum number of writes until emulating a power cut * @dfs_dir_name: name of debugfs directory containing files of this UBI device * @dfs_dir: direntry object of the UBI device debugfs directory * @dfs_chk_gen: debugfs knob to enable UBI general extra checks * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks + * @dfs_chk_fastmap: debugfs knob to enable UBI fastmap extra checks * @dfs_disable_bgt: debugfs knob to disable the background task * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures + * @dfs_emulate_power_cut: debugfs knob to emulate power cuts + * @dfs_power_cut_min: debugfs knob for minimum writes before power cut + * @dfs_power_cut_max: debugfs knob for maximum writes until power cut */ struct ubi_debug_info { unsigned int chk_gen:1; unsigned int chk_io:1; + unsigned int chk_fastmap:1; unsigned int disable_bgt:1; unsigned int emulate_bitflips:1; unsigned int emulate_io_failures:1; + unsigned int emulate_power_cut:2; + unsigned int power_cut_counter; + unsigned int power_cut_min; + unsigned int power_cut_max; char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; struct dentry *dfs_dir; struct dentry *dfs_chk_gen; struct dentry *dfs_chk_io; + struct dentry *dfs_chk_fastmap; struct dentry *dfs_disable_bgt; struct dentry *dfs_emulate_bitflips; struct dentry *dfs_emulate_io_failures; + struct dentry *dfs_emulate_power_cut; + struct dentry *dfs_power_cut_min; + struct dentry *dfs_power_cut_max; }; /** @@ -390,7 +423,8 @@ struct ubi_debug_info { * @volumes_lock: protects @volumes, @rsvd_pebs, @avail_pebs, beb_rsvd_pebs, * @beb_rsvd_level, @bad_peb_count, @good_peb_count, @vol_count, * @vol->readers, @vol->writers, @vol->exclusive, - * @vol->ref_count, @vol->mapping and @vol->eba_tbl. + * @vol->metaonly, @vol->ref_count, @vol->mapping and + * @vol->eba_tbl. * @ref_count: count of references on the UBI device * @image_seq: image sequence number recorded on EC headers * @@ -422,11 +456,13 @@ struct ubi_debug_info { * @fm_pool: in-memory data structure of the fastmap pool * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL * sub-system - * @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf + * @fm_protect: serializes ubi_update_fastmap(), protects @fm_buf and makes sure + * that critical sections cannot be interrupted by ubi_update_fastmap() * @fm_buf: vmalloc()'d buffer which holds the raw fastmap * @fm_size: fastmap size in bytes - * @fm_sem: allows ubi_update_fastmap() to block EBA table changes + * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes * @fm_work: fastmap work queue + * @fm_work_scheduled: non-zero if fastmap work was scheduled * * @used: RB-tree of used physical eraseblocks * @erroneous: RB-tree of erroneous used physical eraseblocks @@ -438,9 +474,11 @@ struct ubi_debug_info { * @pq_head: protection queue head * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from, * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, - * @erroneous, and @erroneous_peb_count fields + * @erroneous, @erroneous_peb_count, @fm_work_scheduled, @fm_pool, + * and @fm_wl_pool fields * @move_mutex: serializes eraseblock moves - * @work_sem: synchronizes the WL worker with use tasks + * @work_sem: used to wait for all the scheduled works to finish and prevent + * new works from being submitted * @wl_scheduled: non-zero if the wear-leveling was scheduled * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any * physical eraseblock @@ -474,7 +512,7 @@ struct ubi_debug_info { * @vid_hdr_offset: starting offset of the volume identifier header (might be * unaligned) * @vid_hdr_aloffset: starting offset of the VID header aligned to - * @hdrs_min_io_size + * @hdrs_min_io_size * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or * not @@ -527,13 +565,14 @@ struct ubi_device { struct ubi_fastmap_layout *fm; struct ubi_fm_pool fm_pool; struct ubi_fm_pool fm_wl_pool; - struct rw_semaphore fm_sem; - struct mutex fm_mutex; + struct rw_semaphore fm_eba_sem; + struct rw_semaphore fm_protect; void *fm_buf; size_t fm_size; #ifndef __UBOOT__ struct work_struct fm_work; #endif + int fm_work_scheduled; /* Wear-leveling sub-system's stuff */ struct rb_root used; @@ -716,14 +755,15 @@ struct ubi_attach_info { * @torture: if the physical eraseblock has to be tortured * @anchor: produce a anchor PEB to by used by fastmap * - * The @func pointer points to the worker function. If the @cancel argument is - * not zero, the worker has to free the resources and exit immediately. The - * worker has to return zero in case of success and a negative error code in + * The @func pointer points to the worker function. If the @shutdown argument is + * not zero, the worker has to free the resources and exit immediately as the + * WL sub-system is shutting down. + * The worker has to return zero in case of success and a negative error code in * case of failure. */ struct ubi_work { struct list_head list; - int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); + int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int shutdown); /* The below fields are only relevant to erasure works */ struct ubi_wl_entry *e; int vol_id; @@ -738,7 +778,7 @@ extern struct kmem_cache *ubi_wl_entry_slab; extern const struct file_operations ubi_ctrl_cdev_operations; extern const struct file_operations ubi_cdev_operations; extern const struct file_operations ubi_vol_cdev_operations; -extern struct class *ubi_class; +extern struct class ubi_class; extern struct mutex ubi_devices_mutex; extern struct blocking_notifier_head ubi_notifiers; @@ -807,6 +847,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum); int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, void *buf, int offset, int len, int check); +int ubi_eba_read_leb_sg(struct ubi_device *ubi, struct ubi_volume *vol, + struct ubi_sgl *sgl, int lnum, int offset, int len, + int check); int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, const void *buf, int offset, int len); int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, @@ -877,10 +920,14 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, int pnum, const struct ubi_vid_hdr *vid_hdr); /* fastmap.c */ +#ifdef CONFIG_MTD_UBI_FASTMAP size_t ubi_calc_fm_size(struct ubi_device *ubi); int ubi_update_fastmap(struct ubi_device *ubi); int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, int fm_anchor); +#else +static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; } +#endif /* block.c */ #ifdef CONFIG_MTD_UBI_BLOCK @@ -901,6 +948,42 @@ static inline int ubiblock_remove(struct ubi_volume_info *vi) } #endif +/* + * ubi_for_each_free_peb - walk the UBI free RB tree. + * @ubi: UBI device description object + * @e: a pointer to a ubi_wl_entry to use as cursor + * @pos: a pointer to RB-tree entry type to use as a loop counter + */ +#define ubi_for_each_free_peb(ubi, e, tmp_rb) \ + ubi_rb_for_each_entry((tmp_rb), (e), &(ubi)->free, u.rb) + +/* + * ubi_for_each_used_peb - walk the UBI used RB tree. + * @ubi: UBI device description object + * @e: a pointer to a ubi_wl_entry to use as cursor + * @pos: a pointer to RB-tree entry type to use as a loop counter + */ +#define ubi_for_each_used_peb(ubi, e, tmp_rb) \ + ubi_rb_for_each_entry((tmp_rb), (e), &(ubi)->used, u.rb) + +/* + * ubi_for_each_scub_peb - walk the UBI scub RB tree. + * @ubi: UBI device description object + * @e: a pointer to a ubi_wl_entry to use as cursor + * @pos: a pointer to RB-tree entry type to use as a loop counter + */ +#define ubi_for_each_scrub_peb(ubi, e, tmp_rb) \ + ubi_rb_for_each_entry((tmp_rb), (e), &(ubi)->scrub, u.rb) + +/* + * ubi_for_each_protected_peb - walk the UBI protection queue. + * @ubi: UBI device description object + * @i: a integer used as counter + * @e: a pointer to a ubi_wl_entry to use as cursor + */ +#define ubi_for_each_protected_peb(ubi, i, e) \ + for ((i) = 0; (i) < UBI_PROT_QUEUE_LEN; (i)++) \ + list_for_each_entry((e), &(ubi->pq[(i)]), u.list) /* * ubi_rb_for_each_entry - walk an RB-tree. @@ -1004,7 +1087,7 @@ static inline void ubi_ro_mode(struct ubi_device *ubi) { if (!ubi->ro_mode) { ubi->ro_mode = 1; - ubi_warn("switch to read-only mode"); + ubi_warn(ubi, "switch to read-only mode"); dump_stack(); } } @@ -1035,4 +1118,7 @@ static inline int idx2vol_id(const struct ubi_device *ubi, int idx) return idx; } +#ifdef __UBOOT__ +int do_work(struct ubi_device *ubi); +#endif #endif /* !__UBI_UBI_H__ */ diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index c52c9ce776a..e0caf8eed23 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -127,6 +127,10 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, ubi_assert(!vol->updating && !vol->changing_leb); vol->updating = 1; + vol->upd_buf = vmalloc(ubi->leb_size); + if (!vol->upd_buf) + return -ENOMEM; + err = set_update_marker(ubi, vol); if (err) return err; @@ -146,14 +150,12 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, err = clear_update_marker(ubi, vol, 0); if (err) return err; + + vfree(vol->upd_buf); vol->updating = 0; return 0; } - vol->upd_buf = vmalloc(ubi->leb_size); - if (!vol->upd_buf) - return -ENOMEM; - vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1, vol->usable_leb_size); vol->upd_bytes = bytes; diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index f4392f59692..f8ab08f9df0 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -114,6 +114,19 @@ static ssize_t vol_attribute_show(struct device *dev, ubi_put_device(ubi); return ret; } + +static struct attribute *volume_dev_attrs[] = { + &attr_vol_reserved_ebs.attr, + &attr_vol_type.attr, + &attr_vol_name.attr, + &attr_vol_corrupted.attr, + &attr_vol_alignment.attr, + &attr_vol_usable_eb_size.attr, + &attr_vol_data_bytes.attr, + &attr_vol_upd_marker.attr, + NULL +}; +ATTRIBUTE_GROUPS(volume_dev); #endif /* Release method for volume devices */ @@ -125,66 +138,6 @@ static void vol_release(struct device *dev) kfree(vol); } -#ifndef __UBOOT__ -/** - * volume_sysfs_init - initialize sysfs for new volume. - * @ubi: UBI device description object - * @vol: volume description object - * - * This function returns zero in case of success and a negative error code in - * case of failure. - * - * Note, this function does not free allocated resources in case of failure - - * the caller does it. This is because this would cause release() here and the - * caller would oops. - */ -static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol) -{ - int err; - - err = device_create_file(&vol->dev, &attr_vol_reserved_ebs); - if (err) - return err; - err = device_create_file(&vol->dev, &attr_vol_type); - if (err) - return err; - err = device_create_file(&vol->dev, &attr_vol_name); - if (err) - return err; - err = device_create_file(&vol->dev, &attr_vol_corrupted); - if (err) - return err; - err = device_create_file(&vol->dev, &attr_vol_alignment); - if (err) - return err; - err = device_create_file(&vol->dev, &attr_vol_usable_eb_size); - if (err) - return err; - err = device_create_file(&vol->dev, &attr_vol_data_bytes); - if (err) - return err; - err = device_create_file(&vol->dev, &attr_vol_upd_marker); - return err; -} - -/** - * volume_sysfs_close - close sysfs for a volume. - * @vol: volume description object - */ -static void volume_sysfs_close(struct ubi_volume *vol) -{ - device_remove_file(&vol->dev, &attr_vol_upd_marker); - device_remove_file(&vol->dev, &attr_vol_data_bytes); - device_remove_file(&vol->dev, &attr_vol_usable_eb_size); - device_remove_file(&vol->dev, &attr_vol_alignment); - device_remove_file(&vol->dev, &attr_vol_corrupted); - device_remove_file(&vol->dev, &attr_vol_name); - device_remove_file(&vol->dev, &attr_vol_type); - device_remove_file(&vol->dev, &attr_vol_reserved_ebs); - device_unregister(&vol->dev); -} -#endif - /** * ubi_create_volume - create volume. * @ubi: UBI device description object @@ -221,7 +174,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) } if (vol_id == UBI_VOL_NUM_AUTO) { - ubi_err("out of volume IDs"); + ubi_err(ubi, "out of volume IDs"); err = -ENFILE; goto out_unlock; } @@ -235,7 +188,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) /* Ensure that this volume does not exist */ err = -EEXIST; if (ubi->volumes[vol_id]) { - ubi_err("volume %d already exists", vol_id); + ubi_err(ubi, "volume %d already exists", vol_id); goto out_unlock; } @@ -244,20 +197,22 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) if (ubi->volumes[i] && ubi->volumes[i]->name_len == req->name_len && !strcmp(ubi->volumes[i]->name, req->name)) { - ubi_err("volume \"%s\" exists (ID %d)", req->name, i); + ubi_err(ubi, "volume \"%s\" exists (ID %d)", + req->name, i); goto out_unlock; } /* Calculate how many eraseblocks are requested */ vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment; - vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1, - vol->usable_leb_size); + vol->reserved_pebs = div_u64(req->bytes + vol->usable_leb_size - 1, + vol->usable_leb_size); /* Reserve physical eraseblocks */ if (vol->reserved_pebs > ubi->avail_pebs) { - ubi_err("not enough PEBs, only %d available", ubi->avail_pebs); + ubi_err(ubi, "not enough PEBs, only %d available", + ubi->avail_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); err = -ENOSPC; goto out_unlock; @@ -312,26 +267,25 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) dev = MKDEV(MAJOR(ubi->cdev.dev), vol_id + 1); err = cdev_add(&vol->cdev, dev, 1); if (err) { - ubi_err("cannot add character device"); + ubi_err(ubi, "cannot add character device"); goto out_mapping; } vol->dev.release = vol_release; vol->dev.parent = &ubi->dev; vol->dev.devt = dev; - vol->dev.class = ubi_class; +#ifndef __UBOOT__ + vol->dev.class = &ubi_class; + vol->dev.groups = volume_dev_groups; +#endif dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id); err = device_register(&vol->dev); if (err) { - ubi_err("cannot register device"); + ubi_err(ubi, "cannot register device"); goto out_cdev; } - err = volume_sysfs_init(ubi, vol); - if (err) - goto out_sysfs; - /* Fill volume table record */ memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record)); vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs); @@ -368,7 +322,7 @@ out_sysfs: */ do_free = 0; get_device(&vol->dev); - volume_sysfs_close(vol); + device_unregister(&vol->dev); out_cdev: cdev_del(&vol->cdev); out_mapping: @@ -384,7 +338,7 @@ out_unlock: kfree(vol); else put_device(&vol->dev); - ubi_err("cannot create volume %d, error %d", vol_id, err); + ubi_err(ubi, "cannot create volume %d, error %d", vol_id, err); return err; } @@ -436,7 +390,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) } cdev_del(&vol->cdev); - volume_sysfs_close(vol); + device_unregister(&vol->dev); spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs -= reserved_pebs; @@ -452,7 +406,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) return err; out_err: - ubi_err("cannot remove volume %d, error %d", vol_id, err); + ubi_err(ubi, "cannot remove volume %d, error %d", vol_id, err); spin_lock(&ubi->volumes_lock); ubi->volumes[vol_id] = vol; out_unlock: @@ -485,7 +439,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) if (vol->vol_type == UBI_STATIC_VOLUME && reserved_pebs < vol->used_ebs) { - ubi_err("too small size %d, %d LEBs contain data", + ubi_err(ubi, "too small size %d, %d LEBs contain data", reserved_pebs, vol->used_ebs); return -EINVAL; } @@ -514,10 +468,10 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) if (pebs > 0) { spin_lock(&ubi->volumes_lock); if (pebs > ubi->avail_pebs) { - ubi_err("not enough PEBs: requested %d, available %d", + ubi_err(ubi, "not enough PEBs: requested %d, available %d", pebs, ubi->avail_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); spin_unlock(&ubi->volumes_lock); err = -ENOSPC; @@ -641,7 +595,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) dev = MKDEV(MAJOR(ubi->cdev.dev), vol->vol_id + 1); err = cdev_add(&vol->cdev, dev, 1); if (err) { - ubi_err("cannot add character device for volume %d, error %d", + ubi_err(ubi, "cannot add character device for volume %d, error %d", vol_id, err); return err; } @@ -649,19 +603,15 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) vol->dev.release = vol_release; vol->dev.parent = &ubi->dev; vol->dev.devt = dev; - vol->dev.class = ubi_class; +#ifndef __UBOOT__ + vol->dev.class = &ubi_class; + vol->dev.groups = volume_dev_groups; +#endif dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id); err = device_register(&vol->dev); if (err) goto out_cdev; - err = volume_sysfs_init(ubi, vol); - if (err) { - cdev_del(&vol->cdev); - volume_sysfs_close(vol); - return err; - } - self_check_volumes(ubi); return err; @@ -684,7 +634,7 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol) ubi->volumes[vol->vol_id] = NULL; cdev_del(&vol->cdev); - volume_sysfs_close(vol); + device_unregister(&vol->dev); } /** @@ -708,7 +658,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) if (!vol) { if (reserved_pebs) { - ubi_err("no volume info, but volume exists"); + ubi_err(ubi, "no volume info, but volume exists"); goto fail; } spin_unlock(&ubi->volumes_lock); @@ -717,90 +667,91 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) if (vol->reserved_pebs < 0 || vol->alignment < 0 || vol->data_pad < 0 || vol->name_len < 0) { - ubi_err("negative values"); + ubi_err(ubi, "negative values"); goto fail; } if (vol->alignment > ubi->leb_size || vol->alignment == 0) { - ubi_err("bad alignment"); + ubi_err(ubi, "bad alignment"); goto fail; } n = vol->alignment & (ubi->min_io_size - 1); if (vol->alignment != 1 && n) { - ubi_err("alignment is not multiple of min I/O unit"); + ubi_err(ubi, "alignment is not multiple of min I/O unit"); goto fail; } n = ubi->leb_size % vol->alignment; if (vol->data_pad != n) { - ubi_err("bad data_pad, has to be %lld", n); + ubi_err(ubi, "bad data_pad, has to be %lld", n); goto fail; } if (vol->vol_type != UBI_DYNAMIC_VOLUME && vol->vol_type != UBI_STATIC_VOLUME) { - ubi_err("bad vol_type"); + ubi_err(ubi, "bad vol_type"); goto fail; } if (vol->upd_marker && vol->corrupted) { - ubi_err("update marker and corrupted simultaneously"); + ubi_err(ubi, "update marker and corrupted simultaneously"); goto fail; } if (vol->reserved_pebs > ubi->good_peb_count) { - ubi_err("too large reserved_pebs"); + ubi_err(ubi, "too large reserved_pebs"); goto fail; } n = ubi->leb_size - vol->data_pad; if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) { - ubi_err("bad usable_leb_size, has to be %lld", n); + ubi_err(ubi, "bad usable_leb_size, has to be %lld", n); goto fail; } if (vol->name_len > UBI_VOL_NAME_MAX) { - ubi_err("too long volume name, max is %d", UBI_VOL_NAME_MAX); + ubi_err(ubi, "too long volume name, max is %d", + UBI_VOL_NAME_MAX); goto fail; } n = strnlen(vol->name, vol->name_len + 1); if (n != vol->name_len) { - ubi_err("bad name_len %lld", n); + ubi_err(ubi, "bad name_len %lld", n); goto fail; } n = (long long)vol->used_ebs * vol->usable_leb_size; if (vol->vol_type == UBI_DYNAMIC_VOLUME) { if (vol->corrupted) { - ubi_err("corrupted dynamic volume"); + ubi_err(ubi, "corrupted dynamic volume"); goto fail; } if (vol->used_ebs != vol->reserved_pebs) { - ubi_err("bad used_ebs"); + ubi_err(ubi, "bad used_ebs"); goto fail; } if (vol->last_eb_bytes != vol->usable_leb_size) { - ubi_err("bad last_eb_bytes"); + ubi_err(ubi, "bad last_eb_bytes"); goto fail; } if (vol->used_bytes != n) { - ubi_err("bad used_bytes"); + ubi_err(ubi, "bad used_bytes"); goto fail; } } else { if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) { - ubi_err("bad used_ebs"); + ubi_err(ubi, "bad used_ebs"); goto fail; } if (vol->last_eb_bytes < 0 || vol->last_eb_bytes > vol->usable_leb_size) { - ubi_err("bad last_eb_bytes"); + ubi_err(ubi, "bad last_eb_bytes"); goto fail; } if (vol->used_bytes < 0 || vol->used_bytes > n || vol->used_bytes < n - vol->usable_leb_size) { - ubi_err("bad used_bytes"); + ubi_err(ubi, "bad used_bytes"); goto fail; } } @@ -818,7 +769,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) if (alignment != vol->alignment || data_pad != vol->data_pad || upd_marker != vol->upd_marker || vol_type != vol->vol_type || name_len != vol->name_len || strncmp(name, vol->name, name_len)) { - ubi_err("volume info is different"); + ubi_err(ubi, "volume info is different"); goto fail; } @@ -826,7 +777,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) return 0; fail: - ubi_err("self-check failed for volume %d", vol_id); + ubi_err(ubi, "self-check failed for volume %d", vol_id); if (vol) ubi_dump_vol_info(vol); ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index ae8ea38c625..993716fbf39 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -18,9 +18,12 @@ * eraseblock stores one volume table copy, i.e. LEB 0 and LEB 1 duplicate each * other. This redundancy guarantees robustness to unclean reboots. The volume * table is basically an array of volume table records. Each record contains - * full information about the volume and protected by a CRC checksum. + * full information about the volume and protected by a CRC checksum. Note, + * nowadays we use the atomic LEB change operation when updating the volume + * table, so we do not really need 2 LEBs anymore, but we preserve the older + * design for the backward compatibility reasons. * - * The volume table is changed, it is first changed in RAM. Then LEB 0 is + * When the volume table is changed, it is first changed in RAM. Then LEB 0 is * erased, and the updated volume table is written back to LEB 0. Then same for * LEB 1. This scheme guarantees recoverability from unclean reboots. * @@ -61,6 +64,26 @@ static void self_vtbl_check(const struct ubi_device *ubi); static struct ubi_vtbl_record empty_vtbl_record; /** + * ubi_update_layout_vol - helper for updatting layout volumes on flash + * @ubi: UBI device description object + */ +static int ubi_update_layout_vol(struct ubi_device *ubi) +{ + struct ubi_volume *layout_vol; + int i, err; + + layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)]; + for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { + err = ubi_eba_atomic_leb_change(ubi, layout_vol, i, ubi->vtbl, + ubi->vtbl_size); + if (err) + return err; + } + + return 0; +} + +/** * ubi_change_vtbl_record - change volume table record. * @ubi: UBI device description object * @idx: table index to change @@ -74,12 +97,10 @@ static struct ubi_vtbl_record empty_vtbl_record; int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, struct ubi_vtbl_record *vtbl_rec) { - int i, err; + int err; uint32_t crc; - struct ubi_volume *layout_vol; ubi_assert(idx >= 0 && idx < ubi->vtbl_slots); - layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)]; if (!vtbl_rec) vtbl_rec = &empty_vtbl_record; @@ -89,19 +110,10 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, } memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); - for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { - err = ubi_eba_unmap_leb(ubi, layout_vol, i); - if (err) - return err; - - err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, - ubi->vtbl_size); - if (err) - return err; - } + err = ubi_update_layout_vol(ubi); self_vtbl_check(ubi); - return 0; + return err ? err : 0; } /** @@ -116,9 +128,7 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, int ubi_vtbl_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list) { - int i, err; struct ubi_rename_entry *re; - struct ubi_volume *layout_vol; list_for_each_entry(re, rename_list, list) { uint32_t crc; @@ -140,19 +150,7 @@ int ubi_vtbl_rename_volumes(struct ubi_device *ubi, vtbl_rec->crc = cpu_to_be32(crc); } - layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)]; - for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { - err = ubi_eba_unmap_leb(ubi, layout_vol, i); - if (err) - return err; - - err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, - ubi->vtbl_size); - if (err) - return err; - } - - return 0; + return ubi_update_layout_vol(ubi); } /** @@ -184,7 +182,7 @@ static int vtbl_check(const struct ubi_device *ubi, crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC); if (be32_to_cpu(vtbl[i].crc) != crc) { - ubi_err("bad CRC at record %u: %#08x, not %#08x", + ubi_err(ubi, "bad CRC at record %u: %#08x, not %#08x", i, crc, be32_to_cpu(vtbl[i].crc)); ubi_dump_vtbl_record(&vtbl[i], i); return 1; @@ -218,7 +216,7 @@ static int vtbl_check(const struct ubi_device *ubi, n = ubi->leb_size % alignment; if (data_pad != n) { - ubi_err("bad data_pad, has to be %d", n); + ubi_err(ubi, "bad data_pad, has to be %d", n); err = 6; goto bad; } @@ -234,7 +232,7 @@ static int vtbl_check(const struct ubi_device *ubi, } if (reserved_pebs > ubi->good_peb_count) { - ubi_err("too large reserved_pebs %d, good PEBs %d", + ubi_err(ubi, "too large reserved_pebs %d, good PEBs %d", reserved_pebs, ubi->good_peb_count); err = 9; goto bad; @@ -268,7 +266,7 @@ static int vtbl_check(const struct ubi_device *ubi, #else !strncmp((char *)vtbl[i].name, vtbl[n].name, len1)) { #endif - ubi_err("volumes %d and %d have the same name \"%s\"", + ubi_err(ubi, "volumes %d and %d have the same name \"%s\"", i, n, vtbl[i].name); ubi_dump_vtbl_record(&vtbl[i], i); ubi_dump_vtbl_record(&vtbl[n], n); @@ -280,7 +278,7 @@ static int vtbl_check(const struct ubi_device *ubi, return 0; bad: - ubi_err("volume table check failed: record %d, error %d", i, err); + ubi_err(ubi, "volume table check failed: record %d, error %d", i, err); ubi_dump_vtbl_record(&vtbl[i], i); return -EINVAL; } @@ -444,11 +442,11 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, leb_corrupted[1] = memcmp(leb[0], leb[1], ubi->vtbl_size); if (leb_corrupted[1]) { - ubi_warn("volume table copy #2 is corrupted"); + ubi_warn(ubi, "volume table copy #2 is corrupted"); err = create_vtbl(ubi, ai, 1, leb[0]); if (err) goto out_free; - ubi_msg("volume table was restored"); + ubi_msg(ubi, "volume table was restored"); } /* Both LEB 1 and LEB 2 are OK and consistent */ @@ -463,15 +461,15 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, } if (leb_corrupted[1]) { /* Both LEB 0 and LEB 1 are corrupted */ - ubi_err("both volume tables are corrupted"); + ubi_err(ubi, "both volume tables are corrupted"); goto out_free; } - ubi_warn("volume table copy #1 is corrupted"); + ubi_warn(ubi, "volume table copy #1 is corrupted"); err = create_vtbl(ubi, ai, 0, leb[1]); if (err) goto out_free; - ubi_msg("volume table was restored"); + ubi_msg(ubi, "volume table was restored"); vfree(leb[0]); return leb[1]; @@ -560,7 +558,7 @@ static int init_volumes(struct ubi_device *ubi, if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) { /* Auto re-size flag may be set only for one volume */ if (ubi->autoresize_vol_id != -1) { - ubi_err("more than one auto-resize volume (%d and %d)", + ubi_err(ubi, "more than one auto-resize volume (%d and %d)", ubi->autoresize_vol_id, i); kfree(vol); return -EINVAL; @@ -589,7 +587,7 @@ static int init_volumes(struct ubi_device *ubi, /* Static volumes only */ av = ubi_find_av(ai, i); - if (!av) { + if (!av || !av->leb_count) { /* * No eraseblocks belonging to this volume found. We * don't actually know whether this static volume is @@ -606,7 +604,7 @@ static int init_volumes(struct ubi_device *ubi, * We found a static volume which misses several * eraseblocks. Treat it as corrupted. */ - ubi_warn("static volume %d misses %d LEBs - corrupted", + ubi_warn(ubi, "static volume %d misses %d LEBs - corrupted", av->vol_id, av->used_ebs - av->leb_count); vol->corrupted = 1; continue; @@ -644,10 +642,10 @@ static int init_volumes(struct ubi_device *ubi, vol->ubi = ubi; if (reserved_pebs > ubi->avail_pebs) { - ubi_err("not enough PEBs, required %d, available %d", + ubi_err(ubi, "not enough PEBs, required %d, available %d", reserved_pebs, ubi->avail_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); } ubi->rsvd_pebs += reserved_pebs; @@ -692,7 +690,7 @@ static int check_av(const struct ubi_volume *vol, return 0; bad: - ubi_err("bad attaching information, error %d", err); + ubi_err(vol->ubi, "bad attaching information, error %d", err); ubi_dump_av(av); ubi_dump_vol_info(vol); return -EINVAL; @@ -716,14 +714,15 @@ static int check_attaching_info(const struct ubi_device *ubi, struct ubi_volume *vol; if (ai->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { - ubi_err("found %d volumes while attaching, maximum is %d + %d", + ubi_err(ubi, "found %d volumes while attaching, maximum is %d + %d", ai->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots); return -EINVAL; } if (ai->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT && ai->highest_vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("too large volume ID %d found", ai->highest_vol_id); + ubi_err(ubi, "too large volume ID %d found", + ai->highest_vol_id); return -EINVAL; } @@ -751,7 +750,7 @@ static int check_attaching_info(const struct ubi_device *ubi, * reboot while the volume was being removed. Discard * these eraseblocks. */ - ubi_msg("finish volume %d removal", av->vol_id); + ubi_msg(ubi, "finish volume %d removal", av->vol_id); ubi_remove_av(ai, av); } else if (av) { err = check_av(vol, av); @@ -805,13 +804,13 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) if (IS_ERR(ubi->vtbl)) return PTR_ERR(ubi->vtbl); } else { - ubi_err("the layout volume was not found"); + ubi_err(ubi, "the layout volume was not found"); return -EINVAL; } } else { if (av->leb_count > UBI_LAYOUT_VOLUME_EBS) { /* This must not happen with proper UBI images */ - ubi_err("too many LEBs (%d) in layout volume", + ubi_err(ubi, "too many LEBs (%d) in layout volume", av->leb_count); return -EINVAL; } @@ -860,7 +859,7 @@ static void self_vtbl_check(const struct ubi_device *ubi) return; if (vtbl_check(ubi, ubi->vtbl)) { - ubi_err("self-check failed"); + ubi_err(ubi, "self-check failed"); BUG(); } } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 6886f89df25..507b0917206 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -96,6 +96,7 @@ #endif #include "ubi.h" +#include "wl.h" /* Number of physical eraseblocks reserved for wear-leveling purposes */ #define WL_RESERVED_PEBS 1 @@ -133,44 +134,6 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi, static int self_check_in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *e); -#ifdef CONFIG_MTD_UBI_FASTMAP -#ifndef __UBOOT__ -/** - * update_fastmap_work_fn - calls ubi_update_fastmap from a work queue - * @wrk: the work description object - */ -static void update_fastmap_work_fn(struct work_struct *wrk) -{ - struct ubi_device *ubi = container_of(wrk, struct ubi_device, fm_work); - ubi_update_fastmap(ubi); -} -#endif - -/** - * ubi_ubi_is_fm_block - returns 1 if a PEB is currently used in a fastmap. - * @ubi: UBI device description object - * @pnum: the to be checked PEB - */ -static int ubi_is_fm_block(struct ubi_device *ubi, int pnum) -{ - int i; - - if (!ubi->fm) - return 0; - - for (i = 0; i < ubi->fm->used_blocks; i++) - if (ubi->fm->e[i]->pnum == pnum) - return 1; - - return 0; -} -#else -static int ubi_is_fm_block(struct ubi_device *ubi, int pnum) -{ - return 0; -} -#endif - /** * wl_tree_add - add a wear-leveling entry to a WL RB-tree. * @e: the wear-leveling entry to add @@ -208,13 +171,31 @@ static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root) } /** + * wl_tree_destroy - destroy a wear-leveling entry. + * @ubi: UBI device description object + * @e: the wear-leveling entry to add + * + * This function destroys a wear leveling entry and removes + * the reference from the lookup table. + */ +static void wl_entry_destroy(struct ubi_device *ubi, struct ubi_wl_entry *e) +{ + ubi->lookuptbl[e->pnum] = NULL; + kmem_cache_free(ubi_wl_entry_slab, e); +} + +/** * do_work - do one pending work. * @ubi: UBI device description object * * This function returns zero in case of success and a negative error code in * case of failure. */ +#ifndef __UBOOT__ static int do_work(struct ubi_device *ubi) +#else +int do_work(struct ubi_device *ubi) +#endif { int err; struct ubi_work *wrk; @@ -248,40 +229,13 @@ static int do_work(struct ubi_device *ubi) */ err = wrk->func(ubi, wrk, 0); if (err) - ubi_err("work failed with error code %d", err); + ubi_err(ubi, "work failed with error code %d", err); up_read(&ubi->work_sem); return err; } /** - * produce_free_peb - produce a free physical eraseblock. - * @ubi: UBI device description object - * - * This function tries to make a free PEB by means of synchronous execution of - * pending works. This may be needed if, for example the background thread is - * disabled. Returns zero in case of success and a negative error code in case - * of failure. - */ -static int produce_free_peb(struct ubi_device *ubi) -{ - int err; - - while (!ubi->free.rb_node) { - spin_unlock(&ubi->wl_lock); - - dbg_wl("do one work synchronously"); - err = do_work(ubi); - - spin_lock(&ubi->wl_lock); - if (err) - return err; - } - - return 0; -} - -/** * in_wl_tree - check if wear-leveling entry is present in a WL RB-tree. * @e: the wear-leveling entry to check * @root: the root of the tree @@ -404,119 +358,32 @@ static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, if (last->ec - first->ec < WL_FREE_MAX_DIFF) { e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb); -#ifdef CONFIG_MTD_UBI_FASTMAP /* If no fastmap has been written and this WL entry can be used * as anchor PEB, hold it back and return the second best * WL entry such that fastmap can use the anchor PEB later. */ - if (e && !ubi->fm_disabled && !ubi->fm && - e->pnum < UBI_FM_MAX_START) - e = rb_entry(rb_next(root->rb_node), - struct ubi_wl_entry, u.rb); -#endif + e = may_reserve_for_fm(ubi, e, root); } else e = find_wl_entry(ubi, root, WL_FREE_MAX_DIFF/2); return e; } -#ifdef CONFIG_MTD_UBI_FASTMAP -/** - * find_anchor_wl_entry - find wear-leveling entry to used as anchor PEB. - * @root: the RB-tree where to look for - */ -static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root) -{ - struct rb_node *p; - struct ubi_wl_entry *e, *victim = NULL; - int max_ec = UBI_MAX_ERASECOUNTER; - - ubi_rb_for_each_entry(p, e, root, u.rb) { - if (e->pnum < UBI_FM_MAX_START && e->ec < max_ec) { - victim = e; - max_ec = e->ec; - } - } - - return victim; -} - -static int anchor_pebs_avalible(struct rb_root *root) -{ - struct rb_node *p; - struct ubi_wl_entry *e; - - ubi_rb_for_each_entry(p, e, root, u.rb) - if (e->pnum < UBI_FM_MAX_START) - return 1; - - return 0; -} - -/** - * ubi_wl_get_fm_peb - find a physical erase block with a given maximal number. - * @ubi: UBI device description object - * @anchor: This PEB will be used as anchor PEB by fastmap - * - * The function returns a physical erase block with a given maximal number - * and removes it from the wl subsystem. - * Must be called with wl_lock held! - */ -struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor) -{ - struct ubi_wl_entry *e = NULL; - - if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1)) - goto out; - - if (anchor) - e = find_anchor_wl_entry(&ubi->free); - else - e = find_mean_wl_entry(ubi, &ubi->free); - - if (!e) - goto out; - - self_check_in_wl_tree(ubi, e, &ubi->free); - - /* remove it from the free list, - * the wl subsystem does no longer know this erase block */ - rb_erase(&e->u.rb, &ubi->free); - ubi->free_count--; -out: - return e; -} -#endif - /** - * __wl_get_peb - get a physical eraseblock. + * wl_get_wle - get a mean wl entry to be used by ubi_wl_get_peb() or + * refill_wl_user_pool(). * @ubi: UBI device description object * - * This function returns a physical eraseblock in case of success and a - * negative error code in case of failure. + * This function returns a a wear leveling entry in case of success and + * NULL in case of failure. */ -static int __wl_get_peb(struct ubi_device *ubi) +static struct ubi_wl_entry *wl_get_wle(struct ubi_device *ubi) { - int err; struct ubi_wl_entry *e; -retry: - if (!ubi->free.rb_node) { - if (ubi->works_count == 0) { - ubi_err("no free eraseblocks"); - ubi_assert(list_empty(&ubi->works)); - return -ENOSPC; - } - - err = produce_free_peb(ubi); - if (err < 0) - return err; - goto retry; - } - e = find_mean_wl_entry(ubi, &ubi->free); if (!e) { - ubi_err("no free eraseblocks"); - return -ENOSPC; + ubi_err(ubi, "no free eraseblocks"); + return NULL; } self_check_in_wl_tree(ubi, e, &ubi->free); @@ -528,178 +395,10 @@ retry: rb_erase(&e->u.rb, &ubi->free); ubi->free_count--; dbg_wl("PEB %d EC %d", e->pnum, e->ec); -#ifndef CONFIG_MTD_UBI_FASTMAP - /* We have to enqueue e only if fastmap is disabled, - * is fastmap enabled prot_queue_add() will be called by - * ubi_wl_get_peb() after removing e from the pool. */ - prot_queue_add(ubi, e); -#endif - return e->pnum; -} - -#ifdef CONFIG_MTD_UBI_FASTMAP -/** - * return_unused_pool_pebs - returns unused PEB to the free tree. - * @ubi: UBI device description object - * @pool: fastmap pool description object - */ -static void return_unused_pool_pebs(struct ubi_device *ubi, - struct ubi_fm_pool *pool) -{ - int i; - struct ubi_wl_entry *e; - - for (i = pool->used; i < pool->size; i++) { - e = ubi->lookuptbl[pool->pebs[i]]; - wl_tree_add(e, &ubi->free); - ubi->free_count++; - } -} - -/** - * refill_wl_pool - refills all the fastmap pool used by the - * WL sub-system. - * @ubi: UBI device description object - */ -static void refill_wl_pool(struct ubi_device *ubi) -{ - struct ubi_wl_entry *e; - struct ubi_fm_pool *pool = &ubi->fm_wl_pool; - - return_unused_pool_pebs(ubi, pool); - - for (pool->size = 0; pool->size < pool->max_size; pool->size++) { - if (!ubi->free.rb_node || - (ubi->free_count - ubi->beb_rsvd_pebs < 5)) - break; - - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); - self_check_in_wl_tree(ubi, e, &ubi->free); - rb_erase(&e->u.rb, &ubi->free); - ubi->free_count--; - - pool->pebs[pool->size] = e->pnum; - } - pool->used = 0; -} - -/** - * refill_wl_user_pool - refills all the fastmap pool used by ubi_wl_get_peb. - * @ubi: UBI device description object - */ -static void refill_wl_user_pool(struct ubi_device *ubi) -{ - struct ubi_fm_pool *pool = &ubi->fm_pool; - - return_unused_pool_pebs(ubi, pool); - - for (pool->size = 0; pool->size < pool->max_size; pool->size++) { - pool->pebs[pool->size] = __wl_get_peb(ubi); - if (pool->pebs[pool->size] < 0) - break; - } - pool->used = 0; -} - -/** - * ubi_refill_pools - refills all fastmap PEB pools. - * @ubi: UBI device description object - */ -void ubi_refill_pools(struct ubi_device *ubi) -{ - spin_lock(&ubi->wl_lock); - refill_wl_pool(ubi); - refill_wl_user_pool(ubi); - spin_unlock(&ubi->wl_lock); -} - -/* ubi_wl_get_peb - works exaclty like __wl_get_peb but keeps track of - * the fastmap pool. - */ -int ubi_wl_get_peb(struct ubi_device *ubi) -{ - int ret; - struct ubi_fm_pool *pool = &ubi->fm_pool; - struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; - - if (!pool->size || !wl_pool->size || pool->used == pool->size || - wl_pool->used == wl_pool->size) - ubi_update_fastmap(ubi); - - /* we got not a single free PEB */ - if (!pool->size) - ret = -ENOSPC; - else { - spin_lock(&ubi->wl_lock); - ret = pool->pebs[pool->used++]; - prot_queue_add(ubi, ubi->lookuptbl[ret]); - spin_unlock(&ubi->wl_lock); - } - - return ret; -} - -/* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system. - * - * @ubi: UBI device description object - */ -static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) -{ - struct ubi_fm_pool *pool = &ubi->fm_wl_pool; - int pnum; - - if (pool->used == pool->size || !pool->size) { - /* We cannot update the fastmap here because this - * function is called in atomic context. - * Let's fail here and refill/update it as soon as possible. */ -#ifndef __UBOOT__ - schedule_work(&ubi->fm_work); -#else - /* In U-Boot we must call this directly */ - ubi_update_fastmap(ubi); -#endif - return NULL; - } else { - pnum = pool->pebs[pool->used++]; - return ubi->lookuptbl[pnum]; - } -} -#else -static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) -{ - struct ubi_wl_entry *e; - - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); - self_check_in_wl_tree(ubi, e, &ubi->free); - ubi->free_count--; - ubi_assert(ubi->free_count >= 0); - rb_erase(&e->u.rb, &ubi->free); return e; } -int ubi_wl_get_peb(struct ubi_device *ubi) -{ - int peb, err; - - spin_lock(&ubi->wl_lock); - peb = __wl_get_peb(ubi); - spin_unlock(&ubi->wl_lock); - - if (peb < 0) - return peb; - - err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, - ubi->peb_size - ubi->vid_hdr_aloffset); - if (err) { - ubi_err("new PEB %d does not contain all 0xFF bytes", peb); - return err; - } - - return peb; -} -#endif - /** * prot_queue_del - remove a physical eraseblock from the protection queue. * @ubi: UBI device description object @@ -760,7 +459,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, * Erase counter overflow. Upgrade UBI and use 64-bit * erase counters internally. */ - ubi_err("erase counter overflow at PEB %d, EC %llu", + ubi_err(ubi, "erase counter overflow at PEB %d, EC %llu", e->pnum, ec); err = -EINVAL; goto out_free; @@ -835,7 +534,7 @@ repeat: * @wrk: the work to schedule * * This function adds a work defined by @wrk to the tail of the pending works - * list. Can only be used of ubi->work_sem is already held in read mode! + * list. Can only be used if ubi->work_sem is already held in read mode! */ static void __schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) { @@ -847,11 +546,16 @@ static void __schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) if (ubi->thread_enabled && !ubi_dbg_is_bgt_disabled(ubi)) wake_up_process(ubi->bgt_thread); #else + int err; /* * U-Boot special: We have no bgt_thread in U-Boot! * So just call do_work() here directly. */ - do_work(ubi); + err = do_work(ubi); + if (err) { + ubi_err(ubi, "%s: work failed with error code %d", + ubi->bgt_name, err); + } #endif spin_unlock(&ubi->wl_lock); } @@ -872,18 +576,7 @@ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) } static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, - int cancel); - -#ifdef CONFIG_MTD_UBI_FASTMAP -/** - * ubi_is_erase_work - checks whether a work is erase work. - * @wrk: The work object to be checked - */ -int ubi_is_erase_work(struct ubi_work *wrk) -{ - return wrk->func == erase_worker; -} -#endif + int shutdown); /** * schedule_erase - schedule an erase work. @@ -902,7 +595,6 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, struct ubi_work *wl_wrk; ubi_assert(e); - ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", e->pnum, e->ec, torture); @@ -949,66 +641,22 @@ static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, return erase_worker(ubi, wl_wrk, 0); } -#ifdef CONFIG_MTD_UBI_FASTMAP -/** - * ubi_wl_put_fm_peb - returns a PEB used in a fastmap to the wear-leveling - * sub-system. - * see: ubi_wl_put_peb() - * - * @ubi: UBI device description object - * @fm_e: physical eraseblock to return - * @lnum: the last used logical eraseblock number for the PEB - * @torture: if this physical eraseblock has to be tortured - */ -int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e, - int lnum, int torture) -{ - struct ubi_wl_entry *e; - int vol_id, pnum = fm_e->pnum; - - dbg_wl("PEB %d", pnum); - - ubi_assert(pnum >= 0); - ubi_assert(pnum < ubi->peb_count); - - spin_lock(&ubi->wl_lock); - e = ubi->lookuptbl[pnum]; - - /* This can happen if we recovered from a fastmap the very - * first time and writing now a new one. In this case the wl system - * has never seen any PEB used by the original fastmap. - */ - if (!e) { - e = fm_e; - ubi_assert(e->ec >= 0); - ubi->lookuptbl[pnum] = e; - } else { - e->ec = fm_e->ec; - kfree(fm_e); - } - - spin_unlock(&ubi->wl_lock); - - vol_id = lnum ? UBI_FM_DATA_VOLUME_ID : UBI_FM_SB_VOLUME_ID; - return schedule_erase(ubi, e, vol_id, lnum, torture); -} -#endif - /** * wear_leveling_worker - wear-leveling worker function. * @ubi: UBI device description object * @wrk: the work object - * @cancel: non-zero if the worker has to free memory and exit + * @shutdown: non-zero if the worker has to free memory and exit + * because the WL-subsystem is shutting down * * This function copies a more worn out physical eraseblock to a less worn out * one. Returns zero in case of success and a negative error code in case of * failure. */ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, - int cancel) + int shutdown) { int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0; - int vol_id = -1, uninitialized_var(lnum); + int vol_id = -1, lnum = -1; #ifdef CONFIG_MTD_UBI_FASTMAP int anchor = wrk->anchor; #endif @@ -1016,7 +664,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, struct ubi_vid_hdr *vid_hdr; kfree(wrk); - if (cancel) + if (shutdown) return 0; vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); @@ -1144,7 +792,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, goto out_not_moved; } - ubi_err("error %d while reading VID header from PEB %d", + ubi_err(ubi, "error %d while reading VID header from PEB %d", err, e1->pnum); goto out_error; } @@ -1188,7 +836,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, * UBI from trying to move it over and over again. */ if (ubi->erroneous_peb_count > ubi->max_erroneous) { - ubi_err("too many erroneous eraseblocks (%d)", + ubi_err(ubi, "too many erroneous eraseblocks (%d)", ubi->erroneous_peb_count); goto out_error; } @@ -1204,7 +852,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, /* The PEB has been successfully moved */ if (scrubbing) - ubi_msg("scrubbed PEB %d (LEB %d:%d), data moved to PEB %d", + ubi_msg(ubi, "scrubbed PEB %d (LEB %d:%d), data moved to PEB %d", e1->pnum, vol_id, lnum, e2->pnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -1219,9 +867,8 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, err = do_sync_erase(ubi, e1, vol_id, lnum, 0); if (err) { - kmem_cache_free(ubi_wl_entry_slab, e1); if (e2) - kmem_cache_free(ubi_wl_entry_slab, e2); + wl_entry_destroy(ubi, e2); goto out_ro; } @@ -1233,10 +880,8 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", e2->pnum, vol_id, lnum); err = do_sync_erase(ubi, e2, vol_id, lnum, 0); - if (err) { - kmem_cache_free(ubi_wl_entry_slab, e2); + if (err) goto out_ro; - } } dbg_wl("done"); @@ -1272,19 +917,18 @@ out_not_moved: ubi_free_vid_hdr(ubi, vid_hdr); err = do_sync_erase(ubi, e2, vol_id, lnum, torture); - if (err) { - kmem_cache_free(ubi_wl_entry_slab, e2); + if (err) goto out_ro; - } + mutex_unlock(&ubi->move_mutex); return 0; out_error: if (vol_id != -1) - ubi_err("error %d while moving PEB %d to PEB %d", + ubi_err(ubi, "error %d while moving PEB %d to PEB %d", err, e1->pnum, e2->pnum); else - ubi_err("error %d while moving PEB %d (LEB %d:%d) to PEB %d", + ubi_err(ubi, "error %d while moving PEB %d (LEB %d:%d) to PEB %d", err, e1->pnum, vol_id, lnum, e2->pnum); spin_lock(&ubi->wl_lock); ubi->move_from = ubi->move_to = NULL; @@ -1292,8 +936,8 @@ out_error: spin_unlock(&ubi->wl_lock); ubi_free_vid_hdr(ubi, vid_hdr); - kmem_cache_free(ubi_wl_entry_slab, e1); - kmem_cache_free(ubi_wl_entry_slab, e2); + wl_entry_destroy(ubi, e1); + wl_entry_destroy(ubi, e2); out_ro: ubi_ro_mode(ubi); @@ -1379,43 +1023,12 @@ out_unlock: return err; } -#ifdef CONFIG_MTD_UBI_FASTMAP -/** - * ubi_ensure_anchor_pebs - schedule wear-leveling to produce an anchor PEB. - * @ubi: UBI device description object - */ -int ubi_ensure_anchor_pebs(struct ubi_device *ubi) -{ - struct ubi_work *wrk; - - spin_lock(&ubi->wl_lock); - if (ubi->wl_scheduled) { - spin_unlock(&ubi->wl_lock); - return 0; - } - ubi->wl_scheduled = 1; - spin_unlock(&ubi->wl_lock); - - wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); - if (!wrk) { - spin_lock(&ubi->wl_lock); - ubi->wl_scheduled = 0; - spin_unlock(&ubi->wl_lock); - return -ENOMEM; - } - - wrk->anchor = 1; - wrk->func = &wear_leveling_worker; - schedule_ubi_work(ubi, wrk); - return 0; -} -#endif - /** * erase_worker - physical eraseblock erase worker function. * @ubi: UBI device description object * @wl_wrk: the work object - * @cancel: non-zero if the worker has to free memory and exit + * @shutdown: non-zero if the worker has to free memory and exit + * because the WL sub-system is shutting down * * This function erases a physical eraseblock and perform torture testing if * needed. It also takes care about marking the physical eraseblock bad if @@ -1423,7 +1036,7 @@ int ubi_ensure_anchor_pebs(struct ubi_device *ubi) * failure. */ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, - int cancel) + int shutdown) { struct ubi_wl_entry *e = wl_wrk->e; int pnum = e->pnum; @@ -1431,18 +1044,16 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, int lnum = wl_wrk->lnum; int err, available_consumed = 0; - if (cancel) { + if (shutdown) { dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); kfree(wl_wrk); - kmem_cache_free(ubi_wl_entry_slab, e); + wl_entry_destroy(ubi, e); return 0; } dbg_wl("erase PEB %d EC %d LEB %d:%d", pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum); - ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); - err = sync_erase(ubi, e, wl_wrk->torture); if (!err) { /* Fine, we've erased it successfully */ @@ -1464,7 +1075,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, return err; } - ubi_err("failed to erase PEB %d, error %d", pnum, err); + ubi_err(ubi, "failed to erase PEB %d, error %d", pnum, err); kfree(wl_wrk); if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || @@ -1480,7 +1091,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, return err; } - kmem_cache_free(ubi_wl_entry_slab, e); + wl_entry_destroy(ubi, e); if (err != -EIO) /* * If this is not %-EIO, we have no idea what to do. Scheduling @@ -1492,7 +1103,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, /* It is %-EIO, the PEB went bad */ if (!ubi->bad_allowed) { - ubi_err("bad physical eraseblock %d detected", pnum); + ubi_err(ubi, "bad physical eraseblock %d detected", pnum); goto out_ro; } @@ -1500,7 +1111,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, if (ubi->beb_rsvd_pebs == 0) { if (ubi->avail_pebs == 0) { spin_unlock(&ubi->volumes_lock); - ubi_err("no reserved/available physical eraseblocks"); + ubi_err(ubi, "no reserved/available physical eraseblocks"); goto out_ro; } ubi->avail_pebs -= 1; @@ -1508,7 +1119,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, } spin_unlock(&ubi->volumes_lock); - ubi_msg("mark PEB %d as bad", pnum); + ubi_msg(ubi, "mark PEB %d as bad", pnum); err = ubi_io_mark_bad(ubi, pnum); if (err) goto out_ro; @@ -1529,11 +1140,12 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, ubi->good_peb_count -= 1; ubi_calculate_reserved(ubi); if (available_consumed) - ubi_warn("no PEBs in the reserved pool, used an available PEB"); + ubi_warn(ubi, "no PEBs in the reserved pool, used an available PEB"); else if (ubi->beb_rsvd_pebs) - ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs); + ubi_msg(ubi, "%d PEBs left in the reserve", + ubi->beb_rsvd_pebs); else - ubi_warn("last PEB from the reserve was used"); + ubi_warn(ubi, "last PEB from the reserve was used"); spin_unlock(&ubi->volumes_lock); return err; @@ -1571,6 +1183,8 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, ubi_assert(pnum >= 0); ubi_assert(pnum < ubi->peb_count); + down_read(&ubi->fm_protect); + retry: spin_lock(&ubi->wl_lock); e = ubi->lookuptbl[pnum]; @@ -1601,6 +1215,7 @@ retry: ubi_assert(!ubi->move_to_put); ubi->move_to_put = 1; spin_unlock(&ubi->wl_lock); + up_read(&ubi->fm_protect); return 0; } else { if (in_wl_tree(e, &ubi->used)) { @@ -1619,9 +1234,10 @@ retry: } else { err = prot_queue_del(ubi, e->pnum); if (err) { - ubi_err("PEB %d not found", pnum); + ubi_err(ubi, "PEB %d not found", pnum); ubi_ro_mode(ubi); spin_unlock(&ubi->wl_lock); + up_read(&ubi->fm_protect); return err; } } @@ -1635,6 +1251,7 @@ retry: spin_unlock(&ubi->wl_lock); } + up_read(&ubi->fm_protect); return err; } @@ -1652,7 +1269,7 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) { struct ubi_wl_entry *e; - ubi_msg("schedule PEB %d for scrubbing", pnum); + ubi_msg(ubi, "schedule PEB %d for scrubbing", pnum); retry: spin_lock(&ubi->wl_lock); @@ -1684,7 +1301,7 @@ retry: err = prot_queue_del(ubi, e->pnum); if (err) { - ubi_err("PEB %d not found", pnum); + ubi_err(ubi, "PEB %d not found", pnum); ubi_ro_mode(ubi); spin_unlock(&ubi->wl_lock); return err; @@ -1726,12 +1343,12 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) vol_id, lnum, ubi->works_count); while (found) { - struct ubi_work *wrk; + struct ubi_work *wrk, *tmp; found = 0; down_read(&ubi->work_sem); spin_lock(&ubi->wl_lock); - list_for_each_entry(wrk, &ubi->works, list) { + list_for_each_entry_safe(wrk, tmp, &ubi->works, list) { if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) && (lnum == UBI_ALL || wrk->lnum == lnum)) { list_del(&wrk->list); @@ -1766,9 +1383,10 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) /** * tree_destroy - destroy an RB-tree. + * @ubi: UBI device description object * @root: the root of the tree to destroy */ -static void tree_destroy(struct rb_root *root) +static void tree_destroy(struct ubi_device *ubi, struct rb_root *root) { struct rb_node *rb; struct ubi_wl_entry *e; @@ -1790,7 +1408,7 @@ static void tree_destroy(struct rb_root *root) rb->rb_right = NULL; } - kmem_cache_free(ubi_wl_entry_slab, e); + wl_entry_destroy(ubi, e); } } } @@ -1804,7 +1422,7 @@ int ubi_thread(void *u) int failures = 0; struct ubi_device *ubi = u; - ubi_msg("background thread \"%s\" started, PID %d", + ubi_msg(ubi, "background thread \"%s\" started, PID %d", ubi->bgt_name, task_pid_nr(current)); set_freezable(); @@ -1829,14 +1447,14 @@ int ubi_thread(void *u) err = do_work(ubi); if (err) { - ubi_err("%s: work failed with error code %d", + ubi_err(ubi, "%s: work failed with error code %d", ubi->bgt_name, err); if (failures++ > WL_MAX_FAILURES) { /* * Too many failures, disable the thread and * switch to read-only mode. */ - ubi_msg("%s: %d consecutive failures", + ubi_msg(ubi, "%s: %d consecutive failures", ubi->bgt_name, WL_MAX_FAILURES); ubi_ro_mode(ubi); ubi->thread_enabled = 0; @@ -1853,11 +1471,18 @@ int ubi_thread(void *u) } /** - * cancel_pending - cancel all pending works. + * shutdown_work - shutdown all pending works. * @ubi: UBI device description object */ -static void cancel_pending(struct ubi_device *ubi) +static void shutdown_work(struct ubi_device *ubi) { +#ifdef CONFIG_MTD_UBI_FASTMAP +#ifndef __UBOOT__ + flush_work(&ubi->fm_work); +#else + /* in U-Boot, we have all work done */ +#endif +#endif while (!list_empty(&ubi->works)) { struct ubi_work *wrk; @@ -1891,11 +1516,6 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) init_rwsem(&ubi->work_sem); ubi->max_ec = ai->max_ec; INIT_LIST_HEAD(&ubi->works); -#ifndef __UBOOT__ -#ifdef CONFIG_MTD_UBI_FASTMAP - INIT_WORK(&ubi->fm_work, update_fastmap_work_fn); -#endif -#endif sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num); @@ -1917,10 +1537,9 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) e->pnum = aeb->pnum; e->ec = aeb->ec; - ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); ubi->lookuptbl[e->pnum] = e; if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) { - kmem_cache_free(ubi_wl_entry_slab, e); + wl_entry_destroy(ubi, e); goto out_free; } @@ -1938,7 +1557,6 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) e->pnum = aeb->pnum; e->ec = aeb->ec; ubi_assert(e->ec >= 0); - ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); wl_tree_add(e, &ubi->free); ubi->free_count++; @@ -1976,23 +1594,26 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) dbg_wl("found %i PEBs", found_pebs); - if (ubi->fm) - ubi_assert(ubi->good_peb_count == \ + if (ubi->fm) { + ubi_assert(ubi->good_peb_count == found_pebs + ubi->fm->used_blocks); + + for (i = 0; i < ubi->fm->used_blocks; i++) { + e = ubi->fm->e[i]; + ubi->lookuptbl[e->pnum] = e; + } + } else ubi_assert(ubi->good_peb_count == found_pebs); reserved_pebs = WL_RESERVED_PEBS; -#ifdef CONFIG_MTD_UBI_FASTMAP - /* Reserve enough LEBs to store two fastmaps. */ - reserved_pebs += (ubi->fm_size / ubi->leb_size) * 2; -#endif + ubi_fastmap_init(ubi, &reserved_pebs); if (ubi->avail_pebs < reserved_pebs) { - ubi_err("no enough physical eraseblocks (%d, need %d)", + ubi_err(ubi, "no enough physical eraseblocks (%d, need %d)", ubi->avail_pebs, reserved_pebs); if (ubi->corr_peb_count) - ubi_err("%d PEBs are corrupted and not used", + ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); goto out_free; } @@ -2007,10 +1628,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) return 0; out_free: - cancel_pending(ubi); - tree_destroy(&ubi->used); - tree_destroy(&ubi->free); - tree_destroy(&ubi->scrub); + shutdown_work(ubi); + tree_destroy(ubi, &ubi->used); + tree_destroy(ubi, &ubi->free); + tree_destroy(ubi, &ubi->scrub); kfree(ubi->lookuptbl); return err; } @@ -2027,7 +1648,7 @@ static void protection_queue_destroy(struct ubi_device *ubi) for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) { list_for_each_entry_safe(e, tmp, &ubi->pq[i], u.list) { list_del(&e->u.list); - kmem_cache_free(ubi_wl_entry_slab, e); + wl_entry_destroy(ubi, e); } } } @@ -2039,12 +1660,13 @@ static void protection_queue_destroy(struct ubi_device *ubi) void ubi_wl_close(struct ubi_device *ubi) { dbg_wl("close the WL sub-system"); - cancel_pending(ubi); + ubi_fastmap_close(ubi); + shutdown_work(ubi); protection_queue_destroy(ubi); - tree_destroy(&ubi->used); - tree_destroy(&ubi->erroneous); - tree_destroy(&ubi->free); - tree_destroy(&ubi->scrub); + tree_destroy(ubi, &ubi->used); + tree_destroy(ubi, &ubi->erroneous); + tree_destroy(ubi, &ubi->free); + tree_destroy(ubi, &ubi->scrub); kfree(ubi->lookuptbl); } @@ -2080,8 +1702,8 @@ static int self_check_ec(struct ubi_device *ubi, int pnum, int ec) read_ec = be64_to_cpu(ec_hdr->ec); if (ec != read_ec && read_ec - ec > 1) { - ubi_err("self-check failed for PEB %d", pnum); - ubi_err("read EC is %lld, should be %d", read_ec, ec); + ubi_err(ubi, "self-check failed for PEB %d", pnum); + ubi_err(ubi, "read EC is %lld, should be %d", read_ec, ec); dump_stack(); err = 1; } else @@ -2110,7 +1732,7 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi, if (in_wl_tree(e, root)) return 0; - ubi_err("self-check failed for PEB %d, EC %d, RB-tree %p ", + ubi_err(ubi, "self-check failed for PEB %d, EC %d, RB-tree %p ", e->pnum, e->ec, root); dump_stack(); return -EINVAL; @@ -2138,8 +1760,99 @@ static int self_check_in_pq(const struct ubi_device *ubi, if (p == e) return 0; - ubi_err("self-check failed for PEB %d, EC %d, Protect queue", + ubi_err(ubi, "self-check failed for PEB %d, EC %d, Protect queue", e->pnum, e->ec); dump_stack(); return -EINVAL; } +#ifndef CONFIG_MTD_UBI_FASTMAP +static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) +{ + struct ubi_wl_entry *e; + + e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); + self_check_in_wl_tree(ubi, e, &ubi->free); + ubi->free_count--; + ubi_assert(ubi->free_count >= 0); + rb_erase(&e->u.rb, &ubi->free); + + return e; +} + +/** + * produce_free_peb - produce a free physical eraseblock. + * @ubi: UBI device description object + * + * This function tries to make a free PEB by means of synchronous execution of + * pending works. This may be needed if, for example the background thread is + * disabled. Returns zero in case of success and a negative error code in case + * of failure. + */ +static int produce_free_peb(struct ubi_device *ubi) +{ + int err; + + while (!ubi->free.rb_node && ubi->works_count) { + spin_unlock(&ubi->wl_lock); + + dbg_wl("do one work synchronously"); + err = do_work(ubi); + + spin_lock(&ubi->wl_lock); + if (err) + return err; + } + + return 0; +} + +/** + * ubi_wl_get_peb - get a physical eraseblock. + * @ubi: UBI device description object + * + * This function returns a physical eraseblock in case of success and a + * negative error code in case of failure. + * Returns with ubi->fm_eba_sem held in read mode! + */ +int ubi_wl_get_peb(struct ubi_device *ubi) +{ + int err; + struct ubi_wl_entry *e; + +retry: + down_read(&ubi->fm_eba_sem); + spin_lock(&ubi->wl_lock); + if (!ubi->free.rb_node) { + if (ubi->works_count == 0) { + ubi_err(ubi, "no free eraseblocks"); + ubi_assert(list_empty(&ubi->works)); + spin_unlock(&ubi->wl_lock); + return -ENOSPC; + } + + err = produce_free_peb(ubi); + if (err < 0) { + spin_unlock(&ubi->wl_lock); + return err; + } + spin_unlock(&ubi->wl_lock); + up_read(&ubi->fm_eba_sem); + goto retry; + + } + e = wl_get_wle(ubi); + prot_queue_add(ubi, e); + spin_unlock(&ubi->wl_lock); + + err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, + ubi->peb_size - ubi->vid_hdr_aloffset); + if (err) { + ubi_err(ubi, "new PEB %d does not contain all 0xFF bytes", e->pnum); + return err; + } + + return e->pnum; +} +#else +#include "fastmap-wl.c" +#endif diff --git a/drivers/mtd/ubi/wl.h b/drivers/mtd/ubi/wl.h new file mode 100644 index 00000000000..662dbe37654 --- /dev/null +++ b/drivers/mtd/ubi/wl.h @@ -0,0 +1,34 @@ +#ifndef UBI_WL_H +#define UBI_WL_H +#ifdef CONFIG_MTD_UBI_FASTMAP +static int anchor_pebs_avalible(struct rb_root *root); +#ifndef __UBOOT__ +static void update_fastmap_work_fn(struct work_struct *wrk); +#else +void update_fastmap_work_fn(struct ubi_device *ubi); +#endif +static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root); +static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi); +static void ubi_fastmap_close(struct ubi_device *ubi); +static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count) +{ + /* Reserve enough LEBs to store two fastmaps. */ + *count += (ubi->fm_size / ubi->leb_size) * 2; +#ifndef __UBOOT__ + INIT_WORK(&ubi->fm_work, update_fastmap_work_fn); +#endif +} +static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi, + struct ubi_wl_entry *e, + struct rb_root *root); +#else /* !CONFIG_MTD_UBI_FASTMAP */ +static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi); +static inline void ubi_fastmap_close(struct ubi_device *ubi) { } +static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count) { } +static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi, + struct ubi_wl_entry *e, + struct rb_root *root) { + return e; +} +#endif /* CONFIG_MTD_UBI_FASTMAP */ +#endif /* UBI_WL_H */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index bbec6a60e01..a03a95d0fbf 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -25,6 +25,15 @@ menuconfig NETDEVICES if NETDEVICES +config ALTERA_TSE + bool "Altera Triple-Speed Ethernet MAC support" + depends on DM_ETH + select PHYLIB + help + This driver supports the Altera Triple-Speed (TSE) Ethernet MAC. + Please find details on the "Triple-Speed Ethernet MegaCore Function + Resource Center" of Altera. + config E1000 bool "Intel PRO/1000 Gigabit Ethernet support" help diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c index ad3bd1e2124..319983c4829 100644 --- a/drivers/net/altera_tse.c +++ b/drivers/net/altera_tse.c @@ -8,91 +8,44 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include <config.h> #include <common.h> -#include <malloc.h> +#include <dm.h> +#include <errno.h> +#include <fdt_support.h> +#include <memalign.h> +#include <miiphy.h> #include <net.h> -#include <command.h> #include <asm/cache.h> #include <asm/dma-mapping.h> -#include <miiphy.h> +#include <asm/io.h> #include "altera_tse.h" -/* sgdma debug - print descriptor */ -static void alt_sgdma_print_desc(volatile struct alt_sgdma_descriptor *desc) -{ - debug("SGDMA DEBUG :\n"); - debug("desc->source : 0x%x \n", (unsigned int)desc->source); - debug("desc->destination : 0x%x \n", (unsigned int)desc->destination); - debug("desc->next : 0x%x \n", (unsigned int)desc->next); - debug("desc->source_pad : 0x%x \n", (unsigned int)desc->source_pad); - debug("desc->destination_pad : 0x%x \n", - (unsigned int)desc->destination_pad); - debug("desc->next_pad : 0x%x \n", (unsigned int)desc->next_pad); - debug("desc->bytes_to_transfer : 0x%x \n", - (unsigned int)desc->bytes_to_transfer); - debug("desc->actual_bytes_transferred : 0x%x \n", - (unsigned int)desc->actual_bytes_transferred); - debug("desc->descriptor_status : 0x%x \n", - (unsigned int)desc->descriptor_status); - debug("desc->descriptor_control : 0x%x \n", - (unsigned int)desc->descriptor_control); -} +DECLARE_GLOBAL_DATA_PTR; -/* This is a generic routine that the SGDMA mode-specific routines - * call to populate a descriptor. - * arg1 :pointer to first SGDMA descriptor. - * arg2 :pointer to next SGDMA descriptor. - * arg3 :Address to where data to be written. - * arg4 :Address from where data to be read. - * arg5 :no of byte to transaction. - * arg6 :variable indicating to generate start of packet or not - * arg7 :read fixed - * arg8 :write fixed - * arg9 :read burst - * arg10 :write burst - * arg11 :atlantic_channel number - */ -static void alt_sgdma_construct_descriptor_burst( - volatile struct alt_sgdma_descriptor *desc, - volatile struct alt_sgdma_descriptor *next, - unsigned int *read_addr, - unsigned int *write_addr, +static inline void alt_sgdma_construct_descriptor( + struct alt_sgdma_descriptor *desc, + struct alt_sgdma_descriptor *next, + void *read_addr, + void *write_addr, unsigned short length_or_eop, int generate_eop, int read_fixed, - int write_fixed_or_sop, - int read_burst, - int write_burst, - unsigned char atlantic_channel) + int write_fixed_or_sop) { + unsigned char val; + /* * Mark the "next" descriptor as "not" owned by hardware. This prevents - * The SGDMA controller from continuing to process the chain. This is - * done as a single IO write to bypass cache, without flushing - * the entire descriptor, since only the 8-bit descriptor status must - * be flushed. + * The SGDMA controller from continuing to process the chain. */ - if (!next) - debug("Next descriptor not defined!!\n"); - - next->descriptor_control = (next->descriptor_control & - ~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK); - - desc->source = (unsigned int *)((unsigned int)read_addr & 0x1FFFFFFF); - desc->destination = - (unsigned int *)((unsigned int)write_addr & 0x1FFFFFFF); - desc->next = (unsigned int *)((unsigned int)next & 0x1FFFFFFF); - desc->source_pad = 0x0; - desc->destination_pad = 0x0; - desc->next_pad = 0x0; - desc->bytes_to_transfer = length_or_eop; - desc->actual_bytes_transferred = 0; - desc->descriptor_status = 0x0; + next->descriptor_control = next->descriptor_control & + ~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK; - /* SGDMA burst not currently supported */ - desc->read_burst = 0; - desc->write_burst = 0; + memset(desc, 0, sizeof(struct alt_sgdma_descriptor)); + desc->source = virt_to_phys(read_addr); + desc->destination = virt_to_phys(write_addr); + desc->next = virt_to_phys(next); + desc->bytes_to_transfer = length_or_eop; /* * Set the descriptor control block as follows: @@ -108,108 +61,49 @@ static void alt_sgdma_construct_descriptor_burst( * pointing at this descriptor, it will not run (via the "owned by * hardware" bit) until all other descriptor has been set up. */ - - desc->descriptor_control = - ((ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK) | - (generate_eop ? - ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK : 0x0) | - (read_fixed ? - ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK : 0x0) | - (write_fixed_or_sop ? - ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK : 0x0) | - (atlantic_channel ? ((atlantic_channel & 0x0F) << 3) : 0) - ); + val = ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK; + if (generate_eop) + val |= ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK; + if (read_fixed) + val |= ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK; + if (write_fixed_or_sop) + val |= ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK; + desc->descriptor_control = val; } -static int alt_sgdma_do_sync_transfer(volatile struct alt_sgdma_registers *dev, - volatile struct alt_sgdma_descriptor *desc) +static int alt_sgdma_wait_transfer(struct alt_sgdma_registers *regs) { - unsigned int status; - int counter = 0; - - /* Wait for any pending transfers to complete */ - alt_sgdma_print_desc(desc); - status = dev->status; + int status; + ulong ctime; - counter = 0; - while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) + /* Wait for the descriptor (chain) to complete */ + ctime = get_timer(0); + while (1) { + status = readl(®s->status); + if (!(status & ALT_SGDMA_STATUS_BUSY_MSK)) + break; + if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) { + status = -ETIMEDOUT; + debug("sgdma timeout\n"); break; + } } - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - debug("Timeout waiting sgdma in do sync!\n"); - - /* - * Clear any (previous) status register information - * that might occlude our error checking later. - */ - dev->status = 0xFF; - - /* Point the controller at the descriptor */ - dev->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF; - debug("next desc in sgdma 0x%x\n", - (unsigned int)dev->next_descriptor_pointer); - - /* - * Set up SGDMA controller to: - * - Disable interrupt generation - * - Run once a valid descriptor is written to controller - * - Stop on an error with any particular descriptor - */ - dev->control = (ALT_SGDMA_CONTROL_RUN_MSK | - ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK); - - /* Wait for the descriptor (chain) to complete */ - status = dev->status; - debug("wait for sgdma...."); - while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) - ; - debug("done\n"); - /* Clear Run */ - dev->control = (dev->control & (~ALT_SGDMA_CONTROL_RUN_MSK)); - - /* Get & clear status register contents */ - status = dev->status; - dev->status = 0xFF; + writel(0, ®s->control); + /* Clear status */ + writel(0xff, ®s->status); - /* we really should check if the transfer completes properly */ - debug("tx sgdma status = 0x%x", status); - return 0; + return status; } -static int alt_sgdma_do_async_transfer(volatile struct alt_sgdma_registers *dev, - volatile struct alt_sgdma_descriptor *desc) +static int alt_sgdma_start_transfer(struct alt_sgdma_registers *regs, + struct alt_sgdma_descriptor *desc) { - int counter = 0; - - /* Wait for any pending transfers to complete */ - alt_sgdma_print_desc(desc); - - counter = 0; - while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - break; - } - - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - debug("Timeout waiting sgdma in do async!\n"); - - /* - * Clear the RUN bit in the control register. This is needed - * to restart the SGDMA engine later on. - */ - dev->control = 0; - - /* - * Clear any (previous) status register information - * that might occlude our error checking later. - */ - dev->status = 0xFF; + unsigned int val; /* Point the controller at the descriptor */ - dev->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF; + writel(virt_to_phys(desc), ®s->next_descriptor_pointer); /* * Set up SGDMA controller to: @@ -217,26 +111,31 @@ static int alt_sgdma_do_async_transfer(volatile struct alt_sgdma_registers *dev, * - Run once a valid descriptor is written to controller * - Stop on an error with any particular descriptor */ - dev->control = (ALT_SGDMA_CONTROL_RUN_MSK | - ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK); + val = ALT_SGDMA_CONTROL_RUN_MSK | ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK; + writel(val, ®s->control); - /* we really should check if the transfer completes properly */ return 0; } -/* u-boot interface */ -static int tse_adjust_link(struct altera_tse_priv *priv) +static void tse_adjust_link(struct altera_tse_priv *priv, + struct phy_device *phydev) { + struct alt_tse_mac *mac_dev = priv->mac_dev; unsigned int refvar; - refvar = priv->mac_dev->command_config.image; + if (!phydev->link) { + debug("%s: No link.\n", phydev->dev->name); + return; + } + + refvar = readl(&mac_dev->command_config); - if (!(priv->duplexity)) + if (phydev->duplex) refvar |= ALTERA_TSE_CMD_HD_ENA_MSK; else refvar &= ~ALTERA_TSE_CMD_HD_ENA_MSK; - switch (priv->speed) { + switch (phydev->speed) { case 1000: refvar |= ALTERA_TSE_CMD_ETH_SPEED_MSK; refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK; @@ -250,721 +149,383 @@ static int tse_adjust_link(struct altera_tse_priv *priv) refvar |= ALTERA_TSE_CMD_ENA_10_MSK; break; } - priv->mac_dev->command_config.image = refvar; - - return 0; + writel(refvar, &mac_dev->command_config); } -static int tse_eth_send(struct eth_device *dev, void *packet, int length) +static int altera_tse_send(struct udevice *dev, void *packet, int length) { - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; - volatile struct alt_sgdma_descriptor *tx_desc = - (volatile struct alt_sgdma_descriptor *)priv->tx_desc; - - volatile struct alt_sgdma_descriptor *tx_desc_cur = - (volatile struct alt_sgdma_descriptor *)&tx_desc[0]; - - flush_dcache_range((unsigned long)packet, - (unsigned long)packet + length); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&tx_desc[0], - (volatile struct alt_sgdma_descriptor *)&tx_desc[1], - (unsigned int *)packet, /* read addr */ - (unsigned int *)0, + struct altera_tse_priv *priv = dev_get_priv(dev); + struct alt_sgdma_descriptor *tx_desc = priv->tx_desc; + unsigned long tx_buf = (unsigned long)packet; + + flush_dcache_range(tx_buf, tx_buf + length); + alt_sgdma_construct_descriptor( + tx_desc, + tx_desc + 1, + packet, /* read addr */ + NULL, /* write addr */ length, /* length or EOP ,will change for each tx */ - 0x1, /* gen eop */ - 0x0, /* read fixed */ - 0x1, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ + 1, /* gen eop */ + 0, /* read fixed */ + 1 /* write fixed or sop */ ); - debug("TX Packet @ 0x%x,0x%x bytes", (unsigned int)packet, length); /* send the packet */ - debug("sending packet\n"); - alt_sgdma_do_sync_transfer(tx_sgdma, tx_desc_cur); - debug("sent %d bytes\n", tx_desc_cur->actual_bytes_transferred); - return tx_desc_cur->actual_bytes_transferred; + alt_sgdma_start_transfer(priv->sgdma_tx, tx_desc); + alt_sgdma_wait_transfer(priv->sgdma_tx); + debug("sent %d bytes\n", tx_desc->actual_bytes_transferred); + + return tx_desc->actual_bytes_transferred; } -static int tse_eth_rx(struct eth_device *dev) +static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp) { - int packet_length = 0; - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_sgdma_descriptor *rx_desc = - (volatile struct alt_sgdma_descriptor *)priv->rx_desc; - volatile struct alt_sgdma_descriptor *rx_desc_cur = &rx_desc[0]; + struct altera_tse_priv *priv = dev_get_priv(dev); + struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; + int packet_length; - if (rx_desc_cur->descriptor_status & + if (rx_desc->descriptor_status & ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) { - debug("got packet\n"); packet_length = rx_desc->actual_bytes_transferred; - net_process_received_packet(net_rx_packets[0], packet_length); - - /* start descriptor again */ - flush_dcache_range((unsigned long)(net_rx_packets[0]), - (unsigned long)(net_rx_packets[0] + - PKTSIZE_ALIGN)); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&rx_desc[0], - (volatile struct alt_sgdma_descriptor *)&rx_desc[1], - (unsigned int)0x0, /* read addr */ - (unsigned int *)net_rx_packets[0], - 0x0, /* length or EOP */ - 0x0, /* gen eop */ - 0x0, /* read fixed */ - 0x0, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ - ); - - /* setup the sgdma */ - alt_sgdma_do_async_transfer(priv->sgdma_rx, &rx_desc[0]); + debug("recv %d bytes\n", packet_length); + *packetp = priv->rx_buf; return packet_length; } - return -1; + return -EAGAIN; } -static void tse_eth_halt(struct eth_device *dev) +static int altera_tse_free_pkt(struct udevice *dev, uchar *packet, + int length) { - /* don't do anything! */ - /* this gets called after each uboot */ - /* network command. don't need to reset the thing all of the time */ + struct altera_tse_priv *priv = dev_get_priv(dev); + struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; + unsigned long rx_buf = (unsigned long)priv->rx_buf; + + alt_sgdma_wait_transfer(priv->sgdma_rx); + invalidate_dcache_range(rx_buf, rx_buf + PKTSIZE_ALIGN); + alt_sgdma_construct_descriptor( + rx_desc, + rx_desc + 1, + NULL, /* read addr */ + priv->rx_buf, /* write addr */ + 0, /* length or EOP */ + 0, /* gen eop */ + 0, /* read fixed */ + 0 /* write fixed or sop */ + ); + + /* setup the sgdma */ + alt_sgdma_start_transfer(priv->sgdma_rx, rx_desc); + debug("recv setup\n"); + + return 0; } -static void tse_eth_reset(struct eth_device *dev) +static void altera_tse_stop(struct udevice *dev) { - /* stop sgdmas, disable tse receive */ - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_tse_mac *mac_dev = priv->mac_dev; - volatile struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx; - volatile struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; - int counter; - volatile struct alt_sgdma_descriptor *rx_desc = - (volatile struct alt_sgdma_descriptor *)&priv->rx_desc[0]; + struct altera_tse_priv *priv = dev_get_priv(dev); + struct alt_tse_mac *mac_dev = priv->mac_dev; + struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx; + struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; + struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; + unsigned int status; + int ret; + ulong ctime; /* clear rx desc & wait for sgdma to complete */ rx_desc->descriptor_control = 0; - rx_sgdma->control = 0; - counter = 0; - while (rx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - break; - } - - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) { - debug("Timeout waiting for rx sgdma!\n"); - rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - } - - counter = 0; - tx_sgdma->control = 0; - while (tx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - break; - } + writel(0, &rx_sgdma->control); + ret = alt_sgdma_wait_transfer(rx_sgdma); + if (ret == -ETIMEDOUT) + writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK, + &rx_sgdma->control); + + writel(0, &tx_sgdma->control); + ret = alt_sgdma_wait_transfer(tx_sgdma); + if (ret == -ETIMEDOUT) + writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK, + &tx_sgdma->control); - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) { - debug("Timeout waiting for tx sgdma!\n"); - tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - } /* reset the mac */ - mac_dev->command_config.bits.transmit_enable = 1; - mac_dev->command_config.bits.receive_enable = 1; - mac_dev->command_config.bits.software_reset = 1; - - counter = 0; - while (mac_dev->command_config.bits.software_reset) { - if (counter++ > ALT_TSE_SW_RESET_WATCHDOG_CNTR) + writel(ALTERA_TSE_CMD_SW_RESET_MSK, &mac_dev->command_config); + ctime = get_timer(0); + while (1) { + status = readl(&mac_dev->command_config); + if (!(status & ALTERA_TSE_CMD_SW_RESET_MSK)) break; + if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) { + debug("Reset mac timeout\n"); + break; + } } - - if (counter >= ALT_TSE_SW_RESET_WATCHDOG_CNTR) - debug("TSEMAC SW reset bit never cleared!\n"); } -static int tse_mdio_read(struct altera_tse_priv *priv, unsigned int regnum) +static int tse_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) { - volatile struct alt_tse_mac *mac_dev; - unsigned int *mdio_regs; - unsigned int data; - u16 value; - - mac_dev = priv->mac_dev; + struct altera_tse_priv *priv = bus->priv; + struct alt_tse_mac *mac_dev = priv->mac_dev; + unsigned int value; /* set mdio address */ - mac_dev->mdio_phy1_addr = priv->phyaddr; - mdio_regs = (unsigned int *)&mac_dev->mdio_phy1; - + writel(addr, &mac_dev->mdio_phy1_addr); /* get the data */ - data = mdio_regs[regnum]; + value = readl(&mac_dev->mdio_phy1[reg]); - value = data & 0xffff; - - return value; + return value & 0xffff; } -static int tse_mdio_write(struct altera_tse_priv *priv, unsigned int regnum, - unsigned int value) +static int tse_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val) { - volatile struct alt_tse_mac *mac_dev; - unsigned int *mdio_regs; - unsigned int data; - - mac_dev = priv->mac_dev; + struct altera_tse_priv *priv = bus->priv; + struct alt_tse_mac *mac_dev = priv->mac_dev; /* set mdio address */ - mac_dev->mdio_phy1_addr = priv->phyaddr; - mdio_regs = (unsigned int *)&mac_dev->mdio_phy1; - - /* get the data */ - data = (unsigned int)value; - - mdio_regs[regnum] = data; - - return 0; -} - -/* MDIO access to phy */ -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII) -static int altera_tse_miiphy_write(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - struct eth_device *dev; - struct altera_tse_priv *priv; - dev = eth_get_dev_by_name(devname); - priv = dev->priv; - - tse_mdio_write(priv, (uint) reg, (uint) value); - - return 0; -} - -static int altera_tse_miiphy_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - struct eth_device *dev; - struct altera_tse_priv *priv; - volatile struct alt_tse_mac *mac_dev; - unsigned int *mdio_regs; - - dev = eth_get_dev_by_name(devname); - priv = dev->priv; - - mac_dev = priv->mac_dev; - mac_dev->mdio_phy1_addr = (int)addr; - mdio_regs = (unsigned int *)&mac_dev->mdio_phy1; - - *value = 0xffff & mdio_regs[reg]; - - return 0; - -} -#endif - -/* - * Also copied from tsec.c - */ -/* Parse the status register for link, and then do - * auto-negotiation - */ -static uint mii_parse_sr(uint mii_reg, struct altera_tse_priv *priv) -{ - /* - * Wait if the link is up, and autonegotiation is in progress - * (ie - we're capable and it's not done) - */ - mii_reg = tse_mdio_read(priv, MIIM_STATUS); - - if (!(mii_reg & MIIM_STATUS_LINK) && (mii_reg & BMSR_ANEGCAPABLE) - && !(mii_reg & BMSR_ANEGCOMPLETE)) { - int i = 0; - - puts("Waiting for PHY auto negotiation to complete"); - while (!(mii_reg & BMSR_ANEGCOMPLETE)) { - /* - * Timeout reached ? - */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts(" TIMEOUT !\n"); - priv->link = 0; - return 0; - } - - if ((i++ % 1000) == 0) - putc('.'); - udelay(1000); /* 1 ms */ - mii_reg = tse_mdio_read(priv, MIIM_STATUS); - } - puts(" done\n"); - priv->link = 1; - udelay(500000); /* another 500 ms (results in faster booting) */ - } else { - if (mii_reg & MIIM_STATUS_LINK) { - debug("Link is up\n"); - priv->link = 1; - } else { - debug("Link is down\n"); - priv->link = 0; - } - } + writel(addr, &mac_dev->mdio_phy1_addr); + /* set the data */ + writel(val, &mac_dev->mdio_phy1[reg]); return 0; } -/* Parse the 88E1011's status register for speed and duplex - * information - */ -static uint mii_parse_88E1011_psr(uint mii_reg, struct altera_tse_priv *priv) +static int tse_mdio_init(const char *name, struct altera_tse_priv *priv) { - uint speed; - - mii_reg = tse_mdio_read(priv, MIIM_88E1011_PHY_STATUS); - - if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) && - !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { - int i = 0; - - puts("Waiting for PHY realtime link"); - while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { - /* Timeout reached ? */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts(" TIMEOUT !\n"); - priv->link = 0; - break; - } - - if ((i++ == 1000) == 0) { - i = 0; - puts("."); - } - udelay(1000); /* 1 ms */ - mii_reg = tse_mdio_read(priv, MIIM_88E1011_PHY_STATUS); - } - puts(" done\n"); - udelay(500000); /* another 500 ms (results in faster booting) */ - } else { - if (mii_reg & MIIM_88E1011_PHYSTAT_LINK) - priv->link = 1; - else - priv->link = 0; - } - - if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX) - priv->duplexity = 1; - else - priv->duplexity = 0; - - speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED); + struct mii_dev *bus = mdio_alloc(); - switch (speed) { - case MIIM_88E1011_PHYSTAT_GBIT: - priv->speed = 1000; - debug("PHY Speed is 1000Mbit\n"); - break; - case MIIM_88E1011_PHYSTAT_100: - debug("PHY Speed is 100Mbit\n"); - priv->speed = 100; - break; - default: - debug("PHY Speed is 10Mbit\n"); - priv->speed = 10; + if (!bus) { + printf("Failed to allocate MDIO bus\n"); + return -ENOMEM; } - return 0; -} - -static uint mii_m88e1111s_setmode_sr(uint mii_reg, struct altera_tse_priv *priv) -{ - uint mii_data = tse_mdio_read(priv, mii_reg); - mii_data &= 0xfff0; - if ((priv->flags >= 1) && (priv->flags <= 4)) - mii_data |= 0xb; - else if (priv->flags == 5) - mii_data |= 0x4; - - return mii_data; -} + bus->read = tse_mdio_read; + bus->write = tse_mdio_write; + snprintf(bus->name, sizeof(bus->name), name); -static uint mii_m88e1111s_setmode_cr(uint mii_reg, struct altera_tse_priv *priv) -{ - uint mii_data = tse_mdio_read(priv, mii_reg); - mii_data &= ~0x82; - if ((priv->flags >= 1) && (priv->flags <= 4)) - mii_data |= 0x82; + bus->priv = (void *)priv; - return mii_data; + return mdio_register(bus); } -/* - * Returns which value to write to the control register. - * For 10/100, the value is slightly different - */ -static uint mii_cr_init(uint mii_reg, struct altera_tse_priv *priv) -{ - return MIIM_CONTROL_INIT; -} - -/* - * PHY & MDIO code - * Need to add SGMII stuff - * - */ - -static struct phy_info phy_info_M88E1111S = { - 0x01410cc, - "Marvell 88E1111S", - 4, - (struct phy_cmd[]){ /* config */ - /* Reset and configure the PHY */ - {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, - {MIIM_88E1111_PHY_EXT_SR, 0x848f, - &mii_m88e1111s_setmode_sr}, - /* Delay RGMII TX and RX */ - {MIIM_88E1111_PHY_EXT_CR, 0x0cd2, - &mii_m88e1111s_setmode_cr}, - {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, - {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, - {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, - {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, - {miim_end,} - }, - (struct phy_cmd[]){ /* startup */ - /* Status is read once to clear old link state */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, &mii_parse_sr}, - /* Read the status */ - {MIIM_88E1011_PHY_STATUS, miim_read, - &mii_parse_88E1011_psr}, - {miim_end,} - }, - (struct phy_cmd[]){ /* shutdown */ - {miim_end,} - }, -}; - -/* a generic flavor. */ -static struct phy_info phy_info_generic = { - 0, - "Unknown/Generic PHY", - 32, - (struct phy_cmd[]){ /* config */ - {MII_BMCR, BMCR_RESET, NULL}, - {MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART, NULL}, - {miim_end,} - }, - (struct phy_cmd[]){ /* startup */ - {MII_BMSR, miim_read, NULL}, - {MII_BMSR, miim_read, &mii_parse_sr}, - {miim_end,} - }, - (struct phy_cmd[]){ /* shutdown */ - {miim_end,} - } -}; - -static struct phy_info *phy_info[] = { - &phy_info_M88E1111S, - NULL -}; - - /* Grab the identifier of the device's PHY, and search through - * all of the known PHYs to see if one matches. If so, return - * it, if not, return NULL - */ -static struct phy_info *get_phy_info(struct eth_device *dev) +static int tse_phy_init(struct altera_tse_priv *priv, void *dev) { - struct altera_tse_priv *priv = (struct altera_tse_priv *)dev->priv; - uint phy_reg, phy_ID; - int i; - struct phy_info *theInfo = NULL; - - /* Grab the bits from PHYIR1, and put them in the upper half */ - phy_reg = tse_mdio_read(priv, MIIM_PHYIR1); - phy_ID = (phy_reg & 0xffff) << 16; - - /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = tse_mdio_read(priv, MIIM_PHYIR2); - phy_ID |= (phy_reg & 0xffff); - - /* loop through all the known PHY types, and find one that */ - /* matches the ID we read from the PHY. */ - for (i = 0; phy_info[i]; i++) { - if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) { - theInfo = phy_info[i]; - break; - } - } - - if (theInfo == NULL) { - theInfo = &phy_info_generic; - debug("%s: No support for PHY id %x; assuming generic\n", - dev->name, phy_ID); - } else - debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID); + struct phy_device *phydev; + unsigned int mask = 0xffffffff; - return theInfo; -} - -/* Execute the given series of commands on the given device's - * PHY, running functions as necessary - */ -static void phy_run_commands(struct altera_tse_priv *priv, struct phy_cmd *cmd) -{ - int i; - uint result; + if (priv->phyaddr) + mask = 1 << priv->phyaddr; - for (i = 0; cmd->mii_reg != miim_end; i++) { - if (cmd->mii_data == miim_read) { - result = tse_mdio_read(priv, cmd->mii_reg); + phydev = phy_find_by_mask(priv->bus, mask, priv->interface); + if (!phydev) + return -ENODEV; - if (cmd->funct != NULL) - (*(cmd->funct)) (result, priv); + phy_connect_dev(phydev, dev); - } else { - if (cmd->funct != NULL) - result = (*(cmd->funct)) (cmd->mii_reg, priv); - else - result = cmd->mii_data; + phydev->supported &= PHY_GBIT_FEATURES; + phydev->advertising = phydev->supported; - tse_mdio_write(priv, cmd->mii_reg, result); + priv->phydev = phydev; + phy_config(phydev); - } - cmd++; - } + return 0; } -/* Phy init code */ -static int init_phy(struct eth_device *dev) +static int altera_tse_write_hwaddr(struct udevice *dev) { - struct altera_tse_priv *priv = (struct altera_tse_priv *)dev->priv; - struct phy_info *curphy; - - /* Get the cmd structure corresponding to the attached - * PHY */ - curphy = get_phy_info(dev); - - if (curphy == NULL) { - priv->phyinfo = NULL; - debug("%s: No PHY found\n", dev->name); - - return 0; - } else - debug("%s found\n", curphy->name); - priv->phyinfo = curphy; - - phy_run_commands(priv, priv->phyinfo->config); + struct altera_tse_priv *priv = dev_get_priv(dev); + struct alt_tse_mac *mac_dev = priv->mac_dev; + struct eth_pdata *pdata = dev_get_platdata(dev); + u8 *hwaddr = pdata->enetaddr; + unsigned int mac_lo, mac_hi; + + mac_lo = (hwaddr[3] << 24) | (hwaddr[2] << 16) | + (hwaddr[1] << 8) | hwaddr[0]; + mac_hi = (hwaddr[5] << 8) | hwaddr[4]; + debug("Set MAC address to 0x%04x%08x\n", mac_hi, mac_lo); + + writel(mac_lo, &mac_dev->mac_addr_0); + writel(mac_hi, &mac_dev->mac_addr_1); + writel(mac_lo, &mac_dev->supp_mac_addr_0_0); + writel(mac_hi, &mac_dev->supp_mac_addr_0_1); + writel(mac_lo, &mac_dev->supp_mac_addr_1_0); + writel(mac_hi, &mac_dev->supp_mac_addr_1_1); + writel(mac_lo, &mac_dev->supp_mac_addr_2_0); + writel(mac_hi, &mac_dev->supp_mac_addr_2_1); + writel(mac_lo, &mac_dev->supp_mac_addr_3_0); + writel(mac_hi, &mac_dev->supp_mac_addr_3_1); - return 1; -} - -static int tse_set_mac_address(struct eth_device *dev) -{ - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_tse_mac *mac_dev = priv->mac_dev; - - debug("Setting MAC address to 0x%02x%02x%02x%02x%02x%02x\n", - dev->enetaddr[5], dev->enetaddr[4], - dev->enetaddr[3], dev->enetaddr[2], - dev->enetaddr[1], dev->enetaddr[0]); - mac_dev->mac_addr_0 = ((dev->enetaddr[3]) << 24 | - (dev->enetaddr[2]) << 16 | - (dev->enetaddr[1]) << 8 | (dev->enetaddr[0])); - - mac_dev->mac_addr_1 = ((dev->enetaddr[5] << 8 | - (dev->enetaddr[4])) & 0xFFFF); - - /* Set the MAC address */ - mac_dev->supp_mac_addr_0_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_0_1 = mac_dev->mac_addr_1; - - /* Set the MAC address */ - mac_dev->supp_mac_addr_1_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_1_1 = mac_dev->mac_addr_1; - - /* Set the MAC address */ - mac_dev->supp_mac_addr_2_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_2_1 = mac_dev->mac_addr_1; - - /* Set the MAC address */ - mac_dev->supp_mac_addr_3_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_3_1 = mac_dev->mac_addr_1; return 0; } -static int tse_eth_init(struct eth_device *dev, bd_t * bd) +static int altera_tse_start(struct udevice *dev) { - int dat; - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_tse_mac *mac_dev = priv->mac_dev; - volatile struct alt_sgdma_descriptor *tx_desc = priv->tx_desc; - volatile struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; - volatile struct alt_sgdma_descriptor *rx_desc_cur = - (volatile struct alt_sgdma_descriptor *)&rx_desc[0]; - - /* stop controller */ - debug("Reseting TSE & SGDMAs\n"); - tse_eth_reset(dev); - - /* start the phy */ - debug("Configuring PHY\n"); - phy_run_commands(priv, priv->phyinfo->startup); + struct altera_tse_priv *priv = dev_get_priv(dev); + struct alt_tse_mac *mac_dev = priv->mac_dev; + unsigned int val; + int ret; /* need to create sgdma */ - debug("Configuring tx desc\n"); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&tx_desc[0], - (volatile struct alt_sgdma_descriptor *)&tx_desc[1], - (unsigned int *)NULL, /* read addr */ - (unsigned int *)0, - 0, /* length or EOP ,will change for each tx */ - 0x1, /* gen eop */ - 0x0, /* read fixed */ - 0x1, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ - ); debug("Configuring rx desc\n"); - flush_dcache_range((unsigned long)(net_rx_packets[0]), - (unsigned long)(net_rx_packets[0]) + PKTSIZE_ALIGN); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&rx_desc[0], - (volatile struct alt_sgdma_descriptor *)&rx_desc[1], - (unsigned int)0x0, /* read addr */ - (unsigned int *)net_rx_packets[0], - 0x0, /* length or EOP */ - 0x0, /* gen eop */ - 0x0, /* read fixed */ - 0x0, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ - ); - /* start rx async transfer */ - debug("Starting rx sgdma\n"); - alt_sgdma_do_async_transfer(priv->sgdma_rx, rx_desc_cur); - + altera_tse_free_pkt(dev, priv->rx_buf, PKTSIZE_ALIGN); /* start TSE */ debug("Configuring TSE Mac\n"); /* Initialize MAC registers */ - mac_dev->max_frame_length = PKTSIZE_ALIGN; - mac_dev->rx_almost_empty_threshold = 8; - mac_dev->rx_almost_full_threshold = 8; - mac_dev->tx_almost_empty_threshold = 8; - mac_dev->tx_almost_full_threshold = 3; - mac_dev->tx_sel_empty_threshold = - CONFIG_SYS_ALTERA_TSE_TX_FIFO - 16; - mac_dev->tx_sel_full_threshold = 0; - mac_dev->rx_sel_empty_threshold = - CONFIG_SYS_ALTERA_TSE_TX_FIFO - 16; - mac_dev->rx_sel_full_threshold = 0; + writel(PKTSIZE_ALIGN, &mac_dev->max_frame_length); + writel(priv->rx_fifo_depth - 16, &mac_dev->rx_sel_empty_threshold); + writel(0, &mac_dev->rx_sel_full_threshold); + writel(priv->tx_fifo_depth - 16, &mac_dev->tx_sel_empty_threshold); + writel(0, &mac_dev->tx_sel_full_threshold); + writel(8, &mac_dev->rx_almost_empty_threshold); + writel(8, &mac_dev->rx_almost_full_threshold); + writel(8, &mac_dev->tx_almost_empty_threshold); + writel(3, &mac_dev->tx_almost_full_threshold); /* NO Shift */ - mac_dev->rx_cmd_stat.bits.rx_shift16 = 0; - mac_dev->tx_cmd_stat.bits.tx_shift16 = 0; + writel(0, &mac_dev->rx_cmd_stat); + writel(0, &mac_dev->tx_cmd_stat); /* enable MAC */ - dat = 0; - dat = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK; + val = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK; + writel(val, &mac_dev->command_config); + + /* Start up the PHY */ + ret = phy_startup(priv->phydev); + if (ret) { + debug("Could not initialize PHY %s\n", + priv->phydev->dev->name); + return ret; + } - mac_dev->command_config.image = dat; + tse_adjust_link(priv, priv->phydev); - /* configure the TSE core */ - /* -- output clocks, */ - /* -- and later config stuff for SGMII */ - if (priv->link) { - debug("Adjusting TSE to link speed\n"); - tse_adjust_link(priv); - } + if (!priv->phydev->link) + return -EIO; - return priv->link ? 0 : -1; + return 0; } -/* TSE init code */ -int altera_tse_initialize(u8 dev_num, int mac_base, - int sgdma_rx_base, int sgdma_tx_base, - u32 sgdma_desc_base, u32 sgdma_desc_size) +static int altera_tse_probe(struct udevice *dev) { - struct altera_tse_priv *priv; - struct eth_device *dev; - struct alt_sgdma_descriptor *rx_desc; - struct alt_sgdma_descriptor *tx_desc; - unsigned long dma_handle; - - dev = (struct eth_device *)malloc(sizeof *dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + struct altera_tse_priv *priv = dev_get_priv(dev); + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + const char *list, *end; + const fdt32_t *cell; + void *base, *desc_mem = NULL; + unsigned long addr, size; + int len, idx; + int ret; - if (NULL == dev) - return 0; + /* + * decode regs, assume address-cells and size-cells are both one. + * there are multiple reg tuples, and they need to match with + * reg-names. + */ + list = fdt_getprop(blob, node, "reg-names", &len); + if (!list) + return -ENOENT; + end = list + len; + cell = fdt_getprop(blob, node, "reg", &len); + if (!cell) + return -ENOENT; + idx = 0; + while (list < end) { + addr = fdt_translate_address((void *)blob, + node, cell + idx); + size = fdt_addr_to_cpu(cell[idx + 1]); + base = ioremap(addr, size); + len = strlen(list); + if (strcmp(list, "control_port") == 0) + priv->mac_dev = base; + else if (strcmp(list, "rx_csr") == 0) + priv->sgdma_rx = base; + else if (strcmp(list, "tx_csr") == 0) + priv->sgdma_tx = base; + else if (strcmp(list, "s1") == 0) + desc_mem = base; + idx += 2; + list += (len + 1); + } + /* decode fifo depth */ + priv->rx_fifo_depth = fdtdec_get_int(blob, node, + "rx-fifo-depth", 0); + priv->tx_fifo_depth = fdtdec_get_int(blob, node, + "tx-fifo-depth", 0); + /* decode phy */ + addr = fdtdec_get_int(blob, node, + "phy-handle", 0); + addr = fdt_node_offset_by_phandle(blob, addr); + priv->phyaddr = fdtdec_get_int(blob, addr, + "reg", 0); + /* init desc */ + len = sizeof(struct alt_sgdma_descriptor) * 4; + if (!desc_mem) { + desc_mem = dma_alloc_coherent(len, &addr); + if (!desc_mem) + return -ENOMEM; + } + memset(desc_mem, 0, len); + priv->tx_desc = desc_mem; + priv->rx_desc = priv->tx_desc + 2; + /* allocate recv packet buffer */ + priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN); + if (!priv->rx_buf) + return -ENOMEM; - memset(dev, 0, sizeof *dev); + /* stop controller */ + debug("Reset TSE & SGDMAs\n"); + altera_tse_stop(dev); - priv = malloc(sizeof(*priv)); + /* start the phy */ + priv->interface = pdata->phy_interface; + tse_mdio_init(dev->name, priv); + priv->bus = miiphy_get_dev_by_name(dev->name); - if (!priv) { - free(dev); - return 0; - } - if (sgdma_desc_size) { - if (sgdma_desc_size < (sizeof(*tx_desc) * (3 + PKTBUFSRX))) { - printf("ALTERA_TSE-%hu: " - "descriptor memory is too small\n", dev_num); - free(priv); - free(dev); - return 0; - } - tx_desc = (struct alt_sgdma_descriptor *)sgdma_desc_base; - } else { - tx_desc = dma_alloc_coherent(sizeof(*tx_desc) * (3 + PKTBUFSRX), - &dma_handle); - } + ret = tse_phy_init(priv, dev); - rx_desc = tx_desc + 2; - debug("tx desc: address = 0x%x\n", (unsigned int)tx_desc); - debug("rx desc: address = 0x%x\n", (unsigned int)rx_desc); + return ret; +} - if (!tx_desc) { - free(priv); - free(dev); - return 0; +static int altera_tse_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + const char *phy_mode; + + pdata->phy_interface = -1; + phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL); + if (phy_mode) + pdata->phy_interface = phy_get_interface_by_name(phy_mode); + if (pdata->phy_interface == -1) { + debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); + return -EINVAL; } - memset(rx_desc, 0, (sizeof *rx_desc) * (PKTBUFSRX + 1)); - memset(tx_desc, 0, (sizeof *tx_desc) * 2); - - /* initialize tse priv */ - priv->mac_dev = (volatile struct alt_tse_mac *)mac_base; - priv->sgdma_rx = (volatile struct alt_sgdma_registers *)sgdma_rx_base; - priv->sgdma_tx = (volatile struct alt_sgdma_registers *)sgdma_tx_base; - priv->phyaddr = CONFIG_SYS_ALTERA_TSE_PHY_ADDR; - priv->flags = CONFIG_SYS_ALTERA_TSE_FLAGS; - priv->rx_desc = rx_desc; - priv->tx_desc = tx_desc; - - /* init eth structure */ - dev->priv = priv; - dev->init = tse_eth_init; - dev->halt = tse_eth_halt; - dev->send = tse_eth_send; - dev->recv = tse_eth_rx; - dev->write_hwaddr = tse_set_mac_address; - sprintf(dev->name, "%s-%hu", "ALTERA_TSE", dev_num); - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII) - miiphy_register(dev->name, altera_tse_miiphy_read, - altera_tse_miiphy_write); -#endif - - init_phy(dev); - - return 1; + + return 0; } + +static const struct eth_ops altera_tse_ops = { + .start = altera_tse_start, + .send = altera_tse_send, + .recv = altera_tse_recv, + .free_pkt = altera_tse_free_pkt, + .stop = altera_tse_stop, + .write_hwaddr = altera_tse_write_hwaddr, +}; + +static const struct udevice_id altera_tse_ids[] = { + { .compatible = "altr,tse-1.0", }, + { } +}; + +U_BOOT_DRIVER(altera_tse) = { + .name = "altera_tse", + .id = UCLASS_ETH, + .of_match = altera_tse_ids, + .ops = &altera_tse_ops, + .ofdata_to_platdata = altera_tse_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .priv_auto_alloc_size = sizeof(struct altera_tse_priv), + .probe = altera_tse_probe, +}; diff --git a/drivers/net/altera_tse.h b/drivers/net/altera_tse.h index 8880bfc0f8b..08c4f660a0d 100644 --- a/drivers/net/altera_tse.h +++ b/drivers/net/altera_tse.h @@ -13,102 +13,6 @@ #define __packed_1_ __attribute__ ((packed, aligned(1))) -/* PHY Stuff */ -#define miim_end -2 -#define miim_read -1 - -#define PHY_AUTONEGOTIATE_TIMEOUT 5000 /* in ms */ - -#ifndef CONFIG_SYS_TBIPA_VALUE -#define CONFIG_SYS_TBIPA_VALUE 0x1f -#endif -#define MIIMCFG_INIT_VALUE 0x00000003 -#define MIIMCFG_RESET 0x80000000 - -#define MIIMIND_BUSY 0x00000001 -#define MIIMIND_NOTVALID 0x00000004 - -#define MIIM_CONTROL 0x00 -#define MIIM_CONTROL_RESET 0x00009140 -#define MIIM_CONTROL_INIT 0x00001140 -#define MIIM_CONTROL_RESTART 0x00001340 -#define MIIM_ANEN 0x00001000 - -#define MIIM_CR 0x00 -#define MIIM_CR_RST 0x00008000 -#define MIIM_CR_INIT 0x00001000 - -#define MIIM_STATUS 0x1 -#define MIIM_STATUS_AN_DONE 0x00000020 -#define MIIM_STATUS_LINK 0x0004 - -#define MIIM_PHYIR1 0x2 -#define MIIM_PHYIR2 0x3 - -#define MIIM_ANAR 0x4 -#define MIIM_ANAR_INIT 0x1e1 - -#define MIIM_TBI_ANLPBPA 0x5 -#define MIIM_TBI_ANLPBPA_HALF 0x00000040 -#define MIIM_TBI_ANLPBPA_FULL 0x00000020 - -#define MIIM_TBI_ANEX 0x6 -#define MIIM_TBI_ANEX_NP 0x00000004 -#define MIIM_TBI_ANEX_PRX 0x00000002 - -#define MIIM_GBIT_CONTROL 0x9 -#define MIIM_GBIT_CONTROL_INIT 0xe00 - -#define MIIM_EXT_PAGE_ACCESS 0x1f - -/* 88E1011 PHY Status Register */ -#define MIIM_88E1011_PHY_STATUS 0x11 -#define MIIM_88E1011_PHYSTAT_SPEED 0xc000 -#define MIIM_88E1011_PHYSTAT_GBIT 0x8000 -#define MIIM_88E1011_PHYSTAT_100 0x4000 -#define MIIM_88E1011_PHYSTAT_DUPLEX 0x2000 -#define MIIM_88E1011_PHYSTAT_SPDDONE 0x0800 -#define MIIM_88E1011_PHYSTAT_LINK 0x0400 - -#define MIIM_88E1011_PHY_SCR 0x10 -#define MIIM_88E1011_PHY_MDI_X_AUTO 0x0060 - -#define MIIM_88E1111_PHY_EXT_CR 0x14 -#define MIIM_88E1111_PHY_EXT_SR 0x1b - -/* 88E1111 PHY LED Control Register */ -#define MIIM_88E1111_PHY_LED_CONTROL 24 -#define MIIM_88E1111_PHY_LED_DIRECT 0x4100 -#define MIIM_88E1111_PHY_LED_COMBINE 0x411C - -#define MIIM_READ_COMMAND 0x00000001 - -/* struct phy_info: a structure which defines attributes for a PHY - * id will contain a number which represents the PHY. During - * startup, the driver will poll the PHY to find out what its - * UID--as defined by registers 2 and 3--is. The 32-bit result - * gotten from the PHY will be shifted right by "shift" bits to - * discard any bits which may change based on revision numbers - * unimportant to functionality - * - * The struct phy_cmd entries represent pointers to an arrays of - * commands which tell the driver what to do to the PHY. - */ -struct phy_info { - uint id; - char *name; - uint shift; - /* Called to configure the PHY, and modify the controller - * based on the results */ - struct phy_cmd *config; - - /* Called when starting up the controller */ - struct phy_cmd *startup; - - /* Called when bringing down the controller */ - struct phy_cmd *shutdown; -}; - /* SGDMA Stuff */ #define ALT_SGDMA_STATUS_ERROR_MSK (0x00000001) #define ALT_SGDMA_STATUS_EOP_ENCOUNTERED_MSK (0x00000002) @@ -116,18 +20,9 @@ struct phy_info { #define ALT_SGDMA_STATUS_CHAIN_COMPLETED_MSK (0x00000008) #define ALT_SGDMA_STATUS_BUSY_MSK (0x00000010) -#define ALT_SGDMA_CONTROL_IE_ERROR_MSK (0x00000001) -#define ALT_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_MSK (0x00000002) -#define ALT_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK (0x00000004) -#define ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK (0x00000008) -#define ALT_SGDMA_CONTROL_IE_GLOBAL_MSK (0x00000010) #define ALT_SGDMA_CONTROL_RUN_MSK (0x00000020) #define ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK (0x00000040) -#define ALT_SGDMA_CONTROL_IE_MAX_DESC_PROCESSED_MSK (0x00000080) -#define ALT_SGDMA_CONTROL_MAX_DESC_PROCESSED_MSK (0x0000FF00) #define ALT_SGDMA_CONTROL_SOFTWARERESET_MSK (0x00010000) -#define ALT_SGDMA_CONTROL_PARK_MSK (0x00020000) -#define ALT_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK (0x80000000) #define ALTERA_TSE_SGDMA_INTR_MASK (ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK \ | ALT_SGDMA_STATUS_DESC_COMPLETED_MSK \ @@ -176,13 +71,13 @@ struct phy_info { * */ struct alt_sgdma_descriptor { - unsigned int *source; /* the address of data to be read. */ + unsigned int source; /* the address of data to be read. */ unsigned int source_pad; - unsigned int *destination; /* the address to write data */ + unsigned int destination; /* the address to write data */ unsigned int destination_pad; - unsigned int *next; /* the next descriptor in the list. */ + unsigned int next; /* the next descriptor in the list. */ unsigned int next_pad; unsigned short bytes_to_transfer; /* the number of bytes to transfer */ @@ -241,112 +136,15 @@ struct alt_sgdma_registers { #define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16 (0x02000000) -#define ALT_TSE_SW_RESET_WATCHDOG_CNTR 10000 -#define ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR 90000000 - -/* Command_Config Register Bit Definitions */ - -typedef volatile union __alt_tse_command_config { - unsigned int image; - struct { - unsigned int - transmit_enable:1, /* bit 0 */ - receive_enable:1, /* bit 1 */ - pause_frame_xon_gen:1, /* bit 2 */ - ethernet_speed:1, /* bit 3 */ - promiscuous_enable:1, /* bit 4 */ - pad_enable:1, /* bit 5 */ - crc_forward:1, /* bit 6 */ - pause_frame_forward:1, /* bit 7 */ - pause_frame_ignore:1, /* bit 8 */ - set_mac_address_on_tx:1, /* bit 9 */ - halfduplex_enable:1, /* bit 10 */ - excessive_collision:1, /* bit 11 */ - late_collision:1, /* bit 12 */ - software_reset:1, /* bit 13 */ - multicast_hash_mode_sel:1, /* bit 14 */ - loopback_enable:1, /* bit 15 */ - src_mac_addr_sel_on_tx:3, /* bit 18:16 */ - magic_packet_detect:1, /* bit 19 */ - sleep_mode_enable:1, /* bit 20 */ - wake_up_request:1, /* bit 21 */ - pause_frame_xoff_gen:1, /* bit 22 */ - control_frame_enable:1, /* bit 23 */ - payload_len_chk_disable:1, /* bit 24 */ - enable_10mbps_intf:1, /* bit 25 */ - rx_error_discard_enable:1, /* bit 26 */ - reserved_bits:4, /* bit 30:27 */ - self_clear_counter_reset:1; /* bit 31 */ - } __packed_1_ bits; -} __packed_1_ alt_tse_command_config; - -/* Tx_Cmd_Stat Register Bit Definitions */ - -typedef volatile union __alt_tse_tx_cmd_stat { - unsigned int image; - struct { - unsigned int reserved_lsbs:17, /* bit 16:0 */ - omit_crc:1, /* bit 17 */ - tx_shift16:1, /* bit 18 */ - reserved_msbs:13; /* bit 31:19 */ - - } __packed_1_ bits; -} alt_tse_tx_cmd_stat; - -/* Rx_Cmd_Stat Register Bit Definitions */ - -typedef volatile union __alt_tse_rx_cmd_stat { - unsigned int image; - struct { - unsigned int reserved_lsbs:25, /* bit 24:0 */ - rx_shift16:1, /* bit 25 */ - reserved_msbs:6; /* bit 31:26 */ - - } __packed_1_ bits; -} alt_tse_rx_cmd_stat; - -struct alt_tse_mdio { - unsigned int control; /*PHY device operation control register */ - unsigned int status; /*PHY device operation status register */ - unsigned int phy_id1; /*Bits 31:16 of PHY identifier. */ - unsigned int phy_id2; /*Bits 15:0 of PHY identifier. */ - unsigned int auto_negotiation_advertisement; - unsigned int remote_partner_base_page_ability; - - unsigned int reg6; - unsigned int reg7; - unsigned int reg8; - unsigned int reg9; - unsigned int rega; - unsigned int regb; - unsigned int regc; - unsigned int regd; - unsigned int rege; - unsigned int regf; - unsigned int reg10; - unsigned int reg11; - unsigned int reg12; - unsigned int reg13; - unsigned int reg14; - unsigned int reg15; - unsigned int reg16; - unsigned int reg17; - unsigned int reg18; - unsigned int reg19; - unsigned int reg1a; - unsigned int reg1b; - unsigned int reg1c; - unsigned int reg1d; - unsigned int reg1e; - unsigned int reg1f; -}; +#define ALT_TSE_SW_RESET_TIMEOUT (3 * CONFIG_SYS_HZ) +#define ALT_TSE_SGDMA_BUSY_TIMEOUT (3 * CONFIG_SYS_HZ) /* MAC register Space */ struct alt_tse_mac { unsigned int megacore_revision; unsigned int scratch_pad; - alt_tse_command_config command_config; + unsigned int command_config; unsigned int mac_addr_0; unsigned int mac_addr_1; unsigned int max_frame_length; @@ -413,8 +211,8 @@ struct alt_tse_mac { unsigned int reservedxE4; /*FIFO control register. */ - alt_tse_tx_cmd_stat tx_cmd_stat; - alt_tse_rx_cmd_stat rx_cmd_stat; + unsigned int tx_cmd_stat; + unsigned int rx_cmd_stat; unsigned int ipaccTxConf; unsigned int ipaccRxConf; @@ -425,8 +223,8 @@ struct alt_tse_mac { unsigned int hash_table[64]; /*Registers 0 to 31 within PHY device 0/1 */ - struct alt_tse_mdio mdio_phy0; - struct alt_tse_mdio mdio_phy1; + unsigned int mdio_phy0[0x20]; + unsigned int mdio_phy1[0x20]; /*4 Supplemental MAC Addresses */ unsigned int supp_mac_addr_0_0; @@ -441,52 +239,19 @@ struct alt_tse_mac { unsigned int reservedx320[56]; }; -/* flags: TSE MII modes */ -/* GMII/MII = 0 */ -/* RGMII = 1 */ -/* RGMII_ID = 2 */ -/* RGMII_TXID = 3 */ -/* RGMII_RXID = 4 */ -/* SGMII = 5 */ struct altera_tse_priv { - char devname[16]; - volatile struct alt_tse_mac *mac_dev; - volatile struct alt_sgdma_registers *sgdma_rx; - volatile struct alt_sgdma_registers *sgdma_tx; - unsigned int rx_sgdma_irq; - unsigned int tx_sgdma_irq; - unsigned int has_descriptor_mem; - unsigned int descriptor_mem_base; - unsigned int descriptor_mem_size; - volatile struct alt_sgdma_descriptor *rx_desc; - volatile struct alt_sgdma_descriptor *tx_desc; - volatile unsigned char *rx_buf; - struct phy_info *phyinfo; + struct alt_tse_mac *mac_dev; + struct alt_sgdma_registers *sgdma_rx; + struct alt_sgdma_registers *sgdma_tx; + unsigned int rx_fifo_depth; + unsigned int tx_fifo_depth; + struct alt_sgdma_descriptor *rx_desc; + struct alt_sgdma_descriptor *tx_desc; + unsigned char *rx_buf; unsigned int phyaddr; - unsigned int flags; - unsigned int link; - unsigned int duplexity; - unsigned int speed; + unsigned int interface; + struct phy_device *phydev; + struct mii_dev *bus; }; -/* Phy stuff continued */ -/* - * struct phy_cmd: A command for reading or writing a PHY register - * - * mii_reg: The register to read or write - * - * mii_data: For writes, the value to put in the register. - * A value of -1 indicates this is a read. - * - * funct: A function pointer which is invoked for each command. - * For reads, this function will be passed the value read - * from the PHY, and process it. - * For writes, the result of this function will be written - * to the PHY register - */ -struct phy_cmd { - uint mii_reg; - uint mii_data; - uint(*funct) (uint mii_reg, struct altera_tse_priv *priv); -}; #endif /* _ALTERA_TSE_H_ */ diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ac5920ad5a9..53b4e1b9d50 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -54,6 +54,20 @@ choice prompt "Select which UART will provide the debug UART" depends on DEBUG_UART +config DEBUG_UART_ALTERA_JTAGUART + bool "Altera JTAG UART" + help + Select this to enable a debug UART using the altera_jtag_uart driver. + You will need to provide parameters to make this work. The driver will + be available until the real driver model serial is running. + +config DEBUG_UART_ALTERA_UART + bool "Altera UART" + help + Select this to enable a debug UART using the altera_uart driver. + You will need to provide parameters to make this work. The driver will + be available until the real driver model serial is running. + config DEBUG_UART_NS16550 bool "ns16550" help @@ -130,6 +144,32 @@ config DEBUG_UART_ANNOUNCE debug_uart_init()). This can be useful just as a check that everything is working. +config ALTERA_JTAG_UART + bool "Altera JTAG UART support" + depends on DM_SERIAL + help + Select this to enable an JTAG UART for Altera devices.The JTAG UART + core implements a method to communicate serial character streams + between a host PC and a Qsys system on an Altera FPGA. Please find + details on the "Embedded Peripherals IP User Guide" of Altera. + +config ALTERA_JTAG_UART_BYPASS + bool "Bypass output when no connection" + depends on ALTERA_JTAG_UART + help + Bypass console output and keep going even if there is no JTAG + terminal connection with the host. The console output will resume + once the JTAG terminal is connected. Without the bypass, the console + output will wait forever until a JTAG terminal is connected. If you + not are sure, say Y. + +config ALTERA_UART + bool "Altera UART support" + depends on DM_SERIAL + help + Select this to enable an UART for Altera devices. Please find + details on the "Embedded Peripherals IP User Guide" of Altera. + config ROCKCHIP_SERIAL bool "Rockchip on-chip UART support" depends on ARCH_ROCKCHIP && DM_SERIAL diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 869ea7b8fb4..1818c7c3a67 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_EFI_APP) += serial_efi.o obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o obj-$(CONFIG_MCFUART) += mcfuart.o obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o +obj-$(CONFIG_KEYSTONE_SERIAL) += serial_keystone.o obj-$(CONFIG_SYS_NS16550) += ns16550.o obj-$(CONFIG_S5P) += serial_s5p.o obj-$(CONFIG_IMX_SERIAL) += serial_imx.o diff --git a/drivers/serial/altera_jtag_uart.c b/drivers/serial/altera_jtag_uart.c index 9a81402ffb2..39d4a4e933c 100644 --- a/drivers/serial/altera_jtag_uart.c +++ b/drivers/serial/altera_jtag_uart.c @@ -6,98 +6,149 @@ */ #include <common.h> -#include <watchdog.h> +#include <dm.h> +#include <errno.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h> -typedef volatile struct { - unsigned data; /* Data register */ - unsigned control; /* Control register */ -} nios_jtag_t; +struct altera_jtaguart_regs { + u32 data; /* Data register */ + u32 control; /* Control register */ +}; + +struct altera_jtaguart_platdata { + struct altera_jtaguart_regs *regs; +}; /* data register */ -#define NIOS_JTAG_RVALID (1<<15) /* Read valid */ -#define NIOS_JTAG_DATA(d) ((d)&0x0ff) /* Read data */ -#define NIOS_JTAG_RAVAIL(d) ((d)>>16) /* Read space avail */ +#define ALTERA_JTAG_RVALID (1<<15) /* Read valid */ /* control register */ -#define NIOS_JTAG_RE (1 << 0) /* read intr enable */ -#define NIOS_JTAG_WE (1 << 1) /* write intr enable */ -#define NIOS_JTAG_RI (1 << 8) /* read intr pending */ -#define NIOS_JTAG_WI (1 << 9) /* write intr pending*/ -#define NIOS_JTAG_AC (1 << 10) /* activity indicator */ -#define NIOS_JTAG_RRDY (1 << 12) /* read available */ -#define NIOS_JTAG_WSPACE(d) ((d)>>16) /* Write space avail */ +#define ALTERA_JTAG_AC (1 << 10) /* activity indicator */ +#define ALTERA_JTAG_RRDY (1 << 12) /* read available */ +#define ALTERA_JTAG_WSPACE(d) ((d)>>16) /* Write space avail */ +/* Write fifo size. FIXME: this should be extracted with sopc2dts */ +#define ALTERA_JTAG_WRITE_DEPTH 64 DECLARE_GLOBAL_DATA_PTR; -/*------------------------------------------------------------------ - * JTAG acts as the serial port - *-----------------------------------------------------------------*/ -static nios_jtag_t *jtag = (nios_jtag_t *)CONFIG_SYS_NIOS_CONSOLE; - -static void altera_jtag_serial_setbrg(void) +static int altera_jtaguart_setbrg(struct udevice *dev, int baudrate) { + return 0; } -static int altera_jtag_serial_init(void) +static int altera_jtaguart_putc(struct udevice *dev, const char ch) { + struct altera_jtaguart_platdata *plat = dev->platdata; + struct altera_jtaguart_regs *const regs = plat->regs; + u32 st = readl(®s->control); + +#ifdef CONFIG_ALTERA_JTAG_UART_BYPASS + if (!(st & ALTERA_JTAG_AC)) /* no connection yet */ + return -ENETUNREACH; +#endif + + if (ALTERA_JTAG_WSPACE(st) == 0) + return -EAGAIN; + + writel(ch, ®s->data); + return 0; } -static void altera_jtag_serial_putc(char c) +static int altera_jtaguart_pending(struct udevice *dev, bool input) { - while (1) { - unsigned st = readl(&jtag->control); - if (NIOS_JTAG_WSPACE(st)) - break; -#ifdef CONFIG_ALTERA_JTAG_UART_BYPASS - if (!(st & NIOS_JTAG_AC)) /* no connection */ - return; -#endif - WATCHDOG_RESET(); - } - writel ((unsigned char)c, &jtag->data); + struct altera_jtaguart_platdata *plat = dev->platdata; + struct altera_jtaguart_regs *const regs = plat->regs; + u32 st = readl(®s->control); + + if (input) + return st & ALTERA_JTAG_RRDY ? 1 : 0; + else + return !(ALTERA_JTAG_WSPACE(st) == ALTERA_JTAG_WRITE_DEPTH); } -static int altera_jtag_serial_tstc(void) +static int altera_jtaguart_getc(struct udevice *dev) { - return ( readl (&jtag->control) & NIOS_JTAG_RRDY); + struct altera_jtaguart_platdata *plat = dev->platdata; + struct altera_jtaguart_regs *const regs = plat->regs; + u32 val; + + val = readl(®s->data); + + if (!(val & ALTERA_JTAG_RVALID)) + return -EAGAIN; + + return val & 0xff; } -static int altera_jtag_serial_getc(void) +static int altera_jtaguart_probe(struct udevice *dev) { - int c; - unsigned val; +#ifdef CONFIG_ALTERA_JTAG_UART_BYPASS + struct altera_jtaguart_platdata *plat = dev->platdata; + struct altera_jtaguart_regs *const regs = plat->regs; - while (1) { - WATCHDOG_RESET (); - val = readl (&jtag->data); - if (val & NIOS_JTAG_RVALID) - break; - } - c = val & 0x0ff; - return (c); + writel(ALTERA_JTAG_AC, ®s->control); /* clear AC flag */ +#endif + return 0; +} + +static int altera_jtaguart_ofdata_to_platdata(struct udevice *dev) +{ + struct altera_jtaguart_platdata *plat = dev_get_platdata(dev); + + plat->regs = ioremap(dev_get_addr(dev), + sizeof(struct altera_jtaguart_regs)); + + return 0; } -static struct serial_device altera_jtag_serial_drv = { - .name = "altera_jtag_uart", - .start = altera_jtag_serial_init, - .stop = NULL, - .setbrg = altera_jtag_serial_setbrg, - .putc = altera_jtag_serial_putc, - .puts = default_serial_puts, - .getc = altera_jtag_serial_getc, - .tstc = altera_jtag_serial_tstc, +static const struct dm_serial_ops altera_jtaguart_ops = { + .putc = altera_jtaguart_putc, + .pending = altera_jtaguart_pending, + .getc = altera_jtaguart_getc, + .setbrg = altera_jtaguart_setbrg, +}; + +static const struct udevice_id altera_jtaguart_ids[] = { + { .compatible = "altr,juart-1.0", }, + { } +}; + +U_BOOT_DRIVER(altera_jtaguart) = { + .name = "altera_jtaguart", + .id = UCLASS_SERIAL, + .of_match = altera_jtaguart_ids, + .ofdata_to_platdata = altera_jtaguart_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct altera_jtaguart_platdata), + .probe = altera_jtaguart_probe, + .ops = &altera_jtaguart_ops, + .flags = DM_FLAG_PRE_RELOC, }; -void altera_jtag_serial_initialize(void) +#ifdef CONFIG_DEBUG_UART_ALTERA_JTAGUART + +#include <debug_uart.h> + +void debug_uart_init(void) { - serial_register(&altera_jtag_serial_drv); } -__weak struct serial_device *default_serial_console(void) +static inline void _debug_uart_putc(int ch) { - return &altera_jtag_serial_drv; + struct altera_jtaguart_regs *regs = (void *)CONFIG_DEBUG_UART_BASE; + + while (1) { + u32 st = readl(®s->control); + + if (ALTERA_JTAG_WSPACE(st)) + break; + } + + writel(ch, ®s->data); } + +DEBUG_UART_FUNCS + +#endif diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c index d6b14844d67..4ff9fe27a8b 100644 --- a/drivers/serial/altera_uart.c +++ b/drivers/serial/altera_uart.c @@ -5,133 +5,149 @@ * SPDX-License-Identifier: GPL-2.0+ */ - #include <common.h> -#include <watchdog.h> +#include <dm.h> +#include <errno.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h> -typedef volatile struct { - unsigned rxdata; /* Rx data reg */ - unsigned txdata; /* Tx data reg */ - unsigned status; /* Status reg */ - unsigned control; /* Control reg */ - unsigned divisor; /* Baud rate divisor reg */ - unsigned endofpacket; /* End-of-packet reg */ -} nios_uart_t; +struct altera_uart_regs { + u32 rxdata; /* Rx data reg */ + u32 txdata; /* Tx data reg */ + u32 status; /* Status reg */ + u32 control; /* Control reg */ + u32 divisor; /* Baud rate divisor reg */ + u32 endofpacket; /* End-of-packet reg */ +}; + +struct altera_uart_platdata { + struct altera_uart_regs *regs; + unsigned int uartclk; +}; /* status register */ -#define NIOS_UART_PE (1 << 0) /* parity error */ -#define NIOS_UART_FE (1 << 1) /* frame error */ -#define NIOS_UART_BRK (1 << 2) /* break detect */ -#define NIOS_UART_ROE (1 << 3) /* rx overrun */ -#define NIOS_UART_TOE (1 << 4) /* tx overrun */ -#define NIOS_UART_TMT (1 << 5) /* tx empty */ -#define NIOS_UART_TRDY (1 << 6) /* tx ready */ -#define NIOS_UART_RRDY (1 << 7) /* rx ready */ -#define NIOS_UART_E (1 << 8) /* exception */ -#define NIOS_UART_DCTS (1 << 10) /* cts change */ -#define NIOS_UART_CTS (1 << 11) /* cts */ -#define NIOS_UART_EOP (1 << 12) /* eop detected */ - -/* control register */ -#define NIOS_UART_IPE (1 << 0) /* parity error int ena*/ -#define NIOS_UART_IFE (1 << 1) /* frame error int ena */ -#define NIOS_UART_IBRK (1 << 2) /* break detect int ena */ -#define NIOS_UART_IROE (1 << 3) /* rx overrun int ena */ -#define NIOS_UART_ITOE (1 << 4) /* tx overrun int ena */ -#define NIOS_UART_ITMT (1 << 5) /* tx empty int ena */ -#define NIOS_UART_ITRDY (1 << 6) /* tx ready int ena */ -#define NIOS_UART_IRRDY (1 << 7) /* rx ready int ena */ -#define NIOS_UART_IE (1 << 8) /* exception int ena */ -#define NIOS_UART_TBRK (1 << 9) /* transmit break */ -#define NIOS_UART_IDCTS (1 << 10) /* cts change int ena */ -#define NIOS_UART_RTS (1 << 11) /* rts */ -#define NIOS_UART_IEOP (1 << 12) /* eop detected int ena */ +#define ALTERA_UART_TMT (1 << 5) /* tx empty */ +#define ALTERA_UART_TRDY (1 << 6) /* tx ready */ +#define ALTERA_UART_RRDY (1 << 7) /* rx ready */ DECLARE_GLOBAL_DATA_PTR; -/*------------------------------------------------------------------ - * UART the serial port - *-----------------------------------------------------------------*/ - -static nios_uart_t *uart = (nios_uart_t *) CONFIG_SYS_NIOS_CONSOLE; +static int altera_uart_setbrg(struct udevice *dev, int baudrate) +{ + struct altera_uart_platdata *plat = dev->platdata; + struct altera_uart_regs *const regs = plat->regs; + u32 div; -#if defined(CONFIG_SYS_NIOS_FIXEDBAUD) + div = (plat->uartclk / baudrate) - 1; + writel(div, ®s->divisor); -/* - * Everything's already setup for fixed-baud PTF - * assignment - */ -static void altera_serial_setbrg(void) -{ + return 0; } -static int altera_serial_init(void) +static int altera_uart_putc(struct udevice *dev, const char ch) { - return 0; -} + struct altera_uart_platdata *plat = dev->platdata; + struct altera_uart_regs *const regs = plat->regs; -#else + if (!(readl(®s->status) & ALTERA_UART_TRDY)) + return -EAGAIN; -static void altera_serial_setbrg(void) -{ - unsigned div; + writel(ch, ®s->txdata); - div = (CONFIG_SYS_CLK_FREQ/gd->baudrate)-1; - writel (div, &uart->divisor); + return 0; } -static int altera_serial_init(void) +static int altera_uart_pending(struct udevice *dev, bool input) { - serial_setbrg(); - return 0; + struct altera_uart_platdata *plat = dev->platdata; + struct altera_uart_regs *const regs = plat->regs; + u32 st = readl(®s->status); + + if (input) + return st & ALTERA_UART_RRDY ? 1 : 0; + else + return !(st & ALTERA_UART_TMT); } -#endif /* CONFIG_SYS_NIOS_FIXEDBAUD */ - -/*----------------------------------------------------------------------- - * UART CONSOLE - *---------------------------------------------------------------------*/ -static void altera_serial_putc(char c) +static int altera_uart_getc(struct udevice *dev) { - if (c == '\n') - serial_putc ('\r'); - while ((readl (&uart->status) & NIOS_UART_TRDY) == 0) - WATCHDOG_RESET (); - writel ((unsigned char)c, &uart->txdata); + struct altera_uart_platdata *plat = dev->platdata; + struct altera_uart_regs *const regs = plat->regs; + + if (!(readl(®s->status) & ALTERA_UART_RRDY)) + return -EAGAIN; + + return readl(®s->rxdata) & 0xff; } -static int altera_serial_tstc(void) +static int altera_uart_probe(struct udevice *dev) { - return (readl (&uart->status) & NIOS_UART_RRDY); + return 0; } -static int altera_serial_getc(void) +static int altera_uart_ofdata_to_platdata(struct udevice *dev) { - while (serial_tstc () == 0) - WATCHDOG_RESET (); - return (readl (&uart->rxdata) & 0x00ff ); + struct altera_uart_platdata *plat = dev_get_platdata(dev); + + plat->regs = ioremap(dev_get_addr(dev), + sizeof(struct altera_uart_regs)); + plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "clock-frequency", 0); + + return 0; } -static struct serial_device altera_serial_drv = { - .name = "altera_serial", - .start = altera_serial_init, - .stop = NULL, - .setbrg = altera_serial_setbrg, - .putc = altera_serial_putc, - .puts = default_serial_puts, - .getc = altera_serial_getc, - .tstc = altera_serial_tstc, +static const struct dm_serial_ops altera_uart_ops = { + .putc = altera_uart_putc, + .pending = altera_uart_pending, + .getc = altera_uart_getc, + .setbrg = altera_uart_setbrg, +}; + +static const struct udevice_id altera_uart_ids[] = { + { .compatible = "altr,uart-1.0", }, + { } +}; + +U_BOOT_DRIVER(altera_uart) = { + .name = "altera_uart", + .id = UCLASS_SERIAL, + .of_match = altera_uart_ids, + .ofdata_to_platdata = altera_uart_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct altera_uart_platdata), + .probe = altera_uart_probe, + .ops = &altera_uart_ops, + .flags = DM_FLAG_PRE_RELOC, }; -void altera_serial_initialize(void) +#ifdef CONFIG_DEBUG_UART_ALTERA_UART + +#include <debug_uart.h> + +void debug_uart_init(void) { - serial_register(&altera_serial_drv); + struct altera_uart_regs *regs = (void *)CONFIG_DEBUG_UART_BASE; + u32 div; + + div = (CONFIG_DEBUG_UART_CLOCK / CONFIG_BAUDRATE) - 1; + writel(div, ®s->divisor); } -__weak struct serial_device *default_serial_console(void) +static inline void _debug_uart_putc(int ch) { - return &altera_serial_drv; + struct altera_uart_regs *regs = (void *)CONFIG_DEBUG_UART_BASE; + + while (1) { + u32 st = readl(®s->status); + + if (st & ALTERA_UART_TRDY) + break; + } + + writel(ch, ®s->txdata); } + +DEBUG_UART_FUNCS + +#endif diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 699c410d663..422d3aedc31 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -109,8 +109,6 @@ U_BOOT_ENV_CALLBACK(baudrate, on_baudrate); void name(void) \ __attribute__((weak, alias("serial_null"))); -serial_initfunc(altera_jtag_serial_initialize); -serial_initfunc(altera_serial_initialize); serial_initfunc(amirix_serial_initialize); serial_initfunc(arc_serial_initialize); serial_initfunc(arm_dcc_initialize); @@ -202,8 +200,6 @@ void serial_register(struct serial_device *dev) */ void serial_initialize(void) { - altera_jtag_serial_initialize(); - altera_serial_initialize(); amirix_serial_initialize(); arc_serial_initialize(); arm_dcc_initialize(); diff --git a/drivers/serial/serial_keystone.c b/drivers/serial/serial_keystone.c new file mode 100644 index 00000000000..7b5ab6c5cad --- /dev/null +++ b/drivers/serial/serial_keystone.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <ns16550.h> +#include <serial.h> +#include <asm/arch/clock.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(OF_CONTROL) +static const struct udevice_id keystone_serial_ids[] = { + { .compatible = "ti,keystone-uart" }, + { .compatible = "ns16550a" }, + { } +}; + +static int keystone_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct ns16550_platdata *plat = dev_get_platdata(dev); + int ret; + + ret = ns16550_serial_ofdata_to_platdata(dev); + if (ret) + return ret; + plat->clock = CONFIG_SYS_NS16550_CLK; + return 0; +} +#endif + +U_BOOT_DRIVER(serial_keystone_ns16550) = { + .name = "serial_keystone", + .id = UCLASS_SERIAL, +#if CONFIG_IS_ENABLED(OF_CONTROL) + .of_match = of_match_ptr(keystone_serial_ids), + .ofdata_to_platdata = of_match_ptr(keystone_serial_ofdata_to_platdata), + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), +#endif + .priv_auto_alloc_size = sizeof(struct NS16550), + .probe = ns16550_serial_probe, + .ops = &ns16550_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8e04fce6f2a..2f8cf19613a 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -15,6 +15,14 @@ config DM_SPI if DM_SPI +config ALTERA_SPI + bool "Altera SPI driver" + help + Enable the Altera SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this Altera + IP core. Please find details on the "Embedded Peripherals IP + User Guide" of Altera. + config CADENCE_QSPI bool "Cadence QSPI driver" help diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c index a4d03d97cfc..ff3512a0f6f 100644 --- a/drivers/spi/altera_spi.c +++ b/drivers/spi/altera_spi.c @@ -8,18 +8,19 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <asm/io.h> +#include <dm.h> +#include <errno.h> #include <malloc.h> #include <spi.h> +#include <fdtdec.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_ALTERA_SPI_IDLE_VAL #define CONFIG_ALTERA_SPI_IDLE_VAL 0xff #endif -#ifndef CONFIG_SYS_ALTERA_SPI_LIST -#define CONFIG_SYS_ALTERA_SPI_LIST { CONFIG_SYS_SPI_BASE } -#endif - struct altera_spi_regs { u32 rxdata; u32 txdata; @@ -29,102 +30,68 @@ struct altera_spi_regs { u32 slave_sel; }; -#define ALTERA_SPI_STATUS_ROE_MSK (1 << 3) -#define ALTERA_SPI_STATUS_TOE_MSK (1 << 4) -#define ALTERA_SPI_STATUS_TMT_MSK (1 << 5) -#define ALTERA_SPI_STATUS_TRDY_MSK (1 << 6) -#define ALTERA_SPI_STATUS_RRDY_MSK (1 << 7) -#define ALTERA_SPI_STATUS_E_MSK (1 << 8) - -#define ALTERA_SPI_CONTROL_IROE_MSK (1 << 3) -#define ALTERA_SPI_CONTROL_ITOE_MSK (1 << 4) -#define ALTERA_SPI_CONTROL_ITRDY_MSK (1 << 6) -#define ALTERA_SPI_CONTROL_IRRDY_MSK (1 << 7) -#define ALTERA_SPI_CONTROL_IE_MSK (1 << 8) -#define ALTERA_SPI_CONTROL_SSO_MSK (1 << 10) - -static ulong altera_spi_base_list[] = CONFIG_SYS_ALTERA_SPI_LIST; +struct altera_spi_platdata { + struct altera_spi_regs *regs; +}; -struct altera_spi_slave { - struct spi_slave slave; - struct altera_spi_regs *regs; +struct altera_spi_priv { + struct altera_spi_regs *regs; }; -#define to_altera_spi_slave(s) container_of(s, struct altera_spi_slave, slave) -__weak int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - return bus < ARRAY_SIZE(altera_spi_base_list) && cs < 32; -} +#define ALTERA_SPI_STATUS_RRDY_MSK (1 << 7) +#define ALTERA_SPI_CONTROL_SSO_MSK (1 << 10) -__weak void spi_cs_activate(struct spi_slave *slave) +static void spi_cs_activate(struct udevice *dev, uint cs) { - struct altera_spi_slave *altspi = to_altera_spi_slave(slave); - writel(1 << slave->cs, &altspi->regs->slave_sel); - writel(ALTERA_SPI_CONTROL_SSO_MSK, &altspi->regs->control); -} + struct udevice *bus = dev->parent; + struct altera_spi_priv *priv = dev_get_priv(bus); + struct altera_spi_regs *const regs = priv->regs; -__weak void spi_cs_deactivate(struct spi_slave *slave) -{ - struct altera_spi_slave *altspi = to_altera_spi_slave(slave); - writel(0, &altspi->regs->control); - writel(0, &altspi->regs->slave_sel); + writel(1 << cs, ®s->slave_sel); + writel(ALTERA_SPI_CONTROL_SSO_MSK, ®s->control); } -void spi_init(void) +static void spi_cs_deactivate(struct udevice *dev) { -} + struct udevice *bus = dev->parent; + struct altera_spi_priv *priv = dev_get_priv(bus); + struct altera_spi_regs *const regs = priv->regs; -void spi_set_speed(struct spi_slave *slave, uint hz) -{ - /* altera spi core does not support programmable speed */ + writel(0, ®s->control); + writel(0, ®s->slave_sel); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) +static int altera_spi_claim_bus(struct udevice *dev) { - struct altera_spi_slave *altspi; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - altspi = spi_alloc_slave(struct altera_spi_slave, bus, cs); - if (!altspi) - return NULL; + struct udevice *bus = dev->parent; + struct altera_spi_priv *priv = dev_get_priv(bus); + struct altera_spi_regs *const regs = priv->regs; - altspi->regs = (struct altera_spi_regs *)altera_spi_base_list[bus]; - debug("%s: bus:%i cs:%i base:%p\n", __func__, bus, cs, altspi->regs); + writel(0, ®s->control); + writel(0, ®s->slave_sel); - return &altspi->slave; + return 0; } -void spi_free_slave(struct spi_slave *slave) +static int altera_spi_release_bus(struct udevice *dev) { - struct altera_spi_slave *altspi = to_altera_spi_slave(slave); - free(altspi); -} + struct udevice *bus = dev->parent; + struct altera_spi_priv *priv = dev_get_priv(bus); + struct altera_spi_regs *const regs = priv->regs; -int spi_claim_bus(struct spi_slave *slave) -{ - struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + writel(0, ®s->slave_sel); - debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); - writel(0, &altspi->regs->control); - writel(0, &altspi->regs->slave_sel); return 0; } -void spi_release_bus(struct spi_slave *slave) +static int altera_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) { - struct altera_spi_slave *altspi = to_altera_spi_slave(slave); + struct udevice *bus = dev->parent; + struct altera_spi_priv *priv = dev_get_priv(bus); + struct altera_spi_regs *const regs = priv->regs; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); - debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); - writel(0, &altspi->regs->slave_sel); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) -{ - struct altera_spi_slave *altspi = to_altera_spi_slave(slave); /* assume spi core configured to do 8 bit transfers */ unsigned int bytes = bitlen / 8; const unsigned char *txp = dout; @@ -132,7 +99,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, uint32_t reg, data, start; debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__, - slave->bus, slave->cs, bitlen, bytes, flags); + bus->seq, slave_plat->cs, bitlen, bytes, flags); if (bitlen == 0) goto done; @@ -143,11 +110,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, } /* empty read buffer */ - if (readl(&altspi->regs->status) & ALTERA_SPI_STATUS_RRDY_MSK) - readl(&altspi->regs->rxdata); + if (readl(®s->status) & ALTERA_SPI_STATUS_RRDY_MSK) + readl(®s->rxdata); if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); + spi_cs_activate(dev, slave_plat->cs); while (bytes--) { if (txp) @@ -156,20 +123,20 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, data = CONFIG_ALTERA_SPI_IDLE_VAL; debug("%s: tx:%x ", __func__, data); - writel(data, &altspi->regs->txdata); + writel(data, ®s->txdata); start = get_timer(0); while (1) { - reg = readl(&altspi->regs->status); + reg = readl(®s->status); if (reg & ALTERA_SPI_STATUS_RRDY_MSK) break; if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { - printf("%s: Transmission timed out!\n", __func__); - goto done; + debug("%s: Transmission timed out!\n", __func__); + return -1; } } - data = readl(&altspi->regs->rxdata); + data = readl(®s->rxdata); if (rxp) *rxp++ = data & 0xff; @@ -178,7 +145,65 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, done: if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); + spi_cs_deactivate(dev); return 0; } + +static int altera_spi_set_speed(struct udevice *bus, uint speed) +{ + return 0; +} + +static int altera_spi_set_mode(struct udevice *bus, uint mode) +{ + return 0; +} + +static int altera_spi_probe(struct udevice *bus) +{ + struct altera_spi_platdata *plat = dev_get_platdata(bus); + struct altera_spi_priv *priv = dev_get_priv(bus); + + priv->regs = plat->regs; + + return 0; +} + +static int altera_spi_ofdata_to_platdata(struct udevice *bus) +{ + struct altera_spi_platdata *plat = dev_get_platdata(bus); + + plat->regs = ioremap(dev_get_addr(bus), + sizeof(struct altera_spi_regs)); + + return 0; +} + +static const struct dm_spi_ops altera_spi_ops = { + .claim_bus = altera_spi_claim_bus, + .release_bus = altera_spi_release_bus, + .xfer = altera_spi_xfer, + .set_speed = altera_spi_set_speed, + .set_mode = altera_spi_set_mode, + /* + * cs_info is not needed, since we require all chip selects to be + * in the device tree explicitly + */ +}; + +static const struct udevice_id altera_spi_ids[] = { + { .compatible = "altr,spi-1.0", }, + { } +}; + +U_BOOT_DRIVER(altera_spi) = { + .name = "altera_spi", + .id = UCLASS_SPI, + .of_match = altera_spi_ids, + .ops = &altera_spi_ops, + .ofdata_to_platdata = altera_spi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct altera_spi_platdata), + .priv_auto_alloc_size = sizeof(struct altera_spi_priv), + .probe = altera_spi_probe, +}; diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig new file mode 100644 index 00000000000..97c41280052 --- /dev/null +++ b/drivers/timer/Kconfig @@ -0,0 +1,19 @@ +menu "Timer Support" + +config TIMER + bool "Enable Driver Model for Timer drivers" + depends on DM + help + Enable driver model for Timer access. It uses the same API as + lib/time.c. But now implemented by the uclass. The first timer + will be used. The timer is usually a 32 bits free-running up + counter. There may be no real tick, and no timer interrupt. + +config ALTERA_TIMER + bool "Altera Timer support" + depends on TIMER + help + Select this to enable an timer for Altera devices. Please find + details on the "Embedded Peripherals IP User Guide" of Altera. + +endmenu diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile new file mode 100644 index 00000000000..ae66c07d0e4 --- /dev/null +++ b/drivers/timer/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_TIMER) += timer-uclass.o +obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o diff --git a/drivers/timer/altera_timer.c b/drivers/timer/altera_timer.c new file mode 100644 index 00000000000..2ef9ad6934e --- /dev/null +++ b/drivers/timer/altera_timer.c @@ -0,0 +1,104 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct altera_timer_regs { + u32 status; /* Timer status reg */ + u32 control; /* Timer control reg */ + u32 periodl; /* Timeout period low */ + u32 periodh; /* Timeout period high */ + u32 snapl; /* Snapshot low */ + u32 snaph; /* Snapshot high */ +}; + +struct altera_timer_platdata { + struct altera_timer_regs *regs; + unsigned long clock_rate; +}; + +/* control register */ +#define ALTERA_TIMER_CONT (1 << 1) /* Continuous mode */ +#define ALTERA_TIMER_START (1 << 2) /* Start timer */ +#define ALTERA_TIMER_STOP (1 << 3) /* Stop timer */ + +static int altera_timer_get_count(struct udevice *dev, unsigned long *count) +{ + struct altera_timer_platdata *plat = dev->platdata; + struct altera_timer_regs *const regs = plat->regs; + u32 val; + + /* Trigger update */ + writel(0x0, ®s->snapl); + + /* Read timer value */ + val = readl(®s->snapl) & 0xffff; + val |= (readl(®s->snaph) & 0xffff) << 16; + *count = ~val; + + return 0; +} + +static int altera_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct altera_timer_platdata *plat = dev->platdata; + struct altera_timer_regs *const regs = plat->regs; + + uc_priv->clock_rate = plat->clock_rate; + + writel(0, ®s->status); + writel(0, ®s->control); + writel(ALTERA_TIMER_STOP, ®s->control); + + writel(0xffff, ®s->periodl); + writel(0xffff, ®s->periodh); + writel(ALTERA_TIMER_CONT | ALTERA_TIMER_START, ®s->control); + + return 0; +} + +static int altera_timer_ofdata_to_platdata(struct udevice *dev) +{ + struct altera_timer_platdata *plat = dev_get_platdata(dev); + + plat->regs = ioremap(dev_get_addr(dev), + sizeof(struct altera_timer_regs)); + plat->clock_rate = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "clock-frequency", 0); + + return 0; +} + +static const struct timer_ops altera_timer_ops = { + .get_count = altera_timer_get_count, +}; + +static const struct udevice_id altera_timer_ids[] = { + { .compatible = "altr,timer-1.0", }, + { } +}; + +U_BOOT_DRIVER(altera_timer) = { + .name = "altera_timer", + .id = UCLASS_TIMER, + .of_match = altera_timer_ids, + .ofdata_to_platdata = altera_timer_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct altera_timer_platdata), + .probe = altera_timer_probe, + .ops = &altera_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c new file mode 100644 index 00000000000..12aee5ba4e8 --- /dev/null +++ b/drivers/timer/timer-uclass.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> + +/* + * Implement a Timer uclass to work with lib/time.c. The timer is usually + * a 32 bits free-running up counter. The get_rate() method is used to get + * the input clock frequency of the timer. The get_count() method is used + * get the current 32 bits count value. If the hardware is counting down, + * the value should be inversed inside the method. There may be no real + * tick, and no timer interrupt. + */ + +int timer_get_count(struct udevice *dev, unsigned long *count) +{ + const struct timer_ops *ops = device_get_ops(dev); + + if (!ops->get_count) + return -ENOSYS; + + return ops->get_count(dev, count); +} + +unsigned long timer_get_rate(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + return uc_priv->clock_rate; +} + +UCLASS_DRIVER(timer) = { + .id = UCLASS_TIMER, + .name = "timer", + .per_device_auto_alloc_size = sizeof(struct timer_dev_priv), +}; diff --git a/drivers/usb/dwc3/linux-compat.h b/drivers/usb/dwc3/linux-compat.h index b36f68fec86..6c9c2791a8b 100644 --- a/drivers/usb/dwc3/linux-compat.h +++ b/drivers/usb/dwc3/linux-compat.h @@ -30,9 +30,4 @@ static inline void *devm_kzalloc(struct device *dev, unsigned int size, { return kzalloc(size, flags); } - -static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) -{ - return kzalloc(n * size, flags); -} #endif @@ -23,6 +23,7 @@ #include <fat.h> #include <fs.h> #include <sandboxfs.h> +#include <ubifs_uboot.h> #include <asm/io.h> #include <div64.h> #include <linux/math64.h> @@ -157,6 +158,21 @@ static struct fstype_info fstypes[] = { .uuid = fs_uuid_unsupported, }, #endif +#ifdef CONFIG_CMD_UBIFS + { + .fstype = FS_TYPE_UBIFS, + .name = "ubifs", + .null_dev_desc_ok = true, + .probe = ubifs_set_blk_dev, + .close = ubifs_close, + .ls = ubifs_ls, + .exists = ubifs_exists, + .size = ubifs_size, + .read = ubifs_read, + .write = fs_write_unsupported, + .uuid = fs_uuid_unsupported, + }, +#endif { .fstype = FS_TYPE_ANY, .name = "unsupported", diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index c626cbf4843..1b4683fc8e7 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c @@ -433,7 +433,6 @@ static int calc_dd_growth(const struct ubifs_info *c, */ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) { - int uninitialized_var(cmt_retries), uninitialized_var(wb_retries); int err, idx_growth, data_growth, dd_growth, retried = 0; ubifs_assert(req->new_page <= 1); @@ -506,7 +505,7 @@ again: c->bi.nospace_rp = 1; smp_wmb(); } else - ubifs_err("cannot budget space, error %d", err); + ubifs_err(c, "cannot budget space, error %d", err); return err; } diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 6e6f018b2f5..38c91d07347 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -334,9 +334,9 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node) pr_err("\tkey_fmt %d (%s)\n", (int)sup->key_fmt, get_key_fmt(sup->key_fmt)); pr_err("\tflags %#x\n", sup_flags); - pr_err("\t big_lpt %u\n", + pr_err("\tbig_lpt %u\n", !!(sup_flags & UBIFS_FLG_BIGLPT)); - pr_err("\t space_fixup %u\n", + pr_err("\tspace_fixup %u\n", !!(sup_flags & UBIFS_FLG_SPACE_FIXUP)); pr_err("\tmin_io_size %u\n", le32_to_cpu(sup->min_io_size)); pr_err("\tleb_size %u\n", le32_to_cpu(sup->leb_size)); @@ -751,8 +751,10 @@ void ubifs_dump_lprops(struct ubifs_info *c) for (lnum = c->main_first; lnum < c->leb_cnt; lnum++) { err = ubifs_read_one_lp(c, lnum, &lp); - if (err) - ubifs_err("cannot read lprops for LEB %d", lnum); + if (err) { + ubifs_err(c, "cannot read lprops for LEB %d", lnum); + continue; + } ubifs_dump_lprop(c, &lp); } @@ -823,13 +825,13 @@ void ubifs_dump_leb(const struct ubifs_info *c, int lnum) buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); if (!buf) { - ubifs_err("cannot allocate memory for dumping LEB %d", lnum); + ubifs_err(c, "cannot allocate memory for dumping LEB %d", lnum); return; } sleb = ubifs_scan(c, lnum, 0, buf, 0); if (IS_ERR(sleb)) { - ubifs_err("scan error %d", (int)PTR_ERR(sleb)); + ubifs_err(c, "scan error %d", (int)PTR_ERR(sleb)); goto out; } @@ -1037,7 +1039,7 @@ int dbg_check_space_info(struct ubifs_info *c) spin_unlock(&c->space_lock); if (free != d->saved_free) { - ubifs_err("free space changed from %lld to %lld", + ubifs_err(c, "free space changed from %lld to %lld", d->saved_free, free); goto out; } @@ -1045,15 +1047,15 @@ int dbg_check_space_info(struct ubifs_info *c) return 0; out: - ubifs_msg("saved lprops statistics dump"); + ubifs_msg(c, "saved lprops statistics dump"); ubifs_dump_lstats(&d->saved_lst); - ubifs_msg("saved budgeting info dump"); + ubifs_msg(c, "saved budgeting info dump"); ubifs_dump_budg(c, &d->saved_bi); - ubifs_msg("saved idx_gc_cnt %d", d->saved_idx_gc_cnt); - ubifs_msg("current lprops statistics dump"); + ubifs_msg(c, "saved idx_gc_cnt %d", d->saved_idx_gc_cnt); + ubifs_msg(c, "current lprops statistics dump"); ubifs_get_lp_stats(c, &lst); ubifs_dump_lstats(&lst); - ubifs_msg("current budgeting info dump"); + ubifs_msg(c, "current budgeting info dump"); ubifs_dump_budg(c, &c->bi); dump_stack(); return -EINVAL; @@ -1082,9 +1084,9 @@ int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode) mutex_lock(&ui->ui_mutex); spin_lock(&ui->ui_lock); if (ui->ui_size != ui->synced_i_size && !ui->dirty) { - ubifs_err("ui_size is %lld, synced_i_size is %lld, but inode is clean", + ubifs_err(c, "ui_size is %lld, synced_i_size is %lld, but inode is clean", ui->ui_size, ui->synced_i_size); - ubifs_err("i_ino %lu, i_mode %#x, i_size %lld", inode->i_ino, + ubifs_err(c, "i_ino %lu, i_mode %#x, i_size %lld", inode->i_ino, inode->i_mode, i_size_read(inode)); dump_stack(); err = -EINVAL; @@ -1145,7 +1147,7 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir) kfree(pdent); if (i_size_read(dir) != size) { - ubifs_err("directory inode %lu has size %llu, but calculated size is %llu", + ubifs_err(c, "directory inode %lu has size %llu, but calculated size is %llu", dir->i_ino, (unsigned long long)i_size_read(dir), (unsigned long long)size); ubifs_dump_inode(c, dir); @@ -1153,7 +1155,7 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir) return -EINVAL; } if (dir->i_nlink != nlink) { - ubifs_err("directory inode %lu has nlink %u, but calculated nlink is %u", + ubifs_err(c, "directory inode %lu has nlink %u, but calculated nlink is %u", dir->i_ino, dir->i_nlink, nlink); ubifs_dump_inode(c, dir); dump_stack(); @@ -1212,10 +1214,10 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, err = 1; key_read(c, &dent1->key, &key); if (keys_cmp(c, &zbr1->key, &key)) { - ubifs_err("1st entry at %d:%d has key %s", zbr1->lnum, + ubifs_err(c, "1st entry at %d:%d has key %s", zbr1->lnum, zbr1->offs, dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); - ubifs_err("but it should have key %s according to tnc", + ubifs_err(c, "but it should have key %s according to tnc", dbg_snprintf_key(c, &zbr1->key, key_buf, DBG_KEY_BUF_LEN)); ubifs_dump_node(c, dent1); @@ -1224,10 +1226,10 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, key_read(c, &dent2->key, &key); if (keys_cmp(c, &zbr2->key, &key)) { - ubifs_err("2nd entry at %d:%d has key %s", zbr1->lnum, + ubifs_err(c, "2nd entry at %d:%d has key %s", zbr1->lnum, zbr1->offs, dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); - ubifs_err("but it should have key %s according to tnc", + ubifs_err(c, "but it should have key %s according to tnc", dbg_snprintf_key(c, &zbr2->key, key_buf, DBG_KEY_BUF_LEN)); ubifs_dump_node(c, dent2); @@ -1243,14 +1245,14 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, goto out_free; } if (cmp == 0 && nlen1 == nlen2) - ubifs_err("2 xent/dent nodes with the same name"); + ubifs_err(c, "2 xent/dent nodes with the same name"); else - ubifs_err("bad order of colliding key %s", + ubifs_err(c, "bad order of colliding key %s", dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); - ubifs_msg("first node at %d:%d\n", zbr1->lnum, zbr1->offs); + ubifs_msg(c, "first node at %d:%d\n", zbr1->lnum, zbr1->offs); ubifs_dump_node(c, dent1); - ubifs_msg("second node at %d:%d\n", zbr2->lnum, zbr2->offs); + ubifs_msg(c, "second node at %d:%d\n", zbr2->lnum, zbr2->offs); ubifs_dump_node(c, dent2); out_free: @@ -1452,11 +1454,11 @@ static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr) return 0; out: - ubifs_err("failed, error %d", err); - ubifs_msg("dump of the znode"); + ubifs_err(c, "failed, error %d", err); + ubifs_msg(c, "dump of the znode"); ubifs_dump_znode(c, znode); if (zp) { - ubifs_msg("dump of the parent znode"); + ubifs_msg(c, "dump of the parent znode"); ubifs_dump_znode(c, zp); } dump_stack(); @@ -1552,9 +1554,9 @@ int dbg_check_tnc(struct ubifs_info *c, int extra) if (err < 0) return err; if (err) { - ubifs_msg("first znode"); + ubifs_msg(c, "first znode"); ubifs_dump_znode(c, prev); - ubifs_msg("second znode"); + ubifs_msg(c, "second znode"); ubifs_dump_znode(c, znode); return -EINVAL; } @@ -1563,13 +1565,13 @@ int dbg_check_tnc(struct ubifs_info *c, int extra) if (extra) { if (clean_cnt != atomic_long_read(&c->clean_zn_cnt)) { - ubifs_err("incorrect clean_zn_cnt %ld, calculated %ld", + ubifs_err(c, "incorrect clean_zn_cnt %ld, calculated %ld", atomic_long_read(&c->clean_zn_cnt), clean_cnt); return -EINVAL; } if (dirty_cnt != atomic_long_read(&c->dirty_zn_cnt)) { - ubifs_err("incorrect dirty_zn_cnt %ld, calculated %ld", + ubifs_err(c, "incorrect dirty_zn_cnt %ld, calculated %ld", atomic_long_read(&c->dirty_zn_cnt), dirty_cnt); return -EINVAL; @@ -1648,7 +1650,7 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, if (znode_cb) { err = znode_cb(c, znode, priv); if (err) { - ubifs_err("znode checking function returned error %d", + ubifs_err(c, "znode checking function returned error %d", err); ubifs_dump_znode(c, znode); goto out_dump; @@ -1659,7 +1661,7 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, zbr = &znode->zbranch[idx]; err = leaf_cb(c, zbr, priv); if (err) { - ubifs_err("leaf checking function returned error %d, for leaf at LEB %d:%d", + ubifs_err(c, "leaf checking function returned error %d, for leaf at LEB %d:%d", err, zbr->lnum, zbr->offs); goto out_dump; } @@ -1715,7 +1717,7 @@ out_dump: zbr = &znode->parent->zbranch[znode->iip]; else zbr = &c->zroot; - ubifs_msg("dump of znode at LEB %d:%d", zbr->lnum, zbr->offs); + ubifs_msg(c, "dump of znode at LEB %d:%d", zbr->lnum, zbr->offs); ubifs_dump_znode(c, znode); out_unlock: mutex_unlock(&c->tnc_mutex); @@ -1762,12 +1764,12 @@ int dbg_check_idx_size(struct ubifs_info *c, long long idx_size) err = dbg_walk_index(c, NULL, add_size, &calc); if (err) { - ubifs_err("error %d while walking the index", err); + ubifs_err(c, "error %d while walking the index", err); return err; } if (calc != idx_size) { - ubifs_err("index size check failed: calculated size is %lld, should be %lld", + ubifs_err(c, "index size check failed: calculated size is %lld, should be %lld", calc, idx_size); dump_stack(); return -EINVAL; @@ -1855,7 +1857,7 @@ static struct fsck_inode *add_inode(struct ubifs_info *c, } if (inum > c->highest_inum) { - ubifs_err("too high inode number, max. is %lu", + ubifs_err(c, "too high inode number, max. is %lu", (unsigned long)c->highest_inum); return ERR_PTR(-EINVAL); } @@ -1962,17 +1964,17 @@ static struct fsck_inode *read_add_inode(struct ubifs_info *c, ino_key_init(c, &key, inum); err = ubifs_lookup_level0(c, &key, &znode, &n); if (!err) { - ubifs_err("inode %lu not found in index", (unsigned long)inum); + ubifs_err(c, "inode %lu not found in index", (unsigned long)inum); return ERR_PTR(-ENOENT); } else if (err < 0) { - ubifs_err("error %d while looking up inode %lu", + ubifs_err(c, "error %d while looking up inode %lu", err, (unsigned long)inum); return ERR_PTR(err); } zbr = &znode->zbranch[n]; if (zbr->len < UBIFS_INO_NODE_SZ) { - ubifs_err("bad node %lu node length %d", + ubifs_err(c, "bad node %lu node length %d", (unsigned long)inum, zbr->len); return ERR_PTR(-EINVAL); } @@ -1983,7 +1985,7 @@ static struct fsck_inode *read_add_inode(struct ubifs_info *c, err = ubifs_tnc_read_node(c, zbr, ino); if (err) { - ubifs_err("cannot read inode node at LEB %d:%d, error %d", + ubifs_err(c, "cannot read inode node at LEB %d:%d, error %d", zbr->lnum, zbr->offs, err); kfree(ino); return ERR_PTR(err); @@ -1992,7 +1994,7 @@ static struct fsck_inode *read_add_inode(struct ubifs_info *c, fscki = add_inode(c, fsckd, ino); kfree(ino); if (IS_ERR(fscki)) { - ubifs_err("error %ld while adding inode %lu node", + ubifs_err(c, "error %ld while adding inode %lu node", PTR_ERR(fscki), (unsigned long)inum); return fscki; } @@ -2026,7 +2028,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, struct fsck_inode *fscki; if (zbr->len < UBIFS_CH_SZ) { - ubifs_err("bad leaf length %d (LEB %d:%d)", + ubifs_err(c, "bad leaf length %d (LEB %d:%d)", zbr->len, zbr->lnum, zbr->offs); return -EINVAL; } @@ -2037,7 +2039,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, err = ubifs_tnc_read_node(c, zbr, node); if (err) { - ubifs_err("cannot read leaf node at LEB %d:%d, error %d", + ubifs_err(c, "cannot read leaf node at LEB %d:%d, error %d", zbr->lnum, zbr->offs, err); goto out_free; } @@ -2047,7 +2049,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, fscki = add_inode(c, priv, node); if (IS_ERR(fscki)) { err = PTR_ERR(fscki); - ubifs_err("error %d while adding inode node", err); + ubifs_err(c, "error %d while adding inode node", err); goto out_dump; } goto out; @@ -2055,7 +2057,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, if (type != UBIFS_DENT_KEY && type != UBIFS_XENT_KEY && type != UBIFS_DATA_KEY) { - ubifs_err("unexpected node type %d at LEB %d:%d", + ubifs_err(c, "unexpected node type %d at LEB %d:%d", type, zbr->lnum, zbr->offs); err = -EINVAL; goto out_free; @@ -2063,7 +2065,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, ch = node; if (le64_to_cpu(ch->sqnum) > c->max_sqnum) { - ubifs_err("too high sequence number, max. is %llu", + ubifs_err(c, "too high sequence number, max. is %llu", c->max_sqnum); err = -EINVAL; goto out_dump; @@ -2073,6 +2075,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, long long blk_offs; struct ubifs_data_node *dn = node; + ubifs_assert(zbr->len >= UBIFS_DATA_NODE_SZ); + /* * Search the inode node this data node belongs to and insert * it to the RB-tree of inodes. @@ -2081,7 +2085,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, fscki = read_add_inode(c, priv, inum); if (IS_ERR(fscki)) { err = PTR_ERR(fscki); - ubifs_err("error %d while processing data node and trying to find inode node %lu", + ubifs_err(c, "error %d while processing data node and trying to find inode node %lu", err, (unsigned long)inum); goto out_dump; } @@ -2091,7 +2095,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, blk_offs <<= UBIFS_BLOCK_SHIFT; blk_offs += le32_to_cpu(dn->size); if (blk_offs > fscki->size) { - ubifs_err("data node at LEB %d:%d is not within inode size %lld", + ubifs_err(c, "data node at LEB %d:%d is not within inode size %lld", zbr->lnum, zbr->offs, fscki->size); err = -EINVAL; goto out_dump; @@ -2101,6 +2105,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, struct ubifs_dent_node *dent = node; struct fsck_inode *fscki1; + ubifs_assert(zbr->len >= UBIFS_DENT_NODE_SZ); + err = ubifs_validate_entry(c, dent); if (err) goto out_dump; @@ -2113,7 +2119,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, fscki = read_add_inode(c, priv, inum); if (IS_ERR(fscki)) { err = PTR_ERR(fscki); - ubifs_err("error %d while processing entry node and trying to find inode node %lu", + ubifs_err(c, "error %d while processing entry node and trying to find inode node %lu", err, (unsigned long)inum); goto out_dump; } @@ -2125,7 +2131,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, fscki1 = read_add_inode(c, priv, inum); if (IS_ERR(fscki1)) { err = PTR_ERR(fscki1); - ubifs_err("error %d while processing entry node and trying to find parent inode node %lu", + ubifs_err(c, "error %d while processing entry node and trying to find parent inode node %lu", err, (unsigned long)inum); goto out_dump; } @@ -2148,7 +2154,7 @@ out: return 0; out_dump: - ubifs_msg("dump of node at LEB %d:%d", zbr->lnum, zbr->offs); + ubifs_msg(c, "dump of node at LEB %d:%d", zbr->lnum, zbr->offs); ubifs_dump_node(c, node); out_free: kfree(node); @@ -2199,52 +2205,52 @@ static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd) */ if (fscki->inum != UBIFS_ROOT_INO && fscki->references != 1) { - ubifs_err("directory inode %lu has %d direntries which refer it, but should be 1", + ubifs_err(c, "directory inode %lu has %d direntries which refer it, but should be 1", (unsigned long)fscki->inum, fscki->references); goto out_dump; } if (fscki->inum == UBIFS_ROOT_INO && fscki->references != 0) { - ubifs_err("root inode %lu has non-zero (%d) direntries which refer it", + ubifs_err(c, "root inode %lu has non-zero (%d) direntries which refer it", (unsigned long)fscki->inum, fscki->references); goto out_dump; } if (fscki->calc_sz != fscki->size) { - ubifs_err("directory inode %lu size is %lld, but calculated size is %lld", + ubifs_err(c, "directory inode %lu size is %lld, but calculated size is %lld", (unsigned long)fscki->inum, fscki->size, fscki->calc_sz); goto out_dump; } if (fscki->calc_cnt != fscki->nlink) { - ubifs_err("directory inode %lu nlink is %d, but calculated nlink is %d", + ubifs_err(c, "directory inode %lu nlink is %d, but calculated nlink is %d", (unsigned long)fscki->inum, fscki->nlink, fscki->calc_cnt); goto out_dump; } } else { if (fscki->references != fscki->nlink) { - ubifs_err("inode %lu nlink is %d, but calculated nlink is %d", + ubifs_err(c, "inode %lu nlink is %d, but calculated nlink is %d", (unsigned long)fscki->inum, fscki->nlink, fscki->references); goto out_dump; } } if (fscki->xattr_sz != fscki->calc_xsz) { - ubifs_err("inode %lu has xattr size %u, but calculated size is %lld", + ubifs_err(c, "inode %lu has xattr size %u, but calculated size is %lld", (unsigned long)fscki->inum, fscki->xattr_sz, fscki->calc_xsz); goto out_dump; } if (fscki->xattr_cnt != fscki->calc_xcnt) { - ubifs_err("inode %lu has %u xattrs, but calculated count is %lld", + ubifs_err(c, "inode %lu has %u xattrs, but calculated count is %lld", (unsigned long)fscki->inum, fscki->xattr_cnt, fscki->calc_xcnt); goto out_dump; } if (fscki->xattr_nms != fscki->calc_xnms) { - ubifs_err("inode %lu has xattr names' size %u, but calculated names' size is %lld", + ubifs_err(c, "inode %lu has xattr names' size %u, but calculated names' size is %lld", (unsigned long)fscki->inum, fscki->xattr_nms, fscki->calc_xnms); goto out_dump; @@ -2258,11 +2264,11 @@ out_dump: ino_key_init(c, &key, fscki->inum); err = ubifs_lookup_level0(c, &key, &znode, &n); if (!err) { - ubifs_err("inode %lu not found in index", + ubifs_err(c, "inode %lu not found in index", (unsigned long)fscki->inum); return -ENOENT; } else if (err < 0) { - ubifs_err("error %d while looking up inode %lu", + ubifs_err(c, "error %d while looking up inode %lu", err, (unsigned long)fscki->inum); return err; } @@ -2274,13 +2280,13 @@ out_dump: err = ubifs_tnc_read_node(c, zbr, ino); if (err) { - ubifs_err("cannot read inode node at LEB %d:%d, error %d", + ubifs_err(c, "cannot read inode node at LEB %d:%d, error %d", zbr->lnum, zbr->offs, err); kfree(ino); return err; } - ubifs_msg("dump of the inode %lu sitting in LEB %d:%d", + ubifs_msg(c, "dump of the inode %lu sitting in LEB %d:%d", (unsigned long)fscki->inum, zbr->lnum, zbr->offs); ubifs_dump_node(c, ino); kfree(ino); @@ -2321,7 +2327,7 @@ int dbg_check_filesystem(struct ubifs_info *c) return 0; out_free: - ubifs_err("file-system check failed with error %d", err); + ubifs_err(c, "file-system check failed with error %d", err); dump_stack(); free_inodes(&fsckd); return err; @@ -2352,12 +2358,12 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head) sb = container_of(cur->next, struct ubifs_scan_node, list); if (sa->type != UBIFS_DATA_NODE) { - ubifs_err("bad node type %d", sa->type); + ubifs_err(c, "bad node type %d", sa->type); ubifs_dump_node(c, sa->node); return -EINVAL; } if (sb->type != UBIFS_DATA_NODE) { - ubifs_err("bad node type %d", sb->type); + ubifs_err(c, "bad node type %d", sb->type); ubifs_dump_node(c, sb->node); return -EINVAL; } @@ -2368,7 +2374,7 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head) if (inuma < inumb) continue; if (inuma > inumb) { - ubifs_err("larger inum %lu goes before inum %lu", + ubifs_err(c, "larger inum %lu goes before inum %lu", (unsigned long)inuma, (unsigned long)inumb); goto error_dump; } @@ -2377,11 +2383,11 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head) blkb = key_block(c, &sb->key); if (blka > blkb) { - ubifs_err("larger block %u goes before %u", blka, blkb); + ubifs_err(c, "larger block %u goes before %u", blka, blkb); goto error_dump; } if (blka == blkb) { - ubifs_err("two data nodes for the same block"); + ubifs_err(c, "two data nodes for the same block"); goto error_dump; } } @@ -2420,19 +2426,19 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE && sa->type != UBIFS_XENT_NODE) { - ubifs_err("bad node type %d", sa->type); + ubifs_err(c, "bad node type %d", sa->type); ubifs_dump_node(c, sa->node); return -EINVAL; } if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE && sa->type != UBIFS_XENT_NODE) { - ubifs_err("bad node type %d", sb->type); + ubifs_err(c, "bad node type %d", sb->type); ubifs_dump_node(c, sb->node); return -EINVAL; } if (sa->type != UBIFS_INO_NODE && sb->type == UBIFS_INO_NODE) { - ubifs_err("non-inode node goes before inode node"); + ubifs_err(c, "non-inode node goes before inode node"); goto error_dump; } @@ -2442,7 +2448,7 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) if (sa->type == UBIFS_INO_NODE && sb->type == UBIFS_INO_NODE) { /* Inode nodes are sorted in descending size order */ if (sa->len < sb->len) { - ubifs_err("smaller inode node goes first"); + ubifs_err(c, "smaller inode node goes first"); goto error_dump; } continue; @@ -2458,7 +2464,7 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) if (inuma < inumb) continue; if (inuma > inumb) { - ubifs_err("larger inum %lu goes before inum %lu", + ubifs_err(c, "larger inum %lu goes before inum %lu", (unsigned long)inuma, (unsigned long)inumb); goto error_dump; } @@ -2467,7 +2473,7 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) hashb = key_block(c, &sb->key); if (hasha > hashb) { - ubifs_err("larger hash %u goes before %u", + ubifs_err(c, "larger hash %u goes before %u", hasha, hashb); goto error_dump; } @@ -2476,9 +2482,9 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) return 0; error_dump: - ubifs_msg("dumping first node"); + ubifs_msg(c, "dumping first node"); ubifs_dump_node(c, sa->node); - ubifs_msg("dumping second node"); + ubifs_msg(c, "dumping second node"); ubifs_dump_node(c, sb->node); return -EINVAL; return 0; @@ -2503,17 +2509,17 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write) if (chance(1, 2)) { d->pc_delay = 1; - /* Fail withing 1 minute */ + /* Fail within 1 minute */ delay = prandom_u32() % 60000; d->pc_timeout = jiffies; d->pc_timeout += msecs_to_jiffies(delay); - ubifs_warn("failing after %lums", delay); + ubifs_warn(c, "failing after %lums", delay); } else { d->pc_delay = 2; delay = prandom_u32() % 10000; /* Fail within 10000 operations */ d->pc_cnt_max = delay; - ubifs_warn("failing after %lu calls", delay); + ubifs_warn(c, "failing after %lu calls", delay); } } @@ -2531,55 +2537,55 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write) return 0; if (chance(19, 20)) return 0; - ubifs_warn("failing in super block LEB %d", lnum); + ubifs_warn(c, "failing in super block LEB %d", lnum); } else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) { if (chance(19, 20)) return 0; - ubifs_warn("failing in master LEB %d", lnum); + ubifs_warn(c, "failing in master LEB %d", lnum); } else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) { if (write && chance(99, 100)) return 0; if (chance(399, 400)) return 0; - ubifs_warn("failing in log LEB %d", lnum); + ubifs_warn(c, "failing in log LEB %d", lnum); } else if (lnum >= c->lpt_first && lnum <= c->lpt_last) { if (write && chance(7, 8)) return 0; if (chance(19, 20)) return 0; - ubifs_warn("failing in LPT LEB %d", lnum); + ubifs_warn(c, "failing in LPT LEB %d", lnum); } else if (lnum >= c->orph_first && lnum <= c->orph_last) { if (write && chance(1, 2)) return 0; if (chance(9, 10)) return 0; - ubifs_warn("failing in orphan LEB %d", lnum); + ubifs_warn(c, "failing in orphan LEB %d", lnum); } else if (lnum == c->ihead_lnum) { if (chance(99, 100)) return 0; - ubifs_warn("failing in index head LEB %d", lnum); + ubifs_warn(c, "failing in index head LEB %d", lnum); } else if (c->jheads && lnum == c->jheads[GCHD].wbuf.lnum) { if (chance(9, 10)) return 0; - ubifs_warn("failing in GC head LEB %d", lnum); + ubifs_warn(c, "failing in GC head LEB %d", lnum); } else if (write && !RB_EMPTY_ROOT(&c->buds) && !ubifs_search_bud(c, lnum)) { if (chance(19, 20)) return 0; - ubifs_warn("failing in non-bud LEB %d", lnum); + ubifs_warn(c, "failing in non-bud LEB %d", lnum); } else if (c->cmt_state == COMMIT_RUNNING_BACKGROUND || c->cmt_state == COMMIT_RUNNING_REQUIRED) { if (chance(999, 1000)) return 0; - ubifs_warn("failing in bud LEB %d commit running", lnum); + ubifs_warn(c, "failing in bud LEB %d commit running", lnum); } else { if (chance(9999, 10000)) return 0; - ubifs_warn("failing in bud LEB %d commit not running", lnum); + ubifs_warn(c, "failing in bud LEB %d commit not running", lnum); } d->pc_happened = 1; - ubifs_warn("========== Power cut emulated =========="); + ubifs_warn(c, "========== Power cut emulated =========="); dump_stack(); return 1; } @@ -2594,7 +2600,7 @@ static int corrupt_data(const struct ubifs_info *c, const void *buf, /* Corruption span max to end of write unit */ to = min(len, ALIGN(from + 1, c->max_write_size)); - ubifs_warn("filled bytes %u-%u with %s", from, to - 1, + ubifs_warn(c, "filled bytes %u-%u with %s", from, to - 1, ffs ? "0xFFs" : "random data"); if (ffs) @@ -2616,7 +2622,7 @@ int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, failing = power_cut_emulated(c, lnum, 1); if (failing) { len = corrupt_data(c, buf, len); - ubifs_warn("actually write %d bytes to LEB %d:%d (the buffer was corrupted)", + ubifs_warn(c, "actually write %d bytes to LEB %d:%d (the buffer was corrupted)", len, lnum, offs); } err = ubi_leb_write(c->ubi, lnum, buf, offs, len); @@ -2946,7 +2952,7 @@ out_remove: debugfs_remove_recursive(d->dfs_dir); out: err = dent ? PTR_ERR(dent) : -ENODEV; - ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n", + ubifs_err(c, "cannot create \"%s\" debugfs file or directory, error %d\n", fname, err); return err; } @@ -3100,8 +3106,8 @@ out_remove: debugfs_remove_recursive(dfs_rootdir); out: err = dent ? PTR_ERR(dent) : -ENODEV; - ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n", - fname, err); + pr_err("UBIFS error (pid %d): cannot create \"%s\" debugfs file or directory, error %d\n", + current->pid, fname, err); return err; } diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index bdccdc45e11..51a95bb8552 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -79,7 +79,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) c->ro_error = 1; c->no_chk_data_crc = 0; c->vfs_sb->s_flags |= MS_RDONLY; - ubifs_warn("switched to read-only mode, error %d", err); + ubifs_warn(c, "switched to read-only mode, error %d", err); dump_stack(); } } @@ -101,7 +101,7 @@ int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs, * @even_ebadmsg is true. */ if (err && (err != -EBADMSG || even_ebadmsg)) { - ubifs_err("reading %d bytes from LEB %d:%d failed, error %d", + ubifs_err(c, "reading %d bytes from LEB %d:%d failed, error %d", len, lnum, offs, err); dump_stack(); } @@ -118,10 +118,12 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, return -EROFS; if (!dbg_is_tst_rcvry(c)) err = ubi_leb_write(c->ubi, lnum, buf, offs, len); +#ifndef __UBOOT__ else err = dbg_leb_write(c, lnum, buf, offs, len); +#endif if (err) { - ubifs_err("writing %d bytes to LEB %d:%d failed, error %d", + ubifs_err(c, "writing %d bytes to LEB %d:%d failed, error %d", len, lnum, offs, err); ubifs_ro_mode(c, err); dump_stack(); @@ -138,10 +140,12 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len) return -EROFS; if (!dbg_is_tst_rcvry(c)) err = ubi_leb_change(c->ubi, lnum, buf, len); +#ifndef __UBOOT__ else err = dbg_leb_change(c, lnum, buf, len); +#endif if (err) { - ubifs_err("changing %d bytes in LEB %d failed, error %d", + ubifs_err(c, "changing %d bytes in LEB %d failed, error %d", len, lnum, err); ubifs_ro_mode(c, err); dump_stack(); @@ -158,10 +162,12 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum) return -EROFS; if (!dbg_is_tst_rcvry(c)) err = ubi_leb_unmap(c->ubi, lnum); +#ifndef __UBOOT__ else err = dbg_leb_unmap(c, lnum); +#endif if (err) { - ubifs_err("unmap LEB %d failed, error %d", lnum, err); + ubifs_err(c, "unmap LEB %d failed, error %d", lnum, err); ubifs_ro_mode(c, err); dump_stack(); } @@ -177,10 +183,12 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum) return -EROFS; if (!dbg_is_tst_rcvry(c)) err = ubi_leb_map(c->ubi, lnum); +#ifndef __UBOOT__ else err = dbg_leb_map(c, lnum); +#endif if (err) { - ubifs_err("mapping LEB %d failed, error %d", lnum, err); + ubifs_err(c, "mapping LEB %d failed, error %d", lnum, err); ubifs_ro_mode(c, err); dump_stack(); } @@ -193,7 +201,7 @@ int ubifs_is_mapped(const struct ubifs_info *c, int lnum) err = ubi_is_mapped(c->ubi, lnum); if (err < 0) { - ubifs_err("ubi_is_mapped failed for LEB %d, error %d", + ubifs_err(c, "ubi_is_mapped failed for LEB %d, error %d", lnum, err); dump_stack(); } @@ -241,7 +249,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, magic = le32_to_cpu(ch->magic); if (magic != UBIFS_NODE_MAGIC) { if (!quiet) - ubifs_err("bad magic %#08x, expected %#08x", + ubifs_err(c, "bad magic %#08x, expected %#08x", magic, UBIFS_NODE_MAGIC); err = -EUCLEAN; goto out; @@ -250,7 +258,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, type = ch->node_type; if (type < 0 || type >= UBIFS_NODE_TYPES_CNT) { if (!quiet) - ubifs_err("bad node type %d", type); + ubifs_err(c, "bad node type %d", type); goto out; } @@ -273,7 +281,7 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, node_crc = le32_to_cpu(ch->crc); if (crc != node_crc) { if (!quiet) - ubifs_err("bad CRC: calculated %#08x, read %#08x", + ubifs_err(c, "bad CRC: calculated %#08x, read %#08x", crc, node_crc); err = -EUCLEAN; goto out; @@ -283,10 +291,10 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, out_len: if (!quiet) - ubifs_err("bad node length %d", node_len); + ubifs_err(c, "bad node length %d", node_len); out: if (!quiet) { - ubifs_err("bad node at LEB %d:%d", lnum, offs); + ubifs_err(c, "bad node at LEB %d:%d", lnum, offs); ubifs_dump_node(c, buf); dump_stack(); } @@ -349,11 +357,11 @@ static unsigned long long next_sqnum(struct ubifs_info *c) if (unlikely(sqnum >= SQNUM_WARN_WATERMARK)) { if (sqnum >= SQNUM_WATERMARK) { - ubifs_err("sequence number overflow %llu, end of life", + ubifs_err(c, "sequence number overflow %llu, end of life", sqnum); ubifs_ro_mode(c, -EINVAL); } - ubifs_warn("running out of sequence numbers, end of life soon"); + ubifs_warn(c, "running out of sequence numbers, end of life soon"); } return sqnum; @@ -426,7 +434,7 @@ void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last) #ifndef __UBOOT__ /** * wbuf_timer_callback - write-buffer timer callback function. - * @data: timer data (write-buffer descriptor) + * @timer: timer data (write-buffer descriptor) * * This function is called when the write-buffer timer expires. */ @@ -635,7 +643,7 @@ int ubifs_bg_wbufs_sync(struct ubifs_info *c) err = ubifs_wbuf_sync_nolock(wbuf); mutex_unlock(&wbuf->io_mutex); if (err) { - ubifs_err("cannot sync write-buffer, error %d", err); + ubifs_err(c, "cannot sync write-buffer, error %d", err); ubifs_ro_mode(c, err); goto out_timers; } @@ -832,7 +840,7 @@ exit: return 0; out: - ubifs_err("cannot write %d bytes to LEB %d:%d, error %d", + ubifs_err(c, "cannot write %d bytes to LEB %d:%d, error %d", len, wbuf->lnum, wbuf->offs, err); ubifs_dump_node(c, buf); dump_stack(); @@ -932,27 +940,27 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, } if (type != ch->node_type) { - ubifs_err("bad node type (%d but expected %d)", + ubifs_err(c, "bad node type (%d but expected %d)", ch->node_type, type); goto out; } err = ubifs_check_node(c, buf, lnum, offs, 0, 0); if (err) { - ubifs_err("expected node type %d", type); + ubifs_err(c, "expected node type %d", type); return err; } rlen = le32_to_cpu(ch->len); if (rlen != len) { - ubifs_err("bad node length %d, expected %d", rlen, len); + ubifs_err(c, "bad node length %d, expected %d", rlen, len); goto out; } return 0; out: - ubifs_err("bad node at LEB %d:%d", lnum, offs); + ubifs_err(c, "bad node at LEB %d:%d", lnum, offs); ubifs_dump_node(c, buf); dump_stack(); return -EINVAL; @@ -988,30 +996,32 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, return err; if (type != ch->node_type) { - ubifs_err("bad node type (%d but expected %d)", - ch->node_type, type); + ubifs_errc(c, "bad node type (%d but expected %d)", + ch->node_type, type); goto out; } err = ubifs_check_node(c, buf, lnum, offs, 0, 0); if (err) { - ubifs_err("expected node type %d", type); + ubifs_errc(c, "expected node type %d", type); return err; } l = le32_to_cpu(ch->len); if (l != len) { - ubifs_err("bad node length %d, expected %d", l, len); + ubifs_errc(c, "bad node length %d, expected %d", l, len); goto out; } return 0; out: - ubifs_err("bad node at LEB %d:%d, LEB mapping status %d", lnum, offs, - ubi_is_mapped(c->ubi, lnum)); - ubifs_dump_node(c, buf); - dump_stack(); + ubifs_errc(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum, + offs, ubi_is_mapped(c->ubi, lnum)); + if (!c->probing) { + ubifs_dump_node(c, buf); + dump_stack(); + } return -EINVAL; } diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c index 0355fe2b048..a07fdef12f2 100644 --- a/fs/ubifs/log.c +++ b/fs/ubifs/log.c @@ -98,10 +98,14 @@ static inline long long empty_log_bytes(const struct ubifs_info *c) h = (long long)c->lhead_lnum * c->leb_size + c->lhead_offs; t = (long long)c->ltail_lnum * c->leb_size; - if (h >= t) + if (h > t) return c->log_bytes - h + t; - else + else if (h != t) return t - h; + else if (c->lhead_lnum != c->ltail_lnum) + return 0; + else + return c->log_bytes; } /** @@ -232,6 +236,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) if (c->lhead_offs > c->leb_size - c->ref_node_alsz) { c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum); + ubifs_assert(c->lhead_lnum != c->ltail_lnum); c->lhead_offs = 0; } @@ -396,15 +401,14 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) /* Switch to the next log LEB */ if (c->lhead_offs) { c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum); + ubifs_assert(c->lhead_lnum != c->ltail_lnum); c->lhead_offs = 0; } - if (c->lhead_offs == 0) { - /* Must ensure next LEB has been unmapped */ - err = ubifs_leb_unmap(c, c->lhead_lnum); - if (err) - goto out; - } + /* Must ensure next LEB has been unmapped */ + err = ubifs_leb_unmap(c, c->lhead_lnum); + if (err) + goto out; len = ALIGN(len, c->min_io_size); dbg_log("writing commit start at LEB %d:0, len %d", c->lhead_lnum, len); @@ -439,9 +443,9 @@ out: * @ltail_lnum: new log tail LEB number * * This function is called on when the commit operation was finished. It - * moves log tail to new position and unmaps LEBs which contain obsolete data. - * Returns zero in case of success and a negative error code in case of - * failure. + * moves log tail to new position and updates the master node so that it stores + * the new log tail LEB number. Returns zero in case of success and a negative + * error code in case of failure. */ int ubifs_log_end_commit(struct ubifs_info *c, int ltail_lnum) { @@ -469,7 +473,12 @@ int ubifs_log_end_commit(struct ubifs_info *c, int ltail_lnum) spin_unlock(&c->buds_lock); err = dbg_check_bud_bytes(c); + if (err) + goto out; + + err = ubifs_write_master(c); +out: mutex_unlock(&c->log_mutex); return err; } @@ -679,7 +688,7 @@ int ubifs_consolidate_log(struct ubifs_info *c) destroy_done_tree(&done_tree); vfree(buf); if (write_lnum == c->lhead_lnum) { - ubifs_err("log is too full"); + ubifs_err(c, "log is too full"); return -EINVAL; } /* Unmap remaining LEBs */ @@ -726,7 +735,7 @@ static int dbg_check_bud_bytes(struct ubifs_info *c) bud_bytes += c->leb_size - bud->start; if (c->bud_bytes != bud_bytes) { - ubifs_err("bad bud_bytes %lld, calculated %lld", + ubifs_err(c, "bad bud_bytes %lld, calculated %lld", c->bud_bytes, bud_bytes); err = -EINVAL; } diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index a1a814f7797..292ea7ab27b 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c @@ -674,7 +674,7 @@ int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, out: ubifs_release_lprops(c); if (err) - ubifs_err("cannot change properties of LEB %d, error %d", + ubifs_err(c, "cannot change properties of LEB %d, error %d", lnum, err); return err; } @@ -713,7 +713,7 @@ int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty, out: ubifs_release_lprops(c); if (err) - ubifs_err("cannot update properties of LEB %d, error %d", + ubifs_err(c, "cannot update properties of LEB %d, error %d", lnum, err); return err; } @@ -738,7 +738,7 @@ int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp) lpp = ubifs_lpt_lookup(c, lnum); if (IS_ERR(lpp)) { err = PTR_ERR(lpp); - ubifs_err("cannot read properties of LEB %d, error %d", + ubifs_err(c, "cannot read properties of LEB %d, error %d", lnum, err); goto out; } @@ -865,13 +865,13 @@ int dbg_check_cats(struct ubifs_info *c) list_for_each_entry(lprops, &c->empty_list, list) { if (lprops->free != c->leb_size) { - ubifs_err("non-empty LEB %d on empty list (free %d dirty %d flags %d)", + ubifs_err(c, "non-empty LEB %d on empty list (free %d dirty %d flags %d)", lprops->lnum, lprops->free, lprops->dirty, lprops->flags); return -EINVAL; } if (lprops->flags & LPROPS_TAKEN) { - ubifs_err("taken LEB %d on empty list (free %d dirty %d flags %d)", + ubifs_err(c, "taken LEB %d on empty list (free %d dirty %d flags %d)", lprops->lnum, lprops->free, lprops->dirty, lprops->flags); return -EINVAL; @@ -881,13 +881,13 @@ int dbg_check_cats(struct ubifs_info *c) i = 0; list_for_each_entry(lprops, &c->freeable_list, list) { if (lprops->free + lprops->dirty != c->leb_size) { - ubifs_err("non-freeable LEB %d on freeable list (free %d dirty %d flags %d)", + ubifs_err(c, "non-freeable LEB %d on freeable list (free %d dirty %d flags %d)", lprops->lnum, lprops->free, lprops->dirty, lprops->flags); return -EINVAL; } if (lprops->flags & LPROPS_TAKEN) { - ubifs_err("taken LEB %d on freeable list (free %d dirty %d flags %d)", + ubifs_err(c, "taken LEB %d on freeable list (free %d dirty %d flags %d)", lprops->lnum, lprops->free, lprops->dirty, lprops->flags); return -EINVAL; @@ -895,7 +895,7 @@ int dbg_check_cats(struct ubifs_info *c) i += 1; } if (i != c->freeable_cnt) { - ubifs_err("freeable list count %d expected %d", i, + ubifs_err(c, "freeable list count %d expected %d", i, c->freeable_cnt); return -EINVAL; } @@ -904,26 +904,26 @@ int dbg_check_cats(struct ubifs_info *c) list_for_each(pos, &c->idx_gc) i += 1; if (i != c->idx_gc_cnt) { - ubifs_err("idx_gc list count %d expected %d", i, + ubifs_err(c, "idx_gc list count %d expected %d", i, c->idx_gc_cnt); return -EINVAL; } list_for_each_entry(lprops, &c->frdi_idx_list, list) { if (lprops->free + lprops->dirty != c->leb_size) { - ubifs_err("non-freeable LEB %d on frdi_idx list (free %d dirty %d flags %d)", + ubifs_err(c, "non-freeable LEB %d on frdi_idx list (free %d dirty %d flags %d)", lprops->lnum, lprops->free, lprops->dirty, lprops->flags); return -EINVAL; } if (lprops->flags & LPROPS_TAKEN) { - ubifs_err("taken LEB %d on frdi_idx list (free %d dirty %d flags %d)", + ubifs_err(c, "taken LEB %d on frdi_idx list (free %d dirty %d flags %d)", lprops->lnum, lprops->free, lprops->dirty, lprops->flags); return -EINVAL; } if (!(lprops->flags & LPROPS_INDEX)) { - ubifs_err("non-index LEB %d on frdi_idx list (free %d dirty %d flags %d)", + ubifs_err(c, "non-index LEB %d on frdi_idx list (free %d dirty %d flags %d)", lprops->lnum, lprops->free, lprops->dirty, lprops->flags); return -EINVAL; @@ -936,15 +936,15 @@ int dbg_check_cats(struct ubifs_info *c) for (i = 0; i < heap->cnt; i++) { lprops = heap->arr[i]; if (!lprops) { - ubifs_err("null ptr in LPT heap cat %d", cat); + ubifs_err(c, "null ptr in LPT heap cat %d", cat); return -EINVAL; } if (lprops->hpos != i) { - ubifs_err("bad ptr in LPT heap cat %d", cat); + ubifs_err(c, "bad ptr in LPT heap cat %d", cat); return -EINVAL; } if (lprops->flags & LPROPS_TAKEN) { - ubifs_err("taken LEB in LPT heap cat %d", cat); + ubifs_err(c, "taken LEB in LPT heap cat %d", cat); return -EINVAL; } } @@ -980,7 +980,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, goto out; } if (lprops != lp) { - ubifs_err("lprops %zx lp %zx lprops->lnum %d lp->lnum %d", + ubifs_err(c, "lprops %zx lp %zx lprops->lnum %d lp->lnum %d", (size_t)lprops, (size_t)lp, lprops->lnum, lp->lnum); err = 4; @@ -1000,7 +1000,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, } out: if (err) { - ubifs_err("failed cat %d hpos %d err %d", cat, i, err); + ubifs_err(c, "failed cat %d hpos %d err %d", cat, i, err); dump_stack(); ubifs_dump_heap(c, heap, cat); } @@ -1024,14 +1024,14 @@ static int scan_check_cb(struct ubifs_info *c, { struct ubifs_scan_leb *sleb; struct ubifs_scan_node *snod; - int cat, lnum = lp->lnum, is_idx = 0, used = 0, freef, dirty, ret; + int cat, lnum = lp->lnum, is_idx = 0, used = 0, free, dirty, ret; void *buf = NULL; cat = lp->flags & LPROPS_CAT_MASK; if (cat != LPROPS_UNCAT) { cat = ubifs_categorize_lprops(c, lp); if (cat != (lp->flags & LPROPS_CAT_MASK)) { - ubifs_err("bad LEB category %d expected %d", + ubifs_err(c, "bad LEB category %d expected %d", (lp->flags & LPROPS_CAT_MASK), cat); return -EINVAL; } @@ -1066,7 +1066,7 @@ static int scan_check_cb(struct ubifs_info *c, } } if (!found) { - ubifs_err("bad LPT list (category %d)", cat); + ubifs_err(c, "bad LPT list (category %d)", cat); return -EINVAL; } } @@ -1078,7 +1078,7 @@ static int scan_check_cb(struct ubifs_info *c, if ((lp->hpos != -1 && heap->arr[lp->hpos]->lnum != lnum) || lp != heap->arr[lp->hpos]) { - ubifs_err("bad LPT heap (category %d)", cat); + ubifs_err(c, "bad LPT heap (category %d)", cat); return -EINVAL; } } @@ -1125,7 +1125,7 @@ static int scan_check_cb(struct ubifs_info *c, is_idx = (snod->type == UBIFS_IDX_NODE) ? 1 : 0; if (is_idx && snod->type != UBIFS_IDX_NODE) { - ubifs_err("indexing node in data LEB %d:%d", + ubifs_err(c, "indexing node in data LEB %d:%d", lnum, snod->offs); goto out_destroy; } @@ -1146,20 +1146,20 @@ static int scan_check_cb(struct ubifs_info *c, } } - freef = c->leb_size - sleb->endpt; + free = c->leb_size - sleb->endpt; dirty = sleb->endpt - used; - if (freef > c->leb_size || freef < 0 || dirty > c->leb_size || + if (free > c->leb_size || free < 0 || dirty > c->leb_size || dirty < 0) { - ubifs_err("bad calculated accounting for LEB %d: free %d, dirty %d", - lnum, freef, dirty); + ubifs_err(c, "bad calculated accounting for LEB %d: free %d, dirty %d", + lnum, free, dirty); goto out_destroy; } if (lp->free + lp->dirty == c->leb_size && - freef + dirty == c->leb_size) + free + dirty == c->leb_size) if ((is_idx && !(lp->flags & LPROPS_INDEX)) || - (!is_idx && freef == c->leb_size) || + (!is_idx && free == c->leb_size) || lp->free == c->leb_size) { /* * Empty or freeable LEBs could contain index @@ -1168,12 +1168,12 @@ static int scan_check_cb(struct ubifs_info *c, * the same reason. Or it may simply not have been * unmapped. */ - freef = lp->free; + free = lp->free; dirty = lp->dirty; is_idx = 0; } - if (is_idx && lp->free + lp->dirty == freef + dirty && + if (is_idx && lp->free + lp->dirty == free + dirty && lnum != c->ihead_lnum) { /* * After an unclean unmount, an index LEB could have a different @@ -1186,41 +1186,41 @@ static int scan_check_cb(struct ubifs_info *c, * write to the free space at the end of an index LEB - except * by the in-the-gaps method for which it is not a problem. */ - freef = lp->free; + free = lp->free; dirty = lp->dirty; } - if (lp->free != freef || lp->dirty != dirty) + if (lp->free != free || lp->dirty != dirty) goto out_print; if (is_idx && !(lp->flags & LPROPS_INDEX)) { - if (freef == c->leb_size) + if (free == c->leb_size) /* Free but not unmapped LEB, it's fine */ is_idx = 0; else { - ubifs_err("indexing node without indexing flag"); + ubifs_err(c, "indexing node without indexing flag"); goto out_print; } } if (!is_idx && (lp->flags & LPROPS_INDEX)) { - ubifs_err("data node with indexing flag"); + ubifs_err(c, "data node with indexing flag"); goto out_print; } - if (freef == c->leb_size) + if (free == c->leb_size) lst->empty_lebs += 1; if (is_idx) lst->idx_lebs += 1; if (!(lp->flags & LPROPS_INDEX)) - lst->total_used += c->leb_size - freef - dirty; - lst->total_free += freef; + lst->total_used += c->leb_size - free - dirty; + lst->total_free += free; lst->total_dirty += dirty; if (!(lp->flags & LPROPS_INDEX)) { - int spc = freef + dirty; + int spc = free + dirty; if (spc < c->dead_wm) lst->total_dead += spc; @@ -1233,8 +1233,8 @@ static int scan_check_cb(struct ubifs_info *c, return LPT_SCAN_CONTINUE; out_print: - ubifs_err("bad accounting of LEB %d: free %d, dirty %d flags %#x, should be free %d, dirty %d", - lnum, lp->free, lp->dirty, lp->flags, freef, dirty); + ubifs_err(c, "bad accounting of LEB %d: free %d, dirty %d flags %#x, should be free %d, dirty %d", + lnum, lp->free, lp->dirty, lp->flags, free, dirty); ubifs_dump_leb(c, lnum); out_destroy: ubifs_scan_destroy(sleb); @@ -1285,11 +1285,11 @@ int dbg_check_lprops(struct ubifs_info *c) lst.total_free != c->lst.total_free || lst.total_dirty != c->lst.total_dirty || lst.total_used != c->lst.total_used) { - ubifs_err("bad overall accounting"); - ubifs_err("calculated: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld", + ubifs_err(c, "bad overall accounting"); + ubifs_err(c, "calculated: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld", lst.empty_lebs, lst.idx_lebs, lst.total_free, lst.total_dirty, lst.total_used); - ubifs_err("read from lprops: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld", + ubifs_err(c, "read from lprops: empty_lebs %d, idx_lebs %d, total_free %lld, total_dirty %lld, total_used %lld", c->lst.empty_lebs, c->lst.idx_lebs, c->lst.total_free, c->lst.total_dirty, c->lst.total_used); err = -EINVAL; @@ -1298,10 +1298,10 @@ int dbg_check_lprops(struct ubifs_info *c) if (lst.total_dead != c->lst.total_dead || lst.total_dark != c->lst.total_dark) { - ubifs_err("bad dead/dark space accounting"); - ubifs_err("calculated: total_dead %lld, total_dark %lld", + ubifs_err(c, "bad dead/dark space accounting"); + ubifs_err(c, "calculated: total_dead %lld, total_dark %lld", lst.total_dead, lst.total_dark); - ubifs_err("read from lprops: total_dead %lld, total_dark %lld", + ubifs_err(c, "read from lprops: total_dead %lld, total_dark %lld", c->lst.total_dead, c->lst.total_dark); err = -EINVAL; goto out; diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index 8489e90e4a3..b22b63b9438 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c @@ -141,13 +141,13 @@ int ubifs_calc_lpt_geom(struct ubifs_info *c) sz = c->lpt_sz * 2; /* Must have at least 2 times the size */ lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size); if (lebs_needed > c->lpt_lebs) { - ubifs_err("too few LPT LEBs"); + ubifs_err(c, "too few LPT LEBs"); return -EINVAL; } /* Verify that ltab fits in a single LEB (since ltab is a single node */ if (c->ltab_sz > c->leb_size) { - ubifs_err("LPT ltab too big"); + ubifs_err(c, "LPT ltab too big"); return -EINVAL; } @@ -209,7 +209,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs, continue; } if (c->ltab_sz > c->leb_size) { - ubifs_err("LPT ltab too big"); + ubifs_err(c, "LPT ltab too big"); return -EINVAL; } *main_lebs = c->main_lebs; @@ -907,7 +907,7 @@ static void replace_cats(struct ubifs_info *c, struct ubifs_pnode *old_pnode, * * This function returns %0 on success and a negative error code on failure. */ -static int check_lpt_crc(void *buf, int len) +static int check_lpt_crc(const struct ubifs_info *c, void *buf, int len) { int pos = 0; uint8_t *addr = buf; @@ -917,8 +917,8 @@ static int check_lpt_crc(void *buf, int len) calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, len - UBIFS_LPT_CRC_BYTES); if (crc != calc_crc) { - ubifs_err("invalid crc in LPT node: crc %hx calc %hx", crc, - calc_crc); + ubifs_err(c, "invalid crc in LPT node: crc %hx calc %hx", + crc, calc_crc); dump_stack(); return -EINVAL; } @@ -934,14 +934,15 @@ static int check_lpt_crc(void *buf, int len) * * This function returns %0 on success and a negative error code on failure. */ -static int check_lpt_type(uint8_t **addr, int *pos, int type) +static int check_lpt_type(const struct ubifs_info *c, uint8_t **addr, + int *pos, int type) { int node_type; node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS); if (node_type != type) { - ubifs_err("invalid type (%d) in LPT node type %d", node_type, - type); + ubifs_err(c, "invalid type (%d) in LPT node type %d", + node_type, type); dump_stack(); return -EINVAL; } @@ -962,7 +963,7 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf, uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; int i, pos = 0, err; - err = check_lpt_type(&addr, &pos, UBIFS_LPT_PNODE); + err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_PNODE); if (err) return err; if (c->big_lpt) @@ -981,7 +982,7 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf, lprops->flags = 0; lprops->flags |= ubifs_categorize_lprops(c, lprops); } - err = check_lpt_crc(buf, c->pnode_sz); + err = check_lpt_crc(c, buf, c->pnode_sz); return err; } @@ -999,7 +1000,7 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; int i, pos = 0, err; - err = check_lpt_type(&addr, &pos, UBIFS_LPT_NNODE); + err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_NNODE); if (err) return err; if (c->big_lpt) @@ -1015,7 +1016,7 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos, c->lpt_offs_bits); } - err = check_lpt_crc(buf, c->nnode_sz); + err = check_lpt_crc(c, buf, c->nnode_sz); return err; } @@ -1031,7 +1032,7 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf) uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; int i, pos = 0, err; - err = check_lpt_type(&addr, &pos, UBIFS_LPT_LTAB); + err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_LTAB); if (err) return err; for (i = 0; i < c->lpt_lebs; i++) { @@ -1047,7 +1048,7 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf) c->ltab[i].tgc = 0; c->ltab[i].cmt = 0; } - err = check_lpt_crc(buf, c->ltab_sz); + err = check_lpt_crc(c, buf, c->ltab_sz); return err; } @@ -1064,7 +1065,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf) uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; int i, pos = 0, err; - err = check_lpt_type(&addr, &pos, UBIFS_LPT_LSAVE); + err = check_lpt_type(c, &addr, &pos, UBIFS_LPT_LSAVE); if (err) return err; for (i = 0; i < c->lsave_cnt; i++) { @@ -1074,7 +1075,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf) return -EINVAL; c->lsave[i] = lnum; } - err = check_lpt_crc(buf, c->lsave_sz); + err = check_lpt_crc(c, buf, c->lsave_sz); return err; } #endif @@ -1241,7 +1242,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) return 0; out: - ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs); + ubifs_err(c, "error %d reading nnode at %d:%d", err, lnum, offs); dump_stack(); kfree(nnode); return err; @@ -1306,10 +1307,10 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) return 0; out: - ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs); + ubifs_err(c, "error %d reading pnode at %d:%d", err, lnum, offs); ubifs_dump_pnode(c, pnode, parent, iip); dump_stack(); - ubifs_err("calc num: %d", calc_pnode_num_from_parent(c, parent, iip)); + ubifs_err(c, "calc num: %d", calc_pnode_num_from_parent(c, parent, iip)); kfree(pnode); return err; } @@ -1464,7 +1465,6 @@ struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum) return ERR_CAST(nnode); } iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); - shft -= UBIFS_LPT_FANOUT_SHIFT; pnode = ubifs_get_pnode(c, nnode, iip); if (IS_ERR(pnode)) return ERR_CAST(pnode); @@ -1604,7 +1604,6 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum) return ERR_CAST(nnode); } iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); - shft -= UBIFS_LPT_FANOUT_SHIFT; pnode = ubifs_get_pnode(c, nnode, iip); if (IS_ERR(pnode)) return ERR_CAST(pnode); @@ -1970,7 +1969,6 @@ again: } } iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1)); - shft -= UBIFS_LPT_FANOUT_SHIFT; pnode = scan_get_pnode(c, path + h, nnode, iip); if (IS_ERR(pnode)) { err = PTR_ERR(pnode); @@ -2104,7 +2102,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, int i; if (pnode->num != col) { - ubifs_err("pnode num %d expected %d parent num %d iip %d", + ubifs_err(c, "pnode num %d expected %d parent num %d iip %d", pnode->num, col, pnode->parent->num, pnode->iip); return -EINVAL; } @@ -2119,13 +2117,13 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, if (lnum >= c->leb_cnt) continue; if (lprops->lnum != lnum) { - ubifs_err("bad LEB number %d expected %d", + ubifs_err(c, "bad LEB number %d expected %d", lprops->lnum, lnum); return -EINVAL; } if (lprops->flags & LPROPS_TAKEN) { if (cat != LPROPS_UNCAT) { - ubifs_err("LEB %d taken but not uncat %d", + ubifs_err(c, "LEB %d taken but not uncat %d", lprops->lnum, cat); return -EINVAL; } @@ -2138,7 +2136,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, case LPROPS_FRDI_IDX: break; default: - ubifs_err("LEB %d index but cat %d", + ubifs_err(c, "LEB %d index but cat %d", lprops->lnum, cat); return -EINVAL; } @@ -2151,7 +2149,7 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, case LPROPS_FREEABLE: break; default: - ubifs_err("LEB %d not index but cat %d", + ubifs_err(c, "LEB %d not index but cat %d", lprops->lnum, cat); return -EINVAL; } @@ -2192,26 +2190,28 @@ static int dbg_chk_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, break; } if (!found) { - ubifs_err("LEB %d cat %d not found in cat heap/list", + ubifs_err(c, "LEB %d cat %d not found in cat heap/list", lprops->lnum, cat); return -EINVAL; } switch (cat) { case LPROPS_EMPTY: if (lprops->free != c->leb_size) { - ubifs_err("LEB %d cat %d free %d dirty %d", + ubifs_err(c, "LEB %d cat %d free %d dirty %d", lprops->lnum, cat, lprops->free, lprops->dirty); return -EINVAL; } + break; case LPROPS_FREEABLE: case LPROPS_FRDI_IDX: if (lprops->free + lprops->dirty != c->leb_size) { - ubifs_err("LEB %d cat %d free %d dirty %d", + ubifs_err(c, "LEB %d cat %d free %d dirty %d", lprops->lnum, cat, lprops->free, lprops->dirty); return -EINVAL; } + break; } } return 0; @@ -2243,7 +2243,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, /* cnode is a nnode */ num = calc_nnode_num(row, col); if (cnode->num != num) { - ubifs_err("nnode num %d expected %d parent num %d iip %d", + ubifs_err(c, "nnode num %d expected %d parent num %d iip %d", cnode->num, num, (nnode ? nnode->num : 0), cnode->iip); return -EINVAL; diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index c818d4ca5af..2df9130efd1 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c @@ -301,7 +301,6 @@ static int layout_cnodes(struct ubifs_info *c) ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last); } - done_ltab = 1; c->ltab_lnum = lnum; c->ltab_offs = offs; offs += c->ltab_sz; @@ -317,7 +316,7 @@ static int layout_cnodes(struct ubifs_info *c) return 0; no_space: - ubifs_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, done_lsave %d", + ubifs_err(c, "LPT out of space at LEB %d:%d needing %d, done_ltab %d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave); ubifs_dump_lpt_info(c); ubifs_dump_lpt_lebs(c); @@ -458,9 +457,9 @@ static int write_cnodes(struct ubifs_info *c) * important. */ clear_bit(DIRTY_CNODE, &cnode->flags); - smp_mb__before_clear_bit(); + smp_mb__before_atomic(); clear_bit(COW_CNODE, &cnode->flags); - smp_mb__after_clear_bit(); + smp_mb__after_atomic(); offs += len; dbg_chk_lpt_sz(c, 1, len); cnode = cnode->cnext; @@ -512,7 +511,6 @@ static int write_cnodes(struct ubifs_info *c) if (err) return err; } - done_ltab = 1; ubifs_pack_ltab(c, buf + offs, c->ltab_cmt); offs += c->ltab_sz; dbg_chk_lpt_sz(c, 1, c->ltab_sz); @@ -543,7 +541,7 @@ static int write_cnodes(struct ubifs_info *c) return 0; no_space: - ubifs_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab %d, done_lsave %d", + ubifs_err(c, "LPT out of space mismatch at LEB %d:%d needing %d, done_ltab %d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave); ubifs_dump_lpt_info(c); ubifs_dump_lpt_lebs(c); @@ -1644,7 +1642,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); if (!buf) { - ubifs_err("cannot allocate memory for ltab checking"); + ubifs_err(c, "cannot allocate memory for ltab checking"); return 0; } @@ -1666,18 +1664,18 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) continue; } if (!dbg_is_all_ff(p, len)) { - ubifs_err("invalid empty space in LEB %d at %d", + ubifs_err(c, "invalid empty space in LEB %d at %d", lnum, c->leb_size - len); err = -EINVAL; } i = lnum - c->lpt_first; if (len != c->ltab[i].free) { - ubifs_err("invalid free space in LEB %d (free %d, expected %d)", + ubifs_err(c, "invalid free space in LEB %d (free %d, expected %d)", lnum, len, c->ltab[i].free); err = -EINVAL; } if (dirty != c->ltab[i].dirty) { - ubifs_err("invalid dirty space in LEB %d (dirty %d, expected %d)", + ubifs_err(c, "invalid dirty space in LEB %d (dirty %d, expected %d)", lnum, dirty, c->ltab[i].dirty); err = -EINVAL; } @@ -1731,7 +1729,7 @@ int dbg_check_ltab(struct ubifs_info *c) for (lnum = c->lpt_first; lnum <= c->lpt_last; lnum++) { err = dbg_check_ltab_lnum(c, lnum); if (err) { - ubifs_err("failed at LEB %d", lnum); + ubifs_err(c, "failed at LEB %d", lnum); return err; } } @@ -1763,7 +1761,7 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c) free += c->leb_size; } if (free < c->lpt_sz) { - ubifs_err("LPT space error: free %lld lpt_sz %lld", + ubifs_err(c, "LPT space error: free %lld lpt_sz %lld", free, c->lpt_sz); ubifs_dump_lpt_info(c); ubifs_dump_lpt_lebs(c); @@ -1803,12 +1801,12 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) d->chk_lpt_lebs = 0; d->chk_lpt_wastage = 0; if (c->dirty_pn_cnt > c->pnode_cnt) { - ubifs_err("dirty pnodes %d exceed max %d", + ubifs_err(c, "dirty pnodes %d exceed max %d", c->dirty_pn_cnt, c->pnode_cnt); err = -EINVAL; } if (c->dirty_nn_cnt > c->nnode_cnt) { - ubifs_err("dirty nnodes %d exceed max %d", + ubifs_err(c, "dirty nnodes %d exceed max %d", c->dirty_nn_cnt, c->nnode_cnt); err = -EINVAL; } @@ -1826,22 +1824,22 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) chk_lpt_sz *= d->chk_lpt_lebs; chk_lpt_sz += len - c->nhead_offs; if (d->chk_lpt_sz != chk_lpt_sz) { - ubifs_err("LPT wrote %lld but space used was %lld", + ubifs_err(c, "LPT wrote %lld but space used was %lld", d->chk_lpt_sz, chk_lpt_sz); err = -EINVAL; } if (d->chk_lpt_sz > c->lpt_sz) { - ubifs_err("LPT wrote %lld but lpt_sz is %lld", + ubifs_err(c, "LPT wrote %lld but lpt_sz is %lld", d->chk_lpt_sz, c->lpt_sz); err = -EINVAL; } if (d->chk_lpt_sz2 && d->chk_lpt_sz != d->chk_lpt_sz2) { - ubifs_err("LPT layout size %lld but wrote %lld", + ubifs_err(c, "LPT layout size %lld but wrote %lld", d->chk_lpt_sz, d->chk_lpt_sz2); err = -EINVAL; } if (d->chk_lpt_sz2 && d->new_nhead_offs != len) { - ubifs_err("LPT new nhead offs: expected %d was %d", + ubifs_err(c, "LPT new nhead offs: expected %d was %d", d->new_nhead_offs, len); err = -EINVAL; } @@ -1851,7 +1849,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) if (c->big_lpt) lpt_sz += c->lsave_sz; if (d->chk_lpt_sz - d->chk_lpt_wastage > lpt_sz) { - ubifs_err("LPT chk_lpt_sz %lld + waste %lld exceeds %lld", + ubifs_err(c, "LPT chk_lpt_sz %lld + waste %lld exceeds %lld", d->chk_lpt_sz, d->chk_lpt_wastage, lpt_sz); err = -EINVAL; } @@ -1893,7 +1891,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum) pr_err("(pid %d) start dumping LEB %d\n", current->pid, lnum); buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); if (!buf) { - ubifs_err("cannot allocate memory to dump LPT"); + ubifs_err(c, "cannot allocate memory to dump LPT"); return; } @@ -1945,6 +1943,11 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum) pr_err("LEB %d:%d, nnode, ", lnum, offs); err = ubifs_unpack_nnode(c, p, &nnode); + if (err) { + pr_err("failed to unpack_node, error %d\n", + err); + break; + } for (i = 0; i < UBIFS_LPT_FANOUT; i++) { pr_cont("%d:%d", nnode.nbranch[i].lnum, nnode.nbranch[i].offs); @@ -1963,7 +1966,7 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum) pr_err("LEB %d:%d, lsave len\n", lnum, offs); break; default: - ubifs_err("LPT node type %d not recognized", node_type); + ubifs_err(c, "LPT node type %d not recognized", node_type); goto out; } diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c index 761e0704e4a..4dd0bbb2d3f 100644 --- a/fs/ubifs/master.c +++ b/fs/ubifs/master.c @@ -76,7 +76,7 @@ out: return -EUCLEAN; out_dump: - ubifs_err("unexpected node type %d master LEB %d:%d", + ubifs_err(c, "unexpected node type %d master LEB %d:%d", snod->type, lnum, snod->offs); ubifs_scan_destroy(sleb); return -EINVAL; @@ -234,7 +234,7 @@ static int validate_master(const struct ubifs_info *c) return 0; out: - ubifs_err("bad master node at offset %d error %d", c->mst_offs, err); + ubifs_err(c, "bad master node at offset %d error %d", c->mst_offs, err); ubifs_dump_node(c, c->mst_node); return -EINVAL; } @@ -310,7 +310,7 @@ int ubifs_read_master(struct ubifs_info *c) if (c->leb_cnt < old_leb_cnt || c->leb_cnt < UBIFS_MIN_LEB_CNT) { - ubifs_err("bad leb_cnt on master node"); + ubifs_err(c, "bad leb_cnt on master node"); ubifs_dump_node(c, c->mst_node); return -EINVAL; } @@ -349,10 +349,9 @@ int ubifs_read_master(struct ubifs_info *c) * ubifs_write_master - write master node. * @c: UBIFS file-system description object * - * This function writes the master node. The caller has to take the - * @c->mst_mutex lock before calling this function. Returns zero in case of - * success and a negative error code in case of failure. The master node is - * written twice to enable recovery. + * This function writes the master node. Returns zero in case of success and a + * negative error code in case of failure. The master node is written twice to + * enable recovery. */ int ubifs_write_master(struct ubifs_info *c) { diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 4e42879b5d6..f5c8e23d0b3 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -78,7 +78,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) else if (inum > o->inum) p = &(*p)->rb_right; else { - ubifs_err("orphaned twice"); + ubifs_err(c, "orphaned twice"); spin_unlock(&c->orphan_lock); kfree(orphan); return 0; @@ -145,7 +145,7 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) } } spin_unlock(&c->orphan_lock); - ubifs_err("missing orphan ino %lu", (unsigned long)inum); + ubifs_err(c, "missing orphan ino %lu", (unsigned long)inum); dump_stack(); } @@ -277,7 +277,7 @@ static int write_orph_node(struct ubifs_info *c, int atomic) * We limit the number of orphans so that this should * never happen. */ - ubifs_err("out of space in orphan area"); + ubifs_err(c, "out of space in orphan area"); return -EINVAL; } } @@ -336,7 +336,6 @@ static int write_orph_nodes(struct ubifs_info *c, int atomic) int lnum; /* Unmap any unused LEBs after consolidation */ - lnum = c->ohead_lnum + 1; for (lnum = c->ohead_lnum + 1; lnum <= c->orph_last; lnum++) { err = ubifs_leb_unmap(c, lnum); if (err) @@ -388,7 +387,7 @@ static int consolidate(struct ubifs_info *c) * We limit the number of orphans so that this should * never happen. */ - ubifs_err("out of space in orphan area"); + ubifs_err(c, "out of space in orphan area"); err = -EINVAL; } spin_unlock(&c->orphan_lock); @@ -560,7 +559,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, list_for_each_entry(snod, &sleb->nodes, list) { if (snod->type != UBIFS_ORPH_NODE) { - ubifs_err("invalid node type %d in orphan area at %d:%d", + ubifs_err(c, "invalid node type %d in orphan area at %d:%d", snod->type, sleb->lnum, snod->offs); ubifs_dump_node(c, snod->node); return -EINVAL; @@ -587,7 +586,7 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb, * number. That makes this orphan node, out of date. */ if (!first) { - ubifs_err("out of order commit number %llu in orphan node at %d:%d", + ubifs_err(c, "out of order commit number %llu in orphan node at %d:%d", cmt_no, sleb->lnum, snod->offs); ubifs_dump_node(c, snod->node); return -EINVAL; @@ -822,20 +821,20 @@ static int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr, if (inum != ci->last_ino) { /* Lowest node type is the inode node, so it comes first */ if (key_type(c, &zbr->key) != UBIFS_INO_KEY) - ubifs_err("found orphan node ino %lu, type %d", + ubifs_err(c, "found orphan node ino %lu, type %d", (unsigned long)inum, key_type(c, &zbr->key)); ci->last_ino = inum; ci->tot_inos += 1; err = ubifs_tnc_read_node(c, zbr, ci->node); if (err) { - ubifs_err("node read failed, error %d", err); + ubifs_err(c, "node read failed, error %d", err); return err; } if (ci->node->nlink == 0) /* Must be recorded as an orphan */ if (!dbg_find_check_orphan(&ci->root, inum) && !dbg_find_orphan(c, inum)) { - ubifs_err("missing orphan, ino %lu", + ubifs_err(c, "missing orphan, ino %lu", (unsigned long)inum); ci->missing += 1; } @@ -878,7 +877,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci) buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); if (!buf) { - ubifs_err("cannot allocate memory to check orphans"); + ubifs_err(c, "cannot allocate memory to check orphans"); return 0; } @@ -916,7 +915,7 @@ static int dbg_check_orphans(struct ubifs_info *c) ci.root = RB_ROOT; ci.node = kmalloc(UBIFS_MAX_INO_NODE_SZ, GFP_NOFS); if (!ci.node) { - ubifs_err("out of memory"); + ubifs_err(c, "out of memory"); return -ENOMEM; } @@ -926,12 +925,12 @@ static int dbg_check_orphans(struct ubifs_info *c) err = dbg_walk_index(c, &dbg_orphan_check, NULL, &ci); if (err) { - ubifs_err("cannot scan TNC, error %d", err); + ubifs_err(c, "cannot scan TNC, error %d", err); goto out; } if (ci.missing) { - ubifs_err("%lu missing orphan(s)", ci.missing); + ubifs_err(c, "%lu missing orphan(s)", ci.missing); err = -EINVAL; goto out; } diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 763770738b7..386a9c5e54a 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c @@ -298,7 +298,7 @@ int ubifs_recover_master_node(struct ubifs_info *c) mst = mst2; } - ubifs_msg("recovered master node from LEB %d", + ubifs_msg(c, "recovered master node from LEB %d", (mst == mst1 ? UBIFS_MST_LNUM : UBIFS_MST_LNUM + 1)); memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ); @@ -355,13 +355,13 @@ int ubifs_recover_master_node(struct ubifs_info *c) out_err: err = -EINVAL; out_free: - ubifs_err("failed to recover master node"); + ubifs_err(c, "failed to recover master node"); if (mst1) { - ubifs_err("dumping first master node"); + ubifs_err(c, "dumping first master node"); ubifs_dump_node(c, mst1); } if (mst2) { - ubifs_err("dumping second master node"); + ubifs_err(c, "dumping second master node"); ubifs_dump_node(c, mst2); } vfree(buf2); @@ -593,7 +593,6 @@ static void drop_last_group(struct ubifs_scan_leb *sleb, int *offs) * drop_last_node - drop the last node. * @sleb: scanned LEB information * @offs: offset of dropped nodes is returned here - * @grouped: non-zero if whole group of nodes have to be dropped * * This is a helper function for 'ubifs_recover_leb()' which drops the last * node of the scanned LEB. @@ -626,8 +625,8 @@ static void drop_last_node(struct ubifs_scan_leb *sleb, int *offs) * * This function does a scan of a LEB, but caters for errors that might have * been caused by the unclean unmount from which we are attempting to recover. - * Returns %0 in case of success, %-EUCLEAN if an unrecoverable corruption is - * found, and a negative error code in case of failure. + * Returns the scanned information on success and a negative error code on + * failure. */ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf, int jhead) @@ -680,7 +679,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, ret, lnum, offs); break; } else { - ubifs_err("unexpected return value %d", ret); + ubifs_err(c, "unexpected return value %d", ret); err = -EINVAL; goto error; } @@ -700,7 +699,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, * See header comment for this file for more * explanations about the reasons we have this check. */ - ubifs_err("corrupt empty space LEB %d:%d, corruption starts at %d", + ubifs_err(c, "corrupt empty space LEB %d:%d, corruption starts at %d", lnum, offs, corruption); /* Make sure we dump interesting non-0xFF data */ offs += corruption; @@ -786,13 +785,13 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, corrupted_rescan: /* Re-scan the corrupted data with verbose messages */ - ubifs_err("corruption %d", ret); + ubifs_err(c, "corruption %d", ret); ubifs_scan_a_node(c, buf, len, lnum, offs, 1); corrupted: ubifs_scanned_corruption(c, lnum, offs, buf); err = -EUCLEAN; error: - ubifs_err("LEB %d scanning failed", lnum); + ubifs_err(c, "LEB %d scanning failed", lnum); ubifs_scan_destroy(sleb); return ERR_PTR(err); } @@ -824,15 +823,15 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs, goto out_free; ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0); if (ret != SCANNED_A_NODE) { - ubifs_err("Not a valid node"); + ubifs_err(c, "Not a valid node"); goto out_err; } if (cs_node->ch.node_type != UBIFS_CS_NODE) { - ubifs_err("Node a CS node, type is %d", cs_node->ch.node_type); + ubifs_err(c, "Node a CS node, type is %d", cs_node->ch.node_type); goto out_err; } if (le64_to_cpu(cs_node->cmt_no) != c->cmt_no) { - ubifs_err("CS node cmt_no %llu != current cmt_no %llu", + ubifs_err(c, "CS node cmt_no %llu != current cmt_no %llu", (unsigned long long)le64_to_cpu(cs_node->cmt_no), c->cmt_no); goto out_err; @@ -845,7 +844,7 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs, out_err: err = -EINVAL; out_free: - ubifs_err("failed to get CS sqnum"); + ubifs_err(c, "failed to get CS sqnum"); kfree(cs_node); return err; } @@ -897,7 +896,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, } } if (snod->sqnum > cs_sqnum) { - ubifs_err("unrecoverable log corruption in LEB %d", + ubifs_err(c, "unrecoverable log corruption in LEB %d", lnum); ubifs_scan_destroy(sleb); return ERR_PTR(-EUCLEAN); @@ -973,11 +972,8 @@ int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf) return err; dbg_rcvry("checking LPT head at %d:%d", c->nhead_lnum, c->nhead_offs); - err = recover_head(c, c->nhead_lnum, c->nhead_offs, sbuf); - if (err) - return err; - return 0; + return recover_head(c, c->nhead_lnum, c->nhead_offs, sbuf); } /** @@ -1002,10 +998,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c, if (len == 0) { /* Nothing to read, just unmap it */ - err = ubifs_leb_unmap(c, lnum); - if (err) - return err; - return 0; + return ubifs_leb_unmap(c, lnum); } err = ubifs_leb_read(c, lnum, buf, offs, len, 0); @@ -1041,7 +1034,7 @@ static int clean_an_unclean_leb(struct ubifs_info *c, } if (ret == SCANNED_EMPTY_SPACE) { - ubifs_err("unexpected empty space at %d:%d", + ubifs_err(c, "unexpected empty space at %d:%d", lnum, offs); return -EUCLEAN; } @@ -1136,7 +1129,7 @@ static int grab_empty_leb(struct ubifs_info *c) */ lnum = ubifs_find_free_leb_for_idx(c); if (lnum < 0) { - ubifs_err("could not find an empty LEB"); + ubifs_err(c, "could not find an empty LEB"); ubifs_dump_lprops(c); ubifs_dump_budg(c, &c->bi); return lnum; @@ -1216,7 +1209,7 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c) } mutex_unlock(&wbuf->io_mutex); if (err < 0) { - ubifs_err("GC failed, error %d", err); + ubifs_err(c, "GC failed, error %d", err); if (err == -EAGAIN) err = -EINVAL; return err; @@ -1470,7 +1463,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e) return 0; out: - ubifs_warn("inode %lu failed to fix size %lld -> %lld error %d", + ubifs_warn(c, "inode %lu failed to fix size %lld -> %lld error %d", (unsigned long)e->inum, e->i_size, e->d_size, err); return err; } diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 1064cb29ba8..d0fcd83058f 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c @@ -451,13 +451,13 @@ int ubifs_validate_entry(struct ubifs_info *c, nlen > UBIFS_MAX_NLEN || dent->name[nlen] != 0 || strnlen(dent->name, nlen) != nlen || le64_to_cpu(dent->inum) > MAX_INUM) { - ubifs_err("bad %s node", key_type == UBIFS_DENT_KEY ? + ubifs_err(c, "bad %s node", key_type == UBIFS_DENT_KEY ? "directory entry" : "extended attribute entry"); return -EINVAL; } if (key_type != UBIFS_DENT_KEY && key_type != UBIFS_XENT_KEY) { - ubifs_err("bad key type %d", key_type); + ubifs_err(c, "bad key type %d", key_type); return -EINVAL; } @@ -582,7 +582,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) cond_resched(); if (snod->sqnum >= SQNUM_WATERMARK) { - ubifs_err("file system's life ended"); + ubifs_err(c, "file system's life ended"); goto out_dump; } @@ -640,7 +640,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) if (old_size < 0 || old_size > c->max_inode_sz || new_size < 0 || new_size > c->max_inode_sz || old_size <= new_size) { - ubifs_err("bad truncation node"); + ubifs_err(c, "bad truncation node"); goto out_dump; } @@ -655,7 +655,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) break; } default: - ubifs_err("unexpected node type %d in bud LEB %d:%d", + ubifs_err(c, "unexpected node type %d in bud LEB %d:%d", snod->type, lnum, snod->offs); err = -EINVAL; goto out_dump; @@ -678,7 +678,7 @@ out: return err; out_dump: - ubifs_err("bad node is at LEB %d:%d", lnum, snod->offs); + ubifs_err(c, "bad node is at LEB %d:%d", lnum, snod->offs); ubifs_dump_node(c, snod->node); ubifs_scan_destroy(sleb); return -EINVAL; @@ -798,7 +798,7 @@ static int validate_ref(struct ubifs_info *c, const struct ubifs_ref_node *ref) if (bud) { if (bud->jhead == jhead && bud->start <= offs) return 1; - ubifs_err("bud at LEB %d:%d was already referred", lnum, offs); + ubifs_err(c, "bud at LEB %d:%d was already referred", lnum, offs); return -EINVAL; } @@ -854,12 +854,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) * numbers. */ if (snod->type != UBIFS_CS_NODE) { - ubifs_err("first log node at LEB %d:%d is not CS node", + ubifs_err(c, "first log node at LEB %d:%d is not CS node", lnum, offs); goto out_dump; } if (le64_to_cpu(node->cmt_no) != c->cmt_no) { - ubifs_err("first CS node at LEB %d:%d has wrong commit number %llu expected %llu", + ubifs_err(c, "first CS node at LEB %d:%d has wrong commit number %llu expected %llu", lnum, offs, (unsigned long long)le64_to_cpu(node->cmt_no), c->cmt_no); @@ -884,7 +884,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) /* Make sure the first node sits at offset zero of the LEB */ if (snod->offs != 0) { - ubifs_err("first node is not at zero offset"); + ubifs_err(c, "first node is not at zero offset"); goto out_dump; } @@ -892,12 +892,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) cond_resched(); if (snod->sqnum >= SQNUM_WATERMARK) { - ubifs_err("file system's life ended"); + ubifs_err(c, "file system's life ended"); goto out_dump; } if (snod->sqnum < c->cs_sqnum) { - ubifs_err("bad sqnum %llu, commit sqnum %llu", + ubifs_err(c, "bad sqnum %llu, commit sqnum %llu", snod->sqnum, c->cs_sqnum); goto out_dump; } @@ -927,12 +927,12 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) case UBIFS_CS_NODE: /* Make sure it sits at the beginning of LEB */ if (snod->offs != 0) { - ubifs_err("unexpected node in log"); + ubifs_err(c, "unexpected node in log"); goto out_dump; } break; default: - ubifs_err("unexpected node in log"); + ubifs_err(c, "unexpected node in log"); goto out_dump; } } @@ -948,7 +948,7 @@ out: return err; out_dump: - ubifs_err("log error detected while replaying the log at LEB %d:%d", + ubifs_err(c, "log error detected while replaying the log at LEB %d:%d", lnum, offs + snod->offs); ubifs_dump_node(c, snod->node); ubifs_scan_destroy(sleb); @@ -1010,7 +1010,7 @@ int ubifs_replay_journal(struct ubifs_info *c) return free; /* Error code */ if (c->ihead_offs != c->leb_size - free) { - ubifs_err("bad index head LEB %d:%d", c->ihead_lnum, + ubifs_err(c, "bad index head LEB %d:%d", c->ihead_lnum, c->ihead_offs); return -EINVAL; } @@ -1021,9 +1021,22 @@ int ubifs_replay_journal(struct ubifs_info *c) do { err = replay_log_leb(c, lnum, 0, c->sbuf); - if (err == 1) - /* We hit the end of the log */ - break; + if (err == 1) { + if (lnum != c->lhead_lnum) + /* We hit the end of the log */ + break; + + /* + * The head of the log must always start with the + * "commit start" node on a properly formatted UBIFS. + * But we found no nodes at all, which means that + * someting went wrong and we cannot proceed mounting + * the file-system. + */ + ubifs_err(c, "no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted", + lnum, 0); + err = -EINVAL; + } if (err) goto out; lnum = ubifs_next_log_lnum(c, lnum); diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index 4983bf62897..7c7d92a6031 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c @@ -330,8 +330,10 @@ static int create_default_filesystem(struct ubifs_info *c) cs->ch.node_type = UBIFS_CS_NODE; err = ubifs_write_node(c, cs, UBIFS_CS_NODE_SZ, UBIFS_LOG_LNUM, 0); kfree(cs); + if (err) + return err; - ubifs_msg("default file-system created"); + ubifs_msg(c, "default file-system created"); return 0; } #endif @@ -362,13 +364,13 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) } if (le32_to_cpu(sup->min_io_size) != c->min_io_size) { - ubifs_err("min. I/O unit mismatch: %d in superblock, %d real", + ubifs_err(c, "min. I/O unit mismatch: %d in superblock, %d real", le32_to_cpu(sup->min_io_size), c->min_io_size); goto failed; } if (le32_to_cpu(sup->leb_size) != c->leb_size) { - ubifs_err("LEB size mismatch: %d in superblock, %d real", + ubifs_err(c, "LEB size mismatch: %d in superblock, %d real", le32_to_cpu(sup->leb_size), c->leb_size); goto failed; } @@ -390,33 +392,33 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) min_leb_cnt += c->lpt_lebs + c->orph_lebs + c->jhead_cnt + 6; if (c->leb_cnt < min_leb_cnt || c->leb_cnt > c->vi.size) { - ubifs_err("bad LEB count: %d in superblock, %d on UBI volume, %d minimum required", + ubifs_err(c, "bad LEB count: %d in superblock, %d on UBI volume, %d minimum required", c->leb_cnt, c->vi.size, min_leb_cnt); goto failed; } if (c->max_leb_cnt < c->leb_cnt) { - ubifs_err("max. LEB count %d less than LEB count %d", + ubifs_err(c, "max. LEB count %d less than LEB count %d", c->max_leb_cnt, c->leb_cnt); goto failed; } if (c->main_lebs < UBIFS_MIN_MAIN_LEBS) { - ubifs_err("too few main LEBs count %d, must be at least %d", + ubifs_err(c, "too few main LEBs count %d, must be at least %d", c->main_lebs, UBIFS_MIN_MAIN_LEBS); goto failed; } max_bytes = (long long)c->leb_size * UBIFS_MIN_BUD_LEBS; if (c->max_bud_bytes < max_bytes) { - ubifs_err("too small journal (%lld bytes), must be at least %lld bytes", + ubifs_err(c, "too small journal (%lld bytes), must be at least %lld bytes", c->max_bud_bytes, max_bytes); goto failed; } max_bytes = (long long)c->leb_size * c->main_lebs; if (c->max_bud_bytes > max_bytes) { - ubifs_err("too large journal size (%lld bytes), only %lld bytes available in the main area", + ubifs_err(c, "too large journal size (%lld bytes), only %lld bytes available in the main area", c->max_bud_bytes, max_bytes); goto failed; } @@ -446,7 +448,7 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) goto failed; } - if (c->default_compr < 0 || c->default_compr >= UBIFS_COMPR_TYPES_CNT) { + if (c->default_compr >= UBIFS_COMPR_TYPES_CNT) { err = 13; goto failed; } @@ -465,7 +467,7 @@ static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup) return 0; failed: - ubifs_err("bad superblock, error %d", err); + ubifs_err(c, "bad superblock, error %d", err); ubifs_dump_node(c, sup); return -EINVAL; } @@ -551,12 +553,12 @@ int ubifs_read_superblock(struct ubifs_info *c) ubifs_assert(!c->ro_media || c->ro_mount); if (!c->ro_mount || c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) { - ubifs_err("on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d", + ubifs_err(c, "on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d", c->fmt_version, c->ro_compat_version, UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION); if (c->ro_compat_version <= UBIFS_RO_COMPAT_VERSION) { - ubifs_msg("only R/O mounting is possible"); + ubifs_msg(c, "only R/O mounting is possible"); err = -EROFS; } else err = -EINVAL; @@ -572,7 +574,7 @@ int ubifs_read_superblock(struct ubifs_info *c) } if (c->fmt_version < 3) { - ubifs_err("on-flash format version %d is not supported", + ubifs_err(c, "on-flash format version %d is not supported", c->fmt_version); err = -EINVAL; goto out; @@ -597,7 +599,7 @@ int ubifs_read_superblock(struct ubifs_info *c) c->key_len = UBIFS_SK_LEN; break; default: - ubifs_err("unsupported key format"); + ubifs_err(c, "unsupported key format"); err = -EINVAL; goto out; } @@ -794,7 +796,7 @@ int ubifs_fixup_free_space(struct ubifs_info *c) ubifs_assert(c->space_fixup); ubifs_assert(!c->ro_mount); - ubifs_msg("start fixing up free space"); + ubifs_msg(c, "start fixing up free space"); err = fixup_free_space(c); if (err) @@ -813,6 +815,6 @@ int ubifs_fixup_free_space(struct ubifs_info *c) if (err) return err; - ubifs_msg("free space fixup complete"); + ubifs_msg(c, "free space fixup complete"); return err; } diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index 6fc464bb485..12a3597468d 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c @@ -92,7 +92,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, if (pad_len < 0 || offs + node_len + pad_len > c->leb_size) { if (!quiet) { - ubifs_err("bad pad node at LEB %d:%d", + ubifs_err(c, "bad pad node at LEB %d:%d", lnum, offs); ubifs_dump_node(c, pad); } @@ -102,7 +102,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, /* Make the node pads to 8-byte boundary */ if ((node_len + pad_len) & 7) { if (!quiet) - ubifs_err("bad padding length %d - %d", + ubifs_err(c, "bad padding length %d - %d", offs, offs + node_len + pad_len); return SCANNED_A_BAD_PAD_NODE; } @@ -123,7 +123,8 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, * @offs: offset to start at (usually zero) * @sbuf: scan buffer (must be c->leb_size) * - * This function returns %0 on success and a negative error code on failure. + * This function returns the scanned information on success and a negative error + * code on failure. */ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, int offs, void *sbuf) @@ -143,15 +144,16 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, err = ubifs_leb_read(c, lnum, sbuf + offs, offs, c->leb_size - offs, 0); if (err && err != -EBADMSG) { - ubifs_err("cannot read %d bytes from LEB %d:%d, error %d", + ubifs_err(c, "cannot read %d bytes from LEB %d:%d, error %d", c->leb_size - offs, lnum, offs, err); kfree(sleb); return ERR_PTR(err); } - if (err == -EBADMSG) - sleb->ecc = 1; - + /* + * Note, we ignore integrity errors (EBASMSG) because all the nodes are + * protected by CRC checksums. + */ return sleb; } @@ -161,8 +163,6 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, * @sleb: scanning information * @lnum: logical eraseblock number * @offs: offset to start at (usually zero) - * - * This function returns %0 on success and a negative error code on failure. */ void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, int lnum, int offs) @@ -232,11 +232,11 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, { int len; - ubifs_err("corruption at LEB %d:%d", lnum, offs); + ubifs_err(c, "corruption at LEB %d:%d", lnum, offs); len = c->leb_size - offs; if (len > 8192) len = 8192; - ubifs_err("first %d bytes from LEB %d:%d", len, lnum, offs); + ubifs_err(c, "first %d bytes from LEB %d:%d", len, lnum, offs); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); } @@ -249,7 +249,7 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, * @quiet: print no messages * * This function scans LEB number @lnum and returns complete information about - * its contents. Returns the scaned information in case of success and, + * its contents. Returns the scanned information in case of success and, * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case * of failure. * @@ -291,16 +291,16 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, switch (ret) { case SCANNED_GARBAGE: - ubifs_err("garbage"); + ubifs_err(c, "garbage"); goto corrupted; case SCANNED_A_NODE: break; case SCANNED_A_CORRUPT_NODE: case SCANNED_A_BAD_PAD_NODE: - ubifs_err("bad node"); + ubifs_err(c, "bad node"); goto corrupted; default: - ubifs_err("unknown"); + ubifs_err(c, "unknown"); err = -EINVAL; goto error; } @@ -317,7 +317,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, if (offs % c->min_io_size) { if (!quiet) - ubifs_err("empty space starts at non-aligned offset %d", + ubifs_err(c, "empty space starts at non-aligned offset %d", offs); goto corrupted; } @@ -330,7 +330,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, for (; len; offs++, buf++, len--) if (*(uint8_t *)buf != 0xff) { if (!quiet) - ubifs_err("corrupt empty space at LEB %d:%d", + ubifs_err(c, "corrupt empty space at LEB %d:%d", lnum, offs); goto corrupted; } @@ -340,14 +340,14 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, corrupted: if (!quiet) { ubifs_scanned_corruption(c, lnum, offs, buf); - ubifs_err("LEB %d scanning failed", lnum); + ubifs_err(c, "LEB %d scanning failed", lnum); } err = -EUCLEAN; ubifs_scan_destroy(sleb); return ERR_PTR(err); error: - ubifs_err("LEB %d scanning failed, error %d", lnum, err); + ubifs_err(c, "LEB %d scanning failed, error %d", lnum, err); ubifs_scan_destroy(sleb); return ERR_PTR(err); } diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 41763a18979..c4743135fce 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -101,7 +101,7 @@ void iput(struct inode *inode) } if (i >= INODE_LOCKED_MAX) { - ubifs_err("Error, can't lock (save) more inodes while recovery!!!"); + dbg_gen("Error, can't lock (save) more inodes while recovery!!!"); return; } @@ -208,13 +208,13 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode) const struct ubifs_inode *ui = ubifs_inode(inode); if (inode->i_size > c->max_inode_sz) { - ubifs_err("inode is too large (%lld)", + ubifs_err(c, "inode is too large (%lld)", (long long)inode->i_size); return 1; } - if (ui->compr_type < 0 || ui->compr_type >= UBIFS_COMPR_TYPES_CNT) { - ubifs_err("unknown compression type %d", ui->compr_type); + if (ui->compr_type >= UBIFS_COMPR_TYPES_CNT) { + ubifs_err(c, "unknown compression type %d", ui->compr_type); return 2; } @@ -228,7 +228,7 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode) return 5; if (!ubifs_compr_present(ui->compr_type)) { - ubifs_warn("inode %lu uses '%s' compression, but it was not compiled in", + ubifs_warn(c, "inode %lu uses '%s' compression, but it was not compiled in", inode->i_ino, ubifs_compr_name(ui->compr_type)); } @@ -321,9 +321,6 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) goto out_invalid; #ifndef __UBOOT__ - /* Disable read-ahead */ - inode->i_mapping->backing_dev_info = &c->bdi; - switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_mapping->a_ops = &ubifs_file_address_operations; @@ -363,6 +360,7 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) } memcpy(ui->data, ino->data, ui->data_len); ((char *)ui->data)[ui->data_len] = '\0'; + inode->i_link = ui->data; break; case S_IFBLK: case S_IFCHR: @@ -427,14 +425,14 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) return inode; out_invalid: - ubifs_err("inode %lu validation failed, error %d", inode->i_ino, err); + ubifs_err(c, "inode %lu validation failed, error %d", inode->i_ino, err); ubifs_dump_node(c, ino); ubifs_dump_inode(c, inode); err = -EINVAL; out_ino: kfree(ino); out: - ubifs_err("failed to read inode %lu, error %d", inode->i_ino, err); + ubifs_err(c, "failed to read inode %lu, error %d", inode->i_ino, err); iget_failed(inode); return ERR_PTR(err); } @@ -505,7 +503,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc) if (inode->i_nlink) { err = ubifs_jnl_write_inode(c, inode); if (err) - ubifs_err("can't write inode %lu, error %d", + ubifs_err(c, "can't write inode %lu, error %d", inode->i_ino, err); else err = dbg_check_inode_size(c, inode, ui->ui_size); @@ -549,7 +547,7 @@ static void ubifs_evict_inode(struct inode *inode) * Worst case we have a lost orphan inode wasting space, so a * simple error message is OK here. */ - ubifs_err("can't delete inode %lu, error %d", + ubifs_err(c, "can't delete inode %lu, error %d", inode->i_ino, err); out: @@ -609,19 +607,19 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root) struct ubifs_info *c = root->d_sb->s_fs_info; if (c->mount_opts.unmount_mode == 2) - seq_printf(s, ",fast_unmount"); + seq_puts(s, ",fast_unmount"); else if (c->mount_opts.unmount_mode == 1) - seq_printf(s, ",norm_unmount"); + seq_puts(s, ",norm_unmount"); if (c->mount_opts.bulk_read == 2) - seq_printf(s, ",bulk_read"); + seq_puts(s, ",bulk_read"); else if (c->mount_opts.bulk_read == 1) - seq_printf(s, ",no_bulk_read"); + seq_puts(s, ",no_bulk_read"); if (c->mount_opts.chk_data_crc == 2) - seq_printf(s, ",chk_data_crc"); + seq_puts(s, ",chk_data_crc"); else if (c->mount_opts.chk_data_crc == 1) - seq_printf(s, ",no_chk_data_crc"); + seq_puts(s, ",no_chk_data_crc"); if (c->mount_opts.override_compr) { seq_printf(s, ",compr=%s", @@ -681,17 +679,17 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) static int init_constants_early(struct ubifs_info *c) { if (c->vi.corrupted) { - ubifs_warn("UBI volume is corrupted - read-only mode"); + ubifs_warn(c, "UBI volume is corrupted - read-only mode"); c->ro_media = 1; } if (c->di.ro_mode) { - ubifs_msg("read-only UBI device"); + ubifs_msg(c, "read-only UBI device"); c->ro_media = 1; } if (c->vi.vol_type == UBI_STATIC_VOLUME) { - ubifs_msg("static UBI volume - read-only mode"); + ubifs_msg(c, "static UBI volume - read-only mode"); c->ro_media = 1; } @@ -705,19 +703,19 @@ static int init_constants_early(struct ubifs_info *c) c->max_write_shift = fls(c->max_write_size) - 1; if (c->leb_size < UBIFS_MIN_LEB_SZ) { - ubifs_err("too small LEBs (%d bytes), min. is %d bytes", + ubifs_err(c, "too small LEBs (%d bytes), min. is %d bytes", c->leb_size, UBIFS_MIN_LEB_SZ); return -EINVAL; } if (c->leb_cnt < UBIFS_MIN_LEB_CNT) { - ubifs_err("too few LEBs (%d), min. is %d", + ubifs_err(c, "too few LEBs (%d), min. is %d", c->leb_cnt, UBIFS_MIN_LEB_CNT); return -EINVAL; } if (!is_power_of_2(c->min_io_size)) { - ubifs_err("bad min. I/O size %d", c->min_io_size); + ubifs_err(c, "bad min. I/O size %d", c->min_io_size); return -EINVAL; } @@ -728,7 +726,7 @@ static int init_constants_early(struct ubifs_info *c) if (c->max_write_size < c->min_io_size || c->max_write_size % c->min_io_size || !is_power_of_2(c->max_write_size)) { - ubifs_err("bad write buffer size %d for %d min. I/O unit", + ubifs_err(c, "bad write buffer size %d for %d min. I/O unit", c->max_write_size, c->min_io_size); return -EINVAL; } @@ -854,7 +852,7 @@ static int init_constants_sb(struct ubifs_info *c) tmp = UBIFS_CS_NODE_SZ + UBIFS_REF_NODE_SZ * c->jhead_cnt; tmp = ALIGN(tmp, c->min_io_size); if (tmp > c->leb_size) { - ubifs_err("too small LEB size %d, at least %d needed", + ubifs_err(c, "too small LEB size %d, at least %d needed", c->leb_size, tmp); return -EINVAL; } @@ -869,7 +867,7 @@ static int init_constants_sb(struct ubifs_info *c) tmp /= c->leb_size; tmp += 1; if (c->log_lebs < tmp) { - ubifs_err("too small log %d LEBs, required min. %d LEBs", + ubifs_err(c, "too small log %d LEBs, required min. %d LEBs", c->log_lebs, tmp); return -EINVAL; } @@ -961,7 +959,7 @@ static int take_gc_lnum(struct ubifs_info *c) int err; if (c->gc_lnum == -1) { - ubifs_err("no LEB for GC"); + ubifs_err(c, "no LEB for GC"); return -EINVAL; } @@ -982,8 +980,8 @@ static int alloc_wbufs(struct ubifs_info *c) { int i, err; - c->jheads = kzalloc(c->jhead_cnt * sizeof(struct ubifs_jhead), - GFP_KERNEL); + c->jheads = kcalloc(c->jhead_cnt, sizeof(struct ubifs_jhead), + GFP_KERNEL); if (!c->jheads) return -ENOMEM; @@ -1046,7 +1044,7 @@ static void free_orphans(struct ubifs_info *c) orph = list_entry(c->orph_list.next, struct ubifs_orphan, list); list_del(&orph->list); kfree(orph); - ubifs_err("orphan list not empty at unmount"); + ubifs_err(c, "orphan list not empty at unmount"); } vfree(c->orph_buf); @@ -1144,7 +1142,8 @@ static const match_table_t tokens = { */ static int parse_standard_option(const char *option) { - ubifs_msg("parse %s", option); + + pr_notice("UBIFS: parse %s\n", option); if (!strcmp(option, "sync")) return MS_SYNCHRONOUS; return 0; @@ -1216,7 +1215,7 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, else if (!strcmp(name, "zlib")) c->mount_opts.compr_type = UBIFS_COMPR_ZLIB; else { - ubifs_err("unknown compressor \"%s\"", name); + ubifs_err(c, "unknown compressor \"%s\"", name); //FIXME: is c ready? kfree(name); return -EINVAL; } @@ -1232,7 +1231,7 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, flag = parse_standard_option(p); if (!flag) { - ubifs_err("unrecognized mount option \"%s\" or missing value", + ubifs_err(c, "unrecognized mount option \"%s\" or missing value", p); return -EINVAL; } @@ -1296,7 +1295,7 @@ again: } /* Just disable bulk-read */ - ubifs_warn("cannot allocate %d bytes of memory for bulk-read, disabling it", + ubifs_warn(c, "cannot allocate %d bytes of memory for bulk-read, disabling it", c->max_bu_buf_len); c->mount_opts.bulk_read = 1; c->bulk_read = 0; @@ -1316,7 +1315,7 @@ static int check_free_space(struct ubifs_info *c) { ubifs_assert(c->dark_wm > 0); if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) { - ubifs_err("insufficient free space to mount in R/W mode"); + ubifs_err(c, "insufficient free space to mount in R/W mode"); ubifs_dump_budg(c, &c->bi); ubifs_dump_lprops(c); return -ENOSPC; @@ -1339,6 +1338,8 @@ static int mount_ubifs(struct ubifs_info *c) size_t sz; c->ro_mount = !!(c->vfs_sb->s_flags & MS_RDONLY); + /* Suppress error messages while probing if MS_SILENT is set */ + c->probing = !!(c->vfs_sb->s_flags & MS_SILENT); #ifdef __UBOOT__ if (!c->ro_mount) { printf("UBIFS: only ro mode in U-Boot allowed.\n"); @@ -1363,14 +1364,14 @@ static int mount_ubifs(struct ubifs_info *c) * This UBI volume is empty, and read-only, or the file system * is mounted read-only - we cannot format it. */ - ubifs_err("can't format empty UBI volume: read-only %s", + ubifs_err(c, "can't format empty UBI volume: read-only %s", c->ro_media ? "UBI volume" : "mount"); err = -EROFS; goto out_free; } if (c->ro_media && !c->ro_mount) { - ubifs_err("cannot mount read-write - read-only media"); + ubifs_err(c, "cannot mount read-write - read-only media"); err = -EROFS; goto out_free; } @@ -1415,12 +1416,14 @@ static int mount_ubifs(struct ubifs_info *c) if (err) goto out_free; + c->probing = 0; + /* * Make sure the compressor which is set as default in the superblock * or overridden by mount options is actually compiled in. */ if (!ubifs_compr_present(c->default_compr)) { - ubifs_err("'compressor \"%s\" is not compiled in", + ubifs_err(c, "'compressor \"%s\" is not compiled in", ubifs_compr_name(c->default_compr)); err = -ENOTSUPP; goto out_free; @@ -1450,7 +1453,7 @@ static int mount_ubifs(struct ubifs_info *c) if (IS_ERR(c->bgt)) { err = PTR_ERR(c->bgt); c->bgt = NULL; - ubifs_err("cannot spawn \"%s\", error %d", + ubifs_err(c, "cannot spawn \"%s\", error %d", c->bgt_name, err); goto out_wbufs; } @@ -1465,7 +1468,7 @@ static int mount_ubifs(struct ubifs_info *c) init_constants_master(c); if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { - ubifs_msg("recovery needed"); + ubifs_msg(c, "recovery needed"); c->need_recovery = 1; } @@ -1488,7 +1491,7 @@ static int mount_ubifs(struct ubifs_info *c) goto out_lpt; } - if (!c->ro_mount) { + if (!c->ro_mount && !c->need_recovery) { /* * Set the "dirty" flag so that if we reboot uncleanly we * will notice this immediately on the next mount. @@ -1582,10 +1585,10 @@ static int mount_ubifs(struct ubifs_info *c) if (c->need_recovery) { if (c->ro_mount) - ubifs_msg("recovery deferred"); + ubifs_msg(c, "recovery deferred"); else { c->need_recovery = 0; - ubifs_msg("recovery completed"); + ubifs_msg(c, "recovery completed"); /* * GC LEB has to be empty and taken at this point. But * the journal head LEBs may also be accounted as @@ -1606,20 +1609,20 @@ static int mount_ubifs(struct ubifs_info *c) c->mounting = 0; - ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"%s", + ubifs_msg(c, "UBIFS: mounted UBI device %d, volume %d, name \"%s\"%s", c->vi.ubi_num, c->vi.vol_id, c->vi.name, c->ro_mount ? ", R/O mode" : ""); x = (long long)c->main_lebs * c->leb_size; y = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; - ubifs_msg("LEB size: %d bytes (%d KiB), min./max. I/O unit sizes: %d bytes/%d bytes", + ubifs_msg(c, "LEB size: %d bytes (%d KiB), min./max. I/O unit sizes: %d bytes/%d bytes", c->leb_size, c->leb_size >> 10, c->min_io_size, c->max_write_size); - ubifs_msg("FS size: %lld bytes (%lld MiB, %d LEBs), journal size %lld bytes (%lld MiB, %d LEBs)", + ubifs_msg(c, "FS size: %lld bytes (%lld MiB, %d LEBs), journal size %lld bytes (%lld MiB, %d LEBs)", x, x >> 20, c->main_lebs, y, y >> 20, c->log_lebs + c->max_bud_cnt); - ubifs_msg("reserved for root: %llu bytes (%llu KiB)", + ubifs_msg(c, "reserved for root: %llu bytes (%llu KiB)", c->report_rp_size, c->report_rp_size >> 10); - ubifs_msg("media format: w%d/r%d (latest is w%d/r%d), UUID %pUB%s", + ubifs_msg(c, "media format: w%d/r%d (latest is w%d/r%d), UUID %pUB%s", c->fmt_version, c->ro_compat_version, UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION, c->uuid, c->big_lpt ? ", big LPT model" : ", small LPT model"); @@ -1768,8 +1771,8 @@ static int ubifs_remount_rw(struct ubifs_info *c) int err, lnum; if (c->rw_incompat) { - ubifs_err("the file-system is not R/W-compatible"); - ubifs_msg("on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d", + ubifs_err(c, "the file-system is not R/W-compatible"); + ubifs_msg(c, "on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d", c->fmt_version, c->ro_compat_version, UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION); return -EROFS; @@ -1806,7 +1809,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) } if (c->need_recovery) { - ubifs_msg("completing deferred recovery"); + ubifs_msg(c, "completing deferred recovery"); err = ubifs_write_rcvrd_mst_node(c); if (err) goto out; @@ -1855,7 +1858,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) if (IS_ERR(c->bgt)) { err = PTR_ERR(c->bgt); c->bgt = NULL; - ubifs_err("cannot spawn \"%s\", error %d", + ubifs_err(c, "cannot spawn \"%s\", error %d", c->bgt_name, err); goto out; } @@ -1889,7 +1892,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) if (c->need_recovery) { c->need_recovery = 0; - ubifs_msg("deferred recovery completed"); + ubifs_msg(c, "deferred recovery completed"); } else { /* * Do not run the debugging space check if the were doing @@ -1977,8 +1980,7 @@ static void ubifs_put_super(struct super_block *sb) int i; struct ubifs_info *c = sb->s_fs_info; - ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num, - c->vi.vol_id); + ubifs_msg(c, "un-mount UBI device %d", c->vi.ubi_num); /* * The following asserts are only valid if there has not been a failure @@ -2034,7 +2036,7 @@ static void ubifs_put_super(struct super_block *sb) * next mount, so we just print a message and * continue to unmount normally. */ - ubifs_err("failed to write master node, error %d", + ubifs_err(c, "failed to write master node, error %d", err); } else { #ifndef __UBOOT__ @@ -2065,17 +2067,17 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) err = ubifs_parse_options(c, data, 1); if (err) { - ubifs_err("invalid or unknown remount parameter"); + ubifs_err(c, "invalid or unknown remount parameter"); return err; } if (c->ro_mount && !(*flags & MS_RDONLY)) { if (c->ro_error) { - ubifs_msg("cannot re-mount R/W due to prior errors"); + ubifs_msg(c, "cannot re-mount R/W due to prior errors"); return -EROFS; } if (c->ro_media) { - ubifs_msg("cannot re-mount R/W - UBI volume is R/O"); + ubifs_msg(c, "cannot re-mount R/W - UBI volume is R/O"); return -EROFS; } err = ubifs_remount_rw(c); @@ -2083,7 +2085,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) return err; } else if (!c->ro_mount && (*flags & MS_RDONLY)) { if (c->ro_error) { - ubifs_msg("cannot re-mount R/O due to prior errors"); + ubifs_msg(c, "cannot re-mount R/O due to prior errors"); return -EROFS; } ubifs_remount_ro(c); @@ -2200,7 +2202,6 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi) mutex_init(&c->lp_mutex); mutex_init(&c->tnc_mutex); mutex_init(&c->log_mutex); - mutex_init(&c->mst_mutex); mutex_init(&c->umount_mutex); mutex_init(&c->bu_mutex); mutex_init(&c->write_reserve_mutex); @@ -2261,8 +2262,8 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) * * Read-ahead will be disabled because @c->bdi.ra_pages is 0. */ - co>bdi.name = "ubifs", - c->bdi.capabilities = BDI_CAP_MAP_COPY; + c->bdi.name = "ubifs", + c->bdi.capabilities = 0; err = bdi_init(&c->bdi); if (err) goto out_close; @@ -2285,6 +2286,9 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) if (c->max_inode_sz > MAX_LFS_FILESIZE) sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; sb->s_op = &ubifs_super_operations; +#ifndef __UBOOT__ + sb->s_xattr = ubifs_xattr_handlers; +#endif mutex_lock(&c->umount_mutex); err = mount_ubifs(c); @@ -2453,8 +2457,8 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, */ ubi = open_ubi(name, UBI_READONLY); if (IS_ERR(ubi)) { - ubifs_err("cannot open \"%s\", error %d", - name, (int)PTR_ERR(ubi)); + pr_err("UBIFS error (pid: %d): cannot open \"%s\", error %d", + current->pid, name, (int)PTR_ERR(ubi)); return ERR_CAST(ubi); } @@ -2595,8 +2599,8 @@ int ubifs_init(void) * UBIFS_BLOCK_SIZE. It is assumed that both are powers of 2. */ if (PAGE_CACHE_SIZE < UBIFS_BLOCK_SIZE) { - ubifs_err("VFS page cache size is %u bytes, but UBIFS requires at least 4096 bytes", - (unsigned int)PAGE_CACHE_SIZE); + pr_err("UBIFS error (pid %d): VFS page cache size is %u bytes, but UBIFS requires at least 4096 bytes", + current->pid, (unsigned int)PAGE_CACHE_SIZE); return -EINVAL; } @@ -2608,7 +2612,9 @@ int ubifs_init(void) if (!ubifs_inode_slab) return -ENOMEM; - register_shrinker(&ubifs_shrinker_info); + err = register_shrinker(&ubifs_shrinker_info); + if (err) + goto out_slab; #endif err = ubifs_compressors_init(); @@ -2622,7 +2628,8 @@ int ubifs_init(void) err = register_filesystem(&ubifs_fs_type); if (err) { - ubifs_err("cannot register file system, error %d", err); + pr_err("UBIFS error (pid %d): cannot register file system, error %d", + current->pid, err); goto out_dbg; } #endif @@ -2637,6 +2644,7 @@ out_compr: out_shrinker: #ifndef __UBOOT__ unregister_shrinker(&ubifs_shrinker_info); +out_slab: #endif kmem_cache_destroy(ubifs_inode_slab); return err; diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index e20cedda575..f6316a32e3b 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -93,7 +93,7 @@ static int insert_old_idx(struct ubifs_info *c, int lnum, int offs) else if (offs > o->offs) p = &(*p)->rb_right; else { - ubifs_err("old idx added twice!"); + ubifs_err(c, "old idx added twice!"); kfree(old_idx); return 0; } @@ -442,7 +442,7 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type, err = ubifs_leb_read(c, lnum, buf, offs, len, 1); if (err) { - ubifs_err("cannot read node type %d from LEB %d:%d, error %d", + ubifs_err(c, "cannot read node type %d from LEB %d:%d, error %d", type, lnum, offs, err); return err; } @@ -1683,27 +1683,27 @@ static int validate_data_node(struct ubifs_info *c, void *buf, int err, len; if (ch->node_type != UBIFS_DATA_NODE) { - ubifs_err("bad node type (%d but expected %d)", + ubifs_err(c, "bad node type (%d but expected %d)", ch->node_type, UBIFS_DATA_NODE); goto out_err; } err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0, 0); if (err) { - ubifs_err("expected node type %d", UBIFS_DATA_NODE); + ubifs_err(c, "expected node type %d", UBIFS_DATA_NODE); goto out; } len = le32_to_cpu(ch->len); if (len != zbr->len) { - ubifs_err("bad node length %d, expected %d", len, zbr->len); + ubifs_err(c, "bad node length %d, expected %d", len, zbr->len); goto out_err; } /* Make sure the key of the read node is correct */ key_read(c, buf + UBIFS_KEY_OFFSET, &key1); if (!keys_eq(c, &zbr->key, &key1)) { - ubifs_err("bad key in node at LEB %d:%d", + ubifs_err(c, "bad key in node at LEB %d:%d", zbr->lnum, zbr->offs); dbg_tnck(&zbr->key, "looked for key "); dbg_tnck(&key1, "found node's key "); @@ -1715,7 +1715,7 @@ static int validate_data_node(struct ubifs_info *c, void *buf, out_err: err = -EINVAL; out: - ubifs_err("bad node at LEB %d:%d", zbr->lnum, zbr->offs); + ubifs_err(c, "bad node at LEB %d:%d", zbr->lnum, zbr->offs); ubifs_dump_node(c, buf); dump_stack(); return err; @@ -1740,7 +1740,7 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu) len = bu->zbranch[bu->cnt - 1].offs; len += bu->zbranch[bu->cnt - 1].len - offs; if (len > bu->buf_len) { - ubifs_err("buffer too small %d vs %d", bu->buf_len, len); + ubifs_err(c, "buffer too small %d vs %d", bu->buf_len, len); return -EINVAL; } @@ -1756,7 +1756,7 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu) return -EAGAIN; if (err && err != -EBADMSG) { - ubifs_err("failed to read from LEB %d:%d, error %d", + ubifs_err(c, "failed to read from LEB %d:%d, error %d", lnum, offs, err); dump_stack(); dbg_tnck(&bu->key, "key "); @@ -2858,10 +2858,11 @@ void ubifs_tnc_close(struct ubifs_info *c) { tnc_destroy_cnext(c); if (c->zroot.znode) { - long n; + long n, freed; - ubifs_destroy_tnc_subtree(c->zroot.znode); n = atomic_long_read(&c->clean_zn_cnt); + freed = ubifs_destroy_tnc_subtree(c->zroot.znode); + ubifs_assert(freed == n); atomic_long_sub(n, &ubifs_clean_zn_cnt); } kfree(c->gap_lebs); @@ -3292,7 +3293,6 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, goto out_unlock; if (err) { - err = -EINVAL; key = &from_key; goto out_dump; } @@ -3312,7 +3312,7 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, out_dump: block = key_block(c, key); - ubifs_err("inode %lu has size %lld, but there are data at offset %lld", + ubifs_err(c, "inode %lu has size %lld, but there are data at offset %lld", (unsigned long)inode->i_ino, size, ((loff_t)block) << UBIFS_BLOCK_SHIFT); mutex_unlock(&c->tnc_mutex); diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c index f808e0bc2fd..b1bb6470e17 100644 --- a/fs/ubifs/tnc_misc.c +++ b/fs/ubifs/tnc_misc.c @@ -285,9 +285,9 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, lnum, offs, znode->level, znode->child_cnt); if (znode->child_cnt > c->fanout || znode->level > UBIFS_MAX_LEVELS) { - ubifs_err("current fanout %d, branch count %d", + ubifs_err(c, "current fanout %d, branch count %d", c->fanout, znode->child_cnt); - ubifs_err("max levels %d, znode level %d", + ubifs_err(c, "max levels %d, znode level %d", UBIFS_MAX_LEVELS, znode->level); err = 1; goto out_dump; @@ -308,7 +308,7 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, if (zbr->lnum < c->main_first || zbr->lnum >= c->leb_cnt || zbr->offs < 0 || zbr->offs + zbr->len > c->leb_size || zbr->offs & 7) { - ubifs_err("bad branch %d", i); + ubifs_err(c, "bad branch %d", i); err = 2; goto out_dump; } @@ -320,7 +320,7 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, case UBIFS_XENT_KEY: break; default: - ubifs_err("bad key type at slot %d: %d", + ubifs_err(c, "bad key type at slot %d: %d", i, key_type(c, &zbr->key)); err = 3; goto out_dump; @@ -332,17 +332,17 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, type = key_type(c, &zbr->key); if (c->ranges[type].max_len == 0) { if (zbr->len != c->ranges[type].len) { - ubifs_err("bad target node (type %d) length (%d)", + ubifs_err(c, "bad target node (type %d) length (%d)", type, zbr->len); - ubifs_err("have to be %d", c->ranges[type].len); + ubifs_err(c, "have to be %d", c->ranges[type].len); err = 4; goto out_dump; } } else if (zbr->len < c->ranges[type].min_len || zbr->len > c->ranges[type].max_len) { - ubifs_err("bad target node (type %d) length (%d)", + ubifs_err(c, "bad target node (type %d) length (%d)", type, zbr->len); - ubifs_err("have to be in range of %d-%d", + ubifs_err(c, "have to be in range of %d-%d", c->ranges[type].min_len, c->ranges[type].max_len); err = 5; @@ -362,12 +362,12 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, cmp = keys_cmp(c, key1, key2); if (cmp > 0) { - ubifs_err("bad key order (keys %d and %d)", i, i + 1); + ubifs_err(c, "bad key order (keys %d and %d)", i, i + 1); err = 6; goto out_dump; } else if (cmp == 0 && !is_hash_key(c, key1)) { /* These can only be keys with colliding hash */ - ubifs_err("keys %d and %d are not hashed but equivalent", + ubifs_err(c, "keys %d and %d are not hashed but equivalent", i, i + 1); err = 7; goto out_dump; @@ -378,7 +378,7 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len, return 0; out_dump: - ubifs_err("bad indexing node at LEB %d:%d, error %d", lnum, offs, err); + ubifs_err(c, "bad indexing node at LEB %d:%d, error %d", lnum, offs, err); ubifs_dump_node(c, idx); kfree(idx); return -EINVAL; @@ -474,7 +474,7 @@ int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, /* Make sure the key of the read node is correct */ key_read(c, node + UBIFS_KEY_OFFSET, &key1); if (!keys_eq(c, key, &key1)) { - ubifs_err("bad key in node at LEB %d:%d", + ubifs_err(c, "bad key in node at LEB %d:%d", zbr->lnum, zbr->offs); dbg_tnck(key, "looked for key "); dbg_tnck(&key1, "but found node's key "); diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index f7a084747e6..50355e988e9 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -103,8 +103,8 @@ struct crypto_comp { int compressor; }; -static inline struct crypto_comp *crypto_alloc_comp(const char *alg_name, - u32 type, u32 mask) +static inline struct crypto_comp +*crypto_alloc_comp(const char *alg_name, u32 type, u32 mask) { struct ubifs_compressor *comp; struct crypto_comp *ptr; @@ -124,15 +124,16 @@ static inline struct crypto_comp *crypto_alloc_comp(const char *alg_name, i++; } if (i >= UBIFS_COMPR_TYPES_CNT) { - ubifs_err("invalid compression type %s", alg_name); + dbg_gen("invalid compression type %s", alg_name); free (ptr); return NULL; } return ptr; } -static inline int crypto_comp_decompress(struct crypto_comp *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen) +static inline int +crypto_comp_decompress(const struct ubifs_info *c, struct crypto_comp *tfm, + const u8 *src, unsigned int slen, u8 *dst, + unsigned int *dlen) { struct ubifs_compressor *compr = ubifs_compressors[tfm->compressor]; int err; @@ -145,7 +146,7 @@ static inline int crypto_comp_decompress(struct crypto_comp *tfm, err = compr->decompress(src, slen, dst, (size_t *)dlen); if (err) - ubifs_err("cannot decompress %d bytes, compressor %s, " + ubifs_err(c, "cannot decompress %d bytes, compressor %s, " "error %d", slen, compr->name, err); return err; @@ -172,21 +173,21 @@ atomic_long_t ubifs_clean_zn_cnt; * The length of the uncompressed data is returned in @out_len. This functions * returns %0 on success or a negative error code on failure. */ -int ubifs_decompress(const void *in_buf, int in_len, void *out_buf, - int *out_len, int compr_type) +int ubifs_decompress(const struct ubifs_info *c, const void *in_buf, + int in_len, void *out_buf, int *out_len, int compr_type) { int err; struct ubifs_compressor *compr; if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) { - ubifs_err("invalid compression type %d", compr_type); + ubifs_err(c, "invalid compression type %d", compr_type); return -EINVAL; } compr = ubifs_compressors[compr_type]; if (unlikely(!compr->capi_name)) { - ubifs_err("%s compression is not compiled in", compr->name); + ubifs_err(c, "%s compression is not compiled in", compr->name); return -EINVAL; } @@ -198,13 +199,13 @@ int ubifs_decompress(const void *in_buf, int in_len, void *out_buf, if (compr->decomp_mutex) mutex_lock(compr->decomp_mutex); - err = crypto_comp_decompress(compr->cc, in_buf, in_len, out_buf, + err = crypto_comp_decompress(c, compr->cc, in_buf, in_len, out_buf, (unsigned int *)out_len); if (compr->decomp_mutex) mutex_unlock(compr->decomp_mutex); if (err) - ubifs_err("cannot decompress %d bytes, compressor %s, error %d", - in_len, compr->name, err); + ubifs_err(c, "cannot decompress %d bytes, compressor %s," + " error %d", in_len, compr->name, err); return err; } @@ -229,8 +230,9 @@ static int __init compr_init(struct ubifs_compressor *compr) if (compr->capi_name) { compr->cc = crypto_alloc_comp(compr->capi_name, 0, 0); if (IS_ERR(compr->cc)) { - ubifs_err("cannot initialize compressor %s, error %ld", - compr->name, PTR_ERR(compr->cc)); + dbg_gen("cannot initialize compressor %s," + " error %ld", compr->name, + PTR_ERR(compr->cc)); return PTR_ERR(compr->cc); } } @@ -384,7 +386,7 @@ static int ubifs_printdir(struct file *file, void *dirent) out: if (err != -ENOENT) { - ubifs_err("cannot find next direntry, error %d", err); + ubifs_err(c, "cannot find next direntry, error %d", err); return err; } @@ -468,7 +470,7 @@ static int ubifs_finddir(struct super_block *sb, char *dirname, out: if (err != -ENOENT) - ubifs_err("cannot find next direntry, error %d", err); + dbg_gen("cannot find next direntry, error %d", err); out_free: if (file->private_data) @@ -570,7 +572,26 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename) return 0; } -int ubifs_ls(char *filename) +int ubifs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) +{ + if (rbdd) { + debug("UBIFS cannot be used with normal block devices\n"); + return -1; + } + + /* + * Should never happen since get_device_and_partition() already checks + * this, but better safe then sorry. + */ + if (!ubifs_is_mounted()) { + debug("UBIFS not mounted, use ubifsmount to mount volume first!\n"); + return -1; + } + + return 0; +} + +int ubifs_ls(const char *filename) { struct ubifs_info *c = ubifs_sb->s_fs_info; struct file *file; @@ -581,7 +602,7 @@ int ubifs_ls(char *filename) int ret = 0; c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY); - inum = ubifs_findfile(ubifs_sb, filename); + inum = ubifs_findfile(ubifs_sb, (char *)filename); if (!inum) { ret = -1; goto out; @@ -618,6 +639,48 @@ out: return ret; } +int ubifs_exists(const char *filename) +{ + struct ubifs_info *c = ubifs_sb->s_fs_info; + unsigned long inum; + + c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY); + inum = ubifs_findfile(ubifs_sb, (char *)filename); + ubi_close_volume(c->ubi); + + return inum != 0; +} + +int ubifs_size(const char *filename, loff_t *size) +{ + struct ubifs_info *c = ubifs_sb->s_fs_info; + unsigned long inum; + struct inode *inode; + int err = 0; + + c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY); + + inum = ubifs_findfile(ubifs_sb, (char *)filename); + if (!inum) { + err = -1; + goto out; + } + + inode = ubifs_iget(ubifs_sb, inum); + if (IS_ERR(inode)) { + printf("%s: Error reading inode %ld!\n", __func__, inum); + err = PTR_ERR(inode); + goto out; + } + + *size = inode->i_size; + + ubifs_iput(inode); +out: + ubi_close_volume(c->ubi); + return err; +} + /* * ubifsload... */ @@ -654,7 +717,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block, dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ; out_len = UBIFS_BLOCK_SIZE; - err = ubifs_decompress(&dn->data, dlen, addr, &out_len, + err = ubifs_decompress(c, &dn->data, dlen, addr, &out_len, le16_to_cpu(dn->compr_type)); if (err || len != out_len) goto dump; @@ -670,7 +733,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block, return 0; dump: - ubifs_err("bad data node (block %u, inode %lu)", + ubifs_err(c, "bad data node (block %u, inode %lu)", block, inode->i_ino); ubifs_dump_node(c, dn); return -EINVAL; @@ -772,7 +835,7 @@ static int do_readpage(struct ubifs_info *c, struct inode *inode, dbg_gen("hole"); goto out_free; } - ubifs_err("cannot read page %lu of inode %lu, error %d", + ubifs_err(c, "cannot read page %lu of inode %lu, error %d", page->index, inode->i_ino, err); goto error; } @@ -787,7 +850,8 @@ error: return err; } -int ubifs_load(char *filename, u32 addr, u32 size) +int ubifs_read(const char *filename, void *buf, loff_t offset, + loff_t size, loff_t *actread) { struct ubifs_info *c = ubifs_sb->s_fs_info; unsigned long inum; @@ -798,10 +862,18 @@ int ubifs_load(char *filename, u32 addr, u32 size) int count; int last_block_size = 0; + *actread = 0; + + if (offset & (PAGE_SIZE - 1)) { + printf("ubifs: Error offset must be a multple of %d\n", + PAGE_SIZE); + return -1; + } + c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY); /* ubifs_findfile will resolve symlinks, so we know that we get * the real file here */ - inum = ubifs_findfile(ubifs_sb, filename); + inum = ubifs_findfile(ubifs_sb, (char *)filename); if (!inum) { err = -1; goto out; @@ -817,19 +889,24 @@ int ubifs_load(char *filename, u32 addr, u32 size) goto out; } + if (offset > inode->i_size) { + printf("ubifs: Error offset (%lld) > file-size (%lld)\n", + offset, size); + err = -1; + goto put_inode; + } + /* * If no size was specified or if size bigger than filesize * set size to filesize */ - if ((size == 0) || (size > inode->i_size)) - size = inode->i_size; + if ((size == 0) || (size > (inode->i_size - offset))) + size = inode->i_size - offset; count = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; - printf("Loading file '%s' to addr 0x%08x with size %d (0x%08x)...\n", - filename, addr, size, size); - page.addr = (void *)addr; - page.index = 0; + page.addr = buf; + page.index = offset / PAGE_SIZE; page.inode = inode; for (i = 0; i < count; i++) { /* @@ -846,16 +923,48 @@ int ubifs_load(char *filename, u32 addr, u32 size) page.index++; } - if (err) + if (err) { printf("Error reading file '%s'\n", filename); - else { - setenv_hex("filesize", size); - printf("Done\n"); + *actread = i * PAGE_SIZE; + } else { + *actread = size; } +put_inode: ubifs_iput(inode); out: ubi_close_volume(c->ubi); return err; } + +void ubifs_close(void) +{ +} + +/* Compat wrappers for common/cmd_ubifs.c */ +int ubifs_load(char *filename, u32 addr, u32 size) +{ + loff_t actread; + int err; + + printf("Loading file '%s' to addr 0x%08x...\n", filename, addr); + + err = ubifs_read(filename, (void *)addr, 0, size, &actread); + if (err == 0) { + setenv_hex("filesize", actread); + printf("Done\n"); + } + + return err; +} + +void uboot_ubifs_umount(void) +{ + if (ubifs_sb) { + printf("Unmounting UBIFS volume %s!\n", + ((struct ubifs_info *)(ubifs_sb->s_fs_info))->vi.name); + ubifs_umount(ubifs_sb->s_fs_info); + ubifs_sb = NULL; + } +} diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index a51b2376d22..1d894652059 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -29,11 +29,13 @@ #include <linux/mtd/ubi.h> #include <linux/pagemap.h> #include <linux/backing-dev.h> +#include <linux/security.h> #include "ubifs-media.h" #else #include <asm/atomic.h> #include <asm-generic/atomic-long.h> #include <ubi_uboot.h> +#include <ubifs_uboot.h> #include <linux/ctype.h> #include <linux/time.h> @@ -616,24 +618,43 @@ static inline ino_t parent_ino(struct dentry *dentry) #define UBIFS_VERSION 1 /* Normal UBIFS messages */ -#define ubifs_msg(fmt, ...) pr_notice("UBIFS: " fmt "\n", ##__VA_ARGS__) +#define ubifs_msg(c, fmt, ...) \ + pr_notice("UBIFS (ubi%d:%d): " fmt "\n", \ + (c)->vi.ubi_num, (c)->vi.vol_id, ##__VA_ARGS__) /* UBIFS error messages */ #ifndef __UBOOT__ -#define ubifs_err(fmt, ...) \ - pr_err("UBIFS error (pid %d): %s: " fmt "\n", current->pid, \ +#define ubifs_err(c, fmt, ...) \ + pr_err("UBIFS error (ubi%d:%d pid %d): %s: " fmt "\n", \ + (c)->vi.ubi_num, (c)->vi.vol_id, current->pid, \ __func__, ##__VA_ARGS__) /* UBIFS warning messages */ -#define ubifs_warn(fmt, ...) \ - pr_warn("UBIFS warning (pid %d): %s: " fmt "\n", \ - current->pid, __func__, ##__VA_ARGS__) +#define ubifs_warn(c, fmt, ...) \ + pr_warn("UBIFS warning (ubi%d:%d pid %d): %s: " fmt "\n", \ + (c)->vi.ubi_num, (c)->vi.vol_id, current->pid, \ + __func__, ##__VA_ARGS__) #else -#define ubifs_err(fmt, ...) \ - pr_err("UBIFS error: %s: " fmt "\n", __func__, ##__VA_ARGS__) +#define ubifs_err(c, fmt, ...) \ + pr_err("UBIFS error (ubi%d:%d pid %d): %s: " fmt "\n", \ + (c)->vi.ubi_num, (c)->vi.vol_id, 0, \ + __func__, ##__VA_ARGS__) /* UBIFS warning messages */ -#define ubifs_warn(fmt, ...) \ - pr_warn("UBIFS warning: %s: " fmt "\n", __func__, ##__VA_ARGS__) +#define ubifs_warn(c, fmt, ...) \ + pr_warn("UBIFS warning (ubi%d:%d pid %d): %s: " fmt "\n", \ + (c)->vi.ubi_num, (c)->vi.vol_id, 0, \ + __func__, ##__VA_ARGS__) + #endif +/* + * A variant of 'ubifs_err()' which takes the UBIFS file-sytem description + * object as an argument. + */ +#define ubifs_errc(c, fmt, ...) \ + do { \ + if (!(c)->probing) \ + ubifs_err(c, fmt, ##__VA_ARGS__); \ + } while (0) + /* UBIFS file system VFS magic number */ #define UBIFS_SUPER_MAGIC 0x24051905 @@ -730,7 +751,7 @@ static inline ino_t parent_ino(struct dentry *dentry) #define WORST_COMPR_FACTOR 2 /* - * How much memory is needed for a buffer where we comress a data node. + * How much memory is needed for a buffer where we compress a data node. */ #define COMPRESSED_DATA_NODE_BUF_SZ \ (UBIFS_DATA_NODE_SZ + UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR) @@ -887,7 +908,6 @@ struct ubifs_scan_node { * @nodes_cnt: number of nodes scanned * @nodes: list of struct ubifs_scan_node * @endpt: end point (and therefore the start of empty space) - * @ecc: read returned -EBADMSG * @buf: buffer containing entire LEB scanned */ struct ubifs_scan_leb { @@ -895,7 +915,6 @@ struct ubifs_scan_leb { int nodes_cnt; struct list_head nodes; int endpt; - int ecc; void *buf; }; @@ -1238,7 +1257,7 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes * fields * @softlimit: soft write-buffer timeout interval - * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit + * @delta: hard and soft timeouts delta (the timer expire interval is @softlimit * and @softlimit + @delta) * @timer: write-buffer timer * @no_timer: non-zero if this write-buffer does not have a timer @@ -1508,9 +1527,9 @@ struct ubifs_orphan { /** * struct ubifs_mount_opts - UBIFS-specific mount options information. * @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast) - * @bulk_read: enable/disable bulk-reads (%0 default, %1 disabe, %2 enable) + * @bulk_read: enable/disable bulk-reads (%0 default, %1 disable, %2 enable) * @chk_data_crc: enable/disable CRC data checking when reading data nodes - * (%0 default, %1 disabe, %2 enable) + * (%0 default, %1 disable, %2 enable) * @override_compr: override default compressor (%0 - do not override and use * superblock compressor, %1 - override and use compressor * specified in @compr_type) @@ -1540,9 +1559,9 @@ struct ubifs_mount_opts { * optimization) * @nospace_rp: the same as @nospace, but additionally means that even reserved * pool is full - * @page_budget: budget for a page (constant, nenver changed after mount) - * @inode_budget: budget for an inode (constant, nenver changed after mount) - * @dent_budget: budget for a directory entry (constant, nenver changed after + * @page_budget: budget for a page (constant, never changed after mount) + * @inode_budget: budget for an inode (constant, never changed after mount) + * @dent_budget: budget for a directory entry (constant, never changed after * mount) */ struct ubifs_budg_info { @@ -1628,7 +1647,6 @@ struct ubifs_debug_info; * * @mst_node: master node * @mst_offs: offset of valid master node - * @mst_mutex: protects the master node area, @mst_node, and @mst_offs * * @max_bu_buf_len: maximum bulk-read buffer length * @bu_mutex: protects the pre-allocated bulk-read buffer and @c->bu @@ -1795,6 +1813,7 @@ struct ubifs_debug_info; * @need_recovery: %1 if the file-system needs recovery * @replaying: %1 during journal replay * @mounting: %1 while mounting + * @probing: %1 while attempting to mount if MS_SILENT mount flag is set * @remounting_rw: %1 while re-mounting from R/O mode to R/W mode * @replay_list: temporary list used during journal replay * @replay_buds: list of buds to replay @@ -1870,7 +1889,6 @@ struct ubifs_info { struct ubifs_mst_node *mst_node; int mst_offs; - struct mutex mst_mutex; int max_bu_buf_len; struct mutex bu_mutex; @@ -2029,6 +2047,7 @@ struct ubifs_info { unsigned int replaying:1; unsigned int mounting:1; unsigned int remounting_rw:1; + unsigned int probing:1; struct list_head replay_list; struct list_head replay_buds; unsigned long long cs_sqnum; @@ -2048,6 +2067,7 @@ extern spinlock_t ubifs_infos_lock; extern atomic_long_t ubifs_clean_zn_cnt; extern struct kmem_cache *ubifs_inode_slab; extern const struct super_operations ubifs_super_operations; +extern const struct xattr_handler *ubifs_xattr_handlers[]; extern const struct address_space_operations ubifs_file_address_operations; extern const struct file_operations ubifs_file_operations; extern const struct inode_operations ubifs_file_inode_operations; @@ -2339,6 +2359,8 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, size_t size); ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); int ubifs_removexattr(struct dentry *dentry, const char *name); +int ubifs_init_security(struct inode *dentry, struct inode *inode, + const struct qstr *qstr); /* super.c */ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); @@ -2369,21 +2391,16 @@ long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); /* compressor.c */ int __init ubifs_compressors_init(void); void ubifs_compressors_exit(void); -void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len, - int *compr_type); -int ubifs_decompress(const void *buf, int len, void *out, int *out_len, - int compr_type); +void ubifs_compress(const struct ubifs_info *c, const void *in_buf, int in_len, + void *out_buf, int *out_len, int *compr_type); +int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len, + void *out, int *out_len, int compr_type); #include "debug.h" #include "misc.h" #include "key.h" #ifdef __UBOOT__ -/* these are used in cmd_ubifs.c */ -int ubifs_init(void); -int uboot_ubifs_mount(char *vol_name); void ubifs_umount(struct ubifs_info *c); -int ubifs_ls(char *dir_name); -int ubifs_load(char *filename, u32 addr, u32 size); #endif #endif /* !__UBIFS_H__ */ diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 21552650025..d0383f3d769 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -69,6 +69,9 @@ typedef struct global_data { struct udevice *dm_root_f; /* Pre-relocation root instance */ struct list_head uclass_root; /* Head of core tree */ #endif +#ifdef CONFIG_TIMER + struct udevice *timer; /* Timer instance for Driver Model */ +#endif const void *fdt_blob; /* Our device tree, NULL if none */ void *new_fdt; /* Relocated FDT */ diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index d2f49a12c1d..66264ce3b47 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -72,6 +72,24 @@ BOOT_TARGET_DEVICES_references_MMC_without_CONFIG_CMD_MMC #endif +#ifdef CONFIG_CMD_UBIFS +#define BOOTENV_SHARED_UBIFS \ + "ubifs_boot=" \ + "if ubi part UBI && ubifsmount ubi${devnum}:boot; then " \ + "setenv devtype ubi; " \ + "setenv bootpart 0; " \ + "run scan_dev_for_boot; " \ + "fi\0" +#define BOOTENV_DEV_UBIFS BOOTENV_DEV_BLKDEV +#define BOOTENV_DEV_NAME_UBIFS BOOTENV_DEV_NAME_BLKDEV +#else +#define BOOTENV_SHARED_UBIFS +#define BOOTENV_DEV_UBIFS \ + BOOT_TARGET_DEVICES_references_UBIFS_without_CONFIG_CMD_UBIFS +#define BOOTENV_DEV_NAME_UBIFS \ + BOOT_TARGET_DEVICES_references_UBIFS_without_CONFIG_CMD_UBIFS +#endif + #ifdef CONFIG_CMD_SATA #define BOOTENV_SHARED_SATA BOOTENV_SHARED_BLKDEV(sata) #define BOOTENV_DEV_SATA BOOTENV_DEV_BLKDEV @@ -185,6 +203,7 @@ BOOTENV_SHARED_SATA \ BOOTENV_SHARED_SCSI \ BOOTENV_SHARED_IDE \ + BOOTENV_SHARED_UBIFS \ "boot_prefixes=/ /boot/\0" \ "boot_scripts=boot.scr.uimg boot.scr\0" \ "boot_script_dhcp=boot.scr.uimg\0" \ diff --git a/include/configs/B4860QDS.h b/include/configs/B4860QDS.h index 858e25dbc3c..c83e5cea4b7 100644 --- a/include/configs/B4860QDS.h +++ b/include/configs/B4860QDS.h @@ -7,7 +7,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/BSC9131RDB.h b/include/configs/BSC9131RDB.h index 226a170c4d0..2754016b05c 100644 --- a/include/configs/BSC9131RDB.h +++ b/include/configs/BSC9131RDB.h @@ -11,7 +11,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifdef CONFIG_BSC9131RDB diff --git a/include/configs/BSC9132QDS.h b/include/configs/BSC9132QDS.h index e54544789a0..a006dcebaaa 100644 --- a/include/configs/BSC9132QDS.h +++ b/include/configs/BSC9132QDS.h @@ -11,13 +11,13 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifdef CONFIG_BSC9132QDS #define CONFIG_BSC9132 #endif +#define CONFIG_FSL_CLK #define CONFIG_MISC_INIT_R #ifdef CONFIG_SDCARD diff --git a/include/configs/C29XPCIE.h b/include/configs/C29XPCIE.h index f574994219a..94f991b4f76 100644 --- a/include/configs/C29XPCIE.h +++ b/include/configs/C29XPCIE.h @@ -12,7 +12,6 @@ #define __CONFIG_H #define CONFIG_PHYS_64BIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifdef CONFIG_C29XPCIE diff --git a/include/configs/CPCI2DP.h b/include/configs/CPCI2DP.h index ce7bc35dd93..e00ab043e65 100644 --- a/include/configs/CPCI2DP.h +++ b/include/configs/CPCI2DP.h @@ -20,7 +20,6 @@ #define CONFIG_405GP 1 /* This is a PPC405 CPU */ #define CONFIG_SYS_TEXT_BASE 0xFFFC0000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_BOARD_EARLY_INIT_F 1 /* call board_early_init_f() */ diff --git a/include/configs/CPCI4052.h b/include/configs/CPCI4052.h index 2827a04814a..332a1df37d4 100644 --- a/include/configs/CPCI4052.h +++ b/include/configs/CPCI4052.h @@ -23,7 +23,6 @@ #undef CONFIG_CPCI405_6U /* enable this for 6U boards */ #define CONFIG_SYS_TEXT_BASE 0xFFFC0000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_BOARD_EARLY_INIT_F 1 /* call board_early_init_f() */ diff --git a/include/configs/MIP405.h b/include/configs/MIP405.h index 0757e67b57f..ec62c8a0657 100644 --- a/include/configs/MIP405.h +++ b/include/configs/MIP405.h @@ -21,7 +21,6 @@ #define CONFIG_SYS_TEXT_BASE 0xFFF80000 -#define CONFIG_SYS_GENERIC_BOARD /*********************************************************** * Note that it may also be a MIP405T board which is a subset of the diff --git a/include/configs/MPC8308RDB.h b/include/configs/MPC8308RDB.h index 4150d5aad05..cfa59313111 100644 --- a/include/configs/MPC8308RDB.h +++ b/include/configs/MPC8308RDB.h @@ -9,8 +9,8 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK /* * High Level Configuration Options diff --git a/include/configs/MPC8313ERDB.h b/include/configs/MPC8313ERDB.h index d558db7e50c..7db67c2c614 100644 --- a/include/configs/MPC8313ERDB.h +++ b/include/configs/MPC8313ERDB.h @@ -10,7 +10,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/MPC8315ERDB.h b/include/configs/MPC8315ERDB.h index cbe10af19f1..eb50be609e0 100644 --- a/include/configs/MPC8315ERDB.h +++ b/include/configs/MPC8315ERDB.h @@ -9,7 +9,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_NAND_U_BOOT_SIZE (512 << 10) diff --git a/include/configs/MPC8323ERDB.h b/include/configs/MPC8323ERDB.h index 7547c129967..59d5e564aef 100644 --- a/include/configs/MPC8323ERDB.h +++ b/include/configs/MPC8323ERDB.h @@ -9,7 +9,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/MPC832XEMDS.h b/include/configs/MPC832XEMDS.h index 9805df75b99..5ab7d5f0e8c 100644 --- a/include/configs/MPC832XEMDS.h +++ b/include/configs/MPC832XEMDS.h @@ -7,7 +7,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index 57547a48bf3..988a90091d4 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h index 834786d9406..091ca1783e9 100644 --- a/include/configs/MPC8349ITX.h +++ b/include/configs/MPC8349ITX.h @@ -40,7 +40,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #if (CONFIG_SYS_TEXT_BASE == 0xFE000000) diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h index cebd175ff59..990fc04e870 100644 --- a/include/configs/MPC837XEMDS.h +++ b/include/configs/MPC837XEMDS.h @@ -8,8 +8,8 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK /* * High Level Configuration Options diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h index 5c6ad193c0b..fcc531b6001 100644 --- a/include/configs/MPC837XERDB.h +++ b/include/configs/MPC837XERDB.h @@ -16,7 +16,7 @@ #define CONFIG_MPC837x 1 /* MPC837x CPU specific */ #define CONFIG_MPC837XERDB 1 #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK #define CONFIG_SYS_TEXT_BASE 0xFE000000 diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index 7c51eef9d3f..af8eb8c0d2e 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -11,8 +11,8 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #include "../board/freescale/common/ics307_clk.h" #ifdef CONFIG_36BIT diff --git a/include/configs/MPC8540ADS.h b/include/configs/MPC8540ADS.h index dc6e3954bc5..157ca696629 100644 --- a/include/configs/MPC8540ADS.h +++ b/include/configs/MPC8540ADS.h @@ -18,7 +18,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index bf036038377..68ea5d87912 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index bef28b3d3ad..166fcda2973 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -11,7 +11,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index 2bea6048043..517b4492ee0 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifdef CONFIG_36BIT diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index 80b14cbf4f3..184f5146159 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/MPC8560ADS.h b/include/configs/MPC8560ADS.h index e1bc8ccd325..69ce13cf45a 100644 --- a/include/configs/MPC8560ADS.h +++ b/include/configs/MPC8560ADS.h @@ -18,7 +18,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index 064bd850903..f6e43ce1f26 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -10,7 +10,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/MPC8569MDS.h b/include/configs/MPC8569MDS.h index 0af670b2041..9f784e0adb9 100644 --- a/include/configs/MPC8569MDS.h +++ b/include/configs/MPC8569MDS.h @@ -10,9 +10,9 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK /* High Level Configuration Options */ #define CONFIG_BOOKE 1 /* BOOKE */ #define CONFIG_E500 1 /* BOOKE e500 family */ diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index 4b5467b4a84..19da4775a21 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -11,7 +11,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #include "../board/freescale/common/ics307_clk.h" diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index 9a487e0a23e..4ce04a84aa5 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index f20ee79e872..6f1535ec1ec 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -16,7 +16,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* High Level Configuration Options */ diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h index b85e19570a1..9e407303954 100644 --- a/include/configs/P1010RDB.h +++ b/include/configs/P1010RDB.h @@ -14,8 +14,8 @@ #ifdef CONFIG_36BIT #define CONFIG_PHYS_64BIT #endif -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #define CONFIG_P1010 #define CONFIG_E500 /* BOOKE e500 family */ diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h index 95c81ab4fbd..c571fac666e 100644 --- a/include/configs/P1022DS.h +++ b/include/configs/P1022DS.h @@ -11,8 +11,8 @@ #include "../board/freescale/common/ics307_clk.h" -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #ifdef CONFIG_36BIT #define CONFIG_PHYS_64BIT diff --git a/include/configs/P1023RDB.h b/include/configs/P1023RDB.h index e61db18d0c6..4d87198e437 100644 --- a/include/configs/P1023RDB.h +++ b/include/configs/P1023RDB.h @@ -10,7 +10,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifndef CONFIG_SYS_TEXT_BASE diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index de205e82caf..0cd990477b1 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -13,9 +13,9 @@ #define CONFIG_P2041RDB #define CONFIG_PHYS_64BIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_PPC_P2041 +#define CONFIG_FSL_CLK #ifdef CONFIG_RAMBOOT_PBL #define CONFIG_RAMBOOT_TEXT_BASE CONFIG_SYS_TEXT_BASE diff --git a/include/configs/PATI.h b/include/configs/PATI.h index 5d0e4220412..81d535f9d18 100644 --- a/include/configs/PATI.h +++ b/include/configs/PATI.h @@ -21,7 +21,6 @@ #define CONFIG_SYS_TEXT_BASE 0xFFF00000 -#define CONFIG_SYS_GENERIC_BOARD /* Serial Console Configuration */ #define CONFIG_5xx_CONS_SCI1 diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h index 4601bc8accc..45eecc42b05 100644 --- a/include/configs/PIP405.h +++ b/include/configs/PIP405.h @@ -21,7 +21,6 @@ #define CONFIG_SYS_TEXT_BASE 0xFFF80000 -#define CONFIG_SYS_GENERIC_BOARD /*********************************************************** * Clock diff --git a/include/configs/PLU405.h b/include/configs/PLU405.h index d5d30926e36..d668a153793 100644 --- a/include/configs/PLU405.h +++ b/include/configs/PLU405.h @@ -21,7 +21,6 @@ #define CONFIG_PLU405 1 /* ...on a PLU405 board */ #define CONFIG_SYS_TEXT_BASE 0xFFF80000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_BOARD_EARLY_INIT_F 1 /* call board_early_init_f() */ diff --git a/include/configs/PMC405DE.h b/include/configs/PMC405DE.h index 2f35ca9417c..0fdd7e24b1c 100644 --- a/include/configs/PMC405DE.h +++ b/include/configs/PMC405DE.h @@ -12,7 +12,6 @@ #define CONFIG_PMC405DE 1 /* ...on a PMC405DE board */ #define CONFIG_SYS_TEXT_BASE 0xFFFC0000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_BOARD_EARLY_INIT_F 1 /* call board_early_init_f() */ diff --git a/include/configs/PMC440.h b/include/configs/PMC440.h index fad57443988..022764932d7 100644 --- a/include/configs/PMC440.h +++ b/include/configs/PMC440.h @@ -29,7 +29,6 @@ #define CONFIG_SYS_TEXT_BASE 0xFFF90000 #endif -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_CLK_FREQ 33333400 diff --git a/include/configs/T102xQDS.h b/include/configs/T102xQDS.h index c9e5ea9c73e..4f22657703d 100644 --- a/include/configs/T102xQDS.h +++ b/include/configs/T102xQDS.h @@ -12,7 +12,6 @@ #define __T1024QDS_H /* High Level Configuration Options */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_BOOKE #define CONFIG_E500 /* BOOKE e500 family */ @@ -21,6 +20,7 @@ #define CONFIG_MP /* support multiple processors */ #define CONFIG_PHYS_64BIT #define CONFIG_ENABLE_36BIT_PHYS +#define CONFIG_FSL_CLK #ifdef CONFIG_PHYS_64BIT #define CONFIG_ADDR_MAP 1 diff --git a/include/configs/T102xRDB.h b/include/configs/T102xRDB.h index 0601d73d234..d412d0b2b7e 100644 --- a/include/configs/T102xRDB.h +++ b/include/configs/T102xRDB.h @@ -12,7 +12,6 @@ #define __T1024RDB_H /* High Level Configuration Options */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_BOOKE #define CONFIG_E500 /* BOOKE e500 family */ @@ -21,6 +20,7 @@ #define CONFIG_MP /* support multiple processors */ #define CONFIG_PHYS_64BIT #define CONFIG_ENABLE_36BIT_PHYS +#define CONFIG_FSL_CLK #ifdef CONFIG_PHYS_64BIT #define CONFIG_ADDR_MAP 1 diff --git a/include/configs/T1040QDS.h b/include/configs/T1040QDS.h index 4b735b54940..18df2372a48 100644 --- a/include/configs/T1040QDS.h +++ b/include/configs/T1040QDS.h @@ -28,8 +28,8 @@ */ #define CONFIG_T1040QDS #define CONFIG_PHYS_64BIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #ifdef CONFIG_RAMBOOT_PBL #define CONFIG_RAMBOOT_TEXT_BASE CONFIG_SYS_TEXT_BASE diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h index 7f8d110c14d..20910156386 100644 --- a/include/configs/T104xRDB.h +++ b/include/configs/T104xRDB.h @@ -12,8 +12,8 @@ */ #define CONFIG_T104xRDB #define CONFIG_PHYS_64BIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #define CONFIG_E500 /* BOOKE e500 family */ #include <asm/config_mpc85xx.h> diff --git a/include/configs/T208xQDS.h b/include/configs/T208xQDS.h index a804cbe9aa2..d35b9d2d901 100644 --- a/include/configs/T208xQDS.h +++ b/include/configs/T208xQDS.h @@ -11,9 +11,9 @@ #ifndef __T208xQDS_H #define __T208xQDS_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_ICS307_REFCLK_HZ 25000000 /* ICS307 ref clk freq */ +#define CONFIG_FSL_CLK #define CONFIG_MMC #define CONFIG_USB_EHCI #if defined(CONFIG_PPC_T2080) diff --git a/include/configs/T208xRDB.h b/include/configs/T208xRDB.h index 307a0ea02a5..c632b8e328f 100644 --- a/include/configs/T208xRDB.h +++ b/include/configs/T208xRDB.h @@ -11,10 +11,10 @@ #ifndef __T2080RDB_H #define __T2080RDB_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_T2080RDB #define CONFIG_ICS307_REFCLK_HZ 25000000 /* ICS307 ref clk freq */ +#define CONFIG_FSL_CLK #define CONFIG_MMC #define CONFIG_USB_EHCI #define CONFIG_FSL_SATA_V2 diff --git a/include/configs/T4240QDS.h b/include/configs/T4240QDS.h index 4edb3cb91f3..dd8dd73f986 100644 --- a/include/configs/T4240QDS.h +++ b/include/configs/T4240QDS.h @@ -12,6 +12,7 @@ #define CONFIG_T4240QDS #define CONFIG_PHYS_64BIT +#define CONFIG_FSL_CLK #define CONFIG_FSL_SATA_V2 #define CONFIG_PCIE4 diff --git a/include/configs/T4240RDB.h b/include/configs/T4240RDB.h index 754d182c3a4..2c5f800cbd2 100644 --- a/include/configs/T4240RDB.h +++ b/include/configs/T4240RDB.h @@ -12,8 +12,8 @@ #define CONFIG_T4240RDB #define CONFIG_PHYS_64BIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #define CONFIG_FSL_SATA_V2 #define CONFIG_PCIE4 diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index 5a59b80d50d..342fdfe24a6 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -19,7 +19,6 @@ #define CONFIG_MPC5200 1 /* This is an MPC5200 CPU */ #define CONFIG_TQM5200 1 /* ... on TQM5200 module */ #undef CONFIG_TQM5200_REV100 /* define for revision 100 modules */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/TQM823L.h b/include/configs/TQM823L.h index cea314915f6..013e40e3b9c 100644 --- a/include/configs/TQM823L.h +++ b/include/configs/TQM823L.h @@ -19,7 +19,6 @@ #define CONFIG_MPC823 1 /* This is a MPC823 CPU */ #define CONFIG_TQM823L 1 /* ...on a TQM8xxL module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM823M.h b/include/configs/TQM823M.h index 85215b132c1..fbb2f849593 100644 --- a/include/configs/TQM823M.h +++ b/include/configs/TQM823M.h @@ -19,7 +19,6 @@ #define CONFIG_MPC823 1 /* This is a MPC823 CPU */ #define CONFIG_TQM823M 1 /* ...on a TQM8xxM module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index 4164303e94f..0b046d13fbb 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -12,7 +12,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/TQM850L.h b/include/configs/TQM850L.h index 97a9fa7ebea..00771051f04 100644 --- a/include/configs/TQM850L.h +++ b/include/configs/TQM850L.h @@ -19,7 +19,6 @@ #define CONFIG_MPC850 1 /* This is a MPC850 CPU */ #define CONFIG_TQM850L 1 /* ...on a TQM8xxL module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM850M.h b/include/configs/TQM850M.h index 636ffc830bc..4a443eda23a 100644 --- a/include/configs/TQM850M.h +++ b/include/configs/TQM850M.h @@ -19,7 +19,6 @@ #define CONFIG_MPC850 1 /* This is a MPC850 CPU */ #define CONFIG_TQM850M 1 /* ...on a TQM8xxM module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM855L.h b/include/configs/TQM855L.h index 3c82c73e3ea..3fbc1ad1287 100644 --- a/include/configs/TQM855L.h +++ b/include/configs/TQM855L.h @@ -19,7 +19,6 @@ #define CONFIG_MPC855 1 /* This is a MPC855 CPU */ #define CONFIG_TQM855L 1 /* ...on a TQM8xxL module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM855M.h b/include/configs/TQM855M.h index 66f9a88f9c1..d2729d6d72f 100644 --- a/include/configs/TQM855M.h +++ b/include/configs/TQM855M.h @@ -19,7 +19,6 @@ #define CONFIG_MPC855 1 /* This is a MPC855 CPU */ #define CONFIG_TQM855M 1 /* ...on a TQM8xxM module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM860L.h b/include/configs/TQM860L.h index 3e20c7161d1..764568df667 100644 --- a/include/configs/TQM860L.h +++ b/include/configs/TQM860L.h @@ -19,7 +19,6 @@ #define CONFIG_MPC860 1 /* This is a MPC860 CPU */ #define CONFIG_TQM860L 1 /* ...on a TQM8xxL module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM860M.h b/include/configs/TQM860M.h index be1cd3adc5a..0894f59832a 100644 --- a/include/configs/TQM860M.h +++ b/include/configs/TQM860M.h @@ -19,7 +19,6 @@ #define CONFIG_MPC860 1 /* This is a MPC860 CPU */ #define CONFIG_TQM860M 1 /* ...on a TQM8xxM module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM862L.h b/include/configs/TQM862L.h index f07b903314e..9650b8d0b85 100644 --- a/include/configs/TQM862L.h +++ b/include/configs/TQM862L.h @@ -20,7 +20,6 @@ #define CONFIG_MPC860 1 #define CONFIG_MPC860T 1 #define CONFIG_MPC862 1 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_TQM862L 1 /* ...on a TQM8xxL module */ diff --git a/include/configs/TQM862M.h b/include/configs/TQM862M.h index c887a397009..8b8db89e0ee 100644 --- a/include/configs/TQM862M.h +++ b/include/configs/TQM862M.h @@ -20,7 +20,6 @@ #define CONFIG_MPC860 1 #define CONFIG_MPC860T 1 #define CONFIG_MPC862 1 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_TQM862M 1 /* ...on a TQM8xxM module */ diff --git a/include/configs/TQM866M.h b/include/configs/TQM866M.h index a037b4fce5c..a011d2e76c3 100644 --- a/include/configs/TQM866M.h +++ b/include/configs/TQM866M.h @@ -19,7 +19,6 @@ #define CONFIG_MPC866 1 /* This is a MPC866 CPU */ #define CONFIG_TQM866M 1 /* ...on a TQM8xxM module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/TQM885D.h b/include/configs/TQM885D.h index 76ddef54e64..023736ef2b3 100644 --- a/include/configs/TQM885D.h +++ b/include/configs/TQM885D.h @@ -22,7 +22,6 @@ #define CONFIG_MPC885 1 /* This is a MPC885 CPU */ #define CONFIG_TQM885D 1 /* ...on a TQM88D module */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0x40000000 diff --git a/include/configs/UCP1020.h b/include/configs/UCP1020.h index 08011172415..0b609af2c90 100644 --- a/include/configs/UCP1020.h +++ b/include/configs/UCP1020.h @@ -14,8 +14,8 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #define CONFIG_FSL_ELBC #define CONFIG_PCI diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index bfcfb405fad..42af34fdc60 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -27,7 +27,6 @@ #define CONFIG_SYS_TEXT_BASE 0x0 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH diff --git a/include/configs/VOM405.h b/include/configs/VOM405.h index 99ee78b885b..60f266c3458 100644 --- a/include/configs/VOM405.h +++ b/include/configs/VOM405.h @@ -19,7 +19,6 @@ #define CONFIG_VOM405 1 /* ...on a VOM405 board */ #define CONFIG_SYS_TEXT_BASE 0xFFFC8000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_BOARD_EARLY_INIT_F 1 /* call board_early_init_f() */ diff --git a/include/configs/a3m071.h b/include/configs/a3m071.h index fc4595b27cf..4839ede8d44 100644 --- a/include/configs/a3m071.h +++ b/include/configs/a3m071.h @@ -15,7 +15,6 @@ #define CONFIG_MPC5200 #define CONFIG_A3M071 /* A3M071 board */ #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_TEXT_BASE 0x01000000 /* boot low for 32 MiB boards */ diff --git a/include/configs/a4m072.h b/include/configs/a4m072.h index 1be78fdf330..0ff5164ce68 100644 --- a/include/configs/a4m072.h +++ b/include/configs/a4m072.h @@ -20,7 +20,6 @@ #define CONFIG_A4M072 1 /* ... on A4M072 board */ #define CONFIG_MPC5200_DDR 1 /* ... use DDR RAM */ #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_TEXT_BASE 0xFE000000 diff --git a/include/configs/ac14xx.h b/include/configs/ac14xx.h index f05d9ecd149..320be8fd1b2 100644 --- a/include/configs/ac14xx.h +++ b/include/configs/ac14xx.h @@ -14,7 +14,6 @@ #define CONFIG_AC14XX 1 #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD /* * Memory map for the ifm AC14xx board: diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h index 654b7780d19..0bf0af7f3d0 100644 --- a/include/configs/am3517_crane.h +++ b/include/configs/am3517_crane.h @@ -19,7 +19,6 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP3_AM3517CRANE 1 /* working with CRANEBOARD */ #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h index 70490910d73..9aa14f43fb2 100644 --- a/include/configs/am3517_evm.h +++ b/include/configs/am3517_evm.h @@ -19,7 +19,6 @@ #define CONFIG_OMAP 1 /* in a TI OMAP core */ #define CONFIG_OMAP3_AM3517EVM 1 /* working with AM3517EVM */ #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/amcc-common.h b/include/configs/amcc-common.h index c5ef6509507..e87c0cb5d9c 100644 --- a/include/configs/amcc-common.h +++ b/include/configs/amcc-common.h @@ -10,7 +10,6 @@ #ifndef __AMCC_COMMON_H #define __AMCC_COMMON_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_SDRAM_BASE 0x00000000 /* _must_ be 0 */ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* Start of U-Boot */ diff --git a/include/configs/apf27.h b/include/configs/apf27.h index 49fbcac7760..5b286d24fec 100644 --- a/include/configs/apf27.h +++ b/include/configs/apf27.h @@ -20,7 +20,6 @@ */ #define CONFIG_MX27 /* This is a Freescale i.MX27 Chip */ #define CONFIG_MACH_TYPE 1698 /* APF27 */ -#define CONFIG_SYS_GENERIC_BOARD /* * Enable the call to miscellaneous platform dependent initialization. diff --git a/include/configs/aria.h b/include/configs/aria.h index 2265f3e7744..c38bf3cfb02 100644 --- a/include/configs/aria.h +++ b/include/configs/aria.h @@ -14,7 +14,6 @@ #define CONFIG_ARIA 1 #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD /* * Memory map for the ARIA board: diff --git a/include/configs/armadillo-800eva.h b/include/configs/armadillo-800eva.h index 7f5cbccb177..dfbd60d19c5 100644 --- a/include/configs/armadillo-800eva.h +++ b/include/configs/armadillo-800eva.h @@ -41,7 +41,6 @@ #define CONFIG_USE_ARCH_MEMCPY #define CONFIG_TMU_TIMER #define CONFIG_SYS_DCACHE_OFF -#define CONFIG_SYS_GENERIC_BOARD /* STACK */ #define CONFIG_SYS_INIT_SP_ADDR 0xE8083000 diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h index 62c537448b9..fcb5f81a10a 100644 --- a/include/configs/aspenite.h +++ b/include/configs/aspenite.h @@ -11,11 +11,6 @@ #define __CONFIG_ASPENITE_H /* - * Generic board support - */ -#define CONFIG_SYS_GENERIC_BOARD - -/* * Version number information */ #define CONFIG_IDENT_STRING "\nMarvell-Aspenite DB" diff --git a/include/configs/at91-sama5_common.h b/include/configs/at91-sama5_common.h index a5990cec030..f9385349ae0 100644 --- a/include/configs/at91-sama5_common.h +++ b/include/configs/at91-sama5_common.h @@ -31,7 +31,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT /* Device Tree support */ -#define CONFIG_SYS_GENERIC_BOARD /* general purpose I/O */ #define CONFIG_AT91_GPIO diff --git a/include/configs/at91rm9200ek.h b/include/configs/at91rm9200ek.h index 7e026ef4542..9274024fb0b 100644 --- a/include/configs/at91rm9200ek.h +++ b/include/configs/at91rm9200ek.h @@ -61,7 +61,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD /* * Memory Configuration diff --git a/include/configs/at91sam9260ek.h b/include/configs/at91sam9260ek.h index 619f5dab177..cc3e69cdf7f 100644 --- a/include/configs/at91sam9260ek.h +++ b/include/configs/at91sam9260ek.h @@ -48,7 +48,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index 4d260e9fa89..64fb38bad6e 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -33,7 +33,6 @@ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_ATMEL_LEGACY #define CONFIG_SYS_TEXT_BASE 0x21f00000 diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index 2f251db1aeb..89ee9fe3e2b 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -48,7 +48,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD /* * Hardware drivers diff --git a/include/configs/at91sam9m10g45ek.h b/include/configs/at91sam9m10g45ek.h index 70eaf1d6024..cc42c909d41 100644 --- a/include/configs/at91sam9m10g45ek.h +++ b/include/configs/at91sam9m10g45ek.h @@ -33,7 +33,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ diff --git a/include/configs/at91sam9n12ek.h b/include/configs/at91sam9n12ek.h index 44f821be05b..8fa5ff5fc00 100644 --- a/include/configs/at91sam9n12ek.h +++ b/include/configs/at91sam9n12ek.h @@ -31,7 +31,6 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD /* general purpose I/O */ #define CONFIG_AT91_GPIO diff --git a/include/configs/at91sam9rlek.h b/include/configs/at91sam9rlek.h index cba927acb40..a7a0502dfdd 100644 --- a/include/configs/at91sam9rlek.h +++ b/include/configs/at91sam9rlek.h @@ -34,7 +34,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_ATMEL_LEGACY #define CONFIG_AT91_GPIO 1 diff --git a/include/configs/at91sam9x5ek.h b/include/configs/at91sam9x5ek.h index 2068e0de04a..20a5581cf2b 100644 --- a/include/configs/at91sam9x5ek.h +++ b/include/configs/at91sam9x5ek.h @@ -29,7 +29,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ diff --git a/include/configs/bcm28155_ap.h b/include/configs/bcm28155_ap.h index 7b48875d638..6ea6fb07f98 100644 --- a/include/configs/bcm28155_ap.h +++ b/include/configs/bcm28155_ap.h @@ -13,7 +13,6 @@ /* CPU, chip, mach, etc */ #define CONFIG_KONA #define CONFIG_SKIP_LOWLEVEL_INIT -#define CONFIG_SYS_GENERIC_BOARD /* * Memory configuration diff --git a/include/configs/bcm_ep_board.h b/include/configs/bcm_ep_board.h index ba26964feaa..c3ebb4d1163 100644 --- a/include/configs/bcm_ep_board.h +++ b/include/configs/bcm_ep_board.h @@ -11,7 +11,6 @@ #define CONFIG_SKIP_LOWLEVEL_INIT -#define CONFIG_SYS_GENERIC_BOARD /* * Memory configuration diff --git a/include/configs/bur_am335x_common.h b/include/configs/bur_am335x_common.h index c6960920b2b..1d96a2dde74 100644 --- a/include/configs/bur_am335x_common.h +++ b/include/configs/bur_am335x_common.h @@ -26,7 +26,6 @@ #define CONFIG_PREBOOT "run brdefaultip" #define CONFIG_CMD_TIME -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_AM33XX #define CONFIG_OMAP diff --git a/include/configs/calimain.h b/include/configs/calimain.h index c8b15fb5342..a5b2f9e6417 100644 --- a/include/configs/calimain.h +++ b/include/configs/calimain.h @@ -18,7 +18,6 @@ #define CONFIG_DRIVER_TI_EMAC #define MACH_TYPE_CALIMAIN 3528 #define CONFIG_MACH_TYPE MACH_TYPE_CALIMAIN -#define CONFIG_SYS_GENERIC_BOARD /* * SoC Configuration diff --git a/include/configs/canmb.h b/include/configs/canmb.h index 36cd50b71e1..2a6c09f2204 100644 --- a/include/configs/canmb.h +++ b/include/configs/canmb.h @@ -15,7 +15,6 @@ #define CONFIG_MPC5200 1 /* This is a MPC5200 CPU */ #define CONFIG_CANMB 1 /* ... on canmb board - we need this for FEC.C */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/cm5200.h b/include/configs/cm5200.h index 4607d9f6bc8..69b26746c86 100644 --- a/include/configs/cm5200.h +++ b/include/configs/cm5200.h @@ -9,7 +9,6 @@ #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h index e5fb474afce..e951b2d5d16 100644 --- a/include/configs/cm_t35.h +++ b/include/configs/cm_t35.h @@ -25,7 +25,6 @@ #define CONFIG_CMD_GPIO #define CONFIG_CM_T3X /* working with CM-T35 and CM-T3730 */ #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/cm_t3517.h b/include/configs/cm_t3517.h index f3d1f4352e4..8a10e9c6f0b 100644 --- a/include/configs/cm_t3517.h +++ b/include/configs/cm_t3517.h @@ -16,7 +16,6 @@ #define CONFIG_OMAP /* in a TI OMAP core */ #define CONFIG_CM_T3517 /* working with CM-T3517 */ #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/cm_t54.h b/include/configs/cm_t54.h index 95a5a606e33..6d57cd6eb58 100644 --- a/include/configs/cm_t54.h +++ b/include/configs/cm_t54.h @@ -18,9 +18,6 @@ #undef CONFIG_SPL_OS_BOOT -/* Enable Generic board */ -#define CONFIG_SYS_GENERIC_BOARD - /* Device Tree defines */ #define CONFIG_OF_LIBFDT #define CONFIG_OF_BOARD_SETUP diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h index 4efc9c5f3e6..0fc24a04ce8 100644 --- a/include/configs/colibri_pxa270.h +++ b/include/configs/colibri_pxa270.h @@ -14,7 +14,6 @@ * High Level Board Configuration Options */ #define CONFIG_CPU_PXA27X 1 /* Marvell PXA270 CPU */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_TEXT_BASE 0x0 /* Avoid overwriting factory configuration block */ #define CONFIG_BOARD_SIZE_LIMIT 0x40000 diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h index 258315576cd..9fa8f817f29 100644 --- a/include/configs/colibri_vf.h +++ b/include/configs/colibri_vf.h @@ -18,8 +18,8 @@ #define CONFIG_SYS_THUMB_BUILD #define CONFIG_USE_ARCH_MEMCPY #define CONFIG_USE_ARCH_MEMSET +#define CONFIG_FSL_CLK -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_ARCH_MISC_INIT #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/controlcenterd.h b/include/configs/controlcenterd.h index c8790488532..77c2edcbb3c 100644 --- a/include/configs/controlcenterd.h +++ b/include/configs/controlcenterd.h @@ -44,8 +44,8 @@ #define CONFIG_P1022 #define CONFIG_CONTROLCENTERD #define CONFIG_MP /* support multiple processors */ +#define CONFIG_FSL_CLK -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_NO_FLASH #define CONFIG_ENABLE_36BIT_PHYS diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 878fda2f807..3c9a5291622 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -10,8 +10,8 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #include "../board/freescale/common/ics307_clk.h" diff --git a/include/configs/corvus.h b/include/configs/corvus.h index 68056125e9a..97797e2b96d 100644 --- a/include/configs/corvus.h +++ b/include/configs/corvus.h @@ -17,7 +17,6 @@ #include <asm/hardware.h> #include <linux/sizes.h> -#define CONFIG_SYS_GENERIC_BOARD /* * Warning: changing CONFIG_SYS_TEXT_BASE requires * adapting the initial boot program. diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index 1cd11c0ded2..5aa643ac6aa 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -258,7 +258,6 @@ /* * U-Boot general configuration */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_MISC_INIT_R #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOOTFILE "uImage" /* Boot file name */ diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h index 74e5b4759f9..9a0596c5118 100644 --- a/include/configs/db-88f6820-gp.h +++ b/include/configs/db-88f6820-gp.h @@ -19,7 +19,6 @@ #ifdef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ #endif -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO_LATE /* diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h index 672518b83fa..b3b2de942f3 100644 --- a/include/configs/db-mv784mp-gp.h +++ b/include/configs/db-mv784mp-gp.h @@ -16,7 +16,6 @@ #ifdef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ #endif -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO_LATE /* diff --git a/include/configs/digsy_mtc.h b/include/configs/digsy_mtc.h index 02b8f91d339..f802c8dd7eb 100644 --- a/include/configs/digsy_mtc.h +++ b/include/configs/digsy_mtc.h @@ -23,7 +23,6 @@ #define CONFIG_MPC5200 1 /* This is an MPC5200 CPU */ #define CONFIG_DIGSY_MTC 1 /* ... on InterControl digsyMTC board */ #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD /* * Valid values for CONFIG_SYS_TEXT_BASE are: diff --git a/include/configs/dlvision-10g.h b/include/configs/dlvision-10g.h index e39f8ba7afb..0b804ebdd7f 100644 --- a/include/configs/dlvision-10g.h +++ b/include/configs/dlvision-10g.h @@ -24,7 +24,6 @@ #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_MISC_INIT_R #define CONFIG_LAST_STAGE_INIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */ diff --git a/include/configs/dlvision.h b/include/configs/dlvision.h index 3c0553489e3..90e839ab1bb 100644 --- a/include/configs/dlvision.h +++ b/include/configs/dlvision.h @@ -22,7 +22,6 @@ #define CONFIG_BOARD_EARLY_INIT_F /* call board_early_init_f */ #define CONFIG_MISC_INIT_R /* call misc_init_r */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */ diff --git a/include/configs/dns325.h b/include/configs/dns325.h index 54be415712b..c59a3242d61 100644 --- a/include/configs/dns325.h +++ b/include/configs/dns325.h @@ -26,7 +26,6 @@ #define CONFIG_FEROCEON_88FR131 /* CPU Core subversion */ #define CONFIG_KW88F6281 /* SOC Name */ #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ -#define CONFIG_SYS_GENERIC_BOARD /* * Commands configuration diff --git a/include/configs/dockstar.h b/include/configs/dockstar.h index 6ebd703d32d..efe58071a50 100644 --- a/include/configs/dockstar.h +++ b/include/configs/dockstar.h @@ -12,7 +12,6 @@ #ifndef _CONFIG_DOCKSTAR_H #define _CONFIG_DOCKSTAR_H -#define CONFIG_SYS_GENERIC_BOARD /* * Version number information diff --git a/include/configs/dreamplug.h b/include/configs/dreamplug.h index 133c7f4a35e..2815ad86230 100644 --- a/include/configs/dreamplug.h +++ b/include/configs/dreamplug.h @@ -37,7 +37,6 @@ #define CONFIG_KW88F6281 1 /* SOC Name */ #define CONFIG_MACH_TYPE MACH_TYPE_DREAMPLUG #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ -#define CONFIG_SYS_GENERIC_BOARD /* Add target to build it automatically upon "make" */ #define CONFIG_BUILD_TARGET "u-boot.kwb" diff --git a/include/configs/ea20.h b/include/configs/ea20.h index 2d1f1b3db91..b230d9cecbf 100644 --- a/include/configs/ea20.h +++ b/include/configs/ea20.h @@ -24,7 +24,6 @@ #define CONFIG_VIDEO #define CONFIG_PREBOOT -#define CONFIG_SYS_GENERIC_BOARD /* * SoC Configuration diff --git a/include/configs/edb93xx.h b/include/configs/edb93xx.h index e3e32aa0814..9fce1cda6b3 100644 --- a/include/configs/edb93xx.h +++ b/include/configs/edb93xx.h @@ -25,7 +25,6 @@ #error "no board defined" #endif -#define CONFIG_SYS_GENERIC_BOARD /* Initial environment and monitor configuration options. */ #define CONFIG_BOOTDELAY 2 diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h index 8b38d7e75f1..7fb1894c58e 100644 --- a/include/configs/edminiv2.h +++ b/include/configs/edminiv2.h @@ -12,9 +12,6 @@ #ifndef _CONFIG_EDMINIV2_H #define _CONFIG_EDMINIV2_H -/* general settings */ -#define CONFIG_SYS_GENERIC_BOARD - /* * SPL */ diff --git a/include/configs/ethernut5.h b/include/configs/ethernut5.h index b49b9031c69..d6e04568889 100644 --- a/include/configs/ethernut5.h +++ b/include/configs/ethernut5.h @@ -12,7 +12,6 @@ #include <asm/hardware.h> -#define CONFIG_SYS_GENERIC_BOARD /* The first stage boot loader expects u-boot running at this address. */ #define CONFIG_SYS_TEXT_BASE 0x27000000 /* 16MB available */ diff --git a/include/configs/exynos-common.h b/include/configs/exynos-common.h index d7bf80b69bd..852829c344c 100644 --- a/include/configs/exynos-common.h +++ b/include/configs/exynos-common.h @@ -16,7 +16,6 @@ #include <asm/arch/cpu.h> /* get chip and board defs */ #include <linux/sizes.h> -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_ARCH_CPU_INIT #define CONFIG_DISPLAY_CPUINFO diff --git a/include/configs/flea3.h b/include/configs/flea3.h index f646feefa9e..15905b98406 100644 --- a/include/configs/flea3.h +++ b/include/configs/flea3.h @@ -22,7 +22,6 @@ #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_DISPLAY_CPUINFO -#define CONFIG_SYS_GENERIC_BOARD /* Only in case the value is not present in mach-types.h */ #ifndef MACH_TYPE_FLEA3 diff --git a/include/configs/gdppc440etx.h b/include/configs/gdppc440etx.h index bfaba42643e..b514278fc39 100644 --- a/include/configs/gdppc440etx.h +++ b/include/configs/gdppc440etx.h @@ -32,7 +32,6 @@ #define CONFIG_BOARD_EARLY_INIT_F 1 /* call board_early_init_f*/ #define CONFIG_MISC_INIT_R 1 /* call misc_init_r() */ -#define CONFIG_SYS_GENERIC_BOARD #undef CONFIG_ZERO_BOOTDELAY_CHECK /* ignore keypress on bootdelay==0 */ diff --git a/include/configs/goflexhome.h b/include/configs/goflexhome.h index 2a42e7c62ed..188d2e21517 100644 --- a/include/configs/goflexhome.h +++ b/include/configs/goflexhome.h @@ -15,7 +15,6 @@ #ifndef _CONFIG_GOFLEXHOME_H #define _CONFIG_GOFLEXHOME_H -#define CONFIG_SYS_GENERIC_BOARD /* * Version number information diff --git a/include/configs/gplugd.h b/include/configs/gplugd.h index 0de6ae80885..f2fd2ae9a36 100644 --- a/include/configs/gplugd.h +++ b/include/configs/gplugd.h @@ -26,11 +26,6 @@ #endif /* - * Generic board support - */ -#define CONFIG_SYS_GENERIC_BOARD - -/* * Version number information */ #define CONFIG_IDENT_STRING "\nMarvell-gplugD" diff --git a/include/configs/guruplug.h b/include/configs/guruplug.h index 5f095677f18..675ec52bcf9 100644 --- a/include/configs/guruplug.h +++ b/include/configs/guruplug.h @@ -10,7 +10,6 @@ #ifndef _CONFIG_GURUPLUG_H #define _CONFIG_GURUPLUG_H -#define CONFIG_SYS_GENERIC_BOARD /* * Version number information diff --git a/include/configs/h2200.h b/include/configs/h2200.h index e8dfa748efa..6fbbe6e0b86 100644 --- a/include/configs/h2200.h +++ b/include/configs/h2200.h @@ -12,7 +12,6 @@ #define MACH_TYPE_H2200 341 #define CONFIG_MACH_TYPE MACH_TYPE_H2200 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_CPU_PXA25X 1 #define CONFIG_BOARD_H2200 diff --git a/include/configs/highbank.h b/include/configs/highbank.h index 7f331a6a73c..f02575ac04c 100644 --- a/include/configs/highbank.h +++ b/include/configs/highbank.h @@ -13,7 +13,6 @@ #define CONFIG_SYS_THUMB_BUILD #define CONFIG_SYS_NO_FLASH -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_OF_BOARD_SETUP #define CONFIG_FIT diff --git a/include/configs/hikey.h b/include/configs/hikey.h index 3af02132f87..1a4381bfe2f 100644 --- a/include/configs/hikey.h +++ b/include/configs/hikey.h @@ -14,8 +14,6 @@ #include <linux/sizes.h> -/* We use generic board for hikey */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_POWER #define CONFIG_POWER_HI6553 diff --git a/include/configs/hrcon.h b/include/configs/hrcon.h index 558edfce8ee..e2b9deba9e1 100644 --- a/include/configs/hrcon.h +++ b/include/configs/hrcon.h @@ -22,8 +22,8 @@ #define CONFIG_IDENT_STRING " hrcon 0.01" -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_LAST_STAGE_INIT diff --git a/include/configs/ib62x0.h b/include/configs/ib62x0.h index 6afe3409298..594fceb457c 100644 --- a/include/configs/ib62x0.h +++ b/include/configs/ib62x0.h @@ -9,7 +9,6 @@ #ifndef _CONFIG_IB62x0_H #define _CONFIG_IB62x0_H -#define CONFIG_SYS_GENERIC_BOARD /* * Version number information diff --git a/include/configs/iconnect.h b/include/configs/iconnect.h index bce97dc069d..adf3703592c 100644 --- a/include/configs/iconnect.h +++ b/include/configs/iconnect.h @@ -9,7 +9,6 @@ #ifndef _CONFIG_ICONNECT_H #define _CONFIG_ICONNECT_H -#define CONFIG_SYS_GENERIC_BOARD /* * Version number information diff --git a/include/configs/ids8313.h b/include/configs/ids8313.h index e60e753e405..ecb7f10ab78 100644 --- a/include/configs/ids8313.h +++ b/include/configs/ids8313.h @@ -19,7 +19,6 @@ #define CONFIG_MPC8313 #define CONFIG_IDS8313 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_FSL_ELBC diff --git a/include/configs/imx31_phycore.h b/include/configs/imx31_phycore.h index 3bea71b969e..235fdd1883b 100644 --- a/include/configs/imx31_phycore.h +++ b/include/configs/imx31_phycore.h @@ -18,7 +18,6 @@ #define CONFIG_MX31 /* This is a mx31 */ #define CONFIG_MX31_CLK32 32000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/inka4x0.h b/include/configs/inka4x0.h index d3034cf10f1..24da83cc006 100644 --- a/include/configs/inka4x0.h +++ b/include/configs/inka4x0.h @@ -18,7 +18,6 @@ #define CONFIG_MPC5200 1 /* This is an MPC5200 CPU */ #define CONFIG_INKA4X0 1 /* INKA4x0 board */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/integrator-common.h b/include/configs/integrator-common.h index a22efd699c1..639a30a310e 100644 --- a/include/configs/integrator-common.h +++ b/include/configs/integrator-common.h @@ -29,7 +29,6 @@ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_OF_LIBFDT /* enable passing a Device Tree */ #define CONFIG_MISC_INIT_R /* call misc_init_r during start up */ -#define CONFIG_SYS_GENERIC_BOARD /* * There are various dependencies on the core module (CM) fitted diff --git a/include/configs/intip.h b/include/configs/intip.h index 18d314006fb..a676a20ebb4 100644 --- a/include/configs/intip.h +++ b/include/configs/intip.h @@ -45,7 +45,6 @@ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */ #define CONFIG_BOARD_EARLY_INIT_R 1 /* Call board_early_init_r */ #define CONFIG_MISC_INIT_R 1 /* Call misc_init_r */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_BOARD_TYPES 1 /* support board types */ #define CONFIG_FIT #define CFG_ALT_MEMTEST diff --git a/include/configs/io.h b/include/configs/io.h index 7d863fafde0..2c457d47752 100644 --- a/include/configs/io.h +++ b/include/configs/io.h @@ -24,7 +24,6 @@ #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_MISC_INIT_R #define CONFIG_LAST_STAGE_INIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */ diff --git a/include/configs/io64.h b/include/configs/io64.h index 94ccb6bab70..25bd01474a1 100644 --- a/include/configs/io64.h +++ b/include/configs/io64.h @@ -43,7 +43,6 @@ #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_MISC_INIT_R #define CONFIG_LAST_STAGE_INIT -#define CONFIG_SYS_GENERIC_BOARD #undef CONFIG_ZERO_BOOTDELAY_CHECK /* ignore keypress on bootdelay==0 */ diff --git a/include/configs/iocon.h b/include/configs/iocon.h index a4d05e559b2..385a6444d64 100644 --- a/include/configs/iocon.h +++ b/include/configs/iocon.h @@ -23,7 +23,6 @@ #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_LAST_STAGE_INIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */ diff --git a/include/configs/ipam390.h b/include/configs/ipam390.h index b1cd7dfdc28..583f7b3a5a0 100644 --- a/include/configs/ipam390.h +++ b/include/configs/ipam390.h @@ -18,7 +18,6 @@ /* * Board */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DRIVER_TI_EMAC #define CONFIG_BARIX_IPAM390 diff --git a/include/configs/ipek01.h b/include/configs/ipek01.h index 3f6f8dd0afb..637bbb321dc 100644 --- a/include/configs/ipek01.h +++ b/include/configs/ipek01.h @@ -19,7 +19,6 @@ #define CONFIG_MPX5200 1 /* MPX5200 board */ #define CONFIG_MPC5200_DDR 1 /* use DDR RAM */ #define CONFIG_IPEK01 /* Motherboard is ipek01 */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0xfc000000 diff --git a/include/configs/jupiter.h b/include/configs/jupiter.h index 5601cb4797d..ba96d97abf3 100644 --- a/include/configs/jupiter.h +++ b/include/configs/jupiter.h @@ -15,7 +15,6 @@ #define CONFIG_MPC5200 1 /* This is an MPC5200 CPU */ #define CONFIG_JUPITER 1 /* ... on Jupiter board */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/km/km8309-common.h b/include/configs/km/km8309-common.h index ec133f9e927..5cbb348045a 100644 --- a/include/configs/km/km8309-common.h +++ b/include/configs/km/km8309-common.h @@ -10,7 +10,6 @@ #ifndef __CONFIG_KM8309_COMMON_H #define __CONFIG_KM8309_COMMON_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/km/km8321-common.h b/include/configs/km/km8321-common.h index 058b0ab42bc..cd563804929 100644 --- a/include/configs/km/km8321-common.h +++ b/include/configs/km/km8321-common.h @@ -23,7 +23,6 @@ #ifndef __CONFIG_KM8321_COMMON_H #define __CONFIG_KM8321_COMMON_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/km/km83xx-common.h b/include/configs/km/km83xx-common.h index 940000ea712..cebe21060e5 100644 --- a/include/configs/km/km83xx-common.h +++ b/include/configs/km/km83xx-common.h @@ -8,7 +8,6 @@ #ifndef __CONFIG_KM83XX_H #define __CONFIG_KM83XX_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* include common defines/options for all Keymile boards */ diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h index 5e0f483e475..b89af535abb 100644 --- a/include/configs/km/km_arm.h +++ b/include/configs/km/km_arm.h @@ -20,7 +20,6 @@ #ifndef _CONFIG_KM_ARM_H #define _CONFIG_KM_ARM_H -#define CONFIG_SYS_GENERIC_BOARD /* We got removed from Linux mach-types.h */ #define MACH_TYPE_KM_KIRKWOOD 2255 diff --git a/include/configs/km/kmp204x-common.h b/include/configs/km/kmp204x-common.h index 7536cbdb3c7..8a3c74e1dbc 100644 --- a/include/configs/km/kmp204x-common.h +++ b/include/configs/km/kmp204x-common.h @@ -21,7 +21,6 @@ #define CONFIG_NAND_ECC_BCH -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* common KM defines */ diff --git a/include/configs/km82xx.h b/include/configs/km82xx.h index 12f9d424cb1..19e89cec765 100644 --- a/include/configs/km82xx.h +++ b/include/configs/km82xx.h @@ -29,7 +29,6 @@ #error ("Board unsupported") #endif -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0xFE000000 diff --git a/include/configs/km8360.h b/include/configs/km8360.h index 04cde46cc56..c517e78df2e 100644 --- a/include/configs/km8360.h +++ b/include/configs/km8360.h @@ -9,7 +9,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* KMBEC FPGA (PRIO) */ diff --git a/include/configs/kzm9g.h b/include/configs/kzm9g.h index 8a451ecd024..94b0f038f27 100644 --- a/include/configs/kzm9g.h +++ b/include/configs/kzm9g.h @@ -14,7 +14,6 @@ #define CONFIG_KZM_A9_GT #define CONFIG_RMOBILE_BOARD_STRING "KMC KZM-A9-GT" #define CONFIG_MACH_TYPE MACH_TYPE_KZM9G -#define CONFIG_SYS_GENERIC_BOARD #include <asm/arch/rmobile.h> diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h index 7f878b713af..f8cae4013c1 100644 --- a/include/configs/lacie_kw.h +++ b/include/configs/lacie_kw.h @@ -8,11 +8,6 @@ #define _CONFIG_LACIE_KW_H /* - * Generic board support - */ -#define CONFIG_SYS_GENERIC_BOARD - -/* * Machine number definition */ #if defined(CONFIG_INETSPACE_V2) diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index f73900fe30c..b8477e89d27 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -11,7 +11,7 @@ #define CONFIG_ARMV7_PSCI -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index 02cc09c82b7..784331ff8e3 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -11,7 +11,7 @@ #define CONFIG_ARMV7_PSCI -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 55b909ceaca..9c8a8642e50 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -7,7 +7,6 @@ #ifndef __LS2_COMMON_H #define __LS2_COMMON_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_REMAKE_ELF #define CONFIG_FSL_LSCH3 diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h index f7f38700323..4cfcf980941 100644 --- a/include/configs/ls2085aqds.h +++ b/include/configs/ls2085aqds.h @@ -16,6 +16,7 @@ unsigned long get_board_sys_clk(void); unsigned long get_board_ddr_clk(void); #endif +#define CONFIG_FSL_CLK #define CONFIG_SYS_CLK_FREQ get_board_sys_clk() #define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() #define COUNTER_FREQUENCY_REAL (CONFIG_SYS_CLK_FREQ/4) diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h index a190bc7c707..583fed574ad 100644 --- a/include/configs/ls2085ardb.h +++ b/include/configs/ls2085ardb.h @@ -18,6 +18,7 @@ unsigned long get_board_sys_clk(void); #endif +#define CONFIG_FSL_CLK #define CONFIG_SYS_CLK_FREQ get_board_sys_clk() #define CONFIG_DDR_CLK_FREQ 133333333 #define COUNTER_FREQUENCY_REAL (CONFIG_SYS_CLK_FREQ/4) diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h index a57e328dfda..4194a0ff8bb 100644 --- a/include/configs/lsxl.h +++ b/include/configs/lsxl.h @@ -8,7 +8,6 @@ #ifndef _CONFIG_LSXL_H #define _CONFIG_LSXL_H -#define CONFIG_SYS_GENERIC_BOARD /* * Version number information diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h index 2d93d44a3a7..66d9710d336 100644 --- a/include/configs/lwmon5.h +++ b/include/configs/lwmon5.h @@ -23,7 +23,6 @@ #define CONFIG_440EPX 1 /* Specific PPC440EPx */ #define CONFIG_440 1 /* ... PPC440 family */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_TEXT_BASE 0xFFF80000 #define CONFIG_HOSTNAME lwmon5 diff --git a/include/configs/m53evk.h b/include/configs/m53evk.h index 8853d8fcc06..152e295778a 100644 --- a/include/configs/m53evk.h +++ b/include/configs/m53evk.h @@ -9,7 +9,6 @@ #define __M53EVK_CONFIG_H__ #define CONFIG_MX53 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_MXC_GPIO #include <asm/arch/imx-regs.h> @@ -18,6 +17,7 @@ #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_REVISION_TAG #define CONFIG_SYS_NO_FLASH +#define CONFIG_FSL_CLK #define CONFIG_FIT diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h index 3bed9c7ca40..3c4beeba7c0 100644 --- a/include/configs/maxbcm.h +++ b/include/configs/maxbcm.h @@ -14,7 +14,6 @@ #ifdef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ #endif -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO_LATE /* diff --git a/include/configs/mcx.h b/include/configs/mcx.h index 0f70c47649a..62406666eb6 100644 --- a/include/configs/mcx.h +++ b/include/configs/mcx.h @@ -25,7 +25,6 @@ #define CONFIG_MACH_TYPE MACH_TYPE_MCX #define CONFIG_BOARD_LATE_INIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_CACHELINE_SIZE 64 diff --git a/include/configs/mecp5123.h b/include/configs/mecp5123.h index 84f1a400849..0f399641916 100644 --- a/include/configs/mecp5123.h +++ b/include/configs/mecp5123.h @@ -16,7 +16,6 @@ #define CONFIG_MECP5123 1 #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD /* * Memory map for the MECP5123 board: diff --git a/include/configs/meesc.h b/include/configs/meesc.h index ab6c910dee6..9c53fb4ad88 100644 --- a/include/configs/meesc.h +++ b/include/configs/meesc.h @@ -56,7 +56,6 @@ #define CONFIG_DISPLAY_CPUINFO /* display cpu info and speed */ #define CONFIG_PREBOOT /* enable preboot variable */ -#define CONFIG_SYS_GENERIC_BOARD /* * Hardware drivers diff --git a/include/configs/motionpro.h b/include/configs/motionpro.h index 6eb6e518f0c..97c614b5d6f 100644 --- a/include/configs/motionpro.h +++ b/include/configs/motionpro.h @@ -17,7 +17,6 @@ /* CPU and board */ #define CONFIG_MPC5200 1 /* This is a MPC5200 CPU */ #define CONFIG_MOTIONPRO 1 /* ... on Promess Motion-PRO board */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_HIGH_BATS 1 /* High BATs supported */ diff --git a/include/configs/mpc5121ads.h b/include/configs/mpc5121ads.h index 782b29dc971..5f4e15772d0 100644 --- a/include/configs/mpc5121ads.h +++ b/include/configs/mpc5121ads.h @@ -13,7 +13,6 @@ #define CONFIG_MPC5121ADS 1 #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD /* * Memory map for the MPC5121ADS board: diff --git a/include/configs/mpc8308_p1m.h b/include/configs/mpc8308_p1m.h index 1b09e7076e8..1a627fc5205 100644 --- a/include/configs/mpc8308_p1m.h +++ b/include/configs/mpc8308_p1m.h @@ -9,7 +9,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/munices.h b/include/configs/munices.h index 072bd958a0d..c34cba3d5c6 100644 --- a/include/configs/munices.h +++ b/include/configs/munices.h @@ -14,7 +14,6 @@ #define CONFIG_MPC5200 1 /* This is an MPC5200 CPU */ #define CONFIG_MPC5200_DDR 1 /* (with DDR-SDRAM) */ #define CONFIG_MUNICES 1 /* ... on MUNICes board */ -#define CONFIG_SYS_GENERIC_BOARD #ifndef CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_TEXT_BASE 0xFFF00000 diff --git a/include/configs/mx25pdk.h b/include/configs/mx25pdk.h index 04140865f48..0ee8e0d97cb 100644 --- a/include/configs/mx25pdk.h +++ b/include/configs/mx25pdk.h @@ -14,7 +14,7 @@ #define CONFIG_MX25 #define CONFIG_SYS_TEXT_BASE 0x81200000 #define CONFIG_MXC_GPIO -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK #define CONFIG_SYS_TIMER_RATE 32768 #define CONFIG_SYS_TIMER_COUNTER \ diff --git a/include/configs/mx31ads.h b/include/configs/mx31ads.h index c4513d2df7d..ae9f091ef95 100644 --- a/include/configs/mx31ads.h +++ b/include/configs/mx31ads.h @@ -14,7 +14,6 @@ /* High Level Configuration Options */ #define CONFIG_MX31 1 /* This is a mx31 */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h index 72d28c9bd95..863b032042c 100644 --- a/include/configs/mx31pdk.h +++ b/include/configs/mx31pdk.h @@ -19,7 +19,6 @@ /* High Level Configuration Options */ #define CONFIG_MX31 /* This is a mx31 */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h index 6bfdaa6432f..41f518e49b0 100644 --- a/include/configs/mx35pdk.h +++ b/include/configs/mx35pdk.h @@ -19,7 +19,7 @@ #define CONFIG_MX35 #define CONFIG_DISPLAY_CPUINFO -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK /* Set TEXT at the beginning of the NOR flash */ #define CONFIG_SYS_TEXT_BASE 0xA0000000 diff --git a/include/configs/mx51evk.h b/include/configs/mx51evk.h index 2203c15417d..35c9346638f 100644 --- a/include/configs/mx51evk.h +++ b/include/configs/mx51evk.h @@ -18,6 +18,7 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #define CONFIG_SYS_TEXT_BASE 0x97800000 #include <asm/arch/imx-regs.h> @@ -26,7 +27,6 @@ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_INITRD_TAG #define CONFIG_REVISION_TAG -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_OF_LIBFDT diff --git a/include/configs/mx53ard.h b/include/configs/mx53ard.h index b889c254ccb..be37ce53421 100644 --- a/include/configs/mx53ard.h +++ b/include/configs/mx53ard.h @@ -23,7 +23,7 @@ #define CONFIG_INITRD_TAG #define CONFIG_REVISION_TAG -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024) diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h index 4f304ed89f9..81af2486968 100644 --- a/include/configs/mx53evk.h +++ b/include/configs/mx53evk.h @@ -23,7 +23,7 @@ #define CONFIG_INITRD_TAG #define CONFIG_REVISION_TAG -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK #define CONFIG_OF_LIBFDT diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h index 3a65861e5e9..53fb4f79ef1 100644 --- a/include/configs/mx53loco.h +++ b/include/configs/mx53loco.h @@ -22,7 +22,7 @@ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_INITRD_TAG -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (10 * 1024 * 1024) diff --git a/include/configs/mx53smd.h b/include/configs/mx53smd.h index e46f2eeecbb..f5fcd838edd 100644 --- a/include/configs/mx53smd.h +++ b/include/configs/mx53smd.h @@ -23,7 +23,7 @@ #define CONFIG_INITRD_TAG #define CONFIG_REVISION_TAG -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024) diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index ef4cb68e8d7..ba131783842 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -45,7 +45,7 @@ #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_DISPLAY_CPUINFO -#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_FSL_CLK /* ATAGs */ #define CONFIG_CMDLINE_TAG diff --git a/include/configs/mx7_common.h b/include/configs/mx7_common.h index ea2be496e05..04468b94eef 100644 --- a/include/configs/mx7_common.h +++ b/include/configs/mx7_common.h @@ -33,7 +33,6 @@ #define CONFIG_BOARD_LATE_INIT #define CONFIG_ROM_UNIFIED_SECTIONS -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/mxs.h b/include/configs/mxs.h index 9d823def674..63fdf9e4e75 100644 --- a/include/configs/mxs.h +++ b/include/configs/mxs.h @@ -40,7 +40,6 @@ /* * CPU specifics */ -#define CONFIG_SYS_GENERIC_BOARD /* MXS uses FDT */ #define CONFIG_OF_LIBFDT diff --git a/include/configs/nas220.h b/include/configs/nas220.h index ebf67501f0b..e5ff7e1f6c8 100644 --- a/include/configs/nas220.h +++ b/include/configs/nas220.h @@ -24,7 +24,6 @@ */ #define CONFIG_FEROCEON_88FR131 /* #define CPU Core subversion */ #define CONFIG_KW88F6192 /* SOC Name */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ /* power-on led, regulator, sata0, sata1 */ diff --git a/include/configs/neo.h b/include/configs/neo.h index f1783662a47..a60b3f7cf1b 100644 --- a/include/configs/neo.h +++ b/include/configs/neo.h @@ -25,7 +25,6 @@ #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_MISC_INIT_R #define CONFIG_LAST_STAGE_INIT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_CLK_FREQ 33333333 /* external frequency to pll */ diff --git a/include/configs/nios2-generic.h b/include/configs/nios2-generic.h index 945cbd4ee7b..b38513e99b0 100644 --- a/include/configs/nios2-generic.h +++ b/include/configs/nios2-generic.h @@ -12,57 +12,34 @@ /* * BOARD/CPU */ -#include "../board/altera/nios2-generic/custom_fpga.h" /* fpga parameters */ -#define CONFIG_BOARD_NAME "nios2-generic" /* custom board name */ -#define CONFIG_BOARD_EARLY_INIT_F /* enable early board-spec. init */ #define CONFIG_DISPLAY_CPUINFO -#define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_NIOS_SYSID_BASE CONFIG_SYS_SYSID_BASE +#define CONFIG_DISPLAY_BOARDINFO_LATE /* * SERIAL */ -#define CONFIG_ALTERA_JTAG_UART -#if defined(CONFIG_ALTERA_JTAG_UART) -# define CONFIG_SYS_NIOS_CONSOLE CONFIG_SYS_JTAG_UART_BASE -#else -# define CONFIG_SYS_NIOS_CONSOLE CONFIG_SYS_UART_BASE -#endif - -#define CONFIG_ALTERA_JTAG_UART_BYPASS -#define CONFIG_SYS_NIOS_FIXEDBAUD -#define CONFIG_BAUDRATE CONFIG_SYS_UART_BAUD -#define CONFIG_SYS_BAUDRATE_TABLE {CONFIG_BAUDRATE} +#define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_CONSOLE_INFO_QUIET /* Suppress console info */ /* - * TIMER + * CFI Flash */ -#define CONFIG_SYS_LOW_RES_TIMER -#define CONFIG_SYS_NIOS_TMRBASE CONFIG_SYS_TIMER_BASE -#define CONFIG_SYS_NIOS_TMRIRQ CONFIG_SYS_TIMER_IRQ -#define CONFIG_SYS_NIOS_TMRMS 10 /* Desired period (msec)*/ -#define CONFIG_SYS_NIOS_TMRCNT \ - (CONFIG_SYS_NIOS_TMRMS * (CONFIG_SYS_TIMER_FREQ / 1000) - 1) +#define CONFIG_SYS_FLASH_BASE 0xe0000000 +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_CFI_FLASH_STATUS_POLL /* fix amd flash issue */ +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_SYS_FLASH_PROTECTION +#define CONFIG_SYS_MAX_FLASH_BANKS 1 +#define CONFIG_SYS_MAX_FLASH_SECT 512 /* - * STATUS LED + * MII/PHY */ -#define CONFIG_ALTERA_PIO -#define CONFIG_SYS_ALTERA_PIO_NUM 1 -#define CONFIG_SYS_ALTERA_PIO_GPIO_NUM LED_PIO_WIDTH - -#define CONFIG_STATUS_LED /* Enable status driver */ -#define CONFIG_BOARD_SPECIFIC_LED -#define CONFIG_GPIO_LED /* Enable GPIO LED driver */ -#define CONFIG_GPIO /* Enable GPIO driver */ -#define LED_PIO_BASE USER_LED_PIO_8OUT_BASE -#define LED_PIO_WIDTH 8 -#define LED_PIO_RSTVAL 0xff - -#define STATUS_LED_BIT 0 /* Bit-0 on GPIO */ -#define STATUS_LED_STATE 1 /* Blinking */ -#define STATUS_LED_PERIOD (500 / CONFIG_SYS_NIOS_TMRMS) /* 500 msec */ +#define CONFIG_CMD_MII 1 +#define CONFIG_PHY_GIGE 1 +#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN 1 +#define CONFIG_PHY_MARVELL 1 /* * BOOTP options @@ -73,13 +50,8 @@ #define CONFIG_BOOTP_HOSTNAME /* - * Command line configuration. + * FDT options */ -#ifdef CONFIG_CMD_NET -# define CONFIG_CMD_DHCP -# define CONFIG_CMD_PING -#endif - #define CONFIG_OF_LIBFDT #define CONFIG_OF_BOARD_SETUP #define CONFIG_LMB @@ -93,11 +65,9 @@ */ #define CONFIG_ENV_IS_IN_FLASH -#define CONFIG_ENV_SIZE 0x20000 /* 128k, 1 sector */ +#define CONFIG_ENV_SIZE 0x20000 /* 128k, 1 sector */ #define CONFIG_ENV_OVERWRITE /* Serial change Ok */ -#define CONFIG_ENV_ADDR ((CONFIG_SYS_RESET_ADDR + \ - CONFIG_SYS_MONITOR_LEN) | \ - CONFIG_SYS_FLASH_BASE) +#define CONFIG_ENV_ADDR 0xe2840000 /* * MEMORY ORGANIZATION @@ -105,6 +75,8 @@ * -The heap is placed below the monitor * -The stack is placed below the heap (&grows down). */ +#define CONFIG_SYS_SDRAM_BASE 0xD0000000 +#define CONFIG_SYS_SDRAM_SIZE 0x08000000 #define CONFIG_MONITOR_IS_IN_RAM #define CONFIG_SYS_MONITOR_LEN 0x40000 /* Reserve 256k */ #define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_SDRAM_BASE + \ @@ -129,7 +101,6 @@ #define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_INIT_SP - 0x20000) #define CONFIG_CMDLINE_EDITING - -#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_CMD_GPIO #endif /* __CONFIG_H */ diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h index 915df52ccfe..52369be39e5 100644 --- a/include/configs/nokia_rx51.h +++ b/include/configs/nokia_rx51.h @@ -28,7 +28,6 @@ #define CONFIG_OMAP3_RX51 /* working with RX51 */ #define CONFIG_SYS_L2CACHE_OFF /* pretend there is no L2 CACHE */ #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/o2dnt-common.h b/include/configs/o2dnt-common.h index 435f1a27a1e..8b0dbdc7477 100644 --- a/include/configs/o2dnt-common.h +++ b/include/configs/o2dnt-common.h @@ -18,7 +18,6 @@ */ #define CONFIG_MPC5200 #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_MPC5XXX_CLKIN 33000000 /* running at 33.000000MHz */ diff --git a/include/configs/omap3_evm_common.h b/include/configs/omap3_evm_common.h index 0ebe5c118bc..7e7f6f2e9f4 100644 --- a/include/configs/omap3_evm_common.h +++ b/include/configs/omap3_evm_common.h @@ -15,7 +15,6 @@ #define CONFIG_OMAP /* This is TI OMAP core */ #define CONFIG_OMAP_GPIO #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h index cef2243bfeb..a59fd426c50 100644 --- a/include/configs/omap3_zoom1.h +++ b/include/configs/omap3_zoom1.h @@ -17,7 +17,6 @@ * High Level Configuration Options */ #define CONFIG_OMAP3_ZOOM1 1 /* working with Zoom MDK Rev1 */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_NAND #define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ diff --git a/include/configs/omapl138_lcdk.h b/include/configs/omapl138_lcdk.h index d9a3aa42176..80d57f46d4d 100644 --- a/include/configs/omapl138_lcdk.h +++ b/include/configs/omapl138_lcdk.h @@ -195,7 +195,6 @@ /* * U-Boot general configuration */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_MISC_INIT_R #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOOTFILE "uImage" /* Boot file name */ diff --git a/include/configs/p1_p2_rdb_pc.h b/include/configs/p1_p2_rdb_pc.h index 362cf308176..03eb185e16a 100644 --- a/include/configs/p1_p2_rdb_pc.h +++ b/include/configs/p1_p2_rdb_pc.h @@ -10,8 +10,8 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #ifdef CONFIG_36BIT #define CONFIG_PHYS_64BIT diff --git a/include/configs/p1_twr.h b/include/configs/p1_twr.h index 588a6c5ebf8..46f5f0f70e5 100644 --- a/include/configs/p1_twr.h +++ b/include/configs/p1_twr.h @@ -10,8 +10,8 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #if defined(CONFIG_TWR_P1025) #define CONFIG_BOARDNAME "TWR-P1025" #define CONFIG_P1025 diff --git a/include/configs/pcm030.h b/include/configs/pcm030.h index 4ea617a9d4c..29feb7bba13 100644 --- a/include/configs/pcm030.h +++ b/include/configs/pcm030.h @@ -15,7 +15,6 @@ #define __CONFIG_H #define CONFIG_BOARDINFO "phyCORE-MPC5200B-tiny" -#define CONFIG_SYS_GENERIC_BOARD /*----------------------------------------------------------------------------- High Level Configuration Options diff --git a/include/configs/pcm052.h b/include/configs/pcm052.h index 18f45af1fa7..046ddb8516d 100644 --- a/include/configs/pcm052.h +++ b/include/configs/pcm052.h @@ -13,7 +13,6 @@ #define CONFIG_VF610 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_THUMB_BUILD diff --git a/include/configs/pdm360ng.h b/include/configs/pdm360ng.h index e7413c9fa28..a6e7e9c152c 100644 --- a/include/configs/pdm360ng.h +++ b/include/configs/pdm360ng.h @@ -14,7 +14,6 @@ #define CONFIG_PDM360NG 1 #define CONFIG_DISPLAY_BOARDINFO -#define CONFIG_SYS_GENERIC_BOARD /* * Memory map for the PDM360NG board: diff --git a/include/configs/picosam9g45.h b/include/configs/picosam9g45.h index 9e9b1d0c1d7..47613ded3ba 100644 --- a/include/configs/picosam9g45.h +++ b/include/configs/picosam9g45.h @@ -36,7 +36,6 @@ #define CONFIG_CMD_BOOTZ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ diff --git a/include/configs/pm9261.h b/include/configs/pm9261.h index f4f96a71a05..407b83d0201 100644 --- a/include/configs/pm9261.h +++ b/include/configs/pm9261.h @@ -20,7 +20,6 @@ #include <asm/hardware.h> /* ARM asynchronous clock */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO diff --git a/include/configs/pm9263.h b/include/configs/pm9263.h index bd4357722c0..f6886a6eb2b 100644 --- a/include/configs/pm9263.h +++ b/include/configs/pm9263.h @@ -18,7 +18,6 @@ */ #include <asm/hardware.h> -#define CONFIG_SYS_GENERIC_BOARD /* ARM asynchronous clock */ #define CONFIG_DISPLAY_CPUINFO diff --git a/include/configs/pm9g45.h b/include/configs/pm9g45.h index 09f0744b410..ede0ee1f122 100644 --- a/include/configs/pm9g45.h +++ b/include/configs/pm9g45.h @@ -22,7 +22,6 @@ */ #include <asm/hardware.h> -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_PM9G45 1 /* It's an Ronetix PM9G45 */ #define CONFIG_SYS_AT91_CPU_NAME "AT91SAM9G45" diff --git a/include/configs/pogo_e02.h b/include/configs/pogo_e02.h index 8cf3ad84790..b1a3dc7716a 100644 --- a/include/configs/pogo_e02.h +++ b/include/configs/pogo_e02.h @@ -13,7 +13,6 @@ #ifndef _CONFIG_POGO_E02_H #define _CONFIG_POGO_E02_H -#define CONFIG_SYS_GENERIC_BOARD /* * Machine type definition and ID diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h index 5cd090614dd..f45789fd5ea 100644 --- a/include/configs/qemu-ppce500.h +++ b/include/configs/qemu-ppce500.h @@ -19,7 +19,6 @@ #undef CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_TEXT_BASE 0xf01000 /* 15 MB */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_MPC85XX_NO_RESETVEC diff --git a/include/configs/rcar-gen2-common.h b/include/configs/rcar-gen2-common.h index 7dd92605358..f0a3a187d7b 100644 --- a/include/configs/rcar-gen2-common.h +++ b/include/configs/rcar-gen2-common.h @@ -26,7 +26,6 @@ #define CONFIG_CMD_EXT4_WRITE #define CONFIG_SYS_THUMB_BUILD -#define CONFIG_SYS_GENERIC_BOARD /* Support File sytems */ #define CONFIG_FAT_WRITE diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index e8aec286243..36408b99e2c 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -13,7 +13,6 @@ #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_ENV_IS_NOWHERE #define CONFIG_ENV_SIZE 0x2000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_MAXARGS 16 #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_MALLOC_LEN (32 << 20) diff --git a/include/configs/rpi-common.h b/include/configs/rpi-common.h index 06836cd5d8e..0b8c6814731 100644 --- a/include/configs/rpi-common.h +++ b/include/configs/rpi-common.h @@ -11,7 +11,6 @@ #include <asm/arch/timer.h> /* Architecture, CPU, etc.*/ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_BCM2835 #define CONFIG_ARCH_CPU_INIT @@ -133,6 +132,7 @@ #include <config_distro_defaults.h> /* Environment */ +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG #define ENV_DEVICE_SETTINGS \ "stdin=serial,lcd\0" \ "stdout=serial,lcd\0" \ diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index aff264bbd29..2877e19ad4b 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -278,6 +278,5 @@ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD #endif /* __CONFIG_H */ diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h index 9d89b2a3423..c8b14e9b831 100644 --- a/include/configs/sbc8349.h +++ b/include/configs/sbc8349.h @@ -15,7 +15,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 87e562e171b..1c309a42b34 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD /* * Top level Makefile configuration choices diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h index eed0f497516..0b22ce0e02e 100644 --- a/include/configs/sbc8641d.h +++ b/include/configs/sbc8641d.h @@ -20,7 +20,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD /* High Level Configuration Options */ #define CONFIG_MPC8641 1 /* MPC8641 specific */ diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h index 272e3ca9b31..76cdbe0c6dc 100644 --- a/include/configs/sheevaplug.h +++ b/include/configs/sheevaplug.h @@ -10,7 +10,6 @@ #ifndef _CONFIG_SHEEVAPLUG_H #define _CONFIG_SHEEVAPLUG_H -#define CONFIG_SYS_GENERIC_BOARD /* * Version number information diff --git a/include/configs/siemens-am33x-common.h b/include/configs/siemens-am33x-common.h index bcc8dcbfb25..6c374eb0828 100644 --- a/include/configs/siemens-am33x-common.h +++ b/include/configs/siemens-am33x-common.h @@ -45,7 +45,6 @@ #define CONFIG_CMD_CACHE #define CONFIG_CMD_TIME -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_ENV_VARS_UBOOT_CONFIG #ifndef CONFIG_SPL_BUILD diff --git a/include/configs/smartweb.h b/include/configs/smartweb.h index e11c016aedb..44d1d5a171c 100644 --- a/include/configs/smartweb.h +++ b/include/configs/smartweb.h @@ -51,7 +51,6 @@ /* setting board specific options */ # define CONFIG_MACH_TYPE MACH_TYPE_SMARTWEB -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_CMDLINE_EDITING #define CONFIG_AUTO_COMPLETE diff --git a/include/configs/smdk2410.h b/include/configs/smdk2410.h index fb3850259cc..9947dc05f14 100644 --- a/include/configs/smdk2410.h +++ b/include/configs/smdk2410.h @@ -23,7 +23,6 @@ #define CONFIG_SYS_TEXT_BASE 0x0 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH diff --git a/include/configs/smdkc100.h b/include/configs/smdkc100.h index 1d9ce92746b..c36e444a6cc 100644 --- a/include/configs/smdkc100.h +++ b/include/configs/smdkc100.h @@ -214,6 +214,5 @@ #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD #endif /* __CONFIG_H */ diff --git a/include/configs/snapper9260.h b/include/configs/snapper9260.h index 7758b0f51d0..afcd16afbe3 100644 --- a/include/configs/snapper9260.h +++ b/include/configs/snapper9260.h @@ -20,7 +20,6 @@ /* ARM asynchronous clock */ #define CONFIG_SYS_AT91_MAIN_CLOCK 18432000 /* External Crystal, in Hz */ #define CONFIG_SYS_AT91_SLOW_CLOCK 32768 -#define CONFIG_SYS_GENERIC_BOARD /* CPU */ #define CONFIG_ARCH_CPU_INIT diff --git a/include/configs/sniper.h b/include/configs/sniper.h index a0ee5bd5a04..f168e8f97ac 100644 --- a/include/configs/sniper.h +++ b/include/configs/sniper.h @@ -34,7 +34,6 @@ * Board */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_MISC_INIT_R /* diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index cece0950e29..33746839115 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -6,7 +6,6 @@ #ifndef __CONFIG_SOCFPGA_CYCLONE5_COMMON_H__ #define __CONFIG_SOCFPGA_CYCLONE5_COMMON_H__ -#define CONFIG_SYS_GENERIC_BOARD /* Virtual target or real hardware */ #undef CONFIG_SOCFPGA_VIRTUAL_TARGET diff --git a/include/configs/socrates.h b/include/configs/socrates.h index 50911ae2591..019cf309e39 100644 --- a/include/configs/socrates.h +++ b/include/configs/socrates.h @@ -27,7 +27,6 @@ #define CONFIG_E500 1 /* BOOKE e500 family */ #define CONFIG_MPC8544 1 #define CONFIG_SOCRATES 1 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0xfff80000 diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index edae831f22f..1d69477e613 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -11,7 +11,6 @@ * Common configurations used for both spear3xx as well as spear6xx */ -#define CONFIG_SYS_GENERIC_BOARD /* U-boot Load Address */ #define CONFIG_SYS_TEXT_BASE 0x00700000 diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h index 19d9cf9abf3..17969952d12 100644 --- a/include/configs/stm32f429-discovery.h +++ b/include/configs/stm32f429-discovery.h @@ -10,7 +10,6 @@ #define CONFIG_STM32F4 #define CONFIG_STM32F4DISCOVERY -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_OF_LIBFDT diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h index b1b69197d4f..1526d13ac15 100644 --- a/include/configs/stv0991.h +++ b/include/configs/stv0991.h @@ -13,7 +13,6 @@ #define CONFIG_SYS_CORTEX_R4 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_NO_FLASH /* ram memory-related information */ diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index ddcfe94e89e..f5db4d3e3ec 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -158,7 +158,6 @@ #define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ #define CONFIG_SYS_PBSIZE 1024 /* Print Buffer Size */ #define CONFIG_SYS_MAXARGS 16 /* max number of command args */ -#define CONFIG_SYS_GENERIC_BOARD /* Boot Argument Buffer Size */ #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE diff --git a/include/configs/t4qds.h b/include/configs/t4qds.h index 26028df21a9..5754369cf31 100644 --- a/include/configs/t4qds.h +++ b/include/configs/t4qds.h @@ -10,7 +10,6 @@ #ifndef __T4QDS_H #define __T4QDS_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_CMD_REGINFO diff --git a/include/configs/tam3517-common.h b/include/configs/tam3517-common.h index 801220a1ce4..f993433285a 100644 --- a/include/configs/tam3517-common.h +++ b/include/configs/tam3517-common.h @@ -16,7 +16,6 @@ #define CONFIG_OMAP /* in a TI OMAP core */ #define CONFIG_OMAP_GPIO #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/tao3530.h b/include/configs/tao3530.h index bd1c07c3ebb..97fe79607d5 100644 --- a/include/configs/tao3530.h +++ b/include/configs/tao3530.h @@ -20,7 +20,6 @@ #define CONFIG_OMAP_GPIO #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD /* Common ARM Erratas */ #define CONFIG_ARM_ERRATA_454179 #define CONFIG_ARM_ERRATA_430973 diff --git a/include/configs/taurus.h b/include/configs/taurus.h index 12994c80659..a5e7090cb72 100644 --- a/include/configs/taurus.h +++ b/include/configs/taurus.h @@ -22,7 +22,6 @@ #include <asm/hardware.h> #include <linux/sizes.h> -#define CONFIG_SYS_GENERIC_BOARD #if defined(CONFIG_SPL_BUILD) #define CONFIG_SYS_THUMB_BUILD diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index 1c469d092e8..a005e6a2acc 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -130,7 +130,6 @@ #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_GPIO_SUPPORT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_LATE_INIT diff --git a/include/configs/ti814x_evm.h b/include/configs/ti814x_evm.h index ceeb7fe46bd..7fa35a15425 100644 --- a/include/configs/ti814x_evm.h +++ b/include/configs/ti814x_evm.h @@ -21,7 +21,6 @@ #define CONFIG_SYS_NO_FLASH #define CONFIG_OMAP #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD #include <asm/arch/omap.h> diff --git a/include/configs/ti816x_evm.h b/include/configs/ti816x_evm.h index 4c192896ad6..01d82337415 100644 --- a/include/configs/ti816x_evm.h +++ b/include/configs/ti816x_evm.h @@ -15,7 +15,6 @@ #define CONFIG_SYS_NO_FLASH #define CONFIG_OMAP #define CONFIG_OMAP_COMMON -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_ARCH_CPU_INIT diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h index 586bd2b50ff..32bb805f781 100644 --- a/include/configs/ti_armv7_common.h +++ b/include/configs/ti_armv7_common.h @@ -17,9 +17,6 @@ #ifndef __CONFIG_TI_ARMV7_COMMON_H__ #define __CONFIG_TI_ARMV7_COMMON_H__ -/* Common define for many platforms. */ -#define CONFIG_SYS_GENERIC_BOARD - /* * We typically do not contain NOR flash. In the cases where we do, we * undefine this later. diff --git a/include/configs/tricorder.h b/include/configs/tricorder.h index f04b572985e..02b0e6351f4 100644 --- a/include/configs/tricorder.h +++ b/include/configs/tricorder.h @@ -38,7 +38,6 @@ #include <asm/arch/cpu.h> /* get chip and board defs */ #include <asm/arch/omap.h> -#define CONFIG_SYS_GENERIC_BOARD /* Display CPU and Board information */ #define CONFIG_DISPLAY_CPUINFO diff --git a/include/configs/ts4800.h b/include/configs/ts4800.h index 21f1555eb79..fbca8a68ef2 100644 --- a/include/configs/ts4800.h +++ b/include/configs/ts4800.h @@ -37,9 +37,6 @@ #define CONFIG_INITRD_TAG #define CONFIG_REVISION_TAG -/* use common/board_f.c instead of arch/<arch>/lib/<board>.c */ -#define CONFIG_SYS_GENERIC_BOARD - /* * Size of malloc() pool */ diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 9109b7f8d9d..1e71703ef09 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -82,7 +82,6 @@ /* serial console configuration */ #define CONFIG_BAUDRATE 115200 -#define CONFIG_SYS_GENERIC_BOARD #if !defined(CONFIG_SPL_BUILD) #define CONFIG_USE_ARCH_MEMSET diff --git a/include/configs/usb_a9263.h b/include/configs/usb_a9263.h index 10a1664f020..54daede83be 100644 --- a/include/configs/usb_a9263.h +++ b/include/configs/usb_a9263.h @@ -34,7 +34,6 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_TEXT_BASE 0x23f00000 /* diff --git a/include/configs/usbarmory.h b/include/configs/usbarmory.h index 714e3e2ca21..6735055a616 100644 --- a/include/configs/usbarmory.h +++ b/include/configs/usbarmory.h @@ -14,9 +14,9 @@ #define CONFIG_MX53 #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_OF_LIBFDT -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_MXC_GPIO #include <asm/arch/imx-regs.h> diff --git a/include/configs/v38b.h b/include/configs/v38b.h index 3e51b9fc2c9..f15420817b7 100644 --- a/include/configs/v38b.h +++ b/include/configs/v38b.h @@ -14,7 +14,6 @@ */ #define CONFIG_MPC5200 1 /* This is an MPC5200 CPU */ #define CONFIG_V38B 1 /* ...on V38B board */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0xFF000000 diff --git a/include/configs/ve8313.h b/include/configs/ve8313.h index a88216c6ec5..f5df4fb9da8 100644 --- a/include/configs/ve8313.h +++ b/include/configs/ve8313.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h index 0f2f1a30baf..a99d712a47d 100644 --- a/include/configs/vexpress_aemv8a.h +++ b/include/configs/vexpress_aemv8a.h @@ -8,9 +8,6 @@ #ifndef __VEXPRESS_AEMV8A_H #define __VEXPRESS_AEMV8A_H -/* We use generic board and device manager for v8 Versatile Express */ -#define CONFIG_SYS_GENERIC_BOARD - #ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP #ifndef CONFIG_SEMIHOSTING #error CONFIG_TARGET_VEXPRESS64_BASE_FVP requires CONFIG_SEMIHOSTING diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h index 98f6ae94e68..cec510c1f12 100644 --- a/include/configs/vexpress_common.h +++ b/include/configs/vexpress_common.h @@ -122,7 +122,6 @@ #define CONFIG_SETUP_MEMORY_TAGS 1 #define CONFIG_SYS_L2CACHE_OFF 1 #define CONFIG_INITRD_TAG 1 -#define CONFIG_SYS_GENERIC_BOARD /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024) diff --git a/include/configs/vf610twr.h b/include/configs/vf610twr.h index 7f4260a3ac7..abd1e98d9be 100644 --- a/include/configs/vf610twr.h +++ b/include/configs/vf610twr.h @@ -13,9 +13,9 @@ #define CONFIG_VF610 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_FSL_CLK #define CONFIG_MACH_TYPE 4146 diff --git a/include/configs/vme8349.h b/include/configs/vme8349.h index a6f5d6a4ea3..7f5f089b12b 100644 --- a/include/configs/vme8349.h +++ b/include/configs/vme8349.h @@ -18,7 +18,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO /* diff --git a/include/configs/woodburn_common.h b/include/configs/woodburn_common.h index fc4656567da..e6f3e28fe1d 100644 --- a/include/configs/woodburn_common.h +++ b/include/configs/woodburn_common.h @@ -16,12 +16,12 @@ /* High Level Configuration Options */ #define CONFIG_MX35 #define CONFIG_MX35_HCLK_FREQ 24000000 +#define CONFIG_FSL_CLK #define CONFIG_SYS_DCACHE_OFF #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_DISPLAY_CPUINFO -#define CONFIG_SYS_GENERIC_BOARD /* Only in case the value is not present in mach-types.h */ #ifndef MACH_TYPE_FLEA3 diff --git a/include/configs/work_92105.h b/include/configs/work_92105.h index 15ee28414d3..f77d065a722 100644 --- a/include/configs/work_92105.h +++ b/include/configs/work_92105.h @@ -103,7 +103,6 @@ /* * U-Boot General Configurations */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_LONGHELP #define CONFIG_SYS_CBSIZE 1024 #define CONFIG_SYS_PBSIZE \ diff --git a/include/configs/x600.h b/include/configs/x600.h index 73ba67c3e91..85347665881 100644 --- a/include/configs/x600.h +++ b/include/configs/x600.h @@ -16,7 +16,6 @@ */ #define CONFIG_SPEAR600 /* SPEAr600 SoC */ #define CONFIG_X600 /* on X600 board */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_THUMB_BUILD #include <asm/arch/hardware.h> diff --git a/include/configs/xilinx-ppc.h b/include/configs/xilinx-ppc.h index 6bd6be86e1a..1abd0eff0f5 100644 --- a/include/configs/xilinx-ppc.h +++ b/include/configs/xilinx-ppc.h @@ -12,7 +12,6 @@ #ifndef __CONFIG_XLX_H #define __CONFIG_XLX_H -#define CONFIG_SYS_GENERIC_BOARD /* #define DEBUG diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index ed09b7f67e7..32ee0fc149f 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -17,7 +17,6 @@ #define CONFIG_SYS_NO_FLASH -#define CONFIG_SYS_GENERIC_BOARD /* Generic Interrupt Controller Definitions */ #define CONFIG_GICV2 diff --git a/include/configs/xpedite1000.h b/include/configs/xpedite1000.h index 37a31c4797f..005f1495fe0 100644 --- a/include/configs/xpedite1000.h +++ b/include/configs/xpedite1000.h @@ -22,7 +22,6 @@ #define CONFIG_440GX 1 /* 440 GX */ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ #define CONFIG_SYS_CLK_FREQ 33333333 /* external freq to pll */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0xFFF80000 diff --git a/include/configs/xpedite517x.h b/include/configs/xpedite517x.h index 51781daa7f0..3e09635689c 100644 --- a/include/configs/xpedite517x.h +++ b/include/configs/xpedite517x.h @@ -23,7 +23,6 @@ #define CONFIG_BAT_RW 1 /* Use common BAT rw code */ #define CONFIG_HIGH_BATS 1 /* High BATs supported and enabled */ #define CONFIG_ALTIVEC 1 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_TEXT_BASE 0xfff00000 diff --git a/include/configs/xpedite520x.h b/include/configs/xpedite520x.h index e48960b8019..39bdb88a979 100644 --- a/include/configs/xpedite520x.h +++ b/include/configs/xpedite520x.h @@ -21,7 +21,6 @@ #define CONFIG_SYS_BOARD_NAME "XPedite5200" #define CONFIG_SYS_FORM_PMC_XMC 1 #define CONFIG_BOARD_EARLY_INIT_R /* Call board_pre_init */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifndef CONFIG_SYS_TEXT_BASE diff --git a/include/configs/xpedite537x.h b/include/configs/xpedite537x.h index 3645cb28d43..c687555b8ee 100644 --- a/include/configs/xpedite537x.h +++ b/include/configs/xpedite537x.h @@ -21,7 +21,6 @@ #define CONFIG_SYS_BOARD_NAME "XPedite5370" #define CONFIG_SYS_FORM_3U_VPX 1 #define CONFIG_BOARD_EARLY_INIT_R /* Call board_pre_init */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifndef CONFIG_SYS_TEXT_BASE diff --git a/include/configs/xpedite550x.h b/include/configs/xpedite550x.h index 7bf0ccac7fa..f971f8b403b 100644 --- a/include/configs/xpedite550x.h +++ b/include/configs/xpedite550x.h @@ -22,7 +22,6 @@ #define CONFIG_SYS_FORM_PMC_XMC 1 #define CONFIG_PRPMC_PCI_ALIAS "pci0" /* Processor PMC interface on pci0 */ #define CONFIG_BOARD_EARLY_INIT_R /* Call board_pre_init */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO #ifndef CONFIG_SYS_TEXT_BASE diff --git a/include/configs/zmx25.h b/include/configs/zmx25.h index b7134ebc20d..bd8fdfb8bd5 100644 --- a/include/configs/zmx25.h +++ b/include/configs/zmx25.h @@ -15,7 +15,6 @@ #define CONFIG_MX25 #define CONFIG_SYS_TEXT_BASE 0xA0000000 -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_TIMER_RATE 32768 #define CONFIG_SYS_TIMER_COUNTER \ diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 873c42d3a1c..66b1e699c80 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -375,6 +375,5 @@ #define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE -#define CONFIG_SYS_GENERIC_BOARD #endif /* __CONFIG_ZYNQ_COMMON_H */ diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index da414998724..886a44c134b 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -39,6 +39,7 @@ enum uclass_id { UCLASS_LED, /* Light-emitting diode (LED) */ UCLASS_LPC, /* x86 'low pin count' interface */ UCLASS_MASS_STORAGE, /* Mass storage device */ + UCLASS_MISC, /* Miscellaneous device */ UCLASS_MMC, /* SD / MMC card or chip */ UCLASS_MOD_EXP, /* RSA Mod Exp device */ UCLASS_PCH, /* x86 platform controller hub */ @@ -57,6 +58,7 @@ enum uclass_id { UCLASS_SPI_GENERIC, /* Generic SPI flash target */ UCLASS_SYSCON, /* System configuration device */ UCLASS_THERMAL, /* Thermal sensor */ + UCLASS_TIMER, /* Timer device */ UCLASS_TPM, /* Trusted Platform Module TIS interface */ UCLASS_USB, /* USB bus */ UCLASS_USB_DEV_GENERIC, /* USB generic device */ diff --git a/include/fs.h b/include/fs.h index fd1e4ab1c0f..059a39505d4 100644 --- a/include/fs.h +++ b/include/fs.h @@ -22,6 +22,7 @@ #define FS_TYPE_FAT 1 #define FS_TYPE_EXT 2 #define FS_TYPE_SANDBOX 3 +#define FS_TYPE_UBIFS 4 /* * Tell the fs layer which block device an partition to use for future diff --git a/include/linux/compat.h b/include/linux/compat.h index fbebf910add..59937de960a 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -4,6 +4,7 @@ #include <malloc.h> #include <linux/types.h> #include <linux/err.h> +#include <linux/kernel.h> struct unused {}; typedef struct unused unused_t; @@ -49,22 +50,47 @@ static inline void *kzalloc(size_t size, gfp_t flags) { return kmalloc(size, flags | __GFP_ZERO); } + +static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) +{ + if (size != 0 && n > SIZE_MAX / size) + return NULL; + return kmalloc(n * size, flags | __GFP_ZERO); +} + +static inline void *kcalloc(size_t n, size_t size, gfp_t flags) +{ + return kmalloc_array(n, size, flags | __GFP_ZERO); +} + #define vmalloc(size) kmalloc(size, 0) #define __vmalloc(size, flags, pgsz) kmalloc(size, flags) static inline void *vzalloc(unsigned long size) { return kzalloc(size, 0); } -#define kfree(ptr) free(ptr) -#define vfree(ptr) free(ptr) +static inline void kfree(const void *block) +{ + free((void *)block); +} +static inline void vfree(const void *addr) +{ + free((void *)addr); +} struct kmem_cache { int sz; }; struct kmem_cache *get_mem(int element_sz); #define kmem_cache_create(a, sz, c, d, e) get_mem(sz) void *kmem_cache_alloc(struct kmem_cache *obj, int flag); -#define kmem_cache_free(obj, size) free(size) -#define kmem_cache_destroy(obj) free(obj) +static inline void kmem_cache_free(struct kmem_cache *cachep, void *obj) +{ + free(obj); +} +static inline void kmem_cache_destroy(struct kmem_cache *cachep) +{ + free(cachep); +} #define DECLARE_WAITQUEUE(...) do { } while (0) #define add_wait_queue(...) do { } while (0) @@ -159,6 +185,8 @@ typedef unsigned long blkcnt_t; #define class_create(...) __builtin_return_address(0) #define class_create_file(...) 0 +#define class_register(...) 0 +#define class_unregister(...) #define class_remove_file(...) #define class_destroy(...) #define misc_register(...) 0 @@ -171,6 +199,7 @@ typedef unsigned long blkcnt_t; #define dev_set_name(...) do { } while (0) #define device_register(...) 0 +#define device_unregister(...) #define volume_sysfs_init(...) 0 #define volume_sysfs_close(...) do { } while (0) diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index bc4d9bf8f9e..e3d3fc73fd6 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -244,6 +244,7 @@ struct mtd_info { #ifndef __UBOOT__ int (*_suspend) (struct mtd_info *mtd); void (*_resume) (struct mtd_info *mtd); + void (*_reboot) (struct mtd_info *mtd); #endif /* * If the driver is something smart, like UBI, it may need to maintain @@ -478,6 +479,8 @@ static inline int mtd_is_bitflip_or_eccerr(int err) { return mtd_is_bitflip(err) || mtd_is_eccerr(err); } +unsigned mtd_mmap_capabilities(struct mtd_info *mtd); + #ifdef __UBOOT__ /* drivers/mtd/mtdcore.h */ int add_mtd_device(struct mtd_info *mtd); diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h index 05d0ab54c01..036779b3478 100644 --- a/include/linux/mtd/ubi.h +++ b/include/linux/mtd/ubi.h @@ -12,6 +12,7 @@ #include <linux/types.h> #ifndef __UBOOT__ #include <linux/ioctl.h> +#include <linux/scatterlist.h> #include <mtd/ubi-user.h> #endif @@ -19,16 +20,25 @@ #define UBI_ALL -1 /* + * Maximum number of scatter gather list entries, + * we use only 64 to have a lower memory foot print. + */ +#define UBI_MAX_SG_COUNT 64 + +/* * enum ubi_open_mode - UBI volume open mode constants. * * UBI_READONLY: read-only mode * UBI_READWRITE: read-write mode * UBI_EXCLUSIVE: exclusive mode + * UBI_METAONLY: modify only the volume meta-data, + * i.e. the data stored in the volume table, but not in any of volume LEBs. */ enum { UBI_READONLY = 1, UBI_READWRITE, - UBI_EXCLUSIVE + UBI_EXCLUSIVE, + UBI_METAONLY }; /** @@ -106,6 +116,37 @@ struct ubi_volume_info { }; /** + * struct ubi_sgl - UBI scatter gather list data structure. + * @list_pos: current position in @sg[] + * @page_pos: current position in @sg[@list_pos] + * @sg: the scatter gather list itself + * + * ubi_sgl is a wrapper around a scatter list which keeps track of the + * current position in the list and the current list item such that + * it can be used across multiple ubi_leb_read_sg() calls. + */ +struct ubi_sgl { + int list_pos; + int page_pos; +#ifndef __UBOOT__ + struct scatterlist sg[UBI_MAX_SG_COUNT]; +#endif +}; + +/** + * ubi_sgl_init - initialize an UBI scatter gather list data structure. + * @usgl: the UBI scatter gather struct itself + * + * Please note that you still have to use sg_init_table() or any adequate + * function to initialize the unterlaying struct scatterlist. + */ +static inline void ubi_sgl_init(struct ubi_sgl *usgl) +{ + usgl->list_pos = 0; + usgl->page_pos = 0; +} + +/** * struct ubi_device_info - UBI device description data structure. * @ubi_num: ubi device number * @leb_size: logical eraseblock size on this UBI device @@ -214,6 +255,8 @@ int ubi_unregister_volume_notifier(struct notifier_block *nb); void ubi_close_volume(struct ubi_volume_desc *desc); int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, int len, int check); +int ubi_leb_read_sg(struct ubi_volume_desc *desc, int lnum, struct ubi_sgl *sgl, + int offset, int len, int check); int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, int offset, int len); int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, @@ -234,4 +277,14 @@ static inline int ubi_read(struct ubi_volume_desc *desc, int lnum, char *buf, { return ubi_leb_read(desc, lnum, buf, offset, len, 0); } + +/* + * This function is the same as the 'ubi_leb_read_sg()' function, but it does + * not provide the checking capability. + */ +static inline int ubi_read_sg(struct ubi_volume_desc *desc, int lnum, + struct ubi_sgl *sgl, int offset, int len) +{ + return ubi_leb_read_sg(desc, lnum, sgl, offset, len, 0); +} #endif /* !__LINUX_UBI_H__ */ diff --git a/include/misc.h b/include/misc.h new file mode 100644 index 00000000000..7e9badfabd0 --- /dev/null +++ b/include/misc.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MISC_H_ +#define _MISC_H_ + +/* + * Read the device to buffer, optional. + * + * @dev: the device + * @offset: offset to read the device + * @buf: pointer to data buffer + * @size: data size in bytes to read the device + * @return: 0 if OK, -ve on error + */ +int misc_read(struct udevice *dev, int offset, void *buf, int size); +/* + * Write buffer to the device, optional. + * + * @dev: the device + * @offset: offset to write the device + * @buf: pointer to data buffer + * @size: data size in bytes to write the device + * @return: 0 if OK, -ve on error + */ +int misc_write(struct udevice *dev, int offset, void *buf, int size); +/* + * Assert command to the device, optional. + * + * @dev: the device + * @request: command to be sent to the device + * @buf: pointer to buffer related to the requset + * @return: 0 if OK, -ve on error + */ +int misc_ioctl(struct udevice *dev, unsigned long request, void *buf); + +/* + * struct misc_ops - Driver model Misc operations + * + * The uclass interface is implemented by all miscellaneous devices which + * use driver model. + */ +struct misc_ops { + /* + * Read the device to buffer, optional. + * + * @dev: the device + * @offset: offset to read the device + * @buf: pointer to data buffer + * @size: data size in bytes to read the device + * @return: 0 if OK, -ve on error + */ + int (*read)(struct udevice *dev, int offset, void *buf, int size); + /* + * Write buffer to the device, optional. + * + * @dev: the device + * @offset: offset to write the device + * @buf: pointer to data buffer + * @size: data size in bytes to write the device + * @return: 0 if OK, -ve on error + */ + int (*write)(struct udevice *dev, int offset, const void *buf, + int size); + /* + * Assert command to the device, optional. + * + * @dev: the device + * @request: command to be sent to the device + * @buf: pointer to buffer related to the requset + * @return: 0 if OK, -ve on error + */ + int (*ioctl)(struct udevice *dev, unsigned long request, void *buf); +}; + +#endif /* _MISC_H_ */ diff --git a/include/serial.h b/include/serial.h index de40e9406f8..e490f9a0cf5 100644 --- a/include/serial.h +++ b/include/serial.h @@ -164,8 +164,6 @@ struct serial_dev_priv { /* Access the serial operations for a device */ #define serial_get_ops(dev) ((struct dm_serial_ops *)(dev)->driver->ops) -void altera_jtag_serial_initialize(void); -void altera_serial_initialize(void); void amirix_serial_initialize(void); void arc_serial_initialize(void); void arm_dcc_initialize(void); diff --git a/include/status_led.h b/include/status_led.h index f6be18146b2..396ea882eac 100644 --- a/include/status_led.h +++ b/include/status_led.h @@ -23,6 +23,7 @@ #define STATUS_LED_BLINKING 1 #define STATUS_LED_ON 2 +void status_led_init(void); void status_led_tick (unsigned long timestamp); void status_led_set (int led, int state); diff --git a/include/timer.h b/include/timer.h new file mode 100644 index 00000000000..cdf385d174c --- /dev/null +++ b/include/timer.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _TIMER_H_ +#define _TIMER_H_ + +/* + * Get the current timer count + * + * @dev: The Timer device + * @count: pointer that returns the current timer count + * @return: 0 if OK, -ve on error + */ +int timer_get_count(struct udevice *dev, unsigned long *count); +/* + * Get the timer input clock frequency + * + * @dev: The Timer device + * @return: the timer input clock frequency + */ +unsigned long timer_get_rate(struct udevice *dev); + +/* + * struct timer_ops - Driver model Timer operations + * + * The uclass interface is implemented by all Timer devices which use + * driver model. + */ +struct timer_ops { + /* + * Get the current timer count + * + * @dev: The Timer device + * @count: pointer that returns the current timer count + * @return: 0 if OK, -ve on error + */ + int (*get_count)(struct udevice *dev, unsigned long *count); +}; + +/* + * struct timer_dev_priv - information about a device used by the uclass + * + * @clock_rate: the timer input clock frequency + */ +struct timer_dev_priv { + unsigned long clock_rate; +}; + +#endif /* _TIMER_H_ */ diff --git a/include/ubifs_uboot.h b/include/ubifs_uboot.h new file mode 100644 index 00000000000..dab433a39fd --- /dev/null +++ b/include/ubifs_uboot.h @@ -0,0 +1,32 @@ +/* + * UBIFS u-boot wrapper functions header + * + * Copyright (C) 2006-2008 Nokia Corporation + * + * (C) Copyright 2008-2009 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Adrian Hunter + */ + +#ifndef __UBIFS_UBOOT_H__ +#define __UBIFS_UBOOT_H__ + +int ubifs_init(void); +int uboot_ubifs_mount(char *vol_name); +void uboot_ubifs_umount(void); +int ubifs_is_mounted(void); +int ubifs_load(char *filename, u32 addr, u32 size); + +int ubifs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info); +int ubifs_ls(const char *dir_name); +int ubifs_exists(const char *filename); +int ubifs_size(const char *filename, loff_t *size); +int ubifs_read(const char *filename, void *buf, loff_t offset, + loff_t size, loff_t *actread); +void ubifs_close(void); + +#endif /* __UBIFS_UBOOT_H__ */ diff --git a/lib/time.c b/lib/time.c index 477440de16f..b001745203e 100644 --- a/lib/time.c +++ b/lib/time.c @@ -6,6 +6,9 @@ */ #include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> #include <watchdog.h> #include <div64.h> #include <asm/io.h> @@ -37,6 +40,52 @@ unsigned long notrace timer_read_counter(void) extern unsigned long __weak timer_read_counter(void); #endif +#ifdef CONFIG_TIMER +static int notrace dm_timer_init(void) +{ + struct udevice *dev; + int ret; + + if (!gd->timer) { + ret = uclass_first_device(UCLASS_TIMER, &dev); + if (ret) + return ret; + if (!dev) + return -ENODEV; + gd->timer = dev; + } + + return 0; +} + +ulong notrace get_tbclk(void) +{ + int ret; + + ret = dm_timer_init(); + if (ret) + return ret; + + return timer_get_rate(gd->timer); +} + +unsigned long notrace timer_read_counter(void) +{ + unsigned long count; + int ret; + + ret = dm_timer_init(); + if (ret) + return ret; + + ret = timer_get_count(gd->timer, &count); + if (ret) + return ret; + + return count; +} +#endif /* CONFIG_TIMER */ + uint64_t __weak notrace get_ticks(void) { unsigned long now = timer_read_counter(); diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 58442f150d8..2df93c8a095 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -52,6 +52,7 @@ libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/) libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/ libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/ +libs-y += common/init/ libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/ libs-y += drivers/ diff --git a/test/fs/fat-noncontig-test.sh b/test/fs/fat-noncontig-test.sh new file mode 100755 index 00000000000..f153c97bbf0 --- /dev/null +++ b/test/fs/fat-noncontig-test.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +# (C) Copyright 2015 Stephen Warren +# +# SPDX-License-Identifier: GPL-2.0+ + +# This script tests U-Boot's FAT filesystem code's ability to read non- +# contiguous files. + +# When porting the ff.c FAT parsing code into U-Boot, it was found that ff.c +# always reads files cluster-by-cluster, which results in poor performance. +# This was solved by adding a patch to ff.c to coalesce reads of adjacent +# clusters. Since this patch needed to correctly handle non-contiguous files, +# this test was written to validate that. +# +# To execute the test, simply run it from the U-Boot source root directory: +# +# cd u-boot +# ./test/fs/fat-noncontig-test.sh +# +# The test will create a FAT filesystem image, record the CRC of a randomly +# generated file in the image, build U-Boot sandbox, invoke U-Boot sandbox to +# read the file and validate that the CRCs match. Expected output is shown +# below. The important part of the log is the penultimate line that contains +# either "PASS" or "FAILURE". +# +# mkfs.fat 3.0.26 (2014-03-07) +# +# +# U-Boot 2015.10-rc4-00018-g4b22a3e5513f (Oct 03 2015 - 13:49:23 -0600) +# +# DRAM: 128 MiB +# Using default environment +# +# In: serial +# Out: lcd +# Err: lcd +# Net: No ethernet found. +# => host bind 0 sandbox/fat-noncontig.img +# => load host 0:0 1000 noncontig.img +# 33584964 bytes read in 18 ms (1.7 GiB/s) +# => crc32 1000 $filesize 0 +# crc32 for 00001000 ... 02008743 ==> 6a080523 +# => if itest.l *0 != 2305086a; then echo FAILURE; else echo PASS; fi +# PASS +# => reset +# +# All temporary files used by this script are created in ./sandbox to avoid +# polluting the source tree. test/fs/fs-test.sh also uses this directory for +# the same purpose. +# +# TODO: Integrate this (and many other corner-cases e.g. different types of +# FAT) with fs-test.sh so that a single script tests everything filesystem- +# related. + +odir=sandbox +img=${odir}/fat-noncontig.img +mnt=${odir}/mnt +fill=/dev/urandom +testfn=noncontig.img +mnttestfn=${mnt}/${testfn} +crcaddr=0 +loadaddr=1000 + +for prereq in fallocate mkfs.fat dd crc32; do + if [ ! -x "`which $prereq`" ]; then + echo "Missing $prereq binary. Exiting!" + exit 1 + fi +done + +make O=${odir} -s sandbox_defconfig && make O=${odir} -s -j8 + +mkdir -p ${mnt} +if [ ! -f ${img} ]; then + fallocate -l 40M ${img} + mkfs.fat ${img} + + sudo mount -o loop,uid=$(id -u) ${img} ${mnt} + + for ((sects=8; sects < 512; sects += 8)); do + fn=${mnt}/keep-${sects}.img + dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1 + fn=${mnt}/remove-${sects}.img + dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1 + done + + rm -f ${mnt}/remove-*.img + + # 511 deliberately to trigger a file size that's not a multiple of the + # sector size (ignoring sizes that are multiples of both). + dd if=${fill} of=${mnttestfn} bs=511 >/dev/null 2>&1 + + sudo umount ${mnt} +fi + +sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt} +crc=0x`crc32 ${mnttestfn}` +sudo umount ${mnt} + +crc=`printf %02x%02x%02x%02x \ + $((${crc} & 0xff)) \ + $(((${crc} >> 8) & 0xff)) \ + $(((${crc} >> 16) & 0xff)) \ + $((${crc} >> 24))` + +./sandbox/u-boot << EOF +host bind 0 ${img} +load host 0:0 ${loadaddr} ${testfn} +crc32 ${loadaddr} \$filesize ${crcaddr} +if itest.l *${crcaddr} != ${crc}; then echo FAILURE; else echo PASS; fi +reset +EOF diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh index 6f0a3455ed3..fc41c04c15e 100755 --- a/test/fs/fs-test.sh +++ b/test/fs/fs-test.sh @@ -58,7 +58,7 @@ GB2p5="${MOUNT_DIR}/${BIG_FILE}" # Check if the prereq binaries exist, or exit function check_prereq() { for prereq in $PREREQ_BINS; do - if [ ! -x `which $prereq` ]; then + if [ ! -x "`which $prereq`" ]; then echo "Missing $prereq binary. Exiting!" exit fi diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c index 69e99c0d179..d9361b00950 100644 --- a/tools/fit_check_sign.c +++ b/tools/fit_check_sign.c @@ -75,7 +75,7 @@ int main(int argc, char **argv) if (ffd < 0) return EXIT_FAILURE; kfd = mmap_fdt(cmdname, keyfile, 0, &key_blob, &ksbuf, false); - if (ffd < 0) + if (kfd < 0) return EXIT_FAILURE; image_set_host_blob(key_blob); diff --git a/tools/mkexynosspl.c b/tools/mkexynosspl.c index 32b786c724b..46195aad55a 100644 --- a/tools/mkexynosspl.c +++ b/tools/mkexynosspl.c @@ -110,7 +110,7 @@ int main(int argc, char **argv) } ofd = open(argv[of_index], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM); - if (ifd < 0) { + if (ofd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", prog_name, argv[of_index], strerror(errno)); exit(EXIT_FAILURE); |