From fc68911ee379bff429c2f8dfc0a4d3277eb193ec Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 25 Jun 2008 11:41:42 +0800 Subject: [PATCH 001/179] Blackfin arch: use the generic platform nand driver to support nand flash on bf53x board which do not have on-chip nand flash controller Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf537/boards/stamp.c | 86 +++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 671f9d67f23a..7e4b9d95674b 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -29,9 +29,12 @@ */ #include +#include #include #include +#include #include +#include #include #include #include @@ -355,6 +358,84 @@ static struct platform_device net2272_bfin_device = { }; #endif +#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) +#ifdef CONFIG_MTD_PARTITIONS +const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; + +static struct mtd_partition bfin_plat_nand_partitions[] = { + { + .name = "linux kernel", + .size = 0x400000, + .offset = 0, + }, { + .name = "file system", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + }, +}; +#endif + +#define BFIN_NAND_PLAT_CLE 2 +#define BFIN_NAND_PLAT_ALE 1 +static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_CLE)); + else + writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_ALE)); +} + +#define BFIN_NAND_PLAT_READY GPIO_PF3 +static int bfin_plat_nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value(BFIN_NAND_PLAT_READY); +} + +static struct platform_nand_data bfin_plat_nand_data = { + .chip = { + .chip_delay = 30, +#ifdef CONFIG_MTD_PARTITIONS + .part_probe_types = part_probes, + .partitions = bfin_plat_nand_partitions, + .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions), +#endif + }, + .ctrl = { + .cmd_ctrl = bfin_plat_nand_cmd_ctrl, + .dev_ready = bfin_plat_nand_dev_ready, + }, +}; + +#define MAX(x, y) (x > y ? x : y) +static struct resource bfin_plat_nand_resources = { + .start = 0x20212000, + .end = 0x20212000 + (1 << MAX(BFIN_NAND_PLAT_CLE, BFIN_NAND_PLAT_ALE)), + .flags = IORESOURCE_IO, +}; + +static struct platform_device bfin_async_nand_device = { + .name = "gen_nand", + .id = -1, + .num_resources = 1, + .resource = &bfin_plat_nand_resources, + .dev = { + .platform_data = &bfin_plat_nand_data, + }, +}; + +static void bfin_plat_nand_init(void) +{ + gpio_request(BFIN_NAND_PLAT_READY, "bfin_nand_plat"); +} +#else +static void bfin_plat_nand_init(void) {} +#endif + #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) static struct mtd_partition stamp_partitions[] = { { @@ -922,6 +1003,10 @@ static struct platform_device *stamp_devices[] __initdata = { &bfin_gpios_device, +#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) + &bfin_async_nand_device, +#endif + #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) &stamp_flash_device, #endif @@ -936,6 +1021,7 @@ static int __init stamp_init(void) ARRAY_SIZE(bfin_i2c_board_info)); #endif + bfin_plat_nand_init(); platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); From 1f2d18690f4390ac4cf75648a5bc18fc07b3aef6 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 14 Jul 2008 16:31:22 +0800 Subject: [PATCH 002/179] Blackfin arch: Fix Bug - GPIO interrupts not disabled; edge sensitive interrupt hang system. - Implement irq_chip.enable and irq_chip.disable Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/mach-common/ints-priority.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index f5fd768022ea..64d746114e4b 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -459,6 +459,8 @@ static struct irq_chip bfin_gpio_irqchip = { .mask = bfin_gpio_mask_irq, .mask_ack = bfin_gpio_mask_ack_irq, .unmask = bfin_gpio_unmask_irq, + .disable = bfin_gpio_mask_irq, + .enable = bfin_gpio_unmask_irq, .set_type = bfin_gpio_irq_type, .startup = bfin_gpio_irq_startup, .shutdown = bfin_gpio_irq_shutdown, @@ -846,6 +848,8 @@ static struct irq_chip bfin_gpio_irqchip = { .mask = bfin_gpio_mask_irq, .mask_ack = bfin_gpio_mask_ack_irq, .unmask = bfin_gpio_unmask_irq, + .disable = bfin_gpio_mask_irq, + .enable = bfin_gpio_unmask_irq, .set_type = bfin_gpio_irq_type, .startup = bfin_gpio_irq_startup, .shutdown = bfin_gpio_irq_shutdown, From 260d5d3517c67c5b68b4e28c5d3e1e3b73976a90 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Jul 2008 16:34:05 +0800 Subject: [PATCH 003/179] Blackfin arch: Fix bug - do not overflow the buffer given to us which tends to happen when CONFIG_L1_MAX_PIECE is increased past its default Singed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mm/blackfin_sram.c | 38 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c index 3246f91c7baa..8f6fdc245330 100644 --- a/arch/blackfin/mm/blackfin_sram.c +++ b/arch/blackfin/mm/blackfin_sram.c @@ -549,13 +549,16 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); /* Once we get a real allocator, we'll throw all of this away. * Until then, we need some sort of visibility into the L1 alloc. */ -static void _l1sram_proc_read(char *buf, int *len, const char *desc, +/* Need to keep line of output the same. Currently, that is 44 bytes + * (including newline). + */ +static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, struct l1_sram_piece *pfree, const int array_size) { int i; - *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State\n", desc); - for (i = 0; i < array_size; ++i) { + *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State \n", desc); + for (i = 0; i < array_size && *len < count; ++i) { const char *alloc_type; switch (pfree[i].flag) { case SRAM_SLT_NULL: alloc_type = "NULL"; break; @@ -563,31 +566,42 @@ static void _l1sram_proc_read(char *buf, int *len, const char *desc, case SRAM_SLT_ALLOCATED: alloc_type = "ALLOCATED"; break; default: alloc_type = "????"; break; } - *len += sprintf(&buf[*len], "%p-%p %8i %4i %s\n", + /* if we've got a lot of space to cover, omit things */ + if ((PAGE_SIZE - 1024) < (CONFIG_L1_MAX_PIECE + 1) * 4 * 44 && + pfree[i].size == 0) + continue; + *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", pfree[i].paddr, pfree[i].paddr + pfree[i].size, pfree[i].size, pfree[i].pid, alloc_type); } + return (i != array_size); } static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len = 0; - _l1sram_proc_read(buf, &len, "Scratchpad", - l1_ssram, ARRAY_SIZE(l1_ssram)); + if (_l1sram_proc_read(buf, &len, count, "Scratchpad", + l1_ssram, ARRAY_SIZE(l1_ssram))) + goto not_done; #if L1_DATA_A_LENGTH != 0 - _l1sram_proc_read(buf, &len, "Data A", - l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); + if (_l1sram_proc_read(buf, &len, count, "Data A", + l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram))) + goto not_done; #endif #if L1_DATA_B_LENGTH != 0 - _l1sram_proc_read(buf, &len, "Data B", - l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + if (_l1sram_proc_read(buf, &len, count, "Data B", + l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram))) + goto not_done; #endif #if L1_CODE_LENGTH != 0 - _l1sram_proc_read(buf, &len, "Instruction", - l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + if (_l1sram_proc_read(buf, &len, count, "Instruction", + l1_inst_sram, ARRAY_SIZE(l1_inst_sram))) + goto not_done; #endif + *eof = 1; + not_done: return len; } From 68e2fc78e5055740126df8eab0d31005495756c9 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 14 Jul 2008 16:51:57 +0800 Subject: [PATCH 004/179] Blackfin arch: Fix bug - Kernel does not boot if re-program clocks Don't write conflicting data to EBIU_SDBCTL after the SDRAM is configured. This can cause data corruption, since we might change SDRAM row and column addressing modes. Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig | 14 ----------- arch/blackfin/mach-bf527/head.S | 12 +++------- arch/blackfin/mach-bf533/head.S | 12 +++------- arch/blackfin/mach-bf537/head.S | 12 +++------- arch/blackfin/mach-bf548/head.S | 6 ++--- arch/blackfin/mach-bf561/head.S | 6 ----- include/asm-blackfin/mach-bf527/mem_init.h | 27 ---------------------- include/asm-blackfin/mach-bf533/mem_init.h | 27 ---------------------- include/asm-blackfin/mach-bf537/mem_init.h | 27 ---------------------- include/asm-blackfin/mach-bf561/mem_init.h | 27 ---------------------- 10 files changed, 12 insertions(+), 158 deletions(-) diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index b87634e75f20..d0f7ff3dc088 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -315,20 +315,6 @@ config MEM_SIZE depends on BFIN_KERNEL_CLOCK default 64 -config MEM_ADD_WIDTH - int "Memory Address Width" - depends on BFIN_KERNEL_CLOCK - depends on (!BF54x) - range 8 11 - default 9 if BFIN533_EZKIT - default 9 if BFIN561_EZKIT - default 9 if H8606_HVSISTEMAS - default 10 if BFIN527_EZKIT - default 10 if BFIN537_STAMP - default 11 if BFIN533_STAMP - default 10 if PNAV10 - default 10 if BFIN532_IP0X - config PLL_BYPASS bool "Bypass PLL" depends on BFIN_KERNEL_CLOCK diff --git a/arch/blackfin/mach-bf527/head.S b/arch/blackfin/mach-bf527/head.S index 57bdb3ba2fed..fe05cc1ef174 100644 --- a/arch/blackfin/mach-bf527/head.S +++ b/arch/blackfin/mach-bf527/head.S @@ -32,7 +32,7 @@ #include #include -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -185,7 +185,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif @@ -318,7 +318,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) /* Enable PHY CLK buffer output */ @@ -398,12 +398,6 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; - p0.l = LO(EBIU_SDBCTL); - p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ - r0 = mem_SDBCTL; - w[p0] = r0.l; - ssync; - P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S index 1295deac00a4..c671e8549b17 100644 --- a/arch/blackfin/mach-bf533/head.S +++ b/arch/blackfin/mach-bf533/head.S @@ -31,7 +31,7 @@ #include #include #include -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -186,7 +186,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif @@ -319,7 +319,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) p0.h = hi(SIC_IWR); p0.l = lo(SIC_IWR); @@ -390,12 +390,6 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; - p0.l = LO(EBIU_SDBCTL); - p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ - r0 = mem_SDBCTL; - w[p0] = r0.l; - ssync; - P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S index 48cd58a410a0..6b019eaee0b6 100644 --- a/arch/blackfin/mach-bf537/head.S +++ b/arch/blackfin/mach-bf537/head.S @@ -32,7 +32,7 @@ #include #include -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -217,7 +217,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif @@ -350,7 +350,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) /* Enable PHY CLK buffer output */ @@ -430,12 +430,6 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; - p0.l = LO(EBIU_SDBCTL); - p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ - r0 = mem_SDBCTL; - w[p0] = r0.l; - ssync; - P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index f7191141a3ce..06b9178cfcfe 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S @@ -31,7 +31,7 @@ #include #include #include -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK #include #include #endif @@ -130,7 +130,7 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK call _start_dma_code; #endif /* Code for initializing Async memory banks */ @@ -288,7 +288,7 @@ ENDPROC(_real_start) __FINIT .section .l1.text -#if CONFIG_BFIN_KERNEL_CLOCK +#ifdef CONFIG_BFIN_KERNEL_CLOCK ENTRY(_start_dma_code) /* Enable PHY CLK buffer output */ diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S index 5b8bd40851dd..cf1a2dff01e7 100644 --- a/arch/blackfin/mach-bf561/head.S +++ b/arch/blackfin/mach-bf561/head.S @@ -377,12 +377,6 @@ ENTRY(_start_dma_code) w[p0] = r0.l; ssync; - p0.l = LO(EBIU_SDBCTL); - p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */ - r0 = mem_SDBCTL; - w[p0] = r0.l; - ssync; - P2.H = hi(EBIU_SDGCTL); P2.L = lo(EBIU_SDGCTL); R0 = [P2]; diff --git a/include/asm-blackfin/mach-bf527/mem_init.h b/include/asm-blackfin/mach-bf527/mem_init.h index 008ca66719e2..cbe03f4a5698 100644 --- a/include/asm-blackfin/mach-bf527/mem_init.h +++ b/include/asm-blackfin/mach-bf527/mem_init.h @@ -146,33 +146,6 @@ #define SDRAM_CL CL_3 #endif -#if (CONFIG_MEM_SIZE == 128) -#define SDRAM_SIZE EBSZ_128 -#endif -#if (CONFIG_MEM_SIZE == 64) -#define SDRAM_SIZE EBSZ_64 -#endif -#if (CONFIG_MEM_SIZE == 32) -#define SDRAM_SIZE EBSZ_32 -#endif -#if (CONFIG_MEM_SIZE == 16) -#define SDRAM_SIZE EBSZ_16 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 11) -#define SDRAM_WIDTH EBCAW_11 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 10) -#define SDRAM_WIDTH EBCAW_10 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 9) -#define SDRAM_WIDTH EBCAW_9 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 8) -#define SDRAM_WIDTH EBCAW_8 -#endif - -#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) - /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) diff --git a/include/asm-blackfin/mach-bf533/mem_init.h b/include/asm-blackfin/mach-bf533/mem_init.h index f8f31901fca9..995c06b2b1ef 100644 --- a/include/asm-blackfin/mach-bf533/mem_init.h +++ b/include/asm-blackfin/mach-bf533/mem_init.h @@ -133,33 +133,6 @@ #define SDRAM_CL CL_3 #endif -#if (CONFIG_MEM_SIZE == 128) -#define SDRAM_SIZE EBSZ_128 -#endif -#if (CONFIG_MEM_SIZE == 64) -#define SDRAM_SIZE EBSZ_64 -#endif -#if (CONFIG_MEM_SIZE == 32) -#define SDRAM_SIZE EBSZ_32 -#endif -#if (CONFIG_MEM_SIZE == 16) -#define SDRAM_SIZE EBSZ_16 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 11) -#define SDRAM_WIDTH EBCAW_11 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 10) -#define SDRAM_WIDTH EBCAW_10 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 9) -#define SDRAM_WIDTH EBCAW_9 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 8) -#define SDRAM_WIDTH EBCAW_8 -#endif - -#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) - /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) diff --git a/include/asm-blackfin/mach-bf537/mem_init.h b/include/asm-blackfin/mach-bf537/mem_init.h index 9ad979d416c6..f67698f670ca 100644 --- a/include/asm-blackfin/mach-bf537/mem_init.h +++ b/include/asm-blackfin/mach-bf537/mem_init.h @@ -139,33 +139,6 @@ #define SDRAM_CL CL_3 #endif -#if (CONFIG_MEM_SIZE == 128) -#define SDRAM_SIZE EBSZ_128 -#endif -#if (CONFIG_MEM_SIZE == 64) -#define SDRAM_SIZE EBSZ_64 -#endif -#if (CONFIG_MEM_SIZE == 32) -#define SDRAM_SIZE EBSZ_32 -#endif -#if (CONFIG_MEM_SIZE == 16) -#define SDRAM_SIZE EBSZ_16 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 11) -#define SDRAM_WIDTH EBCAW_11 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 10) -#define SDRAM_WIDTH EBCAW_10 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 9) -#define SDRAM_WIDTH EBCAW_9 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 8) -#define SDRAM_WIDTH EBCAW_8 -#endif - -#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE) - /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) diff --git a/include/asm-blackfin/mach-bf561/mem_init.h b/include/asm-blackfin/mach-bf561/mem_init.h index 439a5895b346..e163260bca18 100644 --- a/include/asm-blackfin/mach-bf561/mem_init.h +++ b/include/asm-blackfin/mach-bf561/mem_init.h @@ -131,33 +131,6 @@ #define SDRAM_CL CL_3 #endif -#if (CONFIG_MEM_SIZE == 128) -#define SDRAM_SIZE EB0_SZ_128 -#endif -#if (CONFIG_MEM_SIZE == 64) -#define SDRAM_SIZE EB0_SZ_64 -#endif -#if ( CONFIG_MEM_SIZE == 32) -#define SDRAM_SIZE EB0_SZ_32 -#endif -#if (CONFIG_MEM_SIZE == 16) -#define SDRAM_SIZE EB0_SZ_16 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 11) -#define SDRAM_WIDTH EB0_CAW_11 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 10) -#define SDRAM_WIDTH EB0_CAW_10 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 9) -#define SDRAM_WIDTH EB0_CAW_9 -#endif -#if (CONFIG_MEM_ADD_WIDTH == 8) -#define SDRAM_WIDTH EB0_CAW_8 -#endif - -#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EB0_E) - /* Equation from section 17 (p17-46) of BF533 HRM */ #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) From 96b86e94bcf7eadbd8c959c0474d2971b3695478 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Jul 2008 16:39:43 +0800 Subject: [PATCH 005/179] Blackfin arch: use the symbolic IRQ define rather than the backend number Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf537/boards/stamp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 7e4b9d95674b..6dbc76fb080b 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -861,7 +861,7 @@ static struct platform_device bfin_sport1_uart_device = { #endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) -#define PATA_INT 55 +#define PATA_INT IRQ_PF5 static struct pata_platform_info bfin_pata_platform_data = { .ioport_shift = 1, From 99d95bbd48f43dafdcd0540eb0da26c5655d7f33 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 14 Jul 2008 17:04:14 +0800 Subject: [PATCH 006/179] Blackfin arch: Remove redundant kernel option use kernel command line mem and max_mem bootargs to limit availabe memory instead. Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig | 7 +------ arch/blackfin/kernel/cplb-nompu/cplbinit.c | 6 +----- arch/blackfin/kernel/setup.c | 14 +++++--------- arch/blackfin/mach-common/arch_checks.c | 6 ------ 4 files changed, 7 insertions(+), 26 deletions(-) diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index d0f7ff3dc088..c602727d1a9a 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -310,11 +310,6 @@ config BFIN_KERNEL_CLOCK are also not changed, and the Bootloader does 100% of the hardware configuration. -config MEM_SIZE - int "SDRAM Memory Size in MBytes" - depends on BFIN_KERNEL_CLOCK - default 64 - config PLL_BYPASS bool "Bypass PLL" depends on BFIN_KERNEL_CLOCK @@ -376,7 +371,7 @@ config SCLK_DIV config MAX_MEM_SIZE int "Max SDRAM Memory Size in MBytes" - depends on !BFIN_KERNEL_CLOCK && !MPU + depends on !MPU default 512 help This is the max memory size that the kernel will create CPLB diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 6be0c50122e8..224e7cc30bc5 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -26,11 +26,7 @@ #include #include -#ifdef CONFIG_MAX_MEM_SIZE -# define CPLB_MEM CONFIG_MAX_MEM_SIZE -#else -# define CPLB_MEM CONFIG_MEM_SIZE -#endif +#define CPLB_MEM CONFIG_MAX_MEM_SIZE /* * Number of required data CPLB switchtable entries diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8efea004aecb..861a1db74df8 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -664,11 +664,8 @@ static __init void setup_bootmem_allocator(void) }) static inline int __init get_mem_size(void) { -#ifdef CONFIG_MEM_SIZE - return CONFIG_MEM_SIZE; -#else -# if defined(EBIU_SDBCTL) -# if defined(BF561_FAMILY) +#if defined(EBIU_SDBCTL) +# if defined(BF561_FAMILY) int ret = 0; u32 sdbctl = bfin_read_EBIU_SDBCTL(); ret += EBSZ_TO_MEG(sdbctl >> 0); @@ -676,10 +673,10 @@ static inline int __init get_mem_size(void) ret += EBSZ_TO_MEG(sdbctl >> 16); ret += EBSZ_TO_MEG(sdbctl >> 24); return ret; -# else +# else return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); -# endif -# elif defined(EBIU_DDRCTL1) +# endif +#elif defined(EBIU_DDRCTL1) u32 ddrctl = bfin_read_EBIU_DDRCTL1(); int ret = 0; switch (ddrctl & 0xc0000) { @@ -694,7 +691,6 @@ static inline int __init get_mem_size(void) case DEVWD_16: break; } return ret; -# endif #endif BUG(); } diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c index caaab49e9cfa..f9160d83b91f 100644 --- a/arch/blackfin/mach-common/arch_checks.c +++ b/arch/blackfin/mach-common/arch_checks.c @@ -53,9 +53,3 @@ # endif #endif /* CONFIG_BFIN_KERNEL_CLOCK */ - -#ifdef CONFIG_MEM_SIZE -#if (CONFIG_MEM_SIZE % 4) -#error "SDRAM mem size must be multible of 4MB" -#endif -#endif From ed987319ed6a3f5e14c87141e210deb057a6c507 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 26 Jul 2008 18:40:06 +0800 Subject: [PATCH 007/179] Blackfin arch: update board defconfigs Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/configs/BF527-EZKIT_defconfig | 187 ++++++++++- arch/blackfin/configs/BF533-EZKIT_defconfig | 279 +++++----------- arch/blackfin/configs/BF533-STAMP_defconfig | 342 ++++++++------------ arch/blackfin/configs/BF537-STAMP_defconfig | 337 ++++++++----------- arch/blackfin/configs/BF548-EZKIT_defconfig | 65 +++- arch/blackfin/configs/BF561-EZKIT_defconfig | 273 +++++----------- arch/blackfin/configs/CM-BF533_defconfig | 14 +- arch/blackfin/configs/CM-BF537E_defconfig | 21 +- arch/blackfin/configs/CM-BF537U_defconfig | 18 +- arch/blackfin/configs/CM-BF548_defconfig | 10 +- arch/blackfin/configs/CM-BF561_defconfig | 14 +- arch/blackfin/configs/H8606_defconfig | 2 +- arch/blackfin/configs/IP0X_defconfig | 2 +- arch/blackfin/configs/PNAV-10_defconfig | 4 +- arch/blackfin/configs/SRV1_defconfig | 2 +- 15 files changed, 707 insertions(+), 863 deletions(-) diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index 5e6fb9d8e50f..66854a83c0de 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -1,7 +1,6 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.24.7 -# Fri May 16 10:02:29 2008 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -290,7 +289,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y -# CONFIG_BFIN_GPTIMERS is not set +CONFIG_BFIN_GPTIMERS=y CONFIG_BFIN_DMA_5XX=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set @@ -430,7 +429,58 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_BFIN_SIR=m +CONFIG_BFIN_SIR0=y +CONFIG_SIR_BFIN_DMA=y +# CONFIG_SIR_BFIN_PIO is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set +# CONFIG_KINGSUN_DONGLE is not set +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_MCS_FIR is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -689,8 +739,11 @@ CONFIG_BFIN_OTP=y # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set -# CONFIG_SIMPLE_GPIO is not set -# CONFIG_VT is not set +CONFIG_SIMPLE_GPIO=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -872,18 +925,136 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_BFIN_T350MCQB=y +# CONFIG_FB_BFIN_7393 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_LTV350QV=m +CONFIG_BACKLIGHT_CLASS_DEVICE=m +# CONFIG_BACKLIGHT_CORGI is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_LOGO_BLACKFIN_VGA16 is not set +CONFIG_LOGO_BLACKFIN_CLUT224=y + # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# SPI devices +# + +# +# ALSA Blackfin devices +# +# CONFIG_SND_BLACKFIN_AD1836 is not set +# CONFIG_SND_BLACKFIN_AD1836_TDM is not set +# CONFIG_SND_BLACKFIN_AD1836_I2S is not set +# CONFIG_SND_BLACKFIN_AD1836_MULSUB is not set +# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set +# CONFIG_SND_BFIN_AD73311 is not set +# CONFIG_SND_BFIN_AD73322 is not set + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +CONFIG_SND_SOC_AC97_BUS=y +CONFIG_SND_SOC=m +CONFIG_SND_BF5XX_SOC=m +CONFIG_SND_MMAP_SUPPORT=y +CONFIG_SND_BF5XX_SOC_I2S=m +CONFIG_SND_BF5XX_SOC_AC97=m +# CONFIG_SND_BF5XX_SOC_WM8750 is not set +# CONFIG_SND_BF5XX_SOC_WM8731 is not set +CONFIG_SND_BF5XX_SOC_SSM2602=m +CONFIG_SND_BF5XX_SOC_BF5xx=m +CONFIG_SND_BF5XX_SPORT_NUM=0 +# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set + +# +# SoC Audio support for SuperH +# +CONFIG_SND_SOC_SSM2602=m +# CONFIG_SND_SOC_SSM2602_SPI is not set +CONFIG_SND_SOC_AD1980=m + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 8d817ba01945..6bc11db12690 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.24.7 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,35 +13,34 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -64,32 +63,24 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -141,12 +132,12 @@ CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y -CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC16M16A2TG_75=y CONFIG_BFIN533_EZKIT=y # CONFIG_BFIN533_STAMP is not set # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_H8606_HVSISTEMAS is not set +# CONFIG_BFIN532_IP0X is not set # CONFIG_GENERIC_BF533_BOARD is not set # @@ -189,12 +180,14 @@ CONFIG_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=27000000 # CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=750000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -208,13 +201,17 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=512 -CONFIG_MEM_ADD_WIDTH=9 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -250,12 +247,14 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -293,17 +292,13 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xAAC3 +CONFIG_BANK_3=0xAAC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# # CONFIG_PCCARD is not set # @@ -321,7 +316,9 @@ CONFIG_BINFMT_ZFLAT=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set @@ -367,6 +364,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -393,10 +391,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -428,6 +422,7 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m +# CONFIG_BFIN_SIR is not set # # Dongle support @@ -457,6 +452,7 @@ CONFIG_IRTTY_SIR=m # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -465,14 +461,11 @@ CONFIG_IRTTY_SIR=m # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -492,6 +485,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -548,20 +542,8 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -571,10 +553,8 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -582,32 +562,29 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -624,15 +601,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -647,7 +616,6 @@ CONFIG_INPUT=m # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -672,13 +640,12 @@ CONFIG_INPUT_EVDEV=m # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set CONFIG_BFIN_SPORT=y # CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_AD5304 is not set +CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -706,28 +673,11 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set -CONFIG_BLACKFIN_DPMC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -748,22 +698,37 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set - -# -# Dallas's 1-wire bus -# +# CONFIG_SPI_TLE62X0 is not set # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -780,72 +745,27 @@ CONFIG_DAB=y # # Graphics support # +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set -# CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=m # CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set - -# -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set +# CONFIG_HIDRAW is not set +# CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -861,10 +781,6 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set # CONFIG_RTC_DRV_TEST is not set -# -# I2C RTC drivers -# - # # SPI RTC drivers # @@ -875,8 +791,10 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -885,22 +803,9 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# DMA Engine support +# Userspace I/O # -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_UIO is not set # # File systems @@ -945,7 +850,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -971,10 +875,12 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -983,10 +889,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1006,17 +909,12 @@ CONFIG_SMB_FS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1057,21 +955,16 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set - -# -# Profiling support -# +CONFIG_INSTRUMENTATION=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1079,6 +972,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1098,11 +992,7 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=m - -# -# Cryptographic options -# +# CONFIG_SECURITY_CAPABILITIES is not set # CONFIG_CRYPTO is not set # @@ -1113,6 +1003,7 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index 20d598d17bd1..d77d991a1f61 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.24.7 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,35 +13,34 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -64,32 +63,24 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -141,12 +132,12 @@ CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y -CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC64M4A2FB_7E=y # CONFIG_BFIN533_EZKIT is not set CONFIG_BFIN533_STAMP=y # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_H8606_HVSISTEMAS is not set +# CONFIG_BFIN532_IP0X is not set # CONFIG_GENERIC_BF533_BOARD is not set # @@ -189,12 +180,14 @@ CONFIG_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=11059200 # CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=750000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -208,14 +201,17 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=512 -CONFIG_MEM_ADD_WIDTH=11 -CONFIG_ENET_FLASH_PIN=0 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -251,12 +247,14 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -294,17 +292,13 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xAAC3 +CONFIG_BANK_3=0xAAC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# # CONFIG_PCCARD is not set # @@ -322,7 +316,9 @@ CONFIG_BINFMT_ZFLAT=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set @@ -368,6 +364,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -394,10 +391,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -429,6 +422,9 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m +CONFIG_BFIN_SIR=m +CONFIG_SIR_BFIN_DMA=y +# CONFIG_SIR_BFIN_PIO is not set # # Dongle support @@ -458,6 +454,7 @@ CONFIG_IRTTY_SIR=m # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -466,14 +463,11 @@ CONFIG_IRTTY_SIR=m # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -493,6 +487,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -524,11 +519,7 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_BF5xx=m -CONFIG_BFIN_FLASH_BANK_0=0x7BB0 -CONFIG_BFIN_FLASH_BANK_1=0x7BB0 -CONFIG_BFIN_FLASH_BANK_2=0x7BB0 -CONFIG_BFIN_FLASH_BANK_3=0x7BB0 +CONFIG_MTD_BFIN_ASYNC=m # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -555,20 +546,8 @@ CONFIG_BFIN_FLASH_BANK_3=0x7BB0 # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -578,10 +557,8 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -589,32 +566,29 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -631,15 +605,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -654,7 +620,6 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -667,14 +632,8 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_UINPUT is not set CONFIG_TWI_KEYPAD=m -CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39 # # Hardware I/O ports @@ -687,15 +646,13 @@ CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39 # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set CONFIG_BFIN_SPORT=y # CONFIG_BFIN_TIMER_LATENCY is not set CONFIG_TWI_LCD=m -CONFIG_TWI_LCD_SLAVE_ADDR=34 -# CONFIG_AD5304 is not set +CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -723,28 +680,11 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set -CONFIG_BLACKFIN_DPMC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y @@ -764,6 +704,7 @@ CONFIG_I2C_ALGOBIT=m # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_STUB is not set # @@ -771,14 +712,15 @@ CONFIG_I2C_ALGOBIT=m # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set # CONFIG_SENSORS_AD5252 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8575 is not set -# CONFIG_SENSORS_PCA9543 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -801,14 +743,11 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set - -# -# Dallas's 1-wire bus -# +# CONFIG_SPI_TLE62X0 is not set # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -816,12 +755,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -836,13 +775,16 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -852,6 +794,20 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -863,24 +819,20 @@ CONFIG_HWMON=y # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -CONFIG_DAB=y +# CONFIG_DAB is not set # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=m CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=m CONFIG_FB_CFB_COPYAREA=m CONFIG_FB_CFB_IMAGEBLIT=m +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set @@ -895,7 +847,7 @@ CONFIG_FB_DEFERRED_IO=y # # Frame buffer hardware drivers # -CONFIG_FB_BFIN_7171=m +# CONFIG_FB_BFIN_T350MCQB is not set CONFIG_FB_BFIN_7393=m CONFIG_NTSC=y # CONFIG_PAL is not set @@ -905,9 +857,14 @@ CONFIG_NTSC=y # CONFIG_PAL_YCBCR is not set CONFIG_ADV7393_1XMEM=y # CONFIG_ADV7393_2XMEM is not set -# CONFIG_FB_BFIN_T350MCQB is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_LOGO is not set # @@ -940,6 +897,10 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set +# +# SPI devices +# + # # ALSA Blackfin devices # @@ -953,69 +914,43 @@ CONFIG_SND_BLACKFIN_SPI_PFBIT=4 CONFIG_SND_BFIN_AD73311=m CONFIG_SND_BFIN_SPORT=0 CONFIG_SND_BFIN_AD73311_SE=4 +CONFIG_SND_BFIN_AD73322=m +CONFIG_SND_BFIN_AD73322_SPORT0_SE=10 +CONFIG_SND_BFIN_AD73322_SPORT1_SE=14 +CONFIG_SND_BFIN_AD73322_RESET=12 # # System on Chip audio support # -# CONFIG_SND_SOC is not set +CONFIG_SND_SOC_AC97_BUS=y +CONFIG_SND_SOC=m +CONFIG_SND_BF5XX_SOC=m +CONFIG_SND_MMAP_SUPPORT=y +CONFIG_SND_BF5XX_SOC_AC97=m +# CONFIG_SND_BF5XX_SOC_WM8750 is not set +# CONFIG_SND_BF5XX_SOC_WM8731 is not set +# CONFIG_SND_BF5XX_SOC_SSM2602 is not set +CONFIG_SND_BF5XX_SOC_BF5xx=m +CONFIG_SND_BF5XX_SPORT_NUM=0 +# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set + +# +# SoC Audio support for SuperH +# +CONFIG_SND_SOC_AD1980=m # # Open Sound System # # CONFIG_SOUND_PRIME is not set - -# -# HID Devices -# +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set - -# -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set +# CONFIG_HIDRAW is not set +# CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -1035,6 +970,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -1042,6 +978,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set # # SPI RTC drivers @@ -1053,8 +990,10 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1063,22 +1002,9 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# DMA Engine support +# Userspace I/O # -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_UIO is not set # # File systems @@ -1123,7 +1049,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1149,10 +1074,12 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -1161,10 +1088,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1184,17 +1108,12 @@ CONFIG_SMB_FS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1235,21 +1154,16 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set - -# -# Profiling support -# +CONFIG_INSTRUMENTATION=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1257,6 +1171,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1276,11 +1191,7 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=m - -# -# Cryptographic options -# +# CONFIG_SECURITY_CAPABILITIES is not set # CONFIG_CRYPTO is not set # @@ -1291,6 +1202,7 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index b5189c8ba263..5fd7c4b143df 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.24.7 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,35 +13,34 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -64,32 +63,24 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -141,7 +132,6 @@ CONFIG_BF_REV_0_2=y # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set CONFIG_BF53x=y -CONFIG_BFIN_SINGLE_CORE=y CONFIG_MEM_MT48LC32M8A2_75=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_RTC=8 @@ -197,12 +187,14 @@ CONFIG_IRQ_PROG_INTA=12 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=25000000 # CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=600000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -216,13 +208,17 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=512 -CONFIG_MEM_ADD_WIDTH=10 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -258,12 +254,14 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -301,17 +299,13 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B3 +CONFIG_BANK_3=0x99B2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# # CONFIG_PCCARD is not set # @@ -329,7 +323,9 @@ CONFIG_BINFMT_ZFLAT=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_SUSPEND=y CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set @@ -375,6 +371,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -401,10 +398,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -436,6 +429,10 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m +CONFIG_BFIN_SIR=m +CONFIG_BFIN_SIR1=y +CONFIG_SIR_BFIN_DMA=y +# CONFIG_SIR_BFIN_PIO is not set # # Dongle support @@ -465,6 +462,7 @@ CONFIG_IRTTY_SIR=m # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -473,14 +471,11 @@ CONFIG_IRTTY_SIR=m # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -500,6 +495,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -572,20 +568,8 @@ CONFIG_MTD_NAND_IDS=m # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -595,10 +579,8 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -606,22 +588,18 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set CONFIG_PHYLIB=y # @@ -635,21 +613,24 @@ CONFIG_PHYLIB=y # CONFIG_VITESSE_PHY is not set CONFIG_SMSC_PHY=y # CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set # CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_SMC91X is not set CONFIG_BFIN_MAC=y CONFIG_BFIN_MAC_USE_L1=y CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_BFIN_MAC_RMII is not set +# CONFIG_SMC91X is not set # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -666,15 +647,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -689,7 +662,6 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -702,14 +674,8 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_UINPUT is not set CONFIG_TWI_KEYPAD=m -CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 # # Hardware I/O ports @@ -722,15 +688,13 @@ CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set CONFIG_BFIN_SPORT=y # CONFIG_BFIN_TIMER_LATENCY is not set CONFIG_TWI_LCD=m -CONFIG_TWI_LCD_SLAVE_ADDR=34 -# CONFIG_AD5304 is not set +CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -766,28 +730,11 @@ CONFIG_CAN4LINUX=y # CONFIG_CAN_MCF5282 is not set # CONFIG_CAN_UNCTWINCAN is not set CONFIG_CAN_BLACKFIN=m - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set -CONFIG_BLACKFIN_DPMC=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y @@ -809,6 +756,7 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_STUB is not set # @@ -816,14 +764,15 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # # CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set CONFIG_SENSORS_AD5252=m # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8575 is not set -# CONFIG_SENSORS_PCA9543 is not set # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -846,14 +795,11 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set - -# -# Dallas's 1-wire bus -# +# CONFIG_SPI_TLE62X0 is not set # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -861,12 +807,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -881,13 +827,16 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -897,6 +846,20 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -913,21 +876,15 @@ CONFIG_DAB=y # # Graphics support # -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BACKLIGHT_CLASS_DEVICE=m -CONFIG_LCD_CLASS_DEVICE=m - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=m CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=m CONFIG_FB_CFB_COPYAREA=m CONFIG_FB_CFB_IMAGEBLIT=m +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set @@ -942,7 +899,8 @@ CONFIG_FB_DEFERRED_IO=y # # Frame buffer hardware drivers # -CONFIG_FB_BFIN_7171=m +# CONFIG_FB_HITACHI_TX09 is not set +# CONFIG_FB_BFIN_T350MCQB is not set CONFIG_FB_BFIN_7393=m CONFIG_NTSC=y # CONFIG_PAL is not set @@ -956,10 +914,18 @@ CONFIG_FB_BF537_LQ035=m CONFIG_LQ035_SLAVE_ADDR=0x58 # CONFIG_FB_BFIN_LANDSCAPE is not set # CONFIG_FB_BFIN_BGR is not set -# CONFIG_FB_BFIN_T350MCQB is not set -# CONFIG_FB_HITACHI_TX09 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_LTV350QV is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_CORGI=m + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_LOGO is not set # @@ -992,6 +958,10 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set +# +# SPI devices +# + # # ALSA Blackfin devices # @@ -1005,6 +975,10 @@ CONFIG_SND_BLACKFIN_SPI_PFBIT=4 CONFIG_SND_BFIN_AD73311=m CONFIG_SND_BFIN_SPORT=0 CONFIG_SND_BFIN_AD73311_SE=4 +CONFIG_SND_BFIN_AD73322=m +CONFIG_SND_BFIN_AD73322_SPORT0_SE=10 +CONFIG_SND_BFIN_AD73322_SPORT1_SE=14 +CONFIG_SND_BFIN_AD73322_RESET=12 # # System on Chip audio support @@ -1016,9 +990,14 @@ CONFIG_SND_MMAP_SUPPORT=y CONFIG_SND_BF5XX_SOC_AC97=m # CONFIG_SND_BF5XX_SOC_WM8750 is not set # CONFIG_SND_BF5XX_SOC_WM8731 is not set +# CONFIG_SND_BF5XX_SOC_SSM2602 is not set CONFIG_SND_BF5XX_SOC_BF5xx=m CONFIG_SND_BF5XX_SPORT_NUM=0 # CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set + +# +# SoC Audio support for SuperH +# CONFIG_SND_SOC_AD1980=m # @@ -1026,59 +1005,18 @@ CONFIG_SND_SOC_AD1980=m # # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=m - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set - -# -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set +# CONFIG_HIDRAW is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_NO_DUMMY_DELAY is not set +# CONFIG_DUMMY_DELAY_BANK0 is not set +# CONFIG_DUMMY_DELAY_BANK1 is not set +# CONFIG_DUMMY_DELAY_BANK2 is not set +# CONFIG_DUMMY_DELAY_BANK3 is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -1098,6 +1036,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -1105,6 +1044,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set # # SPI RTC drivers @@ -1116,8 +1056,10 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1126,22 +1068,9 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_BFIN=y # -# DMA Engine support +# Userspace I/O # -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_UIO is not set # # File systems @@ -1186,7 +1115,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1212,10 +1140,12 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -1224,10 +1154,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1247,17 +1174,12 @@ CONFIG_SMB_FS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1298,21 +1220,16 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set - -# -# Profiling support -# +CONFIG_INSTRUMENTATION=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1320,6 +1237,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1339,11 +1257,7 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=m - -# -# Cryptographic options -# +# CONFIG_SECURITY_CAPABILITIES is not set # CONFIG_CRYPTO is not set # @@ -1354,6 +1268,7 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index 1ff2ff4b49aa..390669e8668e 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -365,7 +365,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x5554 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B3 +CONFIG_BANK_3=0x99B2 CONFIG_EBIU_MBSCTLVAL=0x0 CONFIG_EBIU_MODEVAL=0x1 CONFIG_EBIU_FCTLVAL=0x6 @@ -468,7 +468,60 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_BFIN_SIR=m +# CONFIG_BFIN_SIR0 is not set +# CONFIG_BFIN_SIR2 is not set +CONFIG_BFIN_SIR3=y +CONFIG_SIR_BFIN_DMA=y +# CONFIG_SIR_BFIN_PIO is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set +# CONFIG_KINGSUN_DONGLE is not set +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_MCS_FIR is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -575,6 +628,7 @@ CONFIG_MTD_NAND=y CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_BF5XX=y CONFIG_MTD_NAND_BF5XX_HWECC=y +# CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC is not set # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set @@ -766,7 +820,7 @@ CONFIG_BFIN_OTP=y # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set -# CONFIG_SIMPLE_GPIO is not set +CONFIG_SIMPLE_GPIO=m CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y @@ -1071,6 +1125,7 @@ CONFIG_SND_BF5XX_SOC_AC97=y CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y # CONFIG_SND_BF5XX_SOC_WM8750 is not set # CONFIG_SND_BF5XX_SOC_WM8731 is not set +# CONFIG_SND_BF5XX_SOC_SSM2602 is not set CONFIG_SND_BF5XX_SPORT_NUM=0 CONFIG_SND_BF5XX_HAVE_COLD_RESET=y CONFIG_SND_BF5XX_RESET_GPIO_NUM=19 @@ -1133,7 +1188,7 @@ CONFIG_USB_MUSB_HOST=y # CONFIG_USB_MUSB_OTG is not set CONFIG_USB_MUSB_HDRC_HCD=y # CONFIG_MUSB_PIO_ONLY is not set -# CONFIG_USB_INVENTRA_DMA is not set +CONFIG_USB_INVENTRA_DMA=y # CONFIG_USB_TI_CPPI_DMA is not set CONFIG_USB_MUSB_LOGLEVEL=0 @@ -1312,7 +1367,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index b4a20c890816..976a4d7ba175 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.16 +# Linux kernel version: 2.6.24.7 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -13,35 +13,34 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y @@ -64,32 +63,24 @@ CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_EVENTFD=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3 -# CONFIG_NP2 is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -140,7 +131,6 @@ CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_5 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set -CONFIG_BFIN_DUAL_CORE=y CONFIG_MEM_MT48LC16M16A2TG_75=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_SPORT0_ERROR=7 @@ -233,12 +223,14 @@ CONFIG_IRQ_WDTIMER=13 # Board customizations # # CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 # # Clock/PLL Setup # CONFIG_CLKIN_HZ=30000000 # CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 CONFIG_MAX_VCO_HZ=600000000 CONFIG_MIN_VCO_HZ=50000000 CONFIG_MAX_SCLK_HZ=133333333 @@ -252,13 +244,17 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # -# Memory Setup +# Misc # -CONFIG_MAX_MEM_SIZE=512 -CONFIG_MEM_ADD_WIDTH=9 -CONFIG_BOOT_LOAD=0x1000 CONFIG_BFIN_SCRATCH_REG_RETN=y # CONFIG_BFIN_SCRATCH_REG_RETE is not set # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set @@ -294,12 +290,14 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 -CONFIG_LARGE_ALLOCS=y +CONFIG_VIRT_TO_BUS=y # CONFIG_BFIN_GPTIMERS is not set CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y # CONFIG_DMA_UNCACHED_NONE is not set @@ -341,17 +339,13 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xAAC3 +CONFIG_BANK_3=0xAAC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# # CONFIG_PCCARD is not set # @@ -367,8 +361,14 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y # CONFIG_PM_WAKEUP_BY_GPIO is not set +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + # # Networking # @@ -405,6 +405,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -431,10 +432,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -466,6 +463,7 @@ CONFIG_IRDA_CACHE_LAST_LSAP=y # SIR device drivers # CONFIG_IRTTY_SIR=m +# CONFIG_BFIN_SIR is not set # # Dongle support @@ -495,6 +493,7 @@ CONFIG_IRTTY_SIR=m # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -503,14 +502,11 @@ CONFIG_IRTTY_SIR=m # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set @@ -530,6 +526,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -590,20 +587,8 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set - -# -# Parallel port support -# # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -613,10 +598,8 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -624,32 +607,29 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y # CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_NETDEV_1000=y # CONFIG_AX88180 is not set CONFIG_NETDEV_10000=y @@ -666,15 +646,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -689,7 +661,6 @@ CONFIG_INPUT=m # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set @@ -714,13 +685,12 @@ CONFIG_INPUT_EVDEV=m # # CONFIG_AD9960 is not set # CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF5xx_PFLAGS is not set # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set -# CONFIG_AD5304 is not set +CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -748,27 +718,11 @@ CONFIG_UNIX98_PTYS=y # CAN, the car bus and industrial fieldbus # # CONFIG_CAN4LINUX is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set @@ -789,22 +743,37 @@ CONFIG_SPI_BFIN=y # # CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set - -# -# Dallas's 1-wire bus -# +# CONFIG_SPI_TLE62X0 is not set # CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -821,91 +790,33 @@ CONFIG_DAB=y # # Graphics support # +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set -# CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=m # CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set - -# -# Enable Host or Gadget support to see Inventra options -# - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set +# CONFIG_HIDRAW is not set +# CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set - -# -# LED devices -# # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# # CONFIG_RTC_CLASS is not set # -# DMA Engine support +# Userspace I/O # -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# PBX support -# -# CONFIG_PBX is not set +# CONFIG_UIO is not set # # File systems @@ -950,7 +861,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -976,10 +886,12 @@ CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set @@ -988,10 +900,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1011,17 +920,12 @@ CONFIG_SMB_FS=m # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# CONFIG_NLS=m CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1062,21 +966,16 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set - -# -# Profiling support -# +CONFIG_INSTRUMENTATION=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1084,6 +983,7 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y @@ -1104,11 +1004,7 @@ CONFIG_ACCESS_CHECK=y # CONFIG_KEYS is not set CONFIG_SECURITY=y # CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=m - -# -# Cryptographic options -# +# CONFIG_SECURITY_CAPABILITIES is not set # CONFIG_CRYPTO is not set # @@ -1119,6 +1015,7 @@ CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig index 560890fe0d30..09deea44480b 100644 --- a/arch/blackfin/configs/CM-BF533_defconfig +++ b/arch/blackfin/configs/CM-BF533_defconfig @@ -39,7 +39,8 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -291,7 +292,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC3 +CONFIG_BANK_3=0xFFC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -617,8 +618,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set # # CAN, the car bus and industrial fieldbus @@ -778,7 +778,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -866,11 +866,11 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_MMRS is not set +CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y diff --git a/arch/blackfin/configs/CM-BF537E_defconfig b/arch/blackfin/configs/CM-BF537E_defconfig index 9f66d2de1007..219fc345a5f5 100644 --- a/arch/blackfin/configs/CM-BF537E_defconfig +++ b/arch/blackfin/configs/CM-BF537E_defconfig @@ -39,7 +39,8 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -299,7 +300,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC3 +CONFIG_BANK_3=0xFFC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -351,7 +352,10 @@ CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_ARPD is not set @@ -645,8 +649,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set # # CAN, the car bus and industrial fieldbus @@ -806,7 +809,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -894,12 +897,12 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_MMRS is not set -# CONFIG_DEBUG_HUNT_FOR_ZERO is not set +CONFIG_DEBUG_MMRS=y +CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y # CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set diff --git a/arch/blackfin/configs/CM-BF537U_defconfig b/arch/blackfin/configs/CM-BF537U_defconfig index 2694d06c5bde..9873d586fc77 100644 --- a/arch/blackfin/configs/CM-BF537U_defconfig +++ b/arch/blackfin/configs/CM-BF537U_defconfig @@ -39,7 +39,8 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TASKSTATS is not set # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set @@ -298,8 +299,8 @@ CONFIG_C_AMBEN_ALL=y # CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 -CONFIG_BANK_2=0xFFC3 -CONFIG_BANK_3=0xFFC3 +CONFIG_BANK_2=0xFFC2 +CONFIG_BANK_3=0xFFC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -628,8 +629,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set # # CAN, the car bus and industrial fieldbus @@ -806,7 +806,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -894,12 +894,12 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_MMRS is not set -# CONFIG_DEBUG_HUNT_FOR_ZERO is not set +CONFIG_DEBUG_MMRS=y +CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y # CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig index 90207251c533..0e3605fdb7b0 100644 --- a/arch/blackfin/configs/CM-BF548_defconfig +++ b/arch/blackfin/configs/CM-BF548_defconfig @@ -363,7 +363,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x5554 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B3 +CONFIG_BANK_3=0x99B2 CONFIG_EBIU_MBSCTLVAL=0x0 CONFIG_EBIU_MODEVAL=0x1 CONFIG_EBIU_FCTLVAL=0x6 @@ -744,8 +744,8 @@ CONFIG_BFIN_OTP=y # CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y -# CONFIG_SERIAL_BFIN_DMA is not set -CONFIG_SERIAL_BFIN_PIO=y +CONFIG_SERIAL_BFIN_DMA=y +# CONFIG_SERIAL_BFIN_PIO is not set # CONFIG_SERIAL_BFIN_UART0 is not set CONFIG_SERIAL_BFIN_UART1=y # CONFIG_BFIN_UART1_CTSRTS is not set @@ -1149,7 +1149,7 @@ CONFIG_RTC_DRV_BFIN=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -1332,7 +1332,7 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_SAMPLES is not set -# CONFIG_DEBUG_MMRS is not set +CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig index daf00906c1ef..59c7cdbee904 100644 --- a/arch/blackfin/configs/CM-BF561_defconfig +++ b/arch/blackfin/configs/CM-BF561_defconfig @@ -35,7 +35,8 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_USER_NS is not set # CONFIG_PID_NS is not set # CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set CONFIG_FAIR_GROUP_SCHED=y @@ -341,7 +342,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x7BB0 CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0xFFC3 +CONFIG_BANK_3=0xFFC2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -631,8 +632,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set # # CAN, the car bus and industrial fieldbus @@ -756,7 +756,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -830,12 +830,12 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_SAMPLES is not set -# CONFIG_DEBUG_MMRS is not set +CONFIG_DEBUG_MMRS=y CONFIG_DEBUG_HUNT_FOR_ZERO=y CONFIG_DEBUG_BFIN_HWTRACE_ON=y CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig index 679c7483ea71..ba0bee90b7e1 100644 --- a/arch/blackfin/configs/H8606_defconfig +++ b/arch/blackfin/configs/H8606_defconfig @@ -967,7 +967,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/arch/blackfin/configs/IP0X_defconfig b/arch/blackfin/configs/IP0X_defconfig index 4384a670a8b8..285d2241df26 100644 --- a/arch/blackfin/configs/IP0X_defconfig +++ b/arch/blackfin/configs/IP0X_defconfig @@ -1066,7 +1066,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig index 87622ad9df47..bffca7de65d4 100644 --- a/arch/blackfin/configs/PNAV-10_defconfig +++ b/arch/blackfin/configs/PNAV-10_defconfig @@ -294,7 +294,7 @@ CONFIG_C_AMBEN_ALL=y CONFIG_BANK_0=0x7BB0 CONFIG_BANK_1=0x33B0 CONFIG_BANK_2=0x33B0 -CONFIG_BANK_3=0x99B3 +CONFIG_BANK_3=0x99B2 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -1080,7 +1080,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set diff --git a/arch/blackfin/configs/SRV1_defconfig b/arch/blackfin/configs/SRV1_defconfig index 951ea0412576..b1309f878fcd 100644 --- a/arch/blackfin/configs/SRV1_defconfig +++ b/arch/blackfin/configs/SRV1_defconfig @@ -1067,7 +1067,7 @@ CONFIG_FS_MBCACHE=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set From c71b47835188d0c2a1e1f9590564f1b71c651710 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 14 Jul 2008 17:10:50 +0800 Subject: [PATCH 008/179] Blackfin arch: set CROSS_COMPILE in our arch Makefile so it gets used by default Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 3cbe16caad4b..9564731ad3a8 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -6,8 +6,9 @@ # for more details. # - -CROSS_COMPILE ?= bfin-uclinux- +ifeq ($(CROSS_COMPILE),) +CROSS_COMPILE := bfin-uclinux- +endif LDFLAGS_vmlinux := -X OBJCOPYFLAGS := -O binary -R .note -R .comment -S GZFLAGS := -9 From 1c0d20cd29aec11a3580cedf0bccec25052e8d4c Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Tue, 15 Jul 2008 12:08:50 +0800 Subject: [PATCH 009/179] Blackfin arch: add TXDWA definition to enable new feature Signed-off-by: Bryan Wu --- include/asm-blackfin/mach-bf527/anomaly.h | 2 ++ include/asm-blackfin/mach-bf527/defBF527.h | 1 + include/asm-blackfin/mach-bf537/defBF537.h | 1 + 3 files changed, 4 insertions(+) diff --git a/include/asm-blackfin/mach-bf527/anomaly.h b/include/asm-blackfin/mach-bf527/anomaly.h index 4725268a5ada..b7b166f4f064 100644 --- a/include/asm-blackfin/mach-bf527/anomaly.h +++ b/include/asm-blackfin/mach-bf527/anomaly.h @@ -23,6 +23,8 @@ #define ANOMALY_05000245 (1) /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ #define ANOMALY_05000265 (1) +/* New Feature: EMAC TX DMA Word Alignment */ +#define ANOMALY_05000285 (1) /* Errors when SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */ #define ANOMALY_05000312 (1) /* Incorrect Access of OTP_STATUS During otp_write() Function */ diff --git a/include/asm-blackfin/mach-bf527/defBF527.h b/include/asm-blackfin/mach-bf527/defBF527.h index 82134f578f32..f1a70db70cb8 100644 --- a/include/asm-blackfin/mach-bf527/defBF527.h +++ b/include/asm-blackfin/mach-bf527/defBF527.h @@ -302,6 +302,7 @@ #define PHYIE 0x00000001 /* PHY_INT Interrupt Enable */ #define RXDWA 0x00000002 /* Receive Frame DMA Word Alignment (Odd/Even*) */ #define RXCKS 0x00000004 /* Enable RX Frame TCP/UDP Checksum Computation */ +#define TXDWA 0x00000010 /* Transmit Frame DMA Word Alignment (Odd/Even*) */ #define MDCDIV 0x00003F00 /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))] */ #define SET_MDCDIV(x) (((x)&0x3F)<< 8) /* Set MDC Clock Divisor */ diff --git a/include/asm-blackfin/mach-bf537/defBF537.h b/include/asm-blackfin/mach-bf537/defBF537.h index 3f455909c418..abde24c6d3b1 100644 --- a/include/asm-blackfin/mach-bf537/defBF537.h +++ b/include/asm-blackfin/mach-bf537/defBF537.h @@ -290,6 +290,7 @@ #define PHYIE 0x00000001 /* PHY_INT Interrupt Enable */ #define RXDWA 0x00000002 /* Receive Frame DMA Word Alignment (Odd/Even*) */ #define RXCKS 0x00000004 /* Enable RX Frame TCP/UDP Checksum Computation */ +#define TXDWA 0x00000010 /* Transmit Frame DMA Word Alignment (Odd/Even*) */ #define MDCDIV 0x00003F00 /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))] */ #define SET_MDCDIV(x) (((x)&0x3F)<< 8) /* Set MDC Clock Divisor */ From 4f13f548cef5af1717cbbc341a1a3474f3e7466e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 15 Jul 2008 16:38:28 +0800 Subject: [PATCH 010/179] Blackfin arch: Fix BUG - JUMP error in kernel (relocation truncated to fit: R_pcrel12_jump_s) Use long jump Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/kernel/cplb-nompu/cplbhdlr.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S index 2788532de72b..ecbabc0a1fed 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S +++ b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S @@ -125,6 +125,6 @@ ENTRY(__cplb_hdr) SP += -12; call _panic_cplb_error; SP += 12; - JUMP _handle_bad_cplb; + JUMP.L _handle_bad_cplb; ENDPROC(__cplb_hdr) From 1efc80b53eb54770139219f99657abd92595fc86 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Sat, 19 Jul 2008 16:57:32 +0800 Subject: [PATCH 011/179] Blackfin arch: Functional power management support Enable: PM_SUSPEND_MEM -> Blackfin Hibernate to SDRAM This feature requires a special bootloader (u-boot) supporting return from hibernate. Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig | 66 ++- arch/blackfin/kernel/bfin_dma_5xx.c | 26 ++ arch/blackfin/kernel/bfin_gpio.c | 118 ++++- arch/blackfin/mach-common/dpmc_modes.S | 606 +++++++++++++++++++++++-- arch/blackfin/mach-common/pm.c | 225 ++++++++- include/asm-blackfin/dma.h | 8 + include/asm-blackfin/dpmc.h | 82 ++-- include/asm-blackfin/gpio.h | 19 +- include/asm-blackfin/mach-bf548/gpio.h | 8 + 9 files changed, 1036 insertions(+), 122 deletions(-) diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index c602727d1a9a..8f21b78b2e6f 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -880,7 +880,7 @@ config ARCH_SUSPEND_POSSIBLE depends on !SMP choice - prompt "Default Power Saving Mode" + prompt "Standby Power Saving Mode" depends on PM default PM_BFIN_SLEEP_DEEPER config PM_BFIN_SLEEP_DEEPER @@ -899,6 +899,8 @@ config PM_BFIN_SLEEP_DEEPER normal during Sleep Deeper, due to the reduced SCLK frequency. When in the sleep mode, system DMA access to L1 memory is not supported. + If unsure, select "Sleep Deeper". + config PM_BFIN_SLEEP bool "Sleep" help @@ -906,15 +908,17 @@ config PM_BFIN_SLEEP dissipation by disabling the clock to the processor core (CCLK). The PLL and system clock (SCLK), however, continue to operate in this mode. Typically an external event or RTC activity will wake - up the processor. When in the sleep mode, - system DMA access to L1 memory is not supported. + up the processor. When in the sleep mode, system DMA access to L1 + memory is not supported. + + If unsure, select "Sleep Deeper". endchoice config PM_WAKEUP_BY_GPIO - bool "Cause Wakeup Event by GPIO" + bool "Allow Wakeup from Standby by GPIO" config PM_WAKEUP_GPIO_NUMBER - int "Wakeup GPIO number" + int "GPIO number" range 0 47 depends on PM_WAKEUP_BY_GPIO default 2 if BFIN537_STAMP @@ -935,6 +939,58 @@ config PM_WAKEUP_GPIO_POLAR_EDGE_B bool "Both EDGE" endchoice +comment "Possible Suspend Mem / Hibernate Wake-Up Sources" + depends on PM + +config PM_BFIN_WAKE_RTC + bool "Allow Wake-Up from RESET and on-chip RTC" + depends on PM + default n + help + Enable RTC Wake-Up (Voltage Regulator Power-Up) + +config PM_BFIN_WAKE_PH6 + bool "Allow Wake-Up from on-chip PHY or PH6 GP" + depends on PM && (BF52x || BF534 || BF536 || BF537) + default n + help + Enable PHY and PH6 GP Wake-Up (Voltage Regulator Power-Up) + +config PM_BFIN_WAKE_CAN + bool "Allow Wake-Up from on-chip CAN0/1" + depends on PM && (BF54x || BF534 || BF536 || BF537) + default n + help + Enable CAN0/1 Wake-Up (Voltage Regulator Power-Up) + +config PM_BFIN_WAKE_GP + bool "Allow Wake-Up from GPIOs" + depends on PM && BF54x + default n + help + Enable General-Purpose Wake-Up (Voltage Regulator Power-Up) + +config PM_BFIN_WAKE_USB + bool "Allow Wake-Up from on-chip USB" + depends on PM && (BF54x || BF52x) + default n + help + Enable USB Wake-Up (Voltage Regulator Power-Up) + +config PM_BFIN_WAKE_KEYPAD + bool "Allow Wake-Up from on-chip Keypad" + depends on PM && BF54x + default n + help + Enable Keypad Wake-Up (Voltage Regulator Power-Up) + +config PM_BFIN_WAKE_ROTARY + bool "Allow Wake-Up from on-chip Rotary" + depends on PM && BF54x + default n + help + Enable Rotary Wake-Up (Voltage Regulator Power-Up) + endmenu menu "CPU Frequency scaling" diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index d54f19085f37..ad0e75845ac2 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -472,6 +472,32 @@ unsigned long get_dma_curr_addr(unsigned int channel) } EXPORT_SYMBOL(get_dma_curr_addr); +#ifdef CONFIG_PM +int blackfin_dma_suspend(void) +{ + int i; + + for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { + if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) { + printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); + return -EBUSY; + } + + dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map; + } + + return 0; +} + +void blackfin_dma_resume(void) +{ + int i; + + for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) + dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; +} +#endif + static void *__dma_memcpy(void *dest, const void *src, size_t size) { int direction; /* 1 - address decrease, 0 - address increase */ diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index b6d89d1644cc..ecbd141e0ef2 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -186,7 +186,10 @@ static struct str_ident { char name[RESOURCE_LABEL_SIZE]; } str_ident[MAX_RESOURCES]; -#if defined(CONFIG_PM) && !defined(CONFIG_BF54x) +#if defined(CONFIG_PM) +#if defined(CONFIG_BF54x) +static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; +#else static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; @@ -206,7 +209,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PORTF_INT #ifdef BF561_FAMILY static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; #endif - +#endif #endif /* CONFIG_PM */ #if defined(BF548_FAMILY) @@ -667,7 +670,7 @@ static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) return 0; } -u32 bfin_pm_setup(void) +u32 bfin_pm_standby_setup(void) { u16 bank, mask, i, gpio; @@ -679,7 +682,7 @@ u32 bfin_pm_setup(void) gpio_bankb[bank]->maskb = 0; if (mask) { -#ifdef BF537_FAMILY +#if defined(BF527_FAMILY) || defined(BF537_FAMILY) gpio_bank_saved[bank].fer = *port_fer[bank]; #endif gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; @@ -715,7 +718,7 @@ u32 bfin_pm_setup(void) return 0; } -void bfin_pm_restore(void) +void bfin_pm_standby_restore(void) { u16 bank, mask, i; @@ -724,7 +727,7 @@ void bfin_pm_restore(void) bank = gpio_bank(i); if (mask) { -#ifdef BF537_FAMILY +#if defined(BF527_FAMILY) || defined(BF537_FAMILY) *port_fer[bank] = gpio_bank_saved[bank].fer; #endif gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; @@ -743,8 +746,111 @@ void bfin_pm_restore(void) AWA_DUMMY_READ(maskb); } +void bfin_gpio_pm_hibernate_suspend(void) +{ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { + bank = gpio_bank(i); + +#if defined(BF527_FAMILY) || defined(BF537_FAMILY) + gpio_bank_saved[bank].fer = *port_fer[bank]; +#ifdef BF527_FAMILY + gpio_bank_saved[bank].mux = *port_mux[bank]; +#else + if (bank == 0) + gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); +#endif +#endif + gpio_bank_saved[bank].data = gpio_bankb[bank]->data; + gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; + gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; + gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; + gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; + gpio_bank_saved[bank].both = gpio_bankb[bank]->both; + gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; + } + + AWA_DUMMY_READ(maska); +} + +void bfin_gpio_pm_hibernate_restore(void) +{ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { + bank = gpio_bank(i); + +#if defined(BF527_FAMILY) || defined(BF537_FAMILY) +#ifdef BF527_FAMILY + *port_mux[bank] = gpio_bank_saved[bank].mux; +#else + if (bank == 0) + bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); +#endif + *port_fer[bank] = gpio_bank_saved[bank].fer; +#endif + gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; + gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; + gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; + gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; + gpio_bankb[bank]->both = gpio_bank_saved[bank].both; + + gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data + | gpio_bank_saved[bank].dir; + + gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; + } + AWA_DUMMY_READ(maska); +} + + #endif #else /* BF548_FAMILY */ +#ifdef CONFIG_PM + +u32 bfin_pm_standby_setup(void) +{ + return 0; +} + +void bfin_pm_standby_restore(void) +{ + +} + +void bfin_gpio_pm_hibernate_suspend(void) +{ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { + bank = gpio_bank(i); + + gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; + gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; + gpio_bank_saved[bank].data = gpio_array[bank]->port_data; + gpio_bank_saved[bank].data = gpio_array[bank]->port_data; + gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; + gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; + } +} + +void bfin_gpio_pm_hibernate_restore(void) +{ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { + bank = gpio_bank(i); + + gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; + gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; + gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; + gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; + gpio_array[bank]->port_set = gpio_bank_saved[bank].data + | gpio_bank_saved[bank].dir; + } +} +#endif unsigned short get_gpio_dir(unsigned gpio) { diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index b7981d31c392..46ee77afed20 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S @@ -7,7 +7,7 @@ #include #include #include - +#include .section .l1.text @@ -56,26 +56,25 @@ ENTRY(_hibernate_mode) [--SP] = ( R7:0, P5:0 ); [--SP] = RETS; + R3 = R0; + R0 = IWR_DISABLE_ALL; + R1 = IWR_DISABLE_ALL; + R2 = IWR_DISABLE_ALL; call _set_sic_iwr; + call _set_dram_srfs; + SSYNC; R0 = 0xFFFF (Z); call _set_rtc_istat; P0.H = hi(VR_CTL); P0.L = lo(VR_CTL); - R1 = W[P0](z); - BITSET (R1, 8); - BITCLR (R1, 0); - BITCLR (R1, 1); - W[P0] = R1.L; - SSYNC; + W[P0] = R3.L; CLI R2; IDLE; - - /* Actually, adding anything may not be necessary...SDRAM contents - * are lost - */ +.Lforever: + jump .Lforever; ENTRY(_deep_sleep) [--SP] = ( R7:0, P5:0 ); @@ -233,51 +232,70 @@ ENTRY(_sleep_deeper) ( R7:0, P5:0 ) = [SP++]; RTS; + ENTRY(_set_dram_srfs) /* set the dram to self refresh mode */ -#if defined(CONFIG_BF54x) + SSYNC; +#if defined(EBIU_RSTCTL) /* DDR */ P0.H = hi(EBIU_RSTCTL); P0.L = lo(EBIU_RSTCTL); R2 = [P0]; - R3.H = hi(SRREQ); - R3.L = lo(SRREQ); -#else - P0.H = hi(EBIU_SDGCTL); - P0.L = lo(EBIU_SDGCTL); - R2 = [P0]; - R3.H = hi(SRFS); - R3.L = lo(SRFS); -#endif - R2 = R2|R3; + BITSET(R2, 3); /* SRREQ enter self-refresh mode */ [P0] = R2; - ssync; -#if defined(CONFIG_BF54x) -.LSRR_MODE: + SSYNC; +1: R2 = [P0]; CC = BITTST(R2, 4); - if !CC JUMP .LSRR_MODE; + if !CC JUMP 1b; +#else /* SDRAM */ + P0.L = lo(EBIU_SDGCTL); + P0.H = hi(EBIU_SDGCTL); + R2 = [P0]; + BITSET(R2, 24); /* SRFS enter self-refresh mode */ + [P0] = R2; + SSYNC; + + P0.L = lo(EBIU_SDSTAT); + P0.H = hi(EBIU_SDSTAT); +1: + R2 = w[P0]; + SSYNC; + cc = BITTST(R2, 1); /* SDSRA poll self-refresh status */ + if !cc jump 1b; + + P0.L = lo(EBIU_SDGCTL); + P0.H = hi(EBIU_SDGCTL); + R2 = [P0]; + BITCLR(R2, 0); /* SCTLE disable CLKOUT */ + [P0] = R2; #endif RTS; + ENTRY(_unset_dram_srfs) /* set the dram out of self refresh mode */ -#if defined(CONFIG_BF54x) +#if defined(EBIU_RSTCTL) /* DDR */ P0.H = hi(EBIU_RSTCTL); P0.L = lo(EBIU_RSTCTL); R2 = [P0]; - R3.H = hi(SRREQ); - R3.L = lo(SRREQ); -#else - P0.H = hi(EBIU_SDGCTL); - P0.L = lo(EBIU_SDGCTL); - R2 = [P0]; - R3.H = hi(SRFS); - R3.L = lo(SRFS); -#endif - R3 = ~R3; - R2 = R2&R3; + BITCLR(R2, 3); /* clear SRREQ bit */ [P0] = R2; - ssync; +#elif defined(EBIU_SDGCTL) /* SDRAM */ + + P0.L = lo(EBIU_SDGCTL); /* release CLKOUT from self-refresh */ + P0.H = hi(EBIU_SDGCTL); + R2 = [P0]; + BITSET(R2, 0); /* SCTLE enable CLKOUT */ + [P0] = R2 + SSYNC; + + P0.L = lo(EBIU_SDGCTL); /* release SDRAM from self-refresh */ + P0.H = hi(EBIU_SDGCTL); + R2 = [P0]; + BITCLR(R2, 24); /* clear SRFS bit */ + [P0] = R2 +#endif + SSYNC; RTS; ENTRY(_set_sic_iwr) @@ -307,6 +325,11 @@ ENTRY(_set_rtc_istat) P0.L = lo(RTC_ISTAT); w[P0] = R0.L; SSYNC; +#elif (ANOMALY_05000371) + nop; + nop; + nop; + nop; #endif RTS; @@ -318,3 +341,508 @@ ENTRY(_test_pll_locked) CC = BITTST(R0,5); IF !CC JUMP 1b; RTS; + +.section .text + + +ENTRY(_do_hibernate) + [--SP] = ( R7:0, P5:0 ); + [--SP] = RETS; + /* Save System MMRs */ + R2 = R0; + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + +#ifdef SIC_IMASK0 + PM_SYS_PUSH(SIC_IMASK0) +#endif +#ifdef SIC_IMASK1 + PM_SYS_PUSH(SIC_IMASK1) +#endif +#ifdef SIC_IMASK2 + PM_SYS_PUSH(SIC_IMASK2) +#endif +#ifdef SIC_IMASK + PM_SYS_PUSH(SIC_IMASK) +#endif +#ifdef SICA_IMASK0 + PM_SYS_PUSH(SICA_IMASK0) +#endif +#ifdef SICA_IMASK1 + PM_SYS_PUSH(SICA_IMASK1) +#endif +#ifdef SIC_IAR2 + PM_SYS_PUSH(SIC_IAR0) + PM_SYS_PUSH(SIC_IAR1) + PM_SYS_PUSH(SIC_IAR2) +#endif +#ifdef SIC_IAR3 + PM_SYS_PUSH(SIC_IAR3) +#endif +#ifdef SIC_IAR4 + PM_SYS_PUSH(SIC_IAR4) + PM_SYS_PUSH(SIC_IAR5) + PM_SYS_PUSH(SIC_IAR6) +#endif +#ifdef SIC_IAR7 + PM_SYS_PUSH(SIC_IAR7) +#endif +#ifdef SIC_IAR8 + PM_SYS_PUSH(SIC_IAR8) + PM_SYS_PUSH(SIC_IAR9) + PM_SYS_PUSH(SIC_IAR10) + PM_SYS_PUSH(SIC_IAR11) +#endif + +#ifdef SICA_IAR0 + PM_SYS_PUSH(SICA_IAR0) + PM_SYS_PUSH(SICA_IAR1) + PM_SYS_PUSH(SICA_IAR2) + PM_SYS_PUSH(SICA_IAR3) + PM_SYS_PUSH(SICA_IAR4) + PM_SYS_PUSH(SICA_IAR5) + PM_SYS_PUSH(SICA_IAR6) + PM_SYS_PUSH(SICA_IAR7) +#endif + +#ifdef SIC_IWR + PM_SYS_PUSH(SIC_IWR) +#endif +#ifdef SIC_IWR0 + PM_SYS_PUSH(SIC_IWR0) +#endif +#ifdef SIC_IWR1 + PM_SYS_PUSH(SIC_IWR1) +#endif +#ifdef SIC_IWR2 + PM_SYS_PUSH(SIC_IWR2) +#endif +#ifdef SICA_IWR0 + PM_SYS_PUSH(SICA_IWR0) +#endif +#ifdef SICA_IWR1 + PM_SYS_PUSH(SICA_IWR1) +#endif + +#ifdef PINT0_ASSIGN + PM_SYS_PUSH(PINT0_ASSIGN) + PM_SYS_PUSH(PINT1_ASSIGN) + PM_SYS_PUSH(PINT2_ASSIGN) + PM_SYS_PUSH(PINT3_ASSIGN) +#endif + + PM_SYS_PUSH(EBIU_AMBCTL0) + PM_SYS_PUSH(EBIU_AMBCTL1) + PM_SYS_PUSH16(EBIU_AMGCTL) + +#ifdef EBIU_FCTL + PM_SYS_PUSH(EBIU_MBSCTL) + PM_SYS_PUSH(EBIU_MODE) + PM_SYS_PUSH(EBIU_FCTL) +#endif + + PM_SYS_PUSH16(SYSCR) + + /* Save Core MMRs */ + P0.H = hi(SRAM_BASE_ADDRESS); + P0.L = lo(SRAM_BASE_ADDRESS); + + PM_PUSH(DMEM_CONTROL) + PM_PUSH(DCPLB_ADDR0) + PM_PUSH(DCPLB_ADDR1) + PM_PUSH(DCPLB_ADDR2) + PM_PUSH(DCPLB_ADDR3) + PM_PUSH(DCPLB_ADDR4) + PM_PUSH(DCPLB_ADDR5) + PM_PUSH(DCPLB_ADDR6) + PM_PUSH(DCPLB_ADDR7) + PM_PUSH(DCPLB_ADDR8) + PM_PUSH(DCPLB_ADDR9) + PM_PUSH(DCPLB_ADDR10) + PM_PUSH(DCPLB_ADDR11) + PM_PUSH(DCPLB_ADDR12) + PM_PUSH(DCPLB_ADDR13) + PM_PUSH(DCPLB_ADDR14) + PM_PUSH(DCPLB_ADDR15) + PM_PUSH(DCPLB_DATA0) + PM_PUSH(DCPLB_DATA1) + PM_PUSH(DCPLB_DATA2) + PM_PUSH(DCPLB_DATA3) + PM_PUSH(DCPLB_DATA4) + PM_PUSH(DCPLB_DATA5) + PM_PUSH(DCPLB_DATA6) + PM_PUSH(DCPLB_DATA7) + PM_PUSH(DCPLB_DATA8) + PM_PUSH(DCPLB_DATA9) + PM_PUSH(DCPLB_DATA10) + PM_PUSH(DCPLB_DATA11) + PM_PUSH(DCPLB_DATA12) + PM_PUSH(DCPLB_DATA13) + PM_PUSH(DCPLB_DATA14) + PM_PUSH(DCPLB_DATA15) + PM_PUSH(IMEM_CONTROL) + PM_PUSH(ICPLB_ADDR0) + PM_PUSH(ICPLB_ADDR1) + PM_PUSH(ICPLB_ADDR2) + PM_PUSH(ICPLB_ADDR3) + PM_PUSH(ICPLB_ADDR4) + PM_PUSH(ICPLB_ADDR5) + PM_PUSH(ICPLB_ADDR6) + PM_PUSH(ICPLB_ADDR7) + PM_PUSH(ICPLB_ADDR8) + PM_PUSH(ICPLB_ADDR9) + PM_PUSH(ICPLB_ADDR10) + PM_PUSH(ICPLB_ADDR11) + PM_PUSH(ICPLB_ADDR12) + PM_PUSH(ICPLB_ADDR13) + PM_PUSH(ICPLB_ADDR14) + PM_PUSH(ICPLB_ADDR15) + PM_PUSH(ICPLB_DATA0) + PM_PUSH(ICPLB_DATA1) + PM_PUSH(ICPLB_DATA2) + PM_PUSH(ICPLB_DATA3) + PM_PUSH(ICPLB_DATA4) + PM_PUSH(ICPLB_DATA5) + PM_PUSH(ICPLB_DATA6) + PM_PUSH(ICPLB_DATA7) + PM_PUSH(ICPLB_DATA8) + PM_PUSH(ICPLB_DATA9) + PM_PUSH(ICPLB_DATA10) + PM_PUSH(ICPLB_DATA11) + PM_PUSH(ICPLB_DATA12) + PM_PUSH(ICPLB_DATA13) + PM_PUSH(ICPLB_DATA14) + PM_PUSH(ICPLB_DATA15) + PM_PUSH(EVT0) + PM_PUSH(EVT1) + PM_PUSH(EVT2) + PM_PUSH(EVT3) + PM_PUSH(EVT4) + PM_PUSH(EVT5) + PM_PUSH(EVT6) + PM_PUSH(EVT7) + PM_PUSH(EVT8) + PM_PUSH(EVT9) + PM_PUSH(EVT10) + PM_PUSH(EVT11) + PM_PUSH(EVT12) + PM_PUSH(EVT13) + PM_PUSH(EVT14) + PM_PUSH(EVT15) + PM_PUSH(IMASK) + PM_PUSH(ILAT) + PM_PUSH(IPRIO) + PM_PUSH(TCNTL) + PM_PUSH(TPERIOD) + PM_PUSH(TSCALE) + PM_PUSH(TCOUNT) + PM_PUSH(TBUFCTL) + + /* Save Core Registers */ + [--sp] = SYSCFG; + [--sp] = ( R7:0, P5:0 ); + [--sp] = fp; + [--sp] = usp; + + [--sp] = i0; + [--sp] = i1; + [--sp] = i2; + [--sp] = i3; + + [--sp] = m0; + [--sp] = m1; + [--sp] = m2; + [--sp] = m3; + + [--sp] = l0; + [--sp] = l1; + [--sp] = l2; + [--sp] = l3; + + [--sp] = b0; + [--sp] = b1; + [--sp] = b2; + [--sp] = b3; + [--sp] = a0.x; + [--sp] = a0.w; + [--sp] = a1.x; + [--sp] = a1.w; + + [--sp] = LC0; + [--sp] = LC1; + [--sp] = LT0; + [--sp] = LT1; + [--sp] = LB0; + [--sp] = LB1; + + [--sp] = ASTAT; + [--sp] = CYCLES; + [--sp] = CYCLES2; + + [--sp] = RETS; + r0 = RETI; + [--sp] = r0; + [--sp] = RETX; + [--sp] = RETN; + [--sp] = RETE; + [--sp] = SEQSTAT; + + /* Save Magic, return address and Stack Pointer */ + P0.H = 0; + P0.L = 0; + R0.H = 0xDEAD; /* Hibernate Magic */ + R0.L = 0xBEEF; + [P0++] = R0; /* Store Hibernate Magic */ + R0.H = pm_resume_here; + R0.L = pm_resume_here; + [P0++] = R0; /* Save Return Address */ + [P0++] = SP; /* Save Stack Pointer */ + P0.H = _hibernate_mode; + P0.L = _hibernate_mode; + R0 = R2; + call (P0); /* Goodbye */ + +pm_resume_here: + + /* Restore Core Registers */ + SEQSTAT = [sp++]; + RETE = [sp++]; + RETN = [sp++]; + RETX = [sp++]; + r0 = [sp++]; + RETI = r0; + RETS = [sp++]; + + CYCLES2 = [sp++]; + CYCLES = [sp++]; + ASTAT = [sp++]; + + LB1 = [sp++]; + LB0 = [sp++]; + LT1 = [sp++]; + LT0 = [sp++]; + LC1 = [sp++]; + LC0 = [sp++]; + + a1.w = [sp++]; + a1.x = [sp++]; + a0.w = [sp++]; + a0.x = [sp++]; + b3 = [sp++]; + b2 = [sp++]; + b1 = [sp++]; + b0 = [sp++]; + + l3 = [sp++]; + l2 = [sp++]; + l1 = [sp++]; + l0 = [sp++]; + + m3 = [sp++]; + m2 = [sp++]; + m1 = [sp++]; + m0 = [sp++]; + + i3 = [sp++]; + i2 = [sp++]; + i1 = [sp++]; + i0 = [sp++]; + + usp = [sp++]; + fp = [sp++]; + + ( R7 : 0, P5 : 0) = [ SP ++ ]; + SYSCFG = [sp++]; + + /* Restore Core MMRs */ + + PM_POP(TBUFCTL) + PM_POP(TCOUNT) + PM_POP(TSCALE) + PM_POP(TPERIOD) + PM_POP(TCNTL) + PM_POP(IPRIO) + PM_POP(ILAT) + PM_POP(IMASK) + PM_POP(EVT15) + PM_POP(EVT14) + PM_POP(EVT13) + PM_POP(EVT12) + PM_POP(EVT11) + PM_POP(EVT10) + PM_POP(EVT9) + PM_POP(EVT8) + PM_POP(EVT7) + PM_POP(EVT6) + PM_POP(EVT5) + PM_POP(EVT4) + PM_POP(EVT3) + PM_POP(EVT2) + PM_POP(EVT1) + PM_POP(EVT0) + PM_POP(ICPLB_DATA15) + PM_POP(ICPLB_DATA14) + PM_POP(ICPLB_DATA13) + PM_POP(ICPLB_DATA12) + PM_POP(ICPLB_DATA11) + PM_POP(ICPLB_DATA10) + PM_POP(ICPLB_DATA9) + PM_POP(ICPLB_DATA8) + PM_POP(ICPLB_DATA7) + PM_POP(ICPLB_DATA6) + PM_POP(ICPLB_DATA5) + PM_POP(ICPLB_DATA4) + PM_POP(ICPLB_DATA3) + PM_POP(ICPLB_DATA2) + PM_POP(ICPLB_DATA1) + PM_POP(ICPLB_DATA0) + PM_POP(ICPLB_ADDR15) + PM_POP(ICPLB_ADDR14) + PM_POP(ICPLB_ADDR13) + PM_POP(ICPLB_ADDR12) + PM_POP(ICPLB_ADDR11) + PM_POP(ICPLB_ADDR10) + PM_POP(ICPLB_ADDR9) + PM_POP(ICPLB_ADDR8) + PM_POP(ICPLB_ADDR7) + PM_POP(ICPLB_ADDR6) + PM_POP(ICPLB_ADDR5) + PM_POP(ICPLB_ADDR4) + PM_POP(ICPLB_ADDR3) + PM_POP(ICPLB_ADDR2) + PM_POP(ICPLB_ADDR1) + PM_POP(ICPLB_ADDR0) + PM_POP(IMEM_CONTROL) + PM_POP(DCPLB_DATA15) + PM_POP(DCPLB_DATA14) + PM_POP(DCPLB_DATA13) + PM_POP(DCPLB_DATA12) + PM_POP(DCPLB_DATA11) + PM_POP(DCPLB_DATA10) + PM_POP(DCPLB_DATA9) + PM_POP(DCPLB_DATA8) + PM_POP(DCPLB_DATA7) + PM_POP(DCPLB_DATA6) + PM_POP(DCPLB_DATA5) + PM_POP(DCPLB_DATA4) + PM_POP(DCPLB_DATA3) + PM_POP(DCPLB_DATA2) + PM_POP(DCPLB_DATA1) + PM_POP(DCPLB_DATA0) + PM_POP(DCPLB_ADDR15) + PM_POP(DCPLB_ADDR14) + PM_POP(DCPLB_ADDR13) + PM_POP(DCPLB_ADDR12) + PM_POP(DCPLB_ADDR11) + PM_POP(DCPLB_ADDR10) + PM_POP(DCPLB_ADDR9) + PM_POP(DCPLB_ADDR8) + PM_POP(DCPLB_ADDR7) + PM_POP(DCPLB_ADDR6) + PM_POP(DCPLB_ADDR5) + PM_POP(DCPLB_ADDR4) + PM_POP(DCPLB_ADDR3) + PM_POP(DCPLB_ADDR2) + PM_POP(DCPLB_ADDR1) + PM_POP(DCPLB_ADDR0) + PM_POP(DMEM_CONTROL) + + /* Restore System MMRs */ + + P0.H = hi(PLL_CTL); + P0.L = lo(PLL_CTL); + PM_SYS_POP16(SYSCR) + +#ifdef EBIU_FCTL + PM_SYS_POP(EBIU_FCTL) + PM_SYS_POP(EBIU_MODE) + PM_SYS_POP(EBIU_MBSCTL) +#endif + PM_SYS_POP16(EBIU_AMGCTL) + PM_SYS_POP(EBIU_AMBCTL1) + PM_SYS_POP(EBIU_AMBCTL0) + +#ifdef PINT0_ASSIGN + PM_SYS_POP(PINT3_ASSIGN) + PM_SYS_POP(PINT2_ASSIGN) + PM_SYS_POP(PINT1_ASSIGN) + PM_SYS_POP(PINT0_ASSIGN) +#endif + +#ifdef SICA_IWR1 + PM_SYS_POP(SICA_IWR1) +#endif +#ifdef SICA_IWR0 + PM_SYS_POP(SICA_IWR0) +#endif +#ifdef SIC_IWR2 + PM_SYS_POP(SIC_IWR2) +#endif +#ifdef SIC_IWR1 + PM_SYS_POP(SIC_IWR1) +#endif +#ifdef SIC_IWR0 + PM_SYS_POP(SIC_IWR0) +#endif +#ifdef SIC_IWR + PM_SYS_POP(SIC_IWR) +#endif + +#ifdef SICA_IAR0 + PM_SYS_POP(SICA_IAR7) + PM_SYS_POP(SICA_IAR6) + PM_SYS_POP(SICA_IAR5) + PM_SYS_POP(SICA_IAR4) + PM_SYS_POP(SICA_IAR3) + PM_SYS_POP(SICA_IAR2) + PM_SYS_POP(SICA_IAR1) + PM_SYS_POP(SICA_IAR0) +#endif + +#ifdef SIC_IAR8 + PM_SYS_POP(SIC_IAR11) + PM_SYS_POP(SIC_IAR10) + PM_SYS_POP(SIC_IAR9) + PM_SYS_POP(SIC_IAR8) +#endif +#ifdef SIC_IAR7 + PM_SYS_POP(SIC_IAR7) +#endif +#ifdef SIC_IAR6 + PM_SYS_POP(SIC_IAR6) + PM_SYS_POP(SIC_IAR5) + PM_SYS_POP(SIC_IAR4) +#endif +#ifdef SIC_IAR3 + PM_SYS_POP(SIC_IAR3) +#endif +#ifdef SIC_IAR2 + PM_SYS_POP(SIC_IAR2) + PM_SYS_POP(SIC_IAR1) + PM_SYS_POP(SIC_IAR0) +#endif +#ifdef SICA_IMASK1 + PM_SYS_POP(SICA_IMASK1) +#endif +#ifdef SICA_IMASK0 + PM_SYS_POP(SICA_IMASK0) +#endif +#ifdef SIC_IMASK + PM_SYS_POP(SIC_IMASK) +#endif +#ifdef SIC_IMASK2 + PM_SYS_POP(SIC_IMASK2) +#endif +#ifdef SIC_IMASK1 + PM_SYS_POP(SIC_IMASK1) +#endif +#ifdef SIC_IMASK0 + PM_SYS_POP(SIC_IMASK0) +#endif + + [--sp] = RETI; /* Clear Global Interrupt Disable */ + SP += 4; + + RETS = [SP++]; + ( R7:0, P5:0 ) = [SP++]; + RTS; diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 0be805ca423f..4fe6a2366b13 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -38,8 +38,9 @@ #include #include -#include #include +#include +#include #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H #define WAKEUP_TYPE PM_WAKE_HIGH @@ -61,16 +62,17 @@ #define WAKEUP_TYPE PM_WAKE_BOTH_EDGES #endif + void bfin_pm_suspend_standby_enter(void) { + unsigned long flags; + #ifdef CONFIG_PM_WAKEUP_BY_GPIO gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); #endif - u32 flags; - local_irq_save(flags); - bfin_pm_setup(); + bfin_pm_standby_setup(); #ifdef CONFIG_PM_BFIN_SLEEP_DEEPER sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); @@ -78,7 +80,7 @@ void bfin_pm_suspend_standby_enter(void) sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); #endif - bfin_pm_restore(); + bfin_pm_standby_restore(); #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) bfin_write_SIC_IWR0(IWR_ENABLE_ALL); @@ -93,6 +95,195 @@ void bfin_pm_suspend_standby_enter(void) local_irq_restore(flags); } +int bf53x_suspend_l1_mem(unsigned char *memptr) +{ + dma_memcpy(memptr, (const void *) L1_CODE_START, L1_CODE_LENGTH); + dma_memcpy(memptr + L1_CODE_LENGTH, (const void *) L1_DATA_A_START, + L1_DATA_A_LENGTH); + dma_memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH, + (const void *) L1_DATA_B_START, L1_DATA_B_LENGTH); + memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH + + L1_DATA_B_LENGTH, (const void *) L1_SCRATCH_START, + L1_SCRATCH_LENGTH); + + return 0; +} + +int bf53x_resume_l1_mem(unsigned char *memptr) +{ + dma_memcpy((void *) L1_CODE_START, memptr, L1_CODE_LENGTH); + dma_memcpy((void *) L1_DATA_A_START, memptr + L1_CODE_LENGTH, + L1_DATA_A_LENGTH); + dma_memcpy((void *) L1_DATA_B_START, memptr + L1_CODE_LENGTH + + L1_DATA_A_LENGTH, L1_DATA_B_LENGTH); + memcpy((void *) L1_SCRATCH_START, memptr + L1_CODE_LENGTH + + L1_DATA_A_LENGTH + L1_DATA_B_LENGTH, L1_SCRATCH_LENGTH); + + return 0; +} + +#ifdef CONFIG_BFIN_WB +static void flushinv_all_dcache(void) +{ + u32 way, bank, subbank, set; + u32 status, addr; + u32 dmem_ctl = bfin_read_DMEM_CONTROL(); + + for (bank = 0; bank < 2; ++bank) { + if (!(dmem_ctl & (1 << (DMC1_P - bank)))) + continue; + + for (way = 0; way < 2; ++way) + for (subbank = 0; subbank < 4; ++subbank) + for (set = 0; set < 64; ++set) { + + bfin_write_DTEST_COMMAND( + way << 26 | + bank << 23 | + subbank << 16 | + set << 5 + ); + CSYNC(); + status = bfin_read_DTEST_DATA0(); + + /* only worry about valid/dirty entries */ + if ((status & 0x3) != 0x3) + continue; + + /* construct the address using the tag */ + addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); + + /* flush it */ + __asm__ __volatile__("FLUSHINV[%0];" : : "a"(addr)); + } + } +} +#endif + +static inline void dcache_disable(void) +{ +#ifdef CONFIG_BFIN_DCACHE + unsigned long ctrl; + +#ifdef CONFIG_BFIN_WB + flushinv_all_dcache(); +#endif + SSYNC(); + ctrl = bfin_read_DMEM_CONTROL(); + ctrl &= ~ENDCPLB; + bfin_write_DMEM_CONTROL(ctrl); + SSYNC(); +#endif +} + +static inline void dcache_enable(void) +{ +#ifdef CONFIG_BFIN_DCACHE + unsigned long ctrl; + SSYNC(); + ctrl = bfin_read_DMEM_CONTROL(); + ctrl |= ENDCPLB; + bfin_write_DMEM_CONTROL(ctrl); + SSYNC(); +#endif +} + +static inline void icache_disable(void) +{ +#ifdef CONFIG_BFIN_ICACHE + unsigned long ctrl; + SSYNC(); + ctrl = bfin_read_IMEM_CONTROL(); + ctrl &= ~ENICPLB; + bfin_write_IMEM_CONTROL(ctrl); + SSYNC(); +#endif +} + +static inline void icache_enable(void) +{ +#ifdef CONFIG_BFIN_ICACHE + unsigned long ctrl; + SSYNC(); + ctrl = bfin_read_IMEM_CONTROL(); + ctrl |= ENICPLB; + bfin_write_IMEM_CONTROL(ctrl); + SSYNC(); +#endif +} + +int bfin_pm_suspend_mem_enter(void) +{ + unsigned long flags; + int wakeup, ret; + + unsigned char *memptr = kmalloc(L1_CODE_LENGTH + L1_DATA_A_LENGTH + + L1_DATA_B_LENGTH + L1_SCRATCH_LENGTH, + GFP_KERNEL); + + if (memptr == NULL) { + panic("bf53x_suspend_l1_mem malloc failed"); + return -ENOMEM; + } + + wakeup = bfin_read_VR_CTL() & ~FREQ; + wakeup |= SCKELOW; + + /* FIXME: merge this somehow with set_irq_wake */ +#ifdef CONFIG_PM_BFIN_WAKE_RTC + wakeup |= WAKE; +#endif +#ifdef CONFIG_PM_BFIN_WAKE_PH6 + wakeup |= PHYWE; +#endif +#ifdef CONFIG_PM_BFIN_WAKE_CAN + wakeup |= CANWE; +#endif +#ifdef CONFIG_PM_BFIN_WAKE_GP + wakeup |= GPWE; +#endif +#ifdef CONFIG_PM_BFIN_WAKE_USB + wakeup |= USBWE; +#endif +#ifdef CONFIG_PM_BFIN_WAKE_KEYPAD + wakeup |= KPADWE; +#endif +#ifdef CONFIG_PM_BFIN_WAKE_ROTARY + wakeup |= ROTWE; +#endif + + local_irq_save(flags); + + ret = blackfin_dma_suspend(); + + if (ret) { + local_irq_restore(flags); + kfree(memptr); + return ret; + } + + bfin_gpio_pm_hibernate_suspend(); + + dcache_disable(); + icache_disable(); + bf53x_suspend_l1_mem(memptr); + + do_hibernate(wakeup); /* Goodbye */ + + bf53x_resume_l1_mem(memptr); + + icache_enable(); + dcache_enable(); + + bfin_gpio_pm_hibernate_restore(); + blackfin_dma_resume(); + + local_irq_restore(flags); + kfree(memptr); + + return 0; +} + /* * bfin_pm_valid - Tell the PM core that we only support the standby sleep * state @@ -101,7 +292,24 @@ void bfin_pm_suspend_standby_enter(void) */ static int bfin_pm_valid(suspend_state_t state) { - return (state == PM_SUSPEND_STANDBY); + return (state == PM_SUSPEND_STANDBY +#ifndef BF533_FAMILY + /* + * On BF533/2/1: + * If we enter Hibernate the SCKE Pin is driven Low, + * so that the SDRAM enters Self Refresh Mode. + * However when the reset sequence that follows hibernate + * state is executed, SCKE is driven High, taking the + * SDRAM out of Self Refresh. + * + * If you reconfigure and access the SDRAM "very quickly", + * you are likely to avoid errors, otherwise the SDRAM + * start losing its contents. + * An external HW workaround is possible using logic gates. + */ + || state == PM_SUSPEND_MEM +#endif + ); } /* @@ -115,10 +323,9 @@ static int bfin_pm_enter(suspend_state_t state) case PM_SUSPEND_STANDBY: bfin_pm_suspend_standby_enter(); break; - case PM_SUSPEND_MEM: - return -ENOTSUPP; - + bfin_pm_suspend_mem_enter(); + break; default: return -EINVAL; } diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h index c0d5259e315b..3cd4b522aa3f 100644 --- a/include/asm-blackfin/dma.h +++ b/include/asm-blackfin/dma.h @@ -144,8 +144,16 @@ struct dma_channel { void *data; unsigned int dma_enable_flag; unsigned int loopback_flag; +#ifdef CONFIG_PM + unsigned short saved_peripheral_map; +#endif }; +#ifdef CONFIG_PM +int blackfin_dma_suspend(void); +void blackfin_dma_resume(void); +#endif + /******************************************************************************* * DMA API's *******************************************************************************/ diff --git a/include/asm-blackfin/dpmc.h b/include/asm-blackfin/dpmc.h index 7f34cd384f12..de28e6e018b3 100644 --- a/include/asm-blackfin/dpmc.h +++ b/include/asm-blackfin/dpmc.h @@ -7,63 +7,18 @@ #ifndef _BLACKFIN_DPMC_H_ #define _BLACKFIN_DPMC_H_ -#define SLEEP_MODE 1 -#define DEEP_SLEEP_MODE 2 -#define ACTIVE_PLL_DISABLED 3 -#define FULLON_MODE 4 -#define ACTIVE_PLL_ENABLED 5 -#define HIBERNATE_MODE 6 - -#define IOCTL_FULL_ON_MODE _IO('s', 0xA0) -#define IOCTL_ACTIVE_MODE _IO('s', 0xA1) -#define IOCTL_SLEEP_MODE _IO('s', 0xA2) -#define IOCTL_DEEP_SLEEP_MODE _IO('s', 0xA3) -#define IOCTL_HIBERNATE_MODE _IO('s', 0xA4) -#define IOCTL_CHANGE_FREQUENCY _IOW('s', 0xA5, unsigned long) -#define IOCTL_CHANGE_VOLTAGE _IOW('s', 0xA6, unsigned long) -#define IOCTL_SET_CCLK _IOW('s', 0xA7, unsigned long) -#define IOCTL_SET_SCLK _IOW('s', 0xA8, unsigned long) -#define IOCTL_GET_PLLSTATUS _IOW('s', 0xA9, unsigned long) -#define IOCTL_GET_CORECLOCK _IOW('s', 0xAA, unsigned long) -#define IOCTL_GET_SYSTEMCLOCK _IOW('s', 0xAB, unsigned long) -#define IOCTL_GET_VCO _IOW('s', 0xAC, unsigned long) -#define IOCTL_DISABLE_WDOG_TIMER _IO('s', 0xAD) -#define IOCTL_UNMASK_WDOG_WAKEUP_EVENT _IO('s',0xAE) -#define IOCTL_PROGRAM_WDOG_TIMER _IOW('s',0xAF,unsigned long) -#define IOCTL_CLEAR_WDOG_WAKEUP_EVENT _IO('s',0xB0) -#define IOCTL_SLEEP_DEEPER_MODE _IO('s',0xB1) - -#define DPMC_MINOR 254 - -#define ON 0 -#define OFF 1 - #ifdef __KERNEL__ +#ifndef __ASSEMBLY__ -unsigned long calc_volt(void); -int calc_vlev(int vlt); -unsigned long change_voltage(unsigned long volt); -int calc_msel(int vco_hz); -unsigned long change_frequency(unsigned long vco_mhz); -int set_pll_div(unsigned short sel, unsigned char flag); -int get_vco(void); -unsigned long change_system_clock(unsigned long clock); -unsigned long change_core_clock(unsigned long clock); -unsigned long get_pll_status(void); -void change_baud(int baud); -void fullon_mode(void); -void active_mode(void); void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); void deep_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); void hibernate_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); void sleep_deeper(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); -void program_wdog_timer(unsigned long); -void unmask_wdog_wakeup_evt(void); -void clear_wdog_wakeup_evt(void); -void disable_wdog_timer(void); +void do_hibernate(int wakeup); +void set_dram_srfs(void); +void unset_dram_srfs(void); -extern unsigned long get_cclk(void); -extern unsigned long get_sclk(void); +#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16)) struct bfin_dpmc_platform_data { const unsigned int *tuple_tab; @@ -71,8 +26,33 @@ struct bfin_dpmc_platform_data { unsigned short vr_settling_time; /* in us */ }; -#define VRPAIR(vlev, freq) (((vlev) << 16) | ((freq) >> 16)) +#else +#define PM_PUSH(x) \ + R0 = [P0 + (x - SRAM_BASE_ADDRESS)];\ + [--SP] = R0;\ + +#define PM_POP(x) \ + R0 = [SP++];\ + [P0 + (x - SRAM_BASE_ADDRESS)] = R0;\ + +#define PM_SYS_PUSH(x) \ + R0 = [P0 + (x - PLL_CTL)];\ + [--SP] = R0;\ + +#define PM_SYS_POP(x) \ + R0 = [SP++];\ + [P0 + (x - PLL_CTL)] = R0;\ + +#define PM_SYS_PUSH16(x) \ + R0 = w[P0 + (x - PLL_CTL)];\ + [--SP] = R0;\ + +#define PM_SYS_POP16(x) \ + R0 = [SP++];\ + w[P0 + (x - PLL_CTL)] = R0;\ + +#endif #endif /* __KERNEL__ */ #endif /*_BLACKFIN_DPMC_H_*/ diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h index ff95e9d88342..168f1251eb4d 100644 --- a/include/asm-blackfin/gpio.h +++ b/include/asm-blackfin/gpio.h @@ -376,8 +376,12 @@ struct gpio_port_t { #endif #ifdef CONFIG_PM -unsigned int bfin_pm_setup(void); -void bfin_pm_restore(void); + +unsigned int bfin_pm_standby_setup(void); +void bfin_pm_standby_restore(void); + +void bfin_gpio_pm_hibernate_restore(void); +void bfin_gpio_pm_hibernate_suspend(void); #ifndef CONFIG_BF54x #define PM_WAKE_RISING 0x1 @@ -392,17 +396,8 @@ void gpio_pm_wakeup_free(unsigned gpio); struct gpio_port_s { unsigned short data; - unsigned short data_clear; - unsigned short data_set; - unsigned short toggle; unsigned short maska; - unsigned short maska_clear; - unsigned short maska_set; - unsigned short maska_toggle; unsigned short maskb; - unsigned short maskb_clear; - unsigned short maskb_set; - unsigned short maskb_toggle; unsigned short dir; unsigned short polar; unsigned short edge; @@ -411,10 +406,10 @@ struct gpio_port_s { unsigned short fer; unsigned short reserved; + unsigned short mux; }; #endif /*CONFIG_BF54x*/ #endif /*CONFIG_PM*/ - /*********************************************************** * * FUNCTIONS: Blackfin GPIO Driver diff --git a/include/asm-blackfin/mach-bf548/gpio.h b/include/asm-blackfin/mach-bf548/gpio.h index cb8b0f15c9a6..bba82dc75f16 100644 --- a/include/asm-blackfin/mach-bf548/gpio.h +++ b/include/asm-blackfin/mach-bf548/gpio.h @@ -209,3 +209,11 @@ struct gpio_port_t { unsigned short dummy7; unsigned int port_mux; }; + +struct gpio_port_s { + unsigned short fer; + unsigned short data; + unsigned short dir; + unsigned short inen; + unsigned int mux; +}; From 2cfebf2bceff4645b403246b608b1bb6222e4deb Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 16 Jul 2008 16:59:05 +0800 Subject: [PATCH 012/179] Blackfin arch: Add ANOMALY_05000368 workaround Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/kernel/entry.S | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S index 65f4e67a65c4..31bd9bf3efae 100644 --- a/arch/blackfin/kernel/entry.S +++ b/arch/blackfin/kernel/entry.S @@ -64,6 +64,11 @@ ENDPROC(_ret_from_fork) ENTRY(_sys_fork) r0 = -EINVAL; +#if (ANOMALY_05000371) + nop; + nop; + nop; +#endif rts; ENDPROC(_sys_fork) From 6546eae4fd90ab11ca7ab6d6b9e1b243d1ce5fe6 Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Tue, 15 Jul 2008 16:15:40 +0800 Subject: [PATCH 013/179] Blackfin arch: Allow ptrace to peek and poke application data in L1 data SRAM. Signed-off-by: Jie Zhang Signed-off-by: Bryan Wu --- arch/blackfin/kernel/ptrace.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index f51ab088098e..bf1a51d8e608 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -219,6 +219,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp)); copied = sizeof(tmp); } else +#endif +#if L1_DATA_A_LENGTH != 0 + if (addr + add >= L1_DATA_A_START + && addr + add + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { + memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); + copied = sizeof(tmp); + } else +#endif +#if L1_DATA_B_LENGTH != 0 + if (addr + add >= L1_DATA_B_START + && addr + add + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { + memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); + copied = sizeof(tmp); + } else #endif if (addr + add >= FIXED_CODE_START && addr + add + sizeof(tmp) <= FIXED_CODE_END) { @@ -289,6 +303,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data)); copied = sizeof(data); } else +#endif +#if L1_DATA_A_LENGTH != 0 + if (addr + add >= L1_DATA_A_START + && addr + add + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { + memcpy((void *)(addr + add), &data, sizeof(data)); + copied = sizeof(data); + } else +#endif +#if L1_DATA_B_LENGTH != 0 + if (addr + add >= L1_DATA_B_START + && addr + add + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { + memcpy((void *)(addr + add), &data, sizeof(data)); + copied = sizeof(data); + } else #endif if (addr + add >= FIXED_CODE_START && addr + add + sizeof(data) <= FIXED_CODE_END) { From 7dee62ac5a3e3f5aa7cc5069fa2d32cec5117229 Mon Sep 17 00:00:00 2001 From: Yi Li Date: Sat, 19 Jul 2008 20:53:46 +0800 Subject: [PATCH 014/179] Blackfin arch: Do not need this dualcore test module in kernel. Signed-off-by: Yi Li Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig.debug | 7 ---- arch/blackfin/kernel/Makefile | 1 - arch/blackfin/kernel/dualcore_test.c | 49 ---------------------------- 3 files changed, 57 deletions(-) delete mode 100644 arch/blackfin/kernel/dualcore_test.c diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index c61bdebb9974..c468624d55f0 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -154,13 +154,6 @@ config EARLY_PRINTK all of this lives in the init section and is thrown away after the kernel boots completely. -config DUAL_CORE_TEST_MODULE - tristate "Dual Core Test Module" - depends on (BF561) - default n - help - Say Y here to build-in dual core test module for dual core test. - config CPLB_INFO bool "Display the CPLB information" help diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 6140cd69c782..606adc78aa85 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -18,6 +18,5 @@ endif obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o -obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/blackfin/kernel/dualcore_test.c b/arch/blackfin/kernel/dualcore_test.c deleted file mode 100644 index 0fcba74840b7..000000000000 --- a/arch/blackfin/kernel/dualcore_test.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * File: arch/blackfin/kernel/dualcore_test.c - * Based on: - * Author: - * - * Created: - * Description: Small test code for CoreB on a BF561 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -static int *testarg = (int *)0xfeb00000; - -static int test_init(void) -{ - *testarg = 1; - printk(KERN_INFO "Dual core test module inserted: set testarg = [%d]\n @ [%p]\n", - *testarg, testarg); - return 0; -} - -static void test_exit(void) -{ - printk(KERN_INFO "Dual core test module removed: testarg = [%d]\n", *testarg); -} - -module_init(test_init); -module_exit(test_exit); From 1a8caeebe3689ad4ef67d7ff5d4143f7748deedd Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 16 Jul 2008 17:07:26 +0800 Subject: [PATCH 015/179] Blackfin arch: use local labels and ENDPROC() markings Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-common/dpmc_modes.S | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index 46ee77afed20..5e3f1d8a4fb8 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S @@ -51,6 +51,7 @@ ENTRY(_sleep_mode) RETS = [SP++]; ( R7:0, P5:0 ) = [SP++]; RTS; +ENDPROC(_sleep_mode) ENTRY(_hibernate_mode) [--SP] = ( R7:0, P5:0 ); @@ -75,6 +76,7 @@ ENTRY(_hibernate_mode) IDLE; .Lforever: jump .Lforever; +ENDPROC(_hibernate_mode) ENTRY(_deep_sleep) [--SP] = ( R7:0, P5:0 ); @@ -130,6 +132,7 @@ ENTRY(_deep_sleep) RETS = [SP++]; ( R7:0, P5:0 ) = [SP++]; RTS; +ENDPROC(_deep_sleep) ENTRY(_sleep_deeper) [--SP] = ( R7:0, P5:0 ); @@ -231,7 +234,7 @@ ENTRY(_sleep_deeper) RETS = [SP++]; ( R7:0, P5:0 ) = [SP++]; RTS; - +ENDPROC(_sleep_deeper) ENTRY(_set_dram_srfs) /* set the dram to self refresh mode */ @@ -270,7 +273,7 @@ ENTRY(_set_dram_srfs) [P0] = R2; #endif RTS; - +ENDPROC(_set_dram_srfs) ENTRY(_unset_dram_srfs) /* set the dram out of self refresh mode */ @@ -297,6 +300,7 @@ ENTRY(_unset_dram_srfs) #endif SSYNC; RTS; +ENDPROC(_unset_dram_srfs) ENTRY(_set_sic_iwr) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) @@ -318,6 +322,7 @@ ENTRY(_set_sic_iwr) SSYNC; RTS; +ENDPROC(_set_sic_iwr) ENTRY(_set_rtc_istat) #ifndef CONFIG_BF561 @@ -332,6 +337,7 @@ ENTRY(_set_rtc_istat) nop; #endif RTS; +ENDPROC(_set_rtc_istat) ENTRY(_test_pll_locked) P0.H = hi(PLL_STAT); @@ -341,10 +347,10 @@ ENTRY(_test_pll_locked) CC = BITTST(R0,5); IF !CC JUMP 1b; RTS; +ENDPROC(_test_pll_locked) .section .text - ENTRY(_do_hibernate) [--SP] = ( R7:0, P5:0 ); [--SP] = RETS; @@ -593,8 +599,8 @@ ENTRY(_do_hibernate) R0.H = 0xDEAD; /* Hibernate Magic */ R0.L = 0xBEEF; [P0++] = R0; /* Store Hibernate Magic */ - R0.H = pm_resume_here; - R0.L = pm_resume_here; + R0.H = .Lpm_resume_here; + R0.L = .Lpm_resume_here; [P0++] = R0; /* Save Return Address */ [P0++] = SP; /* Save Stack Pointer */ P0.H = _hibernate_mode; @@ -602,7 +608,7 @@ ENTRY(_do_hibernate) R0 = R2; call (P0); /* Goodbye */ -pm_resume_here: +.Lpm_resume_here: /* Restore Core Registers */ SEQSTAT = [sp++]; @@ -846,3 +852,4 @@ pm_resume_here: RETS = [SP++]; ( R7:0, P5:0 ) = [SP++]; RTS; +ENDPROC(_do_hibernate) From e59494f441c834ca7aaa0e6fa6678ddbd3d72743 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 16 Jul 2008 00:13:45 -0400 Subject: [PATCH 016/179] ftrace: fix 4d3702b6 (post-v2.6.26): WARNING: at kernel/lockdep.c:2731 check_flags (ftrace) On Wed, 16 Jul 2008, Vegard Nossum wrote: > When booting 4d3702b6, I got this huge thing: > > Testing tracer wakeup: <4>------------[ cut here ]------------ > WARNING: at kernel/lockdep.c:2731 check_flags+0x123/0x160() > Modules linked in: > Pid: 1, comm: swapper Not tainted 2.6.26-crashing-02127-g4d3702b6 #30 > [] warn_on_slowpath+0x59/0xb0 > [] ? ftrace_call+0x5/0x8 > [] ? native_read_tsc+0x0/0x20 > [] ? sub_preempt_count+0x12/0xf0 > [] ? trace_hardirqs_off+0xb/0x10 > [] ? __lock_acquire+0x2cc/0x1120 > [] ? trace_hardirqs_off+0xb/0x10 > [] ? mcount_call+0x5/0xa > [] check_flags+0x123/0x160 > [] lock_acquire+0x51/0xd0 > [] ? ftrace_call+0x5/0x8 > [] _spin_lock_irqsave+0x5f/0xa0 > [] ? ftrace_record_ip+0xf5/0x220 > [] ? debug_locks_off+0x3/0x50 > [] ftrace_record_ip+0xf5/0x220 > [] mcount_call+0x5/0xa > [] ? debug_locks_off+0x8/0x50 > [] check_flags+0xf7/0x160 > [] lock_acquire+0x51/0xd0 > [] ? ftrace_call+0x5/0x8 > [] _spin_lock_irqsave+0x5f/0xa0 > [] ? wakeup_tracer_call+0x6d/0xf0 > [] ? _local_bh_enable+0x62/0xb0 > [] ? sub_preempt_count+0xd/0xf0 > [] wakeup_tracer_call+0x6d/0xf0 > [] ? __do_softirq+0xf4/0x110 > [] ? wakeup_tracer_call+0x91/0xf0 > [] ftrace_call+0x5/0x8 > [] ? __do_softirq+0xf4/0x110 > [] ? sub_preempt_count+0x12/0xf0 > [] _local_bh_enable+0x62/0xb0 > [] __do_softirq+0xf4/0x110 > [] do_softirq+0xad/0xb0 > [] irq_exit+0xa5/0xb0 > [] smp_apic_timer_interrupt+0x66/0xa0 > [] ? trace_hardirqs_off_thunk+0xc/0x10 > [] apic_timer_interrupt+0x2d/0x34 > [] ? find_usage_backwards+0xb/0xf0 > [] ? _spin_unlock_irqrestore+0x69/0x80 > [] tg_shares_up+0x132/0x1d0 > [] walk_tg_tree+0x62/0xa0 > [] ? tg_shares_up+0x0/0x1d0 > [] ? tg_nop+0x0/0x10 > [] update_shares+0x5d/0x80 > [] try_to_wake_up+0x6f/0x280 > [] ? __ftrace_modify_code+0x0/0xc0 > [] ? __ftrace_modify_code+0x0/0xc0 > [] wake_up_process+0x14/0x20 > [] kthread_create+0x66/0xb0 > [] ? do_stop+0x0/0x200 > [] ? __stop_machine_run+0x30/0xb0 > [] __stop_machine_run+0x50/0xb0 > [] ? do_stop+0x0/0x200 > [] ? __ftrace_modify_code+0x0/0xc0 > [] ? mutex_unlock+0xd/0x10 > [] stop_machine_run+0x2c/0x60 > [] unregister_ftrace_function+0x103/0x180 > [] stop_wakeup_tracer+0x17/0x60 > [] wakeup_tracer_ctrl_update+0xf/0x30 > [] trace_selftest_startup_wakeup+0xb5/0x130 > [] ? trace_wakeup_test_thread+0x0/0x70 > [] register_tracer+0x135/0x1b0 > [] init_wakeup_tracer+0xd/0xf > [] kernel_init+0x1a9/0x2ce > [] ? _spin_unlock_irq+0x3b/0x60 > [] ? trace_hardirqs_on_thunk+0xc/0x10 > [] ? init_wakeup_tracer+0x0/0xf > [] ? trace_hardirqs_on_caller+0x126/0x180 > [] ? trace_hardirqs_on_thunk+0xc/0x10 > [] ? restore_nocheck_notrace+0x0/0xe > [] ? kernel_init+0x0/0x2ce > [] ? kernel_init+0x0/0x2ce > [] kernel_thread_helper+0x7/0x10 > ======================= > ---[ end trace a7919e7f17c0a725 ]--- > irq event stamp: 579530 > hardirqs last enabled at (579528): [] trace_hardirqs_on+0xb/0x10 > hardirqs last disabled at (579529): [] trace_hardirqs_off+0xb/0x10 > softirqs last enabled at (579530): [] __do_softirq+0xf4/0x110 > softirqs last disabled at (579517): [] do_softirq+0xad/0xb0 > irq event stamp: 579530 > hardirqs last enabled at (579528): [] trace_hardirqs_on+0xb/0x10 > hardirqs last disabled at (579529): [] trace_hardirqs_off+0xb/0x10 > softirqs last enabled at (579530): [] __do_softirq+0xf4/0x110 > softirqs last disabled at (579517): [] do_softirq+0xad/0xb0 > PASSED > > Incidentally, the kernel also hung while I was typing in this report. Things get weird between lockdep and ftrace because ftrace can be called within lockdep internal code (via the mcount pointer) and lockdep can be called with ftrace (via spin_locks). Signed-off-by: Steven Rostedt Tested-by: Vegard Nossum Signed-off-by: Ingo Molnar --- kernel/trace/trace_sched_wakeup.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 3c8d61df4474..e303ccb62cdf 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -26,7 +26,8 @@ static struct task_struct *wakeup_task; static int wakeup_cpu; static unsigned wakeup_prio = -1; -static DEFINE_SPINLOCK(wakeup_lock); +static raw_spinlock_t wakeup_lock = + (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; static void __wakeup_reset(struct trace_array *tr); @@ -56,7 +57,8 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) if (unlikely(disabled != 1)) goto out; - spin_lock_irqsave(&wakeup_lock, flags); + local_irq_save(flags); + __raw_spin_lock(&wakeup_lock); if (unlikely(!wakeup_task)) goto unlock; @@ -71,7 +73,8 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) trace_function(tr, data, ip, parent_ip, flags); unlock: - spin_unlock_irqrestore(&wakeup_lock, flags); + __raw_spin_unlock(&wakeup_lock); + local_irq_restore(flags); out: atomic_dec(&data->disabled); @@ -145,7 +148,8 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev, if (likely(disabled != 1)) goto out; - spin_lock_irqsave(&wakeup_lock, flags); + local_irq_save(flags); + __raw_spin_lock(&wakeup_lock); /* We could race with grabbing wakeup_lock */ if (unlikely(!tracer_enabled || next != wakeup_task)) @@ -174,7 +178,8 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev, out_unlock: __wakeup_reset(tr); - spin_unlock_irqrestore(&wakeup_lock, flags); + __raw_spin_unlock(&wakeup_lock); + local_irq_restore(flags); out: atomic_dec(&tr->data[cpu]->disabled); } @@ -209,8 +214,6 @@ static void __wakeup_reset(struct trace_array *tr) struct trace_array_cpu *data; int cpu; - assert_spin_locked(&wakeup_lock); - for_each_possible_cpu(cpu) { data = tr->data[cpu]; tracing_reset(data); @@ -229,9 +232,11 @@ static void wakeup_reset(struct trace_array *tr) { unsigned long flags; - spin_lock_irqsave(&wakeup_lock, flags); + local_irq_save(flags); + __raw_spin_lock(&wakeup_lock); __wakeup_reset(tr); - spin_unlock_irqrestore(&wakeup_lock, flags); + __raw_spin_unlock(&wakeup_lock); + local_irq_restore(flags); } static void @@ -252,7 +257,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p, goto out; /* interrupts should be off from try_to_wake_up */ - spin_lock(&wakeup_lock); + __raw_spin_lock(&wakeup_lock); /* check for races. */ if (!tracer_enabled || p->prio >= wakeup_prio) @@ -274,7 +279,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p, CALLER_ADDR1, CALLER_ADDR2, flags); out_locked: - spin_unlock(&wakeup_lock); + __raw_spin_unlock(&wakeup_lock); out: atomic_dec(&tr->data[cpu]->disabled); } From 1e01cb0c6ff7e9ddb6547551794c6aa82785a7cb Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 15 Jul 2008 09:53:37 -0400 Subject: [PATCH 017/179] ftrace: only trace preempt off with preempt tracer When PREEMPT_TRACER and IRQSOFF_TRACER are both configured and irqsoff tracer is running, the preempt_off sections might also be traced. Thanks to Andrew Morton for pointing out my mistake of spin_lock disabling interrupts while he was reviewing ftrace.txt. Seems that my example I used actually hit this bug. Signed-off-by: Steven Rostedt Cc: Linus Torvalds Cc: Andrew Morton Cc: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/trace/trace_irqsoff.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 421d6fe3650e..b1e4a89b08eb 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -337,12 +337,14 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller); #ifdef CONFIG_PREEMPT_TRACER void trace_preempt_on(unsigned long a0, unsigned long a1) { - stop_critical_timing(a0, a1); + if (preempt_trace()) + stop_critical_timing(a0, a1); } void trace_preempt_off(unsigned long a0, unsigned long a1) { - start_critical_timing(a0, a1); + if (preempt_trace()) + start_critical_timing(a0, a1); } #endif /* CONFIG_PREEMPT_TRACER */ From 5d481f497559245ecfb1b95cafe39bfbf037fda5 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 19 Jul 2008 14:51:31 +0800 Subject: [PATCH 018/179] Blackfin arch: change L1 malloc to base on slab cache and lists. Remove the sram piece limitation and improve the performance to alloc/free sram piece data. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/mm/blackfin_sram.c | 405 ++++++++++++++++++------------- arch/blackfin/mm/blackfin_sram.h | 4 +- arch/blackfin/mm/init.c | 12 +- 3 files changed, 253 insertions(+), 168 deletions(-) diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c index 8f6fdc245330..b58cf196d7cc 100644 --- a/arch/blackfin/mm/blackfin_sram.c +++ b/arch/blackfin/mm/blackfin_sram.c @@ -41,215 +41,276 @@ #include #include "blackfin_sram.h" -spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; - -#if CONFIG_L1_MAX_PIECE < 16 -#undef CONFIG_L1_MAX_PIECE -#define CONFIG_L1_MAX_PIECE 16 -#endif - -#if CONFIG_L1_MAX_PIECE > 1024 -#undef CONFIG_L1_MAX_PIECE -#define CONFIG_L1_MAX_PIECE 1024 -#endif - -#define SRAM_SLT_NULL 0 -#define SRAM_SLT_FREE 1 -#define SRAM_SLT_ALLOCATED 2 +static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; /* the data structure for L1 scratchpad and DATA SRAM */ -struct l1_sram_piece { +struct sram_piece { void *paddr; int size; - int flag; pid_t pid; + struct sram_piece *next; }; -static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_ssram_head, used_l1_ssram_head; #if L1_DATA_A_LENGTH != 0 -static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_data_A_sram_head, used_l1_data_A_sram_head; #endif #if L1_DATA_B_LENGTH != 0 -static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head; #endif #if L1_CODE_LENGTH != 0 -static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE]; +static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head; #endif -/* L1 Scratchpad SRAM initialization function */ -void __init l1sram_init(void) -{ - printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", - L1_SCRATCH_LENGTH >> 10); +static struct kmem_cache *sram_piece_cache; - memset(&l1_ssram, 0x00, sizeof(l1_ssram)); - l1_ssram[0].paddr = (void *)L1_SCRATCH_START; - l1_ssram[0].size = L1_SCRATCH_LENGTH; - l1_ssram[0].flag = SRAM_SLT_FREE; +/* L1 Scratchpad SRAM initialization function */ +static void __init l1sram_init(void) +{ + free_l1_ssram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_ssram_head.next) { + printk(KERN_INFO"Fail to initialize Scratchpad data SRAM.\n"); + return; + } + + free_l1_ssram_head.next->paddr = (void *)L1_SCRATCH_START; + free_l1_ssram_head.next->size = L1_SCRATCH_LENGTH; + free_l1_ssram_head.next->pid = 0; + free_l1_ssram_head.next->next = NULL; + + used_l1_ssram_head.next = NULL; /* mutex initialize */ spin_lock_init(&l1sram_lock); + + printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", + L1_SCRATCH_LENGTH >> 10); } -void __init l1_data_sram_init(void) +static void __init l1_data_sram_init(void) { #if L1_DATA_A_LENGTH != 0 - memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram)); - l1_data_A_sram[0].paddr = (void *)L1_DATA_A_START + - (_ebss_l1 - _sdata_l1); - l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); - l1_data_A_sram[0].flag = SRAM_SLT_FREE; + free_l1_data_A_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_data_A_sram_head.next) { + printk(KERN_INFO"Fail to initialize Data A SRAM.\n"); + return; + } + + free_l1_data_A_sram_head.next->paddr = + (void *)L1_DATA_A_START + (_ebss_l1 - _sdata_l1); + free_l1_data_A_sram_head.next->size = + L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); + free_l1_data_A_sram_head.next->pid = 0; + free_l1_data_A_sram_head.next->next = NULL; + + used_l1_data_A_sram_head.next = NULL; printk(KERN_INFO "Blackfin Data A SRAM: %d KB (%d KB free)\n", - L1_DATA_A_LENGTH >> 10, l1_data_A_sram[0].size >> 10); + L1_DATA_A_LENGTH >> 10, + free_l1_data_A_sram_head.next->size >> 10); #endif #if L1_DATA_B_LENGTH != 0 - memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram)); - l1_data_B_sram[0].paddr = (void *)L1_DATA_B_START + - (_ebss_b_l1 - _sdata_b_l1); - l1_data_B_sram[0].size = L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); - l1_data_B_sram[0].flag = SRAM_SLT_FREE; + free_l1_data_B_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_data_B_sram_head.next) { + printk(KERN_INFO"Fail to initialize Data B SRAM.\n"); + return; + } + + free_l1_data_B_sram_head.next->paddr = + (void *)L1_DATA_B_START + (_ebss_b_l1 - _sdata_b_l1); + free_l1_data_B_sram_head.next->size = + L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); + free_l1_data_B_sram_head.next->pid = 0; + free_l1_data_B_sram_head.next->next = NULL; + + used_l1_data_B_sram_head.next = NULL; printk(KERN_INFO "Blackfin Data B SRAM: %d KB (%d KB free)\n", - L1_DATA_B_LENGTH >> 10, l1_data_B_sram[0].size >> 10); + L1_DATA_B_LENGTH >> 10, + free_l1_data_B_sram_head.next->size >> 10); #endif /* mutex initialize */ spin_lock_init(&l1_data_sram_lock); } -void __init l1_inst_sram_init(void) +static void __init l1_inst_sram_init(void) { #if L1_CODE_LENGTH != 0 - memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram)); - l1_inst_sram[0].paddr = (void *)L1_CODE_START + (_etext_l1 - _stext_l1); - l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1); - l1_inst_sram[0].flag = SRAM_SLT_FREE; + free_l1_inst_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l1_inst_sram_head.next) { + printk(KERN_INFO"Fail to initialize Instruction SRAM.\n"); + return; + } + + free_l1_inst_sram_head.next->paddr = + (void *)L1_CODE_START + (_etext_l1 - _stext_l1); + free_l1_inst_sram_head.next->size = + L1_CODE_LENGTH - (_etext_l1 - _stext_l1); + free_l1_inst_sram_head.next->pid = 0; + free_l1_inst_sram_head.next->next = NULL; + + used_l1_inst_sram_head.next = NULL; printk(KERN_INFO "Blackfin Instruction SRAM: %d KB (%d KB free)\n", - L1_CODE_LENGTH >> 10, l1_inst_sram[0].size >> 10); + L1_CODE_LENGTH >> 10, + free_l1_inst_sram_head.next->size >> 10); #endif /* mutex initialize */ spin_lock_init(&l1_inst_sram_lock); } -/* L1 memory allocate function */ -static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count) +void __init bfin_sram_init(void) { - int i, index = 0; - void *addr = NULL; + sram_piece_cache = kmem_cache_create("sram_piece_cache", + sizeof(struct sram_piece), + 0, SLAB_PANIC, NULL); - if (size <= 0) + l1sram_init(); + l1_data_sram_init(); + l1_inst_sram_init(); +} + +/* L1 memory allocate function */ +static void *_l1_sram_alloc(size_t size, struct sram_piece *pfree_head, + struct sram_piece *pused_head) +{ + struct sram_piece *pslot, *plast, *pavail; + + if (size <= 0 || !pfree_head || !pused_head) return NULL; /* Align the size */ size = (size + 3) & ~3; - /* not use the good method to match the best slot !!! */ - /* search an available memory slot */ - for (i = 0; i < count; i++) { - if ((pfree[i].flag == SRAM_SLT_FREE) - && (pfree[i].size >= size)) { - addr = pfree[i].paddr; - pfree[i].flag = SRAM_SLT_ALLOCATED; - pfree[i].pid = current->pid; - index = i; - break; - } + pslot = pfree_head->next; + plast = pfree_head; + + /* search an available piece slot */ + while (pslot != NULL && size > pslot->size) { + plast = pslot; + pslot = pslot->next; } - if (i >= count) + + if (!pslot) return NULL; - /* updated the NULL memory slot !!! */ - if (pfree[i].size > size) { - for (i = 0; i < count; i++) { - if (pfree[i].flag == SRAM_SLT_NULL) { - pfree[i].pid = 0; - pfree[i].flag = SRAM_SLT_FREE; - pfree[i].paddr = addr + size; - pfree[i].size = pfree[index].size - size; - pfree[index].size = size; - break; - } - } + if (pslot->size == size) { + plast->next = pslot->next; + pavail = pslot; + } else { + pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + + if (!pavail) + return NULL; + + pavail->paddr = pslot->paddr; + pavail->size = size; + pslot->paddr += size; + pslot->size -= size; } - return addr; + pavail->pid = current->pid; + + pslot = pused_head->next; + plast = pused_head; + + /* insert new piece into used piece list !!! */ + while (pslot != NULL && pavail->paddr < pslot->paddr) { + plast = pslot; + pslot = pslot->next; + } + + pavail->next = pslot; + plast->next = pavail; + + return pavail->paddr; } /* Allocate the largest available block. */ -static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count, +static void *_l1_sram_alloc_max(struct sram_piece *pfree_head, + struct sram_piece *pused_head, unsigned long *psize) { - unsigned long best = 0; - int i, index = -1; - void *addr = NULL; + struct sram_piece *pslot, *pmax; - /* search an available memory slot */ - for (i = 0; i < count; i++) { - if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) { - addr = pfree[i].paddr; - index = i; - best = pfree[i].size; - } - } - if (index < 0) + if (!pfree_head || !pused_head) return NULL; - *psize = best; - pfree[index].pid = current->pid; - pfree[index].flag = SRAM_SLT_ALLOCATED; - return addr; + pmax = pslot = pfree_head->next; + + /* search an available piece slot */ + while (pslot != NULL) { + if (pslot->size > pmax->size) + pmax = pslot; + pslot = pslot->next; + } + + if (!pmax) + return NULL; + + *psize = pmax->size; + + return _l1_sram_alloc(*psize, pfree_head, pused_head); } /* L1 memory free function */ static int _l1_sram_free(const void *addr, - struct l1_sram_piece *pfree, - int count) + struct sram_piece *pfree_head, + struct sram_piece *pused_head) { - int i, index = 0; + struct sram_piece *pslot, *plast, *pavail; - /* search the relevant memory slot */ - for (i = 0; i < count; i++) { - if (pfree[i].paddr == addr) { - if (pfree[i].flag != SRAM_SLT_ALLOCATED) { - /* error log */ - return -1; - } - index = i; - break; - } - } - if (i >= count) + if (!pfree_head || !pused_head) return -1; - pfree[index].pid = 0; - pfree[index].flag = SRAM_SLT_FREE; + /* search the relevant memory slot */ + pslot = pused_head->next; + plast = pused_head; - /* link the next address slot */ - for (i = 0; i < count; i++) { - if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr) - && (pfree[i].flag == SRAM_SLT_FREE)) { - pfree[i].pid = 0; - pfree[i].flag = SRAM_SLT_NULL; - pfree[index].size += pfree[i].size; - pfree[index].flag = SRAM_SLT_FREE; - break; - } + /* search an available piece slot */ + while (pslot != NULL && pslot->paddr != addr) { + plast = pslot; + pslot = pslot->next; } - /* link the last address slot */ - for (i = 0; i < count; i++) { - if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) && - (pfree[i].flag == SRAM_SLT_FREE)) { - pfree[index].flag = SRAM_SLT_NULL; - pfree[i].size += pfree[index].size; - break; - } + if (!pslot) + return -1; + + plast->next = pslot->next; + pavail = pslot; + pavail->pid = 0; + + /* insert free pieces back to the free list */ + pslot = pfree_head->next; + plast = pfree_head; + + while (pslot != NULL && addr > pslot->paddr) { + plast = pslot; + pslot = pslot->next; + } + + if (plast != pfree_head && plast->paddr + plast->size == pavail->paddr) { + plast->size += pavail->size; + kmem_cache_free(sram_piece_cache, pavail); + } else { + pavail->next = plast; + plast->next = pavail; + plast = pavail; + } + + if (pslot && plast->paddr + plast->size == pslot->paddr) { + plast->size += pslot->size; + plast->next = pslot->next; + kmem_cache_free(sram_piece_cache, pslot); } return 0; @@ -287,7 +348,8 @@ void *l1_data_A_sram_alloc(size_t size) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); + addr = _l1_sram_alloc(size, &free_l1_data_A_sram_head, + &used_l1_data_A_sram_head); #endif /* add mutex operation */ @@ -309,8 +371,8 @@ int l1_data_A_sram_free(const void *addr) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - ret = _l1_sram_free(addr, - l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); + ret = _l1_sram_free(addr, &free_l1_data_A_sram_head, + &used_l1_data_A_sram_head); #else ret = -1; #endif @@ -331,7 +393,8 @@ void *l1_data_B_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + addr = _l1_sram_alloc(size, &free_l1_data_B_sram_head, + &used_l1_data_B_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_data_sram_lock, flags); @@ -355,7 +418,8 @@ int l1_data_B_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); + ret = _l1_sram_free(addr, &free_l1_data_B_sram_head, + &used_l1_data_B_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_data_sram_lock, flags); @@ -408,7 +472,8 @@ void *l1_inst_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + addr = _l1_sram_alloc(size, &free_l1_inst_sram_head, + &used_l1_inst_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_inst_sram_lock, flags); @@ -432,7 +497,8 @@ int l1_inst_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); + ret = _l1_sram_free(addr, &free_l1_inst_sram_head, + &used_l1_inst_sram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1_inst_sram_lock, flags); @@ -453,7 +519,8 @@ void *l1sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram)); + addr = _l1_sram_alloc(size, &free_l1_ssram_head, + &used_l1_ssram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -470,7 +537,8 @@ void *l1sram_alloc_max(size_t *psize) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize); + addr = _l1_sram_alloc_max(&free_l1_ssram_head, + &used_l1_ssram_head, psize); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -487,7 +555,8 @@ int l1sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram)); + ret = _l1_sram_free(addr, &free_l1_ssram_head, + &used_l1_ssram_head); /* add mutex operation */ spin_unlock_irqrestore(&l1sram_lock, flags); @@ -553,28 +622,38 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); * (including newline). */ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, - struct l1_sram_piece *pfree, const int array_size) + struct sram_piece *pfree_head, + struct sram_piece *pused_head) { - int i; + struct sram_piece *pslot; + + if (!pfree_head || !pused_head) + return -1; *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State \n", desc); - for (i = 0; i < array_size && *len < count; ++i) { - const char *alloc_type; - switch (pfree[i].flag) { - case SRAM_SLT_NULL: alloc_type = "NULL"; break; - case SRAM_SLT_FREE: alloc_type = "FREE"; break; - case SRAM_SLT_ALLOCATED: alloc_type = "ALLOCATED"; break; - default: alloc_type = "????"; break; - } - /* if we've got a lot of space to cover, omit things */ - if ((PAGE_SIZE - 1024) < (CONFIG_L1_MAX_PIECE + 1) * 4 * 44 && - pfree[i].size == 0) - continue; + + /* search the relevant memory slot */ + pslot = pused_head->next; + + while (pslot != NULL) { *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", - pfree[i].paddr, pfree[i].paddr + pfree[i].size, - pfree[i].size, pfree[i].pid, alloc_type); + pslot->paddr, pslot->paddr + pslot->size, + pslot->size, pslot->pid, "ALLOCATED"); + + pslot = pslot->next; } - return (i != array_size); + + pslot = pfree_head->next; + + while (pslot != NULL) { + *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", + pslot->paddr, pslot->paddr + pslot->size, + pslot->size, pslot->pid, "FREE"); + + pslot = pslot->next; + } + + return 0; } static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) @@ -582,21 +661,23 @@ static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, int len = 0; if (_l1sram_proc_read(buf, &len, count, "Scratchpad", - l1_ssram, ARRAY_SIZE(l1_ssram))) + &free_l1_ssram_head, &used_l1_ssram_head)) goto not_done; #if L1_DATA_A_LENGTH != 0 if (_l1sram_proc_read(buf, &len, count, "Data A", - l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram))) + &free_l1_data_A_sram_head, + &used_l1_data_A_sram_head)) goto not_done; #endif #if L1_DATA_B_LENGTH != 0 if (_l1sram_proc_read(buf, &len, count, "Data B", - l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram))) + &free_l1_data_B_sram_head, + &used_l1_data_B_sram_head)) goto not_done; #endif #if L1_CODE_LENGTH != 0 if (_l1sram_proc_read(buf, &len, count, "Instruction", - l1_inst_sram, ARRAY_SIZE(l1_inst_sram))) + &free_l1_inst_sram_head, &used_l1_inst_sram_head)) goto not_done; #endif diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h index 0fb73b78dd60..8cb0945563f9 100644 --- a/arch/blackfin/mm/blackfin_sram.h +++ b/arch/blackfin/mm/blackfin_sram.h @@ -30,9 +30,7 @@ #ifndef __BLACKFIN_SRAM_H__ #define __BLACKFIN_SRAM_H__ -extern void l1sram_init(void); -extern void l1_inst_sram_init(void); -extern void l1_data_sram_init(void); +extern void bfin_sram_init(void); extern void *l1sram_alloc(size_t); #endif diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index ec3141fefd20..4aab21f44096 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -164,11 +164,14 @@ void __init mem_init(void) "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n", (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); +} + +static int __init sram_init(void) +{ + unsigned long tmp; /* Initialize the blackfin L1 Memory. */ - l1sram_init(); - l1_data_sram_init(); - l1_inst_sram_init(); + bfin_sram_init(); /* Allocate this once; never free it. We assume this gives us a pointer to the start of L1 scratchpad memory; panic if it @@ -179,7 +182,10 @@ void __init mem_init(void) tmp, (unsigned long)L1_SCRATCH_TASK_INFO); panic("No L1, time to give up\n"); } + + return 0; } +pure_initcall(sram_init); static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) { From bafcc1b97323261a42d47960db99947bcc1be133 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 19 Jul 2008 15:11:15 +0800 Subject: [PATCH 019/179] Blackfin arch: Remove useless config option. Signed-off-by: Robin Getz Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 8f21b78b2e6f..5a08194e4118 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -729,14 +729,6 @@ config BFIN_WT endchoice -config L1_MAX_PIECE - int "Set the max L1 SRAM pieces" - default 16 - help - Set the max memory pieces for the L1 SRAM allocation algorithm. - Min value is 16. Max value is 1024. - - config MPU bool "Enable the memory protection unit (EXPERIMENTAL)" default n From 262c3825a9f3eb0f4f30ebb4b1ee57397bcb3ffc Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 19 Jul 2008 15:42:41 +0800 Subject: [PATCH 020/179] Blackfin arch: Extend sram malloc to handle L2 SRAM. Extend system call to alloc L2 SRAM in application. Automatically move following sections to L2 SRAM: 1. kernel built-in l2 attribute section 2. kernel module l2 attribute section 3. elf-fdpic application l2 attribute section Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/kernel/module.c | 74 ++++++++++--- arch/blackfin/kernel/setup.c | 10 ++ arch/blackfin/kernel/vmlinux.lds.S | 40 ++++++- arch/blackfin/mm/blackfin_sram.c | 170 +++++++++++++++++++++++------ include/asm-blackfin/bfin-global.h | 8 +- include/asm-blackfin/elf.h | 2 + include/asm-blackfin/module.h | 5 +- 7 files changed, 253 insertions(+), 56 deletions(-) diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 14a42848f37f..e1bebc80a5bf 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -173,7 +173,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, for (s = sechdrs; s < sechdrs_end; ++s) { if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || ((strcmp(".text", secstrings + s->sh_name) == 0) && - (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) { dest = l1_inst_sram_alloc(s->sh_size); mod->arch.text_l1 = dest; if (dest == NULL) { @@ -188,7 +188,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, } if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || ((strcmp(".data", secstrings + s->sh_name) == 0) && - (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { dest = l1_data_sram_alloc(s->sh_size); mod->arch.data_a_l1 = dest; if (dest == NULL) { @@ -203,7 +203,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, } if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || ((strcmp(".bss", secstrings + s->sh_name) == 0) && - (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { + (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { dest = l1_data_sram_alloc(s->sh_size); mod->arch.bss_a_l1 = dest; if (dest == NULL) { @@ -242,6 +242,51 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, s->sh_flags &= ~SHF_ALLOC; s->sh_addr = (unsigned long)dest; } + if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) || + ((strcmp(".text", secstrings + s->sh_name) == 0) && + (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) { + dest = l2_sram_alloc(s->sh_size); + mod->arch.text_l2 = dest; + if (dest == NULL) { + printk(KERN_ERR + "module %s: L2 SRAM allocation failed\n", + mod->name); + return -1; + } + memcpy(dest, (void *)s->sh_addr, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) || + ((strcmp(".data", secstrings + s->sh_name) == 0) && + (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { + dest = l2_sram_alloc(s->sh_size); + mod->arch.data_l2 = dest; + if (dest == NULL) { + printk(KERN_ERR + "module %s: L2 SRAM allocation failed\n", + mod->name); + return -1; + } + memcpy(dest, (void *)s->sh_addr, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } + if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 || + ((strcmp(".bss", secstrings + s->sh_name) == 0) && + (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { + dest = l2_sram_alloc(s->sh_size); + mod->arch.bss_l2 = dest; + if (dest == NULL) { + printk(KERN_ERR + "module %s: L2 SRAM allocation failed\n", + mod->name); + return -1; + } + memset(dest, 0, s->sh_size); + s->sh_flags &= ~SHF_ALLOC; + s->sh_addr = (unsigned long)dest; + } } return 0; } @@ -411,9 +456,10 @@ module_finalize(const Elf_Ehdr * hdr, continue; if ((sechdrs[i].sh_type == SHT_RELA) && - ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || + ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) || + (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && - (hdr->e_flags & FLG_CODE_IN_L1)))) { + (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) { apply_relocate_add((Elf_Shdr *) sechdrs, strtab, symindex, i, mod); } @@ -423,14 +469,12 @@ module_finalize(const Elf_Ehdr * hdr, void module_arch_cleanup(struct module *mod) { - if (mod->arch.text_l1) - l1_inst_sram_free((void *)mod->arch.text_l1); - if (mod->arch.data_a_l1) - l1_data_sram_free((void *)mod->arch.data_a_l1); - if (mod->arch.bss_a_l1) - l1_data_sram_free((void *)mod->arch.bss_a_l1); - if (mod->arch.data_b_l1) - l1_data_B_sram_free((void *)mod->arch.data_b_l1); - if (mod->arch.bss_b_l1) - l1_data_B_sram_free((void *)mod->arch.bss_b_l1); + l1_inst_sram_free(mod->arch.text_l1); + l1_data_A_sram_free(mod->arch.data_a_l1); + l1_data_A_sram_free(mod->arch.bss_a_l1); + l1_data_B_sram_free(mod->arch.data_b_l1); + l1_data_B_sram_free(mod->arch.bss_b_l1); + l2_sram_free(mod->arch.text_l2); + l2_sram_free(mod->arch.data_l2); + l2_sram_free(mod->arch.bss_l2); } diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 861a1db74df8..8671d1db1f99 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -104,6 +104,7 @@ void __init bf53x_relocate_l1_mem(void) unsigned long l1_code_length; unsigned long l1_data_a_length; unsigned long l1_data_b_length; + unsigned long l2_length; l1_code_length = _etext_l1 - _stext_l1; if (l1_code_length > L1_CODE_LENGTH) @@ -129,6 +130,15 @@ void __init bf53x_relocate_l1_mem(void) /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + l1_data_a_length, l1_data_b_length); + +#ifdef L2_LENGTH + l2_length = _ebss_l2 - _stext_l2; + if (l2_length > L2_LENGTH) + panic("L2 SRAM Overflow\n"); + + /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ + dma_memcpy(_stext_l2, _l2_lma_start, l2_length); +#endif } /* add_memory_region to memmap */ diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 3ecc64cab3be..0896e38d6108 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -101,6 +101,11 @@ SECTIONS #if !L1_DATA_B_LENGTH *(.l1.data.B) #endif +#ifndef L2_LENGTH + . = ALIGN(32); + *(.data_l2.cacheline_aligned) + *(.l2.data) +#endif DATA_DATA *(.data.*) @@ -182,13 +187,12 @@ SECTIONS *(.l1.data) __edata_l1 = .; - . = ALIGN(4); - __sbss_l1 = .; - *(.l1.bss) - . = ALIGN(32); *(.data_l1.cacheline_aligned) + . = ALIGN(4); + __sbss_l1 = .; + *(.l1.bss) . = ALIGN(4); __ebss_l1 = .; } @@ -203,11 +207,37 @@ SECTIONS . = ALIGN(4); __sbss_b_l1 = .; *(.l1.bss.B) - . = ALIGN(4); __ebss_b_l1 = .; } +#ifdef L2_LENGTH + __l2_lma_start = .; + + .text_data_l2 L2_START : AT(LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1)) + { + . = ALIGN(4); + __stext_l2 = .; + *(.l1.text) + . = ALIGN(4); + __etext_l2 = .; + + . = ALIGN(4); + __sdata_l2 = .; + *(.l1.data) + __edata_l2 = .; + + . = ALIGN(32); + *(.data_l2.cacheline_aligned) + + . = ALIGN(4); + __sbss_l2 = .; + *(.l1.bss) + . = ALIGN(4); + __ebss_l2 = .; + } +#endif + /* Force trailing alignment of our init section so that when we * free our init memory, we don't leave behind a partial page. */ diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c index b58cf196d7cc..5af3c31c9365 100644 --- a/arch/blackfin/mm/blackfin_sram.c +++ b/arch/blackfin/mm/blackfin_sram.c @@ -42,6 +42,7 @@ #include "blackfin_sram.h" static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; +static spinlock_t l2_sram_lock; /* the data structure for L1 scratchpad and DATA SRAM */ struct sram_piece { @@ -65,6 +66,10 @@ static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head; static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head; #endif +#ifdef L2_LENGTH +static struct sram_piece free_l2_sram_head, used_l2_sram_head; +#endif + static struct kmem_cache *sram_piece_cache; /* L1 Scratchpad SRAM initialization function */ @@ -97,7 +102,7 @@ static void __init l1_data_sram_init(void) free_l1_data_A_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_data_A_sram_head.next) { - printk(KERN_INFO"Fail to initialize Data A SRAM.\n"); + printk(KERN_INFO"Fail to initialize L1 Data A SRAM.\n"); return; } @@ -110,7 +115,7 @@ static void __init l1_data_sram_init(void) used_l1_data_A_sram_head.next = NULL; - printk(KERN_INFO "Blackfin Data A SRAM: %d KB (%d KB free)\n", + printk(KERN_INFO "Blackfin L1 Data A SRAM: %d KB (%d KB free)\n", L1_DATA_A_LENGTH >> 10, free_l1_data_A_sram_head.next->size >> 10); #endif @@ -118,7 +123,7 @@ static void __init l1_data_sram_init(void) free_l1_data_B_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_data_B_sram_head.next) { - printk(KERN_INFO"Fail to initialize Data B SRAM.\n"); + printk(KERN_INFO"Fail to initialize L1 Data B SRAM.\n"); return; } @@ -131,7 +136,7 @@ static void __init l1_data_sram_init(void) used_l1_data_B_sram_head.next = NULL; - printk(KERN_INFO "Blackfin Data B SRAM: %d KB (%d KB free)\n", + printk(KERN_INFO "Blackfin L1 Data B SRAM: %d KB (%d KB free)\n", L1_DATA_B_LENGTH >> 10, free_l1_data_B_sram_head.next->size >> 10); #endif @@ -146,7 +151,7 @@ static void __init l1_inst_sram_init(void) free_l1_inst_sram_head.next = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); if (!free_l1_inst_sram_head.next) { - printk(KERN_INFO"Fail to initialize Instruction SRAM.\n"); + printk(KERN_INFO"Fail to initialize L1 Instruction SRAM.\n"); return; } @@ -159,7 +164,7 @@ static void __init l1_inst_sram_init(void) used_l1_inst_sram_head.next = NULL; - printk(KERN_INFO "Blackfin Instruction SRAM: %d KB (%d KB free)\n", + printk(KERN_INFO "Blackfin L1 Instruction SRAM: %d KB (%d KB free)\n", L1_CODE_LENGTH >> 10, free_l1_inst_sram_head.next->size >> 10); #endif @@ -168,6 +173,33 @@ static void __init l1_inst_sram_init(void) spin_lock_init(&l1_inst_sram_lock); } +static void __init l2_sram_init(void) +{ +#ifdef L2_LENGTH + free_l2_sram_head.next = + kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); + if (!free_l2_sram_head.next) { + printk(KERN_INFO"Fail to initialize L2 SRAM.\n"); + return; + } + + free_l2_sram_head.next->paddr = (void *)L2_START + + (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); + free_l2_sram_head.next->size = L2_LENGTH - + (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); + free_l2_sram_head.next->pid = 0; + free_l2_sram_head.next->next = NULL; + + used_l2_sram_head.next = NULL; + + printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n", + L2_LENGTH >> 10, + free_l2_sram_head.next->size >> 10); +#endif + + /* mutex initialize */ + spin_lock_init(&l2_sram_lock); +} void __init bfin_sram_init(void) { sram_piece_cache = kmem_cache_create("sram_piece_cache", @@ -177,10 +209,11 @@ void __init bfin_sram_init(void) l1sram_init(); l1_data_sram_init(); l1_inst_sram_init(); + l2_sram_init(); } -/* L1 memory allocate function */ -static void *_l1_sram_alloc(size_t size, struct sram_piece *pfree_head, +/* SRAM allocate function */ +static void *_sram_alloc(size_t size, struct sram_piece *pfree_head, struct sram_piece *pused_head) { struct sram_piece *pslot, *plast, *pavail; @@ -236,7 +269,7 @@ static void *_l1_sram_alloc(size_t size, struct sram_piece *pfree_head, } /* Allocate the largest available block. */ -static void *_l1_sram_alloc_max(struct sram_piece *pfree_head, +static void *_sram_alloc_max(struct sram_piece *pfree_head, struct sram_piece *pused_head, unsigned long *psize) { @@ -259,11 +292,11 @@ static void *_l1_sram_alloc_max(struct sram_piece *pfree_head, *psize = pmax->size; - return _l1_sram_alloc(*psize, pfree_head, pused_head); + return _sram_alloc(*psize, pfree_head, pused_head); } -/* L1 memory free function */ -static int _l1_sram_free(const void *addr, +/* SRAM free function */ +static int _sram_free(const void *addr, struct sram_piece *pfree_head, struct sram_piece *pused_head) { @@ -333,6 +366,11 @@ int sram_free(const void *addr) else if (addr >= (void *)L1_DATA_B_START && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) return l1_data_B_sram_free(addr); +#endif +#ifdef L2_LENGTH + else if (addr >= (void *)L2_START + && addr < (void *)(L2_START + L2_LENGTH)) + return l2_sram_free(addr); #endif else return -1; @@ -348,7 +386,7 @@ void *l1_data_A_sram_alloc(size_t size) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - addr = _l1_sram_alloc(size, &free_l1_data_A_sram_head, + addr = _sram_alloc(size, &free_l1_data_A_sram_head, &used_l1_data_A_sram_head); #endif @@ -371,7 +409,7 @@ int l1_data_A_sram_free(const void *addr) spin_lock_irqsave(&l1_data_sram_lock, flags); #if L1_DATA_A_LENGTH != 0 - ret = _l1_sram_free(addr, &free_l1_data_A_sram_head, + ret = _sram_free(addr, &free_l1_data_A_sram_head, &used_l1_data_A_sram_head); #else ret = -1; @@ -393,7 +431,7 @@ void *l1_data_B_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - addr = _l1_sram_alloc(size, &free_l1_data_B_sram_head, + addr = _sram_alloc(size, &free_l1_data_B_sram_head, &used_l1_data_B_sram_head); /* add mutex operation */ @@ -418,7 +456,7 @@ int l1_data_B_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_data_sram_lock, flags); - ret = _l1_sram_free(addr, &free_l1_data_B_sram_head, + ret = _sram_free(addr, &free_l1_data_B_sram_head, &used_l1_data_B_sram_head); /* add mutex operation */ @@ -472,7 +510,7 @@ void *l1_inst_sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - addr = _l1_sram_alloc(size, &free_l1_inst_sram_head, + addr = _sram_alloc(size, &free_l1_inst_sram_head, &used_l1_inst_sram_head); /* add mutex operation */ @@ -497,7 +535,7 @@ int l1_inst_sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1_inst_sram_lock, flags); - ret = _l1_sram_free(addr, &free_l1_inst_sram_head, + ret = _sram_free(addr, &free_l1_inst_sram_head, &used_l1_inst_sram_head); /* add mutex operation */ @@ -519,7 +557,7 @@ void *l1sram_alloc(size_t size) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc(size, &free_l1_ssram_head, + addr = _sram_alloc(size, &free_l1_ssram_head, &used_l1_ssram_head); /* add mutex operation */ @@ -537,7 +575,7 @@ void *l1sram_alloc_max(size_t *psize) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - addr = _l1_sram_alloc_max(&free_l1_ssram_head, + addr = _sram_alloc_max(&free_l1_ssram_head, &used_l1_ssram_head, psize); /* add mutex operation */ @@ -555,7 +593,7 @@ int l1sram_free(const void *addr) /* add mutex operation */ spin_lock_irqsave(&l1sram_lock, flags); - ret = _l1_sram_free(addr, &free_l1_ssram_head, + ret = _sram_free(addr, &free_l1_ssram_head, &used_l1_ssram_head); /* add mutex operation */ @@ -564,6 +602,64 @@ int l1sram_free(const void *addr) return ret; } +void *l2_sram_alloc(size_t size) +{ +#ifdef L2_LENGTH + unsigned flags; + void *addr; + + /* add mutex operation */ + spin_lock_irqsave(&l2_sram_lock, flags); + + addr = _sram_alloc(size, &free_l2_sram_head, + &used_l2_sram_head); + + /* add mutex operation */ + spin_unlock_irqrestore(&l2_sram_lock, flags); + + pr_debug("Allocated address in l2_sram_alloc is 0x%lx+0x%lx\n", + (long unsigned int)addr, size); + + return addr; +#else + return NULL; +#endif +} +EXPORT_SYMBOL(l2_sram_alloc); + +void *l2_sram_zalloc(size_t size) +{ + void *addr = l2_sram_alloc(size); + + if (addr) + memset(addr, 0x00, size); + + return addr; +} +EXPORT_SYMBOL(l2_sram_zalloc); + +int l2_sram_free(const void *addr) +{ +#ifdef L2_LENGTH + unsigned flags; + int ret; + + /* add mutex operation */ + spin_lock_irqsave(&l2_sram_lock, flags); + + ret = _sram_free(addr, &free_l2_sram_head, + &used_l2_sram_head); + + /* add mutex operation */ + spin_unlock_irqrestore(&l2_sram_lock, flags); + + return ret; +#else + return -1; +#endif +} +EXPORT_SYMBOL(l2_sram_free); + int sram_free_with_lsl(const void *addr) { struct sram_list_struct *lsl, **tmp; @@ -602,6 +698,9 @@ void *sram_alloc_with_lsl(size_t size, unsigned long flags) if (addr == NULL && (flags & L1_DATA_B_SRAM)) addr = l1_data_B_sram_alloc(size); + if (addr == NULL && (flags & L2_SRAM)) + addr = l2_sram_alloc(size); + if (addr == NULL) { kfree(lsl); return NULL; @@ -621,7 +720,7 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); /* Need to keep line of output the same. Currently, that is 44 bytes * (including newline). */ -static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, +static int _sram_proc_read(char *buf, int *len, int count, const char *desc, struct sram_piece *pfree_head, struct sram_piece *pused_head) { @@ -630,13 +729,13 @@ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, if (!pfree_head || !pused_head) return -1; - *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State \n", desc); + *len += sprintf(&buf[*len], "--- SRAM %-14s Size PID State \n", desc); /* search the relevant memory slot */ pslot = pused_head->next; while (pslot != NULL) { - *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", + *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", pslot->paddr, pslot->paddr + pslot->size, pslot->size, pslot->pid, "ALLOCATED"); @@ -646,7 +745,7 @@ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, pslot = pfree_head->next; while (pslot != NULL) { - *len += sprintf(&buf[*len], "%p-%p %8i %5i %-10s\n", + *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", pslot->paddr, pslot->paddr + pslot->size, pslot->size, pslot->pid, "FREE"); @@ -655,38 +754,43 @@ static int _l1sram_proc_read(char *buf, int *len, int count, const char *desc, return 0; } -static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, +static int sram_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len = 0; - if (_l1sram_proc_read(buf, &len, count, "Scratchpad", + if (_sram_proc_read(buf, &len, count, "Scratchpad", &free_l1_ssram_head, &used_l1_ssram_head)) goto not_done; #if L1_DATA_A_LENGTH != 0 - if (_l1sram_proc_read(buf, &len, count, "Data A", + if (_sram_proc_read(buf, &len, count, "L1 Data A", &free_l1_data_A_sram_head, &used_l1_data_A_sram_head)) goto not_done; #endif #if L1_DATA_B_LENGTH != 0 - if (_l1sram_proc_read(buf, &len, count, "Data B", + if (_sram_proc_read(buf, &len, count, "L1 Data B", &free_l1_data_B_sram_head, &used_l1_data_B_sram_head)) goto not_done; #endif #if L1_CODE_LENGTH != 0 - if (_l1sram_proc_read(buf, &len, count, "Instruction", + if (_sram_proc_read(buf, &len, count, "L1 Instruction", &free_l1_inst_sram_head, &used_l1_inst_sram_head)) goto not_done; #endif +#ifdef L2_LENGTH + if (_sram_proc_read(buf, &len, count, "L2", + &free_l2_sram_head, &used_l2_sram_head)) + goto not_done; +#endif *eof = 1; not_done: return len; } -static int __init l1sram_proc_init(void) +static int __init sram_proc_init(void) { struct proc_dir_entry *ptr; ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL); @@ -695,8 +799,8 @@ static int __init l1sram_proc_init(void) return -1; } ptr->owner = THIS_MODULE; - ptr->read_proc = l1sram_proc_read; + ptr->read_proc = sram_proc_read; return 0; } -late_initcall(l1sram_proc_init); +late_initcall(sram_proc_init); #endif diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h index 76033831eb35..320aa5e167e9 100644 --- a/include/asm-blackfin/bfin-global.h +++ b/include/asm-blackfin/bfin-global.h @@ -92,16 +92,20 @@ extern void *l1_data_B_sram_alloc(size_t); extern void *l1_inst_sram_alloc(size_t); extern void *l1_data_sram_alloc(size_t); extern void *l1_data_sram_zalloc(size_t); +extern void *l2_sram_alloc(size_t); +extern void *l2_sram_zalloc(size_t); extern int l1_data_A_sram_free(const void*); extern int l1_data_B_sram_free(const void*); extern int l1_inst_sram_free(const void*); extern int l1_data_sram_free(const void*); +extern int l2_sram_free(const void *); extern int sram_free(const void*); #define L1_INST_SRAM 0x00000001 #define L1_DATA_A_SRAM 0x00000002 #define L1_DATA_B_SRAM 0x00000004 #define L1_DATA_SRAM 0x00000006 +#define L2_SRAM 0x00000008 extern void *sram_alloc_with_lsl(size_t, unsigned long); extern int sram_free_with_lsl(const void*); @@ -114,7 +118,9 @@ extern struct file_operations dpmc_fops; extern unsigned long _ramstart, _ramend, _rambase; extern unsigned long memory_start, memory_end, physical_mem_end; extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], - _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[]; + _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[], + _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[], + _ebss_l2[], _l2_lma_start[]; #ifdef CONFIG_MTD_UCLINUX extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size; diff --git a/include/asm-blackfin/elf.h b/include/asm-blackfin/elf.h index 30303fc8292c..67a03a8a353e 100644 --- a/include/asm-blackfin/elf.h +++ b/include/asm-blackfin/elf.h @@ -15,6 +15,8 @@ #define EF_BFIN_FDPIC 0x00000002 /* -mfdpic */ #define EF_BFIN_CODE_IN_L1 0x00000010 /* --code-in-l1 */ #define EF_BFIN_DATA_IN_L1 0x00000020 /* --data-in-l1 */ +#define EF_BFIN_CODE_IN_L2 0x00000040 /* --code-in-l2 */ +#define EF_BFIN_DATA_IN_L2 0x00000080 /* --data-in-l2 */ typedef unsigned long elf_greg_t; diff --git a/include/asm-blackfin/module.h b/include/asm-blackfin/module.h index 3c7ce1644280..e3128df139d6 100644 --- a/include/asm-blackfin/module.h +++ b/include/asm-blackfin/module.h @@ -6,8 +6,6 @@ #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr -#define FLG_CODE_IN_L1 0x10 -#define FLG_DATA_IN_L1 0x20 struct mod_arch_specific { Elf_Shdr *text_l1; @@ -15,5 +13,8 @@ struct mod_arch_specific { Elf_Shdr *bss_a_l1; Elf_Shdr *data_b_l1; Elf_Shdr *bss_b_l1; + Elf_Shdr *text_l2; + Elf_Shdr *data_l2; + Elf_Shdr *bss_l2; }; #endif /* _ASM_BFIN_MODULE_H */ From aa3348f461da1df5c583f9916ab80298ddd68eff Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Sat, 19 Jul 2008 15:54:10 +0800 Subject: [PATCH 021/179] Blackfin arch: Add return value check in bfin_sir_probe(), remove SSYNC(). Signed-off-by: Graf Yang Signed-off-by: Bryan Wu --- include/asm-blackfin/mach-bf527/bfin_sir.h | 21 ++++++++---- include/asm-blackfin/mach-bf533/bfin_sir.h | 13 +++++--- include/asm-blackfin/mach-bf537/bfin_sir.h | 21 ++++++++---- include/asm-blackfin/mach-bf548/bfin_sir.h | 37 ++++++++++++++++------ include/asm-blackfin/mach-bf561/bfin_sir.h | 13 +++++--- 5 files changed, 75 insertions(+), 30 deletions(-) diff --git a/include/asm-blackfin/mach-bf527/bfin_sir.h b/include/asm-blackfin/mach-bf527/bfin_sir.h index 0612d0c9501c..cfd8ad4f1f2c 100644 --- a/include/asm-blackfin/mach-bf527/bfin_sir.h +++ b/include/asm-blackfin/mach-bf527/bfin_sir.h @@ -118,16 +118,25 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static void bfin_sir_hw_init(void) +static int bfin_sir_hw_init(void) { + int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); + ret = peripheral_request(P_UART0_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART0_RX, DRIVER_NAME); + if (ret) + return ret; #endif #ifdef CONFIG_BFIN_SIR1 - peripheral_request(P_UART1_TX, DRIVER_NAME); - peripheral_request(P_UART1_RX, DRIVER_NAME); + ret = peripheral_request(P_UART1_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART1_RX, DRIVER_NAME); + if (ret) + return ret; #endif - SSYNC(); + return ret; } diff --git a/include/asm-blackfin/mach-bf533/bfin_sir.h b/include/asm-blackfin/mach-bf533/bfin_sir.h index cefcf8bb505b..9bb87e9e2e9b 100644 --- a/include/asm-blackfin/mach-bf533/bfin_sir.h +++ b/include/asm-blackfin/mach-bf533/bfin_sir.h @@ -110,11 +110,16 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static void bfin_sir_hw_init(void) +static int bfin_sir_hw_init(void) { + int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); + ret = peripheral_request(P_UART0_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART0_RX, DRIVER_NAME); + if (ret) + return ret; #endif - SSYNC(); + return ret; } diff --git a/include/asm-blackfin/mach-bf537/bfin_sir.h b/include/asm-blackfin/mach-bf537/bfin_sir.h index 0612d0c9501c..cfd8ad4f1f2c 100644 --- a/include/asm-blackfin/mach-bf537/bfin_sir.h +++ b/include/asm-blackfin/mach-bf537/bfin_sir.h @@ -118,16 +118,25 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static void bfin_sir_hw_init(void) +static int bfin_sir_hw_init(void) { + int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); + ret = peripheral_request(P_UART0_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART0_RX, DRIVER_NAME); + if (ret) + return ret; #endif #ifdef CONFIG_BFIN_SIR1 - peripheral_request(P_UART1_TX, DRIVER_NAME); - peripheral_request(P_UART1_RX, DRIVER_NAME); + ret = peripheral_request(P_UART1_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART1_RX, DRIVER_NAME); + if (ret) + return ret; #endif - SSYNC(); + return ret; } diff --git a/include/asm-blackfin/mach-bf548/bfin_sir.h b/include/asm-blackfin/mach-bf548/bfin_sir.h index 5e94271c7e3b..c41f9cf00268 100644 --- a/include/asm-blackfin/mach-bf548/bfin_sir.h +++ b/include/asm-blackfin/mach-bf548/bfin_sir.h @@ -124,26 +124,43 @@ struct bfin_sir_self { #define DRIVER_NAME "bfin_sir" -static void bfin_sir_hw_init(void) +static int bfin_sir_hw_init(void) { + int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); + ret = peripheral_request(P_UART0_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART0_RX, DRIVER_NAME); + if (ret) + return ret; #endif #ifdef CONFIG_BFIN_SIR1 - peripheral_request(P_UART1_TX, DRIVER_NAME); - peripheral_request(P_UART1_RX, DRIVER_NAME); + ret = peripheral_request(P_UART1_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART1_RX, DRIVER_NAME); + if (ret) + return ret; #endif #ifdef CONFIG_BFIN_SIR2 - peripheral_request(P_UART2_TX, DRIVER_NAME); - peripheral_request(P_UART2_RX, DRIVER_NAME); + ret = peripheral_request(P_UART2_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART2_RX, DRIVER_NAME); + if (ret) + return ret; #endif #ifdef CONFIG_BFIN_SIR3 - peripheral_request(P_UART3_TX, DRIVER_NAME); - peripheral_request(P_UART3_RX, DRIVER_NAME); + ret = peripheral_request(P_UART3_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART3_RX, DRIVER_NAME); + if (ret) + return ret; #endif - SSYNC(); + return ret; } diff --git a/include/asm-blackfin/mach-bf561/bfin_sir.h b/include/asm-blackfin/mach-bf561/bfin_sir.h index cefcf8bb505b..9bb87e9e2e9b 100644 --- a/include/asm-blackfin/mach-bf561/bfin_sir.h +++ b/include/asm-blackfin/mach-bf561/bfin_sir.h @@ -110,11 +110,16 @@ static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port) #define DRIVER_NAME "bfin_sir" -static void bfin_sir_hw_init(void) +static int bfin_sir_hw_init(void) { + int ret = -ENODEV; #ifdef CONFIG_BFIN_SIR0 - peripheral_request(P_UART0_TX, DRIVER_NAME); - peripheral_request(P_UART0_RX, DRIVER_NAME); + ret = peripheral_request(P_UART0_TX, DRIVER_NAME); + if (ret) + return ret; + ret = peripheral_request(P_UART0_RX, DRIVER_NAME); + if (ret) + return ret; #endif - SSYNC(); + return ret; } From cc2e16bd35f6d78f559467358259e7d7264d4e96 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 19 Jul 2008 16:43:51 +0800 Subject: [PATCH 022/179] Blackfin arch: add missing IORESOURCE_MEM flags to UART3 Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf548/boards/ezkit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index af7c211a580e..547dd253a3f3 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -177,6 +177,7 @@ static struct resource bfin_uart_resources[] = { { .start = 0xFFC03100, .end = 0xFFC031FF, + .flags = IORESOURCE_MEM, }, #endif }; From 0138da6101fa3cdfea7f470d014c2f13cc03e7a9 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Sat, 19 Jul 2008 16:56:53 +0800 Subject: [PATCH 023/179] Blackfin arch: fix bug - detect 0.1 silicon revision BF527-EZKIT as 0.0 version Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- include/asm-blackfin/processor.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h index 1c0040724612..6f3995b119d8 100644 --- a/include/asm-blackfin/processor.h +++ b/include/asm-blackfin/processor.h @@ -112,7 +112,26 @@ unsigned long get_wchan(struct task_struct *p); static inline uint32_t __pure bfin_revid(void) { /* stored in the upper 4 bits */ - return bfin_read_CHIPID() >> 28; + uint32_t revid = bfin_read_CHIPID() >> 28; + +#ifdef CONFIG_BF52x + /* ANOMALY_05000357 + * Incorrect Revision Number in DSPID Register + */ + if (revid == 0) + switch (bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI)) { + case 0x0010: + revid = 0; + break; + case 0x2796: + revid = 1; + break; + default: + revid = 0xFFFF; + break; + } +#endif + return revid; } static inline uint32_t __pure bfin_compiled_revid(void) From 0a6304a9517aa3593913ecfbbcad80e798641723 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Sat, 26 Jul 2008 16:14:57 +0800 Subject: [PATCH 024/179] Blackfin arch: Add ISP1760 board resources to BF548-EZKIT Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf548/boards/ezkit.c | 43 +++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 547dd253a3f3..166fa2201ee7 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -61,6 +61,49 @@ const char bfin_board_name[] = "ADSP-BF548-EZKIT"; * Driver needs to know address, irq and flag pin. */ +#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) +static struct resource bfin_isp1761_resources[] = { + [0] = { + .name = "isp1761-regs", + .start = 0x2C0C0000, + .end = 0x2C0C0000 + 0xfffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PG7, + .end = IRQ_PG7, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_isp1761_device = { + .name = "isp1761", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_isp1761_resources), + .resource = bfin_isp1761_resources, +}; + +static struct platform_device *bfin_isp1761_devices[] = { + &bfin_isp1761_device, +}; + +int __init bfin_isp1761_init(void) +{ + unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices); + + printk(KERN_INFO "%s(): registering device resources\n", __func__); + set_irq_type(bfin_isp1761_resources[1].start, IRQF_TRIGGER_FALLING); + + return platform_add_devices(bfin_isp1761_devices, num_devices); +} + +void __exit bfin_isp1761_exit(void) +{ + platform_device_unregister(&bfin_isp1761_device); +} +arch_initcall(bfin_isp1761_init); +#endif + #if defined(CONFIG_FB_BF54X_LQ043) || defined(CONFIG_FB_BF54X_LQ043_MODULE) #include From f09630bff51daaf427968c61c0f2370c64148e06 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 26 Jul 2008 19:45:46 +0800 Subject: [PATCH 025/179] Blackfin arch: Add unwinding for stack info, and a little more detail on trace buffer Signed-off-by: Robin Getz Signed-off-by: Bryan Wu --- arch/blackfin/kernel/traps.c | 300 ++++++++++++++++++++++++++++------- 1 file changed, 243 insertions(+), 57 deletions(-) diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index f061f5181623..ad922ab91543 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -69,8 +69,6 @@ void __init trap_init(void) unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; -int kstack_depth_to_print = 48; - static void decode_address(char *buf, unsigned long address) { struct vm_list_struct *vml; @@ -163,6 +161,9 @@ static void decode_address(char *buf, unsigned long address) if (!in_atomic) mmput(mm); + if (!strlen(buf)) + sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); + goto done; } @@ -173,7 +174,7 @@ static void decode_address(char *buf, unsigned long address) } /* we were unable to find this address anywhere */ - sprintf(buf, "<0x%p> /* unknown address */", (void *)address); + sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); done: write_unlock_irqrestore(&tasklist_lock, flags); @@ -494,7 +495,7 @@ asmlinkage void trap_c(struct pt_regs *fp) BUG_ON(sig == 0); if (sig != SIGTRAP) { - unsigned long stack; + unsigned long *stack; dump_bfin_process(fp); dump_bfin_mem(fp); show_regs(fp); @@ -508,14 +509,23 @@ asmlinkage void trap_c(struct pt_regs *fp) else #endif dump_bfin_trace_buffer(); - show_stack(current, &stack); + if (oops_in_progress) { + /* Dump the current kernel stack */ + printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); + show_stack(current, NULL); + print_modules(); #ifndef CONFIG_ACCESS_CHECK printk(KERN_EMERG "Please turn on " "CONFIG_ACCESS_CHECK\n"); #endif panic("Kernel exception"); + } else { + /* Dump the user space stack */ + stack = (unsigned long *)rdusp(); + printk(KERN_NOTICE "Userspace Stack\n"); + show_stack(NULL, stack); } } @@ -532,11 +542,71 @@ asmlinkage void trap_c(struct pt_regs *fp) #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) +/* + * Similar to get_user, do some address checking, then dereference + * Return true on sucess, false on bad address + */ +bool get_instruction(unsigned short *val, unsigned short *address) +{ + + unsigned long addr; + + addr = (unsigned long)address; + + /* Check for odd addresses */ + if (addr & 0x1) + return false; + + /* Check that things do not wrap around */ + if (addr > (addr + 2)) + return false; + + /* + * Since we are in exception context, we need to do a little address checking + * We need to make sure we are only accessing valid memory, and + * we don't read something in the async space that can hang forever + */ + if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || +#ifdef L2_START + (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || +#endif + (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || +#if L1_DATA_A_LENGTH != 0 + (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || +#endif +#if L1_DATA_B_LENGTH != 0 + (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) || +#endif + (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) || + (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) && + addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) || + (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) && + addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) || + (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) && + addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) || + (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) && + addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) { + *val = *address; + return true; + } + +#if L1_CODE_LENGTH != 0 + if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { + dma_memcpy(val, address, 2); + return true; + } +#endif + + + return false; +} + void dump_bfin_trace_buffer(void) { #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int tflags, i = 0; char buf[150]; + unsigned short val = 0, *addr; #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND int j, index; #endif @@ -549,8 +619,42 @@ void dump_bfin_trace_buffer(void) for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { decode_address(buf, (unsigned long)bfin_read_TBUF()); printk(KERN_NOTICE "%4i Target : %s\n", i, buf); - decode_address(buf, (unsigned long)bfin_read_TBUF()); - printk(KERN_NOTICE " Source : %s\n", buf); + addr = (unsigned short *)bfin_read_TBUF(); + decode_address(buf, (unsigned long)addr); + printk(KERN_NOTICE " Source : %s ", buf); + if (get_instruction(&val, addr)) { + if (val == 0x0010) + printk("RTS"); + else if (val == 0x0011) + printk("RTI"); + else if (val == 0x0012) + printk("RTX"); + else if (val >= 0x0050 && val <= 0x0057) + printk("JUMP (P%i)", val & 7); + else if (val >= 0x0060 && val <= 0x0067) + printk("CALL (P%i)", val & 7); + else if (val >= 0x0070 && val <= 0x0077) + printk("CALL (PC+P%i)", val & 7); + else if (val >= 0x0080 && val <= 0x0087) + printk("JUMP (PC+P%i)", val & 7); + else if ((val >= 0x1000 && val <= 0x13FF) || + (val >= 0x1800 && val <= 0x1BFF)) + printk("IF !CC JUMP"); + else if ((val >= 0x1400 && val <= 0x17ff) || + (val >= 0x1c00 && val <= 0x1fff)) + printk("IF CC JUMP"); + else if (val >= 0x2000 && val <= 0x2fff) + printk("JUMP.S"); + else if (val >= 0xe080 && val <= 0xe0ff) + printk("LSETUP"); + else if (val >= 0xe200 && val <= 0xe2ff) + printk("JUMP.L"); + else if (val >= 0xe300 && val <= 0xe3ff) + printk("CALL pcrel"); + else + printk("0x%04x", val); + } + printk("\n"); } } @@ -582,59 +686,151 @@ void dump_bfin_trace_buffer(void) } EXPORT_SYMBOL(dump_bfin_trace_buffer); -static void show_trace(struct task_struct *tsk, unsigned long *sp) +/* + * Checks to see if the address pointed to is either a + * 16-bit CALL instruction, or a 32-bit CALL instruction + */ +bool is_bfin_call(unsigned short *addr) { - unsigned long addr; + unsigned short opcode = 0, *ins_addr; + ins_addr = (unsigned short *)addr; - printk(KERN_NOTICE "\n" KERN_NOTICE "Call Trace:\n"); + if (!get_instruction(&opcode, ins_addr)) + return false; - while (!kstack_end(sp)) { - addr = *sp++; - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ - if (kernel_text_address(addr)) - print_ip_sym(addr); - } + if ((opcode >= 0x0060 && opcode <= 0x0067) || + (opcode >= 0x0070 && opcode <= 0x0077)) + return true; + + ins_addr--; + if (!get_instruction(&opcode, ins_addr)) + return false; + + if (opcode >= 0xE300 && opcode <= 0xE3FF) + return true; + + return false; - printk(KERN_NOTICE "\n"); } - void show_stack(struct task_struct *task, unsigned long *stack) { - unsigned long *endstack, addr; - int i; + unsigned int *addr, *endstack, *fp = 0, *frame; + unsigned short *ins_addr; + char buf[150]; + unsigned int i, j, ret_addr, frame_no = 0; - /* Cannot call dump_bfin_trace_buffer() here as show_stack() is - * called externally in some places in the kernel. + /* + * If we have been passed a specific stack, use that one otherwise + * if we have been passed a task structure, use that, otherwise + * use the stack of where the variable "stack" exists */ - if (!stack) { - if (task) + if (stack == NULL) { + if (task) { + /* We know this is a kernel stack, so this is the start/end */ stack = (unsigned long *)task->thread.ksp; - else + endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); + } else { + /* print out the existing stack info */ stack = (unsigned long *)&stack; + endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); + } + } else + endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); + + decode_address(buf, (unsigned int)stack); + printk(KERN_NOTICE "Stack info:\n" KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); + addr = (unsigned int *)((unsigned int)stack & ~0x3F); + + /* First thing is to look for a frame pointer */ + for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; + addr < endstack; addr++, i++) { + if (*addr & 0x1) + continue; + ins_addr = (unsigned short *)*addr; + ins_addr--; + if (is_bfin_call(ins_addr)) + fp = addr - 1; + + if (fp) { + /* Let's check to see if it is a frame pointer */ + while (fp >= (addr - 1) && fp < endstack && fp) + fp = (unsigned int *)*fp; + if (fp == 0 || fp == endstack) { + fp = addr - 1; + break; + } + fp = 0; + } + } + if (fp) { + frame = fp; + printk(" FP: (0x%p)\n", fp); + } else + frame = 0; + + /* + * Now that we think we know where things are, we + * walk the stack again, this time printing things out + * incase there is no frame pointer, we still look for + * valid return addresses + */ + + /* First time print out data, next time, print out symbols */ + for (j = 0; j <= 1; j++) { + if (j) + printk(KERN_NOTICE "Return addresses in stack:\n"); + else + printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); + + fp = frame; + frame_no = 0; + + for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; + addr <= endstack; addr++, i++) { + + ret_addr = 0; + if (!j && i % 8 == 0) + printk("\n" KERN_NOTICE "%p:",addr); + + /* if it is an odd address, or zero, just skip it */ + if (*addr & 0x1 || !*addr) + goto print; + + ins_addr = (unsigned short *)*addr; + + /* Go back one instruction, and see if it is a CALL */ + ins_addr--; + ret_addr = is_bfin_call(ins_addr); + print: + if (!j && stack == (unsigned long *)addr) + printk("[%08x]", *addr); + else if (ret_addr) + if (j) { + decode_address(buf, (unsigned int)*addr); + if (frame == addr) { + printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); + continue; + } + printk(KERN_NOTICE " address : %s\n", buf); + } else + printk("<%08x>", *addr); + else if (fp == addr) { + if (j) + frame = addr+1; + else + printk("(%08x)", *addr); + + fp = (unsigned int *)*addr; + frame_no++; + + } else if (!j) + printk(" %08x ", *addr); + } + if (!j) + printk("\n"); } - addr = (unsigned long)stack; - endstack = (unsigned long *)PAGE_ALIGN(addr); - - printk(KERN_NOTICE "Stack from %08lx:", (unsigned long)stack); - for (i = 0; i < kstack_depth_to_print; i++) { - if (stack + 1 > endstack) - break; - if (i % 8 == 0) - printk("\n" KERN_NOTICE " "); - printk(" %08lx", *stack++); - } - printk("\n"); - - show_trace(task, stack); } void dump_stack(void) @@ -715,19 +911,9 @@ void dump_bfin_mem(struct pt_regs *fp) if (!((unsigned long)addr & 0xF)) printk("\n" KERN_NOTICE "0x%p: ", addr); - if (get_user(val, addr)) { - if (addr >= (unsigned short *)L1_CODE_START && - addr < (unsigned short *)(L1_CODE_START + L1_CODE_LENGTH)) { - dma_memcpy(&val, addr, sizeof(val)); - sprintf(buf, "%04x", val); - } else if (addr >= (unsigned short *)FIXED_CODE_START && - addr <= (unsigned short *)memory_start) { - val = bfin_read16(addr); - sprintf(buf, "%04x", val); - } else { + if (get_instruction(&val, addr)) { val = 0; sprintf(buf, "????"); - } } else sprintf(buf, "%04x", val); From 9db144fe897bb09838294aab2229cb423ab40988 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Sat, 19 Jul 2008 17:16:07 +0800 Subject: [PATCH 026/179] Blackfin arch: Apply Bluetechnix CM-BF527 board support patch Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig | 5 +- arch/blackfin/configs/CM-BF527_defconfig | 1185 ++++++++++++++++++++ arch/blackfin/mach-bf527/boards/Kconfig | 5 + arch/blackfin/mach-bf527/boards/Makefile | 1 + arch/blackfin/mach-bf527/boards/cm_bf527.c | 1011 +++++++++++++++++ 5 files changed, 2204 insertions(+), 3 deletions(-) create mode 100644 arch/blackfin/configs/CM-BF527_defconfig create mode 100644 arch/blackfin/mach-bf527/boards/cm_bf527.c diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 5a08194e4118..efa77f3a30d8 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -234,7 +234,7 @@ config MEM_MT48LC16M16A2TG_75 bool depends on (BFIN533_EZKIT || BFIN561_EZKIT \ || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM \ - || H8606_HVSISTEMAS) + || H8606_HVSISTEMAS || BFIN527_BLUETECHNIX_CM) default y config MEM_MT48LC32M8A2_75 @@ -330,8 +330,7 @@ config VCO_MULT default "45" if BFIN533_STAMP default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM) default "22" if BFIN533_BLUETECHNIX_CM - default "20" if BFIN537_BLUETECHNIX_CM - default "20" if BFIN561_BLUETECHNIX_CM + default "20" if (BFIN537_BLUETECHNIX_CM || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) default "20" if BFIN561_EZKIT default "16" if H8606_HVSISTEMAS help diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig new file mode 100644 index 000000000000..0799aa9bba9d --- /dev/null +++ b/arch/blackfin/configs/CM-BF527_defconfig @@ -0,0 +1,1185 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.24.7 +# Fri Jul 18 18:00:41 2008 +# +# CONFIG_MMU is not set +# CONFIG_FPU is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BLACKFIN=y +CONFIG_ZONE_DMA=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_GPIO=y +CONFIG_FORCE_MAX_ZONEORDER=14 +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_EVENTFD=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set + +# +# Blackfin Processor Options +# + +# +# Processor and Board Settings +# +# CONFIG_BF522 is not set +# CONFIG_BF523 is not set +# CONFIG_BF524 is not set +# CONFIG_BF525 is not set +# CONFIG_BF526 is not set +CONFIG_BF527=y +# CONFIG_BF531 is not set +# CONFIG_BF532 is not set +# CONFIG_BF533 is not set +# CONFIG_BF534 is not set +# CONFIG_BF536 is not set +# CONFIG_BF537 is not set +# CONFIG_BF542 is not set +# CONFIG_BF544 is not set +# CONFIG_BF547 is not set +# CONFIG_BF548 is not set +# CONFIG_BF549 is not set +# CONFIG_BF561 is not set +# CONFIG_BF_REV_0_0 is not set +CONFIG_BF_REV_0_1=y +# CONFIG_BF_REV_0_2 is not set +# CONFIG_BF_REV_0_3 is not set +# CONFIG_BF_REV_0_4 is not set +# CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_BF52x=y +CONFIG_MEM_MT48LC16M16A2TG_75=y +# CONFIG_BFIN527_EZKIT is not set +CONFIG_BFIN527_BLUETECHNIX_CM=y + +# +# BF527 Specific Configuration +# + +# +# Alternative Multiplexing Scheme +# +# CONFIG_BF527_SPORT0_PORTF is not set +CONFIG_BF527_SPORT0_PORTG=y +CONFIG_BF527_SPORT0_TSCLK_PG10=y +# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set +CONFIG_BF527_UART1_PORTF=y +# CONFIG_BF527_UART1_PORTG is not set +# CONFIG_BF527_NAND_D_PORTF is not set +CONFIG_BF527_NAND_D_PORTH=y + +# +# Interrupt Priority Assignment +# + +# +# Priority +# +CONFIG_IRQ_PLL_WAKEUP=7 +CONFIG_IRQ_DMA0_ERROR=7 +CONFIG_IRQ_DMAR0_BLK=7 +CONFIG_IRQ_DMAR1_BLK=7 +CONFIG_IRQ_DMAR0_OVR=7 +CONFIG_IRQ_DMAR1_OVR=7 +CONFIG_IRQ_PPI_ERROR=7 +CONFIG_IRQ_MAC_ERROR=7 +CONFIG_IRQ_SPORT0_ERROR=7 +CONFIG_IRQ_SPORT1_ERROR=7 +CONFIG_IRQ_UART0_ERROR=7 +CONFIG_IRQ_UART1_ERROR=7 +CONFIG_IRQ_RTC=8 +CONFIG_IRQ_PPI=8 +CONFIG_IRQ_SPORT0_RX=9 +CONFIG_IRQ_SPORT0_TX=9 +CONFIG_IRQ_SPORT1_RX=9 +CONFIG_IRQ_SPORT1_TX=9 +CONFIG_IRQ_TWI=10 +CONFIG_IRQ_SPI=10 +CONFIG_IRQ_UART0_RX=10 +CONFIG_IRQ_UART0_TX=10 +CONFIG_IRQ_UART1_RX=10 +CONFIG_IRQ_UART1_TX=10 +CONFIG_IRQ_OPTSEC=11 +CONFIG_IRQ_CNT=11 +CONFIG_IRQ_MAC_RX=11 +CONFIG_IRQ_PORTH_INTA=11 +CONFIG_IRQ_MAC_TX=11 +CONFIG_IRQ_PORTH_INTB=11 +CONFIG_IRQ_TMR0=12 +CONFIG_IRQ_TMR1=12 +CONFIG_IRQ_TMR2=12 +CONFIG_IRQ_TMR3=12 +CONFIG_IRQ_TMR4=12 +CONFIG_IRQ_TMR5=12 +CONFIG_IRQ_TMR6=12 +CONFIG_IRQ_TMR7=12 +CONFIG_IRQ_PORTG_INTA=12 +CONFIG_IRQ_PORTG_INTB=12 +CONFIG_IRQ_MEM_DMA0=13 +CONFIG_IRQ_MEM_DMA1=13 +CONFIG_IRQ_WATCH=13 +CONFIG_IRQ_PORTF_INTA=13 +CONFIG_IRQ_PORTF_INTB=13 +CONFIG_IRQ_SPI_ERROR=7 +CONFIG_IRQ_NFC_ERROR=7 +CONFIG_IRQ_HDMA_ERROR=7 +CONFIG_IRQ_HDMA=7 +CONFIG_IRQ_USB_EINT=10 +CONFIG_IRQ_USB_INT0=11 +CONFIG_IRQ_USB_INT1=11 +CONFIG_IRQ_USB_INT2=11 +CONFIG_IRQ_USB_DMA=11 + +# +# Board customizations +# +# CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 + +# +# Clock/PLL Setup +# +CONFIG_CLKIN_HZ=25000000 +# CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_MEM_SIZE=512 +CONFIG_MAX_VCO_HZ=600000000 +CONFIG_MIN_VCO_HZ=50000000 +CONFIG_MAX_SCLK_HZ=133333333 +CONFIG_MIN_SCLK_HZ=27000000 + +# +# Kernel Timer/Scheduler +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Misc +# +CONFIG_BFIN_SCRATCH_REG_RETN=y +# CONFIG_BFIN_SCRATCH_REG_RETE is not set +# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set + +# +# Blackfin Kernel Optimizations +# + +# +# Memory Optimizations +# +CONFIG_I_ENTRY_L1=y +CONFIG_EXCPT_IRQ_SYSC_L1=y +CONFIG_DO_IRQ_L1=y +CONFIG_CORE_TIMER_IRQ_L1=y +CONFIG_IDLE_L1=y +# CONFIG_SCHEDULE_L1 is not set +CONFIG_ARITHMETIC_OPS_L1=y +CONFIG_ACCESS_OK_L1=y +# CONFIG_MEMSET_L1 is not set +# CONFIG_MEMCPY_L1 is not set +# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set +# CONFIG_IP_CHECKSUM_L1 is not set +CONFIG_CACHELINE_ALIGNED_L1=y +# CONFIG_SYSCALL_TAB_L1 is not set +# CONFIG_CPLB_SWITCH_TAB_L1 is not set +CONFIG_RAMKERNEL=y +# CONFIG_ROMKERNEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +CONFIG_BFIN_GPTIMERS=y +CONFIG_BFIN_DMA_5XX=y +# CONFIG_DMA_UNCACHED_4M is not set +# CONFIG_DMA_UNCACHED_2M is not set +CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_NONE is not set + +# +# Cache Support +# +CONFIG_BFIN_ICACHE=y +CONFIG_BFIN_DCACHE=y +# CONFIG_BFIN_DCACHE_BANKA is not set +# CONFIG_BFIN_ICACHE_LOCK is not set +# CONFIG_BFIN_WB is not set +CONFIG_BFIN_WT=y +# CONFIG_MPU is not set + +# +# Asynchonous Memory Configuration +# + +# +# EBIU_AMGCTL Global Control +# +CONFIG_C_AMCKEN=y +CONFIG_C_CDPRIO=y +# CONFIG_C_AMBEN is not set +# CONFIG_C_AMBEN_B0 is not set +# CONFIG_C_AMBEN_B0_B1 is not set +# CONFIG_C_AMBEN_B0_B1_B2 is not set +CONFIG_C_AMBEN_ALL=y + +# +# EBIU_AMBCTL Control +# +CONFIG_BANK_0=0x7BB0 +CONFIG_BANK_1=0x5554 +CONFIG_BANK_2=0x7BB0 +CONFIG_BANK_3=0xFFC0 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_PCI is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_SUSPEND_UP_POSSIBLE=y +# CONFIG_PM_BFIN_SLEEP_DEEPER is not set +# CONFIG_PM_BFIN_SLEEP is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=m +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_UCLINUX is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_BFIN_MAC=y +CONFIG_BFIN_MAC_USE_L1=y +CONFIG_BFIN_TX_DESC_NUM=10 +CONFIG_BFIN_RX_DESC_NUM=20 +CONFIG_BFIN_MAC_RMII=y +# CONFIG_SMC91X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_AD9960 is not set +# CONFIG_SPI_ADC_BF533 is not set +# CONFIG_BF5xx_PPIFCD is not set +# CONFIG_BFIN_SIMPLE_TIMER is not set +# CONFIG_BF5xx_PPI is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set +# CONFIG_BFIN_SPORT is not set +# CONFIG_BFIN_TIMER_LATENCY is not set +# CONFIG_TWI_LCD is not set +CONFIG_SIMPLE_GPIO=m +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_BFIN=y +CONFIG_SERIAL_BFIN_CONSOLE=y +CONFIG_SERIAL_BFIN_DMA=y +# CONFIG_SERIAL_BFIN_PIO is not set +CONFIG_SERIAL_BFIN_UART0=y +# CONFIG_BFIN_UART0_CTSRTS is not set +CONFIG_SERIAL_BFIN_UART1=y +# CONFIG_BFIN_UART1_CTSRTS is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_BFIN_SPORT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# CAN, the car bus and industrial fieldbus +# +# CONFIG_CAN4LINUX is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_BLACKFIN_TWI=m +CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_AD5252 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BITBANG is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_OTG_BLACKLIST_HUB=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# Blackfin high speed USB support +# +CONFIG_USB_MUSB_HOST=y +# CONFIG_USB_MUSB_PERIPHERAL is not set +# CONFIG_USB_MUSB_OTG is not set +CONFIG_USB_MUSB_HDRC_HCD=y +CONFIG_MUSB_PIO_ONLY=y +CONFIG_USB_MUSB_LOGLEVEL=0 + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_BFIN=y + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_YAFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set +# CONFIG_INSTRUMENTATION is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set +CONFIG_DEBUG_MMRS=y +CONFIG_DEBUG_HUNT_FOR_ZERO=y +CONFIG_DEBUG_BFIN_HWTRACE_ON=y +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 +# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set +# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_CPLB_INFO is not set +CONFIG_ACCESS_CHECK=y + +# +# Security options +# +# CONFIG_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/blackfin/mach-bf527/boards/Kconfig b/arch/blackfin/mach-bf527/boards/Kconfig index 6a570ad03746..8bf9e58f0148 100644 --- a/arch/blackfin/mach-bf527/boards/Kconfig +++ b/arch/blackfin/mach-bf527/boards/Kconfig @@ -9,4 +9,9 @@ config BFIN527_EZKIT help BF527-EZKIT-LITE board support. +config BFIN527_BLUETECHNIX_CM + bool "Bluetechnix CM-BF527" + help + CM-BF527 support for EVAL- and DEV-Board. + endchoice diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile index 7277d35ef111..7ba7d256bbb8 100644 --- a/arch/blackfin/mach-bf527/boards/Makefile +++ b/arch/blackfin/mach-bf527/boards/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_BFIN527_EZKIT) += ezkit.o +obj-$(CONFIG_BFIN527_BLUETECHNIX_CM) += cm_bf527.o diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c new file mode 100644 index 000000000000..0b26ae2de5ee --- /dev/null +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -0,0 +1,1011 @@ +/* + * File: arch/blackfin/mach-bf527/boards/cm-bf527.c + * Based on: arch/blackfin/mach-bf537/boards/stamp.c + * Author: Aidan Williams + * + * Created: + * Description: + * + * Modified: + * Copyright 2005 National ICT Australia (NICTA) + * Copyright 2004-2008 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +#include +#endif +#include +#include +#include +#include +#include +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +const char bfin_board_name[] = "Bluetechnix CM-BF527"; + +/* + * Driver needs to know address, irq and flag pin. + */ + +#define ISP1761_BASE 0x203C0000 +#define ISP1761_IRQ IRQ_PF7 + +#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) +static struct resource bfin_isp1761_resources[] = { + [0] = { + .name = "isp1761-regs", + .start = ISP1761_BASE + 0x00000000, + .end = ISP1761_BASE + 0x000fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ISP1761_IRQ, + .end = ISP1761_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_isp1761_device = { + .name = "isp1761", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_isp1761_resources), + .resource = bfin_isp1761_resources, +}; + +static struct platform_device *bfin_isp1761_devices[] = { + &bfin_isp1761_device, +}; + +int __init bfin_isp1761_init(void) +{ + unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices); + + printk(KERN_INFO "%s(): registering device resources\n", __func__); + set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING); + + return platform_add_devices(bfin_isp1761_devices, num_devices); +} + +void __exit bfin_isp1761_exit(void) +{ + platform_device_unregister(&bfin_isp1761_device); +} + +arch_initcall(bfin_isp1761_init); +#endif + +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) +static struct resource musb_resources[] = { + [0] = { + .start = 0xffc03800, + .end = 0xffc03cff, + .flags = IORESOURCE_MEM, + }, + [1] = { /* general IRQ */ + .start = IRQ_USB_INT0, + .end = IRQ_USB_INT0, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, + [2] = { /* DMA IRQ */ + .start = IRQ_USB_DMA, + .end = IRQ_USB_DMA, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct musb_hdrc_platform_data musb_plat = { +#if defined(CONFIG_USB_MUSB_OTG) + .mode = MUSB_OTG, +#elif defined(CONFIG_USB_MUSB_HDRC_HCD) + .mode = MUSB_HOST, +#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) + .mode = MUSB_PERIPHERAL, +#endif + .multipoint = 0, +}; + +static u64 musb_dmamask = ~(u32)0; + +static struct platform_device musb_device = { + .name = "musb_hdrc", + .id = 0, + .dev = { + .dma_mask = &musb_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &musb_plat, + }, + .num_resources = ARRAY_SIZE(musb_resources), + .resource = musb_resources, +}; +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition ezkit_partitions[] = { + { + .name = "Bootloader", + .size = 0x40000, + .offset = 0, + }, { + .name = "Kernel", + .size = 0x1C0000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "RootFS", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data ezkit_flash_data = { + .width = 2, + .parts = ezkit_partitions, + .nr_parts = ARRAY_SIZE(ezkit_partitions), +}; + +static struct resource ezkit_flash_resource = { + .start = 0x20000000, + .end = 0x201fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ezkit_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ezkit_flash_data, + }, + .num_resources = 1, + .resource = &ezkit_flash_resource, +}; +#endif + +#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) +static struct mtd_partition partition_info[] = { + { + .name = "Linux Kernel", + .offset = 0, + .size = 4 * SIZE_1M, + }, + { + .name = "File System", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct bf5xx_nand_platform bf5xx_nand_platform = { + .page_size = NFC_PG_SIZE_256, + .data_width = NFC_NWIDTH_8, + .partitions = partition_info, + .nr_partitions = ARRAY_SIZE(partition_info), + .rd_dly = 3, + .wr_dly = 3, +}; + +static struct resource bf5xx_nand_resources[] = { + { + .start = NFC_CTL, + .end = NFC_DATA_RD + 2, + .flags = IORESOURCE_MEM, + }, + { + .start = CH_NFC, + .end = CH_NFC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bf5xx_nand_device = { + .name = "bf5xx-nand", + .id = 0, + .num_resources = ARRAY_SIZE(bf5xx_nand_resources), + .resource = bf5xx_nand_resources, + .dev = { + .platform_data = &bf5xx_nand_platform, + }, +}; +#endif + +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) +static struct resource bfin_pcmcia_cf_resources[] = { + { + .start = 0x20310000, /* IO PORT */ + .end = 0x20312000, + .flags = IORESOURCE_MEM, + }, { + .start = 0x20311000, /* Attribute Memory */ + .end = 0x20311FFF, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PF4, + .end = IRQ_PF4, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, { + .start = 6, /* Card Detect PF6 */ + .end = 6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pcmcia_cf_device = { + .name = "bfin_cf_pcmcia", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), + .resource = bfin_pcmcia_cf_resources, +}; +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) +static struct resource smc91x_resources[] = { + { + .name = "smc91x-regs", + .start = 0x20300300, + .end = 0x20300300 + 16, + .flags = IORESOURCE_MEM, + }, { + + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; +#endif + +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) +static struct resource dm9000_resources[] = { + [0] = { + .start = 0x203FB800, + .end = 0x203FB800 + 8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PF9, + .end = IRQ_PF9, + .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), + }, +}; + +static struct platform_device dm9000_device = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(dm9000_resources), + .resource = dm9000_resources, +}; +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) +static struct resource sl811_hcd_resources[] = { + { + .start = 0x20340000, + .end = 0x20340000, + .flags = IORESOURCE_MEM, + }, { + .start = 0x20340004, + .end = 0x20340004, + .flags = IORESOURCE_MEM, + }, { + .start = CONFIG_USB_SL811_BFIN_IRQ, + .end = CONFIG_USB_SL811_BFIN_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) +void sl811_port_power(struct device *dev, int is_on) +{ + gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); + gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); +} +#endif + +static struct sl811_platform_data sl811_priv = { + .potpg = 10, + .power = 250, /* == 500mA */ +#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) + .port_power = &sl811_port_power, +#endif +}; + +static struct platform_device sl811_hcd_device = { + .name = "sl811-hcd", + .id = 0, + .dev = { + .platform_data = &sl811_priv, + }, + .num_resources = ARRAY_SIZE(sl811_hcd_resources), + .resource = sl811_hcd_resources, +}; +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) +static struct resource isp1362_hcd_resources[] = { + { + .start = 0x20360000, + .end = 0x20360000, + .flags = IORESOURCE_MEM, + }, { + .start = 0x20360004, + .end = 0x20360004, + .flags = IORESOURCE_MEM, + }, { + .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, + .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct isp1362_platform_data isp1362_priv = { + .sel15Kres = 1, + .clknotstop = 0, + .oc_enable = 0, + .int_act_high = 0, + .int_edge_triggered = 0, + .remote_wakeup_connected = 0, + .no_power_switching = 1, + .power_switching_mode = 0, +}; + +static struct platform_device isp1362_hcd_device = { + .name = "isp1362-hcd", + .id = 0, + .dev = { + .platform_data = &isp1362_priv, + }, + .num_resources = ARRAY_SIZE(isp1362_hcd_resources), + .resource = isp1362_hcd_resources, +}; +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +}; +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) +static struct resource net2272_bfin_resources[] = { + { + .start = 0x20300000, + .end = 0x20300000 + 0x100, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PF7, + .end = IRQ_PF7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct platform_device net2272_bfin_device = { + .name = "net2272", + .id = -1, + .num_resources = ARRAY_SIZE(net2272_bfin_resources), + .resource = net2272_bfin_resources, +}; +#endif + +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + }, { + .name = "linux kernel", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p16", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_SPI_ADC_BF533) \ + || defined(CONFIG_SPI_ADC_BF533_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +static struct bfin5xx_spi_chip ad1836_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) +static struct bfin5xx_spi_chip ad9960_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) +static struct bfin5xx_spi_chip spi_mmc_chip_info = { + .enable_dma = 1, + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_PBX) +static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { + .ctl_reg = 0x4, /* send zero */ + .enable_dma = 0, + .bits_per_word = 8, + .cs_change_per_word = 1, +}; +#endif + +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) +static struct bfin5xx_spi_chip spi_ad7877_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; + +static const struct ad7877_platform_data bfin_ad7877_ts_info = { + .model = 7877, + .vref_delay_usecs = 50, /* internal, no capacitor */ + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .pressure_max = 1000, + .pressure_min = 0, + .stopacq_polarity = 1, + .first_conversion_delay = 3, + .acquisition_time = 1, + .averaging = 1, + .pen_down_acc_interval = 1, +}; +#endif + +#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ + && defined(CONFIG_SND_SOC_WM8731_SPI) +static struct bfin5xx_spi_chip spi_wm8731_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) +static struct bfin5xx_spi_chip spidev_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_SPI_ADC_BF533) \ + || defined(CONFIG_SPI_ADC_BF533_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_SND_BLACKFIN_AD1836) \ + || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) + { + .modalias = "ad1836-spi", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, + .controller_data = &ad1836_spi_chip_info, + }, +#endif +#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) + { + .modalias = "ad9960-spi", + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 1, + .controller_data = &ad9960_spi_chip_info, + }, +#endif +#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { + .modalias = "spi_mmc_dummy", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 0, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = CONFIG_SPI_MMC_CS_CHAN, + .platform_data = NULL, + .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_PBX) + { + .modalias = "fxs-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 8 - CONFIG_J11_JUMPER, + .controller_data = &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, + { + .modalias = "fxo-spi", + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 8 - CONFIG_J19_JUMPER, + .controller_data = &spi_si3xxx_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) + { + .modalias = "ad7877", + .platform_data = &bfin_ad7877_ts_info, + .irq = IRQ_PF8, + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 2, + .controller_data = &spi_ad7877_chip_info, + }, +#endif +#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ + && defined(CONFIG_SND_SOC_WM8731_SPI) + { + .modalias = "wm8731", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 5, + .controller_data = &spi_wm8731_chip_info, + .mode = SPI_MODE_0, + }, +#endif +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + { + .modalias = "spidev", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 1, + .controller_data = &spidev_chip_info, + }, +#endif +}; + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* SPI controller data */ +static struct bfin5xx_spi_master bfin_spi0_info = { + .num_chipselect = 8, + .enable_dma = 1, /* master has the ability to do dma transfer */ + .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, +}; + +/* SPI (0) */ +static struct resource bfin_spi0_resource[] = { + [0] = { + .start = SPI0_REGBASE, + .end = SPI0_REGBASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CH_SPI, + .end = CH_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_spi0_device = { + .name = "bfin-spi", + .id = 0, /* Bus number */ + .num_resources = ARRAY_SIZE(bfin_spi0_resource), + .resource = bfin_spi0_resource, + .dev = { + .platform_data = &bfin_spi0_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) +static struct platform_device bfin_fb_adv7393_device = { + .name = "bfin-adv7393", +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + { + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, +#endif +}; + +static struct platform_device bfin_uart_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart_resources), + .resource = bfin_uart_resources, +}; +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) +static struct resource bfin_sir_resources[] = { +#ifdef CONFIG_BFIN_SIR0 + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, +#endif +#ifdef CONFIG_BFIN_SIR1 + { + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, +#endif +}; + +static struct platform_device bfin_sir_device = { + .name = "bfin_sir", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sir_resources), + .resource = bfin_sir_resources, +}; +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static struct resource bfin_twi0_resource[] = { + [0] = { + .start = TWI0_REGBASE, + .end = TWI0_REGBASE, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TWI, + .end = IRQ_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device i2c_bfin_twi_device = { + .name = "i2c-bfin-twi", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_twi0_resource), + .resource = bfin_twi0_resource, +}; +#endif + +#ifdef CONFIG_I2C_BOARDINFO +static struct i2c_board_info __initdata bfin_i2c_board_info[] = { +#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) + { + I2C_BOARD_INFO("pcf8574_lcd", 0x22), + .type = "pcf8574_lcd", + }, +#endif +#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE) + { + I2C_BOARD_INFO("pcf8574_keypad", 0x27), + .type = "pcf8574_keypad", + .irq = IRQ_PF8, + }, +#endif +}; +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, +}; +#endif + +#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) +#define PATA_INT 55 + +static struct pata_platform_info bfin_pata_platform_data = { + .ioport_shift = 1, + .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED, +}; + +static struct resource bfin_pata_resources[] = { + { + .start = 0x20314020, + .end = 0x2031403F, + .flags = IORESOURCE_MEM, + }, + { + .start = 0x2031401C, + .end = 0x2031401F, + .flags = IORESOURCE_MEM, + }, + { + .start = PATA_INT, + .end = PATA_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_pata_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_pata_resources), + .resource = bfin_pata_resources, + .dev = { + .platform_data = &bfin_pata_platform_data, + } +}; +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +#include +#include + +static struct gpio_keys_button bfin_gpio_keys_table[] = { + {BTN_0, GPIO_PF14, 1, "gpio-keys: BTN0"}, +}; + +static struct gpio_keys_platform_data bfin_gpio_keys_data = { + .buttons = bfin_gpio_keys_table, + .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), +}; + +static struct platform_device bfin_device_gpiokeys = { + .name = "gpio-keys", + .dev = { + .platform_data = &bfin_gpio_keys_data, + }, +}; +#endif + +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_100, 400000000), + VRPAIR(VLEV_105, 426000000), + VRPAIR(VLEV_110, 500000000), + VRPAIR(VLEV_115, 533000000), + VRPAIR(VLEV_120, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + +static struct platform_device *stamp_devices[] __initdata = { + + &bfin_dpmc, + +#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) + &bf5xx_nand_device, +#endif + +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) + &bfin_pcmcia_cf_device, +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) + &sl811_hcd_device, +#endif + +#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) + &isp1362_hcd_device, +#endif + +#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) + &musb_device, +#endif + +#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) + &smc91x_device, +#endif + +#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) + &dm9000_device, +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + &bfin_mac_device, +#endif + +#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) + &net2272_bfin_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &bfin_spi0_device, +#endif + +#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) + &bfin_fb_adv7393_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) + &bfin_sir_device, +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) + &i2c_bfin_twi_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + &bfin_sport0_uart_device, + &bfin_sport1_uart_device, +#endif + +#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) + &bfin_pata_device, +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + &bfin_device_gpiokeys, +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + &ezkit_flash_device, +#endif + + &bfin_gpios_device, +}; + +static int __init stamp_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __func__); + +#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); +#endif + + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); + +#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) + irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; +#endif + return 0; +} + +arch_initcall(stamp_init); + +void native_machine_restart(char *cmd) +{ + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) + bfin_gpio_reset_spi0_ssel1(); +} + +void bfin_get_ether_addr(char *addr) +{ + random_ether_addr(addr); + printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); +} +EXPORT_SYMBOL(bfin_get_ether_addr); From 04e1e0cccade330ab3715ce59234f7e3b087e246 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 22 Jul 2008 13:04:18 +0000 Subject: [PATCH 027/179] [CIFS] Fix compiler warning on 64-bit Signed-off-by: Steve French --- fs/cifs/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index f58e41d3ba48..42765465701c 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c @@ -400,7 +400,7 @@ asn1_oid_decode(struct asn1_ctx *ctx, size = eoc - ctx->pointer + 1; /* first subid actually encodes first two subids */ - if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) + if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) return 0; *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); From 09e50d55a9490e9b7a6fdfbf8fc078924b25ecb5 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 23 Jul 2008 10:11:19 -0400 Subject: [PATCH 028/179] lockdep: annotate cifs in-kernel sockets Put CIFS sockets in their own class to avoid some lockdep warnings. CIFS sockets are not exposed to user-space, and so are not subject to the same deadlock scenarios. A similar change was made a couple of years ago for RPC sockets in commit ed07536ed6731775219c1df7fa26a7588753e693. This patch should prevent lockdep false-positives like this one: ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.18-98.el5.jtltest.38.bz456320.1debug #1 ------------------------------------------------------- test5/2483 is trying to acquire lock: (sk_lock-AF_INET){--..}, at: [] tcp_sendmsg+0x1c/0xb2f but task is already holding lock: (&inode->i_alloc_sem){--..}, at: [] notify_change+0xf5/0x2e0 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #3 (&inode->i_alloc_sem){--..}: [] __lock_acquire+0x9a9/0xadf [] lock_acquire+0x55/0x70 [] notify_change+0xf5/0x2e0 [] down_write+0x3c/0x68 [] notify_change+0xf5/0x2e0 [] do_truncate+0x50/0x6b [] get_write_access+0x40/0x46 [] may_open+0x1d3/0x22e [] open_namei+0x2c6/0x6dd [] do_filp_open+0x1c/0x38 [] _spin_unlock+0x17/0x20 [] get_unused_fd+0xf9/0x107 [] do_sys_open+0x44/0xbe [] system_call+0x7e/0x83 [] 0xffffffffffffffff -> #2 (&sysfs_inode_imutex_key){--..}: [] __lock_acquire+0x9a9/0xadf [] create_dir+0x26/0x1d7 [] lock_acquire+0x55/0x70 [] create_dir+0x26/0x1d7 [] mutex_lock_nested+0x104/0x29c [] __lock_acquire+0x9ca/0xadf [] create_dir+0x26/0x1d7 [] sysfs_create_dir+0x58/0x76 [] kobject_add+0xdb/0x198 [] class_device_add+0xb2/0x465 [] kobject_get+0x12/0x17 [] register_netdevice+0x270/0x33e [] register_netdev+0x59/0x67 [] net_olddevs_init+0xb/0xac [] init+0x1f9/0x2fc [] _spin_unlock_irq+0x24/0x27 [] trace_hardirqs_on_thunk+0x35/0x37 [] child_rip+0xa/0x11 [] _spin_unlock_irq+0x24/0x27 [] restore_args+0x0/0x30 [] acpi_ds_init_one_object+0x0/0x80 [] init+0x0/0x2fc [] child_rip+0x0/0x11 [] 0xffffffffffffffff -> #1 (rtnl_mutex){--..}: [] __lock_acquire+0x9a9/0xadf [] ip_mc_leave_group+0x23/0xb7 [] lock_acquire+0x55/0x70 [] ip_mc_leave_group+0x23/0xb7 [] mutex_lock_nested+0x104/0x29c [] ip_mc_leave_group+0x23/0xb7 [] do_ip_setsockopt+0x6d1/0x9bf [] lock_release_holdtime+0x27/0x48 [] lock_release_holdtime+0x27/0x48 [] do_page_fault+0x503/0x835 [] socket_has_perm+0x5b/0x68 [] ip_setsockopt+0x22/0x78 [] sys_setsockopt+0x91/0xb7 [] tracesys+0xd5/0xdf [] 0xffffffffffffffff -> #0 (sk_lock-AF_INET){--..}: [] print_stack_trace+0x59/0x68 [] __lock_acquire+0x8bf/0xadf [] lock_acquire+0x55/0x70 [] tcp_sendmsg+0x1c/0xb2f [] lock_sock+0xd4/0xe4 [] _local_bh_enable+0xcb/0xe0 [] restore_args+0x0/0x30 [] tcp_sendmsg+0x1c/0xb2f [] sock_sendmsg+0xf3/0x110 [] autoremove_wake_function+0x0/0x2e [] kernel_text_address+0x1a/0x26 [] dump_trace+0x211/0x23a [] find_usage_backwards+0x5f/0x88 [] MD5Final+0xaf/0xc2 [cifs] [] cifs_calculate_signature+0x55/0x69 [cifs] [] kernel_sendmsg+0x35/0x47 [] smb_send+0xa3/0x151 [cifs] [] SendReceive+0x1a2/0x448 [cifs] [] __lock_acquire+0x95c/0xadf [] CIFSSMBSetEOF+0x20d/0x25b [cifs] [] cifs_set_file_size+0x110/0x3b7 [cifs] [] cifs_setattr+0x3b2/0x6f6 [cifs] [] notify_change+0xf5/0x2e0 [] notify_change+0x145/0x2e0 [] do_truncate+0x50/0x6b [] get_write_access+0x40/0x46 [] may_open+0x1d3/0x22e [] open_namei+0x2c6/0x6dd [] do_filp_open+0x1c/0x38 [] _spin_unlock+0x17/0x20 [] get_unused_fd+0xf9/0x107 [] do_sys_open+0x44/0xbe [] tracesys+0xd5/0xdf [] 0xffffffffffffffff other info that might help us debug this: 2 locks held by test5/2483: #0: (&inode->i_mutex){--..}, at: [] do_truncate+0x45/0x6b #1: (&inode->i_alloc_sem){--..}, at: [] notify_change+0xf5/0x2e0 stack backtrace: Call Trace: [] print_circular_bug_tail+0x65/0x6e [] print_stack_trace+0x59/0x68 [] __lock_acquire+0x8bf/0xadf [] lock_acquire+0x55/0x70 [] tcp_sendmsg+0x1c/0xb2f [] lock_sock+0xd4/0xe4 [] _local_bh_enable+0xcb/0xe0 [] restore_args+0x0/0x30 [] tcp_sendmsg+0x1c/0xb2f [] sock_sendmsg+0xf3/0x110 [] autoremove_wake_function+0x0/0x2e [] kernel_text_address+0x1a/0x26 [] dump_trace+0x211/0x23a [] find_usage_backwards+0x5f/0x88 [] :cifs:MD5Final+0xaf/0xc2 [] :cifs:cifs_calculate_signature+0x55/0x69 [] kernel_sendmsg+0x35/0x47 [] :cifs:smb_send+0xa3/0x151 [] :cifs:SendReceive+0x1a2/0x448 [] __lock_acquire+0x95c/0xadf [] :cifs:CIFSSMBSetEOF+0x20d/0x25b [] :cifs:cifs_set_file_size+0x110/0x3b7 [] :cifs:cifs_setattr+0x3b2/0x6f6 [] notify_change+0xf5/0x2e0 [] notify_change+0x145/0x2e0 [] do_truncate+0x50/0x6b [] get_write_access+0x40/0x46 [] may_open+0x1d3/0x22e [] open_namei+0x2c6/0x6dd [] do_filp_open+0x1c/0x38 [] _spin_unlock+0x17/0x20 [] get_unused_fd+0xf9/0x107 [] do_sys_open+0x44/0xbe [] tracesys+0xd5/0xdf Signed-off-by: Jeff Layton Acked-by: Peter Zijlstra Signed-off-by: Steve French --- fs/cifs/connect.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e8fa46c7cff2..644462729387 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1461,6 +1461,39 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, return rc; } +#ifdef CONFIG_DEBUG_LOCK_ALLOC +static struct lock_class_key cifs_key[2]; +static struct lock_class_key cifs_slock_key[2]; + +static inline void +cifs_reclassify_socket4(struct socket *sock) +{ + struct sock *sk = sock->sk; + BUG_ON(sock_owned_by_user(sk)); + sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS", + &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]); +} + +static inline void +cifs_reclassify_socket6(struct socket *sock) +{ + struct sock *sk = sock->sk; + BUG_ON(sock_owned_by_user(sk)); + sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS", + &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]); +} +#else +static inline void +cifs_reclassify_socket4(struct socket *sock) +{ +} + +static inline void +cifs_reclassify_socket6(struct socket *sock) +{ +} +#endif + /* See RFC1001 section 14 on representation of Netbios names */ static void rfc1002mangle(char *target, char *source, unsigned int length) { @@ -1495,6 +1528,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, /* BB other socket options to set KEEPALIVE, NODELAY? */ cFYI(1, ("Socket created")); (*csocket)->sk->sk_allocation = GFP_NOFS; + cifs_reclassify_socket4(*csocket); } } @@ -1627,6 +1661,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) /* BB other socket options to set KEEPALIVE, NODELAY? */ cFYI(1, ("ipv6 Socket created")); (*csocket)->sk->sk_allocation = GFP_NOFS; + cifs_reclassify_socket6(*csocket); } } From 8efdbde647f542ce0d303273df7ad4157caa03d0 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 23 Jul 2008 21:28:12 +0000 Subject: [PATCH 029/179] [CIFS] break ATTR_SIZE changes out into their own function Move the code that handles ATTR_SIZE changes to its own function. This makes for a smaller function and reduces the level of indentation. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/inode.c | 151 +++++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 73 deletions(-) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 2e904bd111c8..46e54d39461d 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1413,6 +1413,82 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset) return -ETXTBSY; } +static int +cifs_set_file_size(struct inode *inode, struct iattr *attrs, + int xid, char *full_path) +{ + int rc; + struct cifsFileInfo *open_file; + struct cifsInodeInfo *cifsInode = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifsTconInfo *pTcon = cifs_sb->tcon; + + /* + * To avoid spurious oplock breaks from server, in the case of + * inodes that we already have open, avoid doing path based + * setting of file size if we can do it by handle. + * This keeps our caching token (oplock) and avoids timeouts + * when the local oplock break takes longer to flush + * writebehind data than the SMB timeout for the SetPathInfo + * request would allow + */ + open_file = find_writable_file(cifsInode); + if (open_file) { + __u16 nfid = open_file->netfid; + __u32 npid = open_file->pid; + rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, + npid, false); + atomic_dec(&open_file->wrtPending); + cFYI(1, ("SetFSize for attrs rc = %d", rc)); + if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { + unsigned int bytes_written; + rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size, + &bytes_written, NULL, NULL, 1); + cFYI(1, ("Wrt seteof rc %d", rc)); + } + } else + rc = -EINVAL; + + if (rc != 0) { + /* Set file size by pathname rather than by handle + either because no valid, writeable file handle for + it was found or because there was an error setting + it by handle */ + rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, + false, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); + if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { + __u16 netfid; + int oplock = 0; + + rc = SMBLegacyOpen(xid, pTcon, full_path, + FILE_OPEN, GENERIC_WRITE, + CREATE_NOT_DIR, &netfid, &oplock, NULL, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc == 0) { + unsigned int bytes_written; + rc = CIFSSMBWrite(xid, pTcon, netfid, 0, + attrs->ia_size, + &bytes_written, NULL, + NULL, 1); + cFYI(1, ("wrt seteof rc %d", rc)); + CIFSSMBClose(xid, pTcon, netfid); + } + } + } + + if (rc == 0) { + rc = cifs_vmtruncate(inode, attrs->ia_size); + cifs_truncate_page(inode->i_mapping, inode->i_size); + } + + return rc; +} + int cifs_setattr(struct dentry *direntry, struct iattr *attrs) { int xid; @@ -1420,7 +1496,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) struct cifsTconInfo *pTcon; char *full_path = NULL; int rc = -EACCES; - struct cifsFileInfo *open_file = NULL; FILE_BASIC_INFO time_buf; bool set_time = false; bool set_dosattr = false; @@ -1472,78 +1547,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) } if (attrs->ia_valid & ATTR_SIZE) { - /* To avoid spurious oplock breaks from server, in the case of - inodes that we already have open, avoid doing path based - setting of file size if we can do it by handle. - This keeps our caching token (oplock) and avoids timeouts - when the local oplock break takes longer to flush - writebehind data than the SMB timeout for the SetPathInfo - request would allow */ - - open_file = find_writable_file(cifsInode); - if (open_file) { - __u16 nfid = open_file->netfid; - __u32 npid = open_file->pid; - rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, - nfid, npid, false); - atomic_dec(&open_file->wrtPending); - cFYI(1, ("SetFSize for attrs rc = %d", rc)); - if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { - unsigned int bytes_written; - rc = CIFSSMBWrite(xid, pTcon, - nfid, 0, attrs->ia_size, - &bytes_written, NULL, NULL, - 1 /* 45 seconds */); - cFYI(1, ("Wrt seteof rc %d", rc)); - } - } else - rc = -EINVAL; - - if (rc != 0) { - /* Set file size by pathname rather than by handle - either because no valid, writeable file handle for - it was found or because there was an error setting - it by handle */ - rc = CIFSSMBSetEOF(xid, pTcon, full_path, - attrs->ia_size, false, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); - if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { - __u16 netfid; - int oplock = 0; - - rc = SMBLegacyOpen(xid, pTcon, full_path, - FILE_OPEN, GENERIC_WRITE, - CREATE_NOT_DIR, &netfid, &oplock, - NULL, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc == 0) { - unsigned int bytes_written; - rc = CIFSSMBWrite(xid, pTcon, - netfid, 0, - attrs->ia_size, - &bytes_written, NULL, - NULL, 1 /* 45 sec */); - cFYI(1, ("wrt seteof rc %d", rc)); - CIFSSMBClose(xid, pTcon, netfid); - } - - } - } - - /* Server is ok setting allocation size implicitly - no need - to call: - CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true, - cifs_sb->local_nls); - */ - - if (rc == 0) { - rc = cifs_vmtruncate(inode, attrs->ia_size); - cifs_truncate_page(inode->i_mapping, inode->i_size); - } else + rc = cifs_set_file_size(inode, attrs, xid, full_path); + if (rc != 0) goto cifs_setattr_exit; } From 5ca33c6ac30596fc1403a092f46ea48c406734e4 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 23 Jul 2008 17:45:58 -0700 Subject: [PATCH 030/179] cifs: assorted endian annotations fs/cifs/cifssmb.c:3917:13: warning: incorrect type in assignment (different base types) fs/cifs/cifssmb.c:3917:13: expected bool [unsigned] [usertype] is_unicode fs/cifs/cifssmb.c:3917:13: got restricted __le16 The comment explains why __force is used here. fs/cifs/connect.c:458:16: warning: cast to restricted __be32 fs/cifs/connect.c:458:16: warning: cast to restricted __be32 fs/cifs/connect.c:458:16: warning: cast to restricted __be32 fs/cifs/connect.c:458:16: warning: cast to restricted __be32 fs/cifs/connect.c:458:16: warning: cast to restricted __be32 fs/cifs/connect.c:458:16: warning: cast to restricted __be32 Signed-off-by: Harvey Harrison Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 5 ++++- fs/cifs/connect.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 4511b708f0f3..7e175e1399d1 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3914,7 +3914,10 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, bool is_unicode; struct dfs_referral_level_3 *ref; - is_unicode = pSMBr->hdr.Flags2 & SMBFLG2_UNICODE; + if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) + is_unicode = true; + else + is_unicode = false; *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals); if (*num_of_nodes < 1) { diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 644462729387..b51d5777cde6 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -455,7 +455,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) /* Note that FC 1001 length is big endian on the wire, but we convert it here so it is always manipulated as host byte order */ - pdu_length = ntohl(smb_buffer->smb_buf_length); + pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length); smb_buffer->smb_buf_length = pdu_length; cFYI(1, ("rfc1002 length 0x%x", pdu_length+4)); From f984c7b98253c541ed6e702ee521f6a84c8113d4 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 24 Jul 2008 02:34:24 +0000 Subject: [PATCH 031/179] Signed-off-by: Alexey Dobriyan Cc: Steven French Signed-off-by: Andrew Morton Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 658 +++++++++++++++++-------------------------- 1 file changed, 252 insertions(+), 406 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index cc950f69e51e..73925a77375e 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -107,9 +107,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server) #endif /* CONFIG_CIFS_DEBUG2 */ #ifdef CONFIG_PROC_FS -static int -cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, - int count, int *eof, void *data) +static int cifs_debug_data_proc_show(struct seq_file *m, void *v) { struct list_head *tmp; struct list_head *tmp1; @@ -117,23 +115,13 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, struct cifsSesInfo *ses; struct cifsTconInfo *tcon; int i; - int length = 0; - char *original_buf = buf; - *beginBuffer = buf + offset; - - length = - sprintf(buf, + seq_puts(m, "Display Internal CIFS Data Structures for Debugging\n" "---------------------------------------------------\n"); - buf += length; - length = sprintf(buf, "CIFS Version %s\n", CIFS_VERSION); - buf += length; - length = sprintf(buf, - "Active VFS Requests: %d\n", GlobalTotalActiveXid); - buf += length; - length = sprintf(buf, "Servers:"); - buf += length; + seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); + seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); + seq_printf(m, "Servers:"); i = 0; read_lock(&GlobalSMBSeslock); @@ -142,11 +130,10 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) || (ses->serverNOS == NULL)) { - buf += sprintf(buf, "\nentry for %s not fully " + seq_printf(m, "\nentry for %s not fully " "displayed\n\t", ses->serverName); } else { - length = - sprintf(buf, + seq_printf(m, "\n%d) Name: %s Domain: %s Mounts: %d OS:" " %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB" " session status: %d\t", @@ -154,10 +141,9 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, atomic_read(&ses->inUse), ses->serverOS, ses->serverNOS, ses->capabilities, ses->status); - buf += length; } if (ses->server) { - buf += sprintf(buf, "TCP status: %d\n\tLocal Users To " + seq_printf(m, "TCP status: %d\n\tLocal Users To " "Server: %d SecMode: 0x%x Req On Wire: %d", ses->server->tcpStatus, atomic_read(&ses->server->socketUseCount), @@ -165,13 +151,12 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, atomic_read(&ses->server->inFlight)); #ifdef CONFIG_CIFS_STATS2 - buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d", + seq_printf(m, " In Send: %d In MaxReq Wait: %d", atomic_read(&ses->server->inSend), atomic_read(&ses->server->num_waiters)); #endif - length = sprintf(buf, "\nMIDs:\n"); - buf += length; + seq_puts(m, "\nMIDs:\n"); spin_lock(&GlobalMid_Lock); list_for_each(tmp1, &ses->server->pending_mid_q) { @@ -179,7 +164,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, mid_q_entry, qhead); if (mid_entry) { - length = sprintf(buf, + seq_printf(m, "State: %d com: %d pid:" " %d tsk: %p mid %d\n", mid_entry->midState, @@ -187,7 +172,6 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, mid_entry->pid, mid_entry->tsk, mid_entry->mid); - buf += length; } } spin_unlock(&GlobalMid_Lock); @@ -195,11 +179,9 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, } read_unlock(&GlobalSMBSeslock); - sprintf(buf, "\n"); - buf++; + seq_putc(m, '\n'); - length = sprintf(buf, "Shares:"); - buf += length; + seq_puts(m, "Shares:"); i = 0; read_lock(&GlobalSMBSeslock); @@ -208,62 +190,52 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, i++; tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); - length = sprintf(buf, "\n%d) %s Uses: %d ", i, + seq_printf(m, "\n%d) %s Uses: %d ", i, tcon->treeName, atomic_read(&tcon->useCount)); - buf += length; if (tcon->nativeFileSystem) { - length = sprintf(buf, "Type: %s ", + seq_printf(m, "Type: %s ", tcon->nativeFileSystem); - buf += length; } - length = sprintf(buf, "DevInfo: 0x%x Attributes: 0x%x" + seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x" "\nPathComponentMax: %d Status: %d", le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), le32_to_cpu(tcon->fsAttrInfo.Attributes), le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), tcon->tidStatus); - buf += length; if (dev_type == FILE_DEVICE_DISK) - length = sprintf(buf, " type: DISK "); + seq_puts(m, " type: DISK "); else if (dev_type == FILE_DEVICE_CD_ROM) - length = sprintf(buf, " type: CDROM "); + seq_puts(m, " type: CDROM "); else - length = - sprintf(buf, " type: %d ", dev_type); - buf += length; + seq_printf(m, " type: %d ", dev_type); if (tcon->tidStatus == CifsNeedReconnect) { - buf += sprintf(buf, "\tDISCONNECTED "); - length += 14; + seq_puts(m, "\tDISCONNECTED "); } } read_unlock(&GlobalSMBSeslock); - length = sprintf(buf, "\n"); - buf += length; + seq_putc(m, '\n'); /* BB add code to dump additional info such as TCP session info now */ - /* Now calculate total size of returned data */ - length = buf - original_buf; - - if (offset + count >= length) - *eof = 1; - if (length < offset) { - *eof = 1; - return 0; - } else { - length = length - offset; - } - if (length > count) - length = count; - - return length; + return 0; } -#ifdef CONFIG_CIFS_STATS +static int cifs_debug_data_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_debug_data_proc_show, NULL); +} -static int -cifs_stats_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static const struct file_operations cifs_debug_data_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_debug_data_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +#ifdef CONFIG_CIFS_STATS +static ssize_t cifs_stats_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { char c; int rc; @@ -307,236 +279,127 @@ cifs_stats_write(struct file *file, const char __user *buffer, return count; } -static int -cifs_stats_read(char *buf, char **beginBuffer, off_t offset, - int count, int *eof, void *data) +static int cifs_stats_proc_show(struct seq_file *m, void *v) { - int item_length, i, length; + int i; struct list_head *tmp; struct cifsTconInfo *tcon; - *beginBuffer = buf + offset; - - length = sprintf(buf, + seq_printf(m, "Resources in use\nCIFS Session: %d\n", sesInfoAllocCount.counter); - buf += length; - item_length = - sprintf(buf, "Share (unique mount targets): %d\n", + seq_printf(m, "Share (unique mount targets): %d\n", tconInfoAllocCount.counter); - length += item_length; - buf += item_length; - item_length = - sprintf(buf, "SMB Request/Response Buffer: %d Pool size: %d\n", + seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n", bufAllocCount.counter, cifs_min_rcv + tcpSesAllocCount.counter); - length += item_length; - buf += item_length; - item_length = - sprintf(buf, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", + seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", smBufAllocCount.counter, cifs_min_small); - length += item_length; - buf += item_length; #ifdef CONFIG_CIFS_STATS2 - item_length = sprintf(buf, "Total Large %d Small %d Allocations\n", + seq_printf(m, "Total Large %d Small %d Allocations\n", atomic_read(&totBufAllocCount), atomic_read(&totSmBufAllocCount)); - length += item_length; - buf += item_length; #endif /* CONFIG_CIFS_STATS2 */ - item_length = - sprintf(buf, "Operations (MIDs): %d\n", - midCount.counter); - length += item_length; - buf += item_length; - item_length = sprintf(buf, + seq_printf(m, "Operations (MIDs): %d\n", midCount.counter); + seq_printf(m, "\n%d session %d share reconnects\n", tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); - length += item_length; - buf += item_length; - item_length = sprintf(buf, + seq_printf(m, "Total vfs operations: %d maximum at one time: %d\n", GlobalCurrentXid, GlobalMaxActiveXid); - length += item_length; - buf += item_length; i = 0; read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { i++; tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - item_length = sprintf(buf, "\n%d) %s", i, tcon->treeName); - buf += item_length; - length += item_length; - if (tcon->tidStatus == CifsNeedReconnect) { - buf += sprintf(buf, "\tDISCONNECTED "); - length += 14; - } - item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d", + seq_printf(m, "\n%d) %s", i, tcon->treeName); + if (tcon->tidStatus == CifsNeedReconnect) + seq_puts(m, "\tDISCONNECTED "); + seq_printf(m, "\nSMBs: %d Oplock Breaks: %d", atomic_read(&tcon->num_smbs_sent), atomic_read(&tcon->num_oplock_brks)); - buf += item_length; - length += item_length; - item_length = sprintf(buf, "\nReads: %d Bytes: %lld", + seq_printf(m, "\nReads: %d Bytes: %lld", atomic_read(&tcon->num_reads), (long long)(tcon->bytes_read)); - buf += item_length; - length += item_length; - item_length = sprintf(buf, "\nWrites: %d Bytes: %lld", + seq_printf(m, "\nWrites: %d Bytes: %lld", atomic_read(&tcon->num_writes), (long long)(tcon->bytes_written)); - buf += item_length; - length += item_length; - item_length = sprintf(buf, + seq_printf(m, "\nLocks: %d HardLinks: %d Symlinks: %d", atomic_read(&tcon->num_locks), atomic_read(&tcon->num_hardlinks), atomic_read(&tcon->num_symlinks)); - buf += item_length; - length += item_length; - item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d", + seq_printf(m, "\nOpens: %d Closes: %d Deletes: %d", atomic_read(&tcon->num_opens), atomic_read(&tcon->num_closes), atomic_read(&tcon->num_deletes)); - buf += item_length; - length += item_length; - item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d", + seq_printf(m, "\nMkdirs: %d Rmdirs: %d", atomic_read(&tcon->num_mkdirs), atomic_read(&tcon->num_rmdirs)); - buf += item_length; - length += item_length; - item_length = sprintf(buf, "\nRenames: %d T2 Renames %d", + seq_printf(m, "\nRenames: %d T2 Renames %d", atomic_read(&tcon->num_renames), atomic_read(&tcon->num_t2renames)); - buf += item_length; - length += item_length; - item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d", + seq_printf(m, "\nFindFirst: %d FNext %d FClose %d", atomic_read(&tcon->num_ffirst), atomic_read(&tcon->num_fnext), atomic_read(&tcon->num_fclose)); - buf += item_length; - length += item_length; } read_unlock(&GlobalSMBSeslock); - buf += sprintf(buf, "\n"); - length++; - - if (offset + count >= length) - *eof = 1; - if (length < offset) { - *eof = 1; - return 0; - } else { - length = length - offset; - } - if (length > count) - length = count; - - return length; + seq_putc(m, '\n'); + return 0; } + +static int cifs_stats_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_stats_proc_show, NULL); +} + +static const struct file_operations cifs_stats_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_stats_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_stats_proc_write, +}; #endif /* STATS */ static struct proc_dir_entry *proc_fs_cifs; -read_proc_t cifs_txanchor_read; -static read_proc_t cifsFYI_read; -static write_proc_t cifsFYI_write; -static read_proc_t oplockEnabled_read; -static write_proc_t oplockEnabled_write; -static read_proc_t lookupFlag_read; -static write_proc_t lookupFlag_write; -static read_proc_t traceSMB_read; -static write_proc_t traceSMB_write; -static read_proc_t multiuser_mount_read; -static write_proc_t multiuser_mount_write; -static read_proc_t security_flags_read; -static write_proc_t security_flags_write; -/* static read_proc_t ntlmv2_enabled_read; -static write_proc_t ntlmv2_enabled_write; -static read_proc_t packet_signing_enabled_read; -static write_proc_t packet_signing_enabled_write;*/ -static read_proc_t experimEnabled_read; -static write_proc_t experimEnabled_write; -static read_proc_t linuxExtensionsEnabled_read; -static write_proc_t linuxExtensionsEnabled_write; +static const struct file_operations cifsFYI_proc_fops; +static const struct file_operations cifs_oplock_proc_fops; +static const struct file_operations cifs_lookup_cache_proc_fops; +static const struct file_operations traceSMB_proc_fops; +static const struct file_operations cifs_multiuser_mount_proc_fops; +static const struct file_operations cifs_security_flags_proc_fops; +static const struct file_operations cifs_experimental_proc_fops; +static const struct file_operations cifs_linux_ext_proc_fops; void cifs_proc_init(void) { - struct proc_dir_entry *pde; - proc_fs_cifs = proc_mkdir("fs/cifs", NULL); if (proc_fs_cifs == NULL) return; proc_fs_cifs->owner = THIS_MODULE; - create_proc_read_entry("DebugData", 0, proc_fs_cifs, - cifs_debug_data_read, NULL); + proc_create("DebugData", 0, proc_fs_cifs, &cifs_debug_data_proc_fops); #ifdef CONFIG_CIFS_STATS - pde = create_proc_read_entry("Stats", 0, proc_fs_cifs, - cifs_stats_read, NULL); - if (pde) - pde->write_proc = cifs_stats_write; + proc_create("Stats", 0, proc_fs_cifs, &cifs_stats_proc_fops); #endif /* STATS */ - pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, - cifsFYI_read, NULL); - if (pde) - pde->write_proc = cifsFYI_write; - - pde = - create_proc_read_entry("traceSMB", 0, proc_fs_cifs, - traceSMB_read, NULL); - if (pde) - pde->write_proc = traceSMB_write; - - pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs, - oplockEnabled_read, NULL); - if (pde) - pde->write_proc = oplockEnabled_write; - - pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs, - experimEnabled_read, NULL); - if (pde) - pde->write_proc = experimEnabled_write; - - pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs, - linuxExtensionsEnabled_read, NULL); - if (pde) - pde->write_proc = linuxExtensionsEnabled_write; - - pde = - create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs, - multiuser_mount_read, NULL); - if (pde) - pde->write_proc = multiuser_mount_write; - - pde = - create_proc_read_entry("SecurityFlags", 0, proc_fs_cifs, - security_flags_read, NULL); - if (pde) - pde->write_proc = security_flags_write; - - pde = - create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs, - lookupFlag_read, NULL); - if (pde) - pde->write_proc = lookupFlag_write; - -/* pde = - create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs, - ntlmv2_enabled_read, NULL); - if (pde) - pde->write_proc = ntlmv2_enabled_write; - - pde = - create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs, - packet_signing_enabled_read, NULL); - if (pde) - pde->write_proc = packet_signing_enabled_write;*/ + proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops); + proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops); + proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops); + proc_create("Experimental", 0, proc_fs_cifs, &cifs_experimental_proc_fops); + proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, &cifs_linux_ext_proc_fops); + proc_create("MultiuserMount", 0, proc_fs_cifs, &cifs_multiuser_mount_proc_fops); + proc_create("SecurityFlags", 0, proc_fs_cifs, &cifs_security_flags_proc_fops); + proc_create("LookupCacheEnabled", 0, proc_fs_cifs, &cifs_lookup_cache_proc_fops); } void @@ -553,39 +416,26 @@ cifs_proc_clean(void) #endif remove_proc_entry("MultiuserMount", proc_fs_cifs); remove_proc_entry("OplockEnabled", proc_fs_cifs); -/* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */ remove_proc_entry("SecurityFlags", proc_fs_cifs); -/* remove_proc_entry("PacketSigningEnabled", proc_fs_cifs); */ remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); remove_proc_entry("Experimental", proc_fs_cifs); remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); remove_proc_entry("fs/cifs", NULL); } -static int -cifsFYI_read(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int cifsFYI_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", cifsFYI); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "%d\n", cifsFYI); + return 0; } -static int -cifsFYI_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int cifsFYI_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifsFYI_proc_show, NULL); +} + +static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) { char c; int rc; @@ -603,30 +453,28 @@ cifsFYI_write(struct file *file, const char __user *buffer, return count; } -static int -oplockEnabled_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static const struct file_operations cifsFYI_proc_fops = { + .owner = THIS_MODULE, + .open = cifsFYI_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifsFYI_proc_write, +}; + +static int cifs_oplock_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", oplockEnabled); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "%d\n", oplockEnabled); + return 0; } -static int -oplockEnabled_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int cifs_oplock_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_oplock_proc_show, NULL); +} + +static ssize_t cifs_oplock_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { char c; int rc; @@ -642,30 +490,28 @@ oplockEnabled_write(struct file *file, const char __user *buffer, return count; } -static int -experimEnabled_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static const struct file_operations cifs_oplock_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_oplock_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_oplock_proc_write, +}; + +static int cifs_experimental_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", experimEnabled); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "%d\n", experimEnabled); + return 0; } -static int -experimEnabled_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int cifs_experimental_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_experimental_proc_show, NULL); +} + +static ssize_t cifs_experimental_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { char c; int rc; @@ -683,29 +529,28 @@ experimEnabled_write(struct file *file, const char __user *buffer, return count; } -static int -linuxExtensionsEnabled_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static const struct file_operations cifs_experimental_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_experimental_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_experimental_proc_write, +}; + +static int cifs_linux_ext_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", linuxExtEnabled); - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "%d\n", linuxExtEnabled); + return 0; } -static int -linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_linux_ext_proc_show, NULL); +} + +static ssize_t cifs_linux_ext_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { char c; int rc; @@ -721,31 +566,28 @@ linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, return count; } +static const struct file_operations cifs_linux_ext_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_linux_ext_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_linux_ext_proc_write, +}; -static int -lookupFlag_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", lookupCacheEnabled); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "%d\n", lookupCacheEnabled); + return 0; } -static int -lookupFlag_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_lookup_cache_proc_show, NULL); +} + +static ssize_t cifs_lookup_cache_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { char c; int rc; @@ -760,30 +602,29 @@ lookupFlag_write(struct file *file, const char __user *buffer, return count; } -static int -traceSMB_read(char *page, char **start, off_t off, int count, - int *eof, void *data) + +static const struct file_operations cifs_lookup_cache_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_lookup_cache_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_lookup_cache_proc_write, +}; + +static int traceSMB_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", traceSMB); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "%d\n", traceSMB); + return 0; } -static int -traceSMB_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int traceSMB_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, traceSMB_proc_show, NULL); +} + +static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) { char c; int rc; @@ -799,30 +640,28 @@ traceSMB_write(struct file *file, const char __user *buffer, return count; } -static int -multiuser_mount_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static const struct file_operations traceSMB_proc_fops = { + .owner = THIS_MODULE, + .open = traceSMB_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = traceSMB_proc_write, +}; + +static int cifs_multiuser_mount_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "%d\n", multiuser_mount); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "%d\n", multiuser_mount); + return 0; } -static int -multiuser_mount_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_multiuser_mount_proc_show, NULL); +} + +static ssize_t cifs_multiuser_mount_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { char c; int rc; @@ -838,30 +677,28 @@ multiuser_mount_write(struct file *file, const char __user *buffer, return count; } -static int -security_flags_read(char *page, char **start, off_t off, - int count, int *eof, void *data) +static const struct file_operations cifs_multiuser_mount_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_multiuser_mount_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_multiuser_mount_proc_write, +}; + +static int cifs_security_flags_proc_show(struct seq_file *m, void *v) { - int len; - - len = sprintf(page, "0x%x\n", extended_security); - - len -= off; - *start = page + off; - - if (len > count) - len = count; - else - *eof = 1; - - if (len < 0) - len = 0; - - return len; + seq_printf(m, "0x%x\n", extended_security); + return 0; } -static int -security_flags_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int cifs_security_flags_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_security_flags_proc_show, NULL); +} + +static ssize_t cifs_security_flags_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) { unsigned int flags; char flags_string[12]; @@ -917,6 +754,15 @@ security_flags_write(struct file *file, const char __user *buffer, /* BB should we turn on MAY flags for other MUST options? */ return count; } + +static const struct file_operations cifs_security_flags_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_security_flags_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_security_flags_proc_write, +}; #else inline void cifs_proc_init(void) { From 99b1f5b2f6cd2f65cce02c5f63302df5878a5fbc Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 24 Jul 2008 02:37:45 +0000 Subject: [PATCH 032/179] [CIFS] remove checkpatch warning Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 73925a77375e..c213aa40064e 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -395,11 +395,16 @@ cifs_proc_init(void) proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops); proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops); proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops); - proc_create("Experimental", 0, proc_fs_cifs, &cifs_experimental_proc_fops); - proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, &cifs_linux_ext_proc_fops); - proc_create("MultiuserMount", 0, proc_fs_cifs, &cifs_multiuser_mount_proc_fops); - proc_create("SecurityFlags", 0, proc_fs_cifs, &cifs_security_flags_proc_fops); - proc_create("LookupCacheEnabled", 0, proc_fs_cifs, &cifs_lookup_cache_proc_fops); + proc_create("Experimental", 0, proc_fs_cifs, + &cifs_experimental_proc_fops); + proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, + &cifs_linux_ext_proc_fops); + proc_create("MultiuserMount", 0, proc_fs_cifs, + &cifs_multiuser_mount_proc_fops); + proc_create("SecurityFlags", 0, proc_fs_cifs, + &cifs_security_flags_proc_fops); + proc_create("LookupCacheEnabled", 0, proc_fs_cifs, + &cifs_lookup_cache_proc_fops); } void @@ -655,9 +660,9 @@ static int cifs_multiuser_mount_proc_show(struct seq_file *m, void *v) return 0; } -static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *file) +static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *fh) { - return single_open(file, cifs_multiuser_mount_proc_show, NULL); + return single_open(fh, cifs_multiuser_mount_proc_show, NULL); } static ssize_t cifs_multiuser_mount_proc_write(struct file *file, From 1986b0cb1671ea39178b4e2b00461109728fc935 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 24 Jul 2008 08:10:02 +0200 Subject: [PATCH 033/179] ftrace: remove latency-tracer leftover remove the :vim=ft=help tag from trace files. I used them years ago to syntax-highlight traces and forgot about this hack. Signed-off-by: Ingo Molnar --- kernel/trace/trace.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 868e121c8e38..fc20e09a6cb1 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1203,9 +1203,6 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos) iter->pos = *pos; - if (last_ent && !ent) - seq_puts(m, "\n\nvim:ft=help\n"); - return ent; } From 76c510ad2e7d56cfe8f2cc7b23783e5c687cf704 Mon Sep 17 00:00:00 2001 From: Shirish Pargaonkar Date: Thu, 24 Jul 2008 14:48:33 +0000 Subject: [PATCH 034/179] [CIFS] Fix possible double free if search immediately after search rewind fails Signed-off-by: Shirish Pargaonkar Signed-off-by: Steve French --- fs/cifs/readdir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 83f306954883..5f40ed3473f5 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -690,6 +690,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, else cifs_buf_release(cifsFile->srch_inf. ntwrk_buf_start); + cifsFile->srch_inf.ntwrk_buf_start = NULL; } rc = initiate_cifs_search(xid, file); if (rc) { From b1910ad6222a705650dc991c003af43b94cdb3e1 Mon Sep 17 00:00:00 2001 From: Shirish Pargaonkar Date: Thu, 24 Jul 2008 14:53:20 +0000 Subject: [PATCH 035/179] [CIFS] Fix improper endian conversion of ACL subauth field In mode_to_acl when converting a Unix mode to a Windows ACL the subauth fields of the SID in the ACL were translated incorrectly on bigendian architectures Signed-off-by: Steve French --- fs/cifs/cifsacl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 0e9fc2ba90ee..18faf65b9114 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -169,8 +169,7 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, for (i = 0; i < 6; i++) ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; for (i = 0; i < 5; i++) - ngroup_sid_ptr->sub_auth[i] = - cpu_to_le32(group_sid_ptr->sub_auth[i]); + ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; return; } From ef571cadd516e7ffcdeac6bb8054e5908fcccfcf Mon Sep 17 00:00:00 2001 From: Shirish Pargaonkar Date: Thu, 24 Jul 2008 15:56:05 +0000 Subject: [PATCH 036/179] [CIFS] Fix warnings from checkpatch Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 4 ++-- fs/cifs/cifsacl.c | 38 +++++++++++++++++++------------------- fs/cifs/cifsencrypt.c | 3 +-- fs/cifs/cifsglob.h | 6 +++--- fs/cifs/cifspdu.h | 8 ++++---- fs/cifs/cifssmb.c | 5 ++--- 6 files changed, 31 insertions(+), 33 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index c213aa40064e..688a2d42153f 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -208,9 +208,9 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) seq_puts(m, " type: CDROM "); else seq_printf(m, " type: %d ", dev_type); - if (tcon->tidStatus == CifsNeedReconnect) { + + if (tcon->tidStatus == CifsNeedReconnect) seq_puts(m, "\tDISCONNECTED "); - } } read_unlock(&GlobalSMBSeslock); diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 18faf65b9114..57ecdc83c26f 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -56,7 +56,7 @@ int match_sid(struct cifs_sid *ctsid) struct cifs_sid *cwsid; if (!ctsid) - return (-1); + return -1; for (i = 0; i < NUM_WK_SIDS; ++i) { cwsid = &(wksidarr[i].cifssid); @@ -87,11 +87,11 @@ int match_sid(struct cifs_sid *ctsid) } cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname)); - return (0); /* sids compare/match */ + return 0; /* sids compare/match */ } cFYI(1, ("No matching sid")); - return (-1); + return -1; } /* if the two SIDs (roughly equivalent to a UUID for a user or group) are @@ -102,16 +102,16 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) int num_subauth, num_sat, num_saw; if ((!ctsid) || (!cwsid)) - return (0); + return 0; /* compare the revision */ if (ctsid->revision != cwsid->revision) - return (0); + return 0; /* compare all of the six auth values */ for (i = 0; i < 6; ++i) { if (ctsid->authority[i] != cwsid->authority[i]) - return (0); + return 0; } /* compare all of the subauth values if any */ @@ -121,11 +121,11 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) if (num_subauth) { for (i = 0; i < num_subauth; ++i) { if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) - return (0); + return 0; } } - return (1); /* sids compare/match */ + return 1; /* sids compare/match */ } @@ -284,7 +284,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace, size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4); pntace->size = cpu_to_le16(size); - return (size); + return size; } @@ -425,7 +425,7 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); pndacl->num_aces = cpu_to_le32(3); - return (0); + return 0; } @@ -509,7 +509,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, sizeof(struct cifs_sid)); */ - return (0); + return 0; } @@ -526,7 +526,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL)) - return (-EIO); + return -EIO; owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); @@ -549,7 +549,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, /* copy security descriptor control portion and owner and group sid */ copy_sec_desc(pntsd, pnntsd, sidsoffset); - return (rc); + return rc; } @@ -628,11 +628,11 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); if (!inode) - return (rc); + return rc; sb = inode->i_sb; if (sb == NULL) - return (rc); + return rc; cifs_sb = CIFS_SB(sb); xid = GetXid(); @@ -651,7 +651,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, if (rc != 0) { cERROR(1, ("Unable to open file to set ACL")); FreeXid(xid); - return (rc); + return rc; } } @@ -664,7 +664,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, FreeXid(xid); - return (rc); + return rc; } /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ @@ -714,7 +714,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) if (!pnntsd) { cERROR(1, ("Unable to allocate security descriptor")); kfree(pntsd); - return (-ENOMEM); + return -ENOMEM; } rc = build_sec_desc(pntsd, pnntsd, inode, nmode); @@ -731,6 +731,6 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) kfree(pntsd); } - return (rc); + return rc; } #endif /* CONFIG_CIFS_EXPERIMENTAL */ diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 4ff8939c6cc7..83fd40dc1ef0 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -310,9 +310,8 @@ void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key) utf8 and other multibyte codepages each need their own strupper function since a byte at a time will ont work. */ - for (i = 0; i < CIFS_ENCPWD_SIZE; i++) { + for (i = 0; i < CIFS_ENCPWD_SIZE; i++) password_with_pad[i] = toupper(password_with_pad[i]); - } SMBencrypt(password_with_pad, ses->server->cryptKey, lnm_session_key); /* clear password before we return/free memory */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 9cfcf326ead3..7e1cf262effe 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -27,7 +27,7 @@ #define MAX_SES_INFO 2 #define MAX_TCON_INFO 4 -#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1 +#define MAX_TREE_SIZE (2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1) #define MAX_SERVER_SIZE 15 #define MAX_SHARE_SIZE 64 /* used to be 20, this should still be enough */ #define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null @@ -537,8 +537,8 @@ require use of the stronger protocol */ #endif /* WEAK_PW_HASH */ #define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ -#define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 -#define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2 +#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2) +#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2) #define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5) /* ***************************************************************** diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 0f327c224da3..409abce12732 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -31,7 +31,7 @@ #else #define CIFS_PROT 0 #endif -#define POSIX_PROT CIFS_PROT+1 +#define POSIX_PROT (CIFS_PROT+1) #define BAD_PROT 0xFFFF /* SMB command codes */ @@ -341,7 +341,7 @@ #define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */ #define CREATE_NO_EA_KNOWLEDGE 0x00000200 #define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete - "open for recovery" flag - should + "open for recovery" flag should be zero in any case */ #define CREATE_OPEN_FOR_RECOVERY 0x00000400 #define CREATE_RANDOM_ACCESS 0x00000800 @@ -414,8 +414,8 @@ struct smb_hdr { __u8 WordCount; } __attribute__((packed)); /* given a pointer to an smb_hdr retrieve the value of byte count */ -#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) -#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) +#define BCC(smb_var) (*(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) +#define BCC_LE(smb_var) (*(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) /* given a pointer to an smb_hdr retrieve the pointer to the byte area */ #define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 7e175e1399d1..c621ffa2ca90 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -686,11 +686,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) SecurityBlob, count - 16, &server->secType); - if (rc == 1) { + if (rc == 1) rc = 0; - } else { + else rc = -EINVAL; - } } } else server->capabilities &= ~CAP_EXTENDED_SECURITY; From e2d2867ff8700d7431c68c089ff5f5ed7f2d5b40 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Thu, 24 Jul 2008 20:43:34 +0000 Subject: [PATCH 037/179] When verifying the decoded header before decoding the object identifier (expecting a SPNEGO pseudo-mechanism oid), the test to verify it is a primitive encoding is compared against the asn1 class. Primitive is not a class. This brings check in line with similar check for krb/ntlmssp oid. Signed-off-by: Chris Wright Cc: Steven French Signed-off-by: Andrew Morton Signed-off-by: Steve French --- fs/cifs/asn1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index 42765465701c..6bb440b257b0 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c @@ -494,7 +494,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, /* remember to free obj->oid */ rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (rc) { - if ((tag == ASN1_OJI) && (cls == ASN1_PRI)) { + if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); if (rc) { rc = compare_oid(oid, oidlen, From 054a3fd824705543322d787893de9f3755151517 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Fri, 25 Jul 2008 15:44:33 +0800 Subject: [PATCH 038/179] flag parameters: fix compile error of sys_epoll_create1 GEN .version CHK include/linux/compile.h UPD include/linux/compile.h CC init/version.o LD init/built-in.o LD vmlinux arch/x86/kernel/built-in.o: In function `sys_call_table': (.rodata+0x8a4): undefined reference to `sys_epoll_create1' make: *** [vmlinux] Error 1 Signed-off-by: Wang Chen Cc: Andrew Morton Cc: Davide Libenzi Cc: Ulrich Drepper Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- kernel/sys_ni.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 0fea0ee12da9..0be4fc1409a2 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -56,6 +56,7 @@ cond_syscall(compat_sys_set_robust_list); cond_syscall(sys_get_robust_list); cond_syscall(compat_sys_get_robust_list); cond_syscall(sys_epoll_create); +cond_syscall(sys_epoll_create1); cond_syscall(sys_epoll_ctl); cond_syscall(sys_epoll_wait); cond_syscall(sys_epoll_pwait); From 36ac26171afa8dbf29226199699fe955d4a0b6f6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 26 Jul 2008 11:22:33 +0200 Subject: [PATCH 039/179] crashdump: fix undefined reference to `elfcorehdr_addr' fix build bug introduced by 95b68dec0d5 "calgary iommu: use the first kernels TCE tables in kdump": arch/x86/kernel/built-in.o: In function `calgary_iommu_init': (.init.text+0x8399): undefined reference to `elfcorehdr_addr' arch/x86/kernel/built-in.o: In function `calgary_iommu_init': (.init.text+0x856c): undefined reference to `elfcorehdr_addr' arch/x86/kernel/built-in.o: In function `detect_calgary': (.init.text+0x8c68): undefined reference to `elfcorehdr_addr' arch/x86/kernel/built-in.o: In function `detect_calgary': (.init.text+0x8d0c): undefined reference to `elfcorehdr_addr' make elfcorehdr_addr a generally available symbol. Signed-off-by: Ingo Molnar --- include/linux/crash_dump.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 6cd39a927e1f..025e4f575103 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -8,7 +8,13 @@ #include #define ELFCORE_ADDR_MAX (-1ULL) + +#ifdef CONFIG_PROC_VMCORE extern unsigned long long elfcorehdr_addr; +#else +static const unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; +#endif + extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, unsigned long, int); extern const struct file_operations proc_vmcore_operations; From b1b154e503a0e590eb9e189586783dc8750f910e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 26 Jul 2008 18:02:05 +0800 Subject: [PATCH 040/179] Blackfin arch: check the EXTBANKS field of the DDRCTL1 register to see if we are using both memory banks Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/kernel/setup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8671d1db1f99..102a9db98559 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -700,6 +700,8 @@ static inline int __init get_mem_size(void) case DEVWD_8: ret *= 2; case DEVWD_16: break; } + if ((ddrctl & 0xc000) == 0x4000) + ret *= 2; return ret; #endif BUG(); From 377d43e7d07fc9a64eb162c6f70e6d1961604629 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Sat, 26 Jul 2008 18:28:03 +0800 Subject: [PATCH 041/179] Blackfin arch: fix bug - IMDMA is not type struct dma_register TEMP Workaround - avoid access to PERIPHERAL_MAP Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/kernel/bfin_dma_5xx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index ad0e75845ac2..93229b3d6e3e 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -477,7 +477,11 @@ int blackfin_dma_suspend(void) { int i; +#ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ + for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) { +#else for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { +#endif if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) { printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); return -EBUSY; @@ -493,7 +497,11 @@ void blackfin_dma_resume(void) { int i; +#ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ + for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) +#else for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) +#endif dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; } #endif From 3a2521fa75359450f5ec7e6b76847f933b7ee680 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 26 Jul 2008 18:52:56 +0800 Subject: [PATCH 042/179] Blackfin arch: cache the values of vco/sclk/cclk as the overhead of doing so (~24 bytes) is worth avoiding the software mult/div routines Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/kernel/setup.c | 44 ++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 102a9db98559..5a455b6bb542 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -850,38 +850,55 @@ static int __init topology_init(void) subsys_initcall(topology_init); +/* Get the voltage input multiplier */ +static u_long cached_vco_pll_ctl, cached_vco; static u_long get_vco(void) { u_long msel; - u_long vco; - msel = (bfin_read_PLL_CTL() >> 9) & 0x3F; + u_long pll_ctl = bfin_read_PLL_CTL(); + if (pll_ctl == cached_vco_pll_ctl) + return cached_vco; + else + cached_vco_pll_ctl = pll_ctl; + + msel = (pll_ctl >> 9) & 0x3F; if (0 == msel) msel = 64; - vco = CONFIG_CLKIN_HZ; - vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */ - vco = msel * vco; - return vco; + cached_vco = CONFIG_CLKIN_HZ; + cached_vco >>= (1 & pll_ctl); /* DF bit */ + cached_vco *= msel; + return cached_vco; } /* Get the Core clock */ +static u_long cached_cclk_pll_div, cached_cclk; u_long get_cclk(void) { u_long csel, ssel; + if (bfin_read_PLL_STAT() & 0x1) return CONFIG_CLKIN_HZ; ssel = bfin_read_PLL_DIV(); + if (ssel == cached_cclk_pll_div) + return cached_cclk; + else + cached_cclk_pll_div = ssel; + csel = ((ssel >> 4) & 0x03); ssel &= 0xf; if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ - return get_vco() / ssel; - return get_vco() >> csel; + cached_cclk = get_vco() / ssel; + else + cached_cclk = get_vco() >> csel; + return cached_cclk; } EXPORT_SYMBOL(get_cclk); /* Get the System clock */ +static u_long cached_sclk_pll_div, cached_sclk; u_long get_sclk(void) { u_long ssel; @@ -889,13 +906,20 @@ u_long get_sclk(void) if (bfin_read_PLL_STAT() & 0x1) return CONFIG_CLKIN_HZ; - ssel = (bfin_read_PLL_DIV() & 0xf); + ssel = bfin_read_PLL_DIV(); + if (ssel == cached_sclk_pll_div) + return cached_sclk; + else + cached_sclk_pll_div = ssel; + + ssel &= 0xf; if (0 == ssel) { printk(KERN_WARNING "Invalid System Clock\n"); ssel = 1; } - return get_vco() / ssel; + cached_sclk = get_vco() / ssel; + return cached_sclk; } EXPORT_SYMBOL(get_sclk); From 0d1cdd7ab6e0e7ccaf9f3b1d2afa0ddeead23ccc Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 26 Jul 2008 18:54:38 +0800 Subject: [PATCH 043/179] Blackfin arch: Fix bug - skip single step in high priority interrupt handler instead of disabling all interrupts in single step debugging. Skip single step if event priority of current instruction is higher than that of the first instruction, from which gdb starts single step. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/kernel/kgdb.c | 16 +++++++++- arch/blackfin/mach-common/entry.S | 50 +++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index a9c15515bfd7..a1f9641a6425 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -203,6 +203,8 @@ struct hw_breakpoint { int kgdb_arch_init(void) { + debugger_step = 0; + kgdb_remove_all_hw_break(); return 0; } @@ -368,6 +370,7 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo, char *ptr; int newPC; int wp_status; + int i; switch (remcom_in_buffer[0]) { case 'c': @@ -392,7 +395,18 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo, /* set the trace bit if we're stepping */ if (remcom_in_buffer[0] == 's') { linux_regs->syscfg |= 0x1; - debugger_step = 1; + debugger_step = linux_regs->ipend; + debugger_step >>= 6; + for (i = 10; i > 0; i--, debugger_step >>= 1) + if (debugger_step & 1) + break; + /* i indicate event priority of current stopped instruction + * user space instruction is 0, IVG15 is 1, IVTMR is 10. + * debugger_step > 0 means in single step mode + */ + debugger_step = i + 1; + } else { + debugger_step = 0; } wp_status = bfin_read_WPSTAT(); diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 038f70e0be65..eceb484d90f9 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -158,23 +158,45 @@ ENTRY(_ex_single_step) cc = r7 == r6; if cc jump _bfin_return_from_exception; + /* Don't do single step in hardware exception handler */ + p5.l = lo(IPEND); + p5.h = hi(IPEND); + r6 = [p5]; + cc = bittst(r6, 5); + if cc jump _bfin_return_from_exception; + +#ifdef CONFIG_KGDB + /* skip single step if current interrupt priority is higher than + * that of the first instruction, from which gdb starts single step */ + r6 >>= 6; + r7 = 10; +.Lfind_priority_start: + cc = bittst(r6, 0); + if cc jump .Lfind_priority_done; + r6 >>= 1; + r7 += -1; + cc = r7 == 0; + if cc jump .Lfind_priority_done; + jump.s .Lfind_priority_start; +.Lfind_priority_done: + p4.l = _debugger_step; + p4.h = _debugger_step; + r6 = [p4]; + cc = r6 == 0; + if cc jump .Ldo_single_step; + r6 += -1; + cc = r6 < r7; + if cc jump _bfin_return_from_exception; +.Ldo_single_step: +#endif + /* If we were in user mode, do the single step normally. */ - p5.l = lo(IPEND); - p5.h = hi(IPEND); r6 = [p5]; r7 = 0xffe0 (z); r7 = r7 & r6; cc = r7 == 0; - if !cc jump 1f; + if cc jump 1f; - /* Single stepping only a single instruction, so clear the trace - * bit here. */ - r7 = syscfg; - bitclr (r7, 0); - syscfg = R7; - jump _ex_trap_c; - -1: /* * We were in an interrupt handler. By convention, all of them save * SYSCFG with their first instruction, so by checking whether our @@ -202,11 +224,15 @@ ENTRY(_ex_single_step) cc = R7 == R6; if !cc jump _bfin_return_from_exception; +1: + /* Single stepping only a single instruction, so clear the trace + * bit here. */ r7 = syscfg; bitclr (r7, 0); syscfg = R7; - /* Fall through to _bfin_return_from_exception. */ + jump _ex_trap_c; + ENDPROC(_ex_single_step) ENTRY(_bfin_return_from_exception) From 9de3a0b6979a4839d67ca840e386ea06acaabe39 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 26 Jul 2008 19:39:19 +0800 Subject: [PATCH 044/179] Blackfin arch: When icache is off, make sure people know it Signed-off-by: Robin Getz Signed-off-by: Bryan Wu --- arch/blackfin/kernel/setup.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 5a455b6bb542..c2248fe80588 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -948,7 +948,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) uint32_t revid; u_long cclk = 0, sclk = 0; - u_int dcache_size = 0, dsup_banks = 0; + u_int icache_size = BFIN_ICACHESIZE / 1024, dcache_size = 0, dsup_banks = 0; cpu = CPU; mmu = "none"; @@ -1017,12 +1017,15 @@ static int show_cpuinfo(struct seq_file *m, void *v) } /* Is it turned on? */ - if (!((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))) + if (bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE) != (ENDCPLB | DMC_ENABLE)) dcache_size = 0; + if (bfin_read_IMEM_CONTROL() & (IMC | ENICPLB) == (IMC | ENICPLB)) + icache_size = 0; + seq_printf(m, "cache size\t: %d KB(L1 icache) " "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", - BFIN_ICACHESIZE / 1024, dcache_size, + icache_size, dcache_size, #if defined CONFIG_BFIN_WB "wb" #elif defined CONFIG_BFIN_WT @@ -1032,8 +1035,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "%s\n", cache); - seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", - BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); + if (icache_size) + seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", + BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); + else + seq_printf(m, "icache setup\t: off\n"); + seq_printf(m, "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, From 2d2009806dd843f3adc0cbbb5d2204980f28111a Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 26 Jul 2008 19:41:40 +0800 Subject: [PATCH 045/179] Blackfin arch: If we double fault, rather than hang forever, reset Signed-off-by: Robin Getz Signed-off-by: Bryan Wu --- arch/blackfin/kernel/setup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index c2248fe80588..23e637eb78da 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -771,6 +771,9 @@ void __init setup_arch(char **cmdline_p) _bfin_swrst = bfin_read_SWRST(); + /* If we double fault, reset the system - otherwise we hang forever */ + bfin_write_SWRST(DOUBLE_FAULT); + if (_bfin_swrst & RESET_DOUBLE) printk(KERN_INFO "Recovering from Double Fault event\n"); else if (_bfin_swrst & RESET_WDOG) @@ -1017,10 +1020,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) } /* Is it turned on? */ - if (bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE) != (ENDCPLB | DMC_ENABLE)) + if ((bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE)) != (ENDCPLB | DMC_ENABLE)) dcache_size = 0; - if (bfin_read_IMEM_CONTROL() & (IMC | ENICPLB) == (IMC | ENICPLB)) + if ((bfin_read_IMEM_CONTROL() & (IMC | ENICPLB)) == (IMC | ENICPLB)) icache_size = 0; seq_printf(m, "cache size\t: %d KB(L1 icache) " From 1f972768a1df1518f45adb6b8ffbf04fa1c99737 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 26 Jul 2008 13:52:50 +0200 Subject: [PATCH 046/179] x86, RDC321x: add to mach-default first step to add RDC321x support to the default PC architecture. Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 26 +++++++++++--------------- arch/x86/Makefile | 5 ----- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e3cba0b45600..39ae67985950 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -23,7 +23,7 @@ config X86 select HAVE_OPROFILE select HAVE_IOREMAP_PROT select HAVE_KPROBES - select ARCH_WANT_OPTIONAL_GPIOLIB if !X86_RDC321X + select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_KRETPROBES select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE @@ -332,20 +332,6 @@ config X86_BIGSMP endif -config X86_RDC321X - bool "RDC R-321x SoC" - depends on X86_32 - select M486 - select X86_REBOOTFIXUPS - select GENERIC_GPIO - select LEDS_CLASS - select LEDS_GPIO - select NEW_LEDS - help - This option is needed for RDC R-321x system-on-chip, also known - as R-8610-(G). - If you don't have one of these chips, you should say N here. - config X86_VSMP bool "Support for ScaleMP vSMP" select PARAVIRT @@ -369,6 +355,16 @@ config X86_VISWS A kernel compiled for the Visual Workstation will run on general PCs as well. See for details. +config X86_RDC321X + bool "RDC R-321x SoC" + depends on X86_32 + select M486 + select X86_REBOOTFIXUPS + help + This option is needed for RDC R-321x system-on-chip, also known + as R-8610-(G). + If you don't have one of these chips, you should say N here. + config SCHED_NO_NO_OMIT_FRAME_POINTER def_bool y prompt "Single-depth WCHAN output" diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 919ce21ea654..f5631da585b6 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -118,11 +118,6 @@ mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/ mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default/ -# RDC R-321x subarch support -mflags-$(CONFIG_X86_RDC321X) := -Iinclude/asm-x86/mach-rdc321x -mcore-$(CONFIG_X86_RDC321X) := arch/x86/mach-default/ -core-$(CONFIG_X86_RDC321X) += arch/x86/mach-rdc321x/ - # default subarch .h files mflags-y += -Iinclude/asm-x86/mach-default From dcf309974555d17019c6a8e1a425238f17990b71 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 25 Jul 2008 18:00:42 -0400 Subject: [PATCH 047/179] ftrace: disable tracing on acpi idle calls The acpi idle waits calls local_irq_save and then uses mwait to go into idle. The tracer gets reenabled at local_irq_save but does not detect that the idle allows for wake ups. This patch adds code to disable the tracing when acpi puts the CPU to idle. Signed-off-by: Steven Rostedt Cc: Peter Zijlstra Signed-off-by: Ingo Molnar --- drivers/acpi/processor_idle.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index d592dbb1d12a..b7f2963693a7 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -272,6 +272,8 @@ static atomic_t c3_cpu_count; /* Common C-state entry for C2, C3, .. */ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) { + /* Don't trace irqs off for idle */ + stop_critical_timings(); if (cstate->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cstate); @@ -284,6 +286,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } + start_critical_timings(); } #endif /* !CONFIG_CPU_IDLE */ @@ -1418,6 +1421,8 @@ static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, */ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) { + /* Don't trace irqs off for idle */ + stop_critical_timings(); if (cx->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cx); @@ -1432,6 +1437,7 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } + start_critical_timings(); } /** From 071375bc76ee86e58592f4682030c81d410ddfd9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 26 Jul 2008 14:52:26 +0200 Subject: [PATCH 048/179] x86, RDC321x: remove gpio.h complications Remove the include/asm-x86/gpio.h specials, just use the generic version. Signed-off-by: Ingo Molnar --- include/asm-x86/gpio.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/asm-x86/gpio.h b/include/asm-x86/gpio.h index 116e9147fe66..c4c91b37c104 100644 --- a/include/asm-x86/gpio.h +++ b/include/asm-x86/gpio.h @@ -16,10 +16,6 @@ #ifndef _ASM_I386_GPIO_H #define _ASM_I386_GPIO_H -#ifdef CONFIG_X86_RDC321X -#include -#else /* CONFIG_X86_RDC321X */ - #include #ifdef CONFIG_GPIOLIB @@ -57,6 +53,4 @@ static inline int irq_to_gpio(unsigned int irq) #endif /* CONFIG_GPIOLIB */ -#endif /* CONFIG_X86_RDC321X */ - #endif /* _ASM_I386_GPIO_H */ From 1ca9fda4b2f3413e4bc748b983f5585629ca0560 Mon Sep 17 00:00:00 2001 From: Chris McDermott Date: Thu, 24 Jul 2008 19:06:09 -0700 Subject: [PATCH 049/179] x86: fix IBM Summit based systems' phys_cpu_present_map on 32-bit kernels x86 kernels on IBM Summit based systems will only online 1 CPU because the phys_cpu_present_map is not set up correctly. Patch below applied to 2.6.26-git10. Signed-off-by: Chris McDermott Tested-by: Tim Pepper Signed-off-by: Ingo Molnar --- include/asm-x86/mach-summit/mach_apic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-x86/mach-summit/mach_apic.h b/include/asm-x86/mach-summit/mach_apic.h index 75d2c95005d7..c47e2ab5c5ca 100644 --- a/include/asm-x86/mach-summit/mach_apic.h +++ b/include/asm-x86/mach-summit/mach_apic.h @@ -122,7 +122,7 @@ static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_id_map) static inline physid_mask_t apicid_to_cpu_present(int apicid) { - return physid_mask_of_physid(0); + return physid_mask_of_physid(apicid); } static inline void setup_portio_remap(void) From 1fe371044b21b226b96a9dd959e971b50b28c78e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 26 Jul 2008 15:09:47 +0200 Subject: [PATCH 050/179] ftrace: fix modular build fix: ERROR: "start_critical_timings" [drivers/acpi/processor.ko] undefined! ERROR: "stop_critical_timings" [drivers/acpi/processor.ko] undefined! Signed-off-by: Ingo Molnar --- kernel/trace/trace_irqsoff.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index b1e4a89b08eb..ece6cfb649fa 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -253,12 +253,14 @@ void start_critical_timings(void) if (preempt_trace() || irq_trace()) start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } +EXPORT_SYMBOL_GPL(start_critical_timings); void stop_critical_timings(void) { if (preempt_trace() || irq_trace()) stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } +EXPORT_SYMBOL_GPL(stop_critical_timings); #ifdef CONFIG_IRQSOFF_TRACER #ifdef CONFIG_PROVE_LOCKING From 3a61ec387c9092dfc91a5959145d36835a72fc4c Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 25 Jul 2008 13:07:50 +0200 Subject: [PATCH 051/179] x86, AMD IOMMU: include amd_iommu_last_bdf in device initialization All the values read while searching for amd_iommu_last_bdf are defined as inclusive. Let the code handle this value as such. Found by Wei Wang. Thanks Wei. Signed-off-by: Joerg Roedel Cc: iommu@lists.linux-foundation.org Cc: bhavna.sarathy@amd.com Cc: robert.richter@amd.com Cc: Wei Wang Signed-off-by: Ingo Molnar --- arch/x86/kernel/amd_iommu.c | 4 ++-- arch/x86/kernel/amd_iommu_init.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index c25210e6ac88..74697408576f 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -667,7 +667,7 @@ static int get_device_resources(struct device *dev, _bdf = calc_devid(pcidev->bus->number, pcidev->devfn); /* device not translated by any IOMMU in the system? */ - if (_bdf >= amd_iommu_last_bdf) { + if (_bdf > amd_iommu_last_bdf) { *iommu = NULL; *domain = NULL; *bdf = 0xffff; @@ -1085,7 +1085,7 @@ void prealloc_protection_domains(void) while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { devid = (dev->bus->number << 8) | dev->devfn; - if (devid >= amd_iommu_last_bdf) + if (devid > amd_iommu_last_bdf) continue; devid = amd_iommu_alias_table[devid]; if (domain_for_device(devid)) diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index c9d8ff2eb130..d9a9da597e79 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -732,7 +732,7 @@ static int __init init_exclusion_range(struct ivmd_header *m) set_device_exclusion_range(m->devid, m); break; case ACPI_IVMD_TYPE_ALL: - for (i = 0; i < amd_iommu_last_bdf; ++i) + for (i = 0; i <= amd_iommu_last_bdf; ++i) set_device_exclusion_range(i, m); break; case ACPI_IVMD_TYPE_RANGE: @@ -934,7 +934,7 @@ int __init amd_iommu_init(void) /* * let all alias entries point to itself */ - for (i = 0; i < amd_iommu_last_bdf; ++i) + for (i = 0; i <= amd_iommu_last_bdf; ++i) amd_iommu_alias_table[i] = i; /* From 0c7ad106e779549792deb307242dece6f3499bb9 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 25 Jul 2008 19:44:35 -0700 Subject: [PATCH 052/179] drivers/mmc/host/sdhci.h needs scatterlist.h alpha: drivers/mmc/host/sdhci.h:242: error: field 'sg_miter' has incomplete type Cc: Pierre Ossman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index a06bf8b89343..e354faee5df0 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -9,6 +9,8 @@ * your option) any later version. */ +#include + /* * Controller registers */ From 16d69265b930f7e2fa9eea381715696f780718f4 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 25 Jul 2008 19:44:36 -0700 Subject: [PATCH 053/179] uninline arch_pick_mmap_layout() Fix this, on avr32: include/linux/utsname.h:35, from init/main.c:20: include/linux/sched.h: In function 'arch_pick_mmap_layout': include/linux/sched.h:2149: error: implicit declaration of function 'PAGE_ALIGN' Reported-by: Adrian Bunk Cc: Haavard Skinnemoen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 9 --------- mm/util.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 42036ffe6b00..3260a5c42b91 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2139,16 +2139,7 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) #endif /* CONFIG_SMP */ -#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT extern void arch_pick_mmap_layout(struct mm_struct *mm); -#else -static inline void arch_pick_mmap_layout(struct mm_struct *mm) -{ - mm->mmap_base = TASK_UNMAPPED_BASE; - mm->get_unmapped_area = arch_get_unmapped_area; - mm->unmap_area = arch_unmap_area; -} -#endif #ifdef CONFIG_TRACING extern void diff --git a/mm/util.c b/mm/util.c index 8f18683825bc..0efd83097ecf 100644 --- a/mm/util.c +++ b/mm/util.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -136,3 +137,12 @@ char *strndup_user(const char __user *s, long n) return p; } EXPORT_SYMBOL(strndup_user); + +#ifndef HAVE_ARCH_PICK_MMAP_LAYOUT +void arch_pick_mmap_layout(struct mm_struct *mm) +{ + mm->mmap_base = TASK_UNMAPPED_BASE; + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; +} +#endif From 8a21346058ad946134b6ddfeb5de975c3cfcf5da Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Fri, 25 Jul 2008 19:44:37 -0700 Subject: [PATCH 054/179] hugetlb: fix CONFIG_SYSCTL=n build Fixes a build failure reported by Alan Cox: mm/hugetlb.c: In function `hugetlb_acct_memory': mm/hugetlb.c:1507: error: implicit declaration of function `cpuset_mems_nr' Also reverts Ingo's commit e44d1b2998d62a1f2f4d7eb17b56ba396535509f Author: Ingo Molnar Date: Fri Jul 25 12:57:41 2008 +0200 mm/hugetlb.c: fix build failure with !CONFIG_SYSCTL which fixed the build error but added some unused-static-function warnings. Signed-off-by: Nishanth Aravamudan Cc: Alan Cox Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index a8bf4ab01f86..3be79dc18c5c 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1026,18 +1026,6 @@ static void __init report_hugepages(void) } } -static unsigned int cpuset_mems_nr(unsigned int *array) -{ - int node; - unsigned int nr = 0; - - for_each_node_mask(node, cpuset_current_mems_allowed) - nr += array[node]; - - return nr; -} - -#ifdef CONFIG_SYSCTL #ifdef CONFIG_HIGHMEM static void try_to_free_low(struct hstate *h, unsigned long count) { @@ -1386,6 +1374,18 @@ static int __init hugetlb_default_setup(char *s) } __setup("default_hugepagesz=", hugetlb_default_setup); +static unsigned int cpuset_mems_nr(unsigned int *array) +{ + int node; + unsigned int nr = 0; + + for_each_node_mask(node, cpuset_current_mems_allowed) + nr += array[node]; + + return nr; +} + +#ifdef CONFIG_SYSCTL int hugetlb_sysctl_handler(struct ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) From 44ccac13c7f4728cf2992d49384671a176db74dd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:44:38 -0700 Subject: [PATCH 055/179] include/video/atmel_lcdc.h must #include This patch fixes the following compile error caused by commit d22579b837358cbef12ccca5adaf7e93ae09ab7a ("atmel_lcdfb: FIFO underflow management"): In file included from arch/avr32/boards/atstk1000/atstk1004.c:21: include/video/atmel_lcdc.h:40: error: field 'task' has incomplete type Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/video/atmel_lcdc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h index 1ccf462b433a..613173b5db69 100644 --- a/include/video/atmel_lcdc.h +++ b/include/video/atmel_lcdc.h @@ -22,6 +22,7 @@ #ifndef __ATMEL_LCDC_H__ #define __ATMEL_LCDC_H__ +#include /* Way LCD wires are connected to the chip: * Some Atmel chips use BGR color mode (instead of standard RGB) From a2e2e3577c3ef2b5dbb866e97e612aae4adfa32f Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 25 Jul 2008 19:44:38 -0700 Subject: [PATCH 056/179] pm selftest: rtc paranoia Cope with a quirk of some RTCs (notably ACPI ones) which aren't guaranteed to implement oneshot behavior when they woke the system from sleeep: forcibly disable the alarm, just in case. Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/power/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/power/main.c b/kernel/power/main.c index 95bff23ecdaa..0b7476f5d2a6 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -635,6 +635,13 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state) } if (status < 0) printk(err_suspend, status); + + /* Some platforms can't detect that the alarm triggered the + * wakeup, or (accordingly) disable it after it afterwards. + * It's supposed to give oneshot behavior; cope. + */ + alm.enabled = false; + rtc_set_alarm(rtc, &alm); } static int __init has_wakealarm(struct device *dev, void *name_ptr) From a76eef9573c93f8f324ebacfd090a3e319a64d59 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 25 Jul 2008 19:44:39 -0700 Subject: [PATCH 057/179] block/blk-map.c: use the new object_is_on_stack() helper Signed-off-by: FUJITA Tomonori Cc: Bartlomiej Zolnierkiewicz Cc: Thomas Bogendoerfer Cc: Tejun Heo Cc: Jens Axboe Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- block/blk-map.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/block/blk-map.c b/block/blk-map.c index ddd96fb11a7d..af37e4ae62f5 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -269,7 +269,6 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, int reading = rq_data_dir(rq) == READ; int do_copy = 0; struct bio *bio; - unsigned long stack_mask = ~(THREAD_SIZE - 1); if (len > (q->max_hw_sectors << 9)) return -EINVAL; @@ -278,11 +277,8 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, kaddr = (unsigned long)kbuf; alignment = queue_dma_alignment(q) | q->dma_pad_mask; - do_copy = ((kaddr & alignment) || (len & alignment)); - - if (!((kaddr & stack_mask) ^ - ((unsigned long)current->stack & stack_mask))) - do_copy = 1; + do_copy = ((kaddr & alignment) || (len & alignment) || + object_is_on_stack(kbuf)); if (do_copy) bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); From f3c6ba986ab4527b6dfacf9f3b9e40f72466a8b2 Mon Sep 17 00:00:00 2001 From: Kentaro Makita Date: Fri, 25 Jul 2008 19:44:40 -0700 Subject: [PATCH 058/179] vfs: add cond_resched_lock while scanning dentry LRU lists Add cond_resched_lock(&dcache_lock) while scanning LRU lists on superblocks in __shrink_dcache_sb() Signed-off-by: Kentaro Makita Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/dcache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/dcache.c b/fs/dcache.c index 3818d6ab76ca..f2584d22cb45 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -487,6 +487,7 @@ static void __shrink_dcache_sb(struct super_block *sb, int *count, int flags) if (!cnt) break; } + cond_resched_lock(&dcache_lock); } } while (!list_empty(&tmp)) { From c491b2ffae3fad5e6e3cb2320b46bb8ea8729d49 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Fri, 25 Jul 2008 19:44:41 -0700 Subject: [PATCH 059/179] asic3: platform_get_irq() may return signed unnoticed asic->irq_nr is unsigned. platform_get_irq() may return signed unnoticed Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Cc: Joe Perches Acked-by: Samuel Ortiz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mfd/asic3.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 3b870e7fb3e1..eabf0bfccab4 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -314,10 +314,12 @@ static int __init asic3_irq_probe(struct platform_device *pdev) unsigned long clksel = 0; unsigned int irq, irq_base; int map_size; + int ret; - asic->irq_nr = platform_get_irq(pdev, 0); - if (asic->irq_nr < 0) - return asic->irq_nr; + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + asic->irq_nr = ret; /* turn on clock to IRQ controller */ clksel |= CLOCK_SEL_CX; From e86b19ce64a25d39bb0e10e0e695213fc5993dfb Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Fri, 25 Jul 2008 19:44:42 -0700 Subject: [PATCH 060/179] pnp: set the pnp_card dma_mask for use by ISAPnP cards dma_alloc_coherent() on x86 currently takes a passed in NULL device pointer to mean that it should allocate an ISA compatible (24-bit) buffer which is a bit of a hack. The ALSA ISA drivers are the main consumers of this but have a struct device in fact readily available. For the PnP drivers, the specific pnp_dev->dev device pointer is not always available at the right time so for now we want to pass the pnp_card->dev instead which is always available. Set its dma_mask in preparation for doing so. This does not fix a current bug -- 2.6.26-rc1 stumbled over the NULL hack in dma_alloc_coherent() but this has already been fixed in commit 4a367f3a9dbf2e7ffcee4702203479809236ee6e by Takashi Iwai. Signed-off-by: Rene Herman Acked-by: Bjorn Helgaas Acked-by: Takashi Iwai Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/card.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index a762a4176736..b00ef1030e45 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "base.h" LIST_HEAD(pnp_cards); @@ -167,6 +168,9 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnp sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number, card->number); + card->dev.coherent_dma_mask = DMA_24BIT_MASK; + card->dev.dma_mask = &card->dev.coherent_dma_mask; + dev_id = pnp_add_card_id(card, pnpid); if (!dev_id) { kfree(card); From 00412be1d7bdf451653c7dafeb09f4f83398d756 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Fri, 25 Jul 2008 19:44:45 -0700 Subject: [PATCH 061/179] isa: set 24-bit dma_mask for ISA devices dma_alloc_coherent() on x86 currently takes a passed in NULL device pointer to mean that it should allocate an ISA compatible (24-bit) buffer which is a bit of a hack. The ALSA ISA drivers are the main consumers of this but have a struct device in fact readily available. For the legacy drivers, this sets the device dma_mask in preparation for using the actual device with the DMA API so as to eventually not need the NULL hack in dma_alloc_coherent(). This does not fix a current bug -- 2.6.26-rc1 stumbled over the NULL hack in dma_alloc_coherent() but this has already been fixed in commit 4a367f3a9dbf2e7ffcee4702203479809236ee6e by Takashi Iwai. Signed-off-by: Rene Herman Cc: Bjorn Helgaas Acked-by: Takashi Iwai Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/isa.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/base/isa.c b/drivers/base/isa.c index d2222397a401..efd577574948 100644 --- a/drivers/base/isa.c +++ b/drivers/base/isa.c @@ -7,6 +7,7 @@ #include #include #include +#include #include static struct device isa_bus = { @@ -141,6 +142,9 @@ int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev) isa_dev->dev.release = isa_dev_release; isa_dev->id = id; + isa_dev->dev.coherent_dma_mask = DMA_24BIT_MASK; + isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; + error = device_register(&isa_dev->dev); if (error) { put_device(&isa_dev->dev); From 999ed65ad12e374d7445fbc13f5a1d146ae4b0da Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Fri, 25 Jul 2008 19:44:47 -0700 Subject: [PATCH 062/179] pnp: have quirk_system_pci_resources() include io resources quirk_system_pci_resources() disables a PnP mem resource that overlaps a PCI BAR so as to not keep the PCI driver from claiming the resource. Have it do the same for io resources. Here, ACPI claims ports that overlap with my soundcard causing the soundcard driver to fail to load. It's unknown why my ACPI BIOS claims those ports; it did not use to but this is not a (kernel) regression. Some odd BIOS reconfig triggered by temporarily removing the card seems to have brought this on. Signed-off-by: Rene Herman Acked-by: Bjorn Helgaas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/quirks.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 55f55ed72dc7..0bdf9b8a5e58 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -245,15 +245,17 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) */ for_each_pci_dev(pdev) { for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM) || - pci_resource_len(pdev, i) == 0) + unsigned int type; + + type = pci_resource_flags(pdev, i) & + (IORESOURCE_IO | IORESOURCE_MEM); + if (!type || pci_resource_len(pdev, i) == 0) continue; pci_start = pci_resource_start(pdev, i); pci_end = pci_resource_end(pdev, i); for (j = 0; - (res = pnp_get_resource(dev, IORESOURCE_MEM, j)); - j++) { + (res = pnp_get_resource(dev, type, j)); j++) { if (res->start == 0 && res->end == 0) continue; @@ -283,9 +285,10 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) * the PCI region, and that might prevent a PCI * driver from requesting its resources. */ - dev_warn(&dev->dev, "mem resource " + dev_warn(&dev->dev, "%s resource " "(0x%llx-0x%llx) overlaps %s BAR %d " "(0x%llx-0x%llx), disabling\n", + pnp_resource_type_name(res), (unsigned long long) pnp_start, (unsigned long long) pnp_end, pci_name(pdev), i, From c485b465a031b6f9b9a51300e0ee1f86efc6db87 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 25 Jul 2008 19:44:47 -0700 Subject: [PATCH 063/179] pnp: fix the fcpnp_driver declaration to only exist if CONFIG_PNP=y Fix the fcpnp_driver declaration to only exist if CONFIG_PNP=y as it's only accessed in that case. The PNP=n variant was added by 30d55e71a81b1f5a8136f191dc9f4c21f18e77e6 ("hisax: depend on CONFIG_PNP, not __ISAPNP__") Fixes an unused variable warning. Signed-off-by: David Howells Acked-by: Bjorn Helgaas Cc: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/hisax_fcpcipnp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index c0b4db2f8364..1925118122f8 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -974,8 +974,6 @@ static struct pnp_driver fcpnp_driver = { .remove = __devexit_p(fcpnp_remove), .id_table = fcpnp_ids, }; -#else -static struct pnp_driver fcpnp_driver; #endif static void __devexit fcpci_remove(struct pci_dev *pdev) From 8d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 25 Jul 2008 19:44:49 -0700 Subject: [PATCH 064/179] dma-mapping: add the device argument to dma_mapping_error() Add per-device dma_mapping_ops support for CONFIG_X86_64 as POWER architecture does: This enables us to cleanly fix the Calgary IOMMU issue that some devices are not behind the IOMMU (http://lkml.org/lkml/2008/5/8/423). I think that per-device dma_mapping_ops support would be also helpful for KVM people to support PCI passthrough but Andi thinks that this makes it difficult to support the PCI passthrough (see the above thread). So I CC'ed this to KVM camp. Comments are appreciated. A pointer to dma_mapping_ops to struct dev_archdata is added. If the pointer is non NULL, DMA operations in asm/dma-mapping.h use it. If it's NULL, the system-wide dma_ops pointer is used as before. If it's useful for KVM people, I plan to implement a mechanism to register a hook called when a new pci (or dma capable) device is created (it works with hot plugging). It enables IOMMUs to set up an appropriate dma_mapping_ops per device. The major obstacle is that dma_mapping_error doesn't take a pointer to the device unlike other DMA operations. So x86 can't have dma_mapping_ops per device. Note all the POWER IOMMUs use the same dma_mapping_error function so this is not a problem for POWER but x86 IOMMUs use different dma_mapping_error functions. The first patch adds the device argument to dma_mapping_error. The patch is trivial but large since it touches lots of drivers and dma-mapping.h in all the architecture. This patch: dma_mapping_error() doesn't take a pointer to the device unlike other DMA operations. So we can't have dma_mapping_ops per device. Note that POWER already has dma_mapping_ops per device but all the POWER IOMMUs use the same dma_mapping_error function. x86 IOMMUs use device argument. [akpm@linux-foundation.org: fix sge] [akpm@linux-foundation.org: fix svc_rdma] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix bnx2x] [akpm@linux-foundation.org: fix s2io] [akpm@linux-foundation.org: fix pasemi_mac] [akpm@linux-foundation.org: fix sdhci] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix sparc] [akpm@linux-foundation.org: fix ibmvscsi] Signed-off-by: FUJITA Tomonori Cc: Muli Ben-Yehuda Cc: Andi Kleen Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/DMA-API.txt | 4 +- arch/arm/common/dmabounce.c | 2 +- arch/ia64/hp/common/hwsw_iommu.c | 5 +- arch/ia64/hp/common/sba_iommu.c | 2 +- arch/ia64/sn/pci/pci_dma.c | 2 +- arch/mips/mm/dma-default.c | 2 +- .../powerpc/platforms/cell/celleb_scc_pciex.c | 2 +- arch/powerpc/platforms/cell/spider-pci.c | 2 +- arch/powerpc/platforms/iseries/mf.c | 2 +- arch/x86/kernel/pci-calgary_64.c | 2 +- arch/x86/kernel/pci-dma.c | 27 ++--- arch/x86/kernel/pci-gart_64.c | 3 +- arch/x86/kernel/pci-nommu.c | 14 +-- arch/x86/kernel/pci-swiotlb_64.c | 2 +- drivers/firewire/fw-iso.c | 2 +- drivers/firewire/fw-ohci.c | 2 +- drivers/firewire/fw-sbp2.c | 8 +- drivers/infiniband/hw/ipath/ipath_sdma.c | 2 +- drivers/infiniband/hw/ipath/ipath_user_sdma.c | 6 +- drivers/infiniband/hw/mthca/mthca_eq.c | 2 +- drivers/media/dvb/pluto2/pluto2.c | 2 +- drivers/mmc/host/sdhci.c | 4 +- drivers/net/arm/ep93xx_eth.c | 4 +- drivers/net/bnx2x_main.c | 4 +- drivers/net/cxgb3/sge.c | 2 +- drivers/net/e100.c | 2 +- drivers/net/e1000e/ethtool.c | 4 +- drivers/net/e1000e/netdev.c | 11 ++- drivers/net/ibmveth.c | 38 +++---- drivers/net/iseries_veth.c | 4 +- drivers/net/mlx4/eq.c | 2 +- drivers/net/pasemi_mac.c | 6 +- drivers/net/qla3xxx.c | 12 +-- drivers/net/s2io.c | 48 +++++---- drivers/net/sfc/rx.c | 4 +- drivers/net/sfc/tx.c | 7 +- drivers/net/spider_net.c | 4 +- drivers/net/tc35815.c | 4 +- drivers/net/wireless/ath5k/base.c | 4 +- drivers/scsi/ibmvscsi/ibmvfc.c | 4 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 4 +- drivers/scsi/ibmvscsi/ibmvstgt.c | 2 +- drivers/scsi/ibmvscsi/rpa_vscsi.c | 2 +- drivers/spi/atmel_spi.c | 4 +- drivers/spi/au1550_spi.c | 6 +- drivers/spi/omap2_mcspi.c | 4 +- drivers/spi/pxa2xx_spi.c | 4 +- drivers/spi/spi_imx.c | 6 +- include/asm-alpha/dma-mapping.h | 6 +- include/asm-alpha/pci.h | 2 +- include/asm-arm/dma-mapping.h | 2 +- include/asm-avr32/dma-mapping.h | 2 +- include/asm-cris/dma-mapping.h | 2 +- include/asm-frv/dma-mapping.h | 2 +- include/asm-generic/dma-mapping-broken.h | 2 +- include/asm-generic/dma-mapping.h | 4 +- include/asm-generic/pci-dma-compat.h | 4 +- include/asm-ia64/machvec.h | 2 +- include/asm-m68k/dma-mapping.h | 2 +- include/asm-mips/dma-mapping.h | 2 +- include/asm-mn10300/dma-mapping.h | 2 +- include/asm-parisc/dma-mapping.h | 2 +- include/asm-powerpc/dma-mapping.h | 2 +- include/asm-sh/dma-mapping.h | 2 +- include/asm-sparc/dma-mapping_64.h | 2 +- include/asm-sparc/pci_32.h | 3 +- include/asm-sparc/pci_64.h | 5 +- include/asm-x86/device.h | 3 + include/asm-x86/dma-mapping.h | 99 +++++++++++++------ include/asm-x86/swiotlb.h | 2 +- include/asm-xtensa/dma-mapping.h | 2 +- include/linux/i2o.h | 2 +- include/linux/ssb/ssb.h | 4 +- include/rdma/ib_verbs.h | 2 +- lib/swiotlb.c | 4 +- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 3 +- 76 files changed, 256 insertions(+), 210 deletions(-) diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 80d150458c80..d8b63d164e41 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -298,10 +298,10 @@ recommended that you never use these unless you really know what the cache width is. int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr) In some circumstances dma_map_single and dma_map_page will fail to create a mapping. A driver can check for these errors by testing the returned diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index dd2947342604..69130f365904 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -280,7 +280,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, /* * Trying to unmap an invalid mapping */ - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Trying to unmap invalid mapping\n"); return; } diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 1c44ec2a1d58..88b6e6f3fd88 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -186,9 +186,10 @@ hwsw_dma_supported (struct device *dev, u64 mask) } int -hwsw_dma_mapping_error (dma_addr_t dma_addr) +hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return hwiommu_dma_mapping_error (dma_addr) || swiotlb_dma_mapping_error(dma_addr); + return hwiommu_dma_mapping_error(dev, dma_addr) || + swiotlb_dma_mapping_error(dev, dma_addr); } EXPORT_SYMBOL(hwsw_dma_mapping_error); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 34421aed1e2a..4956be40d7b5 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -2147,7 +2147,7 @@ sba_dma_supported (struct device *dev, u64 mask) } int -sba_dma_mapping_error (dma_addr_t dma_addr) +sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 52175af299a0..53ebb6484495 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -350,7 +350,7 @@ void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } EXPORT_SYMBOL(sn_dma_sync_sg_for_device); -int sn_dma_mapping_error(dma_addr_t dma_addr) +int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index ae39dd88b9aa..891312f8e5a6 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -348,7 +348,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele EXPORT_SYMBOL(dma_sync_sg_for_device); -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 0e04f8fb152a..3e7e0f1568ef 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -281,7 +281,7 @@ static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data) dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dummy_page_da)) { + if (dma_mapping_error(bus->phb->parent, dummy_page_da)) { pr_err("PCIEX:Map dummy page failed.\n"); kfree(dummy_page_va); return -1; diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c index 418b605ac35a..5122ec145271 100644 --- a/arch/powerpc/platforms/cell/spider-pci.c +++ b/arch/powerpc/platforms/cell/spider-pci.c @@ -111,7 +111,7 @@ static int __init spiderpci_pci_setup_chip(struct pci_controller *phb, dummy_page_da = dma_map_single(phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dummy_page_da)) { + if (dma_mapping_error(phb->parent, dummy_page_da)) { pr_err("SPIDER-IOWA:Map dummy page filed.\n"); kfree(dummy_page_va); return -1; diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 1dc7295746da..731d7b157749 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -871,7 +871,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, count = 256 - off; dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_addr)) + if (dma_mapping_error(NULL, dma_addr)) return -ENOMEM; memset(page, 0, off + count); memset(&vsp_cmd, 0, sizeof(vsp_cmd)); diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 19e7fc7c2c4f..1eb86be93d7a 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -544,7 +544,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size, return ret; } -static const struct dma_mapping_ops calgary_dma_ops = { +static struct dma_mapping_ops calgary_dma_ops = { .alloc_coherent = calgary_alloc_coherent, .map_single = calgary_map_single, .unmap_single = calgary_unmap_single, diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index cbecb05551bb..37544123896d 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -11,7 +11,7 @@ static int forbid_dac __read_mostly; -const struct dma_mapping_ops *dma_ops; +struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); static int iommu_sac_force __read_mostly; @@ -312,6 +312,8 @@ static int dma_release_coherent(struct device *dev, int order, void *vaddr) int dma_supported(struct device *dev, u64 mask) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + #ifdef CONFIG_PCI if (mask > 0xffffffff && forbid_dac > 0) { dev_info(dev, "PCI: Disallowing DAC for device\n"); @@ -319,8 +321,8 @@ int dma_supported(struct device *dev, u64 mask) } #endif - if (dma_ops->dma_supported) - return dma_ops->dma_supported(dev, mask); + if (ops->dma_supported) + return ops->dma_supported(dev, mask); /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. @@ -367,6 +369,7 @@ void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { + struct dma_mapping_ops *ops = get_dma_ops(dev); void *memory = NULL; struct page *page; unsigned long dma_mask = 0; @@ -435,8 +438,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, /* Let low level make its own zone decisions */ gfp &= ~(GFP_DMA32|GFP_DMA); - if (dma_ops->alloc_coherent) - return dma_ops->alloc_coherent(dev, size, + if (ops->alloc_coherent) + return ops->alloc_coherent(dev, size, dma_handle, gfp); return NULL; } @@ -448,14 +451,14 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, } } - if (dma_ops->alloc_coherent) { + if (ops->alloc_coherent) { free_pages((unsigned long)memory, get_order(size)); gfp &= ~(GFP_DMA|GFP_DMA32); - return dma_ops->alloc_coherent(dev, size, dma_handle, gfp); + return ops->alloc_coherent(dev, size, dma_handle, gfp); } - if (dma_ops->map_simple) { - *dma_handle = dma_ops->map_simple(dev, virt_to_phys(memory), + if (ops->map_simple) { + *dma_handle = ops->map_simple(dev, virt_to_phys(memory), size, PCI_DMA_BIDIRECTIONAL); if (*dma_handle != bad_dma_address) @@ -477,12 +480,14 @@ EXPORT_SYMBOL(dma_alloc_coherent); void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t bus) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + int order = get_order(size); WARN_ON(irqs_disabled()); /* for portability */ if (dma_release_coherent(dev, order, vaddr)) return; - if (dma_ops->unmap_single) - dma_ops->unmap_single(dev, bus, size, 0); + if (ops->unmap_single) + ops->unmap_single(dev, bus, size, 0); free_pages((unsigned long)vaddr, order); } EXPORT_SYMBOL(dma_free_coherent); diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index df5f142657d2..744126e64950 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -692,8 +692,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) extern int agp_amd64_init(void); -static const struct dma_mapping_ops gart_dma_ops = { - .mapping_error = NULL, +static struct dma_mapping_ops gart_dma_ops = { .map_single = gart_map_single, .map_simple = gart_map_simple, .unmap_single = gart_unmap_single, diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 792b9179eff3..3f91f71cdc3e 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -72,21 +72,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, return nents; } -/* Make sure we keep the same behaviour */ -static int nommu_mapping_error(dma_addr_t dma_addr) -{ -#ifdef CONFIG_X86_32 - return 0; -#else - return (dma_addr == bad_dma_address); -#endif -} - - -const struct dma_mapping_ops nommu_dma_ops = { +struct dma_mapping_ops nommu_dma_ops = { .map_single = nommu_map_single, .map_sg = nommu_map_sg, - .mapping_error = nommu_mapping_error, .is_phys = 1, }; diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c index 20df839b9c20..c4ce0332759e 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -18,7 +18,7 @@ swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); } -const struct dma_mapping_ops swiotlb_dma_ops = { +struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, .alloc_coherent = swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/fw-iso.c index bcbe794a3ea5..e14c03dc0065 100644 --- a/drivers/firewire/fw-iso.c +++ b/drivers/firewire/fw-iso.c @@ -50,7 +50,7 @@ fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, address = dma_map_page(card->device, buffer->pages[i], 0, PAGE_SIZE, direction); - if (dma_mapping_error(address)) { + if (dma_mapping_error(card->device, address)) { __free_page(buffer->pages[i]); goto out_pages; } diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 333b12544dd1..566672e0bcff 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -953,7 +953,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet) payload_bus = dma_map_single(ohci->card.device, packet->payload, packet->payload_length, DMA_TO_DEVICE); - if (dma_mapping_error(payload_bus)) { + if (dma_mapping_error(ohci->card.device, payload_bus)) { packet->ack = RCODE_SEND_ERROR; return -1; } diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 53fc5a641e6d..aaff50ebba1d 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -543,7 +543,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); - if (dma_mapping_error(orb->response_bus)) + if (dma_mapping_error(device->card->device, orb->response_bus)) goto fail_mapping_response; orb->request.response.high = 0; @@ -577,7 +577,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) + if (dma_mapping_error(device->card->device, orb->base.request_bus)) goto fail_mapping_request; sbp2_send_orb(&orb->base, lu, node_id, generation, @@ -1424,7 +1424,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, orb->page_table_bus = dma_map_single(device->card->device, orb->page_table, sizeof(orb->page_table), DMA_TO_DEVICE); - if (dma_mapping_error(orb->page_table_bus)) + if (dma_mapping_error(device->card->device, orb->page_table_bus)) goto fail_page_table; /* @@ -1509,7 +1509,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) + if (dma_mapping_error(device->card->device, orb->base.request_bus)) goto out; sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation, diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index eaba03273e4f..284c9bca517e 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -698,7 +698,7 @@ int ipath_sdma_verbs_send(struct ipath_devdata *dd, addr = dma_map_single(&dd->pcidev->dev, tx->txreq.map_addr, tx->map_len, DMA_TO_DEVICE); - if (dma_mapping_error(addr)) { + if (dma_mapping_error(&dd->pcidev->dev, addr)) { ret = -EIO; goto unlock; } diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c index 86e016916cd1..82d9a0b5ca2f 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c @@ -206,7 +206,7 @@ static int ipath_user_sdma_coalesce(const struct ipath_devdata *dd, dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto free_unmap; } @@ -301,7 +301,7 @@ static int ipath_user_sdma_pin_pages(const struct ipath_devdata *dd, pages[j], 0, flen, DMA_TO_DEVICE); unsigned long fofs = addr & ~PAGE_MASK; - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto done; } @@ -508,7 +508,7 @@ static int ipath_user_sdma_queue_pkts(const struct ipath_devdata *dd, if (page) { dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto free_pbc; } diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 4e36aa7cb3d2..cc6858f0b65b 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -780,7 +780,7 @@ int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt) return -ENOMEM; dev->eq_table.icm_dma = pci_map_page(dev->pdev, dev->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->eq_table.icm_dma)) { + if (pci_dma_mapping_error(dev->pdev, dev->eq_table.icm_dma)) { __free_page(dev->eq_table.icm_page); return -ENOMEM; } diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 1360403b88b6..a9653c63f4db 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -242,7 +242,7 @@ static int __devinit pluto_dma_map(struct pluto *pluto) pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, TS_DMA_BYTES, PCI_DMA_FROMDEVICE); - return pci_dma_mapping_error(pluto->dma_addr); + return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); } static void pluto_dma_unmap(struct pluto *pluto) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c3a5db72ddd7..5f95e10229b5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -337,7 +337,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->align_addr = dma_map_single(mmc_dev(host->mmc), host->align_buffer, 128 * 4, direction); - if (dma_mapping_error(host->align_addr)) + if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) goto fail; BUG_ON(host->align_addr & 0x3); @@ -439,7 +439,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->adma_addr = dma_map_single(mmc_dev(host->mmc), host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); - if (dma_mapping_error(host->align_addr)) + if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) goto unmap_entries; BUG_ON(host->adma_addr & 0x3); diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 7a14980f3472..18d3eeb7eab2 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -482,7 +482,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(d)) { + if (dma_mapping_error(NULL, d)) { free_page((unsigned long)page); goto err; } @@ -505,7 +505,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(d)) { + if (dma_mapping_error(NULL, d)) { free_page((unsigned long)page); goto err; } diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 0263bef9cc6d..c7cc760a1777 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1020,7 +1020,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(mapping))) { + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { __free_pages(page, PAGES_PER_SGE_SHIFT); return -ENOMEM; } @@ -1048,7 +1048,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(mapping))) { + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { dev_kfree_skb(skb); return -ENOMEM; } diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index a96331c875e6..1b0861d73ab7 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -386,7 +386,7 @@ static inline int add_one_rx_buf(void *va, unsigned int len, dma_addr_t mapping; mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(mapping))) + if (unlikely(pci_dma_mapping_error(pdev, mapping))) return -ENOMEM; pci_unmap_addr_set(sd, dma_addr, mapping); diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 1037b1332312..19d32a227be1 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1790,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(rx->dma_addr)) { + if (pci_dma_mapping_error(nic->pdev, rx->dma_addr)) { dev_kfree_skb_any(rx->skb); rx->skb = NULL; rx->dma_addr = 0; diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index a14561f40db0..9350564065e7 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1090,7 +1090,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(tx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(pdev, tx_ring->buffer_info[i].dma)) { ret_val = 4; goto err_nomem; } @@ -1153,7 +1153,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, 2048, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(pdev, rx_ring->buffer_info[i].dma)) { ret_val = 8; goto err_nomem; } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 9c0f56b3c518..d13677899767 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -195,7 +195,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(pdev, buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; break; @@ -265,7 +265,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, ps_page->page, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(ps_page->dma)) { + if (pci_dma_mapping_error(pdev, ps_page->dma)) { dev_err(&adapter->pdev->dev, "RX DMA page map failed\n"); adapter->rx_dma_failed++; @@ -300,7 +300,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_ps_bsize0, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(pdev, buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; /* cleanup skb */ @@ -3344,7 +3344,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, skb->data + offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); adapter->tx_dma_failed++; return -1; @@ -3382,7 +3382,8 @@ static int e1000_tx_map(struct e1000_adapter *adapter, offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(adapter->pdev, + buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA page map failed\n"); adapter->tx_dma_failed++; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index e5a6e2e84540..91ec9fdc7184 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -260,7 +260,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, pool->buff_size, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_addr)) + if (dma_mapping_error((&adapter->vdev->dev, dma_addr)) goto failure; pool->free_map[free_index] = IBM_VETH_INVALID_MAP; @@ -294,7 +294,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc pool->consumer_index = pool->size - 1; else pool->consumer_index--; - if (!dma_mapping_error(dma_addr)) + if (!dma_mapping_error((&adapter->vdev->dev, dma_addr)) dma_unmap_single(&adapter->vdev->dev, pool->dma_addr[index], pool->buff_size, DMA_FROM_DEVICE); @@ -448,11 +448,11 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) static void ibmveth_cleanup(struct ibmveth_adapter *adapter) { int i; + struct device *dev = &adapter->vdev->dev; if(adapter->buffer_list_addr != NULL) { - if(!dma_mapping_error(adapter->buffer_list_dma)) { - dma_unmap_single(&adapter->vdev->dev, - adapter->buffer_list_dma, 4096, + if (!dma_mapping_error(dev, adapter->buffer_list_dma)) { + dma_unmap_single(dev, adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->buffer_list_dma = DMA_ERROR_CODE; } @@ -461,9 +461,8 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->filter_list_addr != NULL) { - if(!dma_mapping_error(adapter->filter_list_dma)) { - dma_unmap_single(&adapter->vdev->dev, - adapter->filter_list_dma, 4096, + if (!dma_mapping_error(dev, adapter->filter_list_dma)) { + dma_unmap_single(dev, adapter->filter_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->filter_list_dma = DMA_ERROR_CODE; } @@ -472,8 +471,8 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->rx_queue.queue_addr != NULL) { - if(!dma_mapping_error(adapter->rx_queue.queue_dma)) { - dma_unmap_single(&adapter->vdev->dev, + if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { + dma_unmap_single(dev, adapter->rx_queue.queue_dma, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); @@ -535,6 +534,7 @@ static int ibmveth_open(struct net_device *netdev) int rc; union ibmveth_buf_desc rxq_desc; int i; + struct device *dev; ibmveth_debug_printk("open starting\n"); @@ -563,17 +563,19 @@ static int ibmveth_open(struct net_device *netdev) return -ENOMEM; } - adapter->buffer_list_dma = dma_map_single(&adapter->vdev->dev, + dev = &adapter->vdev->dev; + + adapter->buffer_list_dma = dma_map_single(dev, adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->filter_list_dma = dma_map_single(&adapter->vdev->dev, + adapter->filter_list_dma = dma_map_single(dev, adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->rx_queue.queue_dma = dma_map_single(&adapter->vdev->dev, + adapter->rx_queue.queue_dma = dma_map_single(dev, adapter->rx_queue.queue_addr, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); - if((dma_mapping_error(adapter->buffer_list_dma) ) || - (dma_mapping_error(adapter->filter_list_dma)) || - (dma_mapping_error(adapter->rx_queue.queue_dma))) { + if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || + (dma_mapping_error(dev, adapter->filter_list_dma)) || + (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { ibmveth_error_printk("unable to map filter or buffer list pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -645,7 +647,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); - if (dma_mapping_error(adapter->bounce_buffer_dma)) { + if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { ibmveth_error_printk("unable to map bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -922,7 +924,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) buf[1] = 0; } - if (dma_mapping_error(data_dma_addr)) { + if (dma_mapping_error((&adapter->vdev->dev, data_dma_addr)) { if (!firmware_has_feature(FW_FEATURE_CMO)) ibmveth_error_printk("tx: unable to map xmit buffer\n"); skb_copy_from_linear_data(skb, adapter->bounce_buffer, diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index b8d0639c1cdf..c46864d626b2 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1128,7 +1128,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, msg->data.addr[0] = dma_map_single(port->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(msg->data.addr[0])) + if (dma_mapping_error(port->dev, msg->data.addr[0])) goto recycle_and_drop; msg->dev = port->dev; @@ -1226,7 +1226,7 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx, dma_address = msg->data.addr[0]; dma_length = msg->data.len[0]; - if (!dma_mapping_error(dma_address)) + if (!dma_mapping_error(msg->dev, dma_address)) dma_unmap_single(msg->dev, dma_address, dma_length, DMA_TO_DEVICE); diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index ea3a09aaa844..7df928d3a3d8 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -526,7 +526,7 @@ int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt) return -ENOMEM; priv->eq_table.icm_dma = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(priv->eq_table.icm_dma)) { + if (pci_dma_mapping_error(dev->pdev, priv->eq_table.icm_dma)) { __free_page(priv->eq_table.icm_page); return -ENOMEM; } diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 993d87c9296f..edc0fd588985 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -650,7 +650,7 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev, mac->bufsz - LOCAL_SKB_ALIGN, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(dma))) { + if (unlikely(pci_dma_mapping_error(mac->dma_pdev, dma))) { dev_kfree_skb_irq(info->skb); break; } @@ -1519,7 +1519,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) map[0] = pci_map_single(mac->dma_pdev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE); map_size[0] = skb_headlen(skb); - if (dma_mapping_error(map[0])) + if (pci_dma_mapping_error(mac->dma_pdev, map[0])) goto out_err_nolock; for (i = 0; i < nfrags; i++) { @@ -1529,7 +1529,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) frag->page_offset, frag->size, PCI_DMA_TODEVICE); map_size[i+1] = frag->size; - if (dma_mapping_error(map[i+1])) { + if (pci_dma_mapping_error(mac->dma_pdev, map[i+1])) { nfrags = i; goto out_err_nolock; } diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index e7d48a352beb..e82b37bbd6c3 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -328,7 +328,7 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, qdev->lrg_buffer_len - QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -1919,7 +1919,7 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2454,7 +2454,7 @@ static int ql_send_map(struct ql3_adapter *qdev, */ map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2487,7 +2487,7 @@ static int ql_send_map(struct ql3_adapter *qdev, sizeof(struct oal), PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", @@ -2514,7 +2514,7 @@ static int ql_send_map(struct ql3_adapter *qdev, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", qdev->ndev->name, err); @@ -2916,7 +2916,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 9dae40ccf048..86d77d05190a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2512,8 +2512,8 @@ static void stop_nic(struct s2io_nic *nic) * Return Value: * SUCCESS on success or an appropriate -ve value on failure. */ - -static int fill_rx_buffers(struct ring_info *ring, int from_card_up) +static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, + int from_card_up) { struct sk_buff *skb; struct RxD_t *rxdp; @@ -2602,7 +2602,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) rxdp1->Buffer0_ptr = pci_map_single (ring->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp1->Buffer0_ptr)) goto pci_map_failed; rxdp->Control_2 = @@ -2636,7 +2637,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) rxdp3->Buffer0_ptr = pci_map_single(ring->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer0_ptr)) goto pci_map_failed; } else pci_dma_sync_single_for_device(ring->pdev, @@ -2655,7 +2657,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) (ring->pdev, skb->data, ring->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer2_ptr)) goto pci_map_failed; if (from_card_up) { @@ -2664,8 +2667,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error - (rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer1_ptr)) { pci_unmap_single (ring->pdev, (dma_addr_t)(unsigned long) @@ -2806,9 +2809,9 @@ static void free_rx_buffers(struct s2io_nic *sp) } } -static int s2io_chk_rx_buffers(struct ring_info *ring) +static int s2io_chk_rx_buffers(struct s2io_nic *nic, struct ring_info *ring) { - if (fill_rx_buffers(ring, 0) == -ENOMEM) { + if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } @@ -2848,7 +2851,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) return 0; pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(nic, ring); if (pkts_processed < budget_org) { netif_rx_complete(dev, napi); @@ -2882,7 +2885,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget) for (i = 0; i < config->rx_ring_num; i++) { ring = &mac_control->rings[i]; ring_pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(nic, ring); pkts_processed += ring_pkts_processed; budget -= ring_pkts_processed; if (budget <= 0) @@ -2939,7 +2942,8 @@ static void s2io_netpoll(struct net_device *dev) rx_intr_handler(&mac_control->rings[i], 0); for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) { + if (fill_rx_buffers(nic, &mac_control->rings[i], 0) == + -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; @@ -4235,14 +4239,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, fifo->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) goto pci_map_failed; txdp->Host_Control = (unsigned long) skb; @@ -4345,7 +4349,7 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) netif_rx_schedule(dev, &ring->napi); } else { rx_intr_handler(ring, 0); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(sp, ring); } return IRQ_HANDLED; @@ -4826,7 +4830,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) */ if (!config->napi) { for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(&mac_control->rings[i]); + s2io_chk_rx_buffers(sp, &mac_control->rings[i]); } writeq(sp->general_int_mask, &bar0->general_int_mask); readl(&bar0->general_int_status); @@ -6859,7 +6863,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if (pci_dma_mapping_error(sp->pdev, rxdp1->Buffer0_ptr)) goto memalloc_failed; rxdp->Host_Control = (unsigned long) (*skb); } @@ -6886,12 +6890,13 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(sp->pdev, rxdp3->Buffer2_ptr)) goto memalloc_failed; rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { + if (pci_dma_mapping_error(sp->pdev, + rxdp3->Buffer0_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); @@ -6903,7 +6908,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error(sp->pdev, + rxdp3->Buffer1_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); @@ -7187,7 +7193,7 @@ static int s2io_card_up(struct s2io_nic * sp) for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].mtu = dev->mtu; - ret = fill_rx_buffers(&mac_control->rings[i], 1); + ret = fill_rx_buffers(sp, &mac_control->rings[i], 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 601b001437c0..0d27dd39bc09 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -233,7 +233,7 @@ static inline int efx_init_rx_buffer_skb(struct efx_rx_queue *rx_queue, rx_buf->data, rx_buf->len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(rx_buf->dma_addr))) { + if (unlikely(pci_dma_mapping_error(efx->pci_dev, rx_buf->dma_addr))) { dev_kfree_skb_any(rx_buf->skb); rx_buf->skb = NULL; return -EIO; @@ -275,7 +275,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, 0, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(dma_addr))) { + if (unlikely(pci_dma_mapping_error(efx->pci_dev, dma_addr))) { __free_pages(rx_buf->page, efx->rx_buffer_order); rx_buf->page = NULL; return -EIO; diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 5cdd082ab8f6..5e8374ab28ee 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -172,7 +172,7 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, /* Process all fragments */ while (1) { - if (unlikely(pci_dma_mapping_error(dma_addr))) + if (unlikely(pci_dma_mapping_error(pci_dev, dma_addr))) goto pci_err; /* Store fields for marking in the per-fragment final @@ -661,7 +661,8 @@ efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len) tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev, TSOH_BUFFER(tsoh), header_len, PCI_DMA_TODEVICE); - if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) { + if (unlikely(pci_dma_mapping_error(tx_queue->efx->pci_dev, + tsoh->dma_addr))) { kfree(tsoh); return NULL; } @@ -863,7 +864,7 @@ static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off, len, PCI_DMA_TODEVICE); - if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) { + if (likely(!pci_dma_mapping_error(efx->pci_dev, st->ifc.unmap_addr))) { st->ifc.unmap_len = len; st->ifc.len = len; st->ifc.dma_addr = st->ifc.unmap_addr; diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 00aa0b108cb9..b6435d0d71f9 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -452,7 +452,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, /* iommu-map the skb */ buf = pci_map_single(card->pdev, descr->skb->data, SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buf)) { + if (pci_dma_mapping_error(card->pdev, buf)) { dev_kfree_skb_any(descr->skb); descr->skb = NULL; if (netif_msg_rx_err(card) && net_ratelimit()) @@ -691,7 +691,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, unsigned long flags; buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buf)) { + if (pci_dma_mapping_error(card->pdev, buf)) { if (netif_msg_tx_err(card) && net_ratelimit()) dev_err(&card->netdev->dev, "could not iommu-map packet (%p, %i). " "Dropping packet\n", skb->data, skb->len); diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index a645e5028c14..8487ace9d2e3 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -506,7 +506,7 @@ static void *alloc_rxbuf_page(struct pci_dev *hwdev, dma_addr_t *dma_handle) return NULL; *dma_handle = pci_map_single(hwdev, buf, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(*dma_handle)) { + if (pci_dma_mapping_error(hwdev, *dma_handle)) { free_page((unsigned long)buf); return NULL; } @@ -536,7 +536,7 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev, return NULL; *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(*dma_handle)) { + if (pci_dma_mapping_error(hwdev, *dma_handle)) { dev_kfree_skb_any(skb); return NULL; } diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 217d506527a9..d9769c527346 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1166,7 +1166,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) bf->skb = skb; bf->skbaddr = pci_map_single(sc->pdev, skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(bf->skbaddr))) { + if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) { ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); dev_kfree_skb(skb); bf->skb = NULL; @@ -1918,7 +1918,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " "skbaddr %llx\n", skb, skb->data, skb->len, (unsigned long long)bf->skbaddr); - if (pci_dma_mapping_error(bf->skbaddr)) { + if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) { ATH5K_ERR(sc, "beacon DMA mapping failed\n"); return -EIO; } diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c4a7c06793c5..61f8fdea2d96 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3525,7 +3525,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost) crq->msg_token = dma_map_single(dev, crq->msgs, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(crq->msg_token)) + if (dma_mapping_error(dev, crq->msg_token)) goto map_failed; retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, @@ -3618,7 +3618,7 @@ static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost) async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(async_q->msg_token)) { + if (dma_mapping_error(dev, async_q->msg_token)) { dev_err(dev, "Failed to map async queue\n"); goto free_async_crq; } diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 20000ec79b04..6b24b9cdb04c 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -859,7 +859,7 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) sizeof(hostdata->madapter_info), DMA_BIDIRECTIONAL); - if (dma_mapping_error(req->buffer)) { + if (dma_mapping_error(hostdata->dev, req->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "Unable to map request_buffer for " @@ -1407,7 +1407,7 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, length, DMA_BIDIRECTIONAL); - if (dma_mapping_error(host_config->buffer)) { + if (dma_mapping_error(hostdata->dev, host_config->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "dma_mapping error getting host config\n"); diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 3b9514c8f1f1..2e13ec00172a 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -564,7 +564,7 @@ static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(queue->msg_token)) + if (dma_mapping_error(target->dev, queue->msg_token)) goto map_failed; err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 182146100dc1..462a8574dad9 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -253,7 +253,7 @@ static int rpavscsi_init_crq_queue(struct crq_queue *queue, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(queue->msg_token)) + if (dma_mapping_error(hostdata->dev, queue->msg_token)) goto map_failed; gather_partition_info(); diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index e81d59d78910..0c7165660853 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -313,14 +313,14 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) xfer->tx_dma = dma_map_single(dev, (void *) xfer->tx_buf, xfer->len, DMA_TO_DEVICE); - if (dma_mapping_error(xfer->tx_dma)) + if (dma_mapping_error(dev, xfer->tx_dma)) return -ENOMEM; } if (xfer->rx_buf) { xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, xfer->len, DMA_FROM_DEVICE); - if (dma_mapping_error(xfer->rx_dma)) { + if (dma_mapping_error(dev, xfer->rx_dma)) { if (xfer->tx_buf) dma_unmap_single(dev, xfer->tx_dma, xfer->len, diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index 9149689c79d9..87b73e0169c5 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c @@ -334,7 +334,7 @@ static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size) hw->dma_rx_tmpbuf_size = size; hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf, size, DMA_FROM_DEVICE); - if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) { + if (dma_mapping_error(hw->dev, hw->dma_rx_tmpbuf_addr)) { kfree(hw->dma_rx_tmpbuf); hw->dma_rx_tmpbuf = 0; hw->dma_rx_tmpbuf_size = 0; @@ -378,7 +378,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_rx_addr = dma_map_single(hw->dev, (void *)t->rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_rx_addr)) + if (dma_mapping_error(hw->dev, dma_rx_addr)) dev_err(hw->dev, "rx dma map error\n"); } } else { @@ -401,7 +401,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_tx_addr = dma_map_single(hw->dev, (void *)t->tx_buf, t->len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_tx_addr)) + if (dma_mapping_error(hw->dev, dma_tx_addr)) dev_err(hw->dev, "tx dma map error\n"); } } else { diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index b1cc148036c1..f6f987bb71ca 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -836,7 +836,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (tx_buf != NULL) { t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf, len, DMA_TO_DEVICE); - if (dma_mapping_error(t->tx_dma)) { + if (dma_mapping_error(&spi->dev, t->tx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'T', len); return -EINVAL; @@ -845,7 +845,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (rx_buf != NULL) { t->rx_dma = dma_map_single(&spi->dev, rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(t->rx_dma)) { + if (dma_mapping_error(&spi->dev, t->rx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'R', len); if (tx_buf != NULL) diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 0c452c46ab07..067299d6d192 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -353,7 +353,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->rx_dma = dma_map_single(dev, drv_data->rx, drv_data->rx_map_len, DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) + if (dma_mapping_error(dev, drv_data->rx_dma)) return 0; /* Stream map the tx buffer */ @@ -361,7 +361,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) { + if (dma_mapping_error(dev, drv_data->tx_dma)) { dma_unmap_single(dev, drv_data->rx_dma, drv_data->rx_map_len, DMA_FROM_DEVICE); return 0; diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 54ac7bea5f8c..6fb77fcc4971 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -491,7 +491,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) + if (dma_mapping_error(dev, drv_data->tx_dma)) return -1; drv_data->tx_dma_needs_unmap = 1; @@ -516,7 +516,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->len, DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) + if (dma_mapping_error(dev, drv_data->rx_dma)) return -1; drv_data->rx_dma_needs_unmap = 1; } @@ -534,7 +534,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) { + if (dma_mapping_error(dev, drv_data->tx_dma)) { if (drv_data->rx_dma) { dma_unmap_single(dev, drv_data->rx_dma, diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h index db351d1296f4..a5801ae02e4b 100644 --- a/include/asm-alpha/dma-mapping.h +++ b/include/asm-alpha/dma-mapping.h @@ -24,8 +24,8 @@ pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir) #define dma_supported(dev, mask) \ pci_dma_supported(alpha_gendev_to_pci(dev), mask) -#define dma_mapping_error(addr) \ - pci_dma_mapping_error(addr) +#define dma_mapping_error(dev, addr) \ + pci_dma_mapping_error(alpha_gendev_to_pci(dev), addr) #else /* no PCI - no IOMMU. */ @@ -45,7 +45,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, #define dma_unmap_page(dev, addr, size, dir) ((void)0) #define dma_unmap_sg(dev, sg, nents, dir) ((void)0) -#define dma_mapping_error(addr) (0) +#define dma_mapping_error(dev, addr) (0) #endif /* !CONFIG_PCI */ diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index d31fd49ff79a..2a14302c17a3 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -106,7 +106,7 @@ extern dma_addr_t pci_map_page(struct pci_dev *, struct page *, /* Test for pci_map_single or pci_map_page having generated an error. */ static inline int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h index e99406a7bece..f41335ba6337 100644 --- a/include/asm-arm/dma-mapping.h +++ b/include/asm-arm/dma-mapping.h @@ -56,7 +56,7 @@ static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) /* * DMA errors are defined by all-bits-set in the DMA address. */ -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return dma_addr == ~0; } diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h index 57dc672bab8e..0399359ab5d8 100644 --- a/include/asm-avr32/dma-mapping.h +++ b/include/asm-avr32/dma-mapping.h @@ -35,7 +35,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) /* * dma_map_single can't fail as it is implemented now. */ -static inline int dma_mapping_error(dma_addr_t addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t addr) { return 0; } diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h index edc8d1bfaae2..cb2fb25ff8d9 100644 --- a/include/asm-cris/dma-mapping.h +++ b/include/asm-cris/dma-mapping.h @@ -120,7 +120,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h index 2e8966ca030d..b2898877c07b 100644 --- a/include/asm-frv/dma-mapping.h +++ b/include/asm-frv/dma-mapping.h @@ -126,7 +126,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele } static inline -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h index e2468f894d2a..82cd0cb1c3fe 100644 --- a/include/asm-generic/dma-mapping-broken.h +++ b/include/asm-generic/dma-mapping-broken.h @@ -61,7 +61,7 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, #define dma_sync_sg_for_device dma_sync_sg_for_cpu extern int -dma_mapping_error(dma_addr_t dma_addr); +dma_mapping_error(struct device *dev, dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h index 783ab9944d70..189486c3f92e 100644 --- a/include/asm-generic/dma-mapping.h +++ b/include/asm-generic/dma-mapping.h @@ -144,9 +144,9 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return pci_dma_mapping_error(dma_addr); + return pci_dma_mapping_error(to_pci_dev(dev), dma_addr); } diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h index 25c10e96b2b7..37b3706226e7 100644 --- a/include/asm-generic/pci-dma-compat.h +++ b/include/asm-generic/pci-dma-compat.h @@ -99,9 +99,9 @@ pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, } static inline int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) { - return dma_mapping_error(dma_addr); + return dma_mapping_error(&pdev->dev, dma_addr); } #endif diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index 0721a5e8271e..a6d50c77b6bf 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -54,7 +54,7 @@ typedef void ia64_mv_dma_sync_single_for_cpu (struct device *, dma_addr_t, size_ typedef void ia64_mv_dma_sync_sg_for_cpu (struct device *, struct scatterlist *, int, int); typedef void ia64_mv_dma_sync_single_for_device (struct device *, dma_addr_t, size_t, int); typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int); -typedef int ia64_mv_dma_mapping_error (dma_addr_t dma_addr); +typedef int ia64_mv_dma_mapping_error(struct device *, dma_addr_t dma_addr); typedef int ia64_mv_dma_supported (struct device *, u64); typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *); diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h index a26cdeb46a57..91f7944333d4 100644 --- a/include/asm-m68k/dma-mapping.h +++ b/include/asm-m68k/dma-mapping.h @@ -84,7 +84,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *s { } -static inline int dma_mapping_error(dma_addr_t handle) +static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) { return 0; } diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index 230b3f1b69b1..c64afb40cd06 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -42,7 +42,7 @@ extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); -extern int dma_mapping_error(dma_addr_t dma_addr); +extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); static inline int diff --git a/include/asm-mn10300/dma-mapping.h b/include/asm-mn10300/dma-mapping.h index 7c882fca9ec8..ccae8f6c6326 100644 --- a/include/asm-mn10300/dma-mapping.h +++ b/include/asm-mn10300/dma-mapping.h @@ -182,7 +182,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } static inline -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index c6c0e9ff6bde..53af696f23d2 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -248,6 +248,6 @@ void * sba_get_iommu(struct parisc_device *dev); #endif /* At the moment, we panic on error for IOMMU resource exaustion */ -#define dma_mapping_error(x) 0 +#define dma_mapping_error(dev, x) 0 #endif diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 74c549780987..c7ca45f97dd2 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -415,7 +415,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { #ifdef CONFIG_PPC64 return (dma_addr == DMA_ERROR_CODE); diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index 22cc419389fe..6c0b8a2de143 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -171,7 +171,7 @@ static inline int dma_get_cache_alignment(void) return L1_CACHE_BYTES; } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/include/asm-sparc/dma-mapping_64.h b/include/asm-sparc/dma-mapping_64.h index 38cbec76a33f..bfa64f9702d5 100644 --- a/include/asm-sparc/dma-mapping_64.h +++ b/include/asm-sparc/dma-mapping_64.h @@ -135,7 +135,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, /* No flushing needed to sync cpu writes to the device. */ } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return (dma_addr == DMA_ERROR_CODE); } diff --git a/include/asm-sparc/pci_32.h b/include/asm-sparc/pci_32.h index b93b6c79e08f..0ee949d220c0 100644 --- a/include/asm-sparc/pci_32.h +++ b/include/asm-sparc/pci_32.h @@ -154,7 +154,8 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, #define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0) -static inline int pci_dma_mapping_error(dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(struct pci_dev *pdev, + dma_addr_t dma_addr) { return (dma_addr == PCI_DMA_ERROR_CODE); } diff --git a/include/asm-sparc/pci_64.h b/include/asm-sparc/pci_64.h index f59f2571295b..4f79a54948f6 100644 --- a/include/asm-sparc/pci_64.h +++ b/include/asm-sparc/pci_64.h @@ -140,9 +140,10 @@ extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); #define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) #define PCI64_ADDR_BASE 0xfffc000000000000UL -static inline int pci_dma_mapping_error(dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(struct pci_dev *pdev, + dma_addr_t dma_addr) { - return dma_mapping_error(dma_addr); + return dma_mapping_error(&pdev->dev, dma_addr); } #ifdef CONFIG_PCI diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h index 87a715367a1b..3c034f48fdb0 100644 --- a/include/asm-x86/device.h +++ b/include/asm-x86/device.h @@ -5,6 +5,9 @@ struct dev_archdata { #ifdef CONFIG_ACPI void *acpi_handle; #endif +#ifdef CONFIG_X86_64 +struct dma_mapping_ops *dma_ops; +#endif #ifdef CONFIG_DMAR void *iommu; /* hook for IOMMU specific extension */ #endif diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index c2ddd3d1b883..0eaa9bf6011f 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h @@ -17,7 +17,8 @@ extern int panic_on_overflow; extern int force_iommu; struct dma_mapping_ops { - int (*mapping_error)(dma_addr_t dma_addr); + int (*mapping_error)(struct device *dev, + dma_addr_t dma_addr); void* (*alloc_coherent)(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); void (*free_coherent)(struct device *dev, size_t size, @@ -56,14 +57,32 @@ struct dma_mapping_ops { int is_phys; }; -extern const struct dma_mapping_ops *dma_ops; +extern struct dma_mapping_ops *dma_ops; -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) { - if (dma_ops->mapping_error) - return dma_ops->mapping_error(dma_addr); +#ifdef CONFIG_X86_32 + return dma_ops; +#else + if (unlikely(!dev) || !dev->archdata.dma_ops) + return dma_ops; + else + return dev->archdata.dma_ops; +#endif +} + +/* Make sure we keep the same behaviour */ +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ +#ifdef CONFIG_X86_32 + return 0; +#else + struct dma_mapping_ops *ops = get_dma_ops(dev); + if (ops->mapping_error) + return ops->mapping_error(dev, dma_addr); return (dma_addr == bad_dma_address); +#endif } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) @@ -83,44 +102,53 @@ static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction); + return ops->map_single(hwdev, virt_to_phys(ptr), size, direction); } static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->unmap_single) - dma_ops->unmap_single(dev, addr, size, direction); + if (ops->unmap_single) + ops->unmap_single(dev, addr, size, direction); } static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_sg(hwdev, sg, nents, direction); + return ops->map_sg(hwdev, sg, nents, direction); } static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->unmap_sg) - dma_ops->unmap_sg(hwdev, sg, nents, direction); + if (ops->unmap_sg) + ops->unmap_sg(hwdev, sg, nents, direction); } static inline void dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_for_cpu) - dma_ops->sync_single_for_cpu(hwdev, dma_handle, size, - direction); + if (ops->sync_single_for_cpu) + ops->sync_single_for_cpu(hwdev, dma_handle, size, direction); flush_write_buffers(); } @@ -128,10 +156,11 @@ static inline void dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_for_device) - dma_ops->sync_single_for_device(hwdev, dma_handle, size, - direction); + if (ops->sync_single_for_device) + ops->sync_single_for_device(hwdev, dma_handle, size, direction); flush_write_buffers(); } @@ -139,11 +168,12 @@ static inline void dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, - size, direction); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); + if (ops->sync_single_range_for_cpu) + ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, + size, direction); flush_write_buffers(); } @@ -152,11 +182,12 @@ dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(hwdev, dma_handle, - offset, size, direction); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); + if (ops->sync_single_range_for_device) + ops->sync_single_range_for_device(hwdev, dma_handle, + offset, size, direction); flush_write_buffers(); } @@ -164,9 +195,11 @@ static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_sg_for_cpu) - dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); + if (ops->sync_sg_for_cpu) + ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -174,9 +207,11 @@ static inline void dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_sg_for_device) - dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction); + if (ops->sync_sg_for_device) + ops->sync_sg_for_device(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -185,9 +220,11 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_single(dev, page_to_phys(page)+offset, - size, direction); + return ops->map_single(dev, page_to_phys(page) + offset, + size, direction); } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, diff --git a/include/asm-x86/swiotlb.h b/include/asm-x86/swiotlb.h index c706a7442633..2730b351afcf 100644 --- a/include/asm-x86/swiotlb.h +++ b/include/asm-x86/swiotlb.h @@ -35,7 +35,7 @@ extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); -extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr); +extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); extern int swiotlb_dma_supported(struct device *hwdev, u64 mask); diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h index 3c7d537dd15d..51882ae3db4d 100644 --- a/include/asm-xtensa/dma-mapping.h +++ b/include/asm-xtensa/dma-mapping.h @@ -139,7 +139,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, consistent_sync(sg_virt(sg), sg->length, dir); } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 7d51cbca49ab..75ae6d8aba4f 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -758,7 +758,7 @@ static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, } dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction); - if (!dma_mapping_error(dma_addr)) { + if (!dma_mapping_error(&c->pdev->dev, dma_addr)) { #ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 if ((sizeof(dma_addr_t) > 4) && c->pae_support) { *mptr++ = cpu_to_le32(0x7C020002); diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 4bf8cade9dbc..e530026eedf7 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -427,9 +427,9 @@ static inline int ssb_dma_mapping_error(struct ssb_device *dev, dma_addr_t addr) { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: - return pci_dma_mapping_error(addr); + return pci_dma_mapping_error(dev->bus->host_pci, addr); case SSB_BUSTYPE_SSB: - return dma_mapping_error(addr); + return dma_mapping_error(dev->dev, addr); default: __ssb_dma_not_implemented(dev); } diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 90b529f7a154..936e333e7ce5 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1590,7 +1590,7 @@ static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr) { if (dev->dma_ops) return dev->dma_ops->mapping_error(dev, dma_addr); - return dma_mapping_error(dma_addr); + return dma_mapping_error(dev->dma_device, dma_addr); } /** diff --git a/lib/swiotlb.c b/lib/swiotlb.c index d568894df8cc..977edbdbc1de 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -492,7 +492,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, */ dma_addr_t handle; handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE); - if (swiotlb_dma_mapping_error(handle)) + if (swiotlb_dma_mapping_error(hwdev, handle)) return NULL; ret = bus_to_virt(handle); @@ -824,7 +824,7 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, } int -swiotlb_dma_mapping_error(dma_addr_t dma_addr) +swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) { return (dma_addr == virt_to_bus(io_tlb_overflow_buffer)); } diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index a19b22b452a3..84d328329d98 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -169,7 +169,8 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, (void *) vec->sge[xdr_sge_no].iov_base + sge_off, sge_bytes, DMA_TO_DEVICE); - if (dma_mapping_error(sge[sge_no].addr)) + if (dma_mapping_error(xprt->sc_cm_id->device->dma_device, + sge[sge_no].addr)) goto err; sge_off = 0; sge_no++; From 1956a96de488feb05e95c08c9d5e80f63a4be2b1 Mon Sep 17 00:00:00 2001 From: Alexis Bruemmer Date: Fri, 25 Jul 2008 19:44:51 -0700 Subject: [PATCH 065/179] x86 calgary: fix handling of devices that aren't behind the Calgary The calgary code can give drivers addresses above 4GB which is very bad for hardware that is only 32bit DMA addressable. With this patch, the calgary code sets the global dma_ops to swiotlb or nommu properly, and the dma_ops of devices behind the Calgary/CalIOC2 to calgary_dma_ops. So the calgary code can handle devices safely that aren't behind the Calgary/CalIOC2. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Alexis Bruemmer Signed-off-by: FUJITA Tomonori Cc: Muli Ben-Yehuda Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/kernel/pci-calgary_64.c | 71 ++++++++++++-------------------- include/asm-x86/iommu.h | 1 + 2 files changed, 27 insertions(+), 45 deletions(-) diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 1eb86be93d7a..b67a4b1d4eae 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -37,6 +37,7 @@ #include #include #include + #include #include #include @@ -413,22 +414,6 @@ static void calgary_unmap_sg(struct device *dev, } } -static int calgary_nontranslate_map_sg(struct device* dev, - struct scatterlist *sg, int nelems, int direction) -{ - struct scatterlist *s; - int i; - - for_each_sg(sg, s, nelems, i) { - struct page *p = sg_page(s); - - BUG_ON(!p); - s->dma_address = virt_to_bus(sg_virt(s)); - s->dma_length = s->length; - } - return nelems; -} - static int calgary_map_sg(struct device *dev, struct scatterlist *sg, int nelems, int direction) { @@ -439,9 +424,6 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, unsigned long entry; int i; - if (!translation_enabled(tbl)) - return calgary_nontranslate_map_sg(dev, sg, nelems, direction); - for_each_sg(sg, s, nelems, i) { BUG_ON(!sg_page(s)); @@ -477,7 +459,6 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, size_t size, int direction) { - dma_addr_t dma_handle = bad_dma_address; void *vaddr = phys_to_virt(paddr); unsigned long uaddr; unsigned int npages; @@ -486,12 +467,7 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, uaddr = (unsigned long)vaddr; npages = num_dma_pages(uaddr, size); - if (translation_enabled(tbl)) - dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction); - else - dma_handle = virt_to_bus(vaddr); - - return dma_handle; + return iommu_alloc(dev, tbl, vaddr, npages, direction); } static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, @@ -500,9 +476,6 @@ static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, struct iommu_table *tbl = find_iommu_table(dev); unsigned int npages; - if (!translation_enabled(tbl)) - return; - npages = num_dma_pages(dma_handle, size); iommu_free(tbl, dma_handle, npages); } @@ -525,18 +498,12 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size, goto error; memset(ret, 0, size); - if (translation_enabled(tbl)) { - /* set up tces to cover the allocated range */ - mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL); - if (mapping == bad_dma_address) - goto free; - - *dma_handle = mapping; - } else /* non translated slot */ - *dma_handle = virt_to_bus(ret); - + /* set up tces to cover the allocated range */ + mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL); + if (mapping == bad_dma_address) + goto free; + *dma_handle = mapping; return ret; - free: free_pages((unsigned long)ret, get_order(size)); ret = NULL; @@ -1241,6 +1208,16 @@ static int __init calgary_init(void) goto error; } while (1); + dev = NULL; + for_each_pci_dev(dev) { + struct iommu_table *tbl; + + tbl = find_iommu_table(&dev->dev); + + if (translation_enabled(tbl)) + dev->dev.archdata.dma_ops = &calgary_dma_ops; + } + return ret; error: @@ -1262,6 +1239,7 @@ static int __init calgary_init(void) calgary_disable_translation(dev); calgary_free_bus(dev); pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ + dev->dev.archdata.dma_ops = NULL; } while (1); return ret; @@ -1503,6 +1481,10 @@ void __init detect_calgary(void) printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, debugging ? "enabled" : "disabled"); + + /* swiotlb for devices that aren't behind the Calgary. */ + if (max_pfn > MAX_DMA32_PFN) + swiotlb = 1; } return; @@ -1519,7 +1501,7 @@ int __init calgary_iommu_init(void) { int ret; - if (no_iommu || swiotlb) + if (no_iommu || (swiotlb && !calgary_detected)) return -ENODEV; if (!calgary_detected) @@ -1532,15 +1514,14 @@ int __init calgary_iommu_init(void) if (ret) { printk(KERN_ERR "PCI-DMA: Calgary init failed %d, " "falling back to no_iommu\n", ret); - if (max_pfn > MAX_DMA32_PFN) - printk(KERN_ERR "WARNING more than 4GB of memory, " - "32bit PCI may malfunction.\n"); return ret; } force_iommu = 1; bad_dma_address = 0x0; - dma_ops = &calgary_dma_ops; + /* dma_ops is set to swiotlb or nommu */ + if (!dma_ops) + dma_ops = &nommu_dma_ops; return 0; } diff --git a/include/asm-x86/iommu.h b/include/asm-x86/iommu.h index d63166fb3ab7..ecc8061904a9 100644 --- a/include/asm-x86/iommu.h +++ b/include/asm-x86/iommu.h @@ -3,6 +3,7 @@ extern void pci_iommu_shutdown(void); extern void no_iommu_init(void); +extern struct dma_mapping_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; From 7d135a5d50a08bbc53b189d79d8bdb03136f5303 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Fri, 25 Jul 2008 19:44:51 -0700 Subject: [PATCH 066/179] affs: convert s_bmlock into a mutex The semaphore s_bmlock is used as a mutex. Convert it to the mutex API. Signed-off-by: Matthias Kaehlcke Cc: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/affs/affs.h | 3 ++- fs/affs/bitmap.c | 18 +++++++++--------- fs/affs/super.c | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 223b1917093e..e9ec915f7553 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h @@ -2,6 +2,7 @@ #include #include #include +#include /* AmigaOS allows file names with up to 30 characters length. * Names longer than that will be silently truncated. If you @@ -98,7 +99,7 @@ struct affs_sb_info { gid_t s_gid; /* gid to override */ umode_t s_mode; /* mode to override */ struct buffer_head *s_root_bh; /* Cached root block. */ - struct semaphore s_bmlock; /* Protects bitmap access. */ + struct mutex s_bmlock; /* Protects bitmap access. */ struct affs_bm_info *s_bitmap; /* Bitmap infos. */ u32 s_bmap_count; /* # of bitmap blocks. */ u32 s_bmap_bits; /* # of bits in one bitmap blocks */ diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index c4a5ad09ddf2..dc5ef14bdc1c 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c @@ -45,14 +45,14 @@ affs_count_free_blocks(struct super_block *sb) if (sb->s_flags & MS_RDONLY) return 0; - down(&AFFS_SB(sb)->s_bmlock); + mutex_lock(&AFFS_SB(sb)->s_bmlock); bm = AFFS_SB(sb)->s_bitmap; free = 0; for (i = AFFS_SB(sb)->s_bmap_count; i > 0; bm++, i--) free += bm->bm_free; - up(&AFFS_SB(sb)->s_bmlock); + mutex_unlock(&AFFS_SB(sb)->s_bmlock); return free; } @@ -76,7 +76,7 @@ affs_free_block(struct super_block *sb, u32 block) bit = blk % sbi->s_bmap_bits; bm = &sbi->s_bitmap[bmap]; - down(&sbi->s_bmlock); + mutex_lock(&sbi->s_bmlock); bh = sbi->s_bmap_bh; if (sbi->s_last_bmap != bmap) { @@ -105,19 +105,19 @@ affs_free_block(struct super_block *sb, u32 block) sb->s_dirt = 1; bm->bm_free++; - up(&sbi->s_bmlock); + mutex_unlock(&sbi->s_bmlock); return; err_free: affs_warning(sb,"affs_free_block","Trying to free block %u which is already free", block); - up(&sbi->s_bmlock); + mutex_unlock(&sbi->s_bmlock); return; err_bh_read: affs_error(sb,"affs_free_block","Cannot read bitmap block %u", bm->bm_key); sbi->s_bmap_bh = NULL; sbi->s_last_bmap = ~0; - up(&sbi->s_bmlock); + mutex_unlock(&sbi->s_bmlock); return; err_range: @@ -168,7 +168,7 @@ affs_alloc_block(struct inode *inode, u32 goal) bmap = blk / sbi->s_bmap_bits; bm = &sbi->s_bitmap[bmap]; - down(&sbi->s_bmlock); + mutex_lock(&sbi->s_bmlock); if (bm->bm_free) goto find_bmap_bit; @@ -249,7 +249,7 @@ affs_alloc_block(struct inode *inode, u32 goal) mark_buffer_dirty(bh); sb->s_dirt = 1; - up(&sbi->s_bmlock); + mutex_unlock(&sbi->s_bmlock); pr_debug("%d\n", blk); return blk; @@ -259,7 +259,7 @@ affs_alloc_block(struct inode *inode, u32 goal) sbi->s_bmap_bh = NULL; sbi->s_last_bmap = ~0; err_full: - up(&sbi->s_bmlock); + mutex_unlock(&sbi->s_bmlock); pr_debug("failed\n"); return 0; } diff --git a/fs/affs/super.c b/fs/affs/super.c index d214837d5e42..4e0309566406 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -290,7 +290,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) if (!sbi) return -ENOMEM; sb->s_fs_info = sbi; - init_MUTEX(&sbi->s_bmlock); + mutex_init(&sbi->s_bmlock); if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block, &blocksize,&sbi->s_prefix, From 75b25b4cabb7ce956c36442bf8225659b1864866 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Fri, 25 Jul 2008 19:44:52 -0700 Subject: [PATCH 067/179] bfs: assorted cleanups This patch makes the following cleanups: o removing an unused variable from bfs_fill_super(); o removing unneeded blank spaces from pointer definitions. Signed-off-by: Dmitri Vorobiev Cc: Tigran Aivazian Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/bfs/bfs.h | 4 ++-- fs/bfs/inode.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h index 70f5d3a8eede..d1a6cd10afce 100644 --- a/fs/bfs/bfs.h +++ b/fs/bfs/bfs.h @@ -16,8 +16,8 @@ struct bfs_sb_info { unsigned long si_freei; unsigned long si_lf_eblk; unsigned long si_lasti; - unsigned long * si_imap; - struct buffer_head * si_sbh; /* buffer header w/superblock */ + unsigned long *si_imap; + struct buffer_head *si_sbh; /* buffer header w/superblock */ }; /* diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 8db623838b50..c8b3982e11ca 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -380,7 +380,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) struct bfs_inode *di; int block = (i - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; - unsigned long sblock, eblock; + unsigned long eblock; if (!off) { brelse(bh); @@ -399,7 +399,6 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) set_bit(i, info->si_imap); info->si_freeb -= BFS_FILEBLOCKS(di); - sblock = le32_to_cpu(di->i_sblock); eblock = le32_to_cpu(di->i_eblock); if (eblock > info->si_lf_eblk) info->si_lf_eblk = eblock; From 3f165e4cf2af042af7d2440d688299c0d2a48b1f Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Fri, 25 Jul 2008 19:44:54 -0700 Subject: [PATCH 068/179] bfs: kill BKL Replace the BKL-based locking scheme used in the bfs driver by a private filesystem-wide mutex. Signed-off-by: Dmitri Vorobiev Cc: Tigran Aivazian Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/bfs/bfs.h | 1 + fs/bfs/dir.c | 46 ++++++++++++++++++++++++++-------------------- fs/bfs/file.c | 4 ++-- fs/bfs/inode.c | 24 +++++++++++++++--------- 4 files changed, 44 insertions(+), 31 deletions(-) diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h index d1a6cd10afce..7109e451abf7 100644 --- a/fs/bfs/bfs.h +++ b/fs/bfs/bfs.h @@ -18,6 +18,7 @@ struct bfs_sb_info { unsigned long si_lasti; unsigned long *si_imap; struct buffer_head *si_sbh; /* buffer header w/superblock */ + struct mutex bfs_lock; }; /* diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 034950cb3cbe..87ee5ccee348 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -32,16 +32,17 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) struct inode *dir = f->f_path.dentry->d_inode; struct buffer_head *bh; struct bfs_dirent *de; + struct bfs_sb_info *info = BFS_SB(dir->i_sb); unsigned int offset; int block; - lock_kernel(); + mutex_lock(&info->bfs_lock); if (f->f_pos & (BFS_DIRENT_SIZE - 1)) { printf("Bad f_pos=%08lx for %s:%08lx\n", (unsigned long)f->f_pos, dir->i_sb->s_id, dir->i_ino); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return -EBADF; } @@ -61,7 +62,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) le16_to_cpu(de->ino), DT_UNKNOWN) < 0) { brelse(bh); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return 0; } } @@ -71,7 +72,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) brelse(bh); } - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return 0; } @@ -95,10 +96,10 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, inode = new_inode(s); if (!inode) return -ENOSPC; - lock_kernel(); + mutex_lock(&info->bfs_lock); ino = find_first_zero_bit(info->si_imap, info->si_lasti); if (ino > info->si_lasti) { - unlock_kernel(); + mutex_unlock(&info->bfs_lock); iput(inode); return -ENOSPC; } @@ -125,10 +126,10 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, if (err) { inode_dec_link_count(inode); iput(inode); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return err; } - unlock_kernel(); + mutex_unlock(&info->bfs_lock); d_instantiate(dentry, inode); return 0; } @@ -139,22 +140,23 @@ static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry, struct inode *inode = NULL; struct buffer_head *bh; struct bfs_dirent *de; + struct bfs_sb_info *info = BFS_SB(dir->i_sb); if (dentry->d_name.len > BFS_NAMELEN) return ERR_PTR(-ENAMETOOLONG); - lock_kernel(); + mutex_lock(&info->bfs_lock); bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); if (bh) { unsigned long ino = (unsigned long)le16_to_cpu(de->ino); brelse(bh); inode = bfs_iget(dir->i_sb, ino); if (IS_ERR(inode)) { - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return ERR_CAST(inode); } } - unlock_kernel(); + mutex_unlock(&info->bfs_lock); d_add(dentry, inode); return NULL; } @@ -163,13 +165,14 @@ static int bfs_link(struct dentry *old, struct inode *dir, struct dentry *new) { struct inode *inode = old->d_inode; + struct bfs_sb_info *info = BFS_SB(inode->i_sb); int err; - lock_kernel(); + mutex_lock(&info->bfs_lock); err = bfs_add_entry(dir, new->d_name.name, new->d_name.len, inode->i_ino); if (err) { - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return err; } inc_nlink(inode); @@ -177,19 +180,19 @@ static int bfs_link(struct dentry *old, struct inode *dir, mark_inode_dirty(inode); atomic_inc(&inode->i_count); d_instantiate(new, inode); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return 0; } static int bfs_unlink(struct inode *dir, struct dentry *dentry) { int error = -ENOENT; - struct inode *inode; + struct inode *inode = dentry->d_inode; struct buffer_head *bh; struct bfs_dirent *de; + struct bfs_sb_info *info = BFS_SB(inode->i_sb); - inode = dentry->d_inode; - lock_kernel(); + mutex_lock(&info->bfs_lock); bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de); if (!bh || (le16_to_cpu(de->ino) != inode->i_ino)) goto out_brelse; @@ -210,7 +213,7 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry) out_brelse: brelse(bh); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return error; } @@ -220,6 +223,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode, *new_inode; struct buffer_head *old_bh, *new_bh; struct bfs_dirent *old_de, *new_de; + struct bfs_sb_info *info; int error = -ENOENT; old_bh = new_bh = NULL; @@ -227,7 +231,9 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (S_ISDIR(old_inode->i_mode)) return -EINVAL; - lock_kernel(); + info = BFS_SB(old_inode->i_sb); + + mutex_lock(&info->bfs_lock); old_bh = bfs_find_entry(old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de); @@ -264,7 +270,7 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, error = 0; end_rename: - unlock_kernel(); + mutex_unlock(&info->bfs_lock); brelse(old_bh); brelse(new_bh); return error; diff --git a/fs/bfs/file.c b/fs/bfs/file.c index b11e63e8fbcd..6a021265f018 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c @@ -99,7 +99,7 @@ static int bfs_get_block(struct inode *inode, sector_t block, return -ENOSPC; /* The rest has to be protected against itself. */ - lock_kernel(); + mutex_lock(&info->bfs_lock); /* * If the last data block for this file is the last allocated @@ -151,7 +151,7 @@ static int bfs_get_block(struct inode *inode, sector_t block, mark_buffer_dirty(sbh); map_bh(bh_result, sb, phys); out: - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return err; } diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index c8b3982e11ca..053e690ec9ed 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -104,6 +104,7 @@ static int bfs_write_inode(struct inode *inode, int unused) struct bfs_inode *di; struct buffer_head *bh; int block, off; + struct bfs_sb_info *info = BFS_SB(inode->i_sb); dprintf("ino=%08x\n", ino); @@ -112,13 +113,13 @@ static int bfs_write_inode(struct inode *inode, int unused) return -EIO; } - lock_kernel(); + mutex_lock(&info->bfs_lock); block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; bh = sb_bread(inode->i_sb, block); if (!bh) { printf("Unable to read inode %s:%08x\n", inode->i_sb->s_id, ino); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return -EIO; } @@ -145,7 +146,7 @@ static int bfs_write_inode(struct inode *inode, int unused) mark_buffer_dirty(bh); brelse(bh); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return 0; } @@ -170,7 +171,7 @@ static void bfs_delete_inode(struct inode *inode) inode->i_size = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; - lock_kernel(); + mutex_lock(&info->bfs_lock); mark_inode_dirty(inode); block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1; @@ -178,7 +179,7 @@ static void bfs_delete_inode(struct inode *inode) if (!bh) { printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, ino); - unlock_kernel(); + mutex_unlock(&info->bfs_lock); return; } off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; @@ -204,14 +205,16 @@ static void bfs_delete_inode(struct inode *inode) info->si_lf_eblk = bi->i_sblock - 1; mark_buffer_dirty(info->si_sbh); } - unlock_kernel(); + mutex_unlock(&info->bfs_lock); clear_inode(inode); } static void bfs_put_super(struct super_block *s) { struct bfs_sb_info *info = BFS_SB(s); + brelse(info->si_sbh); + mutex_destroy(&info->bfs_lock); kfree(info->si_imap); kfree(info); s->s_fs_info = NULL; @@ -236,11 +239,13 @@ static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf) static void bfs_write_super(struct super_block *s) { - lock_kernel(); + struct bfs_sb_info *info = BFS_SB(s); + + mutex_lock(&info->bfs_lock); if (!(s->s_flags & MS_RDONLY)) - mark_buffer_dirty(BFS_SB(s)->si_sbh); + mark_buffer_dirty(info->si_sbh); s->s_dirt = 0; - unlock_kernel(); + mutex_unlock(&info->bfs_lock); } static struct kmem_cache *bfs_inode_cachep; @@ -409,6 +414,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) s->s_dirt = 1; } dump_imap("read_super", s); + mutex_init(&info->bfs_lock); return 0; out: From 929dfb24fbcd60e2544b2de7bfb4a68da4dfc747 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:44:54 -0700 Subject: [PATCH 069/179] parport/share.c: proper externs This patch adds proper externs for parport_default_timeslice and parport_default_spintime in include/linux/parport.h Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/parport/procfs.c | 3 --- include/linux/parport.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c index d950fc34320a..554e11f9e1ce 100644 --- a/drivers/parport/procfs.c +++ b/drivers/parport/procfs.c @@ -429,9 +429,6 @@ struct parport_default_sysctl_table ctl_table dev_dir[2]; }; -extern unsigned long parport_default_timeslice; -extern int parport_default_spintime; - static struct parport_default_sysctl_table parport_default_sysctl_table = { .sysctl_header = NULL, diff --git a/include/linux/parport.h b/include/linux/parport.h index dcb9e01a69ca..6a0d7cdb5774 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -560,5 +560,8 @@ extern int parport_device_proc_unregister(struct pardevice *device); #endif /* !CONFIG_PARPORT_NOT_PC */ +extern unsigned long parport_default_timeslice; +extern int parport_default_spintime; + #endif /* __KERNEL__ */ #endif /* _PARPORT_H_ */ From d99a0344aefbfe991147472d46a6ee1c1a0043de Mon Sep 17 00:00:00 2001 From: Andre Haupt Date: Fri, 25 Jul 2008 19:44:55 -0700 Subject: [PATCH 070/179] parport: remove superfluous local variable Signed-off-by: Andre Haupt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/parport/ieee1284.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index 0338b0912674..e97059415ab4 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c @@ -199,8 +199,6 @@ int parport_wait_peripheral(struct parport *port, /* 40ms of slow polling. */ deadline = jiffies + msecs_to_jiffies(40); while (time_before (jiffies, deadline)) { - int ret; - if (signal_pending (current)) return -EINTR; From adbd321a17ccdd26752b57e68ab0a97a4aebc299 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Fri, 25 Jul 2008 19:44:56 -0700 Subject: [PATCH 071/179] parport_pc: add base_hi BAR for oxsemi_840 Use the 2nd BAR for the oxsemi_840 chip as BAR for base_hi. Tested with: Parallel controller [0701]: Oxford Semiconductor Ltd VScom 011H-EP1 1 port parallel adaptor [1415:8403] (prog-if 03 [IEEE1284]) This patch is needed to make 'TRISTATE' work with that adaptor. Signed-off-by: Bernhard Walle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/parport/parport_pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index e0c2a4584ec6..8a846adf1dcf 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -2867,7 +2867,7 @@ static struct parport_pc_pci { * and 840 locks up if you write 1 to bit 2! */ /* oxsemi_952 */ { 1, { { 0, 1 }, } }, /* oxsemi_954 */ { 1, { { 0, -1 }, } }, - /* oxsemi_840 */ { 1, { { 0, -1 }, } }, + /* oxsemi_840 */ { 1, { { 0, 1 }, } }, /* aks_0100 */ { 1, { { 0, -1 }, } }, /* mobility_pp */ { 1, { { 0, 1 }, } }, /* netmos_9705 */ { 1, { { 0, -1 }, } }, /* untested */ From 061991ec6edceda48d60f7a53e17b8d3416266ae Mon Sep 17 00:00:00 2001 From: LE DISEZ Erwan Date: Fri, 25 Jul 2008 19:44:56 -0700 Subject: [PATCH 072/179] tpm: add support for Broadcom TPM TIS device HID Signed-off-by: Rajiv Andrade Cc: Marcel Selhorst Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_tis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index c7a977bc03e8..ed1879c0dd8d 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -622,6 +622,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { {"ATM1200", 0}, /* Atmel */ {"IFX0102", 0}, /* Infineon */ {"BCM0101", 0}, /* Broadcom */ + {"BCM0102", 0}, /* Broadcom */ {"NSC1200", 0}, /* National */ {"ICO0102", 0}, /* Intel */ /* Add new here */ From 3bd60464e3224820bc413c45ea2cc371edc63e9d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:44:58 -0700 Subject: [PATCH 073/179] tpm_bios.c: make 2 structs static This patch makes two needlessly global structs static. Signed-off-by: Adrian Bunk Acked-by: Marcel Selhorst Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm_bios.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 60a2d2630e36..68f052b42ed7 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -448,7 +448,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, goto out; } -const struct file_operations tpm_ascii_bios_measurements_ops = { +static const struct file_operations tpm_ascii_bios_measurements_ops = { .open = tpm_ascii_bios_measurements_open, .read = seq_read, .llseek = seq_lseek, @@ -486,7 +486,7 @@ static int tpm_binary_bios_measurements_open(struct inode *inode, goto out; } -const struct file_operations tpm_binary_bios_measurements_ops = { +static const struct file_operations tpm_binary_bios_measurements_ops = { .open = tpm_binary_bios_measurements_open, .read = seq_read, .llseek = seq_lseek, From ec288bd37e1925f513db40871bc46115cf7fb733 Mon Sep 17 00:00:00 2001 From: Marcin Obara Date: Fri, 25 Jul 2008 19:44:59 -0700 Subject: [PATCH 074/179] tpm: increase size of internal TPM response buffers This patch increases size of driver internal response buffers. Some TPM responses defined in TCG TPM Specification Version 1.2 Revision 103 have increased size and do not fit previously defined buffers. Some TPM responses do not have fixed size, so bigger response buffers have to be allocated. 200B buffers should be enough. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Marcin Obara Cc: Marcel Selhorst Cc: Kylene Jo Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 124 ++++++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 31 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index e1fc193d9396..f354d720b777 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -580,91 +580,133 @@ void tpm_continue_selftest(struct tpm_chip *chip) } EXPORT_SYMBOL_GPL(tpm_continue_selftest); +#define TPM_INTERNAL_RESULT_SIZE 200 + ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, char *buf) { - u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; + u8 *data; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; + data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; - rc = transmit_cmd(chip, data, sizeof(data), - "attemtping to determine the permanent state"); - if (rc) + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + "attemtping to determine the permanent enabled state"); + if (rc) { + kfree(data); return 0; - return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]); + } + + rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]); + + kfree(data); + return rc; } EXPORT_SYMBOL_GPL(tpm_show_enabled); ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, char *buf) { - u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; + u8 *data; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; + data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; - rc = transmit_cmd(chip, data, sizeof(data), - "attemtping to determine the permanent state"); - if (rc) + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, + "attemtping to determine the permanent active state"); + if (rc) { + kfree(data); return 0; - return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]); + } + + rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]); + + kfree(data); + return rc; } EXPORT_SYMBOL_GPL(tpm_show_active); ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, char *buf) { - u8 data[sizeof(tpm_cap)]; + u8 *data; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; + data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER; - rc = transmit_cmd(chip, data, sizeof(data), + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the owner state"); - if (rc) + if (rc) { + kfree(data); return 0; - return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]); + } + + rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]); + + kfree(data); + return rc; } EXPORT_SYMBOL_GPL(tpm_show_owned); ssize_t tpm_show_temp_deactivated(struct device * dev, struct device_attribute * attr, char *buf) { - u8 data[sizeof(tpm_cap)]; + u8 *data; ssize_t rc; struct tpm_chip *chip = dev_get_drvdata(dev); if (chip == NULL) return -ENODEV; + data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_FLAG; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL; - rc = transmit_cmd(chip, data, sizeof(data), + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the temporary state"); - if (rc) + if (rc) { + kfree(data); return 0; - return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]); + } + + rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]); + + kfree(data); + return rc; } EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated); @@ -678,7 +720,7 @@ static const u8 pcrread[] = { ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) { - u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)]; + u8 *data; ssize_t rc; int i, j, num_pcrs; __be32 index; @@ -688,21 +730,27 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, if (chip == NULL) return -ENODEV; + data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR; - rc = transmit_cmd(chip, data, sizeof(data), + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the number of PCRS"); - if (rc) + if (rc) { + kfree(data); return 0; + } num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); for (i = 0; i < num_pcrs; i++) { memcpy(data, pcrread, sizeof(pcrread)); index = cpu_to_be32(i); memcpy(data + 10, &index, 4); - rc = transmit_cmd(chip, data, sizeof(data), + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, "attempting to read a PCR"); if (rc) goto out; @@ -712,6 +760,7 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, str += sprintf(str, "\n"); } out: + kfree(data); return str - buf; } EXPORT_SYMBOL_GPL(tpm_show_pcrs); @@ -795,7 +844,7 @@ static const u8 cap_version[] = { ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, char *buf) { - u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; + u8 *data; ssize_t rc; char *str = buf; @@ -803,21 +852,27 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, if (chip == NULL) return -ENODEV; + data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; - rc = transmit_cmd(chip, data, sizeof(data), + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the manufacturer"); - if (rc) + if (rc) { + kfree(data); return 0; + } str += sprintf(str, "Manufacturer: 0x%x\n", be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); memcpy(data, cap_version, sizeof(cap_version)); data[CAP_VERSION_IDX] = CAP_VERSION_1_1; - rc = transmit_cmd(chip, data, sizeof(data), + rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the 1.1 version"); if (rc) goto out; @@ -828,6 +883,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, (int) data[17]); out: + kfree(data); return str - buf; } EXPORT_SYMBOL_GPL(tpm_show_caps); @@ -835,7 +891,7 @@ EXPORT_SYMBOL_GPL(tpm_show_caps); ssize_t tpm_show_caps_1_2(struct device * dev, struct device_attribute * attr, char *buf) { - u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; + u8 *data; ssize_t len; char *str = buf; @@ -843,15 +899,20 @@ ssize_t tpm_show_caps_1_2(struct device * dev, if (chip == NULL) return -ENODEV; + data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, tpm_cap, sizeof(tpm_cap)); data[TPM_CAP_IDX] = TPM_CAP_PROP; data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; - if ((len = tpm_transmit(chip, data, sizeof(data))) <= - TPM_ERROR_SIZE) { + len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE); + if (len <= TPM_ERROR_SIZE) { dev_dbg(chip->dev, "A TPM error (%d) occurred " "attempting to determine the manufacturer\n", be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); + kfree(data); return 0; } @@ -861,8 +922,8 @@ ssize_t tpm_show_caps_1_2(struct device * dev, memcpy(data, cap_version, sizeof(cap_version)); data[CAP_VERSION_IDX] = CAP_VERSION_1_2; - if ((len = tpm_transmit(chip, data, sizeof(data))) <= - TPM_ERROR_SIZE) { + len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE); + if (len <= TPM_ERROR_SIZE) { dev_err(chip->dev, "A TPM error (%d) occurred " "attempting to determine the 1.2 version\n", be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); @@ -874,6 +935,7 @@ ssize_t tpm_show_caps_1_2(struct device * dev, (int) data[19]); out: + kfree(data); return str - buf; } EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); From 0147600172b4a5d261165d1aa5ef818d84da1557 Mon Sep 17 00:00:00 2001 From: Michael Halcrow Date: Fri, 25 Jul 2008 19:45:00 -0700 Subject: [PATCH 075/179] tpm: Use correct data types for sizes in tpm_write() and tpm_read() Use the correct data types for the size parameters in tpm_write() and tpm_read(). Note that rw_verify_area() makes sure that this bug cannot be exploited to produce a buffer overrun. Signed-off-by: Michael Halcrow Cc: Marcel Selhorst Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index f354d720b777..ae766d868454 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1028,7 +1028,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf, size_t size, loff_t *off) { struct tpm_chip *chip = file->private_data; - int in_size = size, out_size; + size_t in_size = size, out_size; /* cannot perform a write until the read has cleared either via tpm_read or a user_read_timer timeout */ @@ -1063,7 +1063,7 @@ ssize_t tpm_read(struct file *file, char __user *buf, size_t size, loff_t *off) { struct tpm_chip *chip = file->private_data; - int ret_size; + ssize_t ret_size; del_singleshot_timer_sync(&chip->user_read_timer); flush_scheduled_work(); From b77899985bdfd85a8e5a6e485033a9b4713d2471 Mon Sep 17 00:00:00 2001 From: Alex Dubov Date: Fri, 25 Jul 2008 19:45:00 -0700 Subject: [PATCH 076/179] memstick: allow "set_param" method to return an error code Some controllers (Jmicron, for instance) can report temporal failure condition during power-on. It is desirable to account for this using a return value of "set_param" device method. The return value can also be handy to distinguish between supported and unsupported device parameters in run time. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Alex Dubov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/core/memstick.c | 18 ++++++--- drivers/memstick/host/jmb38x_ms.c | 67 ++++++++++++++++++++++--------- drivers/memstick/host/tifm_ms.c | 17 ++++---- include/linux/memstick.h | 2 +- 4 files changed, 71 insertions(+), 33 deletions(-) diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 61b98c333cb0..3c7d9a79c1ea 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -415,10 +415,14 @@ static struct memstick_dev *memstick_alloc_card(struct memstick_host *host) return NULL; } -static void memstick_power_on(struct memstick_host *host) +static int memstick_power_on(struct memstick_host *host) { - host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); - host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); + int rc = host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); + + if (!rc) + rc = host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); + + return rc; } static void memstick_check(struct work_struct *work) @@ -573,11 +577,15 @@ EXPORT_SYMBOL(memstick_suspend_host); */ void memstick_resume_host(struct memstick_host *host) { + int rc = 0; + mutex_lock(&host->lock); if (host->card) - memstick_power_on(host); + rc = memstick_power_on(host); mutex_unlock(&host->lock); - memstick_detect_change(host); + + if (!rc) + memstick_detect_change(host); } EXPORT_SYMBOL(memstick_resume_host); diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 4e3bfbcdf155..9d82e67737db 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -609,36 +609,68 @@ static void jmb38x_ms_request(struct memstick_host *msh) spin_unlock_irqrestore(&host->lock, flags); } -static void jmb38x_ms_reset(struct jmb38x_ms_host *host) +static int jmb38x_ms_reset(struct jmb38x_ms_host *host) { - unsigned int host_ctl = readl(host->addr + HOST_CONTROL); + int cnt; - writel(HOST_CONTROL_RESET_REQ, host->addr + HOST_CONTROL); + writel(HOST_CONTROL_RESET_REQ | HOST_CONTROL_CLOCK_EN + | readl(host->addr + HOST_CONTROL), + host->addr + HOST_CONTROL); + mmiowb(); + + for (cnt = 0; cnt < 20; ++cnt) { + if (!(HOST_CONTROL_RESET_REQ + & readl(host->addr + HOST_CONTROL))) + goto reset_next; - while (HOST_CONTROL_RESET_REQ - & (host_ctl = readl(host->addr + HOST_CONTROL))) { ndelay(20); - dev_dbg(&host->chip->pdev->dev, "reset %08x\n", host_ctl); } + dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); + return -EIO; - writel(HOST_CONTROL_RESET, host->addr + HOST_CONTROL); +reset_next: + writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN + | readl(host->addr + HOST_CONTROL), + host->addr + HOST_CONTROL); + mmiowb(); + + for (cnt = 0; cnt < 20; ++cnt) { + if (!(HOST_CONTROL_RESET + & readl(host->addr + HOST_CONTROL))) + goto reset_ok; + + ndelay(20); + } + dev_dbg(&host->chip->pdev->dev, "reset timeout\n"); + return -EIO; + +reset_ok: mmiowb(); writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE); writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE); + return 0; } -static void jmb38x_ms_set_param(struct memstick_host *msh, - enum memstick_param param, - int value) +static int jmb38x_ms_set_param(struct memstick_host *msh, + enum memstick_param param, + int value) { struct jmb38x_ms_host *host = memstick_priv(msh); unsigned int host_ctl = readl(host->addr + HOST_CONTROL); unsigned int clock_ctl = CLOCK_CONTROL_40MHZ, clock_delay = 0; + int rc = 0; switch (param) { case MEMSTICK_POWER: if (value == MEMSTICK_POWER_ON) { - jmb38x_ms_reset(host); + rc = jmb38x_ms_reset(host); + if (rc) + return rc; + + host_ctl = 7; + host_ctl |= HOST_CONTROL_POWER_EN + | HOST_CONTROL_CLOCK_EN; + writel(host_ctl, host->addr + HOST_CONTROL); writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 : PAD_PU_PD_ON_MS_SOCK0, @@ -647,11 +679,7 @@ static void jmb38x_ms_set_param(struct memstick_host *msh, writel(PAD_OUTPUT_ENABLE_MS, host->addr + PAD_OUTPUT_ENABLE); - host_ctl = 7; - host_ctl |= HOST_CONTROL_POWER_EN - | HOST_CONTROL_CLOCK_EN; - writel(host_ctl, host->addr + HOST_CONTROL); - + msleep(10); dev_dbg(&host->chip->pdev->dev, "power on\n"); } else if (value == MEMSTICK_POWER_OFF) { host_ctl &= ~(HOST_CONTROL_POWER_EN @@ -660,7 +688,8 @@ static void jmb38x_ms_set_param(struct memstick_host *msh, writel(0, host->addr + PAD_OUTPUT_ENABLE); writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD); dev_dbg(&host->chip->pdev->dev, "power off\n"); - } + } else + return -EINVAL; break; case MEMSTICK_INTERFACE: host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); @@ -686,12 +715,14 @@ static void jmb38x_ms_set_param(struct memstick_host *msh, host_ctl &= ~HOST_CONTROL_REI; clock_ctl = CLOCK_CONTROL_60MHZ; clock_delay = 0; - } + } else + return -EINVAL; writel(host_ctl, host->addr + HOST_CONTROL); writel(clock_ctl, host->addr + CLOCK_CONTROL); writel(clock_delay, host->addr + CLOCK_DELAY); break; }; + return 0; } #ifdef CONFIG_PM diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 8577de4ebb0e..14458764588c 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c @@ -489,15 +489,12 @@ static void tifm_ms_request(struct memstick_host *msh) return; } -static void tifm_ms_set_param(struct memstick_host *msh, - enum memstick_param param, - int value) +static int tifm_ms_set_param(struct memstick_host *msh, + enum memstick_param param, + int value) { struct tifm_ms *host = memstick_priv(msh); struct tifm_dev *sock = host->dev; - unsigned long flags; - - spin_lock_irqsave(&sock->lock, flags); switch (param) { case MEMSTICK_POWER: @@ -512,7 +509,8 @@ static void tifm_ms_set_param(struct memstick_host *msh, writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, sock->addr + SOCK_MS_SYSTEM); writel(0xffffffff, sock->addr + SOCK_MS_STATUS); - } + } else + return -EINVAL; break; case MEMSTICK_INTERFACE: if (value == MEMSTICK_SERIAL) { @@ -525,11 +523,12 @@ static void tifm_ms_set_param(struct memstick_host *msh, writel(TIFM_CTRL_FAST_CLK | readl(sock->addr + SOCK_CONTROL), sock->addr + SOCK_CONTROL); - } + } else + return -EINVAL; break; }; - spin_unlock_irqrestore(&sock->lock, flags); + return 0; } static void tifm_ms_abort(unsigned long data) diff --git a/include/linux/memstick.h b/include/linux/memstick.h index 37a5cdb03918..2fe599c66d52 100644 --- a/include/linux/memstick.h +++ b/include/linux/memstick.h @@ -284,7 +284,7 @@ struct memstick_host { /* Notify the host that some requests are pending. */ void (*request)(struct memstick_host *host); /* Set host IO parameters (power, clock, etc). */ - void (*set_param)(struct memstick_host *host, + int (*set_param)(struct memstick_host *host, enum memstick_param param, int value); unsigned long private[0] ____cacheline_aligned; From 17017d8d2c005734d7088d8281ce2daab8fcb097 Mon Sep 17 00:00:00 2001 From: Alex Dubov Date: Fri, 25 Jul 2008 19:45:01 -0700 Subject: [PATCH 077/179] memstick: add "start" and "stop" methods to memstick device In some cases it may be desirable to ensure that associated driver is not going to access the media in some period of time. "start" and "stop" methods are provided therefore to allow it. Signed-off-by: Alex Dubov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/core/memstick.c | 11 +++++++--- drivers/memstick/core/mspro_block.c | 33 +++++++++++++++++++++++++++++ include/linux/memstick.h | 4 ++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 3c7d9a79c1ea..7162f772bbfb 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -433,8 +433,11 @@ static void memstick_check(struct work_struct *work) dev_dbg(&host->dev, "memstick_check started\n"); mutex_lock(&host->lock); - if (!host->card) - memstick_power_on(host); + if (!host->card) { + if (memstick_power_on(host)) + goto out_power_off; + } else + host->card->stop(host->card); card = memstick_alloc_card(host); @@ -452,7 +455,8 @@ static void memstick_check(struct work_struct *work) || !(host->card->check(host->card))) { device_unregister(&host->card->dev); host->card = NULL; - } + } else + host->card->start(host->card); } if (!host->card) { @@ -465,6 +469,7 @@ static void memstick_check(struct work_struct *work) kfree(card); } +out_power_off: if (!host->card) host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 477d0fb6e588..004ac4d176d9 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -752,6 +752,37 @@ static int mspro_block_has_request(struct mspro_block_data *msb) return rc; } +static void mspro_block_stop(struct memstick_dev *card) +{ + struct mspro_block_data *msb = memstick_get_drvdata(card); + int rc = 0; + unsigned long flags; + + while (1) { + spin_lock_irqsave(&msb->q_lock, flags); + if (!msb->has_request) { + blk_stop_queue(msb->queue); + rc = 1; + } + spin_unlock_irqrestore(&msb->q_lock, flags); + + if (rc) + break; + + wait_for_completion(&card->mrq_complete); + } +} + +static void mspro_block_start(struct memstick_dev *card) +{ + struct mspro_block_data *msb = memstick_get_drvdata(card); + unsigned long flags; + + spin_lock_irqsave(&msb->q_lock, flags); + blk_start_queue(msb->queue); + spin_unlock_irqrestore(&msb->q_lock, flags); +} + static int mspro_block_queue_thread(void *data) { struct memstick_dev *card = data; @@ -1272,6 +1303,8 @@ static int mspro_block_probe(struct memstick_dev *card) rc = mspro_block_init_disk(card); if (!rc) { card->check = mspro_block_check_card; + card->stop = mspro_block_stop; + card->start = mspro_block_start; return 0; } diff --git a/include/linux/memstick.h b/include/linux/memstick.h index 2fe599c66d52..a9f998a3f48b 100644 --- a/include/linux/memstick.h +++ b/include/linux/memstick.h @@ -263,6 +263,10 @@ struct memstick_dev { /* Get next request from the media driver. */ int (*next_request)(struct memstick_dev *card, struct memstick_request **mrq); + /* Tell the media driver to stop doing things */ + void (*stop)(struct memstick_dev *card); + /* Allow the media driver to continue */ + void (*start)(struct memstick_dev *card); struct device dev; }; From f1d82698029b92a88f5500b99f66514b6dee2bc3 Mon Sep 17 00:00:00 2001 From: Alex Dubov Date: Fri, 25 Jul 2008 19:45:02 -0700 Subject: [PATCH 078/179] memstick: use fully asynchronous request processing Instead of using a separate thread to pump requests from block layer queue to memstick, do so inline, utilizing the callback design of the memstick. [akpm@linux-foundation.org: fix warnings] Signed-off-by: Alex Dubov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/core/memstick.c | 7 +- drivers/memstick/core/mspro_block.c | 336 +++++++++++++--------------- drivers/memstick/host/jmb38x_ms.c | 35 ++- drivers/memstick/host/tifm_ms.c | 49 ++-- 4 files changed, 214 insertions(+), 213 deletions(-) diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 7162f772bbfb..a38005008a20 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -249,8 +249,11 @@ EXPORT_SYMBOL(memstick_next_req); */ void memstick_new_req(struct memstick_host *host) { - host->retries = cmd_retries; - host->request(host); + if (host->card) { + host->retries = cmd_retries; + INIT_COMPLETION(host->card->mrq_complete); + host->request(host); + } } EXPORT_SYMBOL(memstick_new_req); diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 004ac4d176d9..44b1817f2f2f 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -136,9 +136,8 @@ struct mspro_block_data { unsigned int caps; struct gendisk *disk; struct request_queue *queue; + struct request *block_req; spinlock_t q_lock; - wait_queue_head_t q_wait; - struct task_struct *q_thread; unsigned short page_size; unsigned short cylinders; @@ -147,9 +146,10 @@ struct mspro_block_data { unsigned char system; unsigned char read_only:1, - active:1, + eject:1, has_request:1, - data_dir:1; + data_dir:1, + active:1; unsigned char transfer_cmd; int (*mrq_handler)(struct memstick_dev *card, @@ -160,12 +160,14 @@ struct mspro_block_data { struct scatterlist req_sg[MSPRO_BLOCK_MAX_SEGS]; unsigned int seg_count; unsigned int current_seg; - unsigned short current_page; + unsigned int current_page; }; static DEFINE_IDR(mspro_block_disk_idr); static DEFINE_MUTEX(mspro_block_disk_lock); +static int mspro_block_complete_req(struct memstick_dev *card, int error); + /*** Block device ***/ static int mspro_block_bd_open(struct inode *inode, struct file *filp) @@ -197,8 +199,10 @@ static int mspro_block_disk_release(struct gendisk *disk) mutex_lock(&mspro_block_disk_lock); - if (msb->usage_count) { - msb->usage_count--; + if (msb) { + if (msb->usage_count) + msb->usage_count--; + if (!msb->usage_count) { kfree(msb); disk->private_data = NULL; @@ -523,11 +527,13 @@ static int h_mspro_block_req_init(struct memstick_dev *card, static int h_mspro_block_default(struct memstick_dev *card, struct memstick_request **mrq) { - complete(&card->mrq_complete); - if (!(*mrq)->error) - return -EAGAIN; - else - return (*mrq)->error; + return mspro_block_complete_req(card, (*mrq)->error); +} + +static int h_mspro_block_default_bad(struct memstick_dev *card, + struct memstick_request **mrq) +{ + return -ENXIO; } static int h_mspro_block_get_ro(struct memstick_dev *card, @@ -535,44 +541,30 @@ static int h_mspro_block_get_ro(struct memstick_dev *card, { struct mspro_block_data *msb = memstick_get_drvdata(card); - if ((*mrq)->error) { - complete(&card->mrq_complete); - return (*mrq)->error; + if (!(*mrq)->error) { + if ((*mrq)->data[offsetof(struct ms_status_register, status0)] + & MEMSTICK_STATUS0_WP) + msb->read_only = 1; + else + msb->read_only = 0; } - if ((*mrq)->data[offsetof(struct ms_status_register, status0)] - & MEMSTICK_STATUS0_WP) - msb->read_only = 1; - else - msb->read_only = 0; - - complete(&card->mrq_complete); - return -EAGAIN; + return mspro_block_complete_req(card, (*mrq)->error); } static int h_mspro_block_wait_for_ced(struct memstick_dev *card, struct memstick_request **mrq) { - if ((*mrq)->error) { - complete(&card->mrq_complete); - return (*mrq)->error; - } - dev_dbg(&card->dev, "wait for ced: value %x\n", (*mrq)->data[0]); - if ((*mrq)->data[0] & (MEMSTICK_INT_CMDNAK | MEMSTICK_INT_ERR)) { - card->current_mrq.error = -EFAULT; - complete(&card->mrq_complete); - return card->current_mrq.error; + if (!(*mrq)->error) { + if ((*mrq)->data[0] & (MEMSTICK_INT_CMDNAK | MEMSTICK_INT_ERR)) + (*mrq)->error = -EFAULT; + else if (!((*mrq)->data[0] & MEMSTICK_INT_CED)) + return 0; } - if (!((*mrq)->data[0] & MEMSTICK_INT_CED)) - return 0; - else { - card->current_mrq.error = 0; - complete(&card->mrq_complete); - return -EAGAIN; - } + return mspro_block_complete_req(card, (*mrq)->error); } static int h_mspro_block_transfer_data(struct memstick_dev *card, @@ -583,10 +575,8 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card, struct scatterlist t_sg = { 0 }; size_t t_offset; - if ((*mrq)->error) { - complete(&card->mrq_complete); - return (*mrq)->error; - } + if ((*mrq)->error) + return mspro_block_complete_req(card, (*mrq)->error); switch ((*mrq)->tpc) { case MS_TPC_WRITE_REG: @@ -617,8 +607,8 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card, if (msb->current_seg == msb->seg_count) { if (t_val & MEMSTICK_INT_CED) { - complete(&card->mrq_complete); - return -EAGAIN; + return mspro_block_complete_req(card, + 0); } else { card->next_request = h_mspro_block_wait_for_ced; @@ -666,90 +656,120 @@ static int h_mspro_block_transfer_data(struct memstick_dev *card, /*** Data transfer ***/ -static void mspro_block_process_request(struct memstick_dev *card, - struct request *req) +static int mspro_block_issue_req(struct memstick_dev *card, int chunk) { struct mspro_block_data *msb = memstick_get_drvdata(card); - struct mspro_param_register param; - int rc, chunk, cnt; - unsigned short page_count; sector_t t_sec; - unsigned long flags; + unsigned int count; + struct mspro_param_register param; - do { - page_count = 0; +try_again: + while (chunk) { + msb->current_page = 0; msb->current_seg = 0; - msb->seg_count = blk_rq_map_sg(req->q, req, msb->req_sg); + msb->seg_count = blk_rq_map_sg(msb->block_req->q, + msb->block_req, + msb->req_sg); - if (msb->seg_count) { - msb->current_page = 0; - for (rc = 0; rc < msb->seg_count; rc++) - page_count += msb->req_sg[rc].length - / msb->page_size; + if (!msb->seg_count) { + chunk = __blk_end_request(msb->block_req, -ENOMEM, + blk_rq_cur_bytes(msb->block_req)); + continue; + } - t_sec = req->sector; - sector_div(t_sec, msb->page_size >> 9); - param.system = msb->system; - param.data_count = cpu_to_be16(page_count); - param.data_address = cpu_to_be32((uint32_t)t_sec); - param.tpc_param = 0; + t_sec = msb->block_req->sector << 9; + sector_div(t_sec, msb->page_size); - msb->data_dir = rq_data_dir(req); - msb->transfer_cmd = msb->data_dir == READ - ? MSPRO_CMD_READ_DATA - : MSPRO_CMD_WRITE_DATA; + count = msb->block_req->nr_sectors << 9; + count /= msb->page_size; - dev_dbg(&card->dev, "data transfer: cmd %x, " - "lba %x, count %x\n", msb->transfer_cmd, - be32_to_cpu(param.data_address), - page_count); + param.system = msb->system; + param.data_count = cpu_to_be16(count); + param.data_address = cpu_to_be32((uint32_t)t_sec); + param.tpc_param = 0; - card->next_request = h_mspro_block_req_init; - msb->mrq_handler = h_mspro_block_transfer_data; - memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, - ¶m, sizeof(param)); - memstick_new_req(card->host); - wait_for_completion(&card->mrq_complete); - rc = card->current_mrq.error; + msb->data_dir = rq_data_dir(msb->block_req); + msb->transfer_cmd = msb->data_dir == READ + ? MSPRO_CMD_READ_DATA + : MSPRO_CMD_WRITE_DATA; - if (rc || (card->current_mrq.tpc == MSPRO_CMD_STOP)) { - for (cnt = 0; cnt < msb->current_seg; cnt++) - page_count += msb->req_sg[cnt].length - / msb->page_size; + dev_dbg(&card->dev, "data transfer: cmd %x, " + "lba %x, count %x\n", msb->transfer_cmd, + be32_to_cpu(param.data_address), count); - if (msb->current_page) - page_count += msb->current_page - 1; + card->next_request = h_mspro_block_req_init; + msb->mrq_handler = h_mspro_block_transfer_data; + memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, + ¶m, sizeof(param)); + memstick_new_req(card->host); + return 0; + } - if (page_count && (msb->data_dir == READ)) - rc = msb->page_size * page_count; - else - rc = -EIO; - } else - rc = msb->page_size * page_count; - } else - rc = -EFAULT; + dev_dbg(&card->dev, "elv_next\n"); + msb->block_req = elv_next_request(msb->queue); + if (!msb->block_req) { + dev_dbg(&card->dev, "issue end\n"); + return -EAGAIN; + } - spin_lock_irqsave(&msb->q_lock, flags); - if (rc >= 0) - chunk = __blk_end_request(req, 0, rc); - else - chunk = __blk_end_request(req, rc, 0); - - dev_dbg(&card->dev, "end chunk %d, %d\n", rc, chunk); - spin_unlock_irqrestore(&msb->q_lock, flags); - } while (chunk); + dev_dbg(&card->dev, "trying again\n"); + chunk = 1; + goto try_again; } -static int mspro_block_has_request(struct mspro_block_data *msb) +static int mspro_block_complete_req(struct memstick_dev *card, int error) { - int rc = 0; + struct mspro_block_data *msb = memstick_get_drvdata(card); + int chunk, cnt; + unsigned int t_len = 0; unsigned long flags; spin_lock_irqsave(&msb->q_lock, flags); - if (kthread_should_stop() || msb->has_request) - rc = 1; + dev_dbg(&card->dev, "complete %d, %d\n", msb->has_request ? 1 : 0, + error); + + if (msb->has_request) { + /* Nothing to do - not really an error */ + if (error == -EAGAIN) + error = 0; + + if (error || (card->current_mrq.tpc == MSPRO_CMD_STOP)) { + if (msb->data_dir == READ) { + for (cnt = 0; cnt < msb->current_seg; cnt++) + t_len += msb->req_sg[cnt].length + / msb->page_size; + + if (msb->current_page) + t_len += msb->current_page - 1; + + t_len *= msb->page_size; + } + } else + t_len = msb->block_req->nr_sectors << 9; + + dev_dbg(&card->dev, "transferred %x (%d)\n", t_len, error); + + if (error && !t_len) + t_len = blk_rq_cur_bytes(msb->block_req); + + chunk = __blk_end_request(msb->block_req, error, t_len); + + error = mspro_block_issue_req(card, chunk); + + if (!error) + goto out; + else + msb->has_request = 0; + } else { + if (!error) + error = -EAGAIN; + } + + card->next_request = h_mspro_block_default_bad; + complete_all(&card->mrq_complete); +out: spin_unlock_irqrestore(&msb->q_lock, flags); - return rc; + return error; } static void mspro_block_stop(struct memstick_dev *card) @@ -783,54 +803,37 @@ static void mspro_block_start(struct memstick_dev *card) spin_unlock_irqrestore(&msb->q_lock, flags); } -static int mspro_block_queue_thread(void *data) +static int mspro_block_prepare_req(struct request_queue *q, struct request *req) { - struct memstick_dev *card = data; - struct memstick_host *host = card->host; - struct mspro_block_data *msb = memstick_get_drvdata(card); - struct request *req; - unsigned long flags; - - while (1) { - wait_event(msb->q_wait, mspro_block_has_request(msb)); - dev_dbg(&card->dev, "thread iter\n"); - - spin_lock_irqsave(&msb->q_lock, flags); - req = elv_next_request(msb->queue); - dev_dbg(&card->dev, "next req %p\n", req); - if (!req) { - msb->has_request = 0; - if (kthread_should_stop()) { - spin_unlock_irqrestore(&msb->q_lock, flags); - break; - } - } else - msb->has_request = 1; - spin_unlock_irqrestore(&msb->q_lock, flags); - - if (req) { - mutex_lock(&host->lock); - mspro_block_process_request(card, req); - mutex_unlock(&host->lock); - } + if (!blk_fs_request(req) && !blk_pc_request(req)) { + blk_dump_rq_flags(req, "MSPro unsupported request"); + return BLKPREP_KILL; } - dev_dbg(&card->dev, "thread finished\n"); - return 0; + + req->cmd_flags |= REQ_DONTPREP; + + return BLKPREP_OK; } -static void mspro_block_request(struct request_queue *q) +static void mspro_block_submit_req(struct request_queue *q) { struct memstick_dev *card = q->queuedata; struct mspro_block_data *msb = memstick_get_drvdata(card); struct request *req = NULL; - if (msb->q_thread) { - msb->has_request = 1; - wake_up_all(&msb->q_wait); - } else { + if (msb->has_request) + return; + + if (msb->eject) { while ((req = elv_next_request(q)) != NULL) end_queued_request(req, -ENODEV); + + return; } + + msb->has_request = 1; + if (mspro_block_issue_req(card, 0)) + msb->has_request = 0; } /*** Initialization ***/ @@ -1200,16 +1203,14 @@ static int mspro_block_init_disk(struct memstick_dev *card) goto out_release_id; } - spin_lock_init(&msb->q_lock); - init_waitqueue_head(&msb->q_wait); - - msb->queue = blk_init_queue(mspro_block_request, &msb->q_lock); + msb->queue = blk_init_queue(mspro_block_submit_req, &msb->q_lock); if (!msb->queue) { rc = -ENOMEM; goto out_put_disk; } msb->queue->queuedata = card; + blk_queue_prep_rq(msb->queue, mspro_block_prepare_req); blk_queue_bounce_limit(msb->queue, limit); blk_queue_max_sectors(msb->queue, MSPRO_BLOCK_MAX_PAGES); @@ -1235,14 +1236,8 @@ static int mspro_block_init_disk(struct memstick_dev *card) capacity *= msb->page_size >> 9; set_capacity(msb->disk, capacity); dev_dbg(&card->dev, "capacity set %ld\n", capacity); - msb->q_thread = kthread_run(mspro_block_queue_thread, card, - DRIVER_NAME"d"); - if (IS_ERR(msb->q_thread)) - goto out_put_disk; - mutex_unlock(&host->lock); add_disk(msb->disk); - mutex_lock(&host->lock); msb->active = 1; return 0; @@ -1290,6 +1285,7 @@ static int mspro_block_probe(struct memstick_dev *card) return -ENOMEM; memstick_set_drvdata(card, msb); msb->card = card; + spin_lock_init(&msb->q_lock); rc = mspro_block_init_card(card); @@ -1319,26 +1315,17 @@ static int mspro_block_probe(struct memstick_dev *card) static void mspro_block_remove(struct memstick_dev *card) { struct mspro_block_data *msb = memstick_get_drvdata(card); - struct task_struct *q_thread = NULL; unsigned long flags; del_gendisk(msb->disk); dev_dbg(&card->dev, "mspro block remove\n"); spin_lock_irqsave(&msb->q_lock, flags); - q_thread = msb->q_thread; - msb->q_thread = NULL; - msb->active = 0; + msb->eject = 1; + blk_start_queue(msb->queue); spin_unlock_irqrestore(&msb->q_lock, flags); - if (q_thread) { - mutex_unlock(&card->host->lock); - kthread_stop(q_thread); - mutex_lock(&card->host->lock); - } - - dev_dbg(&card->dev, "queue thread stopped\n"); - blk_cleanup_queue(msb->queue); + msb->queue = NULL; sysfs_remove_group(&card->dev.kobj, &msb->attr_group); @@ -1355,19 +1342,13 @@ static void mspro_block_remove(struct memstick_dev *card) static int mspro_block_suspend(struct memstick_dev *card, pm_message_t state) { struct mspro_block_data *msb = memstick_get_drvdata(card); - struct task_struct *q_thread = NULL; unsigned long flags; spin_lock_irqsave(&msb->q_lock, flags); - q_thread = msb->q_thread; - msb->q_thread = NULL; - msb->active = 0; blk_stop_queue(msb->queue); + msb->active = 0; spin_unlock_irqrestore(&msb->q_lock, flags); - if (q_thread) - kthread_stop(q_thread); - return 0; } @@ -1406,14 +1387,7 @@ static int mspro_block_resume(struct memstick_dev *card) if (memcmp(s_attr->data, r_attr->data, s_attr->size)) break; - memstick_set_drvdata(card, msb); - msb->q_thread = kthread_run(mspro_block_queue_thread, - card, DRIVER_NAME"d"); - if (IS_ERR(msb->q_thread)) - msb->q_thread = NULL; - else - msb->active = 1; - + msb->active = 1; break; } } diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 9d82e67737db..3485c63d20b0 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -50,6 +50,7 @@ struct jmb38x_ms_host { struct jmb38x_ms *chip; void __iomem *addr; spinlock_t lock; + struct tasklet_struct notify; int id; char host_id[32]; int irq; @@ -590,25 +591,35 @@ static void jmb38x_ms_abort(unsigned long data) spin_unlock_irqrestore(&host->lock, flags); } -static void jmb38x_ms_request(struct memstick_host *msh) +static void jmb38x_ms_req_tasklet(unsigned long data) { + struct memstick_host *msh = (struct memstick_host *)data; struct jmb38x_ms_host *host = memstick_priv(msh); unsigned long flags; int rc; spin_lock_irqsave(&host->lock, flags); - if (host->req) { - spin_unlock_irqrestore(&host->lock, flags); - BUG(); - return; + if (!host->req) { + do { + rc = memstick_next_req(msh, &host->req); + dev_dbg(&host->chip->pdev->dev, "tasklet req %d\n", rc); + } while (!rc && jmb38x_ms_issue_cmd(msh)); } - - do { - rc = memstick_next_req(msh, &host->req); - } while (!rc && jmb38x_ms_issue_cmd(msh)); spin_unlock_irqrestore(&host->lock, flags); } +static void jmb38x_ms_dummy_submit(struct memstick_host *msh) +{ + return; +} + +static void jmb38x_ms_submit_req(struct memstick_host *msh) +{ + struct jmb38x_ms_host *host = memstick_priv(msh); + + tasklet_schedule(&host->notify); +} + static int jmb38x_ms_reset(struct jmb38x_ms_host *host) { int cnt; @@ -816,7 +827,9 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt) host->id); host->irq = jm->pdev->irq; host->timeout_jiffies = msecs_to_jiffies(1000); - msh->request = jmb38x_ms_request; + + tasklet_init(&host->notify, jmb38x_ms_req_tasklet, (unsigned long)msh); + msh->request = jmb38x_ms_submit_req; msh->set_param = jmb38x_ms_set_param; msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; @@ -928,6 +941,8 @@ static void jmb38x_ms_remove(struct pci_dev *dev) host = memstick_priv(jm->hosts[cnt]); + jm->hosts[cnt]->request = jmb38x_ms_dummy_submit; + tasklet_kill(&host->notify); writel(0, host->addr + INT_SIGNAL_ENABLE); writel(0, host->addr + INT_STATUS_ENABLE); mmiowb(); diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 14458764588c..d32d6ad8f3fc 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c @@ -71,6 +71,7 @@ struct tifm_ms { struct tifm_dev *dev; struct timer_list timer; struct memstick_request *req; + struct tasklet_struct notify; unsigned int mode_mask; unsigned int block_pos; unsigned long timeout_jiffies; @@ -455,40 +456,45 @@ static void tifm_ms_card_event(struct tifm_dev *sock) return; } -static void tifm_ms_request(struct memstick_host *msh) +static void tifm_ms_req_tasklet(unsigned long data) { + struct memstick_host *msh = (struct memstick_host *)data; struct tifm_ms *host = memstick_priv(msh); struct tifm_dev *sock = host->dev; unsigned long flags; int rc; spin_lock_irqsave(&sock->lock, flags); - if (host->req) { - printk(KERN_ERR "%s : unfinished request detected\n", - sock->dev.bus_id); - spin_unlock_irqrestore(&sock->lock, flags); - tifm_eject(host->dev); - return; - } + if (!host->req) { + if (host->eject) { + do { + rc = memstick_next_req(msh, &host->req); + if (!rc) + host->req->error = -ETIME; + } while (!rc); + spin_unlock_irqrestore(&sock->lock, flags); + return; + } - if (host->eject) { do { rc = memstick_next_req(msh, &host->req); - if (!rc) - host->req->error = -ETIME; - } while (!rc); - spin_unlock_irqrestore(&sock->lock, flags); - return; + } while (!rc && tifm_ms_issue_cmd(host)); } - - do { - rc = memstick_next_req(msh, &host->req); - } while (!rc && tifm_ms_issue_cmd(host)); - spin_unlock_irqrestore(&sock->lock, flags); +} + +static void tifm_ms_dummy_submit(struct memstick_host *msh) +{ return; } +static void tifm_ms_submit_req(struct memstick_host *msh) +{ + struct tifm_ms *host = memstick_priv(msh); + + tasklet_schedule(&host->notify); +} + static int tifm_ms_set_param(struct memstick_host *msh, enum memstick_param param, int value) @@ -569,8 +575,9 @@ static int tifm_ms_probe(struct tifm_dev *sock) host->timeout_jiffies = msecs_to_jiffies(1000); setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); + tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh); - msh->request = tifm_ms_request; + msh->request = tifm_ms_submit_req; msh->set_param = tifm_ms_set_param; sock->card_event = tifm_ms_card_event; sock->data_event = tifm_ms_data_event; @@ -592,6 +599,8 @@ static void tifm_ms_remove(struct tifm_dev *sock) int rc = 0; unsigned long flags; + msh->request = tifm_ms_dummy_submit; + tasklet_kill(&host->notify); spin_lock_irqsave(&sock->lock, flags); host->eject = 1; if (host->req) { From 7fccf0326536c1b245b98740d489abb9aab69a12 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Fri, 25 Jul 2008 19:45:02 -0700 Subject: [PATCH 079/179] kernel/kexec.c: make 'kimage_terminate' void Since kimage_terminate() always returns 0, make it void. Signed-off-by: WANG Cong Signed-off-by: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/kexec.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/kernel/kexec.c b/kernel/kexec.c index 1c5fcacbcf33..6db42ff8d520 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -589,14 +589,12 @@ static void kimage_free_extra_pages(struct kimage *image) kimage_free_page_list(&image->unuseable_pages); } -static int kimage_terminate(struct kimage *image) +static void kimage_terminate(struct kimage *image) { if (*image->entry != 0) image->entry++; *image->entry = IND_DONE; - - return 0; } #define for_each_kimage_entry(image, ptr, entry) \ @@ -997,9 +995,7 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, if (result) goto out; } - result = kimage_terminate(image); - if (result) - goto out; + kimage_terminate(image); } /* Install the new kernel, and Uninstall the old */ image = xchg(dest_image, image); From 3ab83521378268044a448113c6aa9a9e245f4d2f Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Fri, 25 Jul 2008 19:45:07 -0700 Subject: [PATCH 080/179] kexec jump This patch provides an enhancement to kexec/kdump. It implements the following features: - Backup/restore memory used by the original kernel before/after kexec. - Save/restore CPU state before/after kexec. The features of this patch can be used as a general method to call program in physical mode (paging turning off). This can be used to call BIOS code under Linux. kexec-tools needs to be patched to support kexec jump. The patches and the precompiled kexec can be download from the following URL: source: http://khibernation.sourceforge.net/download/release_v10/kexec-tools/kexec-tools-src_git_kh10.tar.bz2 patches: http://khibernation.sourceforge.net/download/release_v10/kexec-tools/kexec-tools-patches_git_kh10.tar.bz2 binary: http://khibernation.sourceforge.net/download/release_v10/kexec-tools/kexec_git_kh10 Usage example of calling some physical mode code and return: 1. Compile and install patched kernel with following options selected: CONFIG_X86_32=y CONFIG_KEXEC=y CONFIG_PM=y CONFIG_KEXEC_JUMP=y 2. Build patched kexec-tool or download the pre-built one. 3. Build some physical mode executable named such as "phy_mode" 4. Boot kernel compiled in step 1. 5. Load physical mode executable with /sbin/kexec. The shell command line can be as follow: /sbin/kexec --load-preserve-context --args-none phy_mode 6. Call physical mode executable with following shell command line: /sbin/kexec -e Implementation point: To support jumping without reserving memory. One shadow backup page (source page) is allocated for each page used by kexeced code image (destination page). When do kexec_load, the image of kexeced code is loaded into source pages, and before executing, the destination pages and the source pages are swapped, so the contents of destination pages are backupped. Before jumping to the kexeced code image and after jumping back to the original kernel, the destination pages and the source pages are swapped too. C ABI (calling convention) is used as communication protocol between kernel and called code. A flag named KEXEC_PRESERVE_CONTEXT for sys_kexec_load is added to indicate that the loaded kernel image is used for jumping back. Now, only the i386 architecture is supported. Signed-off-by: Huang Ying Acked-by: Vivek Goyal Cc: "Eric W. Biederman" Cc: Pavel Machek Cc: Nigel Cunningham Cc: "Rafael J. Wysocki" Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/machine_kexec.c | 2 +- arch/sh/kernel/machine_kexec.c | 2 +- arch/x86/Kconfig | 7 ++ arch/x86/kernel/machine_kexec_32.c | 27 +++- arch/x86/kernel/machine_kexec_64.c | 2 +- arch/x86/kernel/relocate_kernel_32.S | 176 +++++++++++++++++++++++---- include/asm-x86/kexec.h | 18 +-- include/linux/kexec.h | 17 ++- kernel/kexec.c | 57 +++++++++ kernel/sys.c | 31 ++--- 10 files changed, 270 insertions(+), 69 deletions(-) diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index 29a0e039d436..aab76887a842 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -48,7 +48,7 @@ void machine_kexec_cleanup(struct kimage *image) * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -NORET_TYPE void machine_kexec(struct kimage *image) +void machine_kexec(struct kimage *image) { if (ppc_md.machine_kexec) ppc_md.machine_kexec(image); diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 5c17de51987e..ec1eadce4aaa 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -70,7 +70,7 @@ static void kexec_info(struct kimage *image) * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -NORET_TYPE void machine_kexec(struct kimage *image) +void machine_kexec(struct kimage *image) { unsigned long page_list; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e3cba0b45600..7ecb679f0130 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1279,6 +1279,13 @@ config CRASH_DUMP (CONFIG_RELOCATABLE=y). For more details see Documentation/kdump/kdump.txt +config KEXEC_JUMP + bool "kexec jump (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on KEXEC && PM_SLEEP && X86_32 + help + Invoke code in physical address mode via KEXEC + config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) default "0x1000000" if X86_NUMAQ diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 8864230d55af..2b67609d0a1c 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -22,6 +22,7 @@ #include #include #include +#include #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) static u32 kexec_pgd[1024] PAGE_ALIGNED; @@ -85,10 +86,12 @@ static void load_segments(void) * reboot code buffer to allow us to avoid allocations * later. * - * Currently nothing. + * Make control page executable. */ int machine_kexec_prepare(struct kimage *image) { + if (nx_enabled) + set_pages_x(image->control_code_page, 1); return 0; } @@ -98,16 +101,24 @@ int machine_kexec_prepare(struct kimage *image) */ void machine_kexec_cleanup(struct kimage *image) { + if (nx_enabled) + set_pages_nx(image->control_code_page, 1); } /* * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -NORET_TYPE void machine_kexec(struct kimage *image) +void machine_kexec(struct kimage *image) { unsigned long page_list[PAGES_NR]; void *control_page; + asmlinkage unsigned long + (*relocate_kernel_ptr)(unsigned long indirection_page, + unsigned long control_page, + unsigned long start_address, + unsigned int has_pae, + unsigned int preserve_context); tracer_disable(); @@ -115,10 +126,11 @@ NORET_TYPE void machine_kexec(struct kimage *image) local_irq_disable(); control_page = page_address(image->control_code_page); - memcpy(control_page, relocate_kernel, PAGE_SIZE); + memcpy(control_page, relocate_kernel, PAGE_SIZE/2); + relocate_kernel_ptr = control_page; page_list[PA_CONTROL_PAGE] = __pa(control_page); - page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; + page_list[VA_CONTROL_PAGE] = (unsigned long)control_page; page_list[PA_PGD] = __pa(kexec_pgd); page_list[VA_PGD] = (unsigned long)kexec_pgd; #ifdef CONFIG_X86_PAE @@ -131,6 +143,7 @@ NORET_TYPE void machine_kexec(struct kimage *image) page_list[VA_PTE_0] = (unsigned long)kexec_pte0; page_list[PA_PTE_1] = __pa(kexec_pte1); page_list[VA_PTE_1] = (unsigned long)kexec_pte1; + page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) << PAGE_SHIFT); /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is @@ -149,8 +162,10 @@ NORET_TYPE void machine_kexec(struct kimage *image) set_idt(phys_to_virt(0),0); /* now call it */ - relocate_kernel((unsigned long)image->head, (unsigned long)page_list, - image->start, cpu_has_pae); + image->start = relocate_kernel_ptr((unsigned long)image->head, + (unsigned long)page_list, + image->start, cpu_has_pae, + image->preserve_context); } void arch_crash_save_vmcoreinfo(void) diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 9dd9262693a3..c43caa3a91f3 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -181,7 +181,7 @@ void machine_kexec_cleanup(struct kimage *image) * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */ -NORET_TYPE void machine_kexec(struct kimage *image) +void machine_kexec(struct kimage *image) { unsigned long page_list[PAGES_NR]; void *control_page; diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S index c30fe25d470d..703310a99023 100644 --- a/arch/x86/kernel/relocate_kernel_32.S +++ b/arch/x86/kernel/relocate_kernel_32.S @@ -20,11 +20,44 @@ #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) #define PAE_PGD_ATTR (_PAGE_PRESENT) +/* control_page + PAGE_SIZE/2 ~ control_page + PAGE_SIZE * 3/4 are + * used to save some data for jumping back + */ +#define DATA(offset) (PAGE_SIZE/2+(offset)) + +/* Minimal CPU state */ +#define ESP DATA(0x0) +#define CR0 DATA(0x4) +#define CR3 DATA(0x8) +#define CR4 DATA(0xc) + +/* other data */ +#define CP_VA_CONTROL_PAGE DATA(0x10) +#define CP_PA_PGD DATA(0x14) +#define CP_PA_SWAP_PAGE DATA(0x18) +#define CP_PA_BACKUP_PAGES_MAP DATA(0x1c) + .text .align PAGE_SIZE .globl relocate_kernel relocate_kernel: - movl 8(%esp), %ebp /* list of pages */ + /* Save the CPU context, used for jumping back */ + + pushl %ebx + pushl %esi + pushl %edi + pushl %ebp + pushf + + movl 20+8(%esp), %ebp /* list of pages */ + movl PTR(VA_CONTROL_PAGE)(%ebp), %edi + movl %esp, ESP(%edi) + movl %cr0, %eax + movl %eax, CR0(%edi) + movl %cr3, %eax + movl %eax, CR3(%edi) + movl %cr4, %eax + movl %eax, CR4(%edi) #ifdef CONFIG_X86_PAE /* map the control page at its virtual address */ @@ -138,15 +171,25 @@ relocate_kernel: relocate_new_kernel: /* read the arguments and say goodbye to the stack */ - movl 4(%esp), %ebx /* page_list */ - movl 8(%esp), %ebp /* list of pages */ - movl 12(%esp), %edx /* start address */ - movl 16(%esp), %ecx /* cpu_has_pae */ + movl 20+4(%esp), %ebx /* page_list */ + movl 20+8(%esp), %ebp /* list of pages */ + movl 20+12(%esp), %edx /* start address */ + movl 20+16(%esp), %ecx /* cpu_has_pae */ + movl 20+20(%esp), %esi /* preserve_context */ /* zero out flags, and disable interrupts */ pushl $0 popfl + /* save some information for jumping back */ + movl PTR(VA_CONTROL_PAGE)(%ebp), %edi + movl %edi, CP_VA_CONTROL_PAGE(%edi) + movl PTR(PA_PGD)(%ebp), %eax + movl %eax, CP_PA_PGD(%edi) + movl PTR(PA_SWAP_PAGE)(%ebp), %eax + movl %eax, CP_PA_SWAP_PAGE(%edi) + movl %ebx, CP_PA_BACKUP_PAGES_MAP(%edi) + /* get physical address of control page now */ /* this is impossible after page table switch */ movl PTR(PA_CONTROL_PAGE)(%ebp), %edi @@ -197,8 +240,90 @@ identity_mapped: xorl %eax, %eax movl %eax, %cr3 + movl CP_PA_SWAP_PAGE(%edi), %eax + pushl %eax + pushl %ebx + call swap_pages + addl $8, %esp + + /* To be certain of avoiding problems with self-modifying code + * I need to execute a serializing instruction here. + * So I flush the TLB, it's handy, and not processor dependent. + */ + xorl %eax, %eax + movl %eax, %cr3 + + /* set all of the registers to known values */ + /* leave %esp alone */ + + testl %esi, %esi + jnz 1f + xorl %edi, %edi + xorl %eax, %eax + xorl %ebx, %ebx + xorl %ecx, %ecx + xorl %edx, %edx + xorl %esi, %esi + xorl %ebp, %ebp + ret +1: + popl %edx + movl CP_PA_SWAP_PAGE(%edi), %esp + addl $PAGE_SIZE, %esp +2: + call *%edx + + /* get the re-entry point of the peer system */ + movl 0(%esp), %ebp + call 1f +1: + popl %ebx + subl $(1b - relocate_kernel), %ebx + movl CP_VA_CONTROL_PAGE(%ebx), %edi + lea PAGE_SIZE(%ebx), %esp + movl CP_PA_SWAP_PAGE(%ebx), %eax + movl CP_PA_BACKUP_PAGES_MAP(%ebx), %edx + pushl %eax + pushl %edx + call swap_pages + addl $8, %esp + movl CP_PA_PGD(%ebx), %eax + movl %eax, %cr3 + movl %cr0, %eax + orl $(1<<31), %eax + movl %eax, %cr0 + lea PAGE_SIZE(%edi), %esp + movl %edi, %eax + addl $(virtual_mapped - relocate_kernel), %eax + pushl %eax + ret + +virtual_mapped: + movl CR4(%edi), %eax + movl %eax, %cr4 + movl CR3(%edi), %eax + movl %eax, %cr3 + movl CR0(%edi), %eax + movl %eax, %cr0 + movl ESP(%edi), %esp + movl %ebp, %eax + + popf + popl %ebp + popl %edi + popl %esi + popl %ebx + ret + /* Do the copies */ - movl %ebx, %ecx +swap_pages: + movl 8(%esp), %edx + movl 4(%esp), %ecx + pushl %ebp + pushl %ebx + pushl %edi + pushl %esi + movl %ecx, %ebx jmp 1f 0: /* top, read another word from the indirection page */ @@ -226,27 +351,28 @@ identity_mapped: movl %ecx, %esi /* For every source page do a copy */ andl $0xfffff000, %esi + movl %edi, %eax + movl %esi, %ebp + + movl %edx, %edi movl $1024, %ecx rep ; movsl + + movl %ebp, %edi + movl %eax, %esi + movl $1024, %ecx + rep ; movsl + + movl %eax, %edi + movl %edx, %esi + movl $1024, %ecx + rep ; movsl + + lea PAGE_SIZE(%ebp), %esi jmp 0b - 3: - - /* To be certain of avoiding problems with self-modifying code - * I need to execute a serializing instruction here. - * So I flush the TLB, it's handy, and not processor dependent. - */ - xorl %eax, %eax - movl %eax, %cr3 - - /* set all of the registers to known values */ - /* leave %esp alone */ - - xorl %eax, %eax - xorl %ebx, %ebx - xorl %ecx, %ecx - xorl %edx, %edx - xorl %esi, %esi - xorl %edi, %edi - xorl %ebp, %ebp + popl %esi + popl %edi + popl %ebx + popl %ebp ret diff --git a/include/asm-x86/kexec.h b/include/asm-x86/kexec.h index 8f855a15f64d..c0e52a14fd4d 100644 --- a/include/asm-x86/kexec.h +++ b/include/asm-x86/kexec.h @@ -10,14 +10,15 @@ # define VA_PTE_0 5 # define PA_PTE_1 6 # define VA_PTE_1 7 +# define PA_SWAP_PAGE 8 # ifdef CONFIG_X86_PAE -# define PA_PMD_0 8 -# define VA_PMD_0 9 -# define PA_PMD_1 10 -# define VA_PMD_1 11 -# define PAGES_NR 12 +# define PA_PMD_0 9 +# define VA_PMD_0 10 +# define PA_PMD_1 11 +# define VA_PMD_1 12 +# define PAGES_NR 13 # else -# define PAGES_NR 8 +# define PAGES_NR 9 # endif #else # define PA_CONTROL_PAGE 0 @@ -152,11 +153,12 @@ static inline void crash_setup_regs(struct pt_regs *newregs, } #ifdef CONFIG_X86_32 -asmlinkage NORET_TYPE void +asmlinkage unsigned long relocate_kernel(unsigned long indirection_page, unsigned long control_page, unsigned long start_address, - unsigned int has_pae) ATTRIB_NORET; + unsigned int has_pae, + unsigned int preserve_context); #else NORET_TYPE void relocate_kernel(unsigned long indirection_page, diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 3265968cd2cd..82f88a8a827b 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -83,6 +83,7 @@ struct kimage { unsigned long start; struct page *control_code_page; + struct page *swap_page; unsigned long nr_segments; struct kexec_segment segment[KEXEC_SEGMENT_MAX]; @@ -98,18 +99,20 @@ struct kimage { unsigned int type : 1; #define KEXEC_TYPE_DEFAULT 0 #define KEXEC_TYPE_CRASH 1 + unsigned int preserve_context : 1; }; /* kexec interface functions */ -extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET; +extern void machine_kexec(struct kimage *image); extern int machine_kexec_prepare(struct kimage *image); extern void machine_kexec_cleanup(struct kimage *image); extern asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, struct kexec_segment __user *segments, unsigned long flags); +extern int kernel_kexec(void); #ifdef CONFIG_COMPAT extern asmlinkage long compat_sys_kexec_load(unsigned long entry, unsigned long nr_segments, @@ -156,8 +159,9 @@ extern struct kimage *kexec_crash_image; #define kexec_flush_icache_page(page) #endif -#define KEXEC_ON_CRASH 0x00000001 -#define KEXEC_ARCH_MASK 0xffff0000 +#define KEXEC_ON_CRASH 0x00000001 +#define KEXEC_PRESERVE_CONTEXT 0x00000002 +#define KEXEC_ARCH_MASK 0xffff0000 /* These values match the ELF architecture values. * Unless there is a good reason that should continue to be the case. @@ -174,7 +178,12 @@ extern struct kimage *kexec_crash_image; #define KEXEC_ARCH_MIPS_LE (10 << 16) #define KEXEC_ARCH_MIPS ( 8 << 16) -#define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */ +/* List of defined/legal kexec flags */ +#ifndef CONFIG_KEXEC_JUMP +#define KEXEC_FLAGS KEXEC_ON_CRASH +#else +#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT) +#endif #define VMCOREINFO_BYTES (4096) #define VMCOREINFO_NOTE_NAME "VMCOREINFO" diff --git a/kernel/kexec.c b/kernel/kexec.c index 6db42ff8d520..a0d920915b38 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -242,6 +244,12 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, goto out; } + image->swap_page = kimage_alloc_control_pages(image, 0); + if (!image->swap_page) { + printk(KERN_ERR "Could not allocate swap buffer\n"); + goto out; + } + result = 0; out: if (result == 0) @@ -986,6 +994,8 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, if (result) goto out; + if (flags & KEXEC_PRESERVE_CONTEXT) + image->preserve_context = 1; result = machine_kexec_prepare(image); if (result) goto out; @@ -1411,3 +1421,50 @@ static int __init crash_save_vmcoreinfo_init(void) } module_init(crash_save_vmcoreinfo_init) + +/** + * kernel_kexec - reboot the system + * + * Move into place and start executing a preloaded standalone + * executable. If nothing was preloaded return an error. + */ +int kernel_kexec(void) +{ + int error = 0; + + if (xchg(&kexec_lock, 1)) + return -EBUSY; + if (!kexec_image) { + error = -EINVAL; + goto Unlock; + } + + if (kexec_image->preserve_context) { +#ifdef CONFIG_KEXEC_JUMP + local_irq_disable(); + save_processor_state(); +#endif + } else { + blocking_notifier_call_chain(&reboot_notifier_list, + SYS_RESTART, NULL); + system_state = SYSTEM_RESTART; + device_shutdown(); + sysdev_shutdown(); + printk(KERN_EMERG "Starting new kernel\n"); + machine_shutdown(); + } + + machine_kexec(kexec_image); + + if (kexec_image->preserve_context) { +#ifdef CONFIG_KEXEC_JUMP + restore_processor_state(); + local_irq_enable(); +#endif + } + + Unlock: + xchg(&kexec_lock, 0); + + return error; +} diff --git a/kernel/sys.c b/kernel/sys.c index 0c9d3fa1f5ff..c01858090a98 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -301,26 +301,6 @@ void kernel_restart(char *cmd) } EXPORT_SYMBOL_GPL(kernel_restart); -/** - * kernel_kexec - reboot the system - * - * Move into place and start executing a preloaded standalone - * executable. If nothing was preloaded return an error. - */ -static void kernel_kexec(void) -{ -#ifdef CONFIG_KEXEC - struct kimage *image; - image = xchg(&kexec_image, NULL); - if (!image) - return; - kernel_restart_prepare(NULL); - printk(KERN_EMERG "Starting new kernel\n"); - machine_shutdown(); - machine_kexec(image); -#endif -} - static void kernel_shutdown_prepare(enum system_states state) { blocking_notifier_call_chain(&reboot_notifier_list, @@ -425,10 +405,15 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user kernel_restart(buffer); break; +#ifdef CONFIG_KEXEC case LINUX_REBOOT_CMD_KEXEC: - kernel_kexec(); - unlock_kernel(); - return -EINVAL; + { + int ret; + ret = kernel_kexec(); + unlock_kernel(); + return ret; + } +#endif #ifdef CONFIG_HIBERNATION case LINUX_REBOOT_CMD_SW_SUSPEND: From 89081d17f7bb81d89fa1aa9b70f821c5cf4d39e9 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Fri, 25 Jul 2008 19:45:10 -0700 Subject: [PATCH 081/179] kexec jump: save/restore device state This patch implements devices state save/restore before after kexec. This patch together with features in kexec_jump patch can be used for following: - A simple hibernation implementation without ACPI support. You can kexec a hibernating kernel, save the memory image of original system and shutdown the system. When resuming, you restore the memory image of original system via ordinary kexec load then jump back. - Kernel/system debug through making system snapshot. You can make system snapshot, jump back, do some thing and make another system snapshot. - Cooperative multi-kernel/system. With kexec jump, you can switch between several kernels/systems quickly without boot process except the first time. This appears like swap a whole kernel/system out/in. - A general method to call program in physical mode (paging turning off). This can be used to invoke BIOS code under Linux. The following user-space tools can be used with kexec jump: - kexec-tools needs to be patched to support kexec jump. The patches and the precompiled kexec can be download from the following URL: source: http://khibernation.sourceforge.net/download/release_v10/kexec-tools/kexec-tools-src_git_kh10.tar.bz2 patches: http://khibernation.sourceforge.net/download/release_v10/kexec-tools/kexec-tools-patches_git_kh10.tar.bz2 binary: http://khibernation.sourceforge.net/download/release_v10/kexec-tools/kexec_git_kh10 - makedumpfile with patches are used as memory image saving tool, it can exclude free pages from original kernel memory image file. The patches and the precompiled makedumpfile can be download from the following URL: source: http://khibernation.sourceforge.net/download/release_v10/makedumpfile/makedumpfile-src_cvs_kh10.tar.bz2 patches: http://khibernation.sourceforge.net/download/release_v10/makedumpfile/makedumpfile-patches_cvs_kh10.tar.bz2 binary: http://khibernation.sourceforge.net/download/release_v10/makedumpfile/makedumpfile_cvs_kh10 - An initramfs image can be used as the root file system of kexeced kernel. An initramfs image built with "BuildRoot" can be downloaded from the following URL: initramfs image: http://khibernation.sourceforge.net/download/release_v10/initramfs/rootfs_cvs_kh10.gz All user space tools above are included in the initramfs image. Usage example of simple hibernation: 1. Compile and install patched kernel with following options selected: CONFIG_X86_32=y CONFIG_RELOCATABLE=y CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y CONFIG_PM=y CONFIG_HIBERNATION=y CONFIG_KEXEC_JUMP=y 2. Build an initramfs image contains kexec-tool and makedumpfile, or download the pre-built initramfs image, called rootfs.gz in following text. 3. Prepare a partition to save memory image of original kernel, called hibernating partition in following text. 4. Boot kernel compiled in step 1 (kernel A). 5. In the kernel A, load kernel compiled in step 1 (kernel B) with /sbin/kexec. The shell command line can be as follow: /sbin/kexec --load-preserve-context /boot/bzImage --mem-min=0x100000 --mem-max=0xffffff --initrd=rootfs.gz 6. Boot the kernel B with following shell command line: /sbin/kexec -e 7. The kernel B will boot as normal kexec. In kernel B the memory image of kernel A can be saved into hibernating partition as follow: jump_back_entry=`cat /proc/cmdline | tr ' ' '\n' | grep kexec_jump_back_entry | cut -d '='` echo $jump_back_entry > kexec_jump_back_entry cp /proc/vmcore dump.elf Then you can shutdown the machine as normal. 8. Boot kernel compiled in step 1 (kernel C). Use the rootfs.gz as root file system. 9. In kernel C, load the memory image of kernel A as follow: /sbin/kexec -l --args-none --entry=`cat kexec_jump_back_entry` dump.elf 10. Jump back to the kernel A as follow: /sbin/kexec -e Then, kernel A is resumed. Implementation point: To support jumping between two kernels, before jumping to (executing) the new kernel and jumping back to the original kernel, the devices are put into quiescent state, and the state of devices and CPU is saved. After jumping back from kexeced kernel and jumping to the new kernel, the state of devices and CPU are restored accordingly. The devices/CPU state save/restore code of software suspend is called to implement corresponding function. Known issues: - Because the segment number supported by sys_kexec_load is limited, hibernation image with many segments may not be load. This is planned to be eliminated by adding a new flag to sys_kexec_load to make a image can be loaded with multiple sys_kexec_load invoking. Now, only the i386 architecture is supported. Signed-off-by: Huang Ying Acked-by: Vivek Goyal Cc: "Eric W. Biederman" Cc: Pavel Machek Cc: Nigel Cunningham Cc: "Rafael J. Wysocki" Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/Kconfig | 5 ++-- arch/x86/kernel/machine_kexec_32.c | 12 +++++++++ include/linux/suspend.h | 2 ++ kernel/kexec.c | 39 ++++++++++++++++++++++++++++++ kernel/power/power.h | 2 -- 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 7ecb679f0130..6b2debfabddc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1282,9 +1282,10 @@ config CRASH_DUMP config KEXEC_JUMP bool "kexec jump (EXPERIMENTAL)" depends on EXPERIMENTAL - depends on KEXEC && PM_SLEEP && X86_32 + depends on KEXEC && HIBERNATION && X86_32 help - Invoke code in physical address mode via KEXEC + Jump between original kernel and kexeced kernel and invoke + code in physical address mode via KEXEC config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 2b67609d0a1c..9fe478d98406 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -125,6 +125,18 @@ void machine_kexec(struct kimage *image) /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); + if (image->preserve_context) { +#ifdef CONFIG_X86_IO_APIC + /* We need to put APICs in legacy mode so that we can + * get timer interrupts in second kernel. kexec/kdump + * paths already have calls to disable_IO_APIC() in + * one form or other. kexec jump path also need + * one. + */ + disable_IO_APIC(); +#endif + } + control_page = page_address(image->control_code_page); memcpy(control_page, relocate_kernel, PAGE_SIZE/2); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index e8e69159af71..c63435095970 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -278,4 +278,6 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e) } #endif +extern struct mutex pm_mutex; + #endif /* _LINUX_SUSPEND_H */ diff --git a/kernel/kexec.c b/kernel/kexec.c index a0d920915b38..c8a4370e2a34 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -26,6 +26,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -1441,7 +1445,31 @@ int kernel_kexec(void) if (kexec_image->preserve_context) { #ifdef CONFIG_KEXEC_JUMP + mutex_lock(&pm_mutex); + pm_prepare_console(); + error = freeze_processes(); + if (error) { + error = -EBUSY; + goto Restore_console; + } + suspend_console(); + error = device_suspend(PMSG_FREEZE); + if (error) + goto Resume_console; + error = disable_nonboot_cpus(); + if (error) + goto Resume_devices; local_irq_disable(); + /* At this point, device_suspend() has been called, + * but *not* device_power_down(). We *must* + * device_power_down() now. Otherwise, drivers for + * some devices (e.g. interrupt controllers) become + * desynchronized with the actual state of the + * hardware at resume time, and evil weirdness ensues. + */ + error = device_power_down(PMSG_FREEZE); + if (error) + goto Enable_irqs; save_processor_state(); #endif } else { @@ -1459,7 +1487,18 @@ int kernel_kexec(void) if (kexec_image->preserve_context) { #ifdef CONFIG_KEXEC_JUMP restore_processor_state(); + device_power_up(PMSG_RESTORE); + Enable_irqs: local_irq_enable(); + enable_nonboot_cpus(); + Resume_devices: + device_resume(PMSG_RESTORE); + Resume_console: + resume_console(); + thaw_processes(); + Restore_console: + pm_restore_console(); + mutex_unlock(&pm_mutex); #endif } diff --git a/kernel/power/power.h b/kernel/power/power.h index 700f44ec8406..acc0c101dbd5 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -53,8 +53,6 @@ extern int hibernation_platform_enter(void); extern int pfn_is_nosave(unsigned long); -extern struct mutex pm_mutex; - #define power_attr(_name) \ static struct kobj_attribute _name##_attr = { \ .attr = { \ From c2147a5092cfe13dbf3210e54e8a622015edeecc Mon Sep 17 00:00:00 2001 From: Eduard - Gabriel Munteanu Date: Fri, 25 Jul 2008 19:45:11 -0700 Subject: [PATCH 082/179] Better interface for hooking early initcalls Added early initcall (pre-SMP) support, using an identical interface to that of regular initcalls. Functions called from do_pre_smp_initcalls() could be converted to use this cleaner interface. This is required by CPU hotplug, because early users have to register notifiers before going SMP. One such CPU hotplug user is the relay interface with buffer-only channels, which needs to register such a notifier, to be usable in early code. This in turn is used by kmemtrace. Signed-off-by: Eduard - Gabriel Munteanu Cc: Tom Zanussi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/vmlinux.lds.h | 2 ++ include/linux/init.h | 7 +++++++ init/main.c | 13 +++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 729f6b0a60e9..9cd44b162ba1 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -359,6 +359,8 @@ } #define INITCALLS \ + *(.initcallearly.init) \ + __early_initcall_end = .; \ *(.initcall0.init) \ *(.initcall0s.init) \ *(.initcall1.init) \ diff --git a/include/linux/init.h b/include/linux/init.h index 42ae95411a93..11b84e106053 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -169,6 +169,13 @@ extern void (*late_time_init)(void); static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" level ".init"))) = fn +/* + * Early initcalls run before initializing SMP. + * + * Only for built-in code, not modules. + */ +#define early_initcall(fn) __define_initcall("early",fn,early) + /* * A "pure" initcall has no dependencies on anything else, and purely * initializes variables that couldn't be statically initialized. diff --git a/init/main.c b/init/main.c index 0604cbcaf1e4..b6fec08dbbef 100644 --- a/init/main.c +++ b/init/main.c @@ -743,13 +743,13 @@ static void __init do_one_initcall(initcall_t fn) } -extern initcall_t __initcall_start[], __initcall_end[]; +extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; static void __init do_initcalls(void) { initcall_t *call; - for (call = __initcall_start; call < __initcall_end; call++) + for (call = __early_initcall_end; call < __initcall_end; call++) do_one_initcall(*call); /* Make sure there is no pending stuff from the initcall sequence */ @@ -783,6 +783,14 @@ static int __init nosoftlockup_setup(char *str) } __setup("nosoftlockup", nosoftlockup_setup); +static void __init __do_pre_smp_initcalls(void) +{ + initcall_t *call; + + for (call = __initcall_start; call < __early_initcall_end; call++) + do_one_initcall(*call); +} + static void __init do_pre_smp_initcalls(void) { extern int spawn_ksoftirqd(void); @@ -865,6 +873,7 @@ static int __init kernel_init(void * unused) smp_prepare_cpus(setup_max_cpus); + __do_pre_smp_initcalls(); do_pre_smp_initcalls(); smp_init(); From 7babe8db99d305340cf4828ce1f5a1481d5622ef Mon Sep 17 00:00:00 2001 From: Eduard - Gabriel Munteanu Date: Fri, 25 Jul 2008 19:45:11 -0700 Subject: [PATCH 083/179] Full conversion to early_initcall() interface, remove old interface A previous patch added the early_initcall(), to allow a cleaner hooking of pre-SMP initcalls. Now we remove the older interface, converting all existing users to the new one. [akpm@linux-foundation.org: cleanups] [akpm@linux-foundation.org: build fix] [kosaki.motohiro@jp.fujitsu.com: warning fix] [kosaki.motohiro@jp.fujitsu.com: warning fix] Signed-off-by: Eduard - Gabriel Munteanu Cc: Tom Zanussi Signed-off-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 9 --------- include/linux/smp.h | 5 ----- init/main.c | 23 +---------------------- kernel/sched.c | 5 ++++- kernel/smp.c | 4 +++- kernel/softirq.c | 3 ++- kernel/softlockup.c | 25 ++++++++++++++++++++++--- 7 files changed, 32 insertions(+), 42 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 3260a5c42b91..adb8077dc463 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -292,7 +292,6 @@ extern void sched_show_task(struct task_struct *p); #ifdef CONFIG_DETECT_SOFTLOCKUP extern void softlockup_tick(void); -extern void spawn_softlockup_task(void); extern void touch_softlockup_watchdog(void); extern void touch_all_softlockup_watchdogs(void); extern unsigned int softlockup_panic; @@ -2222,14 +2221,6 @@ static inline void inc_syscw(struct task_struct *tsk) } #endif -#ifdef CONFIG_SMP -void migration_init(void); -#else -static inline void migration_init(void) -{ -} -#endif - #ifndef TASK_SIZE_OF #define TASK_SIZE_OF(tsk) TASK_SIZE #endif diff --git a/include/linux/smp.h b/include/linux/smp.h index 48262f86c969..66484d4a8459 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -74,15 +74,10 @@ void __smp_call_function_single(int cpuid, struct call_single_data *data); #ifdef CONFIG_USE_GENERIC_SMP_HELPERS void generic_smp_call_function_single_interrupt(void); void generic_smp_call_function_interrupt(void); -void init_call_single_data(void); void ipi_call_lock(void); void ipi_call_unlock(void); void ipi_call_lock_irq(void); void ipi_call_unlock_irq(void); -#else -static inline void init_call_single_data(void) -{ -} #endif /* diff --git a/init/main.c b/init/main.c index b6fec08dbbef..20fdc9884b77 100644 --- a/init/main.c +++ b/init/main.c @@ -774,16 +774,7 @@ static void __init do_basic_setup(void) do_initcalls(); } -static int __initdata nosoftlockup; - -static int __init nosoftlockup_setup(char *str) -{ - nosoftlockup = 1; - return 1; -} -__setup("nosoftlockup", nosoftlockup_setup); - -static void __init __do_pre_smp_initcalls(void) +static void __init do_pre_smp_initcalls(void) { initcall_t *call; @@ -791,17 +782,6 @@ static void __init __do_pre_smp_initcalls(void) do_one_initcall(*call); } -static void __init do_pre_smp_initcalls(void) -{ - extern int spawn_ksoftirqd(void); - - init_call_single_data(); - migration_init(); - spawn_ksoftirqd(); - if (!nosoftlockup) - spawn_softlockup_task(); -} - static void run_init_process(char *init_filename) { argv_init[0] = init_filename; @@ -873,7 +853,6 @@ static int __init kernel_init(void * unused) smp_prepare_cpus(setup_max_cpus); - __do_pre_smp_initcalls(); do_pre_smp_initcalls(); smp_init(); diff --git a/kernel/sched.c b/kernel/sched.c index 0047bd9b96aa..fde1a1026359 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6389,7 +6389,7 @@ static struct notifier_block __cpuinitdata migration_notifier = { .priority = 10 }; -void __init migration_init(void) +static int __init migration_init(void) { void *cpu = (void *)(long)smp_processor_id(); int err; @@ -6399,7 +6399,10 @@ void __init migration_init(void) BUG_ON(err == NOTIFY_BAD); migration_call(&migration_notifier, CPU_ONLINE, cpu); register_cpu_notifier(&migration_notifier); + + return err; } +early_initcall(migration_init); #endif #ifdef CONFIG_SMP diff --git a/kernel/smp.c b/kernel/smp.c index 462c785ca1ee..96fc7c0edc59 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -33,7 +33,7 @@ struct call_single_queue { spinlock_t lock; }; -void __cpuinit init_call_single_data(void) +static int __cpuinit init_call_single_data(void) { int i; @@ -43,7 +43,9 @@ void __cpuinit init_call_single_data(void) spin_lock_init(&q->lock); INIT_LIST_HEAD(&q->list); } + return 0; } +early_initcall(init_call_single_data); static void csd_flag_wait(struct call_single_data *data) { diff --git a/kernel/softirq.c b/kernel/softirq.c index f6b03d56c2bf..c506f266a6b9 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -630,7 +630,7 @@ static struct notifier_block __cpuinitdata cpu_nfb = { .notifier_call = cpu_callback }; -__init int spawn_ksoftirqd(void) +static __init int spawn_ksoftirqd(void) { void *cpu = (void *)(long)smp_processor_id(); int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); @@ -640,6 +640,7 @@ __init int spawn_ksoftirqd(void) register_cpu_notifier(&cpu_nfb); return 0; } +early_initcall(spawn_ksoftirqd); #ifdef CONFIG_SMP /* diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 7bd8d1aadd5d..b75b492fbfcf 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -338,14 +338,33 @@ static struct notifier_block __cpuinitdata cpu_nfb = { .notifier_call = cpu_callback }; -__init void spawn_softlockup_task(void) +static int __initdata nosoftlockup; + +static int __init nosoftlockup_setup(char *str) +{ + nosoftlockup = 1; + return 1; +} +__setup("nosoftlockup", nosoftlockup_setup); + +static int __init spawn_softlockup_task(void) { void *cpu = (void *)(long)smp_processor_id(); - int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); + int err; - BUG_ON(err == NOTIFY_BAD); + if (nosoftlockup) + return 0; + + err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); + if (err == NOTIFY_BAD) { + BUG(); + return 1; + } cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); register_cpu_notifier(&cpu_nfb); atomic_notifier_chain_register(&panic_notifier_list, &panic_block); + + return 0; } +early_initcall(spawn_softlockup_task); From 20d8b67c06fa5e74f44e80b0a0fd68c8327f7c6a Mon Sep 17 00:00:00 2001 From: Eduard - Gabriel Munteanu Date: Fri, 25 Jul 2008 19:45:12 -0700 Subject: [PATCH 084/179] relay: add buffer-only channels; useful for early logging Allows one to create and use a channel with no associated files. Files can be initialized later. This is useful in scenarios such as logging in early code, before VFS is up. Therefore, such channels can be created and used as soon as kmem_cache_init() completed. This is needed by kmemtrace to do tracing in early kernel code. [kosaki.motohiro@jp.fujitsu.com: build fix] Signed-off-by: Eduard - Gabriel Munteanu Cc: Tom Zanussi Signed-off-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/relay.txt | 10 ++ include/linux/relay.h | 5 + kernel/relay.c | 170 +++++++++++++++++++++++----- 3 files changed, 156 insertions(+), 29 deletions(-) diff --git a/Documentation/filesystems/relay.txt b/Documentation/filesystems/relay.txt index 094f2d2f38b1..510b722667ac 100644 --- a/Documentation/filesystems/relay.txt +++ b/Documentation/filesystems/relay.txt @@ -294,6 +294,16 @@ user-defined data with a channel, and is immediately available (including in create_buf_file()) via chan->private_data or buf->chan->private_data. +Buffer-only channels +-------------------- + +These channels have no files associated and can be created with +relay_open(NULL, NULL, ...). Such channels are useful in scenarios such +as when doing early tracing in the kernel, before the VFS is up. In these +cases, one may open a buffer-only channel and then call +relay_late_setup_files() when the kernel is ready to handle files, +to expose the buffered data to the userspace. + Channel 'modes' --------------- diff --git a/include/linux/relay.h b/include/linux/relay.h index 6cd8c4425fc7..953fc055e875 100644 --- a/include/linux/relay.h +++ b/include/linux/relay.h @@ -48,6 +48,7 @@ struct rchan_buf size_t *padding; /* padding counts per sub-buffer */ size_t prev_padding; /* temporary variable */ size_t bytes_consumed; /* bytes consumed in cur read subbuf */ + size_t early_bytes; /* bytes consumed before VFS inited */ unsigned int cpu; /* this buf's cpu */ } ____cacheline_aligned; @@ -68,6 +69,7 @@ struct rchan int is_global; /* One global buffer ? */ struct list_head list; /* for channel list */ struct dentry *parent; /* parent dentry passed to open */ + int has_base_filename; /* has a filename associated? */ char base_filename[NAME_MAX]; /* saved base filename */ }; @@ -169,6 +171,9 @@ struct rchan *relay_open(const char *base_filename, size_t n_subbufs, struct rchan_callbacks *cb, void *private_data); +extern int relay_late_setup_files(struct rchan *chan, + const char *base_filename, + struct dentry *parent); extern void relay_close(struct rchan *chan); extern void relay_flush(struct rchan *chan); extern void relay_subbufs_consumed(struct rchan *chan, diff --git a/kernel/relay.c b/kernel/relay.c index 7de644cdec43..04006ef970b8 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -407,6 +407,35 @@ void relay_reset(struct rchan *chan) } EXPORT_SYMBOL_GPL(relay_reset); +static inline void relay_set_buf_dentry(struct rchan_buf *buf, + struct dentry *dentry) +{ + buf->dentry = dentry; + buf->dentry->d_inode->i_size = buf->early_bytes; +} + +static struct dentry *relay_create_buf_file(struct rchan *chan, + struct rchan_buf *buf, + unsigned int cpu) +{ + struct dentry *dentry; + char *tmpname; + + tmpname = kzalloc(NAME_MAX + 1, GFP_KERNEL); + if (!tmpname) + return NULL; + snprintf(tmpname, NAME_MAX, "%s%d", chan->base_filename, cpu); + + /* Create file in fs */ + dentry = chan->cb->create_buf_file(tmpname, chan->parent, + S_IRUSR, buf, + &chan->is_global); + + kfree(tmpname); + + return dentry; +} + /* * relay_open_buf - create a new relay channel buffer * @@ -416,45 +445,34 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu) { struct rchan_buf *buf = NULL; struct dentry *dentry; - char *tmpname; if (chan->is_global) return chan->buf[0]; - tmpname = kzalloc(NAME_MAX + 1, GFP_KERNEL); - if (!tmpname) - goto end; - snprintf(tmpname, NAME_MAX, "%s%d", chan->base_filename, cpu); - buf = relay_create_buf(chan); if (!buf) - goto free_name; + return NULL; + + if (chan->has_base_filename) { + dentry = relay_create_buf_file(chan, buf, cpu); + if (!dentry) + goto free_buf; + relay_set_buf_dentry(buf, dentry); + } buf->cpu = cpu; __relay_reset(buf, 1); - /* Create file in fs */ - dentry = chan->cb->create_buf_file(tmpname, chan->parent, S_IRUSR, - buf, &chan->is_global); - if (!dentry) - goto free_buf; - - buf->dentry = dentry; - if(chan->is_global) { chan->buf[0] = buf; buf->cpu = 0; } - goto free_name; + return buf; free_buf: relay_destroy_buf(buf); - buf = NULL; -free_name: - kfree(tmpname); -end: - return buf; + return NULL; } /** @@ -537,8 +555,8 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb, /** * relay_open - create a new relay channel - * @base_filename: base name of files to create - * @parent: dentry of parent directory, %NULL for root directory + * @base_filename: base name of files to create, %NULL for buffering only + * @parent: dentry of parent directory, %NULL for root directory or buffer * @subbuf_size: size of sub-buffers * @n_subbufs: number of sub-buffers * @cb: client callback functions @@ -560,8 +578,6 @@ struct rchan *relay_open(const char *base_filename, { unsigned int i; struct rchan *chan; - if (!base_filename) - return NULL; if (!(subbuf_size && n_subbufs)) return NULL; @@ -576,7 +592,10 @@ struct rchan *relay_open(const char *base_filename, chan->alloc_size = FIX_SIZE(subbuf_size * n_subbufs); chan->parent = parent; chan->private_data = private_data; - strlcpy(chan->base_filename, base_filename, NAME_MAX); + if (base_filename) { + chan->has_base_filename = 1; + strlcpy(chan->base_filename, base_filename, NAME_MAX); + } setup_callbacks(chan, cb); kref_init(&chan->kref); @@ -604,6 +623,94 @@ struct rchan *relay_open(const char *base_filename, } EXPORT_SYMBOL_GPL(relay_open); +struct rchan_percpu_buf_dispatcher { + struct rchan_buf *buf; + struct dentry *dentry; +}; + +/* Called in atomic context. */ +static void __relay_set_buf_dentry(void *info) +{ + struct rchan_percpu_buf_dispatcher *p = info; + + relay_set_buf_dentry(p->buf, p->dentry); +} + +/** + * relay_late_setup_files - triggers file creation + * @chan: channel to operate on + * @base_filename: base name of files to create + * @parent: dentry of parent directory, %NULL for root directory + * + * Returns 0 if successful, non-zero otherwise. + * + * Use to setup files for a previously buffer-only channel. + * Useful to do early tracing in kernel, before VFS is up, for example. + */ +int relay_late_setup_files(struct rchan *chan, + const char *base_filename, + struct dentry *parent) +{ + int err = 0; + unsigned int i, curr_cpu; + unsigned long flags; + struct dentry *dentry; + struct rchan_percpu_buf_dispatcher disp; + + if (!chan || !base_filename) + return -EINVAL; + + strlcpy(chan->base_filename, base_filename, NAME_MAX); + + mutex_lock(&relay_channels_mutex); + /* Is chan already set up? */ + if (unlikely(chan->has_base_filename)) + return -EEXIST; + chan->has_base_filename = 1; + chan->parent = parent; + curr_cpu = get_cpu(); + /* + * The CPU hotplug notifier ran before us and created buffers with + * no files associated. So it's safe to call relay_setup_buf_file() + * on all currently online CPUs. + */ + for_each_online_cpu(i) { + if (unlikely(!chan->buf[i])) { + printk(KERN_ERR "relay_late_setup_files: CPU %u " + "has no buffer, it must have!\n", i); + BUG(); + err = -EINVAL; + break; + } + + dentry = relay_create_buf_file(chan, chan->buf[i], i); + if (unlikely(!dentry)) { + err = -EINVAL; + break; + } + + if (curr_cpu == i) { + local_irq_save(flags); + relay_set_buf_dentry(chan->buf[i], dentry); + local_irq_restore(flags); + } else { + disp.buf = chan->buf[i]; + disp.dentry = dentry; + smp_mb(); + /* relay_channels_mutex must be held, so wait. */ + err = smp_call_function_single(i, + __relay_set_buf_dentry, + &disp, 1); + } + if (unlikely(err)) + break; + } + put_cpu(); + mutex_unlock(&relay_channels_mutex); + + return err; +} + /** * relay_switch_subbuf - switch to a new sub-buffer * @buf: channel buffer @@ -627,8 +734,13 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length) old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs; buf->padding[old_subbuf] = buf->prev_padding; buf->subbufs_produced++; - buf->dentry->d_inode->i_size += buf->chan->subbuf_size - - buf->padding[old_subbuf]; + if (buf->dentry) + buf->dentry->d_inode->i_size += + buf->chan->subbuf_size - + buf->padding[old_subbuf]; + else + buf->early_bytes += buf->chan->subbuf_size - + buf->padding[old_subbuf]; smp_mb(); if (waitqueue_active(&buf->read_wait)) /* @@ -1237,4 +1349,4 @@ static __init int relay_init(void) return 0; } -module_init(relay_init); +early_initcall(relay_init); From 080ccd4573607a930367c2128fc709814b2ade5d Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 25 Jul 2008 19:45:13 -0700 Subject: [PATCH 085/179] include/linux/aio.h: removed duplicated include Removed duplicated include in include/linux/aio.h Signed-off-by: Huang Weiyi Signed-off-by: Benjamin LaHaise Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/aio.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/aio.h b/include/linux/aio.h index b51ddd28444e..09b276c35227 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h @@ -7,7 +7,6 @@ #include #include -#include #define AIO_MAXSEGS 4 #define AIO_KIOGRP_NR_ATOMIC 8 From a14e4b572b0ee5c6dbe4aceb83d00b2c969324e9 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:14 -0700 Subject: [PATCH 086/179] omfs: add filesystem documentation These patches add the Optimized MPEG Filesystem, a proprietary filesystem used by the embedded devices Rio Karma and ReplayTV, which are no longer manufactured. This filesystem module enables people to access files on these devices. This patch: OMFS is a proprietary filesystem created for the ReplayTV and also used by the Rio Karma. It uses hash tables with unordered, unbounded lists in each bucket for directories, extents for data blocks, 64-bit addressing for blocks, with up to 8K blocks (only 2K of a given block is ever used for metadata, so the FS still works with 4K pages). Document the filesystem usage and structures. Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/omfs.txt | 106 +++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 Documentation/filesystems/omfs.txt diff --git a/Documentation/filesystems/omfs.txt b/Documentation/filesystems/omfs.txt new file mode 100644 index 000000000000..1d0d41ff5c65 --- /dev/null +++ b/Documentation/filesystems/omfs.txt @@ -0,0 +1,106 @@ +Optimized MPEG Filesystem (OMFS) + +Overview +======== + +OMFS is a filesystem created by SonicBlue for use in the ReplayTV DVR +and Rio Karma MP3 player. The filesystem is extent-based, utilizing +block sizes from 2k to 8k, with hash-based directories. This +filesystem driver may be used to read and write disks from these +devices. + +Note, it is not recommended that this FS be used in place of a general +filesystem for your own streaming media device. Native Linux filesystems +will likely perform better. + +More information is available at: + + http://linux-karma.sf.net/ + +Various utilities, including mkomfs and omfsck, are included with +omfsprogs, available at: + + http://bobcopeland.com/karma/ + +Instructions are included in its README. + +Options +======= + +OMFS supports the following mount-time options: + + uid=n - make all files owned by specified user + gid=n - make all files owned by specified group + umask=xxx - set permission umask to xxx + fmask=xxx - set umask to xxx for files + dmask=xxx - set umask to xxx for directories + +Disk format +=========== + +OMFS discriminates between "sysblocks" and normal data blocks. The sysblock +group consists of super block information, file metadata, directory structures, +and extents. Each sysblock has a header containing CRCs of the entire +sysblock, and may be mirrored in successive blocks on the disk. A sysblock may +have a smaller size than a data block, but since they are both addressed by the +same 64-bit block number, any remaining space in the smaller sysblock is +unused. + +Sysblock header information: + +struct omfs_header { + __be64 h_self; /* FS block where this is located */ + __be32 h_body_size; /* size of useful data after header */ + __be16 h_crc; /* crc-ccitt of body_size bytes */ + char h_fill1[2]; + u8 h_version; /* version, always 1 */ + char h_type; /* OMFS_INODE_X */ + u8 h_magic; /* OMFS_IMAGIC */ + u8 h_check_xor; /* XOR of header bytes before this */ + __be32 h_fill2; +}; + +Files and directories are both represented by omfs_inode: + +struct omfs_inode { + struct omfs_header i_head; /* header */ + __be64 i_parent; /* parent containing this inode */ + __be64 i_sibling; /* next inode in hash bucket */ + __be64 i_ctime; /* ctime, in milliseconds */ + char i_fill1[35]; + char i_type; /* OMFS_[DIR,FILE] */ + __be32 i_fill2; + char i_fill3[64]; + char i_name[OMFS_NAMELEN]; /* filename */ + __be64 i_size; /* size of file, in bytes */ +}; + +Directories in OMFS are implemented as a large hash table. Filenames are +hashed then prepended into the bucket list beginning at OMFS_DIR_START. +Lookup requires hashing the filename, then seeking across i_sibling pointers +until a match is found on i_name. Empty buckets are represented by block +pointers with all-1s (~0). + +A file is an omfs_inode structure followed by an extent table beginning at +OMFS_EXTENT_START: + +struct omfs_extent_entry { + __be64 e_cluster; /* start location of a set of blocks */ + __be64 e_blocks; /* number of blocks after e_cluster */ +}; + +struct omfs_extent { + __be64 e_next; /* next extent table location */ + __be32 e_extent_count; /* total # extents in this table */ + __be32 e_fill; + struct omfs_extent_entry e_entry; /* start of extent entries */ +}; + +Each extent holds the block offset followed by number of blocks allocated to +the extent. The final extent in each table is a terminator with e_cluster +being ~0 and e_blocks being ones'-complement of the total number of blocks +in the table. + +If this table overflows, a continuation inode is written and pointed to by +e_next. These have a header but lack the rest of the inode structure. + From 1b002d7b173ae7cc15ed90d3c07f6d106babc510 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:15 -0700 Subject: [PATCH 087/179] omfs: define filesystem structures Add header files containing OMFS on-disk and memory structures. Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/omfs/omfs.h | 67 +++++++++++++++++++++++++++++++++++++++ fs/omfs/omfs_fs.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 fs/omfs/omfs.h create mode 100644 fs/omfs/omfs_fs.h diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h new file mode 100644 index 000000000000..2bc0f0670406 --- /dev/null +++ b/fs/omfs/omfs.h @@ -0,0 +1,67 @@ +#ifndef _OMFS_H +#define _OMFS_H + +#include +#include + +#include "omfs_fs.h" + +/* In-memory structures */ +struct omfs_sb_info { + u64 s_num_blocks; + u64 s_bitmap_ino; + u64 s_root_ino; + u32 s_blocksize; + u32 s_mirrors; + u32 s_sys_blocksize; + u32 s_clustersize; + int s_block_shift; + unsigned long **s_imap; + int s_imap_size; + struct mutex s_bitmap_lock; + int s_uid; + int s_gid; + int s_dmask; + int s_fmask; +}; + +/* convert a cluster number to a scaled block number */ +static inline sector_t clus_to_blk(struct omfs_sb_info *sbi, sector_t block) +{ + return block << sbi->s_block_shift; +} + +static inline struct omfs_sb_info *OMFS_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} + +/* bitmap.c */ +extern unsigned long omfs_count_free(struct super_block *sb); +extern int omfs_allocate_block(struct super_block *sb, u64 block); +extern int omfs_allocate_range(struct super_block *sb, int min_request, + int max_request, u64 *return_block, int *return_size); +extern int omfs_clear_range(struct super_block *sb, u64 block, int count); + +/* dir.c */ +extern struct file_operations omfs_dir_operations; +extern struct inode_operations omfs_dir_inops; +extern int omfs_make_empty(struct inode *inode, struct super_block *sb); +extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, + u64 fsblock); + +/* file.c */ +extern struct file_operations omfs_file_operations; +extern struct inode_operations omfs_file_inops; +extern struct address_space_operations omfs_aops; +extern void omfs_make_empty_table(struct buffer_head *bh, int offset); +extern int omfs_shrink_inode(struct inode *inode); + +/* inode.c */ +extern struct inode *omfs_iget(struct super_block *sb, ino_t inode); +extern struct inode *omfs_new_inode(struct inode *dir, int mode); +extern int omfs_reserve_block(struct super_block *sb, sector_t block); +extern int omfs_find_empty_block(struct super_block *sb, int mode, ino_t *ino); +extern int omfs_sync_inode(struct inode *inode); + +#endif diff --git a/fs/omfs/omfs_fs.h b/fs/omfs/omfs_fs.h new file mode 100644 index 000000000000..12cca245d6e8 --- /dev/null +++ b/fs/omfs/omfs_fs.h @@ -0,0 +1,80 @@ +#ifndef _OMFS_FS_H +#define _OMFS_FS_H + +/* OMFS On-disk structures */ + +#define OMFS_MAGIC 0xC2993D87 +#define OMFS_IMAGIC 0xD2 + +#define OMFS_DIR 'D' +#define OMFS_FILE 'F' +#define OMFS_INODE_NORMAL 'e' +#define OMFS_INODE_CONTINUATION 'c' +#define OMFS_INODE_SYSTEM 's' +#define OMFS_NAMELEN 256 +#define OMFS_DIR_START 0x1b8 +#define OMFS_EXTENT_START 0x1d0 +#define OMFS_EXTENT_CONT 0x40 +#define OMFS_XOR_COUNT 19 +#define OMFS_MAX_BLOCK_SIZE 8192 + +struct omfs_super_block { + char s_fill1[256]; + __be64 s_root_block; /* block number of omfs_root_block */ + __be64 s_num_blocks; /* total number of FS blocks */ + __be32 s_magic; /* OMFS_MAGIC */ + __be32 s_blocksize; /* size of a block */ + __be32 s_mirrors; /* # of mirrors of system blocks */ + __be32 s_sys_blocksize; /* size of non-data blocks */ +}; + +struct omfs_header { + __be64 h_self; /* FS block where this is located */ + __be32 h_body_size; /* size of useful data after header */ + __be16 h_crc; /* crc-ccitt of body_size bytes */ + char h_fill1[2]; + u8 h_version; /* version, always 1 */ + char h_type; /* OMFS_INODE_X */ + u8 h_magic; /* OMFS_IMAGIC */ + u8 h_check_xor; /* XOR of header bytes before this */ + __be32 h_fill2; +}; + +struct omfs_root_block { + struct omfs_header r_head; /* header */ + __be64 r_fill1; + __be64 r_num_blocks; /* total number of FS blocks */ + __be64 r_root_dir; /* block # of root directory */ + __be64 r_bitmap; /* block # of free space bitmap */ + __be32 r_blocksize; /* size of a block */ + __be32 r_clustersize; /* size allocated for data blocks */ + __be64 r_mirrors; /* # of mirrors of system blocks */ + char r_name[OMFS_NAMELEN]; /* partition label */ +}; + +struct omfs_inode { + struct omfs_header i_head; /* header */ + __be64 i_parent; /* parent containing this inode */ + __be64 i_sibling; /* next inode in hash bucket */ + __be64 i_ctime; /* ctime, in milliseconds */ + char i_fill1[35]; + char i_type; /* OMFS_[DIR,FILE] */ + __be32 i_fill2; + char i_fill3[64]; + char i_name[OMFS_NAMELEN]; /* filename */ + __be64 i_size; /* size of file, in bytes */ +}; + +struct omfs_extent_entry { + __be64 e_cluster; /* start location of a set of blocks */ + __be64 e_blocks; /* number of blocks after e_cluster */ +}; + +struct omfs_extent { + __be64 e_next; /* next extent table location */ + __be32 e_extent_count; /* total # extents in this table */ + __be32 e_fill; + struct omfs_extent_entry e_entry; /* start of extent entries */ +}; + +#endif From 555e3775ced1d05203934fc6529bbf0560dd8733 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:15 -0700 Subject: [PATCH 088/179] omfs: add inode routines Add basic superblock and inode handling routines for OMFS Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/omfs/inode.c | 553 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100644 fs/omfs/inode.c diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c new file mode 100644 index 000000000000..d865f5535436 --- /dev/null +++ b/fs/omfs/inode.c @@ -0,0 +1,553 @@ +/* + * Optimized MPEG FS - inode and super operations. + * Copyright (C) 2006 Bob Copeland + * Released under GPL v2. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "omfs.h" + +MODULE_AUTHOR("Bob Copeland "); +MODULE_DESCRIPTION("OMFS (ReplayTV/Karma) Filesystem for Linux"); +MODULE_LICENSE("GPL"); + +struct inode *omfs_new_inode(struct inode *dir, int mode) +{ + struct inode *inode; + u64 new_block; + int err; + int len; + struct omfs_sb_info *sbi = OMFS_SB(dir->i_sb); + + inode = new_inode(dir->i_sb); + if (!inode) + return ERR_PTR(-ENOMEM); + + err = omfs_allocate_range(dir->i_sb, sbi->s_mirrors, sbi->s_mirrors, + &new_block, &len); + if (err) + goto fail; + + inode->i_ino = new_block; + inode->i_mode = mode; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_blocks = 0; + inode->i_mapping->a_ops = &omfs_aops; + + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + switch (mode & S_IFMT) { + case S_IFDIR: + inode->i_op = &omfs_dir_inops; + inode->i_fop = &omfs_dir_operations; + inode->i_size = sbi->s_sys_blocksize; + inc_nlink(inode); + break; + case S_IFREG: + inode->i_op = &omfs_file_inops; + inode->i_fop = &omfs_file_operations; + inode->i_size = 0; + break; + } + + insert_inode_hash(inode); + mark_inode_dirty(inode); + return inode; +fail: + make_bad_inode(inode); + iput(inode); + return ERR_PTR(err); +} + +/* + * Update the header checksums for a dirty inode based on its contents. + * Caller is expected to hold the buffer head underlying oi and mark it + * dirty. + */ +static void omfs_update_checksums(struct omfs_inode *oi) +{ + int xor, i, ofs = 0, count; + u16 crc = 0; + unsigned char *ptr = (unsigned char *) oi; + + count = be32_to_cpu(oi->i_head.h_body_size); + ofs = sizeof(struct omfs_header); + + crc = crc_itu_t(crc, ptr + ofs, count); + oi->i_head.h_crc = cpu_to_be16(crc); + + xor = ptr[0]; + for (i = 1; i < OMFS_XOR_COUNT; i++) + xor ^= ptr[i]; + + oi->i_head.h_check_xor = xor; +} + +static int omfs_write_inode(struct inode *inode, int wait) +{ + struct omfs_inode *oi; + struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); + struct buffer_head *bh, *bh2; + unsigned int block; + u64 ctime; + int i; + int ret = -EIO; + int sync_failed = 0; + + /* get current inode since we may have written sibling ptrs etc. */ + block = clus_to_blk(sbi, inode->i_ino); + bh = sb_bread(inode->i_sb, block); + if (!bh) + goto out; + + oi = (struct omfs_inode *) bh->b_data; + + oi->i_head.h_self = cpu_to_be64(inode->i_ino); + if (S_ISDIR(inode->i_mode)) + oi->i_type = OMFS_DIR; + else if (S_ISREG(inode->i_mode)) + oi->i_type = OMFS_FILE; + else { + printk(KERN_WARNING "omfs: unknown file type: %d\n", + inode->i_mode); + goto out_brelse; + } + + oi->i_head.h_body_size = cpu_to_be32(sbi->s_sys_blocksize - + sizeof(struct omfs_header)); + oi->i_head.h_version = 1; + oi->i_head.h_type = OMFS_INODE_NORMAL; + oi->i_head.h_magic = OMFS_IMAGIC; + oi->i_size = cpu_to_be64(inode->i_size); + + ctime = inode->i_ctime.tv_sec * 1000LL + + ((inode->i_ctime.tv_nsec + 999)/1000); + oi->i_ctime = cpu_to_be64(ctime); + + omfs_update_checksums(oi); + + mark_buffer_dirty(bh); + if (wait) { + sync_dirty_buffer(bh); + if (buffer_req(bh) && !buffer_uptodate(bh)) + sync_failed = 1; + } + + /* if mirroring writes, copy to next fsblock */ + for (i = 1; i < sbi->s_mirrors; i++) { + bh2 = sb_bread(inode->i_sb, block + i * + (sbi->s_blocksize / sbi->s_sys_blocksize)); + if (!bh2) + goto out_brelse; + + memcpy(bh2->b_data, bh->b_data, bh->b_size); + mark_buffer_dirty(bh2); + if (wait) { + sync_dirty_buffer(bh2); + if (buffer_req(bh2) && !buffer_uptodate(bh2)) + sync_failed = 1; + } + brelse(bh2); + } + ret = (sync_failed) ? -EIO : 0; +out_brelse: + brelse(bh); +out: + return ret; +} + +int omfs_sync_inode(struct inode *inode) +{ + return omfs_write_inode(inode, 1); +} + +/* + * called when an entry is deleted, need to clear the bits in the + * bitmaps. + */ +static void omfs_delete_inode(struct inode *inode) +{ + truncate_inode_pages(&inode->i_data, 0); + + if (S_ISREG(inode->i_mode)) { + inode->i_size = 0; + omfs_shrink_inode(inode); + } + + omfs_clear_range(inode->i_sb, inode->i_ino, 2); + clear_inode(inode); +} + +struct inode *omfs_iget(struct super_block *sb, ino_t ino) +{ + struct omfs_sb_info *sbi = OMFS_SB(sb); + struct omfs_inode *oi; + struct buffer_head *bh; + unsigned int block; + u64 ctime; + unsigned long nsecs; + struct inode *inode; + + inode = iget_locked(sb, ino); + if (!inode) + return ERR_PTR(-ENOMEM); + if (!(inode->i_state & I_NEW)) + return inode; + + block = clus_to_blk(sbi, ino); + bh = sb_bread(inode->i_sb, block); + if (!bh) + goto iget_failed; + + oi = (struct omfs_inode *)bh->b_data; + + /* check self */ + if (ino != be64_to_cpu(oi->i_head.h_self)) + goto fail_bh; + + inode->i_uid = sbi->s_uid; + inode->i_gid = sbi->s_gid; + + ctime = be64_to_cpu(oi->i_ctime); + nsecs = do_div(ctime, 1000) * 1000L; + + inode->i_atime.tv_sec = ctime; + inode->i_mtime.tv_sec = ctime; + inode->i_ctime.tv_sec = ctime; + inode->i_atime.tv_nsec = nsecs; + inode->i_mtime.tv_nsec = nsecs; + inode->i_ctime.tv_nsec = nsecs; + + inode->i_mapping->a_ops = &omfs_aops; + + switch (oi->i_type) { + case OMFS_DIR: + inode->i_mode = S_IFDIR | (S_IRWXUGO & ~sbi->s_dmask); + inode->i_op = &omfs_dir_inops; + inode->i_fop = &omfs_dir_operations; + inode->i_size = be32_to_cpu(oi->i_head.h_body_size) + + sizeof(struct omfs_header); + inc_nlink(inode); + break; + case OMFS_FILE: + inode->i_mode = S_IFREG | (S_IRWXUGO & ~sbi->s_fmask); + inode->i_fop = &omfs_file_operations; + inode->i_size = be64_to_cpu(oi->i_size); + break; + } + brelse(bh); + unlock_new_inode(inode); + return inode; +fail_bh: + brelse(bh); +iget_failed: + iget_failed(inode); + return ERR_PTR(-EIO); +} + +static void omfs_put_super(struct super_block *sb) +{ + struct omfs_sb_info *sbi = OMFS_SB(sb); + kfree(sbi->s_imap); + kfree(sbi); + sb->s_fs_info = NULL; +} + +static int omfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct super_block *s = dentry->d_sb; + struct omfs_sb_info *sbi = OMFS_SB(s); + buf->f_type = OMFS_MAGIC; + buf->f_bsize = sbi->s_blocksize; + buf->f_blocks = sbi->s_num_blocks; + buf->f_files = sbi->s_num_blocks; + buf->f_namelen = OMFS_NAMELEN; + + buf->f_bfree = buf->f_bavail = buf->f_ffree = + omfs_count_free(s); + return 0; +} + +static struct super_operations omfs_sops = { + .write_inode = omfs_write_inode, + .delete_inode = omfs_delete_inode, + .put_super = omfs_put_super, + .statfs = omfs_statfs, + .show_options = generic_show_options, +}; + +/* + * For Rio Karma, there is an on-disk free bitmap whose location is + * stored in the root block. For ReplayTV, there is no such free bitmap + * so we have to walk the tree. Both inodes and file data are allocated + * from the same map. This array can be big (300k) so we allocate + * in units of the blocksize. + */ +static int omfs_get_imap(struct super_block *sb) +{ + int bitmap_size; + int array_size; + int count; + struct omfs_sb_info *sbi = OMFS_SB(sb); + struct buffer_head *bh; + unsigned long **ptr; + sector_t block; + + bitmap_size = DIV_ROUND_UP(sbi->s_num_blocks, 8); + array_size = DIV_ROUND_UP(bitmap_size, sb->s_blocksize); + + if (sbi->s_bitmap_ino == ~0ULL) + goto out; + + sbi->s_imap_size = array_size; + sbi->s_imap = kzalloc(array_size * sizeof(unsigned long *), GFP_KERNEL); + if (!sbi->s_imap) + goto nomem; + + block = clus_to_blk(sbi, sbi->s_bitmap_ino); + ptr = sbi->s_imap; + for (count = bitmap_size; count > 0; count -= sb->s_blocksize) { + bh = sb_bread(sb, block++); + if (!bh) + goto nomem_free; + *ptr = kmalloc(sb->s_blocksize, GFP_KERNEL); + if (!*ptr) { + brelse(bh); + goto nomem_free; + } + memcpy(*ptr, bh->b_data, sb->s_blocksize); + if (count < sb->s_blocksize) + memset((void *)*ptr + count, 0xff, + sb->s_blocksize - count); + brelse(bh); + ptr++; + } +out: + return 0; + +nomem_free: + for (count = 0; count < array_size; count++) + kfree(sbi->s_imap[count]); + + kfree(sbi->s_imap); +nomem: + sbi->s_imap = NULL; + sbi->s_imap_size = 0; + return -ENOMEM; +} + +enum { + Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask +}; + +static match_table_t tokens = { + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, + {Opt_umask, "umask=%o"}, + {Opt_dmask, "dmask=%o"}, + {Opt_fmask, "fmask=%o"}, +}; + +static int parse_options(char *options, struct omfs_sb_info *sbi) +{ + char *p; + substring_t args[MAX_OPT_ARGS]; + int option; + + if (!options) + return 1; + + while ((p = strsep(&options, ",")) != NULL) { + int token; + if (!*p) + continue; + + token = match_token(p, tokens, args); + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + return 0; + sbi->s_uid = option; + break; + case Opt_gid: + if (match_int(&args[0], &option)) + return 0; + sbi->s_gid = option; + break; + case Opt_umask: + if (match_octal(&args[0], &option)) + return 0; + sbi->s_fmask = sbi->s_dmask = option; + break; + case Opt_dmask: + if (match_octal(&args[0], &option)) + return 0; + sbi->s_dmask = option; + break; + case Opt_fmask: + if (match_octal(&args[0], &option)) + return 0; + sbi->s_fmask = option; + break; + default: + return 0; + } + } + return 1; +} + +static int omfs_fill_super(struct super_block *sb, void *data, int silent) +{ + struct buffer_head *bh, *bh2; + struct omfs_super_block *omfs_sb; + struct omfs_root_block *omfs_rb; + struct omfs_sb_info *sbi; + struct inode *root; + sector_t start; + int ret = -EINVAL; + + save_mount_options(sb, (char *) data); + + sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL); + if (!sbi) + return -ENOMEM; + + sb->s_fs_info = sbi; + + sbi->s_uid = current->uid; + sbi->s_gid = current->gid; + sbi->s_dmask = sbi->s_fmask = current->fs->umask; + + if (!parse_options((char *) data, sbi)) + goto end; + + sb->s_maxbytes = 0xffffffff; + + sb_set_blocksize(sb, 0x200); + + bh = sb_bread(sb, 0); + if (!bh) + goto end; + + omfs_sb = (struct omfs_super_block *)bh->b_data; + + if (omfs_sb->s_magic != cpu_to_be32(OMFS_MAGIC)) { + if (!silent) + printk(KERN_ERR "omfs: Invalid superblock (%x)\n", + omfs_sb->s_magic); + goto out_brelse_bh; + } + sb->s_magic = OMFS_MAGIC; + + sbi->s_num_blocks = be64_to_cpu(omfs_sb->s_num_blocks); + sbi->s_blocksize = be32_to_cpu(omfs_sb->s_blocksize); + sbi->s_mirrors = be32_to_cpu(omfs_sb->s_mirrors); + sbi->s_root_ino = be64_to_cpu(omfs_sb->s_root_block); + sbi->s_sys_blocksize = be32_to_cpu(omfs_sb->s_sys_blocksize); + mutex_init(&sbi->s_bitmap_lock); + + if (sbi->s_sys_blocksize > PAGE_SIZE) { + printk(KERN_ERR "omfs: sysblock size (%d) is out of range\n", + sbi->s_sys_blocksize); + goto out_brelse_bh; + } + + if (sbi->s_blocksize < sbi->s_sys_blocksize || + sbi->s_blocksize > OMFS_MAX_BLOCK_SIZE) { + printk(KERN_ERR "omfs: block size (%d) is out of range\n", + sbi->s_blocksize); + goto out_brelse_bh; + } + + /* + * Use sys_blocksize as the fs block since it is smaller than a + * page while the fs blocksize can be larger. + */ + sb_set_blocksize(sb, sbi->s_sys_blocksize); + + /* + * ...and the difference goes into a shift. sys_blocksize is always + * a power of two factor of blocksize. + */ + sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) - + get_bitmask_order(sbi->s_sys_blocksize); + + start = clus_to_blk(sbi, be64_to_cpu(omfs_sb->s_root_block)); + bh2 = sb_bread(sb, start); + if (!bh2) + goto out_brelse_bh; + + omfs_rb = (struct omfs_root_block *)bh2->b_data; + + sbi->s_bitmap_ino = be64_to_cpu(omfs_rb->r_bitmap); + sbi->s_clustersize = be32_to_cpu(omfs_rb->r_clustersize); + + if (sbi->s_num_blocks != be64_to_cpu(omfs_rb->r_num_blocks)) { + printk(KERN_ERR "omfs: block count discrepancy between " + "super and root blocks (%llx, %llx)\n", + sbi->s_num_blocks, be64_to_cpu(omfs_rb->r_num_blocks)); + goto out_brelse_bh2; + } + + ret = omfs_get_imap(sb); + if (ret) + goto out_brelse_bh2; + + sb->s_op = &omfs_sops; + + root = omfs_iget(sb, be64_to_cpu(omfs_rb->r_root_dir)); + if (IS_ERR(root)) { + ret = PTR_ERR(root); + goto out_brelse_bh2; + } + + sb->s_root = d_alloc_root(root); + if (!sb->s_root) { + iput(root); + goto out_brelse_bh2; + } + printk(KERN_DEBUG "omfs: Mounted volume %s\n", omfs_rb->r_name); + + ret = 0; +out_brelse_bh2: + brelse(bh2); +out_brelse_bh: + brelse(bh); +end: + return ret; +} + +static int omfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data, struct vfsmount *m) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, omfs_fill_super, m); +} + +static struct file_system_type omfs_fs_type = { + .owner = THIS_MODULE, + .name = "omfs", + .get_sb = omfs_get_sb, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, +}; + +static int __init init_omfs_fs(void) +{ + return register_filesystem(&omfs_fs_type); +} + +static void __exit exit_omfs_fs(void) +{ + unregister_filesystem(&omfs_fs_type); +} + +module_init(init_omfs_fs); +module_exit(exit_omfs_fs); From a3ab7155ea21aadc8a4d5687e91b3d876973185e Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:16 -0700 Subject: [PATCH 089/179] omfs: add directory routines Add lookup and directory management routines for OMFS. The filesystem uses hashing based on the filename and stores collisions, unordered, in siblings of files' inode structures. To support telldir, the current position in the hash table is encoded in fpos. Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/omfs/dir.c | 504 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100644 fs/omfs/dir.c diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c new file mode 100644 index 000000000000..05a5bc31e4bd --- /dev/null +++ b/fs/omfs/dir.c @@ -0,0 +1,504 @@ +/* + * OMFS (as used by RIO Karma) directory operations. + * Copyright (C) 2005 Bob Copeland + * Released under GPL v2. + */ + +#include +#include +#include +#include "omfs.h" + +static int omfs_hash(const char *name, int namelen, int mod) +{ + int i, hash = 0; + for (i = 0; i < namelen; i++) + hash ^= tolower(name[i]) << (i % 24); + return hash % mod; +} + +/* + * Finds the bucket for a given name and reads the containing block; + * *ofs is set to the offset of the first list entry. + */ +static struct buffer_head *omfs_get_bucket(struct inode *dir, + const char *name, int namelen, int *ofs) +{ + int nbuckets = (dir->i_size - OMFS_DIR_START)/8; + int block = clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino); + int bucket = omfs_hash(name, namelen, nbuckets); + + *ofs = OMFS_DIR_START + bucket * 8; + return sb_bread(dir->i_sb, block); +} + +static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block, + const char *name, int namelen, + u64 *prev_block) +{ + struct buffer_head *bh; + struct omfs_inode *oi; + int err = -ENOENT; + *prev_block = ~0; + + while (block != ~0) { + bh = sb_bread(dir->i_sb, + clus_to_blk(OMFS_SB(dir->i_sb), block)); + if (!bh) { + err = -EIO; + goto err; + } + + oi = (struct omfs_inode *) bh->b_data; + if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, block)) { + brelse(bh); + goto err; + } + + if (strncmp(oi->i_name, name, namelen) == 0) + return bh; + + *prev_block = block; + block = be64_to_cpu(oi->i_sibling); + brelse(bh); + } +err: + return ERR_PTR(err); +} + +static struct buffer_head *omfs_find_entry(struct inode *dir, + const char *name, int namelen) +{ + struct buffer_head *bh; + int ofs; + u64 block, dummy; + + bh = omfs_get_bucket(dir, name, namelen, &ofs); + if (!bh) + return ERR_PTR(-EIO); + + block = be64_to_cpu(*((__be64 *) &bh->b_data[ofs])); + brelse(bh); + + return omfs_scan_list(dir, block, name, namelen, &dummy); +} + +int omfs_make_empty(struct inode *inode, struct super_block *sb) +{ + struct omfs_sb_info *sbi = OMFS_SB(sb); + int block = clus_to_blk(sbi, inode->i_ino); + struct buffer_head *bh; + struct omfs_inode *oi; + + bh = sb_bread(sb, block); + if (!bh) + return -ENOMEM; + + memset(bh->b_data, 0, sizeof(struct omfs_inode)); + + if (inode->i_mode & S_IFDIR) { + memset(&bh->b_data[OMFS_DIR_START], 0xff, + sbi->s_sys_blocksize - OMFS_DIR_START); + } else + omfs_make_empty_table(bh, OMFS_EXTENT_START); + + oi = (struct omfs_inode *) bh->b_data; + oi->i_head.h_self = cpu_to_be64(inode->i_ino); + oi->i_sibling = ~0ULL; + + mark_buffer_dirty(bh); + brelse(bh); + return 0; +} + +static int omfs_add_link(struct dentry *dentry, struct inode *inode) +{ + struct inode *dir = dentry->d_parent->d_inode; + const char *name = dentry->d_name.name; + int namelen = dentry->d_name.len; + struct omfs_inode *oi; + struct buffer_head *bh; + u64 block; + __be64 *entry; + int ofs; + + /* just prepend to head of queue in proper bucket */ + bh = omfs_get_bucket(dir, name, namelen, &ofs); + if (!bh) + goto out; + + entry = (__be64 *) &bh->b_data[ofs]; + block = be64_to_cpu(*entry); + *entry = cpu_to_be64(inode->i_ino); + mark_buffer_dirty(bh); + brelse(bh); + + /* now set the sibling and parent pointers on the new inode */ + bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), inode->i_ino)); + if (!bh) + goto out; + + oi = (struct omfs_inode *) bh->b_data; + memcpy(oi->i_name, name, namelen); + memset(oi->i_name + namelen, 0, OMFS_NAMELEN - namelen); + oi->i_sibling = cpu_to_be64(block); + oi->i_parent = cpu_to_be64(dir->i_ino); + mark_buffer_dirty(bh); + brelse(bh); + + dir->i_ctime = CURRENT_TIME_SEC; + + /* mark affected inodes dirty to rebuild checksums */ + mark_inode_dirty(dir); + mark_inode_dirty(inode); + return 0; +out: + return -ENOMEM; +} + +static int omfs_delete_entry(struct dentry *dentry) +{ + struct inode *dir = dentry->d_parent->d_inode; + struct inode *dirty; + const char *name = dentry->d_name.name; + int namelen = dentry->d_name.len; + struct omfs_inode *oi; + struct buffer_head *bh, *bh2; + __be64 *entry, next; + u64 block, prev; + int ofs; + int err = -ENOMEM; + + /* delete the proper node in the bucket's linked list */ + bh = omfs_get_bucket(dir, name, namelen, &ofs); + if (!bh) + goto out; + + entry = (__be64 *) &bh->b_data[ofs]; + block = be64_to_cpu(*entry); + + bh2 = omfs_scan_list(dir, block, name, namelen, &prev); + if (IS_ERR(bh2)) { + err = PTR_ERR(bh2); + goto out_free_bh; + } + + oi = (struct omfs_inode *) bh2->b_data; + next = oi->i_sibling; + brelse(bh2); + + if (prev != ~0) { + /* found in middle of list, get list ptr */ + brelse(bh); + bh = sb_bread(dir->i_sb, + clus_to_blk(OMFS_SB(dir->i_sb), prev)); + if (!bh) + goto out; + + oi = (struct omfs_inode *) bh->b_data; + entry = &oi->i_sibling; + } + + *entry = next; + mark_buffer_dirty(bh); + + if (prev != ~0) { + dirty = omfs_iget(dir->i_sb, prev); + if (!IS_ERR(dirty)) { + mark_inode_dirty(dirty); + iput(dirty); + } + } + + err = 0; +out_free_bh: + brelse(bh); +out: + return err; +} + +static int omfs_dir_is_empty(struct inode *inode) +{ + int nbuckets = (inode->i_size - OMFS_DIR_START) / 8; + struct buffer_head *bh; + u64 *ptr; + int i; + + bh = sb_bread(inode->i_sb, clus_to_blk(OMFS_SB(inode->i_sb), + inode->i_ino)); + + if (!bh) + return 0; + + ptr = (u64 *) &bh->b_data[OMFS_DIR_START]; + + for (i = 0; i < nbuckets; i++, ptr++) + if (*ptr != ~0) + break; + + brelse(bh); + return *ptr != ~0; +} + +static int omfs_unlink(struct inode *dir, struct dentry *dentry) +{ + int ret; + struct inode *inode = dentry->d_inode; + + ret = omfs_delete_entry(dentry); + if (ret) + goto end_unlink; + + inode_dec_link_count(inode); + mark_inode_dirty(dir); + +end_unlink: + return ret; +} + +static int omfs_rmdir(struct inode *dir, struct dentry *dentry) +{ + int err = -ENOTEMPTY; + struct inode *inode = dentry->d_inode; + + if (omfs_dir_is_empty(inode)) { + err = omfs_unlink(dir, dentry); + if (!err) + inode_dec_link_count(inode); + } + return err; +} + +static int omfs_add_node(struct inode *dir, struct dentry *dentry, int mode) +{ + int err; + struct inode *inode = omfs_new_inode(dir, mode); + + if (IS_ERR(inode)) + return PTR_ERR(inode); + + err = omfs_make_empty(inode, dir->i_sb); + if (err) + goto out_free_inode; + + err = omfs_add_link(dentry, inode); + if (err) + goto out_free_inode; + + d_instantiate(dentry, inode); + return 0; + +out_free_inode: + iput(inode); + return err; +} + +static int omfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + return omfs_add_node(dir, dentry, mode | S_IFDIR); +} + +static int omfs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + return omfs_add_node(dir, dentry, mode | S_IFREG); +} + +static struct dentry *omfs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + struct buffer_head *bh; + struct inode *inode = NULL; + + if (dentry->d_name.len > OMFS_NAMELEN) + return ERR_PTR(-ENAMETOOLONG); + + bh = omfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len); + if (!IS_ERR(bh)) { + struct omfs_inode *oi = (struct omfs_inode *)bh->b_data; + ino_t ino = be64_to_cpu(oi->i_head.h_self); + brelse(bh); + inode = omfs_iget(dir->i_sb, ino); + if (IS_ERR(inode)) + return ERR_CAST(inode); + } + d_add(dentry, inode); + return NULL; +} + +/* sanity check block's self pointer */ +int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, + u64 fsblock) +{ + int is_bad; + u64 ino = be64_to_cpu(header->h_self); + is_bad = ((ino != fsblock) || (ino < sbi->s_root_ino) || + (ino > sbi->s_num_blocks)); + + if (is_bad) + printk(KERN_WARNING "omfs: bad hash chain detected\n"); + + return is_bad; +} + +static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir, + u64 fsblock, int hindex) +{ + struct inode *dir = filp->f_dentry->d_inode; + struct buffer_head *bh; + struct omfs_inode *oi; + u64 self; + int res = 0; + unsigned char d_type; + + /* follow chain in this bucket */ + while (fsblock != ~0) { + bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), + fsblock)); + if (!bh) + goto out; + + oi = (struct omfs_inode *) bh->b_data; + if (omfs_is_bad(OMFS_SB(dir->i_sb), &oi->i_head, fsblock)) { + brelse(bh); + goto out; + } + + self = fsblock; + fsblock = be64_to_cpu(oi->i_sibling); + + /* skip visited nodes */ + if (hindex) { + hindex--; + brelse(bh); + continue; + } + + d_type = (oi->i_type == OMFS_DIR) ? DT_DIR : DT_REG; + + res = filldir(dirent, oi->i_name, strnlen(oi->i_name, + OMFS_NAMELEN), filp->f_pos, self, d_type); + if (res == 0) + filp->f_pos++; + brelse(bh); + } +out: + return res; +} + +static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + struct inode *new_inode = new_dentry->d_inode; + struct inode *old_inode = old_dentry->d_inode; + struct buffer_head *bh; + int is_dir; + int err; + + is_dir = S_ISDIR(old_inode->i_mode); + + if (new_inode) { + /* overwriting existing file/dir */ + err = -ENOTEMPTY; + if (is_dir && !omfs_dir_is_empty(new_inode)) + goto out; + + err = -ENOENT; + bh = omfs_find_entry(new_dir, new_dentry->d_name.name, + new_dentry->d_name.len); + if (IS_ERR(bh)) + goto out; + brelse(bh); + + err = omfs_unlink(new_dir, new_dentry); + if (err) + goto out; + } + + /* since omfs locates files by name, we need to unlink _before_ + * adding the new link or we won't find the old one */ + inode_inc_link_count(old_inode); + err = omfs_unlink(old_dir, old_dentry); + if (err) { + inode_dec_link_count(old_inode); + goto out; + } + + err = omfs_add_link(new_dentry, old_inode); + if (err) + goto out; + + old_inode->i_ctime = CURRENT_TIME_SEC; +out: + return err; +} + +static int omfs_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct inode *dir = filp->f_dentry->d_inode; + struct buffer_head *bh; + loff_t offset, res; + unsigned int hchain, hindex; + int nbuckets; + u64 fsblock; + int ret = -EINVAL; + + if (filp->f_pos >> 32) + goto success; + + switch ((unsigned long) filp->f_pos) { + case 0: + if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0) + goto success; + filp->f_pos++; + /* fall through */ + case 1: + if (filldir(dirent, "..", 2, 1, + parent_ino(filp->f_dentry), DT_DIR) < 0) + goto success; + filp->f_pos = 1 << 20; + /* fall through */ + } + + nbuckets = (dir->i_size - OMFS_DIR_START) / 8; + + /* high 12 bits store bucket + 1 and low 20 bits store hash index */ + hchain = (filp->f_pos >> 20) - 1; + hindex = filp->f_pos & 0xfffff; + + bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino)); + if (!bh) + goto out; + + offset = OMFS_DIR_START + hchain * 8; + + for (; hchain < nbuckets; hchain++, offset += 8) { + fsblock = be64_to_cpu(*((__be64 *) &bh->b_data[offset])); + + res = omfs_fill_chain(filp, dirent, filldir, fsblock, hindex); + hindex = 0; + if (res < 0) + break; + + filp->f_pos = (hchain+2) << 20; + } + brelse(bh); +success: + ret = 0; +out: + return ret; +} + +struct inode_operations omfs_dir_inops = { + .lookup = omfs_lookup, + .mkdir = omfs_mkdir, + .rename = omfs_rename, + .create = omfs_create, + .unlink = omfs_unlink, + .rmdir = omfs_rmdir, +}; + +struct file_operations omfs_dir_operations = { + .read = generic_read_dir, + .readdir = omfs_readdir, +}; From 8f09e98768c17287df076580c4cc72ac358312c6 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:16 -0700 Subject: [PATCH 090/179] omfs: add file routines Add functions for reading and manipulating the storage of file data in the extent-based OMFS. Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/omfs/file.c | 346 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 fs/omfs/file.c diff --git a/fs/omfs/file.c b/fs/omfs/file.c new file mode 100644 index 000000000000..66e01fae4384 --- /dev/null +++ b/fs/omfs/file.c @@ -0,0 +1,346 @@ +/* + * OMFS (as used by RIO Karma) file operations. + * Copyright (C) 2005 Bob Copeland + * Released under GPL v2. + */ + +#include +#include +#include +#include +#include +#include "omfs.h" + +static int omfs_sync_file(struct file *file, struct dentry *dentry, + int datasync) +{ + struct inode *inode = dentry->d_inode; + int err; + + err = sync_mapping_buffers(inode->i_mapping); + if (!(inode->i_state & I_DIRTY)) + return err; + if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) + return err; + err |= omfs_sync_inode(inode); + return err ? -EIO : 0; +} + +void omfs_make_empty_table(struct buffer_head *bh, int offset) +{ + struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset]; + + oe->e_next = ~0ULL; + oe->e_extent_count = cpu_to_be32(1), + oe->e_fill = cpu_to_be32(0x22), + oe->e_entry.e_cluster = ~0ULL; + oe->e_entry.e_blocks = ~0ULL; +} + +int omfs_shrink_inode(struct inode *inode) +{ + struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); + struct omfs_extent *oe; + struct omfs_extent_entry *entry; + struct buffer_head *bh; + u64 next, last; + u32 extent_count; + int ret; + + /* traverse extent table, freeing each entry that is greater + * than inode->i_size; + */ + next = inode->i_ino; + + /* only support truncate -> 0 for now */ + ret = -EIO; + if (inode->i_size != 0) + goto out; + + bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); + if (!bh) + goto out; + + oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); + + for (;;) { + + if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) { + brelse(bh); + goto out; + } + + extent_count = be32_to_cpu(oe->e_extent_count); + last = next; + next = be64_to_cpu(oe->e_next); + entry = &oe->e_entry; + + /* ignore last entry as it is the terminator */ + for (; extent_count > 1; extent_count--) { + u64 start, count; + start = be64_to_cpu(entry->e_cluster); + count = be64_to_cpu(entry->e_blocks); + + omfs_clear_range(inode->i_sb, start, (int) count); + entry++; + } + omfs_make_empty_table(bh, (char *) oe - bh->b_data); + mark_buffer_dirty(bh); + brelse(bh); + + if (last != inode->i_ino) + omfs_clear_range(inode->i_sb, last, sbi->s_mirrors); + + if (next == ~0) + break; + + bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); + if (!bh) + goto out; + oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); + } + ret = 0; +out: + return ret; +} + +static void omfs_truncate(struct inode *inode) +{ + omfs_shrink_inode(inode); + mark_inode_dirty(inode); +} + +/* + * Add new blocks to the current extent, or create new entries/continuations + * as necessary. + */ +static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe, + u64 *ret_block) +{ + struct omfs_extent_entry *terminator; + struct omfs_extent_entry *entry = &oe->e_entry; + struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); + u32 extent_count = be32_to_cpu(oe->e_extent_count); + u64 new_block = 0; + u32 max_count; + int new_count; + int ret = 0; + + /* reached the end of the extent table with no blocks mapped. + * there are three possibilities for adding: grow last extent, + * add a new extent to the current extent table, and add a + * continuation inode. in last two cases need an allocator for + * sbi->s_cluster_size + */ + + /* TODO: handle holes */ + + /* should always have a terminator */ + if (extent_count < 1) + return -EIO; + + /* trivially grow current extent, if next block is not taken */ + terminator = entry + extent_count - 1; + if (extent_count > 1) { + entry = terminator-1; + new_block = be64_to_cpu(entry->e_cluster) + + be64_to_cpu(entry->e_blocks); + + if (omfs_allocate_block(inode->i_sb, new_block)) { + entry->e_blocks = + cpu_to_be64(be64_to_cpu(entry->e_blocks) + 1); + terminator->e_blocks = ~(cpu_to_be64( + be64_to_cpu(~terminator->e_blocks) + 1)); + goto out; + } + } + max_count = (sbi->s_sys_blocksize - OMFS_EXTENT_START - + sizeof(struct omfs_extent)) / + sizeof(struct omfs_extent_entry) + 1; + + /* TODO: add a continuation block here */ + if (be32_to_cpu(oe->e_extent_count) > max_count-1) + return -EIO; + + /* try to allocate a new cluster */ + ret = omfs_allocate_range(inode->i_sb, 1, sbi->s_clustersize, + &new_block, &new_count); + if (ret) + goto out_fail; + + /* copy terminator down an entry */ + entry = terminator; + terminator++; + memcpy(terminator, entry, sizeof(struct omfs_extent_entry)); + + entry->e_cluster = cpu_to_be64(new_block); + entry->e_blocks = cpu_to_be64((u64) new_count); + + terminator->e_blocks = ~(cpu_to_be64( + be64_to_cpu(~terminator->e_blocks) + (u64) new_count)); + + /* write in new entry */ + oe->e_extent_count = cpu_to_be32(1 + be32_to_cpu(oe->e_extent_count)); + +out: + *ret_block = new_block; +out_fail: + return ret; +} + +/* + * Scans across the directory table for a given file block number. + * If block not found, return 0. + */ +static sector_t find_block(struct inode *inode, struct omfs_extent_entry *ent, + sector_t block, int count, int *left) +{ + /* count > 1 because of terminator */ + sector_t searched = 0; + for (; count > 1; count--) { + int numblocks = clus_to_blk(OMFS_SB(inode->i_sb), + be64_to_cpu(ent->e_blocks)); + + if (block >= searched && + block < searched + numblocks) { + /* + * found it at cluster + (block - searched) + * numblocks - (block - searched) is remainder + */ + *left = numblocks - (block - searched); + return clus_to_blk(OMFS_SB(inode->i_sb), + be64_to_cpu(ent->e_cluster)) + + block - searched; + } + searched += numblocks; + ent++; + } + return 0; +} + +static int omfs_get_block(struct inode *inode, sector_t block, + struct buffer_head *bh_result, int create) +{ + struct buffer_head *bh; + sector_t next, offset; + int ret; + u64 new_block; + int extent_count; + struct omfs_extent *oe; + struct omfs_extent_entry *entry; + struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); + int max_blocks = bh_result->b_size >> inode->i_blkbits; + int remain; + + ret = -EIO; + bh = sb_bread(inode->i_sb, clus_to_blk(sbi, inode->i_ino)); + if (!bh) + goto out; + + oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); + next = inode->i_ino; + + for (;;) { + + if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) + goto out_brelse; + + extent_count = be32_to_cpu(oe->e_extent_count); + next = be64_to_cpu(oe->e_next); + entry = &oe->e_entry; + + offset = find_block(inode, entry, block, extent_count, &remain); + if (offset > 0) { + ret = 0; + map_bh(bh_result, inode->i_sb, offset); + if (remain > max_blocks) + remain = max_blocks; + bh_result->b_size = (remain << inode->i_blkbits); + goto out_brelse; + } + if (next == ~0) + break; + + brelse(bh); + bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next)); + if (!bh) + goto out; + oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); + } + if (create) { + ret = omfs_grow_extent(inode, oe, &new_block); + if (ret == 0) { + mark_buffer_dirty(bh); + mark_inode_dirty(inode); + map_bh(bh_result, inode->i_sb, + clus_to_blk(sbi, new_block)); + } + } +out_brelse: + brelse(bh); +out: + return ret; +} + +static int omfs_readpage(struct file *file, struct page *page) +{ + return block_read_full_page(page, omfs_get_block); +} + +static int omfs_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + return mpage_readpages(mapping, pages, nr_pages, omfs_get_block); +} + +static int omfs_writepage(struct page *page, struct writeback_control *wbc) +{ + return block_write_full_page(page, omfs_get_block, wbc); +} + +static int +omfs_writepages(struct address_space *mapping, struct writeback_control *wbc) +{ + return mpage_writepages(mapping, wbc, omfs_get_block); +} + +static int omfs_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + *pagep = NULL; + return block_write_begin(file, mapping, pos, len, flags, + pagep, fsdata, omfs_get_block); +} + +static sector_t omfs_bmap(struct address_space *mapping, sector_t block) +{ + return generic_block_bmap(mapping, block, omfs_get_block); +} + +struct file_operations omfs_file_operations = { + .llseek = generic_file_llseek, + .read = do_sync_read, + .write = do_sync_write, + .aio_read = generic_file_aio_read, + .aio_write = generic_file_aio_write, + .mmap = generic_file_mmap, + .fsync = omfs_sync_file, + .splice_read = generic_file_splice_read, +}; + +struct inode_operations omfs_file_inops = { + .truncate = omfs_truncate +}; + +struct address_space_operations omfs_aops = { + .readpage = omfs_readpage, + .readpages = omfs_readpages, + .writepage = omfs_writepage, + .writepages = omfs_writepages, + .sync_page = block_sync_page, + .write_begin = omfs_write_begin, + .write_end = generic_write_end, + .bmap = omfs_bmap, +}; + From 36cc410a6799a205bfc6ccc38abd9d52f2afba64 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:17 -0700 Subject: [PATCH 091/179] omfs: add bitmap routines Add block allocation and block bitmap management routines for OMFS. Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/omfs/bitmap.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 fs/omfs/bitmap.c diff --git a/fs/omfs/bitmap.c b/fs/omfs/bitmap.c new file mode 100644 index 000000000000..dc75f22be3f2 --- /dev/null +++ b/fs/omfs/bitmap.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include "omfs.h" + +unsigned long omfs_count_free(struct super_block *sb) +{ + unsigned int i; + unsigned long sum = 0; + struct omfs_sb_info *sbi = OMFS_SB(sb); + int nbits = sb->s_blocksize * 8; + + for (i = 0; i < sbi->s_imap_size; i++) + sum += nbits - bitmap_weight(sbi->s_imap[i], nbits); + + return sum; +} + +/* + * Counts the run of zero bits starting at bit up to max. + * It handles the case where a run might spill over a buffer. + * Called with bitmap lock. + */ +static int count_run(unsigned long **addr, int nbits, + int addrlen, int bit, int max) +{ + int count = 0; + int x; + + for (; addrlen > 0; addrlen--, addr++) { + x = find_next_bit(*addr, nbits, bit); + count += x - bit; + + if (x < nbits || count > max) + return min(count, max); + + bit = 0; + } + return min(count, max); +} + +/* + * Sets or clears the run of count bits starting with bit. + * Called with bitmap lock. + */ +static int set_run(struct super_block *sb, int map, + int nbits, int bit, int count, int set) +{ + int i; + int err; + struct buffer_head *bh; + struct omfs_sb_info *sbi = OMFS_SB(sb); + + err = -ENOMEM; + bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map); + if (!bh) + goto out; + + for (i = 0; i < count; i++, bit++) { + if (bit >= nbits) { + bit = 0; + map++; + + mark_buffer_dirty(bh); + brelse(bh); + bh = sb_bread(sb, + clus_to_blk(sbi, sbi->s_bitmap_ino) + map); + if (!bh) + goto out; + } + if (set) { + set_bit(bit, sbi->s_imap[map]); + set_bit(bit, (long *) bh->b_data); + } else { + clear_bit(bit, sbi->s_imap[map]); + clear_bit(bit, (long *) bh->b_data); + } + } + mark_buffer_dirty(bh); + brelse(bh); + err = 0; +out: + return err; +} + +/* + * Tries to allocate exactly one block. Returns true if sucessful. + */ +int omfs_allocate_block(struct super_block *sb, u64 block) +{ + struct buffer_head *bh; + struct omfs_sb_info *sbi = OMFS_SB(sb); + int bits_per_entry = 8 * sb->s_blocksize; + int map, bit; + int ret = 0; + u64 tmp; + + tmp = block; + bit = do_div(tmp, bits_per_entry); + map = tmp; + + mutex_lock(&sbi->s_bitmap_lock); + if (map >= sbi->s_imap_size || test_and_set_bit(bit, sbi->s_imap[map])) + goto out; + + if (sbi->s_bitmap_ino > 0) { + bh = sb_bread(sb, clus_to_blk(sbi, sbi->s_bitmap_ino) + map); + if (!bh) + goto out; + + set_bit(bit, (long *) bh->b_data); + mark_buffer_dirty(bh); + brelse(bh); + } + ret = 1; +out: + mutex_unlock(&sbi->s_bitmap_lock); + return ret; +} + + +/* + * Tries to allocate a set of blocks. The request size depends on the + * type: for inodes, we must allocate sbi->s_mirrors blocks, and for file + * blocks, we try to allocate sbi->s_clustersize, but can always get away + * with just one block. + */ +int omfs_allocate_range(struct super_block *sb, + int min_request, + int max_request, + u64 *return_block, + int *return_size) +{ + struct omfs_sb_info *sbi = OMFS_SB(sb); + int bits_per_entry = 8 * sb->s_blocksize; + int ret = 0; + int i, run, bit; + + mutex_lock(&sbi->s_bitmap_lock); + for (i = 0; i < sbi->s_imap_size; i++) { + bit = 0; + while (bit < bits_per_entry) { + bit = find_next_zero_bit(sbi->s_imap[i], bits_per_entry, + bit); + + if (bit == bits_per_entry) + break; + + run = count_run(&sbi->s_imap[i], bits_per_entry, + sbi->s_imap_size-i, bit, max_request); + + if (run >= min_request) + goto found; + bit += run; + } + } + ret = -ENOSPC; + goto out; + +found: + *return_block = i * bits_per_entry + bit; + *return_size = run; + ret = set_run(sb, i, bits_per_entry, bit, run, 1); + +out: + mutex_unlock(&sbi->s_bitmap_lock); + return ret; +} + +/* + * Clears count bits starting at a given block. + */ +int omfs_clear_range(struct super_block *sb, u64 block, int count) +{ + struct omfs_sb_info *sbi = OMFS_SB(sb); + int bits_per_entry = 8 * sb->s_blocksize; + u64 tmp; + int map, bit, ret; + + tmp = block; + bit = do_div(tmp, bits_per_entry); + map = tmp; + + if (map >= sbi->s_imap_size) + return 0; + + mutex_lock(&sbi->s_bitmap_lock); + ret = set_run(sb, map, bits_per_entry, bit, count, 0); + mutex_unlock(&sbi->s_bitmap_lock); + return ret; +} From 63ca8ce2a2641f9cb5f0add33ced4591681d1cd7 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:17 -0700 Subject: [PATCH 092/179] omfs: update kbuild to include OMFS Adds OMFS to the fs Kconfig and Makefile Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/Kconfig | 13 +++++++++++++ fs/Makefile | 1 + fs/omfs/Makefile | 4 ++++ 3 files changed, 18 insertions(+) create mode 100644 fs/omfs/Makefile diff --git a/fs/Kconfig b/fs/Kconfig index 97e3bdedb1e6..d3873583360b 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1383,6 +1383,19 @@ config MINIX_FS partition (the one containing the directory /) cannot be compiled as a module. +config OMFS_FS + tristate "SonicBlue Optimized MPEG File System support" + depends on BLOCK + select CRC_ITU_T + help + This is the proprietary file system used by the Rio Karma music + player and ReplayTV DVR. Despite the name, this filesystem is not + more efficient than a standard FS for MPEG files, in fact likely + the opposite is true. Say Y if you have either of these devices + and wish to mount its disk. + + To compile this file system support as a module, choose M here: the + module will be called omfs. If unsure, say N. config HPFS_FS tristate "OS/2 HPFS file system support" diff --git a/fs/Makefile b/fs/Makefile index 3b2178b4bb66..a1482a5eff15 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -111,6 +111,7 @@ obj-$(CONFIG_ADFS_FS) += adfs/ obj-$(CONFIG_FUSE_FS) += fuse/ obj-$(CONFIG_UDF_FS) += udf/ obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ +obj-$(CONFIG_OMFS_FS) += omfs/ obj-$(CONFIG_JFS_FS) += jfs/ obj-$(CONFIG_XFS_FS) += xfs/ obj-$(CONFIG_9P_FS) += 9p/ diff --git a/fs/omfs/Makefile b/fs/omfs/Makefile new file mode 100644 index 000000000000..8b82b63f1129 --- /dev/null +++ b/fs/omfs/Makefile @@ -0,0 +1,4 @@ + +obj-$(CONFIG_OMFS_FS) += omfs.o + +omfs-y := bitmap.o dir.o file.o inode.o From 0ad122d901977890de554fdd3ff65474efc1a9bf Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 25 Jul 2008 19:45:18 -0700 Subject: [PATCH 093/179] omfs: add MAINTAINERS entry Add the MAINTAINERS entry for OMFS. Signed-off-by: Bob Copeland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 4cbf6016a9b9..03c5d6ccb9f8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3123,6 +3123,12 @@ W: http://oss.oracle.com/projects/ocfs2/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2.git S: Supported +OMFS FILESYSTEM +P: Bob Copeland +M: me@bobcopeland.com +L: linux-karma-devel@lists.sourceforge.net +S: Maintained + OMNIKEY CARDMAN 4000 DRIVER P: Harald Welte M: laforge@gnumonks.org From 42a9a58361d3b65f4a7c2ad280cc1ec9b657e7d2 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 25 Jul 2008 19:45:18 -0700 Subject: [PATCH 094/179] cris: use the common ascii hex helpers Signed-off-by: Harvey Harrison Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/cris/arch-v10/kernel/kgdb.c | 79 ++++++++++---------------------- arch/cris/arch-v32/kernel/kgdb.c | 60 ++++++------------------ 2 files changed, 37 insertions(+), 102 deletions(-) diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c index a3ca55150745..6fea45f2e40c 100644 --- a/arch/cris/arch-v10/kernel/kgdb.c +++ b/arch/cris/arch-v10/kernel/kgdb.c @@ -278,14 +278,6 @@ void putDebugChar (int val); void enableDebugIRQ (void); -/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, - represented by int x. */ -static char highhex (int x); - -/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, - represented by int x. */ -static char lowhex (int x); - /* Returns the integer equivalent of a hexadecimal character. */ static int hex (char ch); @@ -356,9 +348,6 @@ extern unsigned char executing_task; /* Run-length encoding maximum length. Send 64 at most. */ #define RUNLENMAX 64 -/* Definition of all valid hexadecimal characters */ -static const char hexchars[] = "0123456789abcdef"; - /* The inbound/outbound buffers used in packet I/O */ static char remcomInBuffer[BUFMAX]; static char remcomOutBuffer[BUFMAX]; @@ -499,8 +488,8 @@ gdb_cris_strtol (const char *s, char **endptr, int base) char *sd; int x = 0; - for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1) - x = x * base + (sd - hexchars); + for (s1 = (char*)s; (sd = gdb_cris_memchr(hex_asc, *s1, base)) != NULL; ++s1) + x = x * base + (sd - hex_asc); if (endptr) { @@ -670,22 +659,6 @@ read_register (char regno, unsigned int *valptr) } /********************************** Packet I/O ******************************/ -/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, - represented by int x. */ -static inline char -highhex(int x) -{ - return hexchars[(x >> 4) & 0xf]; -} - -/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, - represented by int x. */ -static inline char -lowhex(int x) -{ - return hexchars[x & 0xf]; -} - /* Returns the integer equivalent of a hexadecimal character. */ static int hex (char ch) @@ -721,8 +694,7 @@ mem2hex(char *buf, unsigned char *mem, int count) /* Valid mem address. */ for (i = 0; i < count; i++) { ch = *mem++; - *buf++ = highhex (ch); - *buf++ = lowhex (ch); + buf = pack_hex_byte(buf, ch); } } @@ -857,9 +829,9 @@ putpacket(char *buffer) src++; } } - putDebugChar ('#'); - putDebugChar (highhex (checksum)); - putDebugChar (lowhex (checksum)); + putDebugChar('#'); + putDebugChar(hex_asc_hi(checksum)); + putDebugChar(hex_asc_lo(checksum)); } while(kgdb_started && (getDebugChar() != '+')); } @@ -895,9 +867,8 @@ stub_is_stopped(int sigval) /* Send trap type (converted to signal) */ - *ptr++ = 'T'; - *ptr++ = highhex (sigval); - *ptr++ = lowhex (sigval); + *ptr++ = 'T'; + ptr = pack_hex_byte(ptr, sigval); /* Send register contents. We probably only need to send the * PC, frame pointer and stack pointer here. Other registers will be @@ -910,9 +881,7 @@ stub_is_stopped(int sigval) status = read_register (regno, ®_cont); if (status == SUCCESS) { - - *ptr++ = highhex (regno); - *ptr++ = lowhex (regno); + ptr = pack_hex_byte(ptr, regno); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, @@ -937,8 +906,8 @@ stub_is_stopped(int sigval) /* Store thread:r...; with the executing task TID. */ gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:"); pos += gdb_cris_strlen ("thread:"); - remcomOutBuffer[pos++] = highhex (executing_task); - remcomOutBuffer[pos++] = lowhex (executing_task); + remcomOutBuffer[pos++] = hex_asc_hi(executing_task); + remcomOutBuffer[pos++] = hex_asc_lo(executing_task); gdb_cris_strcpy (&remcomOutBuffer[pos], ";"); #endif @@ -1126,8 +1095,8 @@ handle_exception (int sigval) Success: SAA, where AA is the signal number. Failure: void. */ remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = highhex (sigval); - remcomOutBuffer[2] = lowhex (sigval); + remcomOutBuffer[1] = hex_asc_hi(sigval); + remcomOutBuffer[2] = hex_asc_lo(sigval); remcomOutBuffer[3] = 0; break; @@ -1224,23 +1193,23 @@ handle_exception (int sigval) case 'C': /* Identify the remote current thread. */ gdb_cris_strcpy (&remcomOutBuffer[0], "QC"); - remcomOutBuffer[2] = highhex (current_thread_c); - remcomOutBuffer[3] = lowhex (current_thread_c); + remcomOutBuffer[2] = hex_asc_hi(current_thread_c); + remcomOutBuffer[3] = hex_asc_lo(current_thread_c); remcomOutBuffer[4] = '\0'; break; case 'L': gdb_cris_strcpy (&remcomOutBuffer[0], "QM"); /* Reply with number of threads. */ if (os_is_started()) { - remcomOutBuffer[2] = highhex (number_of_tasks); - remcomOutBuffer[3] = lowhex (number_of_tasks); + remcomOutBuffer[2] = hex_asc_hi(number_of_tasks); + remcomOutBuffer[3] = hex_asc_lo(number_of_tasks); } else { - remcomOutBuffer[2] = highhex (0); - remcomOutBuffer[3] = lowhex (1); + remcomOutBuffer[2] = hex_asc_hi(0); + remcomOutBuffer[3] = hex_asc_lo(1); } /* Done with the reply. */ - remcomOutBuffer[4] = lowhex (1); + remcomOutBuffer[4] = hex_asc_lo(1); pos = 5; /* Expects the argument thread id. */ for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++) @@ -1251,16 +1220,16 @@ handle_exception (int sigval) for (thread_id = 0; thread_id < number_of_tasks; thread_id++) { nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; for (; pos < nextpos; pos ++) - remcomOutBuffer[pos] = lowhex (0); - remcomOutBuffer[pos++] = lowhex (thread_id); + remcomOutBuffer[pos] = hex_asc_lo(0); + remcomOutBuffer[pos++] = hex_asc_lo(thread_id); } } else { /* Store the thread identifier of the boot task. */ nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; for (; pos < nextpos; pos ++) - remcomOutBuffer[pos] = lowhex (0); - remcomOutBuffer[pos++] = lowhex (current_thread_c); + remcomOutBuffer[pos] = hex_asc_lo(0); + remcomOutBuffer[pos++] = hex_asc_lo(current_thread_c); } remcomOutBuffer[pos] = '\0'; break; diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c index 4e2e2e271efb..8bd5a5bc0dc7 100644 --- a/arch/cris/arch-v32/kernel/kgdb.c +++ b/arch/cris/arch-v32/kernel/kgdb.c @@ -398,14 +398,6 @@ void putDebugChar(int val) } #endif -/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, - represented by int x. */ -static char highhex(int x); - -/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, - represented by int x. */ -static char lowhex(int x); - /* Returns the integer equivalent of a hexadecimal character. */ static int hex(char ch); @@ -464,9 +456,6 @@ void breakpoint(void); /* Run-length encoding maximum length. Send 64 at most. */ #define RUNLENMAX 64 -/* Definition of all valid hexadecimal characters */ -static const char hexchars[] = "0123456789abcdef"; - /* The inbound/outbound buffers used in packet I/O */ static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; @@ -550,8 +539,8 @@ gdb_cris_strtol(const char *s, char **endptr, int base) char *sd; int x = 0; - for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1) - x = x * base + (sd - hexchars); + for (s1 = (char*)s; (sd = gdb_cris_memchr(hex_asc, *s1, base)) != NULL; ++s1) + x = x * base + (sd - hex_asc); if (endptr) { /* Unconverted suffix is stored in endptr unless endptr is NULL. */ @@ -655,22 +644,6 @@ read_register(char regno, unsigned int *valptr) } /********************************** Packet I/O ******************************/ -/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte, - represented by int x. */ -static inline char -highhex(int x) -{ - return hexchars[(x >> 4) & 0xf]; -} - -/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte, - represented by int x. */ -static inline char -lowhex(int x) -{ - return hexchars[x & 0xf]; -} - /* Returns the integer equivalent of a hexadecimal character. */ static int hex(char ch) @@ -704,8 +677,7 @@ mem2hex(char *buf, unsigned char *mem, int count) /* Valid mem address. */ for (i = 0; i < count; i++) { ch = *mem++; - *buf++ = highhex (ch); - *buf++ = lowhex (ch); + buf = pack_hex_byte(buf, ch); } } /* Terminate properly. */ @@ -723,8 +695,7 @@ mem2hex_nbo(char *buf, unsigned char *mem, int count) mem += count - 1; for (i = 0; i < count; i++) { ch = *mem--; - *buf++ = highhex (ch); - *buf++ = lowhex (ch); + buf = pack_hex_byte(buf, ch); } /* Terminate properly. */ @@ -862,8 +833,8 @@ putpacket(char *buffer) } } putDebugChar('#'); - putDebugChar(highhex (checksum)); - putDebugChar(lowhex (checksum)); + putDebugChar(hex_asc_hi(checksum)); + putDebugChar(hex_asc_lo(checksum)); } while(kgdb_started && (getDebugChar() != '+')); } @@ -909,8 +880,7 @@ stub_is_stopped(int sigval) /* Send trap type (converted to signal) */ *ptr++ = 'T'; - *ptr++ = highhex(sigval); - *ptr++ = lowhex(sigval); + ptr = pack_hex_byte(ptr, sigval); if (((reg.exs & 0xff00) >> 8) == 0xc) { @@ -1018,30 +988,26 @@ stub_is_stopped(int sigval) } /* Only send PC, frame and stack pointer. */ read_register(PC, ®_cont); - *ptr++ = highhex(PC); - *ptr++ = lowhex(PC); + ptr = pack_hex_byte(PC); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[PC]); *ptr++ = ';'; read_register(R8, ®_cont); - *ptr++ = highhex(R8); - *ptr++ = lowhex(R8); + ptr = pack_hex_byte(R8); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[R8]); *ptr++ = ';'; read_register(SP, ®_cont); - *ptr++ = highhex(SP); - *ptr++ = lowhex(SP); + ptr = pack_hex_byte(SP); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[SP]); *ptr++ = ';'; /* Send ERP as well; this will save us an entire register fetch in some cases. */ read_register(ERP, ®_cont); - *ptr++ = highhex(ERP); - *ptr++ = lowhex(ERP); + ptr = pack_hex_byte(ERP); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[ERP]); *ptr++ = ';'; @@ -1533,8 +1499,8 @@ handle_exception(int sigval) Success: SAA, where AA is the signal number. Failure: void. */ output_buffer[0] = 'S'; - output_buffer[1] = highhex(sigval); - output_buffer[2] = lowhex(sigval); + output_buffer[1] = hex_asc_hi(sigval); + output_buffer[2] = hex_asc_lo(sigval); output_buffer[3] = 0; break; From 19caeed6339aec02901e2f4c49d8e1d3d6090559 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 25 Jul 2008 19:45:19 -0700 Subject: [PATCH 095/179] frv: use the common ascii hex helpers Signed-off-by: Harvey Harrison Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/kernel/gdb-stub.c | 88 ++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c index 48a0393e7cee..7ca8a6b19ac9 100644 --- a/arch/frv/kernel/gdb-stub.c +++ b/arch/frv/kernel/gdb-stub.c @@ -182,8 +182,6 @@ extern volatile u32 __attribute__((section(".bss"))) gdbstub_trace_through_excep static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; -static const char hexchars[] = "0123456789abcdef"; - static const char *regnames[] = { "PSR ", "ISR ", "CCR ", "CCCR", "LR ", "LCR ", "PC ", "_stt", @@ -383,8 +381,8 @@ static int gdbstub_send_packet(char *buffer) } gdbstub_tx_char('#'); - gdbstub_tx_char(hexchars[checksum >> 4]); - gdbstub_tx_char(hexchars[checksum & 0xf]); + gdbstub_tx_char(hex_asc_hi(checksum)); + gdbstub_tx_char(hex_asc_lo(checksum)); } while (gdbstub_rx_char(&ch,0), #ifdef GDBSTUB_DEBUG_PROTOCOL @@ -674,8 +672,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if ((uint32_t)mem&1 && count>=1) { if (!gdbstub_read_byte(mem,ch)) return NULL; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); mem++; count--; } @@ -683,10 +680,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if ((uint32_t)mem&3 && count>=2) { if (!gdbstub_read_word(mem,(uint16_t *)ch)) return NULL; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; - *buf++ = hexchars[ch[1] >> 4]; - *buf++ = hexchars[ch[1] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); + buf = pack_hex_byte(buf, ch[1]); mem += 2; count -= 2; } @@ -694,14 +689,10 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa while (count>=4) { if (!gdbstub_read_dword(mem,(uint32_t *)ch)) return NULL; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; - *buf++ = hexchars[ch[1] >> 4]; - *buf++ = hexchars[ch[1] & 0xf]; - *buf++ = hexchars[ch[2] >> 4]; - *buf++ = hexchars[ch[2] & 0xf]; - *buf++ = hexchars[ch[3] >> 4]; - *buf++ = hexchars[ch[3] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); + buf = pack_hex_byte(buf, ch[1]); + buf = pack_hex_byte(buf, ch[2]); + buf = pack_hex_byte(buf, ch[3]); mem += 4; count -= 4; } @@ -709,10 +700,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if (count>=2) { if (!gdbstub_read_word(mem,(uint16_t *)ch)) return NULL; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; - *buf++ = hexchars[ch[1] >> 4]; - *buf++ = hexchars[ch[1] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); + buf = pack_hex_byte(buf, ch[1]); mem += 2; count -= 2; } @@ -720,8 +709,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa if (count>=1) { if (!gdbstub_read_byte(mem,ch)) return NULL; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); } *buf = 0; @@ -1471,22 +1459,22 @@ void gdbstub(int sigval) *ptr++ = 'O'; ptr = mem2hex(title, ptr, sizeof(title) - 1,0); - hx = hexchars[(brr & 0xf0000000) >> 28]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(brr & 0x0f000000) >> 24]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(brr & 0x00f00000) >> 20]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(brr & 0x000f0000) >> 16]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(brr & 0x0000f000) >> 12]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(brr & 0x00000f00) >> 8]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(brr & 0x000000f0) >> 4]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(brr & 0x0000000f)]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hex_asc_hi(brr >> 24); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(brr >> 24); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_hi(brr >> 16); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(brr >> 16); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_hi(brr >> 8); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(brr >> 8); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_hi(brr); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(brr); + ptr = pack_hex_byte(ptr, hx); ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); *ptr = 0; @@ -1500,12 +1488,10 @@ void gdbstub(int sigval) /* Send trap type (converted to signal) */ *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; + ptr = pack_hex_byte(ptr, sigval); /* Send Error PC */ - *ptr++ = hexchars[GDB_REG_PC >> 4]; - *ptr++ = hexchars[GDB_REG_PC & 0xf]; + ptr = pack_hex_byte(ptr, GDB_REG_PC); *ptr++ = ':'; ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0); *ptr++ = ';'; @@ -1513,8 +1499,7 @@ void gdbstub(int sigval) /* * Send frame pointer */ - *ptr++ = hexchars[GDB_REG_FP >> 4]; - *ptr++ = hexchars[GDB_REG_FP & 0xf]; + ptr = pack_hex_byte(ptr, GDB_REG_FP); *ptr++ = ':'; ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0); *ptr++ = ';'; @@ -1522,8 +1507,7 @@ void gdbstub(int sigval) /* * Send stack pointer */ - *ptr++ = hexchars[GDB_REG_SP >> 4]; - *ptr++ = hexchars[GDB_REG_SP & 0xf]; + ptr = pack_hex_byte(ptr, GDB_REG_SP); *ptr++ = ':'; ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0); *ptr++ = ';'; @@ -1548,8 +1532,8 @@ void gdbstub(int sigval) /* request repeat of last signal number */ case '?': output_buffer[0] = 'S'; - output_buffer[1] = hexchars[sigval >> 4]; - output_buffer[2] = hexchars[sigval & 0xf]; + output_buffer[1] = hex_asc_hi(sigval); + output_buffer[2] = hex_asc_lo(sigval); output_buffer[3] = 0; break; @@ -2059,8 +2043,8 @@ void gdbstub_exit(int status) } gdbstub_tx_char('#'); - gdbstub_tx_char(hexchars[checksum >> 4]); - gdbstub_tx_char(hexchars[checksum & 0xf]); + gdbstub_tx_char(hex_asc_hi(checksum)); + gdbstub_tx_char(hex_asc_lo(checksum)); /* make sure the output is flushed, or else RedBoot might clobber it */ gdbstub_tx_char('-'); From 2682497245e7d22160ae63032c378745a7f2cfe5 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 25 Jul 2008 19:45:20 -0700 Subject: [PATCH 096/179] mn10300: use the common ascii hex helpers Signed-off-by: Harvey Harrison Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mn10300/kernel/gdb-stub.c | 108 ++++++++++++++------------------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c index 21891c71d549..54be6afb5555 100644 --- a/arch/mn10300/kernel/gdb-stub.c +++ b/arch/mn10300/kernel/gdb-stub.c @@ -163,8 +163,6 @@ static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; static char trans_buffer[BUFMAX]; -static const char hexchars[] = "0123456789abcdef"; - struct gdbstub_bkpt { u8 *addr; /* address of breakpoint */ u8 len; /* size of breakpoint */ @@ -363,8 +361,8 @@ static int putpacket(char *buffer) } gdbstub_io_tx_char('#'); - gdbstub_io_tx_char(hexchars[checksum >> 4]); - gdbstub_io_tx_char(hexchars[checksum & 0xf]); + gdbstub_io_tx_char(hex_asc_hi(checksum)); + gdbstub_io_tx_char(hex_asc_lo(checksum)); } while (gdbstub_io_rx_char(&ch, 0), ch == '-' && (gdbstub_io("### GDB Rx NAK\n"), 0), @@ -822,8 +820,7 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if ((u32) mem & 1 && count >= 1) { if (gdbstub_read_byte(mem, ch) != 0) return 0; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); mem++; count--; } @@ -831,10 +828,8 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if ((u32) mem & 3 && count >= 2) { if (gdbstub_read_word(mem, ch) != 0) return 0; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; - *buf++ = hexchars[ch[1] >> 4]; - *buf++ = hexchars[ch[1] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); + buf = pack_hex_byte(buf, ch[1]); mem += 2; count -= 2; } @@ -842,14 +837,10 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) while (count >= 4) { if (gdbstub_read_dword(mem, ch) != 0) return 0; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; - *buf++ = hexchars[ch[1] >> 4]; - *buf++ = hexchars[ch[1] & 0xf]; - *buf++ = hexchars[ch[2] >> 4]; - *buf++ = hexchars[ch[2] & 0xf]; - *buf++ = hexchars[ch[3] >> 4]; - *buf++ = hexchars[ch[3] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); + buf = pack_hex_byte(buf, ch[1]); + buf = pack_hex_byte(buf, ch[2]); + buf = pack_hex_byte(buf, ch[3]); mem += 4; count -= 4; } @@ -857,10 +848,8 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if (count >= 2) { if (gdbstub_read_word(mem, ch) != 0) return 0; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; - *buf++ = hexchars[ch[1] >> 4]; - *buf++ = hexchars[ch[1] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); + buf = pack_hex_byte(buf, ch[1]); mem += 2; count -= 2; } @@ -868,8 +857,7 @@ unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault) if (count >= 1) { if (gdbstub_read_byte(mem, ch) != 0) return 0; - *buf++ = hexchars[ch[0] >> 4]; - *buf++ = hexchars[ch[0] & 0xf]; + buf = pack_hex_byte(buf, ch[0]); } *buf = 0; @@ -1304,14 +1292,14 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) *ptr++ = 'O'; ptr = mem2hex(title, ptr, sizeof(title) - 1, 0); - hx = hexchars[(excep & 0xf000) >> 12]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(excep & 0x0f00) >> 8]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(excep & 0x00f0) >> 4]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(excep & 0x000f)]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hex_asc_hi(excep >> 8); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(excep >> 8); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_hi(excep); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(excep); + ptr = pack_hex_byte(ptr, hx); ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); *ptr = 0; @@ -1322,22 +1310,22 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) *ptr++ = 'O'; ptr = mem2hex(tbcberr, ptr, sizeof(tbcberr) - 1, 0); - hx = hexchars[(bcberr & 0xf0000000) >> 28]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(bcberr & 0x0f000000) >> 24]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(bcberr & 0x00f00000) >> 20]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(bcberr & 0x000f0000) >> 16]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(bcberr & 0x0000f000) >> 12]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(bcberr & 0x00000f00) >> 8]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(bcberr & 0x000000f0) >> 4]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; - hx = hexchars[(bcberr & 0x0000000f)]; - *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf]; + hx = hex_asc_hi(bcberr >> 24); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(bcberr >> 24); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_hi(bcberr >> 16); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(bcberr >> 16); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_hi(bcberr >> 8); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(bcberr >> 8); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_hi(bcberr); + ptr = pack_hex_byte(ptr, hx); + hx = hex_asc_lo(bcberr); + ptr = pack_hex_byte(ptr, hx); ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); *ptr = 0; @@ -1353,14 +1341,12 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) * Send trap type (converted to signal) */ *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; + ptr = pack_hex_byte(ptr, sigval); /* * Send Error PC */ - *ptr++ = hexchars[GDB_REGID_PC >> 4]; - *ptr++ = hexchars[GDB_REGID_PC & 0xf]; + ptr = pack_hex_byte(ptr, GDB_REGID_PC); *ptr++ = ':'; ptr = mem2hex(®s->pc, ptr, 4, 0); *ptr++ = ';'; @@ -1368,8 +1354,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) /* * Send frame pointer */ - *ptr++ = hexchars[GDB_REGID_FP >> 4]; - *ptr++ = hexchars[GDB_REGID_FP & 0xf]; + ptr = pack_hex_byte(ptr, GDB_REGID_FP); *ptr++ = ':'; ptr = mem2hex(®s->a3, ptr, 4, 0); *ptr++ = ';'; @@ -1378,8 +1363,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) * Send stack pointer */ ssp = (unsigned long) (regs + 1); - *ptr++ = hexchars[GDB_REGID_SP >> 4]; - *ptr++ = hexchars[GDB_REGID_SP & 0xf]; + ptr = pack_hex_byte(ptr, GDB_REGID_SP); *ptr++ = ':'; ptr = mem2hex(&ssp, ptr, 4, 0); *ptr++ = ';'; @@ -1399,8 +1383,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) /* request repeat of last signal number */ case '?': output_buffer[0] = 'S'; - output_buffer[1] = hexchars[sigval >> 4]; - output_buffer[2] = hexchars[sigval & 0xf]; + output_buffer[1] = hex_asc_hi(sigval); + output_buffer[2] = hex_asc_lo(sigval); output_buffer[3] = 0; break; @@ -1838,8 +1822,8 @@ void gdbstub_exit(int status) gdbstub_busy = 1; output_buffer[0] = 'W'; - output_buffer[1] = hexchars[(status >> 4) & 0x0F]; - output_buffer[2] = hexchars[status & 0x0F]; + output_buffer[1] = hex_asc_hi(status); + output_buffer[2] = hex_asc_lo(status); output_buffer[3] = 0; gdbstub_io_tx_char('$'); @@ -1853,8 +1837,8 @@ void gdbstub_exit(int status) } gdbstub_io_tx_char('#'); - gdbstub_io_tx_char(hexchars[checksum >> 4]); - gdbstub_io_tx_char(hexchars[checksum & 0xf]); + gdbstub_io_tx_char(hex_asc_hi(checksum)); + gdbstub_io_tx_char(hex_asc_lo(checksum)); /* make sure the output is flushed, or else RedBoot might clobber it */ gdbstub_io_tx_flush(); From a0a8f5364a5ad248aec6cb705e0092ff563edc2f Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:20 -0700 Subject: [PATCH 097/179] x86: implement pte_special Implement the pte_special bit for x86. This is required to support lockless get_user_pages, because we need to know whether or not we can refcount a particular page given only its pte (and no vma). [hugh@veritas.com: fix a BUG] Signed-off-by: Nick Piggin Cc: Dave Kleikamp Cc: Andy Whitcroft Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Cc: Dave Kleikamp Cc: Badari Pulavarty Cc: Zach Brown Cc: Jens Axboe Reviewed-by: Peter Zijlstra Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-x86/pgtable.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index 3e5dbc4195f4..04caa2f544df 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h @@ -18,6 +18,7 @@ #define _PAGE_BIT_UNUSED2 10 #define _PAGE_BIT_UNUSED3 11 #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ +#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ #define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT) @@ -34,6 +35,8 @@ #define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3) #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT) #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) +#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL) +#define __HAVE_ARCH_PTE_SPECIAL #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) @@ -54,7 +57,7 @@ /* Set of bits not changed in pte_modify */ #define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ - _PAGE_ACCESSED | _PAGE_DIRTY) + _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY) #define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) #define _PAGE_CACHE_WB (0) @@ -180,7 +183,7 @@ static inline int pte_exec(pte_t pte) static inline int pte_special(pte_t pte) { - return 0; + return pte_val(pte) & _PAGE_SPECIAL; } static inline int pmd_large(pmd_t pte) @@ -246,7 +249,7 @@ static inline pte_t pte_clrglobal(pte_t pte) static inline pte_t pte_mkspecial(pte_t pte) { - return pte; + return __pte(pte_val(pte) | _PAGE_SPECIAL); } extern pteval_t __supported_pte_mask; From 21cc199baa815d7b3f1ace4be20b9558cbddc00f Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:22 -0700 Subject: [PATCH 098/179] mm: introduce get_user_pages_fast Introduce a new get_user_pages_fast mm API, which is basically a get_user_pages with a less general API (but still tends to be suited to the common case): - task and mm are always current and current->mm - force is always 0 - pages is always non-NULL - don't pass back vmas This restricted API can be implemented in a much more scalable way on many architectures when the ptes are present, by walking the page tables locklessly (no mmap_sem or page table locks). When the ptes are not populated, get_user_pages_fast() could be slower. This is implemented locklessly on x86, and used in some key direct IO call sites, in later patches, which provides nearly 10% performance improvement on a threaded database workload. Lots of other code could use this too, depending on use cases (eg. grep drivers/). And it might inspire some new and clever ways to use it. [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Nick Piggin Cc: Dave Kleikamp Cc: Andy Whitcroft Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Cc: Dave Kleikamp Cc: Badari Pulavarty Cc: Zach Brown Cc: Jens Axboe Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index d87a5a5fe87d..f3fd70d6029f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -833,6 +833,39 @@ extern int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, unsigned long start, unsigned long end, unsigned long newflags); +#ifdef CONFIG_HAVE_GET_USER_PAGES_FAST +/* + * get_user_pages_fast provides equivalent functionality to get_user_pages, + * operating on current and current->mm (force=0 and doesn't return any vmas). + * + * get_user_pages_fast may take mmap_sem and page tables, so no assumptions + * can be made about locking. get_user_pages_fast is to be implemented in a + * way that is advantageous (vs get_user_pages()) when the user memory area is + * already faulted in and present in ptes. However if the pages have to be + * faulted in, it may turn out to be slightly slower). + */ +int get_user_pages_fast(unsigned long start, int nr_pages, int write, + struct page **pages); + +#else +/* + * Should probably be moved to asm-generic, and architectures can include it if + * they don't implement their own get_user_pages_fast. + */ +#define get_user_pages_fast(start, nr_pages, write, pages) \ +({ \ + struct mm_struct *mm = current->mm; \ + int ret; \ + \ + down_read(&mm->mmap_sem); \ + ret = get_user_pages(current, mm, start, nr_pages, \ + write, 0, pages, NULL); \ + up_read(&mm->mmap_sem); \ + \ + ret; \ +}) +#endif + /* * A callback you can register to apply pressure to ageable caches. * From 8174c430e445a93016ef18f717fe570214fa38bf Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:24 -0700 Subject: [PATCH 099/179] x86: lockless get_user_pages_fast() Implement get_user_pages_fast without locking in the fastpath on x86. Do an optimistic lockless pagetable walk, without taking mmap_sem or any page table locks or even mmap_sem. Page table existence is guaranteed by turning interrupts off (combined with the fact that we're always looking up the current mm, means we can do the lockless page table walk within the constraints of the TLB shootdown design). Basically we can do this lockless pagetable walk in a similar manner to the way the CPU's pagetable walker does not have to take any locks to find present ptes. This patch (combined with the subsequent ones to convert direct IO to use it) was found to give about 10% performance improvement on a 2 socket 8 core Intel Xeon system running an OLTP workload on DB2 v9.5 "To test the effects of the patch, an OLTP workload was run on an IBM x3850 M2 server with 2 processors (quad-core Intel Xeon processors at 2.93 GHz) using IBM DB2 v9.5 running Linux 2.6.24rc7 kernel. Comparing runs with and without the patch resulted in an overall performance benefit of ~9.8%. Correspondingly, oprofiles showed that samples from __up_read and __down_read routines that is seen during thread contention for system resources was reduced from 2.8% down to .05%. Monitoring the /proc/vmstat output from the patched run showed that the counter for fast_gup contained a very high number while the fast_gup_slow value was zero." (fast_gup is the old name for get_user_pages_fast, fast_gup_slow is a counter we had for the number of times the slowpath was invoked). The main reason for the improvement is that DB2 has multiple threads each issuing direct-IO. Direct-IO uses get_user_pages, and thus the threads contend the mmap_sem cacheline, and can also contend on page table locks. I would anticipate larger performance gains on larger systems, however I think DB2 uses an adaptive mix of threads and processes, so it could be that thread contention remains pretty constant as machine size increases. In which case, we stuck with "only" a 10% gain. The downside of using get_user_pages_fast is that if there is not a pte with the correct permissions for the access, we end up falling back to get_user_pages and so the get_user_pages_fast is a bit of extra work. However this should not be the common case in most performance critical code. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: Kconfig fix] [akpm@linux-foundation.org: Makefile fix/cleanup] [akpm@linux-foundation.org: warning fix] Signed-off-by: Nick Piggin Cc: Dave Kleikamp Cc: Andy Whitcroft Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Cc: Dave Kleikamp Cc: Badari Pulavarty Cc: Zach Brown Cc: Jens Axboe Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/Kconfig | 1 + arch/x86/mm/Makefile | 1 + arch/x86/mm/gup.c | 258 ++++++++++++++++++++++++++++++++++++++ include/asm-x86/uaccess.h | 1 + mm/Kconfig | 3 + 5 files changed, 264 insertions(+) create mode 100644 arch/x86/mm/gup.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6b2debfabddc..6bdde845818e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -22,6 +22,7 @@ config X86 select HAVE_IDE select HAVE_OPROFILE select HAVE_IOREMAP_PROT + select HAVE_GET_USER_PAGES_FAST select HAVE_KPROBES select ARCH_WANT_OPTIONAL_GPIOLIB if !X86_RDC321X select HAVE_KRETPROBES diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 1fbb844c3d7a..2977ea37791f 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -1,6 +1,7 @@ obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ pat.o pgtable.o +obj-$(CONFIG_HAVE_GET_USER_PAGES_FAST) += gup.o obj-$(CONFIG_X86_32) += pgtable_32.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c new file mode 100644 index 000000000000..6f733121f32e --- /dev/null +++ b/arch/x86/mm/gup.c @@ -0,0 +1,258 @@ +/* + * Lockless get_user_pages_fast for x86 + * + * Copyright (C) 2008 Nick Piggin + * Copyright (C) 2008 Novell Inc. + */ +#include +#include +#include +#include + +#include + +static inline pte_t gup_get_pte(pte_t *ptep) +{ +#ifndef CONFIG_X86_PAE + return *ptep; +#else + /* + * With get_user_pages_fast, we walk down the pagetables without taking + * any locks. For this we would like to load the pointers atoimcally, + * but that is not possible (without expensive cmpxchg8b) on PAE. What + * we do have is the guarantee that a pte will only either go from not + * present to present, or present to not present or both -- it will not + * switch to a completely different present page without a TLB flush in + * between; something that we are blocking by holding interrupts off. + * + * Setting ptes from not present to present goes: + * ptep->pte_high = h; + * smp_wmb(); + * ptep->pte_low = l; + * + * And present to not present goes: + * ptep->pte_low = 0; + * smp_wmb(); + * ptep->pte_high = 0; + * + * We must ensure here that the load of pte_low sees l iff pte_high + * sees h. We load pte_high *after* loading pte_low, which ensures we + * don't see an older value of pte_high. *Then* we recheck pte_low, + * which ensures that we haven't picked up a changed pte high. We might + * have got rubbish values from pte_low and pte_high, but we are + * guaranteed that pte_low will not have the present bit set *unless* + * it is 'l'. And get_user_pages_fast only operates on present ptes, so + * we're safe. + * + * gup_get_pte should not be used or copied outside gup.c without being + * very careful -- it does not atomically load the pte or anything that + * is likely to be useful for you. + */ + pte_t pte; + +retry: + pte.pte_low = ptep->pte_low; + smp_rmb(); + pte.pte_high = ptep->pte_high; + smp_rmb(); + if (unlikely(pte.pte_low != ptep->pte_low)) + goto retry; + + return pte; +#endif +} + +/* + * The performance critical leaf functions are made noinline otherwise gcc + * inlines everything into a single function which results in too much + * register pressure. + */ +static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, + unsigned long end, int write, struct page **pages, int *nr) +{ + unsigned long mask; + pte_t *ptep; + + mask = _PAGE_PRESENT|_PAGE_USER; + if (write) + mask |= _PAGE_RW; + + ptep = pte_offset_map(&pmd, addr); + do { + pte_t pte = gup_get_pte(ptep); + struct page *page; + + if ((pte_val(pte) & (mask | _PAGE_SPECIAL)) != mask) { + pte_unmap(ptep); + return 0; + } + VM_BUG_ON(!pfn_valid(pte_pfn(pte))); + page = pte_page(pte); + get_page(page); + pages[*nr] = page; + (*nr)++; + + } while (ptep++, addr += PAGE_SIZE, addr != end); + pte_unmap(ptep - 1); + + return 1; +} + +static inline void get_head_page_multiple(struct page *page, int nr) +{ + VM_BUG_ON(page != compound_head(page)); + VM_BUG_ON(page_count(page) == 0); + atomic_add(nr, &page->_count); +} + +static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, + unsigned long end, int write, struct page **pages, int *nr) +{ + unsigned long mask; + pte_t pte = *(pte_t *)&pmd; + struct page *head, *page; + int refs; + + mask = _PAGE_PRESENT|_PAGE_USER; + if (write) + mask |= _PAGE_RW; + if ((pte_val(pte) & mask) != mask) + return 0; + /* hugepages are never "special" */ + VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); + VM_BUG_ON(!pfn_valid(pte_pfn(pte))); + + refs = 0; + head = pte_page(pte); + page = head + ((addr & ~HPAGE_MASK) >> PAGE_SHIFT); + do { + VM_BUG_ON(compound_head(page) != head); + pages[*nr] = page; + (*nr)++; + page++; + refs++; + } while (addr += PAGE_SIZE, addr != end); + get_head_page_multiple(head, refs); + + return 1; +} + +static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, + int write, struct page **pages, int *nr) +{ + unsigned long next; + pmd_t *pmdp; + + pmdp = pmd_offset(&pud, addr); + do { + pmd_t pmd = *pmdp; + + next = pmd_addr_end(addr, end); + if (pmd_none(pmd)) + return 0; + if (unlikely(pmd_large(pmd))) { + if (!gup_huge_pmd(pmd, addr, next, write, pages, nr)) + return 0; + } else { + if (!gup_pte_range(pmd, addr, next, write, pages, nr)) + return 0; + } + } while (pmdp++, addr = next, addr != end); + + return 1; +} + +static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, + int write, struct page **pages, int *nr) +{ + unsigned long next; + pud_t *pudp; + + pudp = pud_offset(&pgd, addr); + do { + pud_t pud = *pudp; + + next = pud_addr_end(addr, end); + if (pud_none(pud)) + return 0; + if (!gup_pmd_range(pud, addr, next, write, pages, nr)) + return 0; + } while (pudp++, addr = next, addr != end); + + return 1; +} + +int get_user_pages_fast(unsigned long start, int nr_pages, int write, + struct page **pages) +{ + struct mm_struct *mm = current->mm; + unsigned long end = start + (nr_pages << PAGE_SHIFT); + unsigned long addr = start; + unsigned long next; + pgd_t *pgdp; + int nr = 0; + + if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, + start, nr_pages*PAGE_SIZE))) + goto slow_irqon; + + /* + * XXX: batch / limit 'nr', to avoid large irq off latency + * needs some instrumenting to determine the common sizes used by + * important workloads (eg. DB2), and whether limiting the batch size + * will decrease performance. + * + * It seems like we're in the clear for the moment. Direct-IO is + * the main guy that batches up lots of get_user_pages, and even + * they are limited to 64-at-a-time which is not so many. + */ + /* + * This doesn't prevent pagetable teardown, but does prevent + * the pagetables and pages from being freed on x86. + * + * So long as we atomically load page table pointers versus teardown + * (which we do on x86, with the above PAE exception), we can follow the + * address down to the the page and take a ref on it. + */ + local_irq_disable(); + pgdp = pgd_offset(mm, addr); + do { + pgd_t pgd = *pgdp; + + next = pgd_addr_end(addr, end); + if (pgd_none(pgd)) + goto slow; + if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) + goto slow; + } while (pgdp++, addr = next, addr != end); + local_irq_enable(); + + VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT); + return nr; + + { + int ret; + +slow: + local_irq_enable(); +slow_irqon: + /* Try to get the remaining pages with get_user_pages */ + start += nr << PAGE_SHIFT; + pages += nr; + + down_read(&mm->mmap_sem); + ret = get_user_pages(current, mm, start, + (end - start) >> PAGE_SHIFT, write, 0, pages, NULL); + up_read(&mm->mmap_sem); + + /* Have to be a bit careful with return values */ + if (nr > 0) { + if (ret < 0) + ret = nr; + else + ret += nr; + } + + return ret; + } +} diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index f6fa4d841bbc..5f702d1d5218 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -451,3 +451,4 @@ extern struct movsl_mask { #endif #endif + diff --git a/mm/Kconfig b/mm/Kconfig index aa799007a11b..efee5d379df4 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -77,6 +77,9 @@ config FLAT_NODE_MEM_MAP def_bool y depends on !SPARSEMEM +config HAVE_GET_USER_PAGES_FAST + bool + # # Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's # to represent different areas of memory. This variable allows From f5dd33c494a427b1d1a3b574de5c9e511c888864 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:25 -0700 Subject: [PATCH 100/179] dio: use get_user_pages_fast Use get_user_pages_fast in the common/generic block and fs direct IO paths. Signed-off-by: Nick Piggin Cc: Dave Kleikamp Cc: Andy Whitcroft Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Cc: Dave Kleikamp Cc: Badari Pulavarty Cc: Zach Brown Cc: Jens Axboe Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/bio.c | 8 ++------ fs/direct-io.c | 10 ++-------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/fs/bio.c b/fs/bio.c index 88322b066acb..25f1af0d81e5 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -721,12 +721,8 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, const int local_nr_pages = end - start; const int page_limit = cur_page + local_nr_pages; - down_read(¤t->mm->mmap_sem); - ret = get_user_pages(current, current->mm, uaddr, - local_nr_pages, - write_to_vm, 0, &pages[cur_page], NULL); - up_read(¤t->mm->mmap_sem); - + ret = get_user_pages_fast(uaddr, local_nr_pages, + write_to_vm, &pages[cur_page]); if (ret < local_nr_pages) { ret = -EFAULT; goto out_unmap; diff --git a/fs/direct-io.c b/fs/direct-io.c index 9e81addbd6ea..9606ee848fd8 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -150,17 +150,11 @@ static int dio_refill_pages(struct dio *dio) int nr_pages; nr_pages = min(dio->total_pages - dio->curr_page, DIO_PAGES); - down_read(¤t->mm->mmap_sem); - ret = get_user_pages( - current, /* Task for fault acounting */ - current->mm, /* whose pages? */ + ret = get_user_pages_fast( dio->curr_user_address, /* Where from? */ nr_pages, /* How many pages? */ dio->rw == READ, /* Write to memory? */ - 0, /* force (?) */ - &dio->pages[0], - NULL); /* vmas */ - up_read(¤t->mm->mmap_sem); + &dio->pages[0]); /* Put results here */ if (ret < 0 && dio->blocks_available && (dio->rw & WRITE)) { struct page *page = ZERO_PAGE(0); From bc40d73c950146725e9e768e856a416ec8949065 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:26 -0700 Subject: [PATCH 101/179] splice: use get_user_pages_fast Use get_user_pages_fast in splice. This reverts some mmap_sem batching there, however the biggest problem with mmap_sem tends to be hold times blocking out other threads rather than cacheline bouncing. Further: on architectures that implement get_user_pages_fast without locks, mmap_sem can be avoided completely anyway. Signed-off-by: Nick Piggin Cc: Dave Kleikamp Cc: Andy Whitcroft Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Cc: Dave Kleikamp Cc: Badari Pulavarty Cc: Zach Brown Cc: Jens Axboe Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/splice.c | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index 399442179d89..47dc1a445d1f 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1160,36 +1160,6 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; } -/* - * Do a copy-from-user while holding the mmap_semaphore for reading, in a - * manner safe from deadlocking with simultaneous mmap() (grabbing mmap_sem - * for writing) and page faulting on the user memory pointed to by src. - * This assumes that we will very rarely hit the partial != 0 path, or this - * will not be a win. - */ -static int copy_from_user_mmap_sem(void *dst, const void __user *src, size_t n) -{ - int partial; - - if (!access_ok(VERIFY_READ, src, n)) - return -EFAULT; - - pagefault_disable(); - partial = __copy_from_user_inatomic(dst, src, n); - pagefault_enable(); - - /* - * Didn't copy everything, drop the mmap_sem and do a faulting copy - */ - if (unlikely(partial)) { - up_read(¤t->mm->mmap_sem); - partial = copy_from_user(dst, src, n); - down_read(¤t->mm->mmap_sem); - } - - return partial; -} - /* * Map an iov into an array of pages and offset/length tupples. With the * partial_page structure, we can map several non-contiguous ranges into @@ -1203,8 +1173,6 @@ static int get_iovec_page_array(const struct iovec __user *iov, { int buffers = 0, error = 0; - down_read(¤t->mm->mmap_sem); - while (nr_vecs) { unsigned long off, npages; struct iovec entry; @@ -1213,7 +1181,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, int i; error = -EFAULT; - if (copy_from_user_mmap_sem(&entry, iov, sizeof(entry))) + if (copy_from_user(&entry, iov, sizeof(entry))) break; base = entry.iov_base; @@ -1247,9 +1215,8 @@ static int get_iovec_page_array(const struct iovec __user *iov, if (npages > PIPE_BUFFERS - buffers) npages = PIPE_BUFFERS - buffers; - error = get_user_pages(current, current->mm, - (unsigned long) base, npages, 0, 0, - &pages[buffers], NULL); + error = get_user_pages_fast((unsigned long)base, npages, + 0, &pages[buffers]); if (unlikely(error <= 0)) break; @@ -1288,8 +1255,6 @@ static int get_iovec_page_array(const struct iovec __user *iov, iov++; } - up_read(¤t->mm->mmap_sem); - if (buffers) return buffers; From 652ea695364142b2464744746beac206d050ef19 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:27 -0700 Subject: [PATCH 102/179] x86: support 1GB hugepages with get_user_pages_lockless() Signed-off-by: Nick Piggin Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/mm/gup.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index 6f733121f32e..3085f25b4355 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c @@ -124,7 +124,7 @@ static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, refs = 0; head = pte_page(pte); - page = head + ((addr & ~HPAGE_MASK) >> PAGE_SHIFT); + page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT); do { VM_BUG_ON(compound_head(page) != head); pages[*nr] = page; @@ -162,6 +162,38 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, return 1; } +static noinline int gup_huge_pud(pud_t pud, unsigned long addr, + unsigned long end, int write, struct page **pages, int *nr) +{ + unsigned long mask; + pte_t pte = *(pte_t *)&pud; + struct page *head, *page; + int refs; + + mask = _PAGE_PRESENT|_PAGE_USER; + if (write) + mask |= _PAGE_RW; + if ((pte_val(pte) & mask) != mask) + return 0; + /* hugepages are never "special" */ + VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); + VM_BUG_ON(!pfn_valid(pte_pfn(pte))); + + refs = 0; + head = pte_page(pte); + page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT); + do { + VM_BUG_ON(compound_head(page) != head); + pages[*nr] = page; + (*nr)++; + page++; + refs++; + } while (addr += PAGE_SIZE, addr != end); + get_head_page_multiple(head, refs); + + return 1; +} + static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { @@ -175,8 +207,13 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, next = pud_addr_end(addr, end); if (pud_none(pud)) return 0; - if (!gup_pmd_range(pud, addr, next, write, pages, nr)) - return 0; + if (unlikely(pud_large(pud))) { + if (!gup_huge_pud(pud, addr, next, write, pages, nr)) + return 0; + } else { + if (!gup_pmd_range(pud, addr, next, write, pages, nr)) + return 0; + } } while (pudp++, addr = next, addr != end); return 1; From 30002ed2e41830ec03ec3e577ad83ac6b188f96e Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:28 -0700 Subject: [PATCH 103/179] mm: readahead scan lockless radix_tree_next_hole() is implemented as a series of radix_tree_lookup()s. So it can be called locklessly, under rcu_read_lock(). Signed-off-by: Nick Piggin Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Hugh Dickins Cc: "Paul E. McKenney" Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/readahead.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/readahead.c b/mm/readahead.c index d8723a5f6496..77e8ddf945e9 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -382,9 +382,9 @@ ondemand_readahead(struct address_space *mapping, if (hit_readahead_marker) { pgoff_t start; - read_lock_irq(&mapping->tree_lock); - start = radix_tree_next_hole(&mapping->page_tree, offset, max+1); - read_unlock_irq(&mapping->tree_lock); + rcu_read_lock(); + start = radix_tree_next_hole(&mapping->page_tree, offset,max+1); + rcu_read_unlock(); if (!start || start - offset > max) return 0; From 47feff2c8eefe85099f87c43d3096855f0085ca0 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:29 -0700 Subject: [PATCH 104/179] radix-tree: add gang_lookup_slot, gang_lookup_slot_tag Introduce gang_lookup_slot() and gang_lookup_slot_tag() functions, which are used by lockless pagecache. Signed-off-by: Nick Piggin Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Hugh Dickins Cc: "Paul E. McKenney" Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/radix-tree.h | 12 ++- lib/radix-tree.c | 178 ++++++++++++++++++++++++++++++++----- 2 files changed, 166 insertions(+), 24 deletions(-) diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index b8ce2b444bb5..a916c6660dfa 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -99,12 +99,15 @@ do { \ * * The notable exceptions to this rule are the following functions: * radix_tree_lookup + * radix_tree_lookup_slot * radix_tree_tag_get * radix_tree_gang_lookup + * radix_tree_gang_lookup_slot * radix_tree_gang_lookup_tag + * radix_tree_gang_lookup_tag_slot * radix_tree_tagged * - * The first 4 functions are able to be called locklessly, using RCU. The + * The first 7 functions are able to be called locklessly, using RCU. The * caller must ensure calls to these functions are made within rcu_read_lock() * regions. Other readers (lock-free or otherwise) and modifications may be * running concurrently. @@ -159,6 +162,9 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long); unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); +unsigned int +radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, + unsigned long first_index, unsigned int max_items); unsigned long radix_tree_next_hole(struct radix_tree_root *root, unsigned long index, unsigned long max_scan); int radix_tree_preload(gfp_t gfp_mask); @@ -173,6 +179,10 @@ unsigned int radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag); +unsigned int +radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, + unsigned long first_index, unsigned int max_items, + unsigned int tag); int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); static inline void radix_tree_preload_end(void) diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 56ec21a7f73d..9c4f1ffa2864 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -359,18 +359,17 @@ EXPORT_SYMBOL(radix_tree_insert); * Returns: the slot corresponding to the position @index in the * radix tree @root. This is useful for update-if-exists operations. * - * This function cannot be called under rcu_read_lock, it must be - * excluded from writers, as must the returned slot for subsequent - * use by radix_tree_deref_slot() and radix_tree_replace slot. - * Caller must hold tree write locked across slot lookup and - * replace. + * This function can be called under rcu_read_lock iff the slot is not + * modified by radix_tree_replace_slot, otherwise it must be called + * exclusive from other writers. Any dereference of the slot must be done + * using radix_tree_deref_slot. */ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) { unsigned int height, shift; struct radix_tree_node *node, **slot; - node = root->rnode; + node = rcu_dereference(root->rnode); if (node == NULL) return NULL; @@ -390,7 +389,7 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index) do { slot = (struct radix_tree_node **) (node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); - node = *slot; + node = rcu_dereference(*slot); if (node == NULL) return NULL; @@ -667,7 +666,7 @@ unsigned long radix_tree_next_hole(struct radix_tree_root *root, EXPORT_SYMBOL(radix_tree_next_hole); static unsigned int -__lookup(struct radix_tree_node *slot, void **results, unsigned long index, +__lookup(struct radix_tree_node *slot, void ***results, unsigned long index, unsigned int max_items, unsigned long *next_index) { unsigned int nr_found = 0; @@ -701,11 +700,9 @@ __lookup(struct radix_tree_node *slot, void **results, unsigned long index, /* Bottom level: grab some items */ for (i = index & RADIX_TREE_MAP_MASK; i < RADIX_TREE_MAP_SIZE; i++) { - struct radix_tree_node *node; index++; - node = slot->slots[i]; - if (node) { - results[nr_found++] = rcu_dereference(node); + if (slot->slots[i]) { + results[nr_found++] = &(slot->slots[i]); if (nr_found == max_items) goto out; } @@ -759,13 +756,22 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, ret = 0; while (ret < max_items) { - unsigned int nr_found; + unsigned int nr_found, slots_found, i; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; - nr_found = __lookup(node, results + ret, cur_index, + slots_found = __lookup(node, (void ***)results + ret, cur_index, max_items - ret, &next_index); + nr_found = 0; + for (i = 0; i < slots_found; i++) { + struct radix_tree_node *slot; + slot = *(((void ***)results)[ret + i]); + if (!slot) + continue; + results[ret + nr_found] = rcu_dereference(slot); + nr_found++; + } ret += nr_found; if (next_index == 0) break; @@ -776,12 +782,71 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, } EXPORT_SYMBOL(radix_tree_gang_lookup); +/** + * radix_tree_gang_lookup_slot - perform multiple slot lookup on radix tree + * @root: radix tree root + * @results: where the results of the lookup are placed + * @first_index: start the lookup from this key + * @max_items: place up to this many items at *results + * + * Performs an index-ascending scan of the tree for present items. Places + * their slots at *@results and returns the number of items which were + * placed at *@results. + * + * The implementation is naive. + * + * Like radix_tree_gang_lookup as far as RCU and locking goes. Slots must + * be dereferenced with radix_tree_deref_slot, and if using only RCU + * protection, radix_tree_deref_slot may fail requiring a retry. + */ +unsigned int +radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, + unsigned long first_index, unsigned int max_items) +{ + unsigned long max_index; + struct radix_tree_node *node; + unsigned long cur_index = first_index; + unsigned int ret; + + node = rcu_dereference(root->rnode); + if (!node) + return 0; + + if (!radix_tree_is_indirect_ptr(node)) { + if (first_index > 0) + return 0; + results[0] = (void **)&root->rnode; + return 1; + } + node = radix_tree_indirect_to_ptr(node); + + max_index = radix_tree_maxindex(node->height); + + ret = 0; + while (ret < max_items) { + unsigned int slots_found; + unsigned long next_index; /* Index of next search */ + + if (cur_index > max_index) + break; + slots_found = __lookup(node, results + ret, cur_index, + max_items - ret, &next_index); + ret += slots_found; + if (next_index == 0) + break; + cur_index = next_index; + } + + return ret; +} +EXPORT_SYMBOL(radix_tree_gang_lookup_slot); + /* * FIXME: the two tag_get()s here should use find_next_bit() instead of * open-coding the search. */ static unsigned int -__lookup_tag(struct radix_tree_node *slot, void **results, unsigned long index, +__lookup_tag(struct radix_tree_node *slot, void ***results, unsigned long index, unsigned int max_items, unsigned long *next_index, unsigned int tag) { unsigned int nr_found = 0; @@ -811,11 +876,9 @@ __lookup_tag(struct radix_tree_node *slot, void **results, unsigned long index, unsigned long j = index & RADIX_TREE_MAP_MASK; for ( ; j < RADIX_TREE_MAP_SIZE; j++) { - struct radix_tree_node *node; index++; if (!tag_get(slot, tag, j)) continue; - node = slot->slots[j]; /* * Even though the tag was found set, we need to * recheck that we have a non-NULL node, because @@ -826,9 +889,8 @@ __lookup_tag(struct radix_tree_node *slot, void **results, unsigned long index, * lookup ->slots[x] without a lock (ie. can't * rely on its value remaining the same). */ - if (node) { - node = rcu_dereference(node); - results[nr_found++] = node; + if (slot->slots[j]) { + results[nr_found++] = &(slot->slots[j]); if (nr_found == max_items) goto out; } @@ -887,13 +949,22 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, ret = 0; while (ret < max_items) { - unsigned int nr_found; + unsigned int nr_found, slots_found, i; unsigned long next_index; /* Index of next search */ if (cur_index > max_index) break; - nr_found = __lookup_tag(node, results + ret, cur_index, - max_items - ret, &next_index, tag); + slots_found = __lookup_tag(node, (void ***)results + ret, + cur_index, max_items - ret, &next_index, tag); + nr_found = 0; + for (i = 0; i < slots_found; i++) { + struct radix_tree_node *slot; + slot = *(((void ***)results)[ret + i]); + if (!slot) + continue; + results[ret + nr_found] = rcu_dereference(slot); + nr_found++; + } ret += nr_found; if (next_index == 0) break; @@ -904,6 +975,67 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, } EXPORT_SYMBOL(radix_tree_gang_lookup_tag); +/** + * radix_tree_gang_lookup_tag_slot - perform multiple slot lookup on a + * radix tree based on a tag + * @root: radix tree root + * @results: where the results of the lookup are placed + * @first_index: start the lookup from this key + * @max_items: place up to this many items at *results + * @tag: the tag index (< RADIX_TREE_MAX_TAGS) + * + * Performs an index-ascending scan of the tree for present items which + * have the tag indexed by @tag set. Places the slots at *@results and + * returns the number of slots which were placed at *@results. + */ +unsigned int +radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, + unsigned long first_index, unsigned int max_items, + unsigned int tag) +{ + struct radix_tree_node *node; + unsigned long max_index; + unsigned long cur_index = first_index; + unsigned int ret; + + /* check the root's tag bit */ + if (!root_tag_get(root, tag)) + return 0; + + node = rcu_dereference(root->rnode); + if (!node) + return 0; + + if (!radix_tree_is_indirect_ptr(node)) { + if (first_index > 0) + return 0; + results[0] = (void **)&root->rnode; + return 1; + } + node = radix_tree_indirect_to_ptr(node); + + max_index = radix_tree_maxindex(node->height); + + ret = 0; + while (ret < max_items) { + unsigned int slots_found; + unsigned long next_index; /* Index of next search */ + + if (cur_index > max_index) + break; + slots_found = __lookup_tag(node, results + ret, + cur_index, max_items - ret, &next_index, tag); + ret += slots_found; + if (next_index == 0) + break; + cur_index = next_index; + } + + return ret; +} +EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot); + + /** * radix_tree_shrink - shrink height of a radix tree to minimal * @root radix tree root From e286781d5f2e9c846e012a39653a166e9d31777d Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:30 -0700 Subject: [PATCH 105/179] mm: speculative page references If we can be sure that elevating the page_count on a pagecache page will pin it, we can speculatively run this operation, and subsequently check to see if we hit the right page rather than relying on holding a lock or otherwise pinning a reference to the page. This can be done if get_page/put_page behaves consistently throughout the whole tree (ie. if we "get" the page after it has been used for something else, we must be able to free it with a put_page). Actually, there is a period where the count behaves differently: when the page is free or if it is a constituent page of a compound page. We need an atomic_inc_not_zero operation to ensure we don't try to grab the page in either case. This patch introduces the core locking protocol to the pagecache (ie. adds page_cache_get_speculative, and tweaks some update-side code to make it work). Thanks to Hugh for pointing out an improvement to the algorithm setting page_count to zero when we have control of all references, in order to hold off speculative getters. [kamezawa.hiroyu@jp.fujitsu.com: fix migration_entry_wait()] [hugh@veritas.com: fix add_to_page_cache] [akpm@linux-foundation.org: repair a comment] Signed-off-by: Nick Piggin Cc: Jeff Garzik Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Hugh Dickins Cc: "Paul E. McKenney" Reviewed-by: Peter Zijlstra Signed-off-by: Daisuke Nishimura Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: KOSAKI Motohiro Signed-off-by: Hugh Dickins Acked-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/cassini.c | 12 +++++ include/linux/pagemap.h | 111 +++++++++++++++++++++++++++++++++++++++- mm/filemap.c | 32 +++++++----- mm/migrate.c | 20 +++++++- mm/shmem.c | 6 +-- mm/swap_state.c | 17 ++++-- mm/vmscan.c | 74 +++++++++++++++++++-------- 7 files changed, 227 insertions(+), 45 deletions(-) diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 83768df27806..f1936d51b458 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -576,6 +576,18 @@ static void cas_spare_recover(struct cas *cp, const gfp_t flags) list_for_each_safe(elem, tmp, &list) { cas_page_t *page = list_entry(elem, cas_page_t, list); + /* + * With the lockless pagecache, cassini buffering scheme gets + * slightly less accurate: we might find that a page has an + * elevated reference count here, due to a speculative ref, + * and skip it as in-use. Ideally we would be able to reclaim + * it. However this would be such a rare case, it doesn't + * matter too much as we should pick it up the next time round. + * + * Importantly, if we find that the page has a refcount of 1 + * here (our refcount), then we know it is definitely not inuse + * so we can reuse it. + */ if (page_count(page->buffer) > 1) continue; diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index ee1ec2c7723c..a81d81890422 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -12,6 +12,7 @@ #include #include #include +#include /* for in_interrupt() */ /* * Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page @@ -62,6 +63,98 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask) #define page_cache_release(page) put_page(page) void release_pages(struct page **pages, int nr, int cold); +/* + * speculatively take a reference to a page. + * If the page is free (_count == 0), then _count is untouched, and 0 + * is returned. Otherwise, _count is incremented by 1 and 1 is returned. + * + * This function must be called inside the same rcu_read_lock() section as has + * been used to lookup the page in the pagecache radix-tree (or page table): + * this allows allocators to use a synchronize_rcu() to stabilize _count. + * + * Unless an RCU grace period has passed, the count of all pages coming out + * of the allocator must be considered unstable. page_count may return higher + * than expected, and put_page must be able to do the right thing when the + * page has been finished with, no matter what it is subsequently allocated + * for (because put_page is what is used here to drop an invalid speculative + * reference). + * + * This is the interesting part of the lockless pagecache (and lockless + * get_user_pages) locking protocol, where the lookup-side (eg. find_get_page) + * has the following pattern: + * 1. find page in radix tree + * 2. conditionally increment refcount + * 3. check the page is still in pagecache (if no, goto 1) + * + * Remove-side that cares about stability of _count (eg. reclaim) has the + * following (with tree_lock held for write): + * A. atomically check refcount is correct and set it to 0 (atomic_cmpxchg) + * B. remove page from pagecache + * C. free the page + * + * There are 2 critical interleavings that matter: + * - 2 runs before A: in this case, A sees elevated refcount and bails out + * - A runs before 2: in this case, 2 sees zero refcount and retries; + * subsequently, B will complete and 1 will find no page, causing the + * lookup to return NULL. + * + * It is possible that between 1 and 2, the page is removed then the exact same + * page is inserted into the same position in pagecache. That's OK: the + * old find_get_page using tree_lock could equally have run before or after + * such a re-insertion, depending on order that locks are granted. + * + * Lookups racing against pagecache insertion isn't a big problem: either 1 + * will find the page or it will not. Likewise, the old find_get_page could run + * either before the insertion or afterwards, depending on timing. + */ +static inline int page_cache_get_speculative(struct page *page) +{ + VM_BUG_ON(in_interrupt()); + +#if !defined(CONFIG_SMP) && defined(CONFIG_CLASSIC_RCU) +# ifdef CONFIG_PREEMPT + VM_BUG_ON(!in_atomic()); +# endif + /* + * Preempt must be disabled here - we rely on rcu_read_lock doing + * this for us. + * + * Pagecache won't be truncated from interrupt context, so if we have + * found a page in the radix tree here, we have pinned its refcount by + * disabling preempt, and hence no need for the "speculative get" that + * SMP requires. + */ + VM_BUG_ON(page_count(page) == 0); + atomic_inc(&page->_count); + +#else + if (unlikely(!get_page_unless_zero(page))) { + /* + * Either the page has been freed, or will be freed. + * In either case, retry here and the caller should + * do the right thing (see comments above). + */ + return 0; + } +#endif + VM_BUG_ON(PageTail(page)); + + return 1; +} + +static inline int page_freeze_refs(struct page *page, int count) +{ + return likely(atomic_cmpxchg(&page->_count, count, 0) == count); +} + +static inline void page_unfreeze_refs(struct page *page, int count) +{ + VM_BUG_ON(page_count(page) != 0); + VM_BUG_ON(count == 0); + + atomic_set(&page->_count, count); +} + #ifdef CONFIG_NUMA extern struct page *__page_cache_alloc(gfp_t gfp); #else @@ -133,13 +226,29 @@ static inline struct page *read_mapping_page(struct address_space *mapping, return read_cache_page(mapping, index, filler, data); } -int add_to_page_cache(struct page *page, struct address_space *mapping, +int add_to_page_cache_locked(struct page *page, struct address_space *mapping, pgoff_t index, gfp_t gfp_mask); int add_to_page_cache_lru(struct page *page, struct address_space *mapping, pgoff_t index, gfp_t gfp_mask); extern void remove_from_page_cache(struct page *page); extern void __remove_from_page_cache(struct page *page); +/* + * Like add_to_page_cache_locked, but used to add newly allocated pages: + * the page is new, so we can just run SetPageLocked() against it. + */ +static inline int add_to_page_cache(struct page *page, + struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) +{ + int error; + + SetPageLocked(page); + error = add_to_page_cache_locked(page, mapping, offset, gfp_mask); + if (unlikely(error)) + ClearPageLocked(page); + return error; +} + /* * Return byte-offset into filesystem object for page. */ diff --git a/mm/filemap.c b/mm/filemap.c index 2d3ec1ffc66e..4e182a9a14c0 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -442,39 +442,43 @@ int filemap_write_and_wait_range(struct address_space *mapping, } /** - * add_to_page_cache - add newly allocated pagecache pages + * add_to_page_cache_locked - add a locked page to the pagecache * @page: page to add * @mapping: the page's address_space * @offset: page index * @gfp_mask: page allocation mode * - * This function is used to add newly allocated pagecache pages; - * the page is new, so we can just run SetPageLocked() against it. - * The other page state flags were set by rmqueue(). - * + * This function is used to add a page to the pagecache. It must be locked. * This function does not add the page to the LRU. The caller must do that. */ -int add_to_page_cache(struct page *page, struct address_space *mapping, +int add_to_page_cache_locked(struct page *page, struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) { - int error = mem_cgroup_cache_charge(page, current->mm, + int error; + + VM_BUG_ON(!PageLocked(page)); + + error = mem_cgroup_cache_charge(page, current->mm, gfp_mask & ~__GFP_HIGHMEM); if (error) goto out; error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM); if (error == 0) { + page_cache_get(page); + page->mapping = mapping; + page->index = offset; + write_lock_irq(&mapping->tree_lock); error = radix_tree_insert(&mapping->page_tree, offset, page); - if (!error) { - page_cache_get(page); - SetPageLocked(page); - page->mapping = mapping; - page->index = offset; + if (likely(!error)) { mapping->nrpages++; __inc_zone_page_state(page, NR_FILE_PAGES); - } else + } else { + page->mapping = NULL; mem_cgroup_uncharge_cache_page(page); + page_cache_release(page); + } write_unlock_irq(&mapping->tree_lock); radix_tree_preload_end(); @@ -483,7 +487,7 @@ int add_to_page_cache(struct page *page, struct address_space *mapping, out: return error; } -EXPORT_SYMBOL(add_to_page_cache); +EXPORT_SYMBOL(add_to_page_cache_locked); int add_to_page_cache_lru(struct page *page, struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) diff --git a/mm/migrate.c b/mm/migrate.c index d8c65a65c61d..3ca6392e82cc 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -285,7 +285,15 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, page = migration_entry_to_page(entry); - get_page(page); + /* + * Once radix-tree replacement of page migration started, page_count + * *must* be zero. And, we don't want to call wait_on_page_locked() + * against a page without get_page(). + * So, we use get_page_unless_zero(), here. Even failed, page fault + * will occur again. + */ + if (!get_page_unless_zero(page)) + goto out; pte_unmap_unlock(ptep, ptl); wait_on_page_locked(page); put_page(page); @@ -305,6 +313,7 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, static int migrate_page_move_mapping(struct address_space *mapping, struct page *newpage, struct page *page) { + int expected_count; void **pslot; if (!mapping) { @@ -319,12 +328,18 @@ static int migrate_page_move_mapping(struct address_space *mapping, pslot = radix_tree_lookup_slot(&mapping->page_tree, page_index(page)); - if (page_count(page) != 2 + !!PagePrivate(page) || + expected_count = 2 + !!PagePrivate(page); + if (page_count(page) != expected_count || (struct page *)radix_tree_deref_slot(pslot) != page) { write_unlock_irq(&mapping->tree_lock); return -EAGAIN; } + if (!page_freeze_refs(page, expected_count)) { + write_unlock_irq(&mapping->tree_lock); + return -EAGAIN; + } + /* * Now we know that no one else is looking at the page. */ @@ -338,6 +353,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, radix_tree_replace_slot(pslot, newpage); + page_unfreeze_refs(page, expected_count); /* * Drop cache reference from old page. * We know this isn't the last reference. diff --git a/mm/shmem.c b/mm/shmem.c index f92fea94d037..1089092aecaf 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -936,7 +936,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s spin_lock(&info->lock); ptr = shmem_swp_entry(info, idx, NULL); if (ptr && ptr->val == entry.val) { - error = add_to_page_cache(page, inode->i_mapping, + error = add_to_page_cache_locked(page, inode->i_mapping, idx, GFP_NOWAIT); /* does mem_cgroup_uncharge_cache_page on error */ } else /* we must compensate for our precharge above */ @@ -1301,8 +1301,8 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, SetPageUptodate(filepage); set_page_dirty(filepage); swap_free(swap); - } else if (!(error = add_to_page_cache( - swappage, mapping, idx, GFP_NOWAIT))) { + } else if (!(error = add_to_page_cache_locked(swappage, mapping, + idx, GFP_NOWAIT))) { info->flags |= SHMEM_PAGEIN; shmem_swp_set(info, entry, 0); shmem_swp_unmap(entry); diff --git a/mm/swap_state.c b/mm/swap_state.c index d8aadaf2a0ba..3e3381d6c7ee 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -64,7 +64,7 @@ void show_swap_cache_info(void) } /* - * add_to_swap_cache resembles add_to_page_cache on swapper_space, + * add_to_swap_cache resembles add_to_page_cache_locked on swapper_space, * but sets SwapCache flag and private instead of mapping and index. */ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) @@ -76,19 +76,26 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) BUG_ON(PagePrivate(page)); error = radix_tree_preload(gfp_mask); if (!error) { + page_cache_get(page); + SetPageSwapCache(page); + set_page_private(page, entry.val); + write_lock_irq(&swapper_space.tree_lock); error = radix_tree_insert(&swapper_space.page_tree, entry.val, page); - if (!error) { - page_cache_get(page); - SetPageSwapCache(page); - set_page_private(page, entry.val); + if (likely(!error)) { total_swapcache_pages++; __inc_zone_page_state(page, NR_FILE_PAGES); INC_CACHE_INFO(add_total); } write_unlock_irq(&swapper_space.tree_lock); radix_tree_preload_end(); + + if (unlikely(error)) { + set_page_private(page, 0UL); + ClearPageSwapCache(page); + page_cache_release(page); + } } return error; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 26672c6cd3ce..0075eac1cd04 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -391,12 +391,10 @@ static pageout_t pageout(struct page *page, struct address_space *mapping, } /* - * Attempt to detach a locked page from its ->mapping. If it is dirty or if - * someone else has a ref on the page, abort and return 0. If it was - * successfully detached, return 1. Assumes the caller has a single ref on - * this page. + * Same as remove_mapping, but if the page is removed from the mapping, it + * gets returned with a refcount of 0. */ -int remove_mapping(struct address_space *mapping, struct page *page) +static int __remove_mapping(struct address_space *mapping, struct page *page) { BUG_ON(!PageLocked(page)); BUG_ON(mapping != page_mapping(page)); @@ -427,24 +425,24 @@ int remove_mapping(struct address_space *mapping, struct page *page) * Note that if SetPageDirty is always performed via set_page_dirty, * and thus under tree_lock, then this ordering is not required. */ - if (unlikely(page_count(page) != 2)) + if (!page_freeze_refs(page, 2)) goto cannot_free; - smp_rmb(); - if (unlikely(PageDirty(page))) + /* note: atomic_cmpxchg in page_freeze_refs provides the smp_rmb */ + if (unlikely(PageDirty(page))) { + page_unfreeze_refs(page, 2); goto cannot_free; + } if (PageSwapCache(page)) { swp_entry_t swap = { .val = page_private(page) }; __delete_from_swap_cache(page); write_unlock_irq(&mapping->tree_lock); swap_free(swap); - __put_page(page); /* The pagecache ref */ - return 1; + } else { + __remove_from_page_cache(page); + write_unlock_irq(&mapping->tree_lock); } - __remove_from_page_cache(page); - write_unlock_irq(&mapping->tree_lock); - __put_page(page); return 1; cannot_free: @@ -452,6 +450,26 @@ int remove_mapping(struct address_space *mapping, struct page *page) return 0; } +/* + * Attempt to detach a locked page from its ->mapping. If it is dirty or if + * someone else has a ref on the page, abort and return 0. If it was + * successfully detached, return 1. Assumes the caller has a single ref on + * this page. + */ +int remove_mapping(struct address_space *mapping, struct page *page) +{ + if (__remove_mapping(mapping, page)) { + /* + * Unfreezing the refcount with 1 rather than 2 effectively + * drops the pagecache ref for us without requiring another + * atomic operation. + */ + page_unfreeze_refs(page, 1); + return 1; + } + return 0; +} + /* * shrink_page_list() returns the number of reclaimed pages */ @@ -598,18 +616,34 @@ static unsigned long shrink_page_list(struct list_head *page_list, if (PagePrivate(page)) { if (!try_to_release_page(page, sc->gfp_mask)) goto activate_locked; - if (!mapping && page_count(page) == 1) - goto free_it; + if (!mapping && page_count(page) == 1) { + unlock_page(page); + if (put_page_testzero(page)) + goto free_it; + else { + /* + * rare race with speculative reference. + * the speculative reference will free + * this page shortly, so we may + * increment nr_reclaimed here (and + * leave it off the LRU). + */ + nr_reclaimed++; + continue; + } + } } - if (!mapping || !remove_mapping(mapping, page)) + if (!mapping || !__remove_mapping(mapping, page)) goto keep_locked; -free_it: unlock_page(page); +free_it: nr_reclaimed++; - if (!pagevec_add(&freed_pvec, page)) - __pagevec_release_nonlru(&freed_pvec); + if (!pagevec_add(&freed_pvec, page)) { + __pagevec_free(&freed_pvec); + pagevec_reinit(&freed_pvec); + } continue; activate_locked: @@ -623,7 +657,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, } list_splice(&ret_pages, page_list); if (pagevec_count(&freed_pvec)) - __pagevec_release_nonlru(&freed_pvec); + __pagevec_free(&freed_pvec); count_vm_events(PGACTIVATE, pgactivate); return nr_reclaimed; } From a60637c85893e7191faaafa6a72e197c24386727 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:31 -0700 Subject: [PATCH 106/179] mm: lockless pagecache Combine page_cache_get_speculative with lockless radix tree lookups to introduce lockless page cache lookups (ie. no mapping->tree_lock on the read-side). The only atomicity changes this introduces is that the gang pagecache lookup functions now behave as if they are implemented with multiple find_get_page calls, rather than operating on a snapshot of the pages. In practice, this atomicity guarantee is not used anyway, and it is to replace individual lookups, so these semantics are natural. Signed-off-by: Nick Piggin Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Hugh Dickins Cc: "Paul E. McKenney" Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/filemap.c | 179 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 134 insertions(+), 45 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 4e182a9a14c0..feb8448d8618 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -637,15 +637,35 @@ void __lock_page_nosync(struct page *page) * Is there a pagecache struct page at the given (mapping, offset) tuple? * If yes, increment its refcount and return it; if no, return NULL. */ -struct page * find_get_page(struct address_space *mapping, pgoff_t offset) +struct page *find_get_page(struct address_space *mapping, pgoff_t offset) { + void **pagep; struct page *page; - read_lock_irq(&mapping->tree_lock); - page = radix_tree_lookup(&mapping->page_tree, offset); - if (page) - page_cache_get(page); - read_unlock_irq(&mapping->tree_lock); + rcu_read_lock(); +repeat: + page = NULL; + pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); + if (pagep) { + page = radix_tree_deref_slot(pagep); + if (unlikely(!page || page == RADIX_TREE_RETRY)) + goto repeat; + + if (!page_cache_get_speculative(page)) + goto repeat; + + /* + * Has the page moved? + * This is part of the lockless pagecache protocol. See + * include/linux/pagemap.h for details. + */ + if (unlikely(page != *pagep)) { + page_cache_release(page); + goto repeat; + } + } + rcu_read_unlock(); + return page; } EXPORT_SYMBOL(find_get_page); @@ -660,32 +680,22 @@ EXPORT_SYMBOL(find_get_page); * * Returns zero if the page was not present. find_lock_page() may sleep. */ -struct page *find_lock_page(struct address_space *mapping, - pgoff_t offset) +struct page *find_lock_page(struct address_space *mapping, pgoff_t offset) { struct page *page; repeat: - read_lock_irq(&mapping->tree_lock); - page = radix_tree_lookup(&mapping->page_tree, offset); + page = find_get_page(mapping, offset); if (page) { - page_cache_get(page); - if (TestSetPageLocked(page)) { - read_unlock_irq(&mapping->tree_lock); - __lock_page(page); - - /* Has the page been truncated while we slept? */ - if (unlikely(page->mapping != mapping)) { - unlock_page(page); - page_cache_release(page); - goto repeat; - } - VM_BUG_ON(page->index != offset); - goto out; + lock_page(page); + /* Has the page been truncated? */ + if (unlikely(page->mapping != mapping)) { + unlock_page(page); + page_cache_release(page); + goto repeat; } + VM_BUG_ON(page->index != offset); } - read_unlock_irq(&mapping->tree_lock); -out: return page; } EXPORT_SYMBOL(find_lock_page); @@ -751,13 +761,39 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, { unsigned int i; unsigned int ret; + unsigned int nr_found; - read_lock_irq(&mapping->tree_lock); - ret = radix_tree_gang_lookup(&mapping->page_tree, - (void **)pages, start, nr_pages); - for (i = 0; i < ret; i++) - page_cache_get(pages[i]); - read_unlock_irq(&mapping->tree_lock); + rcu_read_lock(); +restart: + nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, + (void ***)pages, start, nr_pages); + ret = 0; + for (i = 0; i < nr_found; i++) { + struct page *page; +repeat: + page = radix_tree_deref_slot((void **)pages[i]); + if (unlikely(!page)) + continue; + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) + goto restart; + + if (!page_cache_get_speculative(page)) + goto repeat; + + /* Has the page moved? */ + if (unlikely(page != *((void **)pages[i]))) { + page_cache_release(page); + goto repeat; + } + + pages[ret] = page; + ret++; + } + rcu_read_unlock(); return ret; } @@ -778,19 +814,44 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, { unsigned int i; unsigned int ret; + unsigned int nr_found; - read_lock_irq(&mapping->tree_lock); - ret = radix_tree_gang_lookup(&mapping->page_tree, - (void **)pages, index, nr_pages); - for (i = 0; i < ret; i++) { - if (pages[i]->mapping == NULL || pages[i]->index != index) + rcu_read_lock(); +restart: + nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, + (void ***)pages, index, nr_pages); + ret = 0; + for (i = 0; i < nr_found; i++) { + struct page *page; +repeat: + page = radix_tree_deref_slot((void **)pages[i]); + if (unlikely(!page)) + continue; + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) + goto restart; + + if (page->mapping == NULL || page->index != index) break; - page_cache_get(pages[i]); + if (!page_cache_get_speculative(page)) + goto repeat; + + /* Has the page moved? */ + if (unlikely(page != *((void **)pages[i]))) { + page_cache_release(page); + goto repeat; + } + + pages[ret] = page; + ret++; index++; } - read_unlock_irq(&mapping->tree_lock); - return i; + rcu_read_unlock(); + return ret; } EXPORT_SYMBOL(find_get_pages_contig); @@ -810,15 +871,43 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, { unsigned int i; unsigned int ret; + unsigned int nr_found; + + rcu_read_lock(); +restart: + nr_found = radix_tree_gang_lookup_tag_slot(&mapping->page_tree, + (void ***)pages, *index, nr_pages, tag); + ret = 0; + for (i = 0; i < nr_found; i++) { + struct page *page; +repeat: + page = radix_tree_deref_slot((void **)pages[i]); + if (unlikely(!page)) + continue; + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) + goto restart; + + if (!page_cache_get_speculative(page)) + goto repeat; + + /* Has the page moved? */ + if (unlikely(page != *((void **)pages[i]))) { + page_cache_release(page); + goto repeat; + } + + pages[ret] = page; + ret++; + } + rcu_read_unlock(); - read_lock_irq(&mapping->tree_lock); - ret = radix_tree_gang_lookup_tag(&mapping->page_tree, - (void **)pages, *index, nr_pages, tag); - for (i = 0; i < ret; i++) - page_cache_get(pages[i]); if (ret) *index = pages[ret - 1]->index + 1; - read_unlock_irq(&mapping->tree_lock); + return ret; } EXPORT_SYMBOL(find_get_pages_tag); From 19fd6231279be3c3bdd02ed99f9b0eb195978064 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:32 -0700 Subject: [PATCH 107/179] mm: spinlock tree_lock mapping->tree_lock has no read lockers. convert the lock from an rwlock to a spinlock. Signed-off-by: Nick Piggin Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Hugh Dickins Cc: "Paul E. McKenney" Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 4 ++-- fs/inode.c | 2 +- include/asm-arm/cacheflush.h | 4 ++-- include/asm-parisc/cacheflush.h | 4 ++-- include/linux/fs.h | 2 +- mm/filemap.c | 10 +++++----- mm/migrate.c | 11 +++++------ mm/page-writeback.c | 12 ++++++------ mm/swap_state.c | 10 +++++----- mm/swapfile.c | 4 ++-- mm/truncate.c | 6 +++--- mm/vmscan.c | 8 ++++---- 12 files changed, 38 insertions(+), 39 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index d48caee12e2a..109b261192d9 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -706,7 +706,7 @@ static int __set_page_dirty(struct page *page, if (TestSetPageDirty(page)) return 0; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); if (page->mapping) { /* Race with truncate? */ WARN_ON_ONCE(warn && !PageUptodate(page)); @@ -719,7 +719,7 @@ static int __set_page_dirty(struct page *page, radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); } - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); return 1; diff --git a/fs/inode.c b/fs/inode.c index c36d9480335c..35b6414522ea 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -209,7 +209,7 @@ void inode_init_once(struct inode *inode) INIT_LIST_HEAD(&inode->i_dentry); INIT_LIST_HEAD(&inode->i_devices); INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); - rwlock_init(&inode->i_data.tree_lock); + spin_lock_init(&inode->i_data.tree_lock); spin_lock_init(&inode->i_data.i_mmap_lock); INIT_LIST_HEAD(&inode->i_data.private_list); spin_lock_init(&inode->i_data.private_lock); diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 70b0fe724b62..03cf1ee977b7 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -424,9 +424,9 @@ static inline void flush_anon_page(struct vm_area_struct *vma, } #define flush_dcache_mmap_lock(mapping) \ - write_lock_irq(&(mapping)->tree_lock) + spin_lock_irq(&(mapping)->tree_lock) #define flush_dcache_mmap_unlock(mapping) \ - write_unlock_irq(&(mapping)->tree_lock) + spin_unlock_irq(&(mapping)->tree_lock) #define flush_icache_user_range(vma,page,addr,len) \ flush_dcache_page(page) diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index 2f1e1b05440a..b7ca6dc7fddc 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h @@ -45,9 +45,9 @@ void flush_cache_mm(struct mm_struct *mm); extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping) \ - write_lock_irq(&(mapping)->tree_lock) + spin_lock_irq(&(mapping)->tree_lock) #define flush_dcache_mmap_unlock(mapping) \ - write_unlock_irq(&(mapping)->tree_lock) + spin_unlock_irq(&(mapping)->tree_lock) #define flush_icache_page(vma,page) do { \ flush_kernel_dcache_page(page); \ diff --git a/include/linux/fs.h b/include/linux/fs.h index 49d8eb7a71be..53d2edb709b3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -499,7 +499,7 @@ struct backing_dev_info; struct address_space { struct inode *host; /* owner: inode, block_device */ struct radix_tree_root page_tree; /* radix tree of all pages */ - rwlock_t tree_lock; /* and rwlock protecting it */ + spinlock_t tree_lock; /* and lock protecting it */ unsigned int i_mmap_writable;/* count VM_SHARED mappings */ struct prio_tree_root i_mmap; /* tree of private and shared mappings */ struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ diff --git a/mm/filemap.c b/mm/filemap.c index feb8448d8618..2ed8b0389c51 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -109,7 +109,7 @@ /* * Remove a page from the page cache and free it. Caller has to make * sure the page is locked and that nobody else uses it - or that usage - * is safe. The caller must hold a write_lock on the mapping's tree_lock. + * is safe. The caller must hold the mapping's tree_lock. */ void __remove_from_page_cache(struct page *page) { @@ -141,9 +141,9 @@ void remove_from_page_cache(struct page *page) BUG_ON(!PageLocked(page)); - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); __remove_from_page_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); } static int sync_page(void *word) @@ -469,7 +469,7 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, page->mapping = mapping; page->index = offset; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); error = radix_tree_insert(&mapping->page_tree, offset, page); if (likely(!error)) { mapping->nrpages++; @@ -480,7 +480,7 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, page_cache_release(page); } - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); radix_tree_preload_end(); } else mem_cgroup_uncharge_cache_page(page); diff --git a/mm/migrate.c b/mm/migrate.c index 3ca6392e82cc..153572fb60b8 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -323,7 +323,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, return 0; } - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); pslot = radix_tree_lookup_slot(&mapping->page_tree, page_index(page)); @@ -331,12 +331,12 @@ static int migrate_page_move_mapping(struct address_space *mapping, expected_count = 2 + !!PagePrivate(page); if (page_count(page) != expected_count || (struct page *)radix_tree_deref_slot(pslot) != page) { - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return -EAGAIN; } if (!page_freeze_refs(page, expected_count)) { - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return -EAGAIN; } @@ -373,10 +373,9 @@ static int migrate_page_move_mapping(struct address_space *mapping, __dec_zone_page_state(page, NR_FILE_PAGES); __inc_zone_page_state(newpage, NR_FILE_PAGES); - write_unlock_irq(&mapping->tree_lock); - if (!PageSwapCache(newpage)) { + spin_unlock_irq(&mapping->tree_lock); + if (!PageSwapCache(newpage)) mem_cgroup_uncharge_cache_page(page); - } return 0; } diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 94c6d8988ab3..24de8b65fdbd 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -1088,7 +1088,7 @@ int __set_page_dirty_nobuffers(struct page *page) if (!mapping) return 1; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); mapping2 = page_mapping(page); if (mapping2) { /* Race with truncate? */ BUG_ON(mapping2 != mapping); @@ -1102,7 +1102,7 @@ int __set_page_dirty_nobuffers(struct page *page) radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); } - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); if (mapping->host) { /* !PageAnon && !swapper_space */ __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); @@ -1258,7 +1258,7 @@ int test_clear_page_writeback(struct page *page) struct backing_dev_info *bdi = mapping->backing_dev_info; unsigned long flags; - write_lock_irqsave(&mapping->tree_lock, flags); + spin_lock_irqsave(&mapping->tree_lock, flags); ret = TestClearPageWriteback(page); if (ret) { radix_tree_tag_clear(&mapping->page_tree, @@ -1269,7 +1269,7 @@ int test_clear_page_writeback(struct page *page) __bdi_writeout_inc(bdi); } } - write_unlock_irqrestore(&mapping->tree_lock, flags); + spin_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestClearPageWriteback(page); } @@ -1287,7 +1287,7 @@ int test_set_page_writeback(struct page *page) struct backing_dev_info *bdi = mapping->backing_dev_info; unsigned long flags; - write_lock_irqsave(&mapping->tree_lock, flags); + spin_lock_irqsave(&mapping->tree_lock, flags); ret = TestSetPageWriteback(page); if (!ret) { radix_tree_tag_set(&mapping->page_tree, @@ -1300,7 +1300,7 @@ int test_set_page_writeback(struct page *page) radix_tree_tag_clear(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); - write_unlock_irqrestore(&mapping->tree_lock, flags); + spin_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestSetPageWriteback(page); } diff --git a/mm/swap_state.c b/mm/swap_state.c index 3e3381d6c7ee..2c217e33d497 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -39,7 +39,7 @@ static struct backing_dev_info swap_backing_dev_info = { struct address_space swapper_space = { .page_tree = RADIX_TREE_INIT(GFP_ATOMIC|__GFP_NOWARN), - .tree_lock = __RW_LOCK_UNLOCKED(swapper_space.tree_lock), + .tree_lock = __SPIN_LOCK_UNLOCKED(swapper_space.tree_lock), .a_ops = &swap_aops, .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear), .backing_dev_info = &swap_backing_dev_info, @@ -80,7 +80,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) SetPageSwapCache(page); set_page_private(page, entry.val); - write_lock_irq(&swapper_space.tree_lock); + spin_lock_irq(&swapper_space.tree_lock); error = radix_tree_insert(&swapper_space.page_tree, entry.val, page); if (likely(!error)) { @@ -88,7 +88,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) __inc_zone_page_state(page, NR_FILE_PAGES); INC_CACHE_INFO(add_total); } - write_unlock_irq(&swapper_space.tree_lock); + spin_unlock_irq(&swapper_space.tree_lock); radix_tree_preload_end(); if (unlikely(error)) { @@ -182,9 +182,9 @@ void delete_from_swap_cache(struct page *page) entry.val = page_private(page); - write_lock_irq(&swapper_space.tree_lock); + spin_lock_irq(&swapper_space.tree_lock); __delete_from_swap_cache(page); - write_unlock_irq(&swapper_space.tree_lock); + spin_unlock_irq(&swapper_space.tree_lock); swap_free(entry); page_cache_release(page); diff --git a/mm/swapfile.c b/mm/swapfile.c index 2f33edb8bee9..af283933c14e 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -369,13 +369,13 @@ int remove_exclusive_swap_page(struct page *page) retval = 0; if (p->swap_map[swp_offset(entry)] == 1) { /* Recheck the page count with the swapcache lock held.. */ - write_lock_irq(&swapper_space.tree_lock); + spin_lock_irq(&swapper_space.tree_lock); if ((page_count(page) == 2) && !PageWriteback(page)) { __delete_from_swap_cache(page); SetPageDirty(page); retval = 1; } - write_unlock_irq(&swapper_space.tree_lock); + spin_unlock_irq(&swapper_space.tree_lock); } spin_unlock(&swap_lock); diff --git a/mm/truncate.c b/mm/truncate.c index b8961cb63414..e68443d74567 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -349,18 +349,18 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL)) return 0; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); if (PageDirty(page)) goto failed; BUG_ON(PagePrivate(page)); __remove_from_page_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); ClearPageUptodate(page); page_cache_release(page); /* pagecache ref */ return 1; failed: - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return 0; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 0075eac1cd04..8f71761bc4b7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -399,7 +399,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) BUG_ON(!PageLocked(page)); BUG_ON(mapping != page_mapping(page)); - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); /* * The non racy check for a busy page. * @@ -436,17 +436,17 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) if (PageSwapCache(page)) { swp_entry_t swap = { .val = page_private(page) }; __delete_from_swap_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); swap_free(swap); } else { __remove_from_page_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); } return 1; cannot_free: - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return 0; } From d91958815d214ea365b98cbff6215383897edcb6 Mon Sep 17 00:00:00 2001 From: Matt LaPlante Date: Fri, 25 Jul 2008 19:45:33 -0700 Subject: [PATCH 108/179] Documentation cleanup: trivial misspelling, punctuation, and grammar corrections. Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/Intel-IOMMU.txt | 4 ++-- Documentation/accounting/taskstats-struct.txt | 2 +- Documentation/cpu-freq/governors.txt | 2 +- Documentation/edac.txt | 2 +- Documentation/filesystems/proc.txt | 4 ++-- Documentation/filesystems/vfs.txt | 6 +++--- Documentation/ia64/kvm.txt | 8 ++++---- Documentation/input/cs461x.txt | 2 +- Documentation/ioctl/ioctl-decoding.txt | 4 ++-- Documentation/iostats.txt | 2 +- Documentation/keys.txt | 2 +- Documentation/leds-class.txt | 2 +- Documentation/local_ops.txt | 2 +- Documentation/networking/bonding.txt | 2 +- Documentation/networking/can.txt | 4 ++-- Documentation/networking/packet_mmap.txt | 2 +- Documentation/networking/tc-actions-env-rules.txt | 15 ++++++++------- Documentation/powerpc/booting-without-of.txt | 8 ++++---- Documentation/powerpc/qe_firmware.txt | 2 +- Documentation/s390/driver-model.txt | 2 +- Documentation/scsi/ibmmca.txt | 6 +++--- Documentation/scsi/lpfc.txt | 2 +- Documentation/scsi/scsi_fc_transport.txt | 6 +++--- Documentation/sh/clk.txt | 2 +- Documentation/sound/alsa/Audiophile-Usb.txt | 10 +++++----- Documentation/sound/alsa/hda_codec.txt | 2 +- Documentation/sound/alsa/soc/dapm.txt | 2 +- Documentation/sysctl/vm.txt | 2 +- Documentation/timers/highres.txt | 2 +- Documentation/usb/authorization.txt | 2 +- Documentation/video4linux/sn9c102.txt | 2 +- Documentation/vm/hugetlbpage.txt | 2 +- Documentation/vm/numa_memory_policy.txt | 4 ++-- Documentation/volatile-considered-harmful.txt | 2 +- drivers/message/fusion/lsi/mpi_history.txt | 6 +++--- 35 files changed, 65 insertions(+), 64 deletions(-) diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt index c2321903aa09..21bc416d887e 100644 --- a/Documentation/Intel-IOMMU.txt +++ b/Documentation/Intel-IOMMU.txt @@ -48,7 +48,7 @@ IOVA generation is pretty generic. We used the same technique as vmalloc() but these are not global address spaces, but separate for each domain. Different DMA engines may support different number of domains. -We also allocate gaurd pages with each mapping, so we can attempt to catch +We also allocate guard pages with each mapping, so we can attempt to catch any overflow that might happen. @@ -112,4 +112,4 @@ TBD - For compatibility testing, could use unity map domain for all devices, just provide a 1-1 for all useful memory under a single domain for all devices. -- API for paravirt ops for abstracting functionlity for VMM folks. +- API for paravirt ops for abstracting functionality for VMM folks. diff --git a/Documentation/accounting/taskstats-struct.txt b/Documentation/accounting/taskstats-struct.txt index b988d110db59..e7512c061c15 100644 --- a/Documentation/accounting/taskstats-struct.txt +++ b/Documentation/accounting/taskstats-struct.txt @@ -6,7 +6,7 @@ This document contains an explanation of the struct taskstats fields. There are three different groups of fields in the struct taskstats: 1) Common and basic accounting fields - If CONFIG_TASKSTATS is set, the taskstats inteface is enabled and + If CONFIG_TASKSTATS is set, the taskstats interface is enabled and the common fields and basic accounting fields are collected for delivery at do_exit() of a task. 2) Delay accounting fields diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt index dcec0564d040..5b0cfa67aff9 100644 --- a/Documentation/cpu-freq/governors.txt +++ b/Documentation/cpu-freq/governors.txt @@ -122,7 +122,7 @@ around '10000' or more. show_sampling_rate_(min|max): the minimum and maximum sampling rates available that you may set 'sampling_rate' to. -up_threshold: defines what the average CPU usaged between the samplings +up_threshold: defines what the average CPU usage between the samplings of 'sampling_rate' needs to be for the kernel to make a decision on whether it should increase the frequency. For example when it is set to its default value of '80' it means that between the checking diff --git a/Documentation/edac.txt b/Documentation/edac.txt index ced527388001..8eda3fb66416 100644 --- a/Documentation/edac.txt +++ b/Documentation/edac.txt @@ -327,7 +327,7 @@ Sdram memory scrubbing rate: 'sdram_scrub_rate' Read/Write attribute file that controls memory scrubbing. The scrubbing - rate is set by writing a minimum bandwith in bytes/sec to the attribute + rate is set by writing a minimum bandwidth in bytes/sec to the attribute file. The rate will be translated to an internal value that gives at least the specified rate. diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 8c6384bdfed4..64557821ee59 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -931,7 +931,7 @@ group_prealloc max_to_scan mb_groups mb_history min_to_scan order2_req stats stream_req mb_groups: -This file gives the details of mutiblock allocator buddy cache of free blocks +This file gives the details of multiblock allocator buddy cache of free blocks mb_history: Multiblock allocation history. @@ -1474,7 +1474,7 @@ used because pages_free(1355) is smaller than watermark + protection[2] normal page requirement. If requirement is DMA zone(index=0), protection[0] (=0) is used. -zone[i]'s protection[j] is calculated by following exprssion. +zone[i]'s protection[j] is calculated by following expression. (i < j): zone[i]->protection[j] diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index b7522c6cbae3..c4d348dabe94 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -143,7 +143,7 @@ struct file_system_type { The get_sb() method has the following arguments: - struct file_system_type *fs_type: decribes the filesystem, partly initialized + struct file_system_type *fs_type: describes the filesystem, partly initialized by the specific filesystem code int flags: mount flags @@ -895,9 +895,9 @@ struct dentry_operations { iput() yourself d_dname: called when the pathname of a dentry should be generated. - Usefull for some pseudo filesystems (sockfs, pipefs, ...) to delay + Useful for some pseudo filesystems (sockfs, pipefs, ...) to delay pathname generation. (Instead of doing it when dentry is created, - its done only when the path is needed.). Real filesystems probably + it's done only when the path is needed.). Real filesystems probably dont want to use it, because their dentries are present in global dcache hash, so their hash should be an invariant. As no lock is held, d_dname() should not try to modify the dentry itself, unless diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt index bec9d815da33..914d07f49268 100644 --- a/Documentation/ia64/kvm.txt +++ b/Documentation/ia64/kvm.txt @@ -50,9 +50,9 @@ Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qe /usr/local/bin/qemu-system-ia64 -smp xx -m 512 -hda $your_image (xx is the number of virtual processors for the guest, now the maximum value is 4) -5. Known possibile issue on some platforms with old Firmware. +5. Known possible issue on some platforms with old Firmware. -If meet strange host crashe issues, try to solve it through either of the following ways: +In the event of strange host crash issues, try to solve it through either of the following ways: (1): Upgrade your Firmware to the latest one. @@ -65,8 +65,8 @@ index 0b53344..f02b0f7 100644 mov ar.pfs = loc1 mov rp = loc0 ;; -- srlz.d // seralize restoration of psr.l -+ srlz.i // seralize restoration of psr.l +- srlz.d // serialize restoration of psr.l ++ srlz.i // serialize restoration of psr.l + ;; br.ret.sptk.many b0 END(ia64_pal_call_static) diff --git a/Documentation/input/cs461x.txt b/Documentation/input/cs461x.txt index afe0d6543e09..202e9dbacec3 100644 --- a/Documentation/input/cs461x.txt +++ b/Documentation/input/cs461x.txt @@ -31,7 +31,7 @@ The driver works with ALSA drivers simultaneously. For example, the xracer uses joystick as input device and PCM device as sound output in one time. There are no sound or input collisions detected. The source code have comments about them; but I've found the joystick can be initialized -separately of ALSA modules. So, you canm use only one joystick driver +separately of ALSA modules. So, you can use only one joystick driver without ALSA drivers. The ALSA drivers are not needed to compile or run this driver. diff --git a/Documentation/ioctl/ioctl-decoding.txt b/Documentation/ioctl/ioctl-decoding.txt index bfdf7f3ee4f0..e35efb0cec2e 100644 --- a/Documentation/ioctl/ioctl-decoding.txt +++ b/Documentation/ioctl/ioctl-decoding.txt @@ -1,6 +1,6 @@ To decode a hex IOCTL code: -Most architecures use this generic format, but check +Most architectures use this generic format, but check include/ARCH/ioctl.h for specifics, e.g. powerpc uses 3 bits to encode read/write and 13 bits for size. @@ -18,7 +18,7 @@ uses 3 bits to encode read/write and 13 bits for size. 7-0 function # - So for example 0x82187201 is a read with arg length of 0x218, +So for example 0x82187201 is a read with arg length of 0x218, character 'r' function 1. Grepping the source reveals this is: #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) diff --git a/Documentation/iostats.txt b/Documentation/iostats.txt index 5925c3cd030d..59a69ec67c40 100644 --- a/Documentation/iostats.txt +++ b/Documentation/iostats.txt @@ -143,7 +143,7 @@ disk and partition statistics are consistent again. Since we still don't keep record of the partition-relative address, an operation is attributed to the partition which contains the first sector of the request after the eventual merges. As requests can be merged across partition, this could lead -to some (probably insignificant) innacuracy. +to some (probably insignificant) inaccuracy. Additional notes ---------------- diff --git a/Documentation/keys.txt b/Documentation/keys.txt index d5c7a57d1700..b56aacc1fff8 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt @@ -864,7 +864,7 @@ payload contents" for more information. request_key_with_auxdata() respectively. These two functions return with the key potentially still under - construction. To wait for contruction completion, the following should be + construction. To wait for construction completion, the following should be called: int wait_for_key_construction(struct key *key, bool intr); diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt index 18860ad9935a..6399557cdab3 100644 --- a/Documentation/leds-class.txt +++ b/Documentation/leds-class.txt @@ -59,7 +59,7 @@ Hardware accelerated blink of LEDs Some LEDs can be programmed to blink without any CPU interaction. To support this feature, a LED driver can optionally implement the -blink_set() function (see ). If implemeted, triggers can +blink_set() function (see ). If implemented, triggers can attempt to use it before falling back to software timers. The blink_set() function should return 0 if the blink setting is supported, or -EINVAL otherwise, which means that LED blinking will be handled by software. diff --git a/Documentation/local_ops.txt b/Documentation/local_ops.txt index 4269a1105b37..f4f8b1c6c8ba 100644 --- a/Documentation/local_ops.txt +++ b/Documentation/local_ops.txt @@ -36,7 +36,7 @@ It can be done by slightly modifying the standard atomic operations : only their UP variant must be kept. It typically means removing LOCK prefix (on i386 and x86_64) and any SMP sychronization barrier. If the architecture does not have a different behavior between SMP and UP, including asm-generic/local.h -in your archtecture's local.h is sufficient. +in your architecture's local.h is sufficient. The local_t type is defined as an opaque signed long by embedding an atomic_long_t inside a structure. This is made so a cast from this type to a diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 7fa7fe71d7a8..688dfe1e6b70 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -631,7 +631,7 @@ xmit_hash_policy in environments where a layer3 gateway device is required to reach most destinations. - This algorithm is 802.3ad complient. + This algorithm is 802.3ad compliant. layer3+4 diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index 641d2afacffa..297ba7b1ccaf 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -186,7 +186,7 @@ solution for a couple of reasons: The Linux network devices (by default) just can handle the transmission and reception of media dependent frames. Due to the - arbritration on the CAN bus the transmission of a low prio CAN-ID + arbitration on the CAN bus the transmission of a low prio CAN-ID may be delayed by the reception of a high prio CAN frame. To reflect the correct* traffic on the node the loopback of the sent data has to be performed right after a successful transmission. If @@ -481,7 +481,7 @@ solution for a couple of reasons: - stats_timer: To calculate the Socket CAN core statistics (e.g. current/maximum frames per second) this 1 second timer is invoked at can.ko module start time by default. This timer can be - disabled by using stattimer=0 on the module comandline. + disabled by using stattimer=0 on the module commandline. - debug: (removed since SocketCAN SVN r546) diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt index db0cd5169581..07c53d596035 100644 --- a/Documentation/networking/packet_mmap.txt +++ b/Documentation/networking/packet_mmap.txt @@ -326,7 +326,7 @@ just one call to mmap is needed: mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); If tp_frame_size is a divisor of tp_block_size frames will be -contiguosly spaced by tp_frame_size bytes. If not, each +contiguously spaced by tp_frame_size bytes. If not, each tp_block_size/tp_frame_size frames there will be a gap between the frames. This is because a frame cannot be spawn across two blocks. diff --git a/Documentation/networking/tc-actions-env-rules.txt b/Documentation/networking/tc-actions-env-rules.txt index 01e716d185f4..dcadf6f88e34 100644 --- a/Documentation/networking/tc-actions-env-rules.txt +++ b/Documentation/networking/tc-actions-env-rules.txt @@ -4,26 +4,27 @@ The "enviromental" rules for authors of any new tc actions are: 1) If you stealeth or borroweth any packet thou shalt be branching from the righteous path and thou shalt cloneth. -For example if your action queues a packet to be processed later -or intentionaly branches by redirecting a packet then you need to +For example if your action queues a packet to be processed later, +or intentionally branches by redirecting a packet, then you need to clone the packet. + There are certain fields in the skb tc_verd that need to be reset so we -avoid loops etc. A few are generic enough so much so that skb_act_clone() -resets them for you. So invoke skb_act_clone() rather than skb_clone() +avoid loops, etc. A few are generic enough that skb_act_clone() +resets them for you, so invoke skb_act_clone() rather than skb_clone(). 2) If you munge any packet thou shalt call pskb_expand_head in the case someone else is referencing the skb. After that you "own" the skb. You must also tell us if it is ok to munge the packet (TC_OK2MUNGE), this way any action downstream can stomp on the packet. -3) dropping packets you dont own is a nono. You simply return +3) Dropping packets you don't own is a no-no. You simply return TC_ACT_SHOT to the caller and they will drop it. The "enviromental" rules for callers of actions (qdiscs etc) are: -*) thou art responsible for freeing anything returned as being +*) Thou art responsible for freeing anything returned as being TC_ACT_SHOT/STOLEN/QUEUED. If none of TC_ACT_SHOT/STOLEN/QUEUED is -returned then all is great and you dont need to do anything. +returned, then all is great and you don't need to do anything. Post on netdev if something is unclear. diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 99514ced82c5..928a79ceb7aa 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -708,7 +708,7 @@ device or bus to be described by the device tree. In general, the format of an address for a device is defined by the parent bus type, based on the #address-cells and #size-cells properties. Note that the parent's parent definitions of #address-cells -and #size-cells are not inhereted so every node with children must specify +and #size-cells are not inherited so every node with children must specify them. The kernel requires the root node to have those properties defining addresses format for devices directly mapped on the processor bus. @@ -1777,7 +1777,7 @@ platforms are moved over to use the flattened-device-tree model. Xilinx uartlite devices are simple fixed speed serial ports. - Requred properties: + Required properties: - current-speed : Baud rate of uartlite v) Xilinx hwicap @@ -1799,7 +1799,7 @@ platforms are moved over to use the flattened-device-tree model. Xilinx UART 16550 devices are very similar to the NS16550 but with different register spacing and an offset from the base address. - Requred properties: + Required properties: - clock-frequency : Frequency of the clock input - reg-offset : A value of 3 is required - reg-shift : A value of 2 is required @@ -1953,7 +1953,7 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. 1) The /system-controller node This node is used to represent the system-controller and must be - present when the system uses a system contller chip. The top-level + present when the system uses a system controller chip. The top-level system-controller node contains information that is global to all devices within the system controller chip. The node name begins with "system-controller" followed by the unit address, which is diff --git a/Documentation/powerpc/qe_firmware.txt b/Documentation/powerpc/qe_firmware.txt index 896266432d33..06da4d4b44f9 100644 --- a/Documentation/powerpc/qe_firmware.txt +++ b/Documentation/powerpc/qe_firmware.txt @@ -217,7 +217,7 @@ Although it is not recommended, you can specify '0' in the soc.model field to skip matching SOCs altogether. The 'model' field is a 16-bit number that matches the actual SOC. The -'major' and 'minor' fields are the major and minor revision numbrs, +'major' and 'minor' fields are the major and minor revision numbers, respectively, of the SOC. For example, to match the 8323, revision 1.0: diff --git a/Documentation/s390/driver-model.txt b/Documentation/s390/driver-model.txt index e938c442277d..bde473df748d 100644 --- a/Documentation/s390/driver-model.txt +++ b/Documentation/s390/driver-model.txt @@ -25,7 +25,7 @@ device 4711 via subchannel 1 in subchannel set 0, and subchannel 2 is a non-I/O subchannel. Device 1234 is accessed via subchannel 0 in subchannel set 1. The subchannel named 'defunct' does not represent any real subchannel on the -system; it is a pseudo subchannel where disconnnected ccw devices are moved to +system; it is a pseudo subchannel where disconnected ccw devices are moved to if they are displaced by another ccw device becoming operational on their former subchannel. The ccw devices will be moved again to a proper subchannel if they become operational again on that subchannel. diff --git a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt index a810421f1fb3..3920f28710c4 100644 --- a/Documentation/scsi/ibmmca.txt +++ b/Documentation/scsi/ibmmca.txt @@ -524,7 +524,7 @@ - Michael Lang June 25 1997: (v1.8b) - 1) Some cosmetical changes for the handling of SCSI-device-types. + 1) Some cosmetic changes for the handling of SCSI-device-types. Now, also CD-Burners / WORMs and SCSI-scanners should work. For MO-drives I have no experience, therefore not yet supported. In logical_devices I changed from different type-variables to one @@ -914,7 +914,7 @@ in version 4.0. This was never really necessary, as all troubles were based on non-command related reasons up to now, so bypassing commands did not help to avoid any bugs. It is kept in 3.2X for debugging reasons. - 5) Dynamical reassignment of ldns was again verified and analyzed to be + 5) Dynamic reassignment of ldns was again verified and analyzed to be completely inoperational. This is corrected and should work now. 6) All commands that get sent to the SCSI adapter were verified and completed in such a way, that they are now completely conform to the @@ -1386,7 +1386,7 @@ concerning the Linux-kernel in special, this SCSI-driver comes without any warranty. Its functionality is tested as good as possible on certain machines and combinations of computer hardware, which does not exclude, - that dataloss or severe damage of hardware is possible while using this + that data loss or severe damage of hardware is possible while using this part of software on some arbitrary computer hardware or in combination with other software packages. It is highly recommended to make backup copies of your data before using this software. Furthermore, personal diff --git a/Documentation/scsi/lpfc.txt b/Documentation/scsi/lpfc.txt index 4dbe41370a6d..5741ea8aa88a 100644 --- a/Documentation/scsi/lpfc.txt +++ b/Documentation/scsi/lpfc.txt @@ -36,7 +36,7 @@ Cable pull and temporary device Loss: being removed, a switch rebooting, or a device reboot), the driver could hide the disappearance of the device from the midlayer. I/O's issued to the LLDD would simply be queued for a short duration, allowing the device - to reappear or link come back alive, with no inadvertant side effects + to reappear or link come back alive, with no inadvertent side effects to the system. If the driver did not hide these conditions, i/o would be errored by the driver, the mid-layer would exhaust its retries, and the device would be taken offline. Manual intervention would be required to diff --git a/Documentation/scsi/scsi_fc_transport.txt b/Documentation/scsi/scsi_fc_transport.txt index d403e46d8463..75143f0c23b6 100644 --- a/Documentation/scsi/scsi_fc_transport.txt +++ b/Documentation/scsi/scsi_fc_transport.txt @@ -65,7 +65,7 @@ Overview: discussion will concentrate on NPIV. Note: World Wide Name assignment (and uniqueness guarantees) are left - up to an administrative entity controling the vport. For example, + up to an administrative entity controlling the vport. For example, if vports are to be associated with virtual machines, a XEN mgmt utility would be responsible for creating wwpn/wwnn's for the vport, using it's own naming authority and OUI. (Note: it already does this @@ -91,7 +91,7 @@ Device Trees and Vport Objects: Here's what to expect in the device tree : The typical Physical Port's Scsi_Host: /sys/devices/.../host17/ - and it has the typical decendent tree: + and it has the typical descendant tree: /sys/devices/.../host17/rport-17:0-0/target17:0:0/17:0:0:0: and then the vport is created on the Physical Port: /sys/devices/.../host17/vport-17:0-0 @@ -192,7 +192,7 @@ Vport States: independent of the adapter's link state. - Instantiation of the vport on the FC link via ELS traffic, etc. This is equivalent to a "link up" and successfull link initialization. - Futher information can be found in the interfaces section below for + Further information can be found in the interfaces section below for Vport Creation. Once a vport has been instantiated with the kernel/LLDD, a vport state diff --git a/Documentation/sh/clk.txt b/Documentation/sh/clk.txt index 9aef710e9a4b..114b595cfa97 100644 --- a/Documentation/sh/clk.txt +++ b/Documentation/sh/clk.txt @@ -12,7 +12,7 @@ means no changes to adjanced clock Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method, if it is present in ops structure. The method should set the clock rate and adjust all needed clocks according to the passed algo_id. -Exact values for algo_id are machine-dependend. For the sh7722, the following +Exact values for algo_id are machine-dependent. For the sh7722, the following values are defined: NO_CHANGE = 0, diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt index 2ad5e6306c44..a4c53d8961e1 100644 --- a/Documentation/sound/alsa/Audiophile-Usb.txt +++ b/Documentation/sound/alsa/Audiophile-Usb.txt @@ -236,15 +236,15 @@ The parameter can be given: alias snd-card-1 snd-usb-audio options snd-usb-audio index=1 device_setup=0x09 -CAUTION when initializaing the device +CAUTION when initializing the device ------------------------------------- * Correct initialization on the device requires that device_setup is given to the module BEFORE the device is turned on. So, if you use the "manual probing" method described above, take care to power-on the device AFTER this initialization. - * Failing to respect this will lead in a misconfiguration of the device. In this case - turn off the device, unproble the snd-usb-audio module, then probe it again with + * Failing to respect this will lead to a misconfiguration of the device. In this case + turn off the device, unprobe the snd-usb-audio module, then probe it again with correct device_setup parameter and then (and only then) turn on the device again. * If you've correctly initialized the device in a valid mode and then want to switch @@ -388,9 +388,9 @@ There are 2 main potential issues when using Jackd with the device: Jack supports big endian devices only in recent versions (thanks to Andreas Steinmetz for his first big-endian patch). I can't remember -extacly when this support was released into jackd, let's just say that +exactly when this support was released into jackd, let's just say that with jackd version 0.103.0 it's almost ok (just a small bug is affecting -16bits Big-Endian devices, but since you've read carefully the above +16bits Big-Endian devices, but since you've read carefully the above paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices are now Little Endians ;-) ). diff --git a/Documentation/sound/alsa/hda_codec.txt b/Documentation/sound/alsa/hda_codec.txt index 8e1b02526698..34e87ec1379c 100644 --- a/Documentation/sound/alsa/hda_codec.txt +++ b/Documentation/sound/alsa/hda_codec.txt @@ -67,7 +67,7 @@ CONFIG_SND_HDA_POWER_SAVE kconfig. It's called when the codec needs to power up or may power down. The controller should check the all belonging codecs on the bus whether they are actually powered off (check codec->power_on), and optionally the driver may power down the -contoller side, too. +controller side, too. The bus instance is created via snd_hda_bus_new(). You need to pass the card instance, the template, and the pointer to store the diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt index c784a18b94dc..b2ed6983f40d 100644 --- a/Documentation/sound/alsa/soc/dapm.txt +++ b/Documentation/sound/alsa/soc/dapm.txt @@ -68,7 +68,7 @@ Audio DAPM widgets fall into a number of types:- (Widgets are defined in include/sound/soc-dapm.h) Widgets are usually added in the codec driver and the machine driver. There are -convience macros defined in soc-dapm.h that can be used to quickly build a +convenience macros defined in soc-dapm.h that can be used to quickly build a list of widgets of the codecs and machines DAPM widgets. Most widgets have a name, register, shift and invert. Some widgets have extra diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 8a4863c4edd4..d79eeda7a699 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -116,7 +116,7 @@ of kilobytes free. The VM uses this number to compute a pages_min value for each lowmem zone in the system. Each lowmem zone gets a number of reserved free pages based proportionally on its size. -Some minimal ammount of memory is needed to satisfy PF_MEMALLOC +Some minimal amount of memory is needed to satisfy PF_MEMALLOC allocations; if you set this to lower than 1024KB, your system will become subtly broken, and prone to deadlock under high loads. diff --git a/Documentation/timers/highres.txt b/Documentation/timers/highres.txt index a73ecf5b4bdb..21332233cef1 100644 --- a/Documentation/timers/highres.txt +++ b/Documentation/timers/highres.txt @@ -125,7 +125,7 @@ increase of flexibility and the avoidance of duplicated code across architectures justifies the slight increase of the binary size. The conversion of an architecture has no functional impact, but allows to -utilize the high resolution and dynamic tick functionalites without any change +utilize the high resolution and dynamic tick functionalities without any change to the clock event device and timer interrupt code. After the conversion the enabling of high resolution timers and dynamic ticks is simply provided by adding the kernel/time/Kconfig file to the architecture specific Kconfig and diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt index 2af400609498..381b22ee7834 100644 --- a/Documentation/usb/authorization.txt +++ b/Documentation/usb/authorization.txt @@ -8,7 +8,7 @@ not) in a system. This feature will allow you to implement a lock-down of USB devices, fully controlled by user space. As of now, when a USB device is connected it is configured and -it's interfaces inmediately made available to the users. With this +its interfaces are immediately made available to the users. With this modification, only if root authorizes the device to be configured will then it be possible to use it. diff --git a/Documentation/video4linux/sn9c102.txt b/Documentation/video4linux/sn9c102.txt index b26f5195af51..73de4050d637 100644 --- a/Documentation/video4linux/sn9c102.txt +++ b/Documentation/video4linux/sn9c102.txt @@ -157,7 +157,7 @@ Loading can be done as shown below: [root@localhost home]# modprobe sn9c102 -Note that the module is called "sn9c102" for historic reasons, althought it +Note that the module is called "sn9c102" for historic reasons, although it does not just support the SN9C102. At this point all the devices supported by the driver and connected to the USB diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index 8a5b5763f0fe..ea8714fcc3ad 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt @@ -77,7 +77,7 @@ memory that is preset in system at this time. System administrators may want to put this command in one of the local rc init files. This will enable the kernel to request huge pages early in the boot process (when the possibility of getting physical contiguous pages is still very high). In either -case, adminstrators will want to verify the number of hugepages actually +case, administrators will want to verify the number of hugepages actually allocated by checking the sysctl or meminfo. /proc/sys/vm/nr_overcommit_hugepages indicates how large the pool of diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt index bad16d3f6a47..6aaaeb38730c 100644 --- a/Documentation/vm/numa_memory_policy.txt +++ b/Documentation/vm/numa_memory_policy.txt @@ -58,7 +58,7 @@ most general to most specific: the policy at the time they were allocated. VMA Policy: A "VMA" or "Virtual Memory Area" refers to a range of a task's - virtual adddress space. A task may define a specific policy for a range + virtual address space. A task may define a specific policy for a range of its virtual address space. See the MEMORY POLICIES APIS section, below, for an overview of the mbind() system call used to set a VMA policy. @@ -353,7 +353,7 @@ follows: Because of this extra reference counting, and because we must lookup shared policies in a tree structure under spinlock, shared policies are - more expensive to use in the page allocation path. This is expecially + more expensive to use in the page allocation path. This is especially true for shared policies on shared memory regions shared by tasks running on different NUMA nodes. This extra overhead can be avoided by always falling back to task or system default policy for shared memory regions, diff --git a/Documentation/volatile-considered-harmful.txt b/Documentation/volatile-considered-harmful.txt index 10c2e411cca8..991c26a6ef64 100644 --- a/Documentation/volatile-considered-harmful.txt +++ b/Documentation/volatile-considered-harmful.txt @@ -114,6 +114,6 @@ CREDITS Original impetus and research by Randy Dunlap Written by Jonathan Corbet -Improvements via coments from Satyam Sharma, Johannes Stezenbach, Jesper +Improvements via comments from Satyam Sharma, Johannes Stezenbach, Jesper Juhl, Heikki Orsila, H. Peter Anvin, Philipp Hahn, and Stefan Richter. diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index 241592ab13ad..3f15fcfe4a2e 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt @@ -127,7 +127,7 @@ mpi_ioc.h * 08-08-01 01.02.01 Original release for v1.2 work. * New format for FWVersion and ProductId in * MSG_IOC_FACTS_REPLY and MPI_FW_HEADER. - * 08-31-01 01.02.02 Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and + * 08-31-01 01.02.02 Added event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and * related structure and defines. * Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED. * Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE. @@ -187,7 +187,7 @@ mpi_ioc.h * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED. * Added MaxInitiators field to PortFacts reply. * Added SAS Device Status Change ReasonCode for - * asynchronous notificaiton. + * asynchronous notification. * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event * data structure. * Added new ImageType values for FWDownload and FWUpload @@ -213,7 +213,7 @@ mpi_cnfg.h * Added _RESPONSE_ID_MASK definition to SCSI_PORT_1 * page and updated the page version. * Added Information field and _INFO_PARAMS_NEGOTIATED - * definitionto SCSI_DEVICE_0 page. + * definition to SCSI_DEVICE_0 page. * 06-22-00 01.00.03 Removed batch controls from LAN_0 page and updated the * page version. * Added BucketsRemaining to LAN_1 page, redefined the From 51cc50685a4275c6a02653670af9f108a64e01cf Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 25 Jul 2008 19:45:34 -0700 Subject: [PATCH 109/179] SL*B: drop kmem cache argument from constructor Kmem cache passed to constructor is only needed for constructors that are themselves multiplexeres. Nobody uses this "feature", nor does anybody uses passed kmem cache in non-trivial way, so pass only pointer to object. Non-trivial places are: arch/powerpc/mm/init_64.c arch/powerpc/mm/hugetlbpage.c This is flag day, yes. Signed-off-by: Alexey Dobriyan Acked-by: Pekka Enberg Acked-by: Christoph Lameter Cc: Jon Tollefson Cc: Nick Piggin Cc: Matt Mackall [akpm@linux-foundation.org: fix arch/powerpc/mm/hugetlbpage.c] [akpm@linux-foundation.org: fix mm/slab.c] [akpm@linux-foundation.org: fix ubifs] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/plat-s3c24xx/dma.c | 2 +- arch/powerpc/kernel/rtas_flash.c | 2 +- arch/powerpc/mm/hugetlbpage.c | 9 ++------- arch/powerpc/mm/init_64.c | 24 +++++++++-------------- arch/powerpc/platforms/cell/spufs/inode.c | 2 +- arch/sh/mm/pmb.c | 2 +- arch/xtensa/mm/init.c | 2 +- drivers/usb/mon/mon_text.c | 4 ++-- fs/adfs/super.c | 2 +- fs/affs/super.c | 2 +- fs/afs/super.c | 4 ++-- fs/befs/linuxvfs.c | 2 +- fs/bfs/inode.c | 2 +- fs/block_dev.c | 2 +- fs/buffer.c | 2 +- fs/cifs/cifsfs.c | 2 +- fs/coda/inode.c | 2 +- fs/ecryptfs/main.c | 4 ++-- fs/efs/super.c | 2 +- fs/ext2/super.c | 2 +- fs/ext3/super.c | 2 +- fs/ext4/super.c | 2 +- fs/fat/cache.c | 2 +- fs/fat/inode.c | 2 +- fs/fuse/inode.c | 2 +- fs/gfs2/main.c | 4 ++-- fs/hfs/super.c | 2 +- fs/hfsplus/super.c | 2 +- fs/hpfs/super.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/inode.c | 2 +- fs/isofs/inode.c | 2 +- fs/jffs2/super.c | 2 +- fs/jfs/jfs_metapage.c | 2 +- fs/jfs/super.c | 2 +- fs/locks.c | 2 +- fs/minix/inode.c | 2 +- fs/ncpfs/inode.c | 2 +- fs/nfs/inode.c | 2 +- fs/ntfs/super.c | 2 +- fs/ocfs2/dlm/dlmfs.c | 3 +-- fs/ocfs2/super.c | 2 +- fs/openpromfs/inode.c | 2 +- fs/proc/inode.c | 2 +- fs/qnx4/inode.c | 2 +- fs/reiserfs/super.c | 2 +- fs/romfs/inode.c | 2 +- fs/smbfs/inode.c | 2 +- fs/sysv/inode.c | 2 +- fs/ubifs/super.c | 2 +- fs/udf/super.c | 2 +- fs/ufs/super.c | 2 +- fs/xfs/linux-2.6/kmem.h | 2 +- fs/xfs/linux-2.6/xfs_super.c | 1 - include/linux/slab.h | 2 +- include/linux/slub_def.h | 2 +- ipc/mqueue.c | 2 +- kernel/fork.c | 2 +- lib/idr.c | 2 +- lib/radix-tree.c | 2 +- mm/rmap.c | 2 +- mm/shmem.c | 2 +- mm/slab.c | 11 +++++------ mm/slob.c | 7 +++---- mm/slub.c | 13 ++++++------ net/socket.c | 2 +- net/sunrpc/rpc_pipe.c | 2 +- 67 files changed, 90 insertions(+), 106 deletions(-) diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 60f162dc4fad..8c5e656d5d8c 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -1304,7 +1304,7 @@ struct sysdev_class dma_sysclass = { /* kmem cache implementation */ -static void s3c2410_dma_cache_ctor(struct kmem_cache *c, void *p) +static void s3c2410_dma_cache_ctor(void *p) { memset(p, 0, sizeof(struct s3c2410_dma_buf)); } diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 09ded5c424a9..149cb112cd1a 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -286,7 +286,7 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, } /* constructor for flash_block_cache */ -void rtas_block_ctor(struct kmem_cache *cache, void *ptr) +void rtas_block_ctor(void *ptr) { memset(ptr, 0, RTAS_BLK_SIZE); } diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index fb42c4dd3217..ed0aab0208a6 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -113,7 +113,7 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, unsigned long address, unsigned int psize) { - pte_t *new = kmem_cache_alloc(huge_pgtable_cache(psize), + pte_t *new = kmem_cache_zalloc(huge_pgtable_cache(psize), GFP_KERNEL|__GFP_REPEAT); if (! new) @@ -730,11 +730,6 @@ static int __init hugepage_setup_sz(char *str) } __setup("hugepagesz=", hugepage_setup_sz); -static void zero_ctor(struct kmem_cache *cache, void *addr) -{ - memset(addr, 0, kmem_cache_size(cache)); -} - static int __init hugetlbpage_init(void) { unsigned int psize; @@ -756,7 +751,7 @@ static int __init hugetlbpage_init(void) HUGEPTE_TABLE_SIZE(psize), HUGEPTE_TABLE_SIZE(psize), 0, - zero_ctor); + NULL); if (!huge_pgtable_cache(psize)) panic("hugetlbpage_init(): could not create %s"\ "\n", HUGEPTE_CACHE_NAME(psize)); diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index a41bc5aa2043..4f7df85129d8 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -136,9 +136,14 @@ static int __init setup_kcore(void) module_init(setup_kcore); #endif -static void zero_ctor(struct kmem_cache *cache, void *addr) +static void pgd_ctor(void *addr) { - memset(addr, 0, kmem_cache_size(cache)); + memset(addr, 0, PGD_TABLE_SIZE); +} + +static void pmd_ctor(void *addr) +{ + memset(addr, 0, PMD_TABLE_SIZE); } static const unsigned int pgtable_cache_size[2] = { @@ -163,19 +168,8 @@ struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; void pgtable_cache_init(void) { - int i; - - for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) { - int size = pgtable_cache_size[i]; - const char *name = pgtable_cache_name[i]; - - pr_debug("Allocating page table cache %s (#%d) " - "for size: %08x...\n", name, i, size); - pgtable_cache[i] = kmem_cache_create(name, - size, size, - SLAB_PANIC, - zero_ctor); - } + pgtable_cache[0] = kmem_cache_create(pgtable_cache_name[0], PGD_TABLE_SIZE, PGD_TABLE_SIZE, SLAB_PANIC, pgd_ctor); + pgtable_cache[1] = kmem_cache_create(pgtable_cache_name[1], PMD_TABLE_SIZE, PMD_TABLE_SIZE, SLAB_PANIC, pmd_ctor); } #ifdef CONFIG_SPARSEMEM_VMEMMAP diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 7123472801d9..690ca7b0dcf6 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -78,7 +78,7 @@ spufs_destroy_inode(struct inode *inode) } static void -spufs_init_once(struct kmem_cache *cachep, void *p) +spufs_init_once(void *p) { struct spufs_inode_info *ei = p; diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 0b0ec6e04753..46911bcbf17b 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -293,7 +293,7 @@ void pmb_unmap(unsigned long addr) } while (pmbe); } -static void pmb_cache_ctor(struct kmem_cache *cachep, void *pmb) +static void pmb_cache_ctor(void *pmb) { struct pmb_entry *pmbe = pmb; diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 81d0560eaea2..ee261005b363 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -309,7 +309,7 @@ void show_mem(void) struct kmem_cache *pgtable_cache __read_mostly; -static void pgd_ctor(struct kmem_cache *cache, void* addr) +static void pgd_ctor(void* addr) { pte_t* ptep = (pte_t*)addr; int i; diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 5e3e4e9b6c77..1f715436d6d3 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -87,7 +87,7 @@ struct mon_reader_text { static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */ -static void mon_text_ctor(struct kmem_cache *, void *); +static void mon_text_ctor(void *); struct mon_text_ptr { int cnt, limit; @@ -720,7 +720,7 @@ void mon_text_del(struct mon_bus *mbus) /* * Slab interface: constructor. */ -static void mon_text_ctor(struct kmem_cache *slab, void *mem) +static void mon_text_ctor(void *mem) { /* * Nothing to initialize. No, really! diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 9e421eeb672b..26f3b43726bb 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -249,7 +249,7 @@ static void adfs_destroy_inode(struct inode *inode) kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; diff --git a/fs/affs/super.c b/fs/affs/super.c index 4e0309566406..3a89094f93d0 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -90,7 +90,7 @@ static void affs_destroy_inode(struct inode *inode) kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct affs_inode_info *ei = (struct affs_inode_info *) foo; diff --git a/fs/afs/super.c b/fs/afs/super.c index 7e3faeef6818..250d8c4d66e4 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -27,7 +27,7 @@ #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ -static void afs_i_init_once(struct kmem_cache *cachep, void *foo); +static void afs_i_init_once(void *foo); static int afs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt); @@ -449,7 +449,7 @@ static void afs_put_super(struct super_block *sb) /* * initialise an inode cache slab element prior to any use */ -static void afs_i_init_once(struct kmem_cache *cachep, void *_vnode) +static void afs_i_init_once(void *_vnode) { struct afs_vnode *vnode = _vnode; diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index e8717de3bab3..02c6e62b72f8 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -289,7 +289,7 @@ befs_destroy_inode(struct inode *inode) kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct befs_inode_info *bi = (struct befs_inode_info *) foo; diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 053e690ec9ed..0ed57b5ee012 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -264,7 +264,7 @@ static void bfs_destroy_inode(struct inode *inode) kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct bfs_inode_info *bi = foo; diff --git a/fs/block_dev.c b/fs/block_dev.c index 10d8a0aa871a..dcf37cada369 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -271,7 +271,7 @@ static void bdev_destroy_inode(struct inode *inode) kmem_cache_free(bdev_cachep, bdi); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct bdev_inode *ei = (struct bdev_inode *) foo; struct block_device *bdev = &ei->bdev; diff --git a/fs/buffer.c b/fs/buffer.c index 109b261192d9..5fd497cdd6f3 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3272,7 +3272,7 @@ int bh_submit_read(struct buffer_head *bh) EXPORT_SYMBOL(bh_submit_read); static void -init_buffer_head(struct kmem_cache *cachep, void *data) +init_buffer_head(void *data) { struct buffer_head *bh = data; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 22857c639df5..fe5f6809cba6 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -766,7 +766,7 @@ const struct file_operations cifs_dir_ops = { }; static void -cifs_init_once(struct kmem_cache *cachep, void *inode) +cifs_init_once(void *inode) { struct cifsInodeInfo *cifsi = inode; diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 2f58dfc70083..830f51abb971 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -58,7 +58,7 @@ static void coda_destroy_inode(struct inode *inode) kmem_cache_free(coda_inode_cachep, ITOC(inode)); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct coda_inode_info *ei = (struct coda_inode_info *) foo; diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 6f403cfba14f..448dfd597b5f 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -578,7 +578,7 @@ static struct file_system_type ecryptfs_fs_type = { * Initializes the ecryptfs_inode_info_cache when it is created */ static void -inode_info_init_once(struct kmem_cache *cachep, void *vptr) +inode_info_init_once(void *vptr) { struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; @@ -589,7 +589,7 @@ static struct ecryptfs_cache_info { struct kmem_cache **cache; const char *name; size_t size; - void (*ctor)(struct kmem_cache *cache, void *obj); + void (*ctor)(void *obj); } ecryptfs_cache_infos[] = { { .cache = &ecryptfs_auth_tok_list_item_cache, diff --git a/fs/efs/super.c b/fs/efs/super.c index d733531b55e2..567b134fa1f1 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -70,7 +70,7 @@ static void efs_destroy_inode(struct inode *inode) kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct efs_inode_info *ei = (struct efs_inode_info *) foo; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 31308a3b0b8b..fd88c7b43e66 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -159,7 +159,7 @@ static void ext2_destroy_inode(struct inode *inode) kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 615788c6843a..8ddced384674 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -472,7 +472,7 @@ static void ext3_destroy_inode(struct inode *inode) kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1cb371dcd609..b5479b1dff14 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -595,7 +595,7 @@ static void ext4_destroy_inode(struct inode *inode) kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 3a9ecac8d61f..3222f51c41cf 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c @@ -36,7 +36,7 @@ static inline int fat_max_cache(struct inode *inode) static struct kmem_cache *fat_cache_cachep; -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct fat_cache *cache = (struct fat_cache *)foo; diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 23676f9d79ce..6d266d793e2c 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -498,7 +498,7 @@ static void fat_destroy_inode(struct inode *inode) kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 7d2f7d6e22e2..d2249f174e20 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -956,7 +956,7 @@ static inline void unregister_fuseblk(void) } #endif -static void fuse_inode_init_once(struct kmem_cache *cachep, void *foo) +static void fuse_inode_init_once(void *foo) { struct inode * inode = foo; diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index bcc668d0fadd..bb2cc303ac29 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -24,7 +24,7 @@ #include "util.h" #include "glock.h" -static void gfs2_init_inode_once(struct kmem_cache *cachep, void *foo) +static void gfs2_init_inode_once(void *foo) { struct gfs2_inode *ip = foo; @@ -33,7 +33,7 @@ static void gfs2_init_inode_once(struct kmem_cache *cachep, void *foo) ip->i_alloc = NULL; } -static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo) +static void gfs2_init_glock_once(void *foo) { struct gfs2_glock *gl = foo; diff --git a/fs/hfs/super.c b/fs/hfs/super.c index ac2ec5ef66e4..4abb1047c689 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -432,7 +432,7 @@ static struct file_system_type hfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void hfs_init_once(struct kmem_cache *cachep, void *p) +static void hfs_init_once(void *p) { struct hfs_inode_info *i = p; diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 3859118531c7..e834e578c93f 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -485,7 +485,7 @@ static struct file_system_type hfsplus_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void hfsplus_init_once(struct kmem_cache *cachep, void *p) +static void hfsplus_init_once(void *p) { struct hfsplus_inode_info *i = p; diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index f63a699ec659..b8ae9c90ada0 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -173,7 +173,7 @@ static void hpfs_destroy_inode(struct inode *inode) kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index dbd01d262ca4..3f58923fb39b 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -705,7 +705,7 @@ static const struct address_space_operations hugetlbfs_aops = { }; -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; diff --git a/fs/inode.c b/fs/inode.c index 35b6414522ea..b6726f644530 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -224,7 +224,7 @@ void inode_init_once(struct inode *inode) EXPORT_SYMBOL(inode_init_once); -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct inode * inode = (struct inode *) foo; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 044a254d526b..26948a6033b6 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -73,7 +73,7 @@ static void isofs_destroy_inode(struct inode *inode) kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct iso_inode_info *ei = foo; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 7da69eae49e4..efd401257ed9 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -44,7 +44,7 @@ static void jffs2_destroy_inode(struct inode *inode) kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); } -static void jffs2_i_init_once(struct kmem_cache *cachep, void *foo) +static void jffs2_i_init_once(void *foo) { struct jffs2_inode_info *f = foo; diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 854ff0ec574f..c350057087dd 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -182,7 +182,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp) #endif -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct metapage *mp = (struct metapage *)foo; diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 359c091d8965..3630718be395 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -760,7 +760,7 @@ static struct file_system_type jfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; diff --git a/fs/locks.c b/fs/locks.c index 01490300f7cb..5eb259e3cd38 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -201,7 +201,7 @@ EXPORT_SYMBOL(locks_init_lock); * Initialises the fields of the file lock which are invariant for * free file_locks. */ -static void init_once(struct kmem_cache *cache, void *foo) +static void init_once(void *foo) { struct file_lock *lock = (struct file_lock *) foo; diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 523d73713418..d1d1eb84679d 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -68,7 +68,7 @@ static void minix_destroy_inode(struct inode *inode) kmem_cache_free(minix_inode_cachep, minix_i(inode)); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct minix_inode_info *ei = (struct minix_inode_info *) foo; diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 2e5ab1204dec..d642f0e5b365 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -64,7 +64,7 @@ static void ncp_destroy_inode(struct inode *inode) kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index df23f987da6b..52daefa2f521 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1242,7 +1242,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) #endif } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct nfs_inode *nfsi = (struct nfs_inode *) foo; diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 3e76f3b216bc..4a46743b5077 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -3080,7 +3080,7 @@ struct kmem_cache *ntfs_inode_cache; struct kmem_cache *ntfs_big_inode_cache; /* Init once constructor for the inode slab cache. */ -static void ntfs_big_inode_init_once(struct kmem_cache *cachep, void *foo) +static void ntfs_big_inode_init_once(void *foo) { ntfs_inode *ni = (ntfs_inode *)foo; diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index e48aba698b77..533a789c3ef8 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c @@ -267,8 +267,7 @@ static ssize_t dlmfs_file_write(struct file *filp, return writelen; } -static void dlmfs_init_once(struct kmem_cache *cachep, - void *foo) +static void dlmfs_init_once(void *foo) { struct dlmfs_inode_private *ip = (struct dlmfs_inode_private *) foo; diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index ccecfe5094fa..2560b33889aa 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1118,7 +1118,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) return status; } -static void ocfs2_inode_init_once(struct kmem_cache *cachep, void *data) +static void ocfs2_inode_init_once(void *data) { struct ocfs2_inode_info *oi = data; diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index d17b4fd204e1..9f5b054f06b9 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -430,7 +430,7 @@ static struct file_system_type openprom_fs_type = { .kill_sb = kill_anon_super, }; -static void op_inode_init_once(struct kmem_cache * cachep, void *data) +static void op_inode_init_once(void *data) { struct op_inode_info *oi = (struct op_inode_info *) data; diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 02eca2ed9dd7..b37f25dc45a5 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -94,7 +94,7 @@ static void proc_destroy_inode(struct inode *inode) kmem_cache_free(proc_inode_cachep, PROC_I(inode)); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct proc_inode *ei = (struct proc_inode *) foo; diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index b31ab78052b3..2aad1044b84c 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -553,7 +553,7 @@ static void qnx4_destroy_inode(struct inode *inode) kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 2ec748ba0bd3..879e54d35c2d 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -521,7 +521,7 @@ static void reiserfs_destroy_inode(struct inode *inode) kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 3f13d491c7c7..8e51a2aaa977 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -577,7 +577,7 @@ static void romfs_destroy_inode(struct inode *inode) kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct romfs_inode_info *ei = foo; diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 376ef3ee6ed7..3528f40ffb0f 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -67,7 +67,7 @@ static void smb_destroy_inode(struct inode *inode) kmem_cache_free(smb_inode_cachep, SMB_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct smb_inode_info *ei = (struct smb_inode_info *) foo; diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index c5d60de0658f..df0d435baa48 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -326,7 +326,7 @@ static void sysv_destroy_inode(struct inode *inode) kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *p) +static void init_once(void *p) { struct sysv_inode_info *si = (struct sysv_inode_info *)p; diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 00eb9c68ad03..ca1e2d4e03cc 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1841,7 +1841,7 @@ static struct file_system_type ubifs_fs_type = { /* * Inode slab cache constructor. */ -static void inode_slab_ctor(struct kmem_cache *cachep, void *obj) +static void inode_slab_ctor(void *obj) { struct ubifs_inode *ui = obj; inode_init_once(&ui->vfs_inode); diff --git a/fs/udf/super.c b/fs/udf/super.c index 44cc702f96cc..5698bbf83bbf 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -148,7 +148,7 @@ static void udf_destroy_inode(struct inode *inode) kmem_cache_free(udf_inode_cachep, UDF_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct udf_inode_info *ei = (struct udf_inode_info *)foo; diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 227c9d700040..3e30e40aa24d 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1302,7 +1302,7 @@ static void ufs_destroy_inode(struct inode *inode) kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); } -static void init_once(struct kmem_cache * cachep, void *foo) +static void init_once(void *foo) { struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index 5e9564902976..a20683cf74dd 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h @@ -79,7 +79,7 @@ kmem_zone_init(int size, char *zone_name) static inline kmem_zone_t * kmem_zone_init_flags(int size, char *zone_name, unsigned long flags, - void (*construct)(kmem_zone_t *, void *)) + void (*construct)(void *)) { return kmem_cache_create(zone_name, size, 0, flags, construct); } diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 742b2c7852c1..943381284e2e 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -843,7 +843,6 @@ xfs_fs_destroy_inode( STATIC void xfs_fs_inode_init_once( - kmem_zone_t *zonep, void *vnode) { inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); diff --git a/include/linux/slab.h b/include/linux/slab.h index 41103910f8a2..9ff8e8499403 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -58,7 +58,7 @@ int slab_is_available(void); struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long, - void (*)(struct kmem_cache *, void *)); + void (*)(void *)); void kmem_cache_destroy(struct kmem_cache *); int kmem_cache_shrink(struct kmem_cache *); void kmem_cache_free(struct kmem_cache *, void *); diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index d117ea2825a9..5bad61a93f65 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -85,7 +85,7 @@ struct kmem_cache { struct kmem_cache_order_objects min; gfp_t allocflags; /* gfp flags to use on each alloc */ int refcount; /* Refcount for slab cache destroy */ - void (*ctor)(struct kmem_cache *, void *); + void (*ctor)(void *); int inuse; /* Offset to metadata */ int align; /* Alignment */ const char *name; /* Name (only for display!) */ diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 1fdc2eb2f6d8..474984f9e032 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -207,7 +207,7 @@ static int mqueue_get_sb(struct file_system_type *fs_type, return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; diff --git a/kernel/fork.c b/kernel/fork.c index b99d73e971a4..80e83e459b17 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1442,7 +1442,7 @@ long do_fork(unsigned long clone_flags, #define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif -static void sighand_ctor(struct kmem_cache *cachep, void *data) +static void sighand_ctor(void *data) { struct sighand_struct *sighand = data; diff --git a/lib/idr.c b/lib/idr.c index 3476f8203e97..e728c7fccc4d 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -607,7 +607,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) } EXPORT_SYMBOL(idr_replace); -static void idr_cache_ctor(struct kmem_cache *idr_layer_cache, void *idr_layer) +static void idr_cache_ctor(void *idr_layer) { memset(idr_layer, 0, sizeof(struct idr_layer)); } diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 9c4f1ffa2864..be86b32bc874 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -1183,7 +1183,7 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag) EXPORT_SYMBOL(radix_tree_tagged); static void -radix_tree_node_ctor(struct kmem_cache *cachep, void *node) +radix_tree_node_ctor(void *node) { memset(node, 0, sizeof(struct radix_tree_node)); } diff --git a/mm/rmap.c b/mm/rmap.c index abbd29f7c43f..39ae5a9bf382 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -138,7 +138,7 @@ void anon_vma_unlink(struct vm_area_struct *vma) anon_vma_free(anon_vma); } -static void anon_vma_ctor(struct kmem_cache *cachep, void *data) +static void anon_vma_ctor(void *data) { struct anon_vma *anon_vma = data; diff --git a/mm/shmem.c b/mm/shmem.c index 1089092aecaf..952d361774bb 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2352,7 +2352,7 @@ static void shmem_destroy_inode(struct inode *inode) kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct shmem_inode_info *p = (struct shmem_inode_info *) foo; diff --git a/mm/slab.c b/mm/slab.c index 052e7d64537e..918f04f7fef1 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -406,7 +406,7 @@ struct kmem_cache { unsigned int dflags; /* dynamic flags */ /* constructor func */ - void (*ctor)(struct kmem_cache *, void *); + void (*ctor)(void *obj); /* 5) cache creation/removal */ const char *name; @@ -2137,8 +2137,7 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep) */ struct kmem_cache * kmem_cache_create (const char *name, size_t size, size_t align, - unsigned long flags, - void (*ctor)(struct kmem_cache *, void *)) + unsigned long flags, void (*ctor)(void *)) { size_t left_over, slab_size, ralign; struct kmem_cache *cachep = NULL, *pc; @@ -2653,7 +2652,7 @@ static void cache_init_objs(struct kmem_cache *cachep, * They must also be threaded. */ if (cachep->ctor && !(cachep->flags & SLAB_POISON)) - cachep->ctor(cachep, objp + obj_offset(cachep)); + cachep->ctor(objp + obj_offset(cachep)); if (cachep->flags & SLAB_RED_ZONE) { if (*dbg_redzone2(cachep, objp) != RED_INACTIVE) @@ -2669,7 +2668,7 @@ static void cache_init_objs(struct kmem_cache *cachep, cachep->buffer_size / PAGE_SIZE, 0); #else if (cachep->ctor) - cachep->ctor(cachep, objp); + cachep->ctor(objp); #endif slab_bufctl(slabp)[i] = i + 1; } @@ -3093,7 +3092,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, #endif objp += obj_offset(cachep); if (cachep->ctor && cachep->flags & SLAB_POISON) - cachep->ctor(cachep, objp); + cachep->ctor(objp); #if ARCH_SLAB_MINALIGN if ((u32)objp & (ARCH_SLAB_MINALIGN-1)) { printk(KERN_ERR "0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n", diff --git a/mm/slob.c b/mm/slob.c index de268eb7ac70..d8fbd4d1bfa7 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -525,12 +525,11 @@ struct kmem_cache { unsigned int size, align; unsigned long flags; const char *name; - void (*ctor)(struct kmem_cache *, void *); + void (*ctor)(void *); }; struct kmem_cache *kmem_cache_create(const char *name, size_t size, - size_t align, unsigned long flags, - void (*ctor)(struct kmem_cache *, void *)) + size_t align, unsigned long flags, void (*ctor)(void *)) { struct kmem_cache *c; @@ -575,7 +574,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node) b = slob_new_page(flags, get_order(c->size), node); if (c->ctor) - c->ctor(c, b); + c->ctor(b); return b; } diff --git a/mm/slub.c b/mm/slub.c index 77c21cf53ff9..b7e2cd5d82db 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1012,7 +1012,7 @@ __setup("slub_debug", setup_slub_debug); static unsigned long kmem_cache_flags(unsigned long objsize, unsigned long flags, const char *name, - void (*ctor)(struct kmem_cache *, void *)) + void (*ctor)(void *)) { /* * Enable debugging if selected on the kernel commandline. @@ -1040,7 +1040,7 @@ static inline int check_object(struct kmem_cache *s, struct page *page, static inline void add_full(struct kmem_cache_node *n, struct page *page) {} static inline unsigned long kmem_cache_flags(unsigned long objsize, unsigned long flags, const char *name, - void (*ctor)(struct kmem_cache *, void *)) + void (*ctor)(void *)) { return flags; } @@ -1103,7 +1103,7 @@ static void setup_object(struct kmem_cache *s, struct page *page, { setup_object_debug(s, page, object); if (unlikely(s->ctor)) - s->ctor(s, object); + s->ctor(object); } static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) @@ -2286,7 +2286,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order) static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags, const char *name, size_t size, size_t align, unsigned long flags, - void (*ctor)(struct kmem_cache *, void *)) + void (*ctor)(void *)) { memset(s, 0, kmem_size); s->name = name; @@ -3042,7 +3042,7 @@ static int slab_unmergeable(struct kmem_cache *s) static struct kmem_cache *find_mergeable(size_t size, size_t align, unsigned long flags, const char *name, - void (*ctor)(struct kmem_cache *, void *)) + void (*ctor)(void *)) { struct kmem_cache *s; @@ -3082,8 +3082,7 @@ static struct kmem_cache *find_mergeable(size_t size, } struct kmem_cache *kmem_cache_create(const char *name, size_t size, - size_t align, unsigned long flags, - void (*ctor)(struct kmem_cache *, void *)) + size_t align, unsigned long flags, void (*ctor)(void *)) { struct kmem_cache *s; diff --git a/net/socket.c b/net/socket.c index 1310a82cbba7..8ef8ba81b9e2 100644 --- a/net/socket.c +++ b/net/socket.c @@ -265,7 +265,7 @@ static void sock_destroy_inode(struct inode *inode) container_of(inode, struct socket_alloc, vfs_inode)); } -static void init_once(struct kmem_cache *cachep, void *foo) +static void init_once(void *foo) { struct socket_alloc *ei = (struct socket_alloc *)foo; diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 5a9b0e7828cd..23a2b8f6dc49 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -897,7 +897,7 @@ static struct file_system_type rpc_pipe_fs_type = { }; static void -init_once(struct kmem_cache * cachep, void *foo) +init_once(void *foo) { struct rpc_inode *rpci = (struct rpc_inode *) foo; From b8c512f6190e313df69060bae4a161c5c044e272 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:36 -0700 Subject: [PATCH 110/179] Use WARN() in kernel/irq/manage.c Replace a printk+WARN_ON() by a WARN(); this increases the chance of the string making it into the bugreport (ie: it goes inside the ---[ cut here ]--- section) Signed-off-by: Arjan van de Ven Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/irq/manage.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index f8914b92b664..152abfd3589f 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -177,8 +177,7 @@ static void __enable_irq(struct irq_desc *desc, unsigned int irq) { switch (desc->depth) { case 0: - printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); - WARN_ON(1); + WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); break; case 1: { unsigned int status = desc->status & ~IRQ_DISABLED; From 4c8573e25f27b60b495aaa23089032f685ffd5ba Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:37 -0700 Subject: [PATCH 111/179] Use WARN() in mm/vmalloc.c Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmalloc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 35f293816294..85b9a0d2c877 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -381,16 +381,14 @@ static void __vunmap(const void *addr, int deallocate_pages) return; if ((PAGE_SIZE-1) & (unsigned long)addr) { - printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr); - WARN_ON(1); + WARN(1, KERN_ERR "Trying to vfree() bad address (%p)\n", addr); return; } area = remove_vm_area(addr); if (unlikely(!area)) { - printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", + WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr); - WARN_ON(1); return; } From 261c40c1191ad8d7a2e49fa2bb5f6a84e3d44b10 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:37 -0700 Subject: [PATCH 112/179] use WARN() in kernel/irq/chip.c Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. Signed-off-by: Arjan van de Ven Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/irq/chip.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 964964baefa2..3cd441ebf5d2 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -28,8 +28,7 @@ void dynamic_irq_init(unsigned int irq) unsigned long flags; if (irq >= NR_IRQS) { - printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); - WARN_ON(1); + WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); return; } @@ -62,8 +61,7 @@ void dynamic_irq_cleanup(unsigned int irq) unsigned long flags; if (irq >= NR_IRQS) { - printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); - WARN_ON(1); + WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); return; } @@ -71,9 +69,8 @@ void dynamic_irq_cleanup(unsigned int irq) spin_lock_irqsave(&desc->lock, flags); if (desc->action) { spin_unlock_irqrestore(&desc->lock, flags); - printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n", + WARN(1, KERN_ERR "Destroying IRQ%d without calling free_irq\n", irq); - WARN_ON(1); return; } desc->msi_desc = NULL; @@ -96,8 +93,7 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip) unsigned long flags; if (irq >= NR_IRQS) { - printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq); - WARN_ON(1); + WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq); return -EINVAL; } From 12e0036818eed243c8ed6583ebf98261a2554e12 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:38 -0700 Subject: [PATCH 113/179] Use WARN() in block/ Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. Signed-off-by: Arjan van de Ven Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- block/as-iosched.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/as-iosched.c b/block/as-iosched.c index 9735acb5b4f5..cf4eb0eefbbf 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c @@ -837,8 +837,7 @@ static void as_completed_request(struct request_queue *q, struct request *rq) WARN_ON(!list_empty(&rq->queuelist)); if (RQ_STATE(rq) != AS_RQ_REMOVED) { - printk("rq->state %d\n", RQ_STATE(rq)); - WARN_ON(1); + WARN(1, "rq->state %d\n", RQ_STATE(rq)); goto out; } From f810a5cf28a818db96333cd23646f0227ec015b4 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:39 -0700 Subject: [PATCH 114/179] Use WARN() in drivers/base/ Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. Signed-off-by: Arjan van de Ven Cc: Greg KH Cc: Kay Sievers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/core.c | 6 ++---- drivers/base/memory.c | 3 +-- drivers/base/sys.c | 12 ++++-------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 7d5c63c81a59..068aa1c9538c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -116,12 +116,10 @@ static void device_release(struct kobject *kobj) dev->type->release(dev); else if (dev->class && dev->class->dev_release) dev->class->dev_release(dev); - else { - printk(KERN_ERR "Device '%s' does not have a release() " + else + WARN(1, KERN_ERR "Device '%s' does not have a release() " "function, it is broken and must be fixed.\n", dev->bus_id); - WARN_ON(1); - } } static struct kobj_type device_ktype = { diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 855ed1a9f97b..3ad49a00029f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -204,9 +204,8 @@ memory_block_action(struct memory_block *mem, unsigned long action) } break; default: - printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", + WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", __func__, mem, action, action); - WARN_ON(1); ret = -EINVAL; } diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 40fc14f03540..75dd6e22faff 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -168,19 +168,16 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) int err = 0; if (!cls) { - printk(KERN_WARNING "sysdev: invalid class passed to " + WARN(1, KERN_WARNING "sysdev: invalid class passed to " "sysdev_driver_register!\n"); - WARN_ON(1); return -EINVAL; } /* Check whether this driver has already been added to a class. */ - if (drv->entry.next && !list_empty(&drv->entry)) { - printk(KERN_WARNING "sysdev: class %s: driver (%p) has already" + if (drv->entry.next && !list_empty(&drv->entry)) + WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already" " been registered to a class, something is wrong, but " "will forge on!\n", cls->name, drv); - WARN_ON(1); - } mutex_lock(&sysdev_drivers_lock); if (cls && kset_get(&cls->kset)) { @@ -194,8 +191,7 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) } } else { err = -EINVAL; - printk(KERN_ERR "%s: invalid device class\n", __func__); - WARN_ON(1); + WARN(1, KERN_ERR "%s: invalid device class\n", __func__); } mutex_unlock(&sysdev_drivers_lock); return err; From 5cd2b459d326a424671dcd95f038649f7bf7cb96 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:39 -0700 Subject: [PATCH 115/179] Use WARN() in lib/ Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. In addition, one of the if() clauses collapes into the WARN() entirely now. Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/debugobjects.c | 15 +++++---------- lib/iomap.c | 3 +-- lib/kobject_uevent.c | 6 ++---- lib/plist.c | 13 +++++++------ 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/lib/debugobjects.c b/lib/debugobjects.c index f86196390cfd..45a6bde762d1 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -205,9 +205,8 @@ static void debug_print_object(struct debug_obj *obj, char *msg) if (limit < 5 && obj->descr != descr_test) { limit++; - printk(KERN_ERR "ODEBUG: %s %s object type: %s\n", msg, + WARN(1, KERN_ERR "ODEBUG: %s %s object type: %s\n", msg, obj_states[obj->state], obj->descr->name); - WARN_ON(1); } debug_objects_warnings++; } @@ -733,26 +732,22 @@ check_results(void *addr, enum debug_obj_state state, int fixups, int warnings) obj = lookup_object(addr, db); if (!obj && state != ODEBUG_STATE_NONE) { - printk(KERN_ERR "ODEBUG: selftest object not found\n"); - WARN_ON(1); + WARN(1, KERN_ERR "ODEBUG: selftest object not found\n"); goto out; } if (obj && obj->state != state) { - printk(KERN_ERR "ODEBUG: selftest wrong state: %d != %d\n", + WARN(1, KERN_ERR "ODEBUG: selftest wrong state: %d != %d\n", obj->state, state); - WARN_ON(1); goto out; } if (fixups != debug_objects_fixups) { - printk(KERN_ERR "ODEBUG: selftest fixups failed %d != %d\n", + WARN(1, KERN_ERR "ODEBUG: selftest fixups failed %d != %d\n", fixups, debug_objects_fixups); - WARN_ON(1); goto out; } if (warnings != debug_objects_warnings) { - printk(KERN_ERR "ODEBUG: selftest warnings failed %d != %d\n", + WARN(1, KERN_ERR "ODEBUG: selftest warnings failed %d != %d\n", warnings, debug_objects_warnings); - WARN_ON(1); goto out; } res = 0; diff --git a/lib/iomap.c b/lib/iomap.c index 37a3ea4cac9f..d32229385151 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -40,8 +40,7 @@ static void bad_io_access(unsigned long port, const char *access) static int count = 10; if (count) { count--; - printk(KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access); - WARN_ON(1); + WARN(1, KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access); } } diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 9f8d599459d1..3f914725bda8 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -285,8 +285,7 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) int len; if (env->envp_idx >= ARRAY_SIZE(env->envp)) { - printk(KERN_ERR "add_uevent_var: too many keys\n"); - WARN_ON(1); + WARN(1, KERN_ERR "add_uevent_var: too many keys\n"); return -ENOMEM; } @@ -297,8 +296,7 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) va_end(args); if (len >= (sizeof(env->buf) - env->buflen)) { - printk(KERN_ERR "add_uevent_var: buffer size too small\n"); - WARN_ON(1); + WARN(1, KERN_ERR "add_uevent_var: buffer size too small\n"); return -ENOMEM; } diff --git a/lib/plist.c b/lib/plist.c index 3074a02272f3..d6c64a824e1d 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -31,12 +31,13 @@ static void plist_check_prev_next(struct list_head *t, struct list_head *p, struct list_head *n) { - if (n->prev != p || p->next != n) { - printk("top: %p, n: %p, p: %p\n", t, t->next, t->prev); - printk("prev: %p, n: %p, p: %p\n", p, p->next, p->prev); - printk("next: %p, n: %p, p: %p\n", n, n->next, n->prev); - WARN_ON(1); - } + WARN(n->prev != p || p->next != n, + "top: %p, n: %p, p: %p\n" + "prev: %p, n: %p, p: %p\n" + "next: %p, n: %p, p: %p\n", + t, t->next, t->prev, + p, p->next, p->prev, + n, n->next, n->prev); } static void plist_check_list(struct list_head *top) From 5c752ad9f35910ff1912b3f3ae82878178ddc432 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:40 -0700 Subject: [PATCH 116/179] Use WARN() in fs/ Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 3 +-- fs/namespace.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 5fd497cdd6f3..f95805019639 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1214,8 +1214,7 @@ void __brelse(struct buffer_head * buf) put_bh(buf); return; } - printk(KERN_ERR "VFS: brelse: Trying to free free buffer\n"); - WARN_ON(1); + WARN(1, KERN_ERR "VFS: brelse: Trying to free free buffer\n"); } /* diff --git a/fs/namespace.c b/fs/namespace.c index 4f6f7635b59c..f30b11e2240e 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -309,10 +309,9 @@ static void handle_write_count_underflow(struct vfsmount *mnt) */ if ((atomic_read(&mnt->__mnt_writers) < 0) && !(mnt->mnt_flags & MNT_IMBALANCED_WRITE_COUNT)) { - printk(KERN_DEBUG "leak detected on mount(%p) writers " + WARN(1, KERN_DEBUG "leak detected on mount(%p) writers " "count: %d\n", mnt, atomic_read(&mnt->__mnt_writers)); - WARN_ON(1); /* use the flag to keep the dmesg spam down */ mnt->mnt_flags |= MNT_IMBALANCED_WRITE_COUNT; } From 99fcd77d15357e8ba51005c25cc750b9c28b2688 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:41 -0700 Subject: [PATCH 117/179] Use WARN() in fs/sysfs Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. Also, with this, one fo the if() sections collapses entirely into the WARN(). Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/sysfs/dir.c | 5 +---- fs/sysfs/file.c | 3 +-- fs/sysfs/group.c | 3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index c1a7efb310bf..aedaeba82ae5 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -459,11 +459,8 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) int ret; ret = __sysfs_add_one(acxt, sd); - if (ret == -EEXIST) { - printk(KERN_WARNING "sysfs: duplicate filename '%s' " + WARN(ret == -EEXIST, KERN_WARNING "sysfs: duplicate filename '%s' " "can not be created\n", sd->s_name); - WARN_ON(1); - } return ret; } diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 3f07893ff896..c9e4e5091da1 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -337,9 +337,8 @@ static int sysfs_open_file(struct inode *inode, struct file *file) if (kobj->ktype && kobj->ktype->sysfs_ops) ops = kobj->ktype->sysfs_ops; else { - printk(KERN_ERR "missing sysfs attribute operations for " + WARN(1, KERN_ERR "missing sysfs attribute operations for " "kobject: %s\n", kobject_name(kobj)); - WARN_ON(1); goto err_out; } diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index eeba38417b1d..fe611949a7f7 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -134,9 +134,8 @@ void sysfs_remove_group(struct kobject * kobj, if (grp->name) { sd = sysfs_get_dirent(dir_sd, grp->name); if (!sd) { - printk(KERN_WARNING "sysfs group %p not found for " + WARN(!sd, KERN_WARNING "sysfs group %p not found for " "kobject '%s'\n", grp, kobject_name(kobj)); - WARN_ON(!sd); return; } } else From 267e2a9c71b8e088ac307f9549f71468e86e26c1 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 25 Jul 2008 19:45:41 -0700 Subject: [PATCH 118/179] Use WARN() in fs/proc/ Use WARN() instead of a printk+WARN_ON() pair; this way the message becomes part of the warning section for better reporting/collection. This way, the entire if() {} section can collapse into the WARN() as well. Signed-off-by: Arjan van de Ven Acked-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/generic.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/proc/generic.c b/fs/proc/generic.c index bc0a0dd2d844..cb4096cc3fb7 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -806,12 +806,9 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) if (S_ISDIR(de->mode)) parent->nlink--; de->nlink = 0; - if (de->subdir) { - printk(KERN_WARNING "%s: removing non-empty directory " + WARN(de->subdir, KERN_WARNING "%s: removing non-empty directory " "'%s/%s', leaking at least '%s'\n", __func__, de->parent->name, de->name, de->subdir->name); - WARN_ON(1); - } if (atomic_dec_and_test(&de->count)) free_proc_entry(de); } From 88ac2921a71f788ed693bcd44731dd6bc1994640 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:43 -0700 Subject: [PATCH 119/179] tracehook: add linux/tracehook.h This patch series introduces the "tracehook" interface layer of inlines in . There are more details in the log entry for patch 01/23 and in the header file comments inside that patch. Most of these changes move code around with little or no change, and they should not break anything or change any behavior. This sets a new standard for uniform arch support to enable clean arch-independent implementations of new debugging and tracing stuff, denoted by CONFIG_HAVE_ARCH_TRACEHOOK. Patch 20/23 adds that symbol to arch/Kconfig, with comments listing everything an arch has to do before setting "select HAVE_ARCH_TRACEHOOK". These are elaborted a bit at: http://sourceware.org/systemtap/wiki/utrace/arch/HowTo The new inlines that arch code must define or call have detailed kerneldoc comments in the generic header files that say what is required. No arch is obligated to do any work, and no arch's build should be broken by these changes. There are several steps that each arch should take so it can set HAVE_ARCH_TRACEHOOK. Most of these are simple. Providing this support will let new things people add for doing debugging and tracing of user-level threads "just work" for your arch in the future. For an arch that does not provide HAVE_ARCH_TRACEHOOK, some new options for such features will not be available for config. I have done some arch work and will submit this to the arch maintainers after the generic tracehook series settles in. For now, that work is available in my GIT repositories, and in patch and mbox-of-patches form at http://people.redhat.com/roland/utrace/2.6-current/ This paves the way for my "utrace" work, to be submitted later. But it is not innately tied to that. I hope that the tracehook series can go in soon regardless of what eventually does or doesn't go on top of it. For anyone implementing any kind of new tracing/debugging plan, or just understanding all the context of the existing ptrace implementation, having tracehook.h makes things much easier to find and understand. This patch: This adds the new kernel-internal header file . This is not yet used at all. The comments in the header introduce what the following series of patches is about. The aim is to formalize and consolidate all the places that the core kernel code and the arch code now ties into the ptrace implementation. These patches mostly don't cause any functional change. They just move the details of ptrace logic out of core code into tracehook.h inlines, where they are mostly compiled away to the same as before. All that changes is that everything is thoroughly documented and any future reworking of ptrace, or addition of something new, would not have to touch core code all over, just change the tracehook.h inlines. The new linux/ptrace.h inlines are used by the following patches in the new tracehook_*() inlines. Using these helpers for the ptrace event stops makes it simple to change or disable the old ptrace implementation of these stops conditionally later. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ptrace.h | 33 +++++++++++++++++++++++++ include/linux/tracehook.h | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 include/linux/tracehook.h diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index c6f5f9dd0cee..c74abfc4c7e8 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -121,6 +121,39 @@ static inline void ptrace_unlink(struct task_struct *child) int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data); int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data); +/** + * task_ptrace - return %PT_* flags that apply to a task + * @task: pointer to &task_struct in question + * + * Returns the %PT_* flags that apply to @task. + */ +static inline int task_ptrace(struct task_struct *task) +{ + return task->ptrace; +} + +/** + * ptrace_event - possibly stop for a ptrace event notification + * @mask: %PT_* bit to check in @current->ptrace + * @event: %PTRACE_EVENT_* value to report if @mask is set + * @message: value for %PTRACE_GETEVENTMSG to return + * + * This checks the @mask bit to see if ptrace wants stops for this event. + * If so we stop, reporting @event and @message to the ptrace parent. + * + * Returns nonzero if we did a ptrace notification, zero if not. + * + * Called without locks. + */ +static inline int ptrace_event(int mask, int event, unsigned long message) +{ + if (mask && likely(!(current->ptrace & mask))) + return 0; + current->ptrace_message = message; + ptrace_notify((event << 8) | SIGTRAP); + return 1; +} + #ifndef force_successful_syscall_return /* * System call handlers that, upon successful completion, need to return a diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h new file mode 100644 index 000000000000..bea0f3eeff54 --- /dev/null +++ b/include/linux/tracehook.h @@ -0,0 +1,52 @@ +/* + * Tracing hooks + * + * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + * + * This file defines hook entry points called by core code where + * user tracing/debugging support might need to do something. These + * entry points are called tracehook_*(). Each hook declared below + * has a detailed kerneldoc comment giving the context (locking et + * al) from which it is called, and the meaning of its return value. + * + * Each function here typically has only one call site, so it is ok + * to have some nontrivial tracehook_*() inlines. In all cases, the + * fast path when no tracing is enabled should be very short. + * + * The purpose of this file and the tracehook_* layer is to consolidate + * the interface that the kernel core and arch code uses to enable any + * user debugging or tracing facility (such as ptrace). The interfaces + * here are carefully documented so that maintainers of core and arch + * code do not need to think about the implementation details of the + * tracing facilities. Likewise, maintainers of the tracing code do not + * need to understand all the calling core or arch code in detail, just + * documented circumstances of each call, such as locking conditions. + * + * If the calling core code changes so that locking is different, then + * it is ok to change the interface documented here. The maintainer of + * core code changing should notify the maintainers of the tracing code + * that they need to work out the change. + * + * Some tracehook_*() inlines take arguments that the current tracing + * implementations might not necessarily use. These function signatures + * are chosen to pass in all the information that is on hand in the + * caller and might conceivably be relevant to a tracer, so that the + * core code won't have to be updated when tracing adds more features. + * If a call site changes so that some of those parameters are no longer + * already on hand without extra work, then the tracehook_* interface + * can change so there is no make-work burden on the core code. The + * maintainer of core code changing should notify the maintainers of the + * tracing code that they need to work out the change. + */ + +#ifndef _LINUX_TRACEHOOK_H +#define _LINUX_TRACEHOOK_H 1 + +#include +#include + +#endif /* */ From 6341c393fcc37d58727865f1ee2f65e632e9d4f0 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:44 -0700 Subject: [PATCH 120/179] tracehook: exec This moves all the ptrace hooks related to exec into tracehook.h inlines. This also lifts the calls for tracing out of the binfmt load_binary hooks into search_binary_handler() after it calls into the binfmt module. This change has no effect, since all the binfmt modules' load_binary functions did the call at the end on success, and now search_binary_handler() does it immediately after return if successful. We consolidate the repeated code, and binfmt modules no longer need to import ptrace_notify(). Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/ia32/ia32_aout.c | 6 ----- fs/binfmt_aout.c | 6 ----- fs/binfmt_elf.c | 6 ----- fs/binfmt_elf_fdpic.c | 7 ------ fs/binfmt_flat.c | 3 --- fs/binfmt_som.c | 2 -- fs/exec.c | 12 ++++------ include/linux/tracehook.h | 46 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 50 insertions(+), 38 deletions(-) diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 58cccb6483b0..a0e1dbe67dc1 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -441,12 +441,6 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0; set_fs(USER_DS); - if (unlikely(current->ptrace & PT_PTRACED)) { - if (current->ptrace & PT_TRACE_EXEC) - ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP); - else - send_sig(SIGTRAP, current, 0); - } return 0; } diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index ba4cddb92f1d..204cfd1d7676 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -444,12 +444,6 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) regs->gp = ex.a_gpvalue; #endif start_thread(regs, ex.a_entry, current->mm->start_stack); - if (unlikely(current->ptrace & PT_PTRACED)) { - if (current->ptrace & PT_TRACE_EXEC) - ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP); - else - send_sig(SIGTRAP, current, 0); - } return 0; } diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3b6ff854d983..655ed8d30a86 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1003,12 +1003,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) #endif start_thread(regs, elf_entry, bprm->p); - if (unlikely(current->ptrace & PT_PTRACED)) { - if (current->ptrace & PT_TRACE_EXEC) - ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP); - else - send_sig(SIGTRAP, current, 0); - } retval = 0; out: kfree(loc); diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 1b59b1edf26d..fdeadab2f18b 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -433,13 +433,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, entryaddr = interp_params.entry_addr ?: exec_params.entry_addr; start_thread(regs, entryaddr, current->mm->start_stack); - if (unlikely(current->ptrace & PT_PTRACED)) { - if (current->ptrace & PT_TRACE_EXEC) - ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP); - else - send_sig(SIGTRAP, current, 0); - } - retval = 0; error: diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 2cb1acda3a82..56372ecf1690 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -920,9 +920,6 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) start_thread(regs, start_addr, current->mm->start_stack); - if (current->ptrace & PT_PTRACED) - send_sig(SIGTRAP, current, 0); - return 0; } diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index fdc36bfd6a7b..68be580ba289 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c @@ -274,8 +274,6 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs) map_hpux_gateway_page(current,current->mm); start_thread_som(regs, som_entry, bprm->p); - if (current->ptrace & PT_PTRACED) - send_sig(SIGTRAP, current, 0); return 0; /* error cleanup */ diff --git a/fs/exec.c b/fs/exec.c index 5e559013e303..b8792a131533 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -42,13 +42,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include @@ -1071,13 +1071,8 @@ EXPORT_SYMBOL(prepare_binprm); static int unsafe_exec(struct task_struct *p) { - int unsafe = 0; - if (p->ptrace & PT_PTRACED) { - if (p->ptrace & PT_PTRACE_CAP) - unsafe |= LSM_UNSAFE_PTRACE_CAP; - else - unsafe |= LSM_UNSAFE_PTRACE; - } + int unsafe = tracehook_unsafe_exec(p); + if (atomic_read(&p->fs->count) > 1 || atomic_read(&p->files->count) > 1 || atomic_read(&p->sighand->count) > 1) @@ -1214,6 +1209,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) read_unlock(&binfmt_lock); retval = fn(bprm, regs); if (retval >= 0) { + tracehook_report_exec(fmt, bprm, regs); put_binfmt(fmt); allow_write_access(bprm->file); if (bprm->file) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index bea0f3eeff54..6276353709c1 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -48,5 +48,51 @@ #include #include +#include +struct linux_binprm; + +/** + * tracehook_unsafe_exec - check for exec declared unsafe due to tracing + * @task: current task doing exec + * + * Return %LSM_UNSAFE_* bits applied to an exec because of tracing. + * + * Called with task_lock() held on @task. + */ +static inline int tracehook_unsafe_exec(struct task_struct *task) +{ + int unsafe = 0; + int ptrace = task_ptrace(task); + if (ptrace & PT_PTRACED) { + if (ptrace & PT_PTRACE_CAP) + unsafe |= LSM_UNSAFE_PTRACE_CAP; + else + unsafe |= LSM_UNSAFE_PTRACE; + } + return unsafe; +} + +/** + * tracehook_report_exec - a successful exec was completed + * @fmt: &struct linux_binfmt that performed the exec + * @bprm: &struct linux_binprm containing exec details + * @regs: user-mode register state + * + * An exec just completed, we are shortly going to return to user mode. + * The freshly initialized register state can be seen and changed in @regs. + * The name, file and other pointers in @bprm are still on hand to be + * inspected, but will be freed as soon as this returns. + * + * Called with no locks, but with some kernel resources held live + * and a reference on @fmt->module. + */ +static inline void tracehook_report_exec(struct linux_binfmt *fmt, + struct linux_binprm *bprm, + struct pt_regs *regs) +{ + if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) && + unlikely(task_ptrace(current) & PT_PTRACED)) + send_sig(SIGTRAP, current, 0); +} #endif /* */ From ff1188646c6870f336e910fb894eeed74f50471f Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:45 -0700 Subject: [PATCH 121/179] tracehook: unexport ptrace_notify The ptrace_notify() function should not be called by any modules. It was only ever exported to be called by binfmt exec functions. But that is no longer necessary since fs/exec.c deals with that generically now. There should be no calls to ptrace_notify() from outside the core kernel. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/signal.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/signal.c b/kernel/signal.c index 82c3545596c5..8715c18b27b9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1895,7 +1895,6 @@ EXPORT_SYMBOL(recalc_sigpending); EXPORT_SYMBOL_GPL(dequeue_signal); EXPORT_SYMBOL(flush_signals); EXPORT_SYMBOL(force_sig); -EXPORT_SYMBOL(ptrace_notify); EXPORT_SYMBOL(send_sig); EXPORT_SYMBOL(send_sig_info); EXPORT_SYMBOL(sigprocmask); From 30199f5a46aee204bf437a4f5b0740f3efe448b7 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:46 -0700 Subject: [PATCH 122/179] tracehook: exit This moves the PTRACE_EVENT_EXIT tracing into a tracehook.h inline, tracehook_report_exec(). The change has no effect, just clean-up. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 15 +++++++++++++++ kernel/exit.c | 6 ++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 6276353709c1..967ab473afbc 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -95,4 +95,19 @@ static inline void tracehook_report_exec(struct linux_binfmt *fmt, send_sig(SIGTRAP, current, 0); } +/** + * tracehook_report_exit - task has begun to exit + * @exit_code: pointer to value destined for @current->exit_code + * + * @exit_code points to the value passed to do_exit(), which tracing + * might change here. This is almost the first thing in do_exit(), + * before freeing any resources or setting the %PF_EXITING flag. + * + * Called with no locks held. + */ +static inline void tracehook_report_exit(long *exit_code) +{ + ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code); +} + #endif /* */ diff --git a/kernel/exit.c b/kernel/exit.c index ad933bb29ec7..c3691cbc220a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -1029,10 +1030,7 @@ NORET_TYPE void do_exit(long code) if (unlikely(!tsk->pid)) panic("Attempted to kill the idle task!"); - if (unlikely(current->ptrace & PT_TRACE_EXIT)) { - current->ptrace_message = code; - ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP); - } + tracehook_report_exit(&code); /* * We're taking recursive faults here in do_exit. Safest is to just From 09a05394fe2448a4139b014936330af23fa7ec83 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:47 -0700 Subject: [PATCH 123/179] tracehook: clone This moves all the ptrace initialization and tracing logic for task creation into tracehook.h and ptrace.h inlines. It reorganizes the code slightly, but should not change any behavior. There are four tracehook entry points, at each important stage of task creation. This keeps the interface from the core fork.c code fairly clean, while supporting the complex setup required for ptrace or something like it. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ptrace.h | 22 +++++++++ include/linux/tracehook.h | 100 ++++++++++++++++++++++++++++++++++++++ kernel/fork.c | 69 +++++++++++--------------- 3 files changed, 150 insertions(+), 41 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index c74abfc4c7e8..dae6d85520fb 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -154,6 +154,28 @@ static inline int ptrace_event(int mask, int event, unsigned long message) return 1; } +/** + * ptrace_init_task - initialize ptrace state for a new child + * @child: new child task + * @ptrace: true if child should be ptrace'd by parent's tracer + * + * This is called immediately after adding @child to its parent's children + * list. @ptrace is false in the normal case, and true to ptrace @child. + * + * Called with current's siglock and write_lock_irq(&tasklist_lock) held. + */ +static inline void ptrace_init_task(struct task_struct *child, bool ptrace) +{ + INIT_LIST_HEAD(&child->ptrace_entry); + INIT_LIST_HEAD(&child->ptraced); + child->parent = child->real_parent; + child->ptrace = 0; + if (unlikely(ptrace)) { + child->ptrace = current->ptrace; + __ptrace_link(child, current->parent); + } +} + #ifndef force_successful_syscall_return /* * System call handlers that, upon successful completion, need to return a diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 967ab473afbc..3ebc58b59766 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -110,4 +110,104 @@ static inline void tracehook_report_exit(long *exit_code) ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code); } +/** + * tracehook_prepare_clone - prepare for new child to be cloned + * @clone_flags: %CLONE_* flags from clone/fork/vfork system call + * + * This is called before a new user task is to be cloned. + * Its return value will be passed to tracehook_finish_clone(). + * + * Called with no locks held. + */ +static inline int tracehook_prepare_clone(unsigned clone_flags) +{ + if (clone_flags & CLONE_UNTRACED) + return 0; + + if (clone_flags & CLONE_VFORK) { + if (current->ptrace & PT_TRACE_VFORK) + return PTRACE_EVENT_VFORK; + } else if ((clone_flags & CSIGNAL) != SIGCHLD) { + if (current->ptrace & PT_TRACE_CLONE) + return PTRACE_EVENT_CLONE; + } else if (current->ptrace & PT_TRACE_FORK) + return PTRACE_EVENT_FORK; + + return 0; +} + +/** + * tracehook_finish_clone - new child created and being attached + * @child: new child task + * @clone_flags: %CLONE_* flags from clone/fork/vfork system call + * @trace: return value from tracehook_clone_prepare() + * + * This is called immediately after adding @child to its parent's children list. + * The @trace value is that returned by tracehook_prepare_clone(). + * + * Called with current's siglock and write_lock_irq(&tasklist_lock) held. + */ +static inline void tracehook_finish_clone(struct task_struct *child, + unsigned long clone_flags, int trace) +{ + ptrace_init_task(child, (clone_flags & CLONE_PTRACE) || trace); +} + +/** + * tracehook_report_clone - in parent, new child is about to start running + * @trace: return value from tracehook_clone_prepare() + * @regs: parent's user register state + * @clone_flags: flags from parent's system call + * @pid: new child's PID in the parent's namespace + * @child: new child task + * + * Called after a child is set up, but before it has been started running. + * The @trace value is that returned by tracehook_clone_prepare(). + * This is not a good place to block, because the child has not started yet. + * Suspend the child here if desired, and block in tracehook_clone_complete(). + * This must prevent the child from self-reaping if tracehook_clone_complete() + * uses the @child pointer; otherwise it might have died and been released by + * the time tracehook_report_clone_complete() is called. + * + * Called with no locks held, but the child cannot run until this returns. + */ +static inline void tracehook_report_clone(int trace, struct pt_regs *regs, + unsigned long clone_flags, + pid_t pid, struct task_struct *child) +{ + if (unlikely(trace)) { + /* + * The child starts up with an immediate SIGSTOP. + */ + sigaddset(&child->pending.signal, SIGSTOP); + set_tsk_thread_flag(child, TIF_SIGPENDING); + } +} + +/** + * tracehook_report_clone_complete - new child is running + * @trace: return value from tracehook_clone_prepare() + * @regs: parent's user register state + * @clone_flags: flags from parent's system call + * @pid: new child's PID in the parent's namespace + * @child: child task, already running + * + * This is called just after the child has started running. This is + * just before the clone/fork syscall returns, or blocks for vfork + * child completion if @clone_flags has the %CLONE_VFORK bit set. + * The @child pointer may be invalid if a self-reaping child died and + * tracehook_report_clone() took no action to prevent it from self-reaping. + * + * Called with no locks held. + */ +static inline void tracehook_report_clone_complete(int trace, + struct pt_regs *regs, + unsigned long clone_flags, + pid_t pid, + struct task_struct *child) +{ + if (unlikely(trace)) + ptrace_event(0, trace, pid); +} + #endif /* */ diff --git a/kernel/fork.c b/kernel/fork.c index 80e83e459b17..b42f8ed23611 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -865,8 +866,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) new_flags &= ~PF_SUPERPRIV; new_flags |= PF_FORKNOEXEC; - if (!(clone_flags & CLONE_PTRACE)) - p->ptrace = 0; + new_flags |= PF_STARTING; p->flags = new_flags; clear_freeze_flag(p); } @@ -907,7 +907,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, struct pt_regs *regs, unsigned long stack_size, int __user *child_tidptr, - struct pid *pid) + struct pid *pid, + int trace) { int retval; struct task_struct *p; @@ -1163,8 +1164,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, */ p->group_leader = p; INIT_LIST_HEAD(&p->thread_group); - INIT_LIST_HEAD(&p->ptrace_entry); - INIT_LIST_HEAD(&p->ptraced); /* Now that the task is set up, run cgroup callbacks if * necessary. We need to run them before the task is visible @@ -1195,7 +1194,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->real_parent = current->real_parent; else p->real_parent = current; - p->parent = p->real_parent; spin_lock(¤t->sighand->siglock); @@ -1237,8 +1235,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (likely(p->pid)) { list_add_tail(&p->sibling, &p->real_parent->children); - if (unlikely(p->ptrace & PT_PTRACED)) - __ptrace_link(p, current->parent); + tracehook_finish_clone(p, clone_flags, trace); if (thread_group_leader(p)) { if (clone_flags & CLONE_NEWPID) @@ -1323,29 +1320,13 @@ struct task_struct * __cpuinit fork_idle(int cpu) struct pt_regs regs; task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, - &init_struct_pid); + &init_struct_pid, 0); if (!IS_ERR(task)) init_idle(task, cpu); return task; } -static int fork_traceflag(unsigned clone_flags) -{ - if (clone_flags & CLONE_UNTRACED) - return 0; - else if (clone_flags & CLONE_VFORK) { - if (current->ptrace & PT_TRACE_VFORK) - return PTRACE_EVENT_VFORK; - } else if ((clone_flags & CSIGNAL) != SIGCHLD) { - if (current->ptrace & PT_TRACE_CLONE) - return PTRACE_EVENT_CLONE; - } else if (current->ptrace & PT_TRACE_FORK) - return PTRACE_EVENT_FORK; - - return 0; -} - /* * Ok, this is the main fork-routine. * @@ -1380,14 +1361,14 @@ long do_fork(unsigned long clone_flags, } } - if (unlikely(current->ptrace)) { - trace = fork_traceflag (clone_flags); - if (trace) - clone_flags |= CLONE_PTRACE; - } + /* + * When called from kernel_thread, don't do user tracing stuff. + */ + if (likely(user_mode(regs))) + trace = tracehook_prepare_clone(clone_flags); p = copy_process(clone_flags, stack_start, regs, stack_size, - child_tidptr, NULL); + child_tidptr, NULL, trace); /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. @@ -1405,24 +1386,30 @@ long do_fork(unsigned long clone_flags, init_completion(&vfork); } - if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) { + tracehook_report_clone(trace, regs, clone_flags, nr, p); + + /* + * We set PF_STARTING at creation in case tracing wants to + * use this to distinguish a fully live task from one that + * hasn't gotten to tracehook_report_clone() yet. Now we + * clear it and set the child going. + */ + p->flags &= ~PF_STARTING; + + if (unlikely(clone_flags & CLONE_STOPPED)) { /* * We'll start up with an immediate SIGSTOP. */ sigaddset(&p->pending.signal, SIGSTOP); set_tsk_thread_flag(p, TIF_SIGPENDING); - } - - if (!(clone_flags & CLONE_STOPPED)) - wake_up_new_task(p, clone_flags); - else __set_task_state(p, TASK_STOPPED); - - if (unlikely (trace)) { - current->ptrace_message = nr; - ptrace_notify ((trace << 8) | SIGTRAP); + } else { + wake_up_new_task(p, clone_flags); } + tracehook_report_clone_complete(trace, regs, + clone_flags, nr, p); + if (clone_flags & CLONE_VFORK) { freezer_do_not_count(); wait_for_completion(&vfork); From daded34be96b1975ff8539ff62ad8b158ce7d842 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:47 -0700 Subject: [PATCH 124/179] tracehook: vfork-done This moves the PTRACE_EVENT_VFORK_DONE tracing into a tracehook.h inline, tracehook_report_vfork_done(). The change has no effect, just clean-up. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 18 ++++++++++++++++++ kernel/fork.c | 5 +---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 3ebc58b59766..830e6e16097d 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -210,4 +210,22 @@ static inline void tracehook_report_clone_complete(int trace, ptrace_event(0, trace, pid); } +/** + * tracehook_report_vfork_done - vfork parent's child has exited or exec'd + * @child: child task, already running + * @pid: new child's PID in the parent's namespace + * + * Called after a %CLONE_VFORK parent has waited for the child to complete. + * The clone/vfork system call will return immediately after this. + * The @child pointer may be invalid if a self-reaping child died and + * tracehook_report_clone() took no action to prevent it from self-reaping. + * + * Called with no locks held. + */ +static inline void tracehook_report_vfork_done(struct task_struct *child, + pid_t pid) +{ + ptrace_event(PT_TRACE_VFORK_DONE, PTRACE_EVENT_VFORK_DONE, pid); +} + #endif /* */ diff --git a/kernel/fork.c b/kernel/fork.c index b42f8ed23611..abb3ed6298f6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1414,10 +1414,7 @@ long do_fork(unsigned long clone_flags, freezer_do_not_count(); wait_for_completion(&vfork); freezer_count(); - if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) { - current->ptrace_message = nr; - ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP); - } + tracehook_report_vfork_done(p, nr); } } else { nr = PTR_ERR(p); From dae33574dcf5211e1f43c7e45fa29f73ba3e00cb Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:48 -0700 Subject: [PATCH 125/179] tracehook: release_task This moves the ptrace-related logic from release_task into tracehook.h and ptrace.h inlines. It provides clean hooks both before and after locking tasklist_lock, for future tracing logic to do more cleanup without the lock. This also changes release_task() itself in the rare "zap_leader" case to set the leader to EXIT_DEAD before iterating. This maintains the invariant that release_task() only ever handles a task in EXIT_DEAD. This is a common-sense invariant that is already always true except in this one arcane case of zombie leader whose parent ignores SIGCHLD. This change is harmless and only costs one store in this one rare case. It keeps the expected state more consisently sane, which is nicer when debugging weirdness in release_task(). It also lets some future code in the tracehook entry points rely on this invariant for bookkeeping. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ptrace.h | 13 +++++++++++++ include/linux/tracehook.h | 28 ++++++++++++++++++++++++++++ kernel/exit.c | 21 +++++++++------------ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index dae6d85520fb..ed69c03692d9 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -176,6 +176,19 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) } } +/** + * ptrace_release_task - final ptrace-related cleanup of a zombie being reaped + * @task: task in %EXIT_DEAD state + * + * Called with write_lock(&tasklist_lock) held. + */ +static inline void ptrace_release_task(struct task_struct *task) +{ + BUG_ON(!list_empty(&task->ptraced)); + ptrace_unlink(task); + BUG_ON(!list_empty(&task->ptrace_entry)); +} + #ifndef force_successful_syscall_return /* * System call handlers that, upon successful completion, need to return a diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 830e6e16097d..9a5b3be2503a 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -228,4 +228,32 @@ static inline void tracehook_report_vfork_done(struct task_struct *child, ptrace_event(PT_TRACE_VFORK_DONE, PTRACE_EVENT_VFORK_DONE, pid); } +/** + * tracehook_prepare_release_task - task is being reaped, clean up tracing + * @task: task in %EXIT_DEAD state + * + * This is called in release_task() just before @task gets finally reaped + * and freed. This would be the ideal place to remove and clean up any + * tracing-related state for @task. + * + * Called with no locks held. + */ +static inline void tracehook_prepare_release_task(struct task_struct *task) +{ +} + +/** + * tracehook_finish_release_task - task is being reaped, clean up tracing + * @task: task in %EXIT_DEAD state + * + * This is called in release_task() when @task is being in the middle of + * being reaped. After this, there must be no tracing entanglements. + * + * Called with write_lock_irq(&tasklist_lock) held. + */ +static inline void tracehook_finish_release_task(struct task_struct *task) +{ + ptrace_release_task(task); +} + #endif /* */ diff --git a/kernel/exit.c b/kernel/exit.c index c3691cbc220a..da28745f7c38 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -163,27 +163,17 @@ static void delayed_put_task_struct(struct rcu_head *rhp) put_task_struct(container_of(rhp, struct task_struct, rcu)); } -/* - * Do final ptrace-related cleanup of a zombie being reaped. - * - * Called with write_lock(&tasklist_lock) held. - */ -static void ptrace_release_task(struct task_struct *p) -{ - BUG_ON(!list_empty(&p->ptraced)); - ptrace_unlink(p); - BUG_ON(!list_empty(&p->ptrace_entry)); -} void release_task(struct task_struct * p) { struct task_struct *leader; int zap_leader; repeat: + tracehook_prepare_release_task(p); atomic_dec(&p->user->processes); proc_flush_task(p); write_lock_irq(&tasklist_lock); - ptrace_release_task(p); + tracehook_finish_release_task(p); __exit_signal(p); /* @@ -205,6 +195,13 @@ void release_task(struct task_struct * p) * that case. */ zap_leader = task_detached(leader); + + /* + * This maintains the invariant that release_task() + * only runs on a task in EXIT_DEAD, just for sanity. + */ + if (zap_leader) + leader->exit_state = EXIT_DEAD; } write_unlock_irq(&tasklist_lock); From 0d094efeb1e98010c6b99923f1eb7e17bf1e3a74 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:49 -0700 Subject: [PATCH 126/179] tracehook: tracehook_tracer_task This adds the tracehook_tracer_task() hook to consolidate all forms of "Who is using ptrace on me?" logic. This is used for "TracerPid:" in /proc and for permission checks. We also clean up the selinux code the called an identical accessor. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/array.c | 9 +++++++-- fs/proc/base.c | 13 +++++++++---- include/linux/tracehook.h | 18 ++++++++++++++++++ security/selinux/hooks.c | 22 +++------------------- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/fs/proc/array.c b/fs/proc/array.c index 797d775e0354..0d6eb33597c6 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -80,6 +80,7 @@ #include #include #include +#include #include #include @@ -168,8 +169,12 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, rcu_read_lock(); ppid = pid_alive(p) ? task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; - tpid = pid_alive(p) && p->ptrace ? - task_pid_nr_ns(rcu_dereference(p->parent), ns) : 0; + tpid = 0; + if (pid_alive(p)) { + struct task_struct *tracer = tracehook_tracer_task(p); + if (tracer) + tpid = task_pid_nr_ns(tracer, ns); + } seq_printf(m, "State:\t%s\n" "Tgid:\t%d\n" diff --git a/fs/proc/base.c b/fs/proc/base.c index a891fe4cb43b..4b74dba69a6d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -231,10 +232,14 @@ static int check_mem_permission(struct task_struct *task) * If current is actively ptrace'ing, and would also be * permitted to freshly attach with ptrace now, permit it. */ - if (task->parent == current && (task->ptrace & PT_PTRACED) && - task_is_stopped_or_traced(task) && - ptrace_may_access(task, PTRACE_MODE_ATTACH)) - return 0; + if (task_is_stopped_or_traced(task)) { + int match; + rcu_read_lock(); + match = (tracehook_tracer_task(task) == current); + rcu_read_unlock(); + if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) + return 0; + } /* * Noone else is allowed. diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 9a5b3be2503a..6468ca0fe69b 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -72,6 +72,24 @@ static inline int tracehook_unsafe_exec(struct task_struct *task) return unsafe; } +/** + * tracehook_tracer_task - return the task that is tracing the given task + * @tsk: task to consider + * + * Returns NULL if noone is tracing @task, or the &struct task_struct + * pointer to its tracer. + * + * Must called under rcu_read_lock(). The pointer returned might be kept + * live only by RCU. During exec, this may be called with task_lock() + * held on @task, still held from when tracehook_unsafe_exec() was called. + */ +static inline struct task_struct *tracehook_tracer_task(struct task_struct *tsk) +{ + if (task_ptrace(tsk) & PT_PTRACED) + return rcu_dereference(tsk->parent); + return NULL; +} + /** * tracehook_report_exec - a successful exec was completed * @fmt: &struct linux_binfmt that performed the exec diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 63f131fc42e4..3481cde5bf15 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -1971,22 +1971,6 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) return __vm_enough_memory(mm, pages, cap_sys_admin); } -/** - * task_tracer_task - return the task that is tracing the given task - * @task: task to consider - * - * Returns NULL if noone is tracing @task, or the &struct task_struct - * pointer to its tracer. - * - * Must be called under rcu_read_lock(). - */ -static struct task_struct *task_tracer_task(struct task_struct *task) -{ - if (task->ptrace & PT_PTRACED) - return rcu_dereference(task->parent); - return NULL; -} - /* binprm security operations */ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) @@ -2238,7 +2222,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) u32 ptsid = 0; rcu_read_lock(); - tracer = task_tracer_task(current); + tracer = tracehook_tracer_task(current); if (likely(tracer != NULL)) { sec = tracer->security; ptsid = sec->sid; @@ -5247,7 +5231,7 @@ static int selinux_setprocattr(struct task_struct *p, Otherwise, leave SID unchanged and fail. */ task_lock(p); rcu_read_lock(); - tracer = task_tracer_task(p); + tracer = tracehook_tracer_task(p); if (tracer != NULL) { struct task_security_struct *ptsec = tracer->security; u32 ptsid = ptsec->sid; From fa8e26ccd485216fc45c8c2dd1ec3b7ef1a0a2f8 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:50 -0700 Subject: [PATCH 127/179] tracehook: tracehook_expect_breakpoints This adds tracehook_expect_breakpoints() as a formal hook for the nommu code to use for its, "Is text-poking likely?" check at mmap time. This names the actual semantics the code means to test, and documents it. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 15 +++++++++++++++ mm/nommu.c | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 6468ca0fe69b..e113e09b0341 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -51,6 +51,21 @@ #include struct linux_binprm; +/** + * tracehook_expect_breakpoints - guess if task memory might be touched + * @task: current task, making a new mapping + * + * Return nonzero if @task is expected to want breakpoint insertion in + * its memory at some point. A zero return is no guarantee it won't + * be done, but this is a hint that it's known to be likely. + * + * May be called with @task->mm->mmap_sem held for writing. + */ +static inline int tracehook_expect_breakpoints(struct task_struct *task) +{ + return (task_ptrace(task) & PT_PTRACED) != 0; +} + /** * tracehook_unsafe_exec - check for exec declared unsafe due to tracing * @task: current task doing exec diff --git a/mm/nommu.c b/mm/nommu.c index 4462b6a3fcb9..5edccd9c9218 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -745,7 +745,7 @@ static unsigned long determine_vm_flags(struct file *file, * it's being traced - otherwise breakpoints set in it may interfere * with another untraced process */ - if ((flags & MAP_PRIVATE) && (current->ptrace & PT_PTRACED)) + if ((flags & MAP_PRIVATE) && tracehook_expect_breakpoints(current)) vm_flags &= ~VM_MAYSHARE; return vm_flags; From c45aea27617d6a1e0aacddc3b0233f704222fcbd Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:50 -0700 Subject: [PATCH 128/179] tracehook: tracehook_signal_handler This defines tracehook_signal_handler() as a hook for the arch signal handling code to call. It gives ptrace the opportunity to stop for a pseudo-single-step trap immediately after signal handler setup is done. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index e113e09b0341..2d1426f8e33b 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -289,4 +289,27 @@ static inline void tracehook_finish_release_task(struct task_struct *task) ptrace_release_task(task); } +/** + * tracehook_signal_handler - signal handler setup is complete + * @sig: number of signal being delivered + * @info: siginfo_t of signal being delivered + * @ka: sigaction setting that chose the handler + * @regs: user register state + * @stepping: nonzero if debugger single-step or block-step in use + * + * Called by the arch code after a signal handler has been set up. + * Register and stack state reflects the user handler about to run. + * Signal mask changes have already been made. + * + * Called without locks, shortly before returning to user mode + * (or handling more signals). + */ +static inline void tracehook_signal_handler(int sig, siginfo_t *info, + const struct k_sigaction *ka, + struct pt_regs *regs, int stepping) +{ + if (stepping) + ptrace_notify(SIGTRAP); +} + #endif /* */ From 35de254dc60f91004b3b5ebb1fc7b2c3093d6032 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:51 -0700 Subject: [PATCH 129/179] tracehook: tracehook_consider_ignored_signal This defines tracehook_consider_ignored_signal() has a fine-grained hook for deciding to prevent the normal short-circuit of sending an ignored signal, as ptrace does. There is no change, only cleanup. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 19 +++++++++++++++++++ kernel/signal.c | 27 ++++++++++++++++----------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 2d1426f8e33b..8cffd34f88d5 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -312,4 +312,23 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, ptrace_notify(SIGTRAP); } +/** + * tracehook_consider_ignored_signal - suppress short-circuit of ignored signal + * @task: task receiving the signal + * @sig: signal number being sent + * @handler: %SIG_IGN or %SIG_DFL + * + * Return zero iff tracing doesn't care to examine this ignored signal, + * so it can short-circuit normal delivery and never even get queued. + * Either @handler is %SIG_DFL and @sig's default is ignore, or it's %SIG_IGN. + * + * Called with @task->sighand->siglock held. + */ +static inline int tracehook_consider_ignored_signal(struct task_struct *task, + int sig, + void __user *handler) +{ + return (task_ptrace(task) & PT_PTRACED) != 0; +} + #endif /* */ diff --git a/kernel/signal.c b/kernel/signal.c index 8715c18b27b9..9efd1cee6d0b 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -39,24 +40,21 @@ static struct kmem_cache *sigqueue_cachep; -static int __sig_ignored(struct task_struct *t, int sig) +static void __user *sig_handler(struct task_struct *t, int sig) { - void __user *handler; + return t->sighand->action[sig - 1].sa.sa_handler; +} +static int sig_handler_ignored(void __user *handler, int sig) +{ /* Is it explicitly or implicitly ignored? */ - - handler = t->sighand->action[sig - 1].sa.sa_handler; return handler == SIG_IGN || (handler == SIG_DFL && sig_kernel_ignore(sig)); } static int sig_ignored(struct task_struct *t, int sig) { - /* - * Tracers always want to know about signals.. - */ - if (t->ptrace & PT_PTRACED) - return 0; + void __user *handler; /* * Blocked signals are never ignored, since the @@ -66,7 +64,14 @@ static int sig_ignored(struct task_struct *t, int sig) if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) return 0; - return __sig_ignored(t, sig); + handler = sig_handler(t, sig); + if (!sig_handler_ignored(handler, sig)) + return 0; + + /* + * Tracers may want to know about even ignored signals. + */ + return !tracehook_consider_ignored_signal(t, sig, handler); } /* @@ -2298,7 +2303,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) * (for example, SIGCHLD), shall cause the pending signal to * be discarded, whether or not it is blocked" */ - if (__sig_ignored(t, sig)) { + if (sig_handler_ignored(sig_handler(t, sig), sig)) { sigemptyset(&mask); sigaddset(&mask, sig); rm_from_queue_full(&mask, &t->signal->shared_pending); From 445a91d2fe3667fb8fc251433645f686933cf56a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:52 -0700 Subject: [PATCH 130/179] tracehook: tracehook_consider_fatal_signal This defines tracehook_consider_fatal_signal() has a fine-grained hook for deciding to skip the special cases for a fatal signal, as ptrace does. There is no change, only cleanup. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 21 +++++++++++++++++++++ kernel/signal.c | 9 +++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 8cffd34f88d5..8b4c15e208fe 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -331,4 +331,25 @@ static inline int tracehook_consider_ignored_signal(struct task_struct *task, return (task_ptrace(task) & PT_PTRACED) != 0; } +/** + * tracehook_consider_fatal_signal - suppress special handling of fatal signal + * @task: task receiving the signal + * @sig: signal number being sent + * @handler: %SIG_DFL or %SIG_IGN + * + * Return nonzero to prevent special handling of this termination signal. + * Normally @handler is %SIG_DFL. It can be %SIG_IGN if @sig is ignored, + * in which case force_sig() is about to reset it to %SIG_DFL. + * When this returns zero, this signal might cause a quick termination + * that does not give the debugger a chance to intercept the signal. + * + * Called with or without @task->sighand->siglock held. + */ +static inline int tracehook_consider_fatal_signal(struct task_struct *task, + int sig, + void __user *handler) +{ + return (task_ptrace(task) & PT_PTRACED) != 0; +} + #endif /* */ diff --git a/kernel/signal.c b/kernel/signal.c index 9efd1cee6d0b..1a942ce32ba0 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -300,12 +300,12 @@ flush_signal_handlers(struct task_struct *t, int force_default) int unhandled_signal(struct task_struct *tsk, int sig) { + void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler; if (is_global_init(tsk)) return 1; - if (tsk->ptrace & PT_PTRACED) + if (handler != SIG_IGN && handler != SIG_DFL) return 0; - return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || - (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); + return !tracehook_consider_fatal_signal(tsk, sig, handler); } @@ -761,7 +761,8 @@ static void complete_signal(int sig, struct task_struct *p, int group) if (sig_fatal(p, sig) && !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && !sigismember(&t->real_blocked, sig) && - (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) { + (sig == SIGKILL || + !tracehook_consider_fatal_signal(t, sig, SIG_DFL))) { /* * This signal will be fatal to the whole group. */ From 283d7559e7712f95a05331eb0a85394c6368101b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:52 -0700 Subject: [PATCH 131/179] tracehook: syscall This adds standard tracehook.h inlines for arch code to call when TIF_SYSCALL_TRACE has been set. This replaces having each arch implement the ptrace guts for its syscall tracing support. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 8b4c15e208fe..3548694a24db 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -66,6 +66,76 @@ static inline int tracehook_expect_breakpoints(struct task_struct *task) return (task_ptrace(task) & PT_PTRACED) != 0; } +/* + * ptrace report for syscall entry and exit looks identical. + */ +static inline void ptrace_report_syscall(struct pt_regs *regs) +{ + int ptrace = task_ptrace(current); + + if (!(ptrace & PT_PTRACED)) + return; + + ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); + + /* + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl + */ + if (current->exit_code) { + send_sig(current->exit_code, current, 1); + current->exit_code = 0; + } +} + +/** + * tracehook_report_syscall_entry - task is about to attempt a system call + * @regs: user register state of current task + * + * This will be called if %TIF_SYSCALL_TRACE has been set, when the + * current task has just entered the kernel for a system call. + * Full user register state is available here. Changing the values + * in @regs can affect the system call number and arguments to be tried. + * It is safe to block here, preventing the system call from beginning. + * + * Returns zero normally, or nonzero if the calling arch code should abort + * the system call. That must prevent normal entry so no system call is + * made. If @task ever returns to user mode after this, its register state + * is unspecified, but should be something harmless like an %ENOSYS error + * return. + * + * Called without locks, just after entering kernel mode. + */ +static inline __must_check int tracehook_report_syscall_entry( + struct pt_regs *regs) +{ + ptrace_report_syscall(regs); + return 0; +} + +/** + * tracehook_report_syscall_exit - task has just finished a system call + * @regs: user register state of current task + * @step: nonzero if simulating single-step or block-step + * + * This will be called if %TIF_SYSCALL_TRACE has been set, when the + * current task has just finished an attempted system call. Full + * user register state is available here. It is safe to block here, + * preventing signals from being processed. + * + * If @step is nonzero, this report is also in lieu of the normal + * trap that would follow the system call instruction because + * user_enable_block_step() or user_enable_single_step() was used. + * In this case, %TIF_SYSCALL_TRACE might not be set. + * + * Called without locks, just before checking for pending signals. + */ +static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) +{ + ptrace_report_syscall(regs); +} + /** * tracehook_unsafe_exec - check for exec declared unsafe due to tracing * @task: current task doing exec From 7bcf6a2ca5f639b038c48711ebe6c4eca2036641 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:53 -0700 Subject: [PATCH 132/179] tracehook: get_signal_to_deliver This defines the tracehook_get_signal() hook to allow tracing code to slip in before normal signal dequeuing. This lays the groundwork for new tracing features that can inject synthetic signals outside the normal queue or control the disposition of delivered signals. The calling convention lets tracehook_get_signal() decide both exactly what will happen and what signal number to report in the handler/exit. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 29 +++++++++++++++++++++++++++++ kernel/signal.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 3548694a24db..42a0d7b11959 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -422,4 +422,33 @@ static inline int tracehook_consider_fatal_signal(struct task_struct *task, return (task_ptrace(task) & PT_PTRACED) != 0; } +/** + * tracehook_get_signal - deliver synthetic signal to traced task + * @task: @current + * @regs: task_pt_regs(@current) + * @info: details of synthetic signal + * @return_ka: sigaction for synthetic signal + * + * Return zero to check for a real pending signal normally. + * Return -1 after releasing the siglock to repeat the check. + * Return a signal number to induce an artifical signal delivery, + * setting *@info and *@return_ka to specify its details and behavior. + * + * The @return_ka->sa_handler value controls the disposition of the + * signal, no matter the signal number. For %SIG_DFL, the return value + * is a representative signal to indicate the behavior (e.g. %SIGTERM + * for death, %SIGQUIT for core dump, %SIGSTOP for job control stop, + * %SIGTSTP for stop unless in an orphaned pgrp), but the signal number + * reported will be @info->si_signo instead. + * + * Called with @task->sighand->siglock held, before dequeuing pending signals. + */ +static inline int tracehook_get_signal(struct task_struct *task, + struct pt_regs *regs, + siginfo_t *info, + struct k_sigaction *return_ka) +{ + return 0; +} + #endif /* */ diff --git a/kernel/signal.c b/kernel/signal.c index 1a942ce32ba0..10b31ecdd9c8 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1754,17 +1754,33 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, do_signal_stop(0)) goto relock; - signr = dequeue_signal(current, ¤t->blocked, info); - if (!signr) - break; /* will return 0 */ + /* + * Tracing can induce an artifical signal and choose sigaction. + * The return value in @signr determines the default action, + * but @info->si_signo is the signal number we will report. + */ + signr = tracehook_get_signal(current, regs, info, return_ka); + if (unlikely(signr < 0)) + goto relock; + if (unlikely(signr != 0)) + ka = return_ka; + else { + signr = dequeue_signal(current, ¤t->blocked, + info); - if (signr != SIGKILL) { - signr = ptrace_signal(signr, info, regs, cookie); if (!signr) - continue; + break; /* will return 0 */ + + if (signr != SIGKILL) { + signr = ptrace_signal(signr, info, + regs, cookie); + if (!signr) + continue; + } + + ka = &sighand->action[signr-1]; } - ka = &sighand->action[signr-1]; if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ continue; if (ka->sa.sa_handler != SIG_DFL) { @@ -1812,7 +1828,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, spin_lock_irq(&sighand->siglock); } - if (likely(do_signal_stop(signr))) { + if (likely(do_signal_stop(info->si_signo))) { /* It released the siglock. */ goto relock; } @@ -1833,7 +1849,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, if (sig_kernel_coredump(signr)) { if (print_fatal_signals) - print_fatal_signal(regs, signr); + print_fatal_signal(regs, info->si_signo); /* * If it was able to dump core, this kills all * other threads in the group and synchronizes with @@ -1842,13 +1858,13 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, * first and our do_group_exit call below will use * that value and ignore the one we pass it. */ - do_coredump((long)signr, signr, regs); + do_coredump(info->si_signo, info->si_signo, regs); } /* * Death signals, no core dump. */ - do_group_exit(signr); + do_group_exit(info->si_signo); /* NOTREACHED */ } spin_unlock_irq(&sighand->siglock); From fa00b80b3c41a845b3d56f866fb40a2e98754c51 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:54 -0700 Subject: [PATCH 133/179] tracehook: job control This defines the tracehook_notify_jctl() hook to formalize the ptrace effects on the job control notifications. There is no change, only cleanup. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 20 ++++++++++++++++++++ kernel/signal.c | 10 +++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 42a0d7b11959..6dc428dd2f38 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -451,4 +451,24 @@ static inline int tracehook_get_signal(struct task_struct *task, return 0; } +/** + * tracehook_notify_jctl - report about job control stop/continue + * @notify: nonzero if this is the last thread in the group to stop + * @why: %CLD_STOPPED or %CLD_CONTINUED + * + * This is called when we might call do_notify_parent_cldstop(). + * It's called when about to stop for job control; we are already in + * %TASK_STOPPED state, about to call schedule(). It's also called when + * a delayed %CLD_STOPPED or %CLD_CONTINUED report is ready to be made. + * + * Return nonzero to generate a %SIGCHLD with @why, which is + * normal if @notify is nonzero. + * + * Called with no locks held. + */ +static inline int tracehook_notify_jctl(int notify, int why) +{ + return notify || (current->ptrace & PT_PTRACED); +} + #endif /* */ diff --git a/kernel/signal.c b/kernel/signal.c index 10b31ecdd9c8..e9e699f4b1bd 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -596,9 +596,6 @@ static int check_kill_permission(int sig, struct siginfo *info, return security_task_kill(t, info, sig, 0); } -/* forward decl */ -static void do_notify_parent_cldstop(struct task_struct *tsk, int why); - /* * Handle magic process-wide effects of stop/continue signals. Unlike * the signal actions, these happen immediately at signal-generation @@ -1605,7 +1602,7 @@ finish_stop(int stop_count) * a group stop in progress and we are the last to stop, * report to the parent. When ptraced, every thread reports itself. */ - if (stop_count == 0 || (current->ptrace & PT_PTRACED)) { + if (tracehook_notify_jctl(stop_count == 0, CLD_STOPPED)) { read_lock(&tasklist_lock); do_notify_parent_cldstop(current, CLD_STOPPED); read_unlock(&tasklist_lock); @@ -1741,6 +1738,9 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, signal->flags &= ~SIGNAL_CLD_MASK; spin_unlock_irq(&sighand->siglock); + if (unlikely(!tracehook_notify_jctl(1, why))) + goto relock; + read_lock(&tasklist_lock); do_notify_parent_cldstop(current->group_leader, why); read_unlock(&tasklist_lock); @@ -1906,7 +1906,7 @@ void exit_signals(struct task_struct *tsk) out: spin_unlock_irq(&tsk->sighand->siglock); - if (unlikely(group_stop)) { + if (unlikely(group_stop) && tracehook_notify_jctl(1, CLD_STOPPED)) { read_lock(&tasklist_lock); do_notify_parent_cldstop(tsk, CLD_STOPPED); read_unlock(&tasklist_lock); From 2b2a1ff64afbadac842bbc58c5166962cf4f7664 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:54 -0700 Subject: [PATCH 134/179] tracehook: death This moves the ptrace logic in task death (exit_notify) into tracehook.h inlines. Some code is rearranged slightly to make things nicer. There is no change, only cleanup. There is one hook called with the tasklist_lock write-locked, as ptrace needs. There is also a new hook called after exit_state changes and without locks. This is a better place for tracing work to be in the future, since it doesn't delay the whole system with locking. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 2 +- include/linux/tracehook.h | 52 +++++++++++++++++++++++++++++++++++++++ kernel/exit.c | 26 +++++++------------- kernel/signal.c | 10 +++++--- 4 files changed, 69 insertions(+), 21 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index adb8077dc463..a95d84d0da95 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1796,7 +1796,7 @@ extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_ extern int kill_pgrp(struct pid *pid, int sig, int priv); extern int kill_pid(struct pid *pid, int sig, int priv); extern int kill_proc_info(int, struct siginfo *, pid_t); -extern void do_notify_parent(struct task_struct *, int); +extern int do_notify_parent(struct task_struct *, int); extern void force_sig(int, struct task_struct *); extern void force_sig_specific(int, struct task_struct *); extern int send_sig(int, struct task_struct *, int); diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 6dc428dd2f38..4c50e1b57349 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -471,4 +471,56 @@ static inline int tracehook_notify_jctl(int notify, int why) return notify || (current->ptrace & PT_PTRACED); } +/** + * tracehook_notify_death - task is dead, ready to notify parent + * @task: @current task now exiting + * @death_cookie: value to pass to tracehook_report_death() + * @group_dead: nonzero if this was the last thread in the group to die + * + * Return the signal number to send our parent with do_notify_parent(), or + * zero to send no signal and leave a zombie, or -1 to self-reap right now. + * + * Called with write_lock_irq(&tasklist_lock) held. + */ +static inline int tracehook_notify_death(struct task_struct *task, + void **death_cookie, int group_dead) +{ + if (task->exit_signal == -1) + return task->ptrace ? SIGCHLD : -1; + + /* + * If something other than our normal parent is ptracing us, then + * send it a SIGCHLD instead of honoring exit_signal. exit_signal + * only has special meaning to our real parent. + */ + if (thread_group_empty(task) && !ptrace_reparented(task)) + return task->exit_signal; + + return task->ptrace ? SIGCHLD : 0; +} + +/** + * tracehook_report_death - task is dead and ready to be reaped + * @task: @current task now exiting + * @signal: signal number sent to parent, or 0 or -1 + * @death_cookie: value passed back from tracehook_notify_death() + * @group_dead: nonzero if this was the last thread in the group to die + * + * Thread has just become a zombie or is about to self-reap. If positive, + * @signal is the signal number just sent to the parent (usually %SIGCHLD). + * If @signal is -1, this thread will self-reap. If @signal is 0, this is + * a delayed_group_leader() zombie. The @death_cookie was passed back by + * tracehook_notify_death(). + * + * If normal reaping is not inhibited, @task->exit_state might be changing + * in parallel. + * + * Called without locks. + */ +static inline void tracehook_report_death(struct task_struct *task, + int signal, void *death_cookie, + int group_dead) +{ +} + #endif /* */ diff --git a/kernel/exit.c b/kernel/exit.c index da28745f7c38..6cdf60712bd2 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -885,7 +885,8 @@ static void forget_original_parent(struct task_struct *father) */ static void exit_notify(struct task_struct *tsk, int group_dead) { - int state; + int signal; + void *cookie; /* * This does two things: @@ -922,22 +923,11 @@ static void exit_notify(struct task_struct *tsk, int group_dead) !capable(CAP_KILL)) tsk->exit_signal = SIGCHLD; - /* If something other than our normal parent is ptracing us, then - * send it a SIGCHLD instead of honoring exit_signal. exit_signal - * only has special meaning to our real parent. - */ - if (!task_detached(tsk) && thread_group_empty(tsk)) { - int signal = ptrace_reparented(tsk) ? - SIGCHLD : tsk->exit_signal; - do_notify_parent(tsk, signal); - } else if (tsk->ptrace) { - do_notify_parent(tsk, SIGCHLD); - } + signal = tracehook_notify_death(tsk, &cookie, group_dead); + if (signal > 0) + signal = do_notify_parent(tsk, signal); - state = EXIT_ZOMBIE; - if (task_detached(tsk) && likely(!tsk->ptrace)) - state = EXIT_DEAD; - tsk->exit_state = state; + tsk->exit_state = signal < 0 ? EXIT_DEAD : EXIT_ZOMBIE; /* mt-exec, de_thread() is waiting for us */ if (thread_group_leader(tsk) && @@ -947,8 +937,10 @@ static void exit_notify(struct task_struct *tsk, int group_dead) write_unlock_irq(&tasklist_lock); + tracehook_report_death(tsk, signal, cookie, group_dead); + /* If the process is dead, release it - nobody will wait for it */ - if (state == EXIT_DEAD) + if (signal < 0) release_task(tsk); } diff --git a/kernel/signal.c b/kernel/signal.c index e9e699f4b1bd..0e862d3130ff 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1326,9 +1326,11 @@ static inline void __wake_up_parent(struct task_struct *p, /* * Let a parent know about the death of a child. * For a stopped/continued status change, use do_notify_parent_cldstop instead. + * + * Returns -1 if our parent ignored us and so we've switched to + * self-reaping, or else @sig. */ - -void do_notify_parent(struct task_struct *tsk, int sig) +int do_notify_parent(struct task_struct *tsk, int sig) { struct siginfo info; unsigned long flags; @@ -1399,12 +1401,14 @@ void do_notify_parent(struct task_struct *tsk, int sig) */ tsk->exit_signal = -1; if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) - sig = 0; + sig = -1; } if (valid_signal(sig) && sig > 0) __group_send_sig_info(sig, &info, tsk->parent); __wake_up_parent(tsk, tsk->parent); spin_unlock_irqrestore(&psig->siglock, flags); + + return sig; } static void do_notify_parent_cldstop(struct task_struct *tsk, int why) From b787f7ba677840da16a2228c16571ce8a1fcb799 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:55 -0700 Subject: [PATCH 135/179] tracehook: force signal_pending() This defines a new hook tracehook_force_sigpending() that lets tracing code decide to force TIF_SIGPENDING on in recalc_sigpending(). This is not used yet, so it compiles away to nothing for now. It lays the groundwork for new tracing code that can interrupt a task synthetically without actually sending a signal. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 14 ++++++++++++++ kernel/signal.c | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 4c50e1b57349..43bc51b6bd33 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -422,6 +422,20 @@ static inline int tracehook_consider_fatal_signal(struct task_struct *task, return (task_ptrace(task) & PT_PTRACED) != 0; } +/** + * tracehook_force_sigpending - let tracing force signal_pending(current) on + * + * Called when recomputing our signal_pending() flag. Return nonzero + * to force the signal_pending() flag on, so that tracehook_get_signal() + * will be called before the next return to user mode. + * + * Called with @current->sighand->siglock held. + */ +static inline int tracehook_force_sigpending(void) +{ + return 0; +} + /** * tracehook_get_signal - deliver synthetic signal to traced task * @task: @current diff --git a/kernel/signal.c b/kernel/signal.c index 0e862d3130ff..954f77d7e3bc 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -134,7 +134,9 @@ void recalc_sigpending_and_wake(struct task_struct *t) void recalc_sigpending(void) { - if (!recalc_sigpending_tsk(current) && !freezing(current)) + if (unlikely(tracehook_force_sigpending())) + set_thread_flag(TIF_SIGPENDING); + else if (!recalc_sigpending_tsk(current) && !freezing(current)) clear_thread_flag(TIF_SIGPENDING); } From 64b1208d5b0ef8859fd52ea7ae286a3eb994669b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:56 -0700 Subject: [PATCH 136/179] tracehook: TIF_NOTIFY_RESUME This adds tracehook.h inlines to enable a new arch feature in support of user debugging/tracing. This is not used yet, but it lays the groundwork for a debugger to be able to wrangle a task that's possibly running, without interrupting its syscalls in progress. Each arch should define TIF_NOTIFY_RESUME, and in their entry.S code treat it much like TIF_SIGPENDING. That is, it causes you to take the slow path when returning to user mode, where you get the full user-mode state accessible as for signal handling or ptrace. The arch code should check TIF_NOTIFY_RESUME after handling TIF_SIGPENDING. When it's set, clear it and then call tracehook_notify_resume(). In future, tracing code will call set_notify_resume() when it wants to get a callback in tracehook_notify_resume(). Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/tracehook.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 43bc51b6bd33..32867ab86c70 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -537,4 +537,38 @@ static inline void tracehook_report_death(struct task_struct *task, { } +#ifdef TIF_NOTIFY_RESUME +/** + * set_notify_resume - cause tracehook_notify_resume() to be called + * @task: task that will call tracehook_notify_resume() + * + * Calling this arranges that @task will call tracehook_notify_resume() + * before returning to user mode. If it's already running in user mode, + * it will enter the kernel and call tracehook_notify_resume() soon. + * If it's blocked, it will not be woken. + */ +static inline void set_notify_resume(struct task_struct *task) +{ + if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME)) + kick_process(task); +} + +/** + * tracehook_notify_resume - report when about to return to user mode + * @regs: user-mode registers of @current task + * + * This is called when %TIF_NOTIFY_RESUME has been set. Now we are + * about to return to user mode, and the user state in @regs can be + * inspected or adjusted. The caller in arch code has cleared + * %TIF_NOTIFY_RESUME before the call. If the flag gets set again + * asynchronously, this will be called again before we return to + * user mode. + * + * Called without locks. + */ +static inline void tracehook_notify_resume(struct pt_regs *regs) +{ +} +#endif /* TIF_NOTIFY_RESUME */ + #endif /* */ From 828c365cc8b8d38c346fccb19fa80d28f2240831 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:57 -0700 Subject: [PATCH 137/179] tracehook: asm/syscall.h This adds asm-generic/syscall.h, which documents what a real asm-ARCH/syscall.h file should define. This is not used yet, but will provide all the machine-dependent details of examining a user system call about to begin, in progress, or just ended. Each arch should add an asm-ARCH/syscall.h that defines all the entry points documented in asm-generic/syscall.h, as short inlines if possible. This lets us write new tracing code that understands user system call registers, without any new arch-specific work. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/syscall.h | 141 ++++++++++++++++++++++++++++++++++ include/linux/tracehook.h | 3 +- 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 include/asm-generic/syscall.h diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h new file mode 100644 index 000000000000..abcf34c2fdc7 --- /dev/null +++ b/include/asm-generic/syscall.h @@ -0,0 +1,141 @@ +/* + * Access to user system call parameters and results + * + * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v.2. + * + * This file is a stub providing documentation for what functions + * asm-ARCH/syscall.h files need to define. Most arch definitions + * will be simple inlines. + * + * All of these functions expect to be called with no locks, + * and only when the caller is sure that the task of interest + * cannot return to user mode while we are looking at it. + */ + +#ifndef _ASM_SYSCALL_H +#define _ASM_SYSCALL_H 1 + +struct task_struct; +struct pt_regs; + +/** + * syscall_get_nr - find what system call a task is executing + * @task: task of interest, must be blocked + * @regs: task_pt_regs() of @task + * + * If @task is executing a system call or is at system call + * tracing about to attempt one, returns the system call number. + * If @task is not executing a system call, i.e. it's blocked + * inside the kernel for a fault or signal, returns -1. + * + * It's only valid to call this when @task is known to be blocked. + */ +long syscall_get_nr(struct task_struct *task, struct pt_regs *regs); + +/** + * syscall_rollback - roll back registers after an aborted system call + * @task: task of interest, must be in system call exit tracing + * @regs: task_pt_regs() of @task + * + * It's only valid to call this when @task is stopped for system + * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT), + * after tracehook_report_syscall_entry() returned nonzero to prevent + * the system call from taking place. + * + * This rolls back the register state in @regs so it's as if the + * system call instruction was a no-op. The registers containing + * the system call number and arguments are as they were before the + * system call instruction. This may not be the same as what the + * register state looked like at system call entry tracing. + */ +void syscall_rollback(struct task_struct *task, struct pt_regs *regs); + +/** + * syscall_get_error - check result of traced system call + * @task: task of interest, must be blocked + * @regs: task_pt_regs() of @task + * + * Returns 0 if the system call succeeded, or -ERRORCODE if it failed. + * + * It's only valid to call this when @task is stopped for tracing on exit + * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. + */ +long syscall_get_error(struct task_struct *task, struct pt_regs *regs); + +/** + * syscall_get_return_value - get the return value of a traced system call + * @task: task of interest, must be blocked + * @regs: task_pt_regs() of @task + * + * Returns the return value of the successful system call. + * This value is meaningless if syscall_get_error() returned nonzero. + * + * It's only valid to call this when @task is stopped for tracing on exit + * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. + */ +long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs); + +/** + * syscall_set_return_value - change the return value of a traced system call + * @task: task of interest, must be blocked + * @regs: task_pt_regs() of @task + * @error: negative error code, or zero to indicate success + * @val: user return value if @error is zero + * + * This changes the results of the system call that user mode will see. + * If @error is zero, the user sees a successful system call with a + * return value of @val. If @error is nonzero, it's a negated errno + * code; the user sees a failed system call with this errno code. + * + * It's only valid to call this when @task is stopped for tracing on exit + * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. + */ +void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, + int error, long val); + +/** + * syscall_get_arguments - extract system call parameter values + * @task: task of interest, must be blocked + * @regs: task_pt_regs() of @task + * @i: argument index [0,5] + * @n: number of arguments; n+i must be [1,6]. + * @args: array filled with argument values + * + * Fetches @n arguments to the system call starting with the @i'th argument + * (from 0 through 5). Argument @i is stored in @args[0], and so on. + * An arch inline version is probably optimal when @i and @n are constants. + * + * It's only valid to call this when @task is stopped for tracing on + * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. + * It's invalid to call this with @i + @n > 6; we only support system calls + * taking up to 6 arguments. + */ +void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, unsigned long *args); + +/** + * syscall_set_arguments - change system call parameter value + * @task: task of interest, must be in system call entry tracing + * @regs: task_pt_regs() of @task + * @i: argument index [0,5] + * @n: number of arguments; n+i must be [1,6]. + * @args: array of argument values to store + * + * Changes @n arguments to the system call starting with the @i'th argument. + * @n'th argument to @val. Argument @i gets value @args[0], and so on. + * An arch inline version is probably optimal when @i and @n are constants. + * + * It's only valid to call this when @task is stopped for tracing on + * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. + * It's invalid to call this with @i + @n > 6; we only support system calls + * taking up to 6 arguments. + */ +void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, + const unsigned long *args); + +#endif /* _ASM_SYSCALL_H */ diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 32867ab86c70..589f429619c9 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -103,7 +103,8 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) * the system call. That must prevent normal entry so no system call is * made. If @task ever returns to user mode after this, its register state * is unspecified, but should be something harmless like an %ENOSYS error - * return. + * return. It should preserve enough information so that syscall_rollback() + * can work (see asm-generic/syscall.h). * * Called without locks, just after entering kernel mode. */ From 1f5a4ad97a0e7b663d527ecc02aabe203d000d91 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:57 -0700 Subject: [PATCH 138/179] tracehook: CONFIG_HAVE_ARCH_TRACEHOOK This adds the generic HAVE_ARCH_TRACEHOOK kconfig item. Each arch should add to some Kconfig file: select HAVE_ARCH_TRACEHOOK if the arch code uses all the latest hooks to enable newfangled tracing and debugging code. The comment in arch/Kconfig lists all the prerequisite arch support. When all these are available, setting HAVE_ARCH_TRACEHOOK will allow enabling any new features that depend on the modern arch interfaces. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/Kconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index b0fabfa864ff..364c6dadde0a 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -59,6 +59,24 @@ config HAVE_KPROBES config HAVE_KRETPROBES def_bool n +# +# An arch should select this if it provides all these things: +# +# task_pt_regs() in asm/processor.h or asm/ptrace.h +# arch_has_single_step() if there is hardware single-step support +# arch_has_block_step() if there is hardware block-step support +# arch_ptrace() and not #define __ARCH_SYS_PTRACE +# compat_arch_ptrace() and #define __ARCH_WANT_COMPAT_SYS_PTRACE +# asm/syscall.h supplying asm-generic/syscall.h interface +# linux/regset.h user_regset interfaces +# CORE_DUMP_USE_REGSET #define'd in linux/elf.h +# TIF_SYSCALL_TRACE calls tracehook_report_syscall_{entry,exit} +# TIF_NOTIFY_RESUME calls tracehook_notify_resume() +# signal delivery calls tracehook_signal_handler() +# +config HAVE_ARCH_TRACEHOOK + def_bool n + config HAVE_DMA_ATTRS def_bool n From 85ba2d862e521375a8ee01526c5c46b1f24bb4af Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:58 -0700 Subject: [PATCH 139/179] tracehook: wait_task_inactive This extends wait_task_inactive() with a new argument so it can be used in a "soft" mode where it will check for the task changing state unexpectedly and back off. There is no change to existing callers. This lays the groundwork to allow robust, noninvasive tracing that can try to sample a blocked thread but back off safely if it wakes up. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/perfmon.c | 4 ++-- include/linux/sched.h | 8 ++++++-- kernel/kthread.c | 2 +- kernel/ptrace.c | 2 +- kernel/sched.c | 29 +++++++++++++++++++++++++++-- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 19d4493c6193..fc8f3509df27 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -2626,7 +2626,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task) /* * make sure the task is off any CPU */ - wait_task_inactive(task); + wait_task_inactive(task, 0); /* more to come... */ @@ -4774,7 +4774,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags) UNPROTECT_CTX(ctx, flags); - wait_task_inactive(task); + wait_task_inactive(task, 0); PROTECT_CTX(ctx, flags); diff --git a/include/linux/sched.h b/include/linux/sched.h index a95d84d0da95..f59318a0099b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1882,9 +1882,13 @@ extern void set_task_comm(struct task_struct *tsk, char *from); extern char *get_task_comm(char *to, struct task_struct *tsk); #ifdef CONFIG_SMP -extern void wait_task_inactive(struct task_struct * p); +extern unsigned long wait_task_inactive(struct task_struct *, long match_state); #else -#define wait_task_inactive(p) do { } while (0) +static inline unsigned long wait_task_inactive(struct task_struct *p, + long match_state) +{ + return 1; +} #endif #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) diff --git a/kernel/kthread.c b/kernel/kthread.c index 6111c27491b1..96cff2f8710b 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -176,7 +176,7 @@ void kthread_bind(struct task_struct *k, unsigned int cpu) return; } /* Must have done schedule() in kthread() before we set_task_cpu */ - wait_task_inactive(k); + wait_task_inactive(k, 0); set_task_cpu(k, cpu); k->cpus_allowed = cpumask_of_cpu(cpu); k->rt.nr_cpus_allowed = 1; diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 8392a9da6450..082b3fcb32a0 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -107,7 +107,7 @@ int ptrace_check_attach(struct task_struct *child, int kill) read_unlock(&tasklist_lock); if (!ret && !kill) - wait_task_inactive(child); + ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; /* All systems go.. */ return ret; diff --git a/kernel/sched.c b/kernel/sched.c index fde1a1026359..0236958addcb 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1867,16 +1867,24 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req) /* * wait_task_inactive - wait for a thread to unschedule. * + * If @match_state is nonzero, it's the @p->state value just checked and + * not expected to change. If it changes, i.e. @p might have woken up, + * then return zero. When we succeed in waiting for @p to be off its CPU, + * we return a positive number (its total switch count). If a second call + * a short while later returns the same number, the caller can be sure that + * @p has remained unscheduled the whole time. + * * The caller must ensure that the task *will* unschedule sometime soon, * else this function might spin for a *long* time. This function can't * be called with interrupts off, or it may introduce deadlock with * smp_call_function() if an IPI is sent by the same process we are * waiting to become inactive. */ -void wait_task_inactive(struct task_struct *p) +unsigned long wait_task_inactive(struct task_struct *p, long match_state) { unsigned long flags; int running, on_rq; + unsigned long ncsw; struct rq *rq; for (;;) { @@ -1899,8 +1907,11 @@ void wait_task_inactive(struct task_struct *p) * return false if the runqueue has changed and p * is actually now running somewhere else! */ - while (task_running(rq, p)) + while (task_running(rq, p)) { + if (match_state && unlikely(p->state != match_state)) + return 0; cpu_relax(); + } /* * Ok, time to look more closely! We need the rq @@ -1910,8 +1921,20 @@ void wait_task_inactive(struct task_struct *p) rq = task_rq_lock(p, &flags); running = task_running(rq, p); on_rq = p->se.on_rq; + ncsw = 0; + if (!match_state || p->state == match_state) { + ncsw = p->nivcsw + p->nvcsw; + if (unlikely(!ncsw)) + ncsw = 1; + } task_rq_unlock(rq, &flags); + /* + * If it changed from the expected state, bail out now. + */ + if (unlikely(!ncsw)) + break; + /* * Was it really running after all now that we * checked with the proper locks actually held? @@ -1944,6 +1967,8 @@ void wait_task_inactive(struct task_struct *p) */ break; } + + return ncsw; } /*** From bbc698636ed48b6fcd323964e0f847a6a796325d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:59 -0700 Subject: [PATCH 140/179] task_current_syscall This adds the new function task_current_syscall() on machines where the asm/syscall.h interface is supported (CONFIG_HAVE_ARCH_TRACEHOOK). It's exported for modules to use in the future. This function safely samples the state of a blocked thread to collect what system call it is blocked in, and the six system call argument registers. Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ptrace.h | 4 +++ lib/Makefile | 2 ++ lib/syscall.c | 75 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 lib/syscall.c diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index ed69c03692d9..fd31756e1a00 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -314,6 +314,10 @@ static inline void user_enable_block_step(struct task_struct *task) #define arch_ptrace_stop(code, info) do { } while (0) #endif +extern int task_current_syscall(struct task_struct *target, long *callno, + unsigned long args[6], unsigned int maxargs, + unsigned long *sp, unsigned long *pc); + #endif #endif diff --git a/lib/Makefile b/lib/Makefile index 9085ad6fa53d..942c7250f603 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -78,6 +78,8 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o obj-$(CONFIG_HAVE_LMB) += lmb.o +obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o + hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/lib/syscall.c b/lib/syscall.c new file mode 100644 index 000000000000..a4f7067f72fa --- /dev/null +++ b/lib/syscall.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +static int collect_syscall(struct task_struct *target, long *callno, + unsigned long args[6], unsigned int maxargs, + unsigned long *sp, unsigned long *pc) +{ + struct pt_regs *regs = task_pt_regs(target); + if (unlikely(!regs)) + return -EAGAIN; + + *sp = user_stack_pointer(regs); + *pc = instruction_pointer(regs); + + *callno = syscall_get_nr(target, regs); + if (*callno != -1L && maxargs > 0) + syscall_get_arguments(target, regs, 0, maxargs, args); + + return 0; +} + +/** + * task_current_syscall - Discover what a blocked task is doing. + * @target: thread to examine + * @callno: filled with system call number or -1 + * @args: filled with @maxargs system call arguments + * @maxargs: number of elements in @args to fill + * @sp: filled with user stack pointer + * @pc: filled with user PC + * + * If @target is blocked in a system call, returns zero with *@callno + * set to the the call's number and @args filled in with its arguments. + * Registers not used for system call arguments may not be available and + * it is not kosher to use &struct user_regset calls while the system + * call is still in progress. Note we may get this result if @target + * has finished its system call but not yet returned to user mode, such + * as when it's stopped for signal handling or syscall exit tracing. + * + * If @target is blocked in the kernel during a fault or exception, + * returns zero with *@callno set to -1 and does not fill in @args. + * If so, it's now safe to examine @target using &struct user_regset + * get() calls as long as we're sure @target won't return to user mode. + * + * Returns -%EAGAIN if @target does not remain blocked. + * + * Returns -%EINVAL if @maxargs is too large (maximum is six). + */ +int task_current_syscall(struct task_struct *target, long *callno, + unsigned long args[6], unsigned int maxargs, + unsigned long *sp, unsigned long *pc) +{ + long state; + unsigned long ncsw; + + if (unlikely(maxargs > 6)) + return -EINVAL; + + if (target == current) + return collect_syscall(target, callno, args, maxargs, sp, pc); + + state = target->state; + if (unlikely(!state)) + return -EAGAIN; + + ncsw = wait_task_inactive(target, state); + if (unlikely(!ncsw) || + unlikely(collect_syscall(target, callno, args, maxargs, sp, pc)) || + unlikely(wait_task_inactive(target, state) != ncsw)) + return -EAGAIN; + + return 0; +} +EXPORT_SYMBOL_GPL(task_current_syscall); From ebcb67341fee34061430f3367f2e507e52ee051b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:46:00 -0700 Subject: [PATCH 141/179] /proc/PID/syscall This adds /proc/PID/syscall and /proc/PID/task/TID/syscall magic files. These use task_current_syscall() to show the task's current system call number and argument registers, stack pointer and PC. For a task blocked but not in a syscall, the file shows "-1" in place of the syscall number, followed by only the SP and PC. For a task that's not blocked, it shows "running". Signed-off-by: Roland McGrath Cc: Oleg Nesterov Reviewed-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/base.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/fs/proc/base.c b/fs/proc/base.c index 4b74dba69a6d..81bce6791bfc 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -509,6 +509,26 @@ static int proc_pid_limits(struct task_struct *task, char *buffer) return count; } +#ifdef CONFIG_HAVE_ARCH_TRACEHOOK +static int proc_pid_syscall(struct task_struct *task, char *buffer) +{ + long nr; + unsigned long args[6], sp, pc; + + if (task_current_syscall(task, &nr, args, 6, &sp, &pc)) + return sprintf(buffer, "running\n"); + + if (nr < 0) + return sprintf(buffer, "%ld 0x%lx 0x%lx\n", nr, sp, pc); + + return sprintf(buffer, + "%ld 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", + nr, + args[0], args[1], args[2], args[3], args[4], args[5], + sp, pc); +} +#endif /* CONFIG_HAVE_ARCH_TRACEHOOK */ + /************************************************************************/ /* Here the fs part begins */ /************************************************************************/ @@ -2477,6 +2497,9 @@ static const struct pid_entry tgid_base_stuff[] = { INF("limits", S_IRUSR, pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, pid_sched), +#endif +#ifdef CONFIG_HAVE_ARCH_TRACEHOOK + INF("syscall", S_IRUSR, pid_syscall), #endif INF("cmdline", S_IRUGO, pid_cmdline), ONE("stat", S_IRUGO, tgid_stat), @@ -2809,6 +2832,9 @@ static const struct pid_entry tid_base_stuff[] = { INF("limits", S_IRUSR, pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, pid_sched), +#endif +#ifdef CONFIG_HAVE_ARCH_TRACEHOOK + INF("syscall", S_IRUSR, pid_syscall), #endif INF("cmdline", S_IRUGO, pid_cmdline), ONE("stat", S_IRUGO, tid_stat), From 2c97b7fc0d8c8661981beb9517da342ced3b3bc7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:01 -0700 Subject: [PATCH 142/179] mm: print swapcache page count in show_swap_cache_info() Every arch implements its own show_mem() function. Most of them share quite some code, some of them are completely identical. This series implements a generic version of this function and migrates almost all architectures to it. This patch: Most show_mem() implementations calculate the amount of pages within the swapcache every time. Move the output to a more appropriate place and use the anyway available total_swapcache_pages variable. Signed-off-by: Johannes Weiner Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Haavard Skinnemoen Cc: Bryan Wu Cc: Chris Zankel Cc: Ingo Molnar Cc: Jeff Dike Cc: David S. Miller Cc: Paul Mundt Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: David Howells Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Yoshinori Sato Cc: Ralf Baechle Cc: Greg Ungerer Cc: Geert Uytterhoeven Cc: Roman Zippel Cc: Hirokazu Takata Cc: Mikael Starvik Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/swap_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/swap_state.c b/mm/swap_state.c index 2c217e33d497..b8035b055129 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -56,7 +56,8 @@ static struct { void show_swap_cache_info(void) { - printk("Swap cache: add %lu, delete %lu, find %lu/%lu\n", + printk("%lu pages in swap cache\n", total_swapcache_pages); + printk("Swap cache stats: add %lu, delete %lu, find %lu/%lu\n", swap_cache_info.add_total, swap_cache_info.del_total, swap_cache_info.find_success, swap_cache_info.find_total); printk("Free swap = %lukB\n", nr_swap_pages << (PAGE_SHIFT - 10)); From 454c63b02e530f10b4345343f63596dd705888d0 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:07 -0700 Subject: [PATCH 143/179] lib: generic show_mem() This implements a platform-independent version of show_mem(). Signed-off-by: Johannes Weiner Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Haavard Skinnemoen Cc: Bryan Wu Cc: Chris Zankel Cc: Ingo Molnar Cc: Jeff Dike Cc: David S. Miller Cc: Paul Mundt Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: David Howells Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Yoshinori Sato Cc: Ralf Baechle Cc: Greg Ungerer Cc: Geert Uytterhoeven Cc: Roman Zippel Cc: Hirokazu Takata Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/Makefile | 2 +- lib/show_mem.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 lib/show_mem.c diff --git a/lib/Makefile b/lib/Makefile index 942c7250f603..3b1f94bbe9de 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -11,7 +11,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ - proportions.o prio_heap.o ratelimit.o + proportions.o prio_heap.o ratelimit.o show_mem.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o diff --git a/lib/show_mem.c b/lib/show_mem.c new file mode 100644 index 000000000000..238e72a18ce1 --- /dev/null +++ b/lib/show_mem.c @@ -0,0 +1,63 @@ +/* + * Generic show_mem() implementation + * + * Copyright (C) 2008 Johannes Weiner + * All code subject to the GPL version 2. + */ + +#include +#include +#include + +void show_mem(void) +{ + pg_data_t *pgdat; + unsigned long total = 0, reserved = 0, shared = 0, + nonshared = 0, highmem = 0; + + printk(KERN_INFO "Mem-Info:\n"); + show_free_areas(); + + for_each_online_pgdat(pgdat) { + unsigned long i, flags; + + pgdat_resize_lock(pgdat, &flags); + for (i = 0; i < pgdat->node_spanned_pages; i++) { + struct page *page; + unsigned long pfn = pgdat->node_start_pfn + i; + + if (unlikely(!(i % MAX_ORDER_NR_PAGES))) + touch_nmi_watchdog(); + + if (!pfn_valid(pfn)) + continue; + + page = pfn_to_page(pfn); + + if (PageHighMem(page)) + highmem++; + + if (PageReserved(page)) + reserved++; + else if (page_count(page) == 1) + nonshared++; + else if (page_count(page) > 1) + shared += page_count(page) - 1; + + total++; + } + pgdat_resize_unlock(pgdat, &flags); + } + + printk(KERN_INFO "%lu pages RAM\n", total); +#ifdef CONFIG_HIGHMEM + printk(KERN_INFO "%lu pages HighMem\n", highmem); +#endif + printk(KERN_INFO "%lu pages reserved\n", reserved); + printk(KERN_INFO "%lu pages shared\n", shared); + printk(KERN_INFO "%lu pages non-shared\n", nonshared); +#ifdef CONFIG_QUICKLIST + printk(KERN_INFO "%lu pages in pagetable cache\n", + quicklist_total_size()); +#endif +} From 5f834b9f3bd3769162fc169efd7ecae0712a2d1d Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:09 -0700 Subject: [PATCH 144/179] alpha: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - free swap pages, printed by show_swap_cache_info() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Cc: Richard Henderson Cc: Ivan Kokshaysky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/mm/init.c | 30 ------------------------------ arch/alpha/mm/numa.c | 35 ----------------------------------- 2 files changed, 65 deletions(-) diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 40c15e7301de..234e42b8ee74 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -94,36 +94,6 @@ __bad_page(void) return pte_mkdirty(mk_pte(virt_to_page(EMPTY_PGE), PAGE_SHARED)); } -#ifndef CONFIG_DISCONTIGMEM -void -show_mem(void) -{ - long i,free = 0,total = 0,reserved = 0; - long shared = 0, cached = 0; - - printk("\nMem-info:\n"); - show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (!page_count(mem_map+i)) - free++; - else - shared += page_count(mem_map + i) - 1; - } - printk("%ld pages of RAM\n",total); - printk("%ld free pages\n",free); - printk("%ld reserved pages\n",reserved); - printk("%ld pages shared\n",shared); - printk("%ld pages swap cached\n",cached); -} -#endif - static inline unsigned long load_PCB(struct pcb_struct *pcb) { diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index d8c4ceaf00b9..a13de49d1265 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -359,38 +359,3 @@ void __init mem_init(void) mem_stress(); #endif } - -void -show_mem(void) -{ - long i,free = 0,total = 0,reserved = 0; - long shared = 0, cached = 0; - int nid; - - printk("\nMem-info:\n"); - show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - for_each_online_node(nid) { - unsigned long flags; - pgdat_resize_lock(NODE_DATA(nid), &flags); - i = node_spanned_pages(nid); - while (i-- > 0) { - struct page *page = nid_page_nr(nid, i); - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - } - pgdat_resize_unlock(NODE_DATA(nid), &flags); - } - printk("%ld pages of RAM\n",total); - printk("%ld free pages\n",free); - printk("%ld reserved pages\n",reserved); - printk("%ld pages shared\n",shared); - printk("%ld pages swap cached\n",cached); -} From 46244a2b3c1dfd83041bcf0428c584d3a66b30cc Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:09 -0700 Subject: [PATCH 145/179] avr32: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in slabs, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Haavard Skinnemoen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/avr32/mm/init.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c index 3c85fdaa9487..fa92ff6d95f7 100644 --- a/arch/avr32/mm/init.c +++ b/arch/avr32/mm/init.c @@ -38,45 +38,6 @@ EXPORT_SYMBOL(empty_zero_page); */ unsigned long mmu_context_cache = NO_CONTEXT; -void show_mem(void) -{ - int total = 0, reserved = 0, cached = 0; - int slab = 0, free = 0, shared = 0; - pg_data_t *pgdat; - - printk("Mem-info:\n"); - show_free_areas(); - - for_each_online_pgdat(pgdat) { - struct page *page, *end; - - page = pgdat->node_mem_map; - end = page + pgdat->node_spanned_pages; - - do { - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (PageSlab(page)) - slab++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - page++; - } while (page < end); - } - - printk ("%d pages of RAM\n", total); - printk ("%d free pages\n", free); - printk ("%d reserved pages\n", reserved); - printk ("%d slab pages\n", slab); - printk ("%d pages shared\n", shared); - printk ("%d pages swap cached\n", cached); -} - /* * paging_init() sets up the page tables * From a2e9c44337b53aef37f3382920a478cac3777ba9 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:10 -0700 Subject: [PATCH 146/179] blackfin: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Bryan Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/blackfin/mm/init.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index ec3141fefd20..4d5326ee9a85 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -53,33 +53,6 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; -void show_mem(void) -{ - unsigned long i; - int free = 0, total = 0, reserved = 0, shared = 0; - - int cached = 0; - printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map + i)) - reserved++; - else if (PageSwapCache(mem_map + i)) - cached++; - else if (!page_count(mem_map + i)) - free++; - else - shared += page_count(mem_map + i) - 1; - } - printk(KERN_INFO "%d pages of RAM\n", total); - printk(KERN_INFO "%d free pages\n", free); - printk(KERN_INFO "%d reserved pages\n", reserved); - printk(KERN_INFO "%d pages shared\n", shared); - printk(KERN_INFO "%d pages swap cached\n", cached); -} - /* * paging_init() continues the virtual memory environment setup which * was begun by the code in arch/head.S. From 47221222a59a565e11954c078a2cf6a07a7e690e Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:10 -0700 Subject: [PATCH 147/179] xtensa: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/mm/init.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index ee261005b363..34163cfaaffc 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -280,33 +280,6 @@ void free_initmem(void) (&__init_end - &__init_begin) >> 10); } -void show_mem(void) -{ - int i, free = 0, total = 0, reserved = 0; - int shared = 0, cached = 0; - - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (!page_count(mem_map + i)) - free++; - else - shared += page_count(mem_map + i) - 1; - } - printk("%d pages of RAM\n", total); - printk("%d reserved pages\n", reserved); - printk("%d pages shared\n", shared); - printk("%d pages swap cached\n",cached); - printk("%d free pages\n", free); -} - struct kmem_cache *pgtable_cache __read_mostly; static void pgd_ctor(void* addr) From 8dad322f5449010c14990dd6934878f576b2ee60 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:11 -0700 Subject: [PATCH 148/179] x86: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - pages in swapcache, printed by show_swap_cache_info() - dirty pages, writeback pages, mapped pages, slab pages, pagetable pages, printed by show_free_areas() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/mm/init_64.c | 37 ------------------------------- arch/x86/mm/pgtable_32.c | 47 ---------------------------------------- 2 files changed, 84 deletions(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index ec37121f6709..129618ca0ea2 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -86,43 +86,6 @@ early_param("gbpages", parse_direct_gbpages_on); * around without checking the pgd every time. */ -void show_mem(void) -{ - long i, total = 0, reserved = 0; - long shared = 0, cached = 0; - struct page *page; - pg_data_t *pgdat; - - printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); - for_each_online_pgdat(pgdat) { - for (i = 0; i < pgdat->node_spanned_pages; ++i) { - /* - * This loop can take a while with 256 GB and - * 4k pages so defer the NMI watchdog: - */ - if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) - touch_nmi_watchdog(); - - if (!pfn_valid(pgdat->node_start_pfn + i)) - continue; - - page = pfn_to_page(pgdat->node_start_pfn + i); - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - } - printk(KERN_INFO "%lu pages of RAM\n", total); - printk(KERN_INFO "%lu reserved pages\n", reserved); - printk(KERN_INFO "%lu pages shared\n", shared); - printk(KERN_INFO "%lu pages swap cached\n", cached); -} - int after_bootmem; static __init void *spp_getpage(void) diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index b4becbf8c570..cab0abbd1ebe 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c @@ -20,53 +20,6 @@ #include #include -void show_mem(void) -{ - int total = 0, reserved = 0; - int shared = 0, cached = 0; - int highmem = 0; - struct page *page; - pg_data_t *pgdat; - unsigned long i; - unsigned long flags; - - printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); - for_each_online_pgdat(pgdat) { - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; ++i) { - if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) - touch_nmi_watchdog(); - page = pgdat_page_nr(pgdat, i); - total++; - if (PageHighMem(page)) - highmem++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - pgdat_resize_unlock(pgdat, &flags); - } - printk(KERN_INFO "%d pages of RAM\n", total); - printk(KERN_INFO "%d pages of HIGHMEM\n", highmem); - printk(KERN_INFO "%d reserved pages\n", reserved); - printk(KERN_INFO "%d pages shared\n", shared); - printk(KERN_INFO "%d pages swap cached\n", cached); - - printk(KERN_INFO "%lu pages dirty\n", global_page_state(NR_FILE_DIRTY)); - printk(KERN_INFO "%lu pages writeback\n", - global_page_state(NR_WRITEBACK)); - printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); - printk(KERN_INFO "%lu pages slab\n", - global_page_state(NR_SLAB_RECLAIMABLE) + - global_page_state(NR_SLAB_UNRECLAIMABLE)); - printk(KERN_INFO "%lu pages pagetables\n", - global_page_state(NR_PAGETABLE)); -} - /* * Associate a virtual page frame with a given physical page frame * and protection flags for that frame. From 79b0cbd113a9de1eaa3322528ccaeb97bd9189cc Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:12 -0700 Subject: [PATCH 149/179] um: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free swap pages, printed by show_swap_cache_info() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/mem.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index e2274ef3155d..61d7e6138ff5 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -264,37 +264,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif -void show_mem(void) -{ - int pfn, total = 0, reserved = 0; - int shared = 0, cached = 0; - int high_mem = 0; - struct page *page; - - printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); - printk(KERN_INFO "Free swap: %6ldkB\n", - nr_swap_pages<<(PAGE_SHIFT-10)); - pfn = max_mapnr; - while (pfn-- > 0) { - page = pfn_to_page(pfn); - total++; - if (PageHighMem(page)) - high_mem++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - printk(KERN_INFO "%d pages of RAM\n", total); - printk(KERN_INFO "%d pages of HIGHMEM\n", high_mem); - printk(KERN_INFO "%d reserved pages\n", reserved); - printk(KERN_INFO "%d pages shared\n", shared); - printk(KERN_INFO "%d pages swap cached\n", cached); -} - /* Allocate and free page tables. */ pgd_t *pgd_alloc(struct mm_struct *mm) From 471a54239a1c8a09cd12733d4e28db2aeebedb59 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:12 -0700 Subject: [PATCH 150/179] sparc64: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free swap pages, printed by show_swap_cache_info() - pages in swapcache, printed by show_swap_cache_info() - dirty pages, writeback pages, mapped pages, slab pages, pagetables pages, printed by show_free_areas() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/mm/init.c | 45 ------------------------------------------ 1 file changed, 45 deletions(-) diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 713297473951..4e821b3ecb03 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -392,51 +392,6 @@ void __kprobes flush_icache_range(unsigned long start, unsigned long end) } } -void show_mem(void) -{ - unsigned long total = 0, reserved = 0; - unsigned long shared = 0, cached = 0; - pg_data_t *pgdat; - - printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); - printk(KERN_INFO "Free swap: %6ldkB\n", - nr_swap_pages << (PAGE_SHIFT-10)); - for_each_online_pgdat(pgdat) { - unsigned long i, flags; - - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; i++) { - struct page *page = pgdat_page_nr(pgdat, i); - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - pgdat_resize_unlock(pgdat, &flags); - } - - printk(KERN_INFO "%lu pages of RAM\n", total); - printk(KERN_INFO "%lu reserved pages\n", reserved); - printk(KERN_INFO "%lu pages shared\n", shared); - printk(KERN_INFO "%lu pages swap cached\n", cached); - - printk(KERN_INFO "%lu pages dirty\n", - global_page_state(NR_FILE_DIRTY)); - printk(KERN_INFO "%lu pages writeback\n", - global_page_state(NR_WRITEBACK)); - printk(KERN_INFO "%lu pages mapped\n", - global_page_state(NR_FILE_MAPPED)); - printk(KERN_INFO "%lu pages slab\n", - global_page_state(NR_SLAB_RECLAIMABLE) + - global_page_state(NR_SLAB_UNRECLAIMABLE)); - printk(KERN_INFO "%lu pages pagetables\n", - global_page_state(NR_PAGETABLE)); -} - void mmu_info(struct seq_file *m) { if (tlb_type == cheetah) From 03da6bfb5b40d454f5439ea905a68441aab23637 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:13 -0700 Subject: [PATCH 151/179] sh: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in slab, printed by show_free_areas() - free swap pages, printed by show_swap_cache_info() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/mm/init.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index d652d375eb1e..b75a7acd62fb 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -25,47 +25,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD]; unsigned long cached_to_uncached = 0; -void show_mem(void) -{ - int total = 0, reserved = 0, free = 0; - int shared = 0, cached = 0, slab = 0; - pg_data_t *pgdat; - - printk("Mem-info:\n"); - show_free_areas(); - - for_each_online_pgdat(pgdat) { - unsigned long flags, i; - - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; i++) { - struct page *page = pgdat_page_nr(pgdat, i); - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (PageSlab(page)) - slab++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - } - pgdat_resize_unlock(pgdat, &flags); - } - - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - printk("%d pages of RAM\n", total); - printk("%d free pages\n", free); - printk("%d reserved pages\n", reserved); - printk("%d slab pages\n", slab); - printk("%d pages shared\n", shared); - printk("%d pages swap cached\n", cached); - printk(KERN_INFO "Total of %ld pages in page table cache\n", - quicklist_total_size()); -} - #ifdef CONFIG_MMU static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) { From c55281dee09a843dd6bf5070324b86b84847e6ea Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:14 -0700 Subject: [PATCH 152/179] s390: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Heiko Carstens Cc: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/mm/init.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 388cc7420055..4993b0f594eb 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -42,38 +42,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); -void show_mem(void) -{ - unsigned long i, total = 0, reserved = 0; - unsigned long shared = 0, cached = 0; - unsigned long flags; - struct page *page; - pg_data_t *pgdat; - - printk("Mem-info:\n"); - show_free_areas(); - for_each_online_pgdat(pgdat) { - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; i++) { - if (!pfn_valid(pgdat->node_start_pfn + i)) - continue; - page = pfn_to_page(pgdat->node_start_pfn + i); - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - pgdat_resize_unlock(pgdat, &flags); - } - printk("%ld pages of RAM\n", total); - printk("%ld reserved pages\n", reserved); - printk("%ld pages shared\n", shared); - printk("%ld pages swap cached\n", cached); -} - /* * paging_init() sets up the page tables */ From bda2fa535564ace56a395d5b65c6dc81305401fa Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:14 -0700 Subject: [PATCH 153/179] powerpc: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/mm/mem.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 1ca2235f0965..702691cb9e82 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -186,45 +186,6 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg, } EXPORT_SYMBOL_GPL(walk_memory_resource); -void show_mem(void) -{ - unsigned long total = 0, reserved = 0; - unsigned long shared = 0, cached = 0; - unsigned long highmem = 0; - struct page *page; - pg_data_t *pgdat; - unsigned long i; - - printk("Mem-info:\n"); - show_free_areas(); - for_each_online_pgdat(pgdat) { - unsigned long flags; - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; i++) { - if (!pfn_valid(pgdat->node_start_pfn + i)) - continue; - page = pgdat_page_nr(pgdat, i); - total++; - if (PageHighMem(page)) - highmem++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - pgdat_resize_unlock(pgdat, &flags); - } - printk("%ld pages of RAM\n", total); -#ifdef CONFIG_HIGHMEM - printk("%ld pages of HIGHMEM\n", highmem); -#endif - printk("%ld reserved pages\n", reserved); - printk("%ld pages shared\n", shared); - printk("%ld pages swap cached\n", cached); -} - /* * Initialize the bootmem system and give it all the memory we * have available. If we are using highmem, we only put the From 4984d2d88805609e7702e8ee72b5e148c992ae7b Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:15 -0700 Subject: [PATCH 154/179] mn10300: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mn10300/mm/pgtable.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/arch/mn10300/mm/pgtable.c b/arch/mn10300/mm/pgtable.c index a477038752ba..baffc581e031 100644 --- a/arch/mn10300/mm/pgtable.c +++ b/arch/mn10300/mm/pgtable.c @@ -27,33 +27,6 @@ #include #include -void show_mem(void) -{ - unsigned long i; - int free = 0, total = 0, reserved = 0, shared = 0; - - int cached = 0; - printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map + i)) - reserved++; - else if (PageSwapCache(mem_map + i)) - cached++; - else if (!page_count(mem_map + i)) - free++; - else - shared += page_count(mem_map + i) - 1; - } - printk(KERN_INFO "%d pages of RAM\n", total); - printk(KERN_INFO "%d free pages\n", free); - printk(KERN_INFO "%d reserved pages\n", reserved); - printk(KERN_INFO "%d pages shared\n", shared); - printk(KERN_INFO "%d pages swap cached\n", cached); -} - /* * Associate a large virtual page frame with a given physical page frame * and protection flags for that frame. pfn is for the base of the page, From 4bad9ea20146860d726ac14a53206da6be132b98 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:16 -0700 Subject: [PATCH 155/179] h8300: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/mm/init.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index e4f4199f97ab..a1d228f5e4e6 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c @@ -64,33 +64,6 @@ unsigned long empty_zero_page; extern unsigned long rom_length; -void show_mem(void) -{ - unsigned long i; - int free = 0, total = 0, reserved = 0, shared = 0; - int cached = 0; - - printk("\nMem-info:\n"); - show_free_areas(); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (!page_count(mem_map+i)) - free++; - else - shared += page_count(mem_map+i) - 1; - } - printk("%d pages of RAM\n",total); - printk("%d free pages\n",free); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); -} - extern unsigned long memory_start; extern unsigned long memory_end; From e66ddf1a4593d9bec8623782b94d7b50cc58cec5 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:16 -0700 Subject: [PATCH 156/179] mips: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). And show_mem() does now actually print something on configurations with multiple nodes. Signed-off-by: Johannes Weiner Acked-by: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/mm/Makefile | 3 +-- arch/mips/mm/pgtable.c | 36 ------------------------------------ 2 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 arch/mips/mm/pgtable.c diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 48731020ca0e..44e8dd8106bf 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -3,8 +3,7 @@ # obj-y += cache.o dma-default.o extable.o fault.o \ - init.o pgtable.o tlbex.o tlbex-fault.o \ - uasm.o page.o + init.o tlbex.o tlbex-fault.o uasm.o page.o obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_64BIT) += pgtable-64.o diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c deleted file mode 100644 index 7dfa579ab24c..000000000000 --- a/arch/mips/mm/pgtable.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include - -void show_mem(void) -{ -#ifndef CONFIG_NEED_MULTIPLE_NODES /* XXX(hch): later.. */ - int pfn, total = 0, reserved = 0; - int shared = 0, cached = 0; - int highmem = 0; - struct page *page; - - printk("Mem-info:\n"); - show_free_areas(); - pfn = max_mapnr; - while (pfn-- > 0) { - if (!pfn_valid(pfn)) - continue; - page = pfn_to_page(pfn); - total++; - if (PageHighMem(page)) - highmem++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - printk("%d pages of RAM\n", total); - printk("%d pages of HIGHMEM\n", highmem); - printk("%d reserved pages\n", reserved); - printk("%d pages shared\n", shared); - printk("%d pages swap cached\n", cached); -#endif -} From 0ec5e0edd155385cb59cb9857de3176524ba4ff8 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:17 -0700 Subject: [PATCH 157/179] m68knommu: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Greg Ungerer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m68knommu/mm/init.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c index 22e2a0d02b81..3bf249c53e41 100644 --- a/arch/m68knommu/mm/init.c +++ b/arch/m68knommu/mm/init.c @@ -62,33 +62,6 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; -void show_mem(void) -{ - unsigned long i; - int free = 0, total = 0, reserved = 0, shared = 0; - int cached = 0; - - printk(KERN_INFO "\nMem-info:\n"); - show_free_areas(); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (!page_count(mem_map+i)) - free++; - else - shared += page_count(mem_map+i) - 1; - } - printk(KERN_INFO "%d pages of RAM\n",total); - printk(KERN_INFO "%d free pages\n",free); - printk(KERN_INFO "%d reserved pages\n",reserved); - printk(KERN_INFO "%d pages shared\n",shared); - printk(KERN_INFO "%d pages swap cached\n",cached); -} - extern unsigned long memory_start; extern unsigned long memory_end; From 969eefb516b71f8abadf5bc4861a672694f48c38 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:18 -0700 Subject: [PATCH 158/179] m68k: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Geert Uytterhoeven Cc: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m68k/mm/init.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index 79f5f94d4800..81bb08ceec18 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c @@ -69,36 +69,6 @@ void __init m68k_setup_node(int node) void *empty_zero_page; EXPORT_SYMBOL(empty_zero_page); -void show_mem(void) -{ - pg_data_t *pgdat; - int free = 0, total = 0, reserved = 0, shared = 0; - int cached = 0; - int i; - - printk("\nMem-info:\n"); - show_free_areas(); - for_each_online_pgdat(pgdat) { - for (i = 0; i < pgdat->node_spanned_pages; i++) { - struct page *page = pgdat->node_mem_map + i; - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - } - } - printk("%d pages of RAM\n",total); - printk("%d free pages\n",free); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); -} - extern void init_pointer_table(unsigned long ptable); /* References to section boundaries */ From aca532016f49eca0341ed7be5885d6c63ca69e63 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:18 -0700 Subject: [PATCH 159/179] m32r: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free swap pages, printed by show_swap_cache_info() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Cc: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/mm/init.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c index 2554eb59cfef..24d429f9358a 100644 --- a/arch/m32r/mm/init.c +++ b/arch/m32r/mm/init.c @@ -36,42 +36,6 @@ pgd_t swapper_pg_dir[1024]; DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -void show_mem(void) -{ - int total = 0, reserved = 0; - int shared = 0, cached = 0; - int highmem = 0; - struct page *page; - pg_data_t *pgdat; - unsigned long i; - - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); - for_each_online_pgdat(pgdat) { - unsigned long flags; - pgdat_resize_lock(pgdat, &flags); - for (i = 0; i < pgdat->node_spanned_pages; ++i) { - page = pgdat_page_nr(pgdat, i); - total++; - if (PageHighMem(page)) - highmem++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (page_count(page)) - shared += page_count(page) - 1; - } - pgdat_resize_unlock(pgdat, &flags); - } - printk("%d pages of RAM\n", total); - printk("%d pages of HIGHMEM\n",highmem); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); -} - /* * Cache of MMU context last used. */ From e275e0a687e83add62b10e6d36b67f0964455469 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:19 -0700 Subject: [PATCH 160/179] frv: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() where show_mem() calls show_free_areas(). Signed-off-by: Johannes Weiner Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/mm/init.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c index 9af7740f32fb..1b851db34186 100644 --- a/arch/frv/mm/init.c +++ b/arch/frv/mm/init.c @@ -61,37 +61,6 @@ static unsigned long empty_bad_page; unsigned long empty_zero_page; EXPORT_SYMBOL(empty_zero_page); -/*****************************************************************************/ -/* - * - */ -void show_mem(void) -{ - unsigned long i; - int free = 0, total = 0, reserved = 0, shared = 0; - - printk("\nMem-info:\n"); - show_free_areas(); - i = max_mapnr; - while (i-- > 0) { - struct page *page = &mem_map[i]; - - total++; - if (PageReserved(page)) - reserved++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - } - - printk("%d pages of RAM\n",total); - printk("%d free pages\n",free); - printk("%d reserved pages\n",reserved); - printk("%d pages shared\n",shared); - -} /* end show_mem() */ - /*****************************************************************************/ /* * paging_init() continues the virtual memory environment setup which From a4074d93dd4e8f46f727840baa2be02d544fd17f Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 25 Jul 2008 19:46:20 -0700 Subject: [PATCH 161/179] cris: use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. This also removes the following redundant information display: - free pages, printed by show_free_areas() - pages in swapcache, printed by show_swap_cache_info() where show_mem() calls show_free_areas(), which calls show_swap_cache_info(). Signed-off-by: Johannes Weiner Acked-by: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/cris/mm/init.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index 5b06ffa15e34..2fdd212eb250 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c @@ -19,36 +19,6 @@ unsigned long empty_zero_page; extern char _stext, _edata, _etext; /* From linkerscript */ extern char __init_begin, __init_end; -void -show_mem(void) -{ - int i,free = 0,total = 0,cached = 0, reserved = 0, nonshared = 0; - int shared = 0; - - printk("\nMem-info:\n"); - show_free_areas(); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (!page_count(mem_map+i)) - free++; - else if (page_count(mem_map+i) == 1) - nonshared++; - else - shared += page_count(mem_map+i) - 1; - } - printk("%d pages of RAM\n",total); - printk("%d free pages\n",free); - printk("%d reserved pages\n",reserved); - printk("%d pages nonshared\n",nonshared); - printk("%d pages shared\n",shared); - printk("%d pages swap cached\n",cached); -} - void __init mem_init(void) { From 0e1451da4f928ae1c9d5ca617faebde9f02985db Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:20 -0700 Subject: [PATCH 162/179] drm: make drm_minors_cleanup() static Make the needlessly global drm_minors_cleanup() static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 564138714bb5..452c2d866ec5 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -318,7 +318,7 @@ static void drm_cleanup(struct drm_device * dev) DRM_ERROR("Cannot unload module\n"); } -int drm_minors_cleanup(int id, void *ptr, void *data) +static int drm_minors_cleanup(int id, void *ptr, void *data) { struct drm_minor *minor = ptr; struct drm_device *dev; From 96930a6365c99c160138a395566e360b27348b8f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:21 -0700 Subject: [PATCH 163/179] make cgroup_seqfile_release() static cgroup_seqfile_release() can become static. Signed-off-by: Adrian Bunk Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 66ec9fd21e0c..89bd6fb7894f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1529,7 +1529,7 @@ static int cgroup_seqfile_show(struct seq_file *m, void *arg) return cft->read_seq_string(state->cgroup, cft, m); } -int cgroup_seqfile_release(struct inode *inode, struct file *file) +static int cgroup_seqfile_release(struct inode *inode, struct file *file) { struct seq_file *seq = file->private_data; kfree(seq->private); From 25cdcd0086d97a011fcd0c1ff572e30da24790ec Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:21 -0700 Subject: [PATCH 164/179] make pnp_add_card_id() static pnp_add_card_id() can now become static. Signed-off-by: Adrian Bunk Cc: Bjorn Helgaas Cc: Rene Herman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/base.h | 1 - drivers/pnp/card.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index e3fa9a2d9a3d..9fd7bb9b7dce 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -19,7 +19,6 @@ struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id); int pnp_interface_attach_device(struct pnp_dev *dev); int pnp_add_card(struct pnp_card *card); -struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id); void pnp_remove_card(struct pnp_card *card); int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); void pnp_remove_card_device(struct pnp_dev *dev); diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index b00ef1030e45..e75b060daa95 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -102,7 +102,7 @@ static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv) * @id: pointer to a pnp_id structure * @card: pointer to the desired card */ -struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id) +static struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id) { struct pnp_id *dev_id, *ptr; From 23d5f96ce6571da51c0f6bfa7361e5f91f314b2b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:22 -0700 Subject: [PATCH 165/179] make parport_cs_release() static This patch makes the needlessly global parport_cs_release() static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/parport/parport_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 802a81d47367..00e1d9620f7c 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -235,7 +235,7 @@ static int parport_config(struct pcmcia_device *link) ======================================================================*/ -void parport_cs_release(struct pcmcia_device *link) +static void parport_cs_release(struct pcmcia_device *link) { parport_info_t *info = link->priv; From 9e5c6da71e89fa25ced6e88182225a99941bec90 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:22 -0700 Subject: [PATCH 166/179] make mm/sparse.c: make a function static This patch makes the needlessly global sparse_early_mem_map_alloc() static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/sparse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/sparse.c b/mm/sparse.c index 8ffc08990008..5d9dbbb9d39e 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -377,7 +377,7 @@ struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid) } #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ -struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) +static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) { struct page *map; struct mem_section *ms = __nr_to_section(pnum); From 9d8fddfb17aaee4ffc5e3d0560620d0fa8b50a42 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:23 -0700 Subject: [PATCH 167/179] mm/allocpercpu.c: make 4 functions static This patch makes the following needlessly global functions static: - percpu_depopulate() - __percpu_depopulate_mask() - percpu_populate() - __percpu_populate_mask() Signed-off-by: Adrian Bunk Acked-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/percpu.h | 29 ----------------------------- mm/allocpercpu.c | 20 +++++++++++--------- 2 files changed, 11 insertions(+), 38 deletions(-) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 4cdd393e71e1..fac3337547eb 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -74,11 +74,6 @@ struct percpu_data { (__typeof__(ptr))__p->ptrs[(cpu)]; \ }) -extern void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu); -extern void percpu_depopulate(void *__pdata, int cpu); -extern int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, - cpumask_t *mask); -extern void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask); extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask); extern void percpu_free(void *__pdata); @@ -86,26 +81,6 @@ extern void percpu_free(void *__pdata); #define percpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) -static inline void percpu_depopulate(void *__pdata, int cpu) -{ -} - -static inline void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) -{ -} - -static inline void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, - int cpu) -{ - return percpu_ptr(__pdata, cpu); -} - -static inline int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, - cpumask_t *mask) -{ - return 0; -} - static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) { return kzalloc(size, gfp); @@ -118,10 +93,6 @@ static inline void percpu_free(void *__pdata) #endif /* CONFIG_SMP */ -#define percpu_populate_mask(__pdata, size, gfp, mask) \ - __percpu_populate_mask((__pdata), (size), (gfp), &(mask)) -#define percpu_depopulate_mask(__pdata, mask) \ - __percpu_depopulate_mask((__pdata), &(mask)) #define percpu_alloc_mask(size, gfp, mask) \ __percpu_alloc_mask((size), (gfp), &(mask)) diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c index 843364594e23..4297bc41bfd2 100644 --- a/mm/allocpercpu.c +++ b/mm/allocpercpu.c @@ -18,27 +18,28 @@ * Depopulating per-cpu data for a cpu going offline would be a typical * use case. You need to register a cpu hotplug handler for that purpose. */ -void percpu_depopulate(void *__pdata, int cpu) +static void percpu_depopulate(void *__pdata, int cpu) { struct percpu_data *pdata = __percpu_disguise(__pdata); kfree(pdata->ptrs[cpu]); pdata->ptrs[cpu] = NULL; } -EXPORT_SYMBOL_GPL(percpu_depopulate); /** * percpu_depopulate_mask - depopulate per-cpu data for some cpu's * @__pdata: per-cpu data to depopulate * @mask: depopulate per-cpu data for cpu's selected through mask bits */ -void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) +static void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) { int cpu; for_each_cpu_mask_nr(cpu, *mask) percpu_depopulate(__pdata, cpu); } -EXPORT_SYMBOL_GPL(__percpu_depopulate_mask); + +#define percpu_depopulate_mask(__pdata, mask) \ + __percpu_depopulate_mask((__pdata), &(mask)) /** * percpu_populate - populate per-cpu data for given cpu @@ -51,7 +52,7 @@ EXPORT_SYMBOL_GPL(__percpu_depopulate_mask); * use case. You need to register a cpu hotplug handler for that purpose. * Per-cpu object is populated with zeroed buffer. */ -void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) +static void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) { struct percpu_data *pdata = __percpu_disguise(__pdata); int node = cpu_to_node(cpu); @@ -68,7 +69,6 @@ void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) pdata->ptrs[cpu] = kzalloc(size, gfp); return pdata->ptrs[cpu]; } -EXPORT_SYMBOL_GPL(percpu_populate); /** * percpu_populate_mask - populate per-cpu data for more cpu's @@ -79,8 +79,8 @@ EXPORT_SYMBOL_GPL(percpu_populate); * * Per-cpu objects are populated with zeroed buffers. */ -int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, - cpumask_t *mask) +static int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, + cpumask_t *mask) { cpumask_t populated; int cpu; @@ -94,7 +94,9 @@ int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, cpu_set(cpu, populated); return 0; } -EXPORT_SYMBOL_GPL(__percpu_populate_mask); + +#define percpu_populate_mask(__pdata, size, gfp, mask) \ + __percpu_populate_mask((__pdata), (size), (gfp), &(mask)) /** * percpu_alloc_mask - initial setup of per-cpu data From 15f59adae001766a2c7f7fe4f196387bb04bcff5 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:23 -0700 Subject: [PATCH 168/179] make mm/memory.c:print_bad_pte() static This patch makes the needlessly global print_bad_pte() static. Signed-off-by: Adrian Bunk Reviewed-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 1 - mm/memory.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index f3fd70d6029f..6e695eaab4ce 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -810,7 +810,6 @@ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void * int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int len, int write, int force, struct page **pages, struct vm_area_struct **vmas); -void print_bad_pte(struct vm_area_struct *, pte_t, unsigned long); extern int try_to_release_page(struct page * page, gfp_t gfp_mask); extern void do_invalidatepage(struct page *page, unsigned long offset); diff --git a/mm/memory.c b/mm/memory.c index 262e3eb6601a..a8ca04faaea6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -374,7 +374,8 @@ static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss) * * The calling function must still handle the error. */ -void print_bad_pte(struct vm_area_struct *vma, pte_t pte, unsigned long vaddr) +static void print_bad_pte(struct vm_area_struct *vma, pte_t pte, + unsigned long vaddr) { printk(KERN_ERR "Bad pte = %08llx, process = %s, " "vm_flags = %lx, vaddr = %lx\n", From 7c363b8c6536f26934172d3c46f0bbec01a97c61 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:24 -0700 Subject: [PATCH 169/179] mm/swapfile.c: make code static This patch makes the following needlessly global code static: - swap_lock - nr_swapfiles - struct swap_list Signed-off-by: Adrian Bunk Reviewed-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 3 --- mm/swapfile.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index 0b3377650c85..de40f169a4e4 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -237,7 +237,6 @@ extern struct page *swapin_readahead(swp_entry_t, gfp_t, /* linux/mm/swapfile.c */ extern long total_swap_pages; -extern unsigned int nr_swapfiles; extern void si_swapinfo(struct sysinfo *); extern swp_entry_t get_swap_page(void); extern swp_entry_t get_swap_page_of_type(int); @@ -254,8 +253,6 @@ extern int can_share_swap_page(struct page *); extern int remove_exclusive_swap_page(struct page *); struct backing_dev_info; -extern spinlock_t swap_lock; - /* linux/mm/thrash.c */ extern struct mm_struct * swap_token_mm; extern void grab_swap_token(void); diff --git a/mm/swapfile.c b/mm/swapfile.c index af283933c14e..6beb6251e99d 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -33,8 +33,8 @@ #include #include -DEFINE_SPINLOCK(swap_lock); -unsigned int nr_swapfiles; +static DEFINE_SPINLOCK(swap_lock); +static unsigned int nr_swapfiles; long total_swap_pages; static int swap_overflow; static int least_priority; @@ -44,7 +44,7 @@ static const char Unused_file[] = "Unused swap file entry "; static const char Bad_offset[] = "Bad swap offset entry "; static const char Unused_offset[] = "Unused swap offset entry "; -struct swap_list_t swap_list = {-1, -1}; +static struct swap_list_t swap_list = {-1, -1}; static struct swap_info_struct swap_info[MAX_SWAPFILES]; From 9580d85f9cdb076c4bfb467bc6c0d3c5e499957a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:25 -0700 Subject: [PATCH 170/179] drivers/char/rtc.c: make 2 functions static The following functions can now become static: - rtc_interrupt() - rtc_get_rtc_time() Signed-off-by: Adrian Bunk Acked-by: Bernhard Walle Acked-by: Paul Gortmaker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/rtc.c | 5 +++-- include/linux/rtc.h | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index dbefbb30ed44..d9799e2bcfbf 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -144,6 +144,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +static void rtc_get_rtc_time(struct rtc_time *rtc_tm); #ifdef RTC_IRQ static unsigned int rtc_poll(struct file *file, poll_table *wait); @@ -235,7 +236,7 @@ static inline unsigned char rtc_is_updating(void) * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.) */ -irqreturn_t rtc_interrupt(int irq, void *dev_id) +static irqreturn_t rtc_interrupt(int irq, void *dev_id) { /* * Can be an alarm interrupt, update complete interrupt, @@ -1303,7 +1304,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file) } #endif -void rtc_get_rtc_time(struct rtc_time *rtc_tm) +static void rtc_get_rtc_time(struct rtc_time *rtc_tm) { unsigned long uip_watchdog = jiffies, flags; unsigned char ctrl; diff --git a/include/linux/rtc.h b/include/linux/rtc.h index b01fe004cb5e..91f597ad6acc 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -225,8 +225,6 @@ typedef struct rtc_task { int rtc_register(rtc_task_t *task); int rtc_unregister(rtc_task_t *task); int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); -void rtc_get_rtc_time(struct rtc_time *rtc_tm); -irqreturn_t rtc_interrupt(int irq, void *dev_id); #endif /* __KERNEL__ */ From f56f6d30c75984d0aba2656eaeb35f3806395191 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:25 -0700 Subject: [PATCH 171/179] make init/do_mounts.c:root_device_name static This patch makes the needlessly global root_device_name static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/do_mounts.c | 2 +- init/do_mounts.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/init/do_mounts.c b/init/do_mounts.c index f769fac4f4c0..3715feb8446d 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -23,7 +23,7 @@ int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ int root_mountflags = MS_RDONLY | MS_SILENT; -char * __initdata root_device_name; +static char * __initdata root_device_name; static char __initdata saved_root_name[64]; static int __initdata root_wait; diff --git a/init/do_mounts.h b/init/do_mounts.h index 735705d137ff..9aa968d54329 100644 --- a/init/do_mounts.h +++ b/init/do_mounts.h @@ -11,7 +11,6 @@ void change_floppy(char *fmt, ...); void mount_block_root(char *name, int flags); void mount_root(void); extern int root_mountflags; -extern char *root_device_name; static inline int create_dev(char *name, dev_t dev) { From 511e7483abe1ab433d8ab7a7998f799042b52941 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:26 -0700 Subject: [PATCH 172/179] make macfb_setup() static This patch makes the needlessly global macfb_setup() static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/macfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index aa8c714d6245..b790ddff76f9 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c @@ -596,7 +596,7 @@ static struct fb_ops macfb_ops = { .fb_imageblit = cfb_imageblit, }; -void __init macfb_setup(char *options) +static void __init macfb_setup(char *options) { char *this_opt; From 3d1e412ac5570a669e1b1fc5fd0f6859250c3d76 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:26 -0700 Subject: [PATCH 173/179] video/console/stico{n,re}.c: make code static This patch makes the following needlessly global code static: - sticon.c: sticonsole_init() - sticore.c: struct default_sti - sticore.c: sti_init_graph() - sticore.c: sti_inq_conf() - sticore.c: sti_rom_copy() - sticore.c: sti_select_fbfont() - sticore.c: sti_select_font() - sticore.c: sti_get_wmode_rom() - sticore.c: sti_read_rom() [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/sticon.c | 2 +- drivers/video/console/sticore.c | 33 +++++++++++++++------------------ drivers/video/sticore.h | 2 -- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index a11cc2fdd4cd..4055dbdd1b42 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -370,7 +370,7 @@ static const struct consw sti_con = { -int __init sticonsole_init(void) +static int __init sticonsole_init(void) { /* already initialized ? */ if (sticon_sti) diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index e9ab657f0bb7..d7822af0e00a 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -29,7 +29,7 @@ #define STI_DRIVERVERSION "Version 0.9a" -struct sti_struct *default_sti __read_mostly; +static struct sti_struct *default_sti __read_mostly; /* number of STI ROMS found and their ptrs to each struct */ static int num_sti_roms __read_mostly; @@ -68,8 +68,7 @@ static const struct sti_init_flags default_init_flags = { .init_cmap_tx = 1, }; -int -sti_init_graph(struct sti_struct *sti) +static int sti_init_graph(struct sti_struct *sti) { struct sti_init_inptr_ext inptr_ext = { 0, }; struct sti_init_inptr inptr = { @@ -100,8 +99,7 @@ static const struct sti_conf_flags default_conf_flags = { .wait = STI_WAIT, }; -void -sti_inq_conf(struct sti_struct *sti) +static void sti_inq_conf(struct sti_struct *sti) { struct sti_conf_inptr inptr = { 0, }; unsigned long flags; @@ -237,8 +235,8 @@ static void sti_flush(unsigned long start, unsigned long end) flush_icache_range(start, end); } -void __devinit -sti_rom_copy(unsigned long base, unsigned long count, void *dest) +static void __devinit sti_rom_copy(unsigned long base, unsigned long count, + void *dest) { unsigned long dest_start = (unsigned long) dest; @@ -478,8 +476,8 @@ sti_init_glob_cfg(struct sti_struct *sti, } #ifdef CONFIG_FB -struct sti_cooked_font * __devinit -sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) +static struct sti_cooked_font __devinit +*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { const struct font_desc *fbfont; unsigned int size, bpc; @@ -534,16 +532,16 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) return cooked_font; } #else -struct sti_cooked_font * __devinit -sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) +static struct sti_cooked_font __devinit +*sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) { return NULL; } #endif -struct sti_cooked_font * __devinit -sti_select_font(struct sti_cooked_rom *rom, - int (*search_font_fnc) (struct sti_cooked_rom *,int,int) ) +static struct sti_cooked_font __devinit +*sti_select_font(struct sti_cooked_rom *rom, + int (*search_font_fnc)(struct sti_cooked_rom *, int, int)) { struct sti_cooked_font *font; int i; @@ -707,8 +705,7 @@ sti_get_bmode_rom (unsigned long address) return raw; } -struct sti_rom * __devinit -sti_get_wmode_rom (unsigned long address) +static struct sti_rom __devinit *sti_get_wmode_rom(unsigned long address) { struct sti_rom *raw; unsigned long size; @@ -723,8 +720,8 @@ sti_get_wmode_rom (unsigned long address) return raw; } -int __devinit -sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address) +static int __devinit sti_read_rom(int wordmode, struct sti_struct *sti, + unsigned long address) { struct sti_cooked_rom *cooked; struct sti_rom *raw = NULL; diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h index 1a9a60c74be3..7fe5be4bc70e 100644 --- a/drivers/video/sticore.h +++ b/drivers/video/sticore.h @@ -352,8 +352,6 @@ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ /* functions to call the STI ROM directly */ -int sti_init_graph(struct sti_struct *sti); -void sti_inq_conf(struct sti_struct *sti); void sti_putc(struct sti_struct *sti, int c, int y, int x); void sti_set(struct sti_struct *sti, int src_y, int src_x, int height, int width, u8 color); From 6ca813c4e515d9b868cd71703ef15f4af3aebb21 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 19:46:27 -0700 Subject: [PATCH 174/179] video/stifb.c: make 2 functions static This patch makes the following needlessly global functions static: - stifb_init_fb() - stifb_init() Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/stifb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 598d35eff935..166481402412 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -1078,8 +1078,7 @@ static struct fb_ops stifb_ops = { * Initialization */ -int __init -stifb_init_fb(struct sti_struct *sti, int bpp_pref) +static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) { struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; @@ -1315,8 +1314,7 @@ static int stifb_disabled __initdata; int __init stifb_setup(char *options); -int __init -stifb_init(void) +static int __init stifb_init(void) { struct sti_struct *sti; struct sti_struct *def_sti; From 37e67b75804b84e092ae9f1d7a19dc3522ef78ab Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sat, 26 Jul 2008 19:37:57 +0800 Subject: [PATCH 175/179] drivers/video/fbmem.c: removed duplicated include Removed duplicated include in drivers/video/fbmem.c Signed-off-by: Huang Weiyi Signed-off-by: Linus Torvalds --- drivers/video/fbmem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 5d84b3431098..6b487801eeae 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -35,7 +35,6 @@ #include #include #include -#include #include From 689796a141cea79d745a4689c65dd01c39e5e100 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 26 Jul 2008 17:15:05 +0200 Subject: [PATCH 176/179] dsp56k: Fix BKL pushdown commit 236b8756a2b6f90498d45b2c36d43e5372f2d4b8 ("dsp56k: BKL pushdown") removed the `struct inode *inode' parameter from dsp56k_ioctl(), but forgot to update the use of `inode' in the first line of the function. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- drivers/char/dsp56k.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 19b88504e960..ca7c72a486b2 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -304,9 +304,9 @@ static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t co } static long dsp56k_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { - int dev = iminor(inode) & 0x0f; + int dev = iminor(file->f_path.dentry->d_inode) & 0x0f; void __user *argp = (void __user *)arg; switch(dev) From aafe0ad81d7458b6c61eeb39068432683c70c9a9 Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Sat, 12 Jul 2008 11:55:42 +0100 Subject: [PATCH 177/179] [ARM] pxa: PXA25x UDC - Fix warning during build Fixes an unterminated ' warning building PXA25X UDC. Signed-off-by: Ian Molton --- include/asm-arm/arch-pxa/pxa25x-udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-arm/arch-pxa/pxa25x-udc.h b/include/asm-arm/arch-pxa/pxa25x-udc.h index 840305916b6d..1b80a4805a60 100644 --- a/include/asm-arm/arch-pxa/pxa25x-udc.h +++ b/include/asm-arm/arch-pxa/pxa25x-udc.h @@ -2,7 +2,7 @@ #define _ASM_ARCH_PXA25X_UDC_H #ifdef _ASM_ARCH_PXA27X_UDC_H -#error You can't include both PXA25x and PXA27x UDC support +#error "You can't include both PXA25x and PXA27x UDC support" #endif #define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ From e84e954a72153ffd5630df6156720440b430c877 Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Mon, 21 Jul 2008 11:02:40 +0100 Subject: [PATCH 178/179] [ARM] PXA: squash warning in pxafb Fixes a warning about using the wrong type in pxafb.c Signed-off-by: Ian Molton --- drivers/video/pxafb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 2b707a8ce5de..69de2fed6c58 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1336,7 +1336,7 @@ static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi) fbi->dma_buff_phys = fbi->map_dma; fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; - pr_debug("pxafb: palette_mem_size = 0x%08lx\n", fbi->palette_size*sizeof(u16)); + pr_debug("pxafb: palette_mem_size = 0x%08x\n", fbi->palette_size*sizeof(u16)); #ifdef CONFIG_FB_PXA_SMARTPANEL fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; From 1d1f8b377c48e5aeddaea52eba74cc0539f088cd Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Sat, 26 Jul 2008 22:39:58 +0100 Subject: [PATCH 179/179] [ARM] update defconfig for eseries. Signed-off-by: Ian Molton --- arch/arm/configs/eseries_pxa_defconfig | 1113 ++++++++++-------------- 1 file changed, 480 insertions(+), 633 deletions(-) diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig index 493ecee24f94..2307587a38a9 100644 --- a/arch/arm/configs/eseries_pxa_defconfig +++ b/arch/arm/configs/eseries_pxa_defconfig @@ -1,15 +1,19 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-hh17 -# Fri Nov 9 20:23:03 2007 +# Linux kernel version: 2.6.26 +# Sat Jul 26 22:28:46 2008 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_MMU=y # CONFIG_NO_IOPORT is not set CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_PROBE=y @@ -18,75 +22,90 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ZONE_DMA=y CONFIG_ARCH_MTD_XIP=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_EMBEDDED=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_KALLSYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set +# CONFIG_HAVE_IOREMAP_PROT is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_ARCH_TRACEHOOK is not set +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_USE_GENERIC_SMP_HELPERS is not set +CONFIG_HAVE_CLK=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers @@ -100,6 +119,7 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y # # System Type @@ -111,21 +131,26 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION5X is not set # CONFIG_ARCH_PNX4008 is not set CONFIG_ARCH_PXA=y # CONFIG_ARCH_RPC is not set @@ -133,80 +158,48 @@ CONFIG_ARCH_PXA=y # CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_BOARD_IRQ_MAP_SMALL is not set -CONFIG_BOARD_IRQ_MAP_BIG=y -CONFIG_DMABOUNCE=y +# CONFIG_ARCH_MSM7X00A is not set # -# Intel PXA2xx Implementations +# Intel PXA2xx/PXA3xx Implementations # +# CONFIG_ARCH_GUMSTIX is not set # CONFIG_ARCH_LUBBOCK is not set # CONFIG_MACH_LOGICPD_PXA270 is not set # CONFIG_MACH_MAINSTONE is not set # CONFIG_ARCH_PXA_IDP is not set -CONFIG_TOSHIBA_TMIO_OHCI=y -CONFIG_ARCH_ESERIES=y +# CONFIG_PXA_SHARPSL is not set +CONFIG_ARCH_PXA_ESERIES=y CONFIG_MACH_E330=y +CONFIG_MACH_E350=y CONFIG_MACH_E740=y CONFIG_MACH_E750=y CONFIG_MACH_E400=y CONFIG_MACH_E800=y -CONFIG_E330_LCD=y -CONFIG_E740_LCD=y -CONFIG_E750_LCD=y -CONFIG_E400_LCD=y -CONFIG_E800_LCD=y -CONFIG_ESERIES_UDC=y -CONFIG_E330_TC6387XB=y -CONFIG_E740_T7L66XB=y -CONFIG_E400_T7L66XB=y -CONFIG_E750_E800_TC6393XB=y -CONFIG_E740_PCMCIA=m -CONFIG_E750_PCMCIA=m -CONFIG_E800_PCMCIA=m -# CONFIG_MACH_A620 is not set -# CONFIG_MACH_A716 is not set -# CONFIG_MACH_A730 is not set -# CONFIG_ARCH_H1900 is not set -# CONFIG_ARCH_H2200 is not set -# CONFIG_MACH_H3900 is not set -# CONFIG_MACH_H4000 is not set -# CONFIG_MACH_H4700 is not set -# CONFIG_MACH_HX2750 is not set -# CONFIG_ARCH_H5400 is not set -# CONFIG_MACH_HIMALAYA is not set -# CONFIG_MACH_HTCUNIVERSAL is not set -# CONFIG_MACH_HTCALPINE is not set -# CONFIG_MACH_MAGICIAN is not set -# CONFIG_MACH_HTCAPACHE is not set -# CONFIG_MACH_BLUEANGEL is not set - -# -# HTC_HW6X00 -# -# CONFIG_MACH_HTCBEETLES is not set -# CONFIG_MACH_HW6900 is not set -# CONFIG_MACH_HTCATHENA is not set -# CONFIG_ARCH_AXIMX3 is not set -# CONFIG_ARCH_AXIMX5 is not set -# CONFIG_MACH_X50 is not set -# CONFIG_ARCH_ROVERP1 is not set -# CONFIG_ARCH_ROVERP5P is not set -# CONFIG_MACH_XSCALE_PALMLD is not set -# CONFIG_MACH_T3XSCALE is not set -# CONFIG_MACH_RECON is not set -# CONFIG_MACH_GHI270HG is not set -# CONFIG_MACH_GHI270 is not set -# CONFIG_MACH_LOOXC550 is not set -# CONFIG_PXA_SHARPSL is not set # CONFIG_MACH_TRIZEPS4 is not set +# CONFIG_MACH_EM_X270 is not set +# CONFIG_MACH_COLIBRI is not set +# CONFIG_MACH_ZYLONITE is not set +# CONFIG_MACH_LITTLETON is not set +# CONFIG_MACH_TAVOREVB is not set +# CONFIG_MACH_SAAR is not set +# CONFIG_MACH_ARMCORE is not set +# CONFIG_MACH_MAGICIAN is not set +# CONFIG_MACH_PCM027 is not set +# CONFIG_ARCH_PXA_PALM is not set +# CONFIG_PXA_EZX is not set CONFIG_PXA25x=y +# CONFIG_PXA_PWM is not set # -# Linux As Bootloader +# Boot options +# + +# +# Power management # -# CONFIG_LAB is not set # # Processor Type @@ -215,6 +208,7 @@ CONFIG_CPU_32=y CONFIG_CPU_XSCALE=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_PABRT_NOIFAR=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WBI=y CONFIG_CPU_CP15=y @@ -232,11 +226,9 @@ CONFIG_XSCALE_PMU=y # # Bus support # - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=m +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCCARD=y # CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=m CONFIG_PCMCIA_LOAD_CIS=y @@ -245,11 +237,14 @@ CONFIG_PCMCIA_IOCTL=y # # PC-card bridges # -CONFIG_PCMCIA_PXA2XX=m # # Kernel Features # +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_PREEMPT is not set CONFIG_HZ=100 CONFIG_AEABI=y @@ -262,9 +257,13 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4096 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y CONFIG_ALIGNMENT_TRAP=y # @@ -275,7 +274,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="" # CONFIG_XIP_KERNEL is not set CONFIG_KEXEC=y -# CONFIG_TXTOFFSET_DELTA is not set +CONFIG_ATAGS_PROC=y # # CPU Frequency scaling @@ -304,11 +303,12 @@ CONFIG_BINFMT_MISC=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set -# CONFIG_DPM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # Networking @@ -318,13 +318,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -339,35 +339,40 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set +CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# # CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -380,10 +385,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -391,15 +392,74 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set +# CONFIG_CAN is not set +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# +# CONFIG_KINGSUN_DONGLE is not set +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +CONFIG_PXA_FICP=y +# CONFIG_MCS_FIR is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +CONFIG_CFG80211=m +CONFIG_NL80211=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_MAC80211=m + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_PID=y +CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_MESH is not set +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_IEEE80211=m # CONFIG_IEEE80211_DEBUG is not set CONFIG_IEEE80211_CRYPT_WEP=m -# CONFIG_IEEE80211_CRYPT_CCMP is not set -# CONFIG_IEEE80211_CRYPT_TKIP is not set -# CONFIG_IEEE80211_SOFTMAC is not set -CONFIG_WIRELESS_EXT=y +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -408,38 +468,32 @@ CONFIG_WIRELESS_EXT=y # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=m # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_PARTITIONS is not set # # User Modules And Translation Layers # -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLKDEVS=m -CONFIG_MTD_BLOCK=m +# CONFIG_MTD_CHAR is not set +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set # CONFIG_MTD_BLOCK_RO is not set # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -459,7 +513,6 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access @@ -482,82 +535,43 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# CONFIG_MTD_NAND=m -CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_H1900 is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_SHARPSL is not set -# CONFIG_MTD_NAND_NANDSIM is not set - -# -# OneNAND Flash Device Drivers -# +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set # CONFIG_MTD_ONENAND is not set # -# Parallel port support +# UBI - Unsorted block images # +# CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=6144 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=m -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=m - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=m -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_IDE_GENERIC is not set -# CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set # # SCSI device support # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=m +CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set # CONFIG_SCSI_PROC_FS is not set @@ -565,7 +579,7 @@ CONFIG_SCSI=m # # SCSI support type (disk, tape, CD-ROM) # -# CONFIG_BLK_DEV_SD is not set +CONFIG_BLK_DEV_SD=m # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set @@ -579,6 +593,7 @@ CONFIG_SCSI=m # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -586,132 +601,78 @@ CONFIG_SCSI=m # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set - -# -# PCMCIA SCSI adapter support -# -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_NINJA_SCSI is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_SYM53C500 is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_DH is not set +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_PMP is not set +CONFIG_ATA_SFF=y +# CONFIG_SATA_MV is not set +CONFIG_PATA_PCMCIA=m +# CONFIG_PATA_PLATFORM is not set # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# - -# -# Ethernet (10 or 100Mbit) -# +# CONFIG_VETH is not set # CONFIG_NET_ETHERNET is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -# CONFIG_NET_WIRELESS_RTNETLINK is not set - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set -# CONFIG_PCMCIA_WAVELAN is not set -# CONFIG_PCMCIA_NETWAVE is not set - -# -# Wireless 802.11 Frequency Hopping cards support +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y # CONFIG_PCMCIA_RAYCS is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_HERMES is not set +# CONFIG_LIBERTAS is not set +CONFIG_HERMES=m +CONFIG_PCMCIA_HERMES=m +# CONFIG_PCMCIA_SPECTRUM is not set # CONFIG_ATMEL is not set - -# -# Wireless 802.11b Pcmcia/Cardbus cards support -# # CONFIG_AIRO_CS is not set # CONFIG_PCMCIA_WL3501 is not set # CONFIG_USB_ZD1201 is not set -CONFIG_HOSTAP=m -# CONFIG_HOSTAP_FIRMWARE is not set -# CONFIG_HOSTAP_CS is not set -# CONFIG_ACX is not set -CONFIG_NET_WIRELESS=y +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_RTL8187 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_P54_COMMON is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_HOSTAP is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_ZD1211RW is not set +# CONFIG_RT2X00 is not set # -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA is not set - -# -# Wan interfaces +# USB Network Adapters # +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=m +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set # @@ -719,38 +680,48 @@ CONFIG_NET_WIRELESS=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_TSDEV=m -CONFIG_INPUT_TSDEV_SCREEN_X=240 -CONFIG_INPUT_TSDEV_SCREEN_Y=320 CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set -# CONFIG_INPUT_LED_TRIGGER is not set # # Input Device Drivers # -# CONFIG_INPUT_KEYBOARD is not set +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYBOARD_GPIO=m # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set -CONFIG_TOUCHSCREEN_WM97XX=m -CONFIG_TOUCHSCREEN_WM9705=y -CONFIG_TOUCHSCREEN_WM9712=y -CONFIG_TOUCHSCREEN_WM9713=y # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_UCB1400 is not set +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_INPUT_MISC is not set # @@ -763,9 +734,11 @@ CONFIG_TOUCHSCREEN_WM9713=y # Character devices # CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y # CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -777,25 +750,12 @@ CONFIG_HW_CONSOLE=y # Non-8250 serial port support # # CONFIG_SERIAL_PXA is not set -# CONFIG_RS232_SERIAL is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=m # CONFIG_NVRAM is not set -# CONFIG_SA1100_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set -# CONFIG_TIHTC is not set # # PCMCIA character devices @@ -803,117 +763,79 @@ CONFIG_HW_RANDOM=m # CONFIG_SYNCLINK_CS is not set # CONFIG_CARDMAN_4000 is not set # CONFIG_CARDMAN_4040 is not set +# CONFIG_IPWIRELESS is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# # CONFIG_TCG_TPM is not set - -# -# I2C support -# # CONFIG_I2C is not set - -# -# SPI support -# # CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_GPIO_SYSFS is not set # -# Dallas's 1-wire bus +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: # # CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set # CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set # -# L3 serial bus support +# Sonics Silicon Backplane # -# CONFIG_L3 is not set - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# -# CONFIG_ADC is not set - -# -# Compaq/iPAQ Drivers -# - -# -# Compaq/HP iPAQ Drivers -# -# CONFIG_IPAQ_SLEEVE is not set -# CONFIG_SLEEVE_DEBUG is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers # +CONFIG_MFD_CORE=y # CONFIG_MFD_SM501 is not set -# CONFIG_HTC_ASIC2 is not set -# CONFIG_HTC_ASIC3 is not set -# CONFIG_HTC_PASIC3 is not set # CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_BBKEYS is not set -# CONFIG_HTC_ASIC3_DS1WM is not set -# CONFIG_SOC_SAMCOP is not set -# CONFIG_SOC_HAMCOP is not set -# CONFIG_SOC_MQ11XX is not set -CONFIG_SOC_T7L66XB=y -# CONFIG_SOC_TC6387XB is not set -CONFIG_SOC_TC6393XB=y -# CONFIG_SOC_TSC2101 is not set -# CONFIG_SOC_TSC2200 is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_HTC_PASIC3 is not set +CONFIG_MFD_TC6393XB=y # # Multimedia devices # -# CONFIG_VIDEO_DEV is not set # -# Digital Video Broadcasting Devices +# Multimedia core support # -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set # # Graphics support # -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CORGI=y +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -923,14 +845,25 @@ CONFIG_FB_CFB_IMAGEBLIT=y # # Frame buffer hardware drivers # -# CONFIG_FB_IMAGEON is not set # CONFIG_FB_S1D13XXX is not set CONFIG_FB_PXA=y +# CONFIG_FB_PXA_SMARTPANEL is not set # CONFIG_FB_PXA_PARAMETERS is not set # CONFIG_FB_MBX is not set CONFIG_FB_W100=y +# CONFIG_FB_AM200EPD is not set # CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_VSFB is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_PLATFORM is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # # Console display driver support @@ -938,6 +871,7 @@ CONFIG_FB_W100=y # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -945,28 +879,13 @@ CONFIG_FONTS=y # CONFIG_FONT_6x11 is not set # CONFIG_FONT_7x14 is not set # CONFIG_FONT_PEARL_8x8 is not set -CONFIG_FONT_ACORN_8x8=y -# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_MINI_4x6=y # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set - -# -# Logo configuration -# -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LOGO_LINUX_CLUT224=y - -# -# Sound -# +# CONFIG_LOGO is not set CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -980,125 +899,75 @@ CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y CONFIG_SND_VERBOSE_PRINTK=y # CONFIG_SND_DEBUG is not set - -# -# Generic devices -# +CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set - -# -# ALSA ARM devices -# +CONFIG_SND_ARM=y # CONFIG_SND_PXA2XX_AC97 is not set -# CONFIG_SND_RECON is not set - -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set - -# -# PCMCIA devices -# -# CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_PDAUDIOCF is not set - -# -# SoC audio support -# -CONFIG_SND_SOC_AC97_BUS=y +# CONFIG_SND_USB is not set +# CONFIG_SND_PCMCIA is not set CONFIG_SND_SOC=m - -# -# SoC Platforms -# - -# -# SoC Audio for the Atmel AT91 -# - -# -# SoC Audio for the Intel PXA2xx -# +CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_PXA2XX_SOC=m CONFIG_SND_PXA2XX_SOC_AC97=m -CONFIG_SND_PXA2XX_SOC_E740_WM9705=m -CONFIG_SND_PXA2XX_SOC_E750_WM9705=m -CONFIG_SND_PXA2XX_SOC_E800_WM9712=m -# CONFIG_SND_PXA2XX_SOC_MAGICIAN is not set -# CONFIG_SND_PXA2XX_SOC_BLUEANGEL is not set -# CONFIG_SND_PXA2XX_SOC_H5000 is not set - -# -# SoC Audio for the Freescale i.MX -# - -# -# SoC Audio for the Samsung S3C24XX -# -# CONFIG_SND_SOC_AC97_CODEC is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8731 is not set -# CONFIG_SND_SOC_WM8750 is not set -# CONFIG_SND_SOC_WM8753 is not set -# CONFIG_SND_SOC_WM8772 is not set -# CONFIG_SND_SOC_WM8971 is not set -# CONFIG_SND_SOC_WM8956 is not set -# CONFIG_SND_SOC_WM8960 is not set -# CONFIG_SND_SOC_WM8976 is not set -# CONFIG_SND_SOC_WM8974 is not set -# CONFIG_SND_SOC_WM8980 is not set -CONFIG_SND_SOC_WM9705=m -# CONFIG_SND_SOC_WM9713 is not set +CONFIG_SND_PXA2XX_SOC_E800=m CONFIG_SND_SOC_WM9712=m -# CONFIG_SND_SOC_UDA1380 is not set -# CONFIG_SND_SOC_AK4535 is not set - -# -# Open Sound System -# # CONFIG_SOUND_PRIME is not set CONFIG_AC97_BUS=m - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set # -# USB support +# USB Input Devices # +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set CONFIG_USB=m -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options # -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set # # USB Host Controller Drivers # +# CONFIG_USB_C67X00_HCD is not set # CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers # # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -1107,68 +976,19 @@ CONFIG_USB_DYNAMIC_MINORS=y # # may also be needed; see USB_STORAGE Help for more information # -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE is not set # CONFIG_USB_LIBUSUAL is not set -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_MON is not set +CONFIG_USB_MON=y # # USB port drivers # - -# -# USB Serial Converter support -# # CONFIG_USB_SERIAL is not set # @@ -1192,56 +1012,57 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# +# CONFIG_USB_ISIGHTFW is not set CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG_FILES is not set CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set # CONFIG_USB_GADGET_NET2280 is not set -CONFIG_USB_GADGET_PXA2XX=y -CONFIG_USB_PXA2XX=y -# CONFIG_USB_PXA2XX_SMALL is not set +CONFIG_USB_GADGET_PXA25X=y +CONFIG_USB_PXA25X=y +CONFIG_USB_PXA25X_SMALL=y +# CONFIG_USB_GADGET_M66592 is not set # CONFIG_USB_GADGET_PXA27X is not set # CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_MQ11XX is not set # CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_S3C2410 is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set # CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set # CONFIG_USB_GADGET_DUALSPEED is not set # CONFIG_USB_ZERO is not set -CONFIG_USB_ETH=y +CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_G_CHAR is not set -# CONFIG_USB_PXA2XX_GPIO is not set - -# -# MMC/SD Card support -# +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set -CONFIG_MMC_BLOCK=y -# CONFIG_MMC_PXA is not set -CONFIG_MMC_TMIO=y -# CONFIG_MMC_SAMCOP is not set +CONFIG_MMC_UNSAFE_RESUME=y # -# Real Time Clock +# MMC/SD Card Drivers # +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_MMC_PXA is not set +# CONFIG_MMC_SDHCI is not set +# CONFIG_NEW_LEDS is not set CONFIG_RTC_LIB=y # CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set # # File systems @@ -1255,14 +1076,11 @@ CONFIG_EXT2_FS=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -1292,7 +1110,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1305,30 +1122,21 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=m -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -1341,7 +1149,6 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -1363,10 +1170,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# +# CONFIG_SYSV68_PARTITION is not set CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=y @@ -1407,30 +1211,32 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set -# -# Profiling support -# -# CONFIG_PROFILING is not set - # # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_MEMORY_INIT is not set CONFIG_FRAME_POINTER=y +# CONFIG_LATENCYTOP is not set +CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +# CONFIG_FTRACE is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y # CONFIG_DEBUG_USER is not set # @@ -1438,61 +1244,102 @@ CONFIG_FRAME_POINTER=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y # -# Cryptographic options +# Crypto core or helper # -CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=m CONFIG_CRYPTO_BLKCIPHER=m CONFIG_CRYPTO_MANAGER=m -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_TEST is not set # -# Hardware crypto devices +# Authenticated Encryption with Associated Data # +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y # # Library routines # CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y