From 7dd06cdbd37c44a468117b0ffae0b54471268035 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Thu, 21 Feb 2008 16:18:43 +0800 Subject: [PATCH 001/880] [MAINTAINERS] use new kernel.org email for kernel development. Signed-off-by: Bryan Wu --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 36c7bc641dba..8ef8c01460e8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -767,14 +767,14 @@ S: Maintained BLACKFIN ARCHITECTURE P: Bryan Wu -M: bryan.wu@analog.com +M: cooloney@kernel.org L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported BLACKFIN EMAC DRIVER P: Bryan Wu -M: bryan.wu@analog.com +M: cooloney@kernel.org L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported From 7aa475cfb7030f491d040333a343d8c414765f1a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Feb 2008 16:01:50 +0800 Subject: [PATCH 002/880] [Blackfin] arch: fix bug add missing header file Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf548/dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c index 374803a8d2e8..f5479298bb79 100644 --- a/arch/blackfin/mach-bf548/dma.c +++ b/arch/blackfin/mach-bf548/dma.c @@ -27,6 +27,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include #include From 4d94bf674683b0560720bdea3b0c5d4716e1abec Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Feb 2008 16:03:54 +0800 Subject: [PATCH 003/880] [Blackfin] arch: respect `make -s` when creating the asm/mach symlink Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index fe254f886a6e..88ae549f7b2d 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -98,8 +98,10 @@ drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ # them changed. We use .mach to indicate when they were updated # last, otherwise make uses the target directory mtime. + quiet_show_mach_symlink = echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' +silent_show_mach_symlink = : include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf - @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' + @$($(quiet)show_mach_symlink) ifneq ($(KBUILD_SRC),) $(Q)mkdir -p include/asm-$(ARCH) $(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach From c63d4e64087aa6633c07964b5f028198c5bee762 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Feb 2008 16:12:01 +0800 Subject: [PATCH 004/880] [Blackfin] arch: add handling for the mach symlink in the `make V=1` case Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 88ae549f7b2d..75eba2ca7881 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -98,6 +98,7 @@ drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ # them changed. We use .mach to indicate when they were updated # last, otherwise make uses the target directory mtime. + show_mach_symlink = : quiet_show_mach_symlink = echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' silent_show_mach_symlink = : include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf From 8929ecf84df529338d258f0ad9c1e553dfc921bc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Feb 2008 16:35:20 +0800 Subject: [PATCH 005/880] [Blackfin] arch: add fixed code to the memory map output Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/kernel/setup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8229b1090eb9..febcbc527b45 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -514,6 +514,7 @@ static __init void memory_setup(void) printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); printk(KERN_INFO "Memory map:\n" + KERN_INFO " fixedcode = 0x%p-0x%p\n" KERN_INFO " text = 0x%p-0x%p\n" KERN_INFO " rodata = 0x%p-0x%p\n" KERN_INFO " bss = 0x%p-0x%p\n" @@ -527,7 +528,8 @@ static __init void memory_setup(void) #if DMA_UNCACHED_REGION > 0 KERN_INFO " DMA Zone = 0x%p-0x%p\n" #endif - , _stext, _etext, + , (void *)FIXED_CODE_START, (void *)FIXED_CODE_END, + _stext, _etext, __start_rodata, __end_rodata, __bss_start, __bss_stop, _sdata, _edata, From 32320ea0a63003a249773b5e3e459e66bb5fb8f8 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 22 Feb 2008 16:43:45 +0800 Subject: [PATCH 006/880] [Blackfin] arch: Update default config Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/configs/BF527-EZKIT_defconfig | 18 ++++++++---------- arch/blackfin/configs/BF533-EZKIT_defconfig | 6 ++---- arch/blackfin/configs/BF533-STAMP_defconfig | 6 ++---- arch/blackfin/configs/BF537-STAMP_defconfig | 6 +++--- arch/blackfin/configs/BF548-EZKIT_defconfig | 2 ++ arch/blackfin/configs/BF561-EZKIT_defconfig | 1 + 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index d59ee1530bd4..ae320dcfedef 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.22.14 -# Thu Nov 29 17:32:47 2007 +# Linux kernel version: 2.6.22.16 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -116,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y # 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 @@ -306,6 +308,7 @@ CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_WB is not set CONFIG_BFIN_WT=y CONFIG_L1_MAX_PIECE=16 +# CONFIG_MPU is not set # # Asynchonous Memory Configuration @@ -354,6 +357,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # Networking @@ -496,7 +500,6 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_INTELEXT is not set # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_MW320D=m CONFIG_MTD_RAM=y CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set @@ -506,9 +509,6 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_BF5xx=m -CONFIG_BFIN_FLASH_SIZE=0x400000 -CONFIG_EBIU_FLASH_BASE=0x20000000 # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -684,7 +684,6 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_UINPUT is not set -# CONFIG_BF53X_PFBUTTONS is not set # CONFIG_TWI_KEYPAD is not set # @@ -702,12 +701,12 @@ CONFIG_INPUT_MISC=y # 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_AD5304 is not set -# CONFIG_BF5xx_TEA5764 is not set -# CONFIG_BF5xx_FBDMA is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -772,7 +771,6 @@ CONFIG_I2C_CHARDEV=m # # I2C Hardware Bus support # -# CONFIG_I2C_BLACKFIN_GPIO is not set CONFIG_I2C_BLACKFIN_TWI=m CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_GPIO is not set diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 811711f59a25..9621caa60b5f 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -322,10 +322,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x80 # # CPU Frequency scaling @@ -697,7 +696,6 @@ 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 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index 198f4123af4b..b51e76ce7f4f 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -323,10 +323,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x80 # # CPU Frequency scaling @@ -714,7 +713,6 @@ 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 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index b37ccc681e7a..d45fa535dad7 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig @@ -330,10 +330,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x8 # # CPU Frequency scaling @@ -1013,6 +1012,7 @@ CONFIG_SND_BFIN_AD73311_SE=4 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 diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index fd702161ef59..c9707f7665ad 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -396,6 +396,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # CPU Frequency scaling @@ -1075,6 +1076,7 @@ CONFIG_SND_VERBOSE_PROCFS=y CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC=y CONFIG_SND_BF5XX_SOC=y +CONFIG_SND_MMAP_SUPPORT=y CONFIG_SND_BF5XX_SOC_AC97=y CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y # CONFIG_SND_BF5XX_SOC_WM8750 is not set diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index 8546994939fb..4d8a63331309 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -367,6 +367,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # Networking From edf056417d11fe9321ec15a55bd128e4f4c73796 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 25 Feb 2008 11:38:11 +0800 Subject: [PATCH 007/880] [Blackfin] arch: fix bug - set right partition size in the board files - set default u-boot partition size to 256k - modify the offset with the size change - use mtd defines (append for offset and full for size) where applicable rather than churning constants when we dont have to Signed-off-by: Grace Pan Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf527/boards/ezkit.c | 10 +++++----- arch/blackfin/mach-bf533/boards/ezkit.c | 6 +++--- arch/blackfin/mach-bf533/boards/stamp.c | 10 +++++----- arch/blackfin/mach-bf537/boards/stamp.c | 12 ++++++------ arch/blackfin/mach-bf548/boards/ezkit.c | 10 +++++----- arch/blackfin/mach-bf561/boards/ezkit.c | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 337515fba612..a28d5df20d71 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -180,8 +180,8 @@ static struct mtd_partition partition_info[] = { }, { .name = "File System", - .offset = 4 * SIZE_1M, - .size = (256 - 4) * SIZE_1M, + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, }, }; @@ -422,11 +422,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 2b09aa39f565..73f76af73e96 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -99,11 +99,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index a645f6fd091b..324317a89105 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -112,7 +112,7 @@ static struct platform_device net2272_bfin_device = { static struct mtd_partition stamp_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -160,17 +160,17 @@ static struct platform_device stamp_flash_device = { static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader", - .size = 0x00020000, + .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 9e2277e0d25c..9c6fa70c4064 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -343,7 +343,7 @@ static struct platform_device net2272_bfin_device = { static struct mtd_partition stamp_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -351,7 +351,7 @@ static struct mtd_partition stamp_partitions[] = { .offset = MTDPART_OFS_APPEND, }, { .name = "RootFS", - .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000, + .size = 0x400000 - 0x40000 - 0xE0000 - 0x10000, .offset = MTDPART_OFS_APPEND, }, { .name = "MAC Address", @@ -391,17 +391,17 @@ static struct platform_device stamp_flash_device = { static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader", - .size = 0x00020000, + .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 916e963e83ba..47a4f5547cf5 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -285,8 +285,8 @@ static struct mtd_partition partition_info[] = { }, { .name = "File System", - .offset = 4 * SIZE_1M, - .size = (256 - 4) * SIZE_1M, + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, }, }; @@ -333,7 +333,7 @@ static struct platform_device bf54x_sdh_device = { static struct mtd_partition ezkit_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -381,8 +381,8 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { .mask_flags = MTD_CAP_ROM }, { .name = "linux kernel", - .size = 0x1c0000, - .offset = 0x40000 + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 43c1b0982819..480b0a91a748 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -223,7 +223,7 @@ static struct platform_device bfin_uart_device = { static struct mtd_partition ezkit_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", From cad2ab65dd1c7d65153ffccd71c90db028fd62f0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Feb 2008 17:01:31 +0800 Subject: [PATCH 008/880] [Blackfin] arch: add board resources for new simple-gpio char driver Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf527/boards/ezkit.c | 15 +++++++++++++++ arch/blackfin/mach-bf533/boards/ezkit.c | 15 +++++++++++++++ arch/blackfin/mach-bf533/boards/stamp.c | 15 +++++++++++++++ arch/blackfin/mach-bf537/boards/stamp.c | 15 +++++++++++++++ arch/blackfin/mach-bf548/boards/ezkit.c | 15 +++++++++++++++ arch/blackfin/mach-bf561/boards/ezkit.c | 14 ++++++++++++++ 6 files changed, 89 insertions(+) diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index a28d5df20d71..770056b0e68b 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -818,6 +818,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #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 struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) &bf5xx_nand_device, @@ -895,6 +908,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, }; static int __init stamp_init(void) diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 73f76af73e96..241b5a20a36a 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -298,6 +298,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #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, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include @@ -350,6 +363,8 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) &i2c_gpio_device, #endif + + &bfin_gpios_device, }; static int __init ezkit_init(void) diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 324317a89105..c0f7d40fe124 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -457,6 +457,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #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, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include @@ -518,6 +531,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) &i2c_gpio_device, #endif + + &bfin_gpios_device, &stamp_flash_device, }; diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 9c6fa70c4064..7a5629a0c374 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -128,6 +128,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #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, +}; + #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) static struct resource bfin_pcmcia_cf_resources[] = { { @@ -821,6 +834,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, &stamp_flash_device, }; diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 47a4f5547cf5..a0950c1fd800 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -594,6 +594,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #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 struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, @@ -646,6 +659,8 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, &ezkit_flash_device, }; diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 480b0a91a748..d357f648d963 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -389,6 +389,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #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, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include @@ -446,6 +459,7 @@ static struct platform_device *ezkit_devices[] __initdata = { &isp1362_hcd_device, #endif + &bfin_gpios_device, &ezkit_flash_device, }; From 549aaa8425b4a1de23cbddc650dac75b91204af6 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 25 Feb 2008 11:13:07 +0800 Subject: [PATCH 009/880] [Blackfin] arch: Fix bug - Setting peripheral_map only when dma channel is UART2/3. Singed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- arch/blackfin/kernel/bfin_dma_5xx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 5453bc3664fc..8fd5d22cec34 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -105,13 +105,14 @@ int request_dma(unsigned int channel, char *device_id) mutex_unlock(&(dma_ch[channel].dmalock)); #ifdef CONFIG_BF54x - if (channel >= CH_UART2_RX && channel <= CH_UART3_TX && - strncmp(device_id, "BFIN_UART", 9) == 0) - dma_ch[channel].regs->peripheral_map |= - (channel - CH_UART2_RX + 0xC); - else - dma_ch[channel].regs->peripheral_map |= - (channel - CH_UART2_RX + 0x6); + if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { + if (strncmp(device_id, "BFIN_UART", 9) == 0) + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0xC); + else + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0x6); + } #endif dma_ch[channel].device_id = device_id; From 181afa94989f431e93eccd784c14c37ccb395a00 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 25 Feb 2008 11:42:17 +0800 Subject: [PATCH 010/880] [Blackfin] arch: grab mac address from OTP on BF527-EZKIT The bf527-ezkit stores the mac address in OTP, so grab it from there rather than flash Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf527/boards/ezkit.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 770056b0e68b..ab7a21faaa71 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -936,13 +936,18 @@ void native_machine_restart(char *cmd) bfin_gpio_reset_spi0_ssel1(); } -/* - * Currently the MAC address is saved in Flash by U-Boot - */ -#define FLASH_MAC 0x203f0000 void bfin_get_ether_addr(char *addr) { - *(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC); - *(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4); + /* the MAC is stored in OTP memory page 0xDF */ + u32 ret; + u64 otp_mac; + u32 (*otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)0xEF00001A; + + ret = otp_read(0xDF, 0x00, &otp_mac); + if (!(ret & 0x1)) { + char *otp_mac_p = (char *)&otp_mac; + for (ret = 0; ret < 6; ++ret) + addr[ret] = otp_mac_p[5 - ret]; + } } EXPORT_SYMBOL(bfin_get_ether_addr); From fe9ec9b9698b95ad21617c1db21eb0d1c040b93d Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 25 Feb 2008 12:04:57 +0800 Subject: [PATCH 011/880] [Blackfin] arch: fix bug - Move IWR Enable All to the end of init_arch_irq otherwise it fails Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/mach-common/ints-priority.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 880595afe98d..b321c4a92a67 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -969,15 +969,11 @@ int __init init_arch_irq(void) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); bfin_write_SIC_IMASK1(SIC_UNMASK_ALL); - bfin_write_SIC_IWR0(IWR_ENABLE_ALL); - bfin_write_SIC_IWR1(IWR_ENABLE_ALL); # ifdef CONFIG_BF54x bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); - bfin_write_SIC_IWR2(IWR_ENABLE_ALL); # endif #else bfin_write_SIC_IMASK(SIC_UNMASK_ALL); - bfin_write_SIC_IWR(IWR_ENABLE_ALL); #endif SSYNC(); @@ -1106,6 +1102,16 @@ int __init init_arch_irq(void) IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; +#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) + bfin_write_SIC_IWR0(IWR_ENABLE_ALL); + bfin_write_SIC_IWR1(IWR_ENABLE_ALL); +# ifdef CONFIG_BF54x + bfin_write_SIC_IWR2(IWR_ENABLE_ALL); +# endif +#else + bfin_write_SIC_IWR(IWR_ENABLE_ALL); +#endif + return 0; } From 0db5d105cd62055ea7a3b7ddf7b7408ba65a07b9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 25 Feb 2008 12:19:57 +0800 Subject: [PATCH 012/880] [Blackfin] arch: punt the simple ad5304 spi driver now that the generic spidev driver lets you do it from userspace Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf527/boards/ezkit.c | 18 ------------------ arch/blackfin/mach-bf533/boards/stamp.c | 18 ------------------ .../blackfin/mach-bf537/boards/generic_board.c | 18 ------------------ arch/blackfin/mach-bf537/boards/stamp.c | 18 ------------------ 4 files changed, 72 deletions(-) diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index ab7a21faaa71..cf4bc0d83355 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -484,13 +484,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -611,17 +604,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index c0f7d40fe124..b2ac4816ae62 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -212,13 +212,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_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, @@ -308,17 +301,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c index 8a3397db1d21..c95395ba7bfa 100644 --- a/arch/blackfin/mach-bf537/boards/generic_board.c +++ b/arch/blackfin/mach-bf537/boards/generic_board.c @@ -371,13 +371,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -483,17 +476,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 7a5629a0c374..ea83148993da 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -472,13 +472,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -591,17 +584,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", From d45118b14bf04e124e4d875b136d5c1c4df97d57 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 25 Feb 2008 12:24:44 +0800 Subject: [PATCH 013/880] [Blackfin] arch: make sure we export the _bfin_swrst symbol as modules (like the watchdog) need it Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/kernel/setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index febcbc527b45..2255c289a714 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -32,6 +32,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); u16 _bfin_swrst; +EXPORT_SYMBOL(_bfin_swrst); unsigned long memory_start, memory_end, physical_mem_end; unsigned long reserved_mem_dcache_on; From ce3b7bb61c120e1e4e70e892ec281ef2bb81d6fa Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 25 Feb 2008 13:48:47 +0800 Subject: [PATCH 014/880] [Blackfin] arch: fix bug - linux-2.6.24 (delayed) disable IRQ feature not functional for handle_simple_irq Bypass delayed disable feature by implementing chip->disable and chip->enable. http://lkml.org/lkml/2008/2/19/115 Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/mach-common/ints-priority.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index b321c4a92a67..22bcdef00e0a 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -213,6 +213,9 @@ static struct irq_chip bfin_internal_irqchip = { .ack = ack_noop, .mask = bfin_internal_mask_irq, .unmask = bfin_internal_unmask_irq, + .mask_ack = bfin_internal_mask_irq, + .disable = bfin_internal_mask_irq, + .enable = bfin_internal_unmask_irq, #ifdef CONFIG_PM .set_wake = bfin_internal_set_wake, #endif From 464abc5de6ea8f4af1c1246e0d1ea7b07362db43 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 25 Feb 2008 13:50:20 +0800 Subject: [PATCH 015/880] [Blackfin] arch: Cleanup abd Simplify: - Simplify init_arch_irq - Make code more readable - Remove useless SSYNCs - Fix comments Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/mach-common/ints-priority.c | 157 +++++++--------------- include/asm-blackfin/irq.h | 2 + 2 files changed, 53 insertions(+), 106 deletions(-) diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 22bcdef00e0a..225ef14af75e 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -74,7 +74,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ #endif struct ivgx { - /* irq number for request_irq, available in mach-bf533/irq.h */ + /* irq number for request_irq, available in mach-bf5xx/irq.h */ unsigned int irqno; /* corresponding bit in the SIC_ISR register */ unsigned int isrflag; @@ -86,7 +86,6 @@ struct ivg_slice { struct ivgx *istop; } ivg7_13[IVG13 - IVG7 + 1]; -static void search_IAR(void); /* * Search SIC_IAR and fill tables with the irqvalues @@ -120,10 +119,10 @@ static void __init search_IAR(void) } /* - * This is for BF533 internal IRQs + * This is for core internal IRQs */ -static void ack_noop(unsigned int irq) +static void bfin_ack_noop(unsigned int irq) { /* Dummy function. */ } @@ -156,11 +155,11 @@ static void bfin_internal_mask_irq(unsigned int irq) { #ifdef CONFIG_BF53x bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << (irq - (IRQ_CORETMR + 1)))); + ~(1 << SIC_SYSIRQ(irq))); #else unsigned mask_bank, mask_bit; - mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; - mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & ~(1 << mask_bit)); #endif @@ -171,11 +170,11 @@ static void bfin_internal_unmask_irq(unsigned int irq) { #ifdef CONFIG_BF53x bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | - (1 << (irq - (IRQ_CORETMR + 1)))); + (1 << SIC_SYSIRQ(irq))); #else unsigned mask_bank, mask_bit; - mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; - mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | (1 << mask_bit)); #endif @@ -187,8 +186,8 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) { unsigned bank, bit; unsigned long flags; - bank = (irq - (IRQ_CORETMR + 1)) / 32; - bit = (irq - (IRQ_CORETMR + 1)) % 32; + bank = SIC_SYSIRQ(irq) / 32; + bit = SIC_SYSIRQ(irq) % 32; local_irq_save(flags); @@ -204,13 +203,13 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) #endif static struct irq_chip bfin_core_irqchip = { - .ack = ack_noop, + .ack = bfin_ack_noop, .mask = bfin_core_mask_irq, .unmask = bfin_core_unmask_irq, }; static struct irq_chip bfin_internal_irqchip = { - .ack = ack_noop, + .ack = bfin_ack_noop, .mask = bfin_internal_mask_irq, .unmask = bfin_internal_unmask_irq, .mask_ack = bfin_internal_mask_irq, @@ -224,38 +223,23 @@ static struct irq_chip bfin_internal_irqchip = { #ifdef BF537_GENERIC_ERROR_INT_DEMUX static int error_int_mask; -static void bfin_generic_error_ack_irq(unsigned int irq) -{ - -} - static void bfin_generic_error_mask_irq(unsigned int irq) { error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); - if (!error_int_mask) { - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << (IRQ_GENERIC_ERROR - - (IRQ_CORETMR + 1)))); - SSYNC(); - local_irq_enable(); - } + if (!error_int_mask) + bfin_internal_mask_irq(IRQ_GENERIC_ERROR); } static void bfin_generic_error_unmask_irq(unsigned int irq) { - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 << - (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1))); - SSYNC(); - local_irq_enable(); - + bfin_internal_unmask_irq(IRQ_GENERIC_ERROR); error_int_mask |= 1L << (irq - IRQ_PPI_ERROR); } static struct irq_chip bfin_generic_error_irqchip = { - .ack = bfin_generic_error_ack_irq, + .ack = bfin_ack_noop, + .mask_ack = bfin_generic_error_mask_irq, .mask = bfin_generic_error_mask_irq, .unmask = bfin_generic_error_unmask_irq, }; @@ -611,7 +595,7 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { (struct pin_int_t *)PINT3_MASK_SET, }; -unsigned short get_irq_base(u8 bank, u8 bmap) +inline unsigned short get_irq_base(u8 bank, u8 bmap) { u16 irq_base; @@ -978,7 +962,6 @@ int __init init_arch_irq(void) #else bfin_write_SIC_IMASK(SIC_UNMASK_ALL); #endif - SSYNC(); local_irq_disable(); @@ -1000,90 +983,53 @@ int __init init_arch_irq(void) set_irq_chip(irq, &bfin_core_irqchip); else set_irq_chip(irq, &bfin_internal_irqchip); -#ifdef BF537_GENERIC_ERROR_INT_DEMUX - if (irq != IRQ_GENERIC_ERROR) { -#endif - switch (irq) { + switch (irq) { #if defined(CONFIG_BF53x) - case IRQ_PROG_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PROG_INTA: # if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) - case IRQ_MAC_RX: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_MAC_RX: # endif #elif defined(CONFIG_BF54x) - case IRQ_PINT0: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT1: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT2: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT3: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PINT0: + case IRQ_PINT1: + case IRQ_PINT2: + case IRQ_PINT3: #elif defined(CONFIG_BF52x) - case IRQ_PORTF_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PORTG_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PORTH_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PORTF_INTA: + case IRQ_PORTG_INTA: + case IRQ_PORTH_INTA: #elif defined(CONFIG_BF561) - case IRQ_PROG0_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PROG1_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PROG2_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PROG0_INTA: + case IRQ_PROG1_INTA: + case IRQ_PROG2_INTA: #endif - default: - set_irq_handler(irq, handle_simple_irq); - break; - } - + set_irq_chained_handler(irq, + bfin_demux_gpio_irq); + break; #ifdef BF537_GENERIC_ERROR_INT_DEMUX - } else { + case IRQ_GENERIC_ERROR: set_irq_handler(irq, bfin_demux_error_irq); - } + + break; #endif + default: + set_irq_handler(irq, handle_simple_irq); + break; + } } + #ifdef BF537_GENERIC_ERROR_INT_DEMUX - for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) { - set_irq_chip(irq, &bfin_generic_error_irqchip); - set_irq_handler(irq, handle_level_irq); - } + for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) + set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, + handle_level_irq); #endif - for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) { + /* if configured as edge, then will be changed to do_edge_IRQ */ + for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) + set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, + handle_level_irq); - set_irq_chip(irq, &bfin_gpio_irqchip); - /* if configured as edge, then will be changed to do_edge_IRQ */ - set_irq_handler(irq, handle_level_irq); - } bfin_write_IMASK(0); CSYNC(); @@ -1131,7 +1077,6 @@ void do_irq(int vec, struct pt_regs *fp) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) unsigned long sic_status[3]; - SSYNC(); sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0(); sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1(); #ifdef CONFIG_BF54x @@ -1147,7 +1092,7 @@ void do_irq(int vec, struct pt_regs *fp) } #else unsigned long sic_status; - SSYNC(); + sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); for (;; ivg++) { diff --git a/include/asm-blackfin/irq.h b/include/asm-blackfin/irq.h index 65480dab244e..86b67834354d 100644 --- a/include/asm-blackfin/irq.h +++ b/include/asm-blackfin/irq.h @@ -67,4 +67,6 @@ static __inline__ int irq_canonicalize(int irq) #define NO_IRQ ((unsigned int)(-1)) #endif +#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) + #endif /* _BFIN_IRQ_H_ */ From 9253d02041c60d732713c40c59b49fbde8f3bc1c Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 25 Feb 2008 14:27:28 +0800 Subject: [PATCH 016/880] [Blackfin] arch: Remove DPMC char driver option Remove redundant/obsolete/dead code from DPMC driver Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/mach-common/dpmc.S | 131 ------------------------------- 1 file changed, 131 deletions(-) diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S index b80ddd8b232d..fc9f6eb9018b 100644 --- a/arch/blackfin/mach-common/dpmc.S +++ b/arch/blackfin/mach-common/dpmc.S @@ -33,137 +33,6 @@ .text -ENTRY(_unmask_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.H = hi(SICA_IWR1); - P0.L = lo(SICA_IWR1); -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x) - P0.h = HI(SIC_IWR0); - P0.l = LO(SIC_IWR0); -#else - P0.h = HI(SIC_IWR); - P0.l = LO(SIC_IWR); -#endif - R7 = [P0]; -#if defined(CONFIG_BF561) - BITSET(R7, 27); -#else - BITSET(R7,(IRQ_WATCH - IVG7)); -#endif - [P0] = R7; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -.LWRITE_TO_STAT: - /* When watch dog timer is enabled, a write to STAT will load the - * contents of CNT to STAT - */ - R7 = 0x0000(z); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_STAT); - P0.l = LO(WDOGA_STAT); -#else - P0.h = HI(WDOG_STAT); - P0.l = LO(WDOG_STAT); -#endif - [P0] = R7; - SSYNC; - JUMP .LSKIP_WRITE_TO_STAT; - -ENTRY(_program_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CNT); - P0.l = LO(WDOGA_CNT); -#else - P0.h = HI(WDOG_CNT); - P0.l = LO(WDOG_CNT); -#endif - [P0] = R0; - SSYNC; - -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = W[P0](Z); - CC = BITTST(R7,1); - if !CC JUMP .LWRITE_TO_STAT; - CC = BITTST(R7,2); - if !CC JUMP .LWRITE_TO_STAT; - -.LSKIP_WRITE_TO_STAT: -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = W[P0](Z); - BITCLR(R7,1); /* Enable GP event */ - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - NOP; - - R7 = W[P0](Z); - BITCLR(R7,4); /* Enable the wdog counter */ - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_clear_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); - -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = 0x0AD6(Z); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,15); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,1); - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_disable_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = 0xAD6(Z); - W[P0] = R7.L; - SSYNC; - ( R7:0, P5:0 ) = [SP++]; - RTS; - #if !defined(CONFIG_BF561) .section .l1.text From 3927819d511f5b5855e6f2345f24e7b04e4fd2f5 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 25 Feb 2008 14:39:50 +0800 Subject: [PATCH 017/880] [Blackfin] arch: Fix CONFIG_PM support for BF561 Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- arch/blackfin/mach-common/dpmc.S | 6 ++---- include/asm-blackfin/mach-bf561/blackfin.h | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S index fc9f6eb9018b..9d45aa3265b1 100644 --- a/arch/blackfin/mach-common/dpmc.S +++ b/arch/blackfin/mach-common/dpmc.S @@ -31,9 +31,6 @@ #include #include -.text - -#if !defined(CONFIG_BF561) .section .l1.text @@ -328,10 +325,12 @@ ENTRY(_set_sic_iwr) RTS; ENTRY(_set_rtc_istat) +#ifndef CONFIG_BF561 P0.H = hi(RTC_ISTAT); P0.L = lo(RTC_ISTAT); w[P0] = R0.L; SSYNC; +#endif RTS; ENTRY(_test_pll_locked) @@ -342,4 +341,3 @@ ENTRY(_test_pll_locked) CC = BITTST(R0,5); IF !CC JUMP 1b; RTS; -#endif diff --git a/include/asm-blackfin/mach-bf561/blackfin.h b/include/asm-blackfin/mach-bf561/blackfin.h index 362617f93845..3a16df2c86d8 100644 --- a/include/asm-blackfin/mach-bf561/blackfin.h +++ b/include/asm-blackfin/mach-bf561/blackfin.h @@ -49,7 +49,8 @@ #define bfin_read_FIO_INEN() bfin_read_FIO0_INEN() #define bfin_write_FIO_INEN(val) bfin_write_FIO0_INEN(val) - +#define SIC_IWR0 SICA_IWR0 +#define SIC_IWR1 SICA_IWR1 #define SIC_IAR0 SICA_IAR0 #define bfin_write_SIC_IMASK0 bfin_write_SICA_IMASK0 #define bfin_write_SIC_IMASK1 bfin_write_SICA_IMASK1 From fee40119a2b2abbe239438b74052854db6f3444d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 25 Feb 2008 15:06:07 +0800 Subject: [PATCH 018/880] [Blackfin] arch: make sure we have proper description/copyright/license lines Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/kernel/gptimers.c | 8 ++++---- include/asm-blackfin/gptimers.h | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index 5cf4bdb1df3b..1904d8b53328 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c @@ -1,9 +1,9 @@ /* - * bfin_gptimers.c - derived from bf53x_timers.c - * Driver for General Purpose Timer functions on the Blackfin processor + * gptimers.c - Blackfin General Purpose Timer core API * - * Copyright (C) 2005 John DeHority - * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) + * Copyright (c) 2005-2008 Analog Devices Inc. + * Copyright (C) 2005 John DeHority + * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) * * Licensed under the GPLv2. */ diff --git a/include/asm-blackfin/gptimers.h b/include/asm-blackfin/gptimers.h index 8265ea473d5b..4f318f1fd2d9 100644 --- a/include/asm-blackfin/gptimers.h +++ b/include/asm-blackfin/gptimers.h @@ -1,12 +1,11 @@ /* - * include/asm/bf5xx_timers.h - * - * This file contains the major Data structures and constants - * used for General Purpose Timer Implementation in BF5xx + * gptimers.h - Blackfin General Purpose Timer structs/defines/prototypes * + * Copyright (c) 2005-2008 Analog Devices Inc. * Copyright (C) 2005 John DeHority * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) * + * Licensed under the GPL-2. */ #ifndef _BLACKFIN_TIMERS_H_ From 40edad3efadb3aa486c7a5452401c4de10902496 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 25 Feb 2008 15:23:30 +0800 Subject: [PATCH 019/880] [Blackfin] arch: add bfin_clear_PPIx_STATUS() helper funcs like we have for other parts Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- include/asm-blackfin/mach-bf561/cdefBF561.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-blackfin/mach-bf561/cdefBF561.h b/include/asm-blackfin/mach-bf561/cdefBF561.h index d667816486c0..1bc8d2f89ccc 100644 --- a/include/asm-blackfin/mach-bf561/cdefBF561.h +++ b/include/asm-blackfin/mach-bf561/cdefBF561.h @@ -559,6 +559,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val) #define bfin_write_PPI0_CONTROL(val) bfin_write16(PPI0_CONTROL,val) #define bfin_read_PPI0_STATUS() bfin_read16(PPI0_STATUS) #define bfin_write_PPI0_STATUS(val) bfin_write16(PPI0_STATUS,val) +#define bfin_clear_PPI0_STATUS() bfin_read_PPI0_STATUS() #define bfin_read_PPI0_COUNT() bfin_read16(PPI0_COUNT) #define bfin_write_PPI0_COUNT(val) bfin_write16(PPI0_COUNT,val) #define bfin_read_PPI0_DELAY() bfin_read16(PPI0_DELAY) @@ -570,6 +571,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val) #define bfin_write_PPI1_CONTROL(val) bfin_write16(PPI1_CONTROL,val) #define bfin_read_PPI1_STATUS() bfin_read16(PPI1_STATUS) #define bfin_write_PPI1_STATUS(val) bfin_write16(PPI1_STATUS,val) +#define bfin_clear_PPI1_STATUS() bfin_read_PPI1_STATUS() #define bfin_read_PPI1_COUNT() bfin_read16(PPI1_COUNT) #define bfin_write_PPI1_COUNT(val) bfin_write16(PPI1_COUNT,val) #define bfin_read_PPI1_DELAY() bfin_read16(PPI1_DELAY) From 8b07a2a1e58beb60c4a40a46251f053d64e1eb36 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 29 Feb 2008 11:57:35 +0800 Subject: [PATCH 020/880] [Blackfin] arch: handle the most common L1 shrinkage case (L1 does not exist for a part) so that any parts labeled for L1 instead get placed into external memory sections Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/kernel/vmlinux.lds.S | 34 ++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index aed832540b3b..cb01a9de2680 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -147,44 +147,64 @@ SECTIONS __l1_lma_start = .; +#if L1_CODE_LENGTH +# define LDS_L1_CODE *(.l1.text) +#else +# define LDS_L1_CODE +#endif .text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs)) { . = ALIGN(4); __stext_l1 = .; - *(.l1.text) - + LDS_L1_CODE . = ALIGN(4); __etext_l1 = .; } +#if L1_DATA_A_LENGTH +# define LDS_L1_A_DATA *(.l1.data) +# define LDS_L1_A_BSS *(.l1.bss) +# define LDS_L1_A_CACHE *(.data_l1.cacheline_aligned) +#else +# define LDS_L1_A_DATA +# define LDS_L1_A_BSS +# define LDS_L1_A_CACHE +#endif .data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1)) { . = ALIGN(4); __sdata_l1 = .; - *(.l1.data) + LDS_L1_A_DATA __edata_l1 = .; . = ALIGN(4); __sbss_l1 = .; - *(.l1.bss) + LDS_L1_A_BSS . = ALIGN(32); - *(.data_l1.cacheline_aligned) + LDS_L1_A_CACHE . = ALIGN(4); __ebss_l1 = .; } +#if L1_DATA_B_LENGTH +# define LDS_L1_B_DATA *(.l1.data.B) +# define LDS_L1_B_BSS *(.l1.bss.B) +#else +# define LDS_L1_B_DATA +# define LDS_L1_B_BSS +#endif .data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1)) { . = ALIGN(4); __sdata_b_l1 = .; - *(.l1.data.B) + LDS_L1_B_DATA __edata_b_l1 = .; . = ALIGN(4); __sbss_b_l1 = .; - *(.l1.bss.B) + LDS_L1_B_BSS . = ALIGN(4); __ebss_b_l1 = .; From c051489df8b027238ff22d64d4e01ede3ad77dd5 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Fri, 29 Feb 2008 12:02:10 +0800 Subject: [PATCH 021/880] [Blackfin] arch: kill section mismatch warnings Signed-off-by: Bryan Wu --- arch/blackfin/mach-bf548/head.S | 9 +++++++-- arch/blackfin/mm/init.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index 74fe258421a5..46222a75321a 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S @@ -28,6 +28,7 @@ */ #include +#include #include #include #if CONFIG_BFIN_KERNEL_CLOCK @@ -44,10 +45,9 @@ #define INITIAL_STACK 0xFFB01000 -.text +__INIT ENTRY(__start) -ENTRY(__stext) /* R0: argument of command line string, passed from uboot, save it */ R7 = R0; /* Enable Cycle Counter and Nesting Of Interrupts */ @@ -213,6 +213,7 @@ ENTRY(__stext) .LWAIT_HERE: jump .LWAIT_HERE; +ENDPROC(__start) ENTRY(_real_start) [ -- sp ] = reti; @@ -285,6 +286,9 @@ ENTRY(_real_start) call _start_kernel; .L_exit: jump.s .L_exit; +ENDPROC(_real_start) + +__FINIT .section .l1.text #if CONFIG_BFIN_KERNEL_CLOCK @@ -450,6 +454,7 @@ ENTRY(_start_dma_code) SSYNC; RTS; +ENDPROC(_start_dma_code) #endif /* CONFIG_BFIN_KERNEL_CLOCK */ .data diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 1f516c55bde6..ec3141fefd20 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -181,7 +181,7 @@ void __init mem_init(void) } } -static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end) +static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) { unsigned long addr; /* next to check that the page we free is not a partial page */ @@ -203,7 +203,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) } #endif -void __init free_initmem(void) +void __init_refok free_initmem(void) { #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU free_init_pages("unused kernel memory", From 759eb040901af60d8a1a2b59b93805521b156cbb Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 21 Nov 2007 17:00:32 +0800 Subject: [PATCH 022/880] Blackfin Serial driver: Fix bug - serial driver in PIO mode cant handle input very quickly Output as many bytes as possible in PIO tx handler. This reduce the number of tx interrupts and shorten the delay to handle rx interrupt. So, rx overrun disappears. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 62 +++++++++------------------------------ 1 file changed, 14 insertions(+), 48 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index ac2a3ef28d55..e059475c91ae 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -74,7 +74,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); #else static void bfin_serial_do_work(struct work_struct *work); static void bfin_serial_tx_chars(struct bfin_serial_port *uart); -static void local_put_char(struct bfin_serial_port *uart, char ch); #endif static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); @@ -85,6 +84,9 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); static void bfin_serial_stop_tx(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; +#ifndef CONFIG_BF54x + unsigned short ier; +#endif while (!(UART_GET_LSR(uart) & TEMT)) continue; @@ -100,8 +102,6 @@ static void bfin_serial_stop_tx(struct uart_port *port) UART_PUT_LSR(uart, TFI); UART_CLEAR_IER(uart, ETBEI); #else - unsigned short ier; - ier = UART_GET_IER(uart); ier &= ~ETBEI; UART_PUT_IER(uart, ier); @@ -210,23 +210,6 @@ int kgdb_get_debug_char(void) #endif #ifdef CONFIG_SERIAL_BFIN_PIO -static void local_put_char(struct bfin_serial_port *uart, char ch) -{ - unsigned short status; - int flags = 0; - - spin_lock_irqsave(&uart->port.lock, flags); - - do { - status = UART_GET_LSR(uart); - } while (!(status & THRE)); - - UART_PUT_CHAR(uart, ch); - SSYNC(); - - spin_unlock_irqrestore(&uart->port.lock, flags); -} - static void bfin_serial_rx_chars(struct bfin_serial_port *uart) { struct tty_struct *tty = uart->port.info->tty; @@ -236,8 +219,8 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) struct pt_regs *regs = get_irq_regs(); #endif - status = UART_GET_LSR(uart); ch = UART_GET_CHAR(uart); + status = UART_GET_LSR(uart); uart->port.icount.rx++; #ifdef CONFIG_KGDB_UART @@ -337,9 +320,12 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) return; } - local_put_char(uart, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - uart->port.icount.tx++; + while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) { + UART_PUT_CHAR(uart, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx++; + SSYNC(); + } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); @@ -352,21 +338,11 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; -#ifdef CONFIG_BF54x - unsigned short status; spin_lock(&uart->port.lock); - status = UART_GET_LSR(uart); - while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) { + while ((UART_GET_IER(uart) & ERBFI) && (UART_GET_LSR(uart) & DR)) bfin_serial_rx_chars(uart); - status = UART_GET_LSR(uart); - } spin_unlock(&uart->port.lock); -#else - spin_lock(&uart->port.lock); - while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) - bfin_serial_rx_chars(uart); - spin_unlock(&uart->port.lock); -#endif + return IRQ_HANDLED; } @@ -374,21 +350,11 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; -#ifdef CONFIG_BF54x - unsigned short status; spin_lock(&uart->port.lock); - status = UART_GET_LSR(uart); - while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) { + if ((UART_GET_IER(uart) & ETBEI) && (UART_GET_LSR(uart) & THRE)) bfin_serial_tx_chars(uart); - status = UART_GET_LSR(uart); - } spin_unlock(&uart->port.lock); -#else - spin_lock(&uart->port.lock); - while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) - bfin_serial_tx_chars(uart); - spin_unlock(&uart->port.lock); -#endif + return IRQ_HANDLED; } From 1b73351c6afcc3acbf9e29a43ee14b3c9a386503 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 21 Dec 2007 16:45:12 +0800 Subject: [PATCH 023/880] [Blackfin] serial driver: Clean up UART DMA code. Start next TX DMA in tx dma handler instead of rx timer handler. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index e059475c91ae..3a2aa7e277fa 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -84,7 +84,7 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); static void bfin_serial_stop_tx(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; -#ifndef CONFIG_BF54x +#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA) unsigned short ier; #endif @@ -307,7 +307,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) UART_PUT_CHAR(uart, uart->port.x_char); uart->port.icount.tx++; uart->port.x_char = 0; - return; } /* * Check the modem control lines before @@ -376,28 +375,26 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) if (!uart->tx_done) return; - uart->tx_done = 0; + if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { + bfin_serial_stop_tx(&uart->port); + uart->tx_done = 1; + return; + } + if (uart->port.x_char) { UART_PUT_CHAR(uart, uart->port.x_char); uart->port.icount.tx++; uart->port.x_char = 0; - uart->tx_done = 1; - return; } + /* * Check the modem control lines before * transmitting anything. */ bfin_serial_mctrl_check(uart); - if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { - bfin_serial_stop_tx(&uart->port); - uart->tx_done = 1; - return; - } - spin_lock_irqsave(&uart->port.lock, flags); uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail)) @@ -471,8 +468,6 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) int x_pos, pos; int flags = 0; - bfin_serial_dma_tx_chars(uart); - spin_lock_irqsave(&uart->port.lock, flags); x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel); if (x_pos == DMA_RX_XCOUNT) @@ -513,9 +508,9 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); - if (uart_circ_empty(xmit)) - bfin_serial_stop_tx(&uart->port); uart->tx_done = 1; + + bfin_serial_dma_tx_chars(uart); } spin_unlock(&uart->port.lock); From 75b780bd99b851682289e7a88763ede5a936edb0 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 21 Dec 2007 17:03:39 +0800 Subject: [PATCH 024/880] [Blackfin] serial driver: Fix bug Free rx dma buffer in shutdown. Kernel crash for the serial driver in DMA mode: http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3679 Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 3a2aa7e277fa..838f491c8deb 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -704,6 +704,7 @@ static void bfin_serial_shutdown(struct uart_port *port) disable_dma(uart->rx_dma_channel); free_dma(uart->rx_dma_channel); del_timer(&(uart->rx_dma_timer)); + dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0); #else #ifdef CONFIG_KGDB_UART if (uart->port.line != CONFIG_KGDB_UART_PORT) From 99ee7b5f3a68324807650f650f2613bbe281627f Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 21 Dec 2007 17:12:55 +0800 Subject: [PATCH 025/880] [Blackfin] serial driver: Fix bug serial driver in DMA mode spams history to console on shell restart http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=2920 Fix by increasing buffer tail immediately before starting tx dma. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 838f491c8deb..007414639e32 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -411,6 +411,10 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) set_dma_x_count(uart->tx_dma_channel, uart->tx_count); set_dma_x_modify(uart->tx_dma_channel, 1); enable_dma(uart->tx_dma_channel); + + xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx += uart->tx_count; + #ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); #else @@ -502,9 +506,6 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) ier &= ~ETBEI; UART_PUT_IER(uart, ier); #endif - xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); - uart->port.icount.tx+=uart->tx_count; - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); From 4c195ad88b7df54b2e7340dec3446aee6ca84cd1 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sun, 23 Dec 2007 23:18:08 +0800 Subject: [PATCH 026/880] [Blackfin] serial driver: fix bug - should not wait for the TFI bit, just clear it when tx stop. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 007414639e32..ca9ceaa113a2 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -95,9 +95,6 @@ static void bfin_serial_stop_tx(struct uart_port *port) disable_dma(uart->tx_dma_channel); #else #ifdef CONFIG_BF54x - /* Waiting for Transmission Finished */ - while (!(UART_GET_LSR(uart) & TFI)) - continue; /* Clear TFI bit */ UART_PUT_LSR(uart, TFI); UART_CLEAR_IER(uart, ETBEI); From 0bcfd70ea11a5d6f2362be463513a60245a62baf Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 24 Dec 2007 19:40:05 +0800 Subject: [PATCH 027/880] [Blackfin] serial driver: fix bug - cache the bits of the LSR on systems where the LSR is read-to-clear Cache the bits of the LSR on systems where the LSR is read-to-clear so that we can safely read the LSR in random places. this fixes older parts where break/framing/parity/overflow was not being detected at all in PIO mode, and this fixes newer parts where break/framing/parity/overflow was being reported all the time without being cleared. Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 10 +++++++--- .../asm-blackfin/mach-bf527/bfin_serial_5xx.h | 19 ++++++++++++++++++- .../asm-blackfin/mach-bf533/bfin_serial_5xx.h | 19 ++++++++++++++++++- .../asm-blackfin/mach-bf537/bfin_serial_5xx.h | 19 ++++++++++++++++++- .../asm-blackfin/mach-bf548/bfin_serial_5xx.h | 1 + .../asm-blackfin/mach-bf561/bfin_serial_5xx.h | 19 ++++++++++++++++++- 6 files changed, 80 insertions(+), 7 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index ca9ceaa113a2..af84984df775 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -216,8 +216,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) struct pt_regs *regs = get_irq_regs(); #endif - ch = UART_GET_CHAR(uart); status = UART_GET_LSR(uart); + UART_CLEAR_LSR(uart); + + ch = UART_GET_CHAR(uart); uart->port.icount.rx++; #ifdef CONFIG_KGDB_UART @@ -335,7 +337,7 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) struct bfin_serial_port *uart = dev_id; spin_lock(&uart->port.lock); - while ((UART_GET_IER(uart) & ERBFI) && (UART_GET_LSR(uart) & DR)) + while (UART_GET_LSR(uart) & DR) bfin_serial_rx_chars(uart); spin_unlock(&uart->port.lock); @@ -347,7 +349,7 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) struct bfin_serial_port *uart = dev_id; spin_lock(&uart->port.lock); - if ((UART_GET_IER(uart) & ETBEI) && (UART_GET_LSR(uart) & THRE)) + if (UART_GET_LSR(uart) & THRE) bfin_serial_tx_chars(uart); spin_unlock(&uart->port.lock); @@ -428,6 +430,8 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) int i, flg, status; status = UART_GET_LSR(uart); + UART_CLEAR_LSR(uart); + uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);; if (status & BI) { diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h index 15dbc21eed8b..233c585efc1e 100644 --- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v) @@ -58,6 +57,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -76,6 +76,23 @@ struct bfin_serial_port { #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index 7871d4313f49..b619065ceeb0 100644 --- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -46,6 +45,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -64,6 +64,23 @@ struct bfin_serial_port { #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h index 86e45c379838..f18c517cc935 100644 --- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -58,6 +57,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -76,6 +76,23 @@ struct bfin_serial_port { #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index 3770aa38ee9f..8733d47747e5 100644 --- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h @@ -32,6 +32,7 @@ #define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) #define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v) #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) +#define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index 7871d4313f49..b619065ceeb0 100644 --- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -46,6 +45,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -64,6 +64,23 @@ struct bfin_serial_port { #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; From 8851c71eb97610f0f63121d62345c969f71201a2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 24 Dec 2007 19:48:04 +0800 Subject: [PATCH 028/880] [Blackfin] serial driver: rework break flood anomaly handling to be more robust/realistic about what we can actually work around Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 66 +++++++++++++++---- .../asm-blackfin/mach-bf533/bfin_serial_5xx.h | 3 + .../asm-blackfin/mach-bf561/bfin_serial_5xx.h | 3 + 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index af84984df775..50aa3b2a19b8 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -206,12 +206,20 @@ int kgdb_get_debug_char(void) } #endif +#if ANOMALY_05000230 && defined(CONFIG_SERIAL_BFIN_PIO) +# define UART_GET_ANOMALY_THRESHOLD(uart) ((uart)->anomaly_threshold) +# define UART_SET_ANOMALY_THRESHOLD(uart, v) ((uart)->anomaly_threshold = (v)) +#else +# define UART_GET_ANOMALY_THRESHOLD(uart) 0 +# define UART_SET_ANOMALY_THRESHOLD(uart, v) +#endif + #ifdef CONFIG_SERIAL_BFIN_PIO static void bfin_serial_rx_chars(struct bfin_serial_port *uart) { struct tty_struct *tty = uart->port.info->tty; unsigned int status, ch, flg; - static int in_break = 0; + static struct timeval anomaly_start = { .tv_sec = 0 }; #ifdef CONFIG_KGDB_UART struct pt_regs *regs = get_irq_regs(); #endif @@ -244,28 +252,56 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) #endif if (ANOMALY_05000230) { - /* The BF533 family of processors have a nice misbehavior where - * they continuously generate characters for a "single" break. + /* The BF533 (and BF561) family of processors have a nice anomaly + * where they continuously generate characters for a "single" break. * We have to basically ignore this flood until the "next" valid - * character comes across. All other Blackfin families operate - * properly though. + * character comes across. Due to the nature of the flood, it is + * not possible to reliably catch bytes that are sent too quickly + * after this break. So application code talking to the Blackfin + * which sends a break signal must allow at least 1.5 character + * times after the end of the break for things to stabilize. This + * timeout was picked as it must absolutely be larger than 1 + * character time +/- some percent. So 1.5 sounds good. All other + * Blackfin families operate properly. Woo. * Note: While Anomaly 05000230 does not directly address this, * the changes that went in for it also fixed this issue. + * That anomaly was fixed in 0.5+ silicon. I like bunnies. */ - if (in_break) { - if (ch != 0) { - in_break = 0; - ch = UART_GET_CHAR(uart); - if (bfin_revid() < 5) - return; - } else - return; + if (anomaly_start.tv_sec) { + struct timeval curr; + suseconds_t usecs; + + if ((~ch & (~ch + 1)) & 0xff) + goto known_good_char; + + do_gettimeofday(&curr); + if (curr.tv_sec - anomaly_start.tv_sec > 1) + goto known_good_char; + + usecs = 0; + if (curr.tv_sec != anomaly_start.tv_sec) + usecs += USEC_PER_SEC; + usecs += curr.tv_usec - anomaly_start.tv_usec; + + if (usecs > UART_GET_ANOMALY_THRESHOLD(uart)) + goto known_good_char; + + if (ch) + anomaly_start.tv_sec = 0; + else + anomaly_start = curr; + + return; + + known_good_char: + anomaly_start.tv_sec = 0; } } if (status & BI) { if (ANOMALY_05000230) - in_break = 1; + if (bfin_revid() < 5) + do_gettimeofday(&anomaly_start); uart->port.icount.brk++; if (uart_handle_break(&uart->port)) goto ignore_char; @@ -778,6 +814,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, quot = uart_get_divisor(port, baud); spin_lock_irqsave(&uart->port.lock, flags); + UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); + do { lsr = UART_GET_LSR(uart); } while (!(lsr & TEMT)); diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index b619065ceeb0..a1b4f4eebd06 100644 --- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -57,6 +57,9 @@ struct bfin_serial_port { struct work_struct tx_dma_workqueue; #else struct work_struct cts_workqueue; +# if ANOMALY_05000230 + unsigned int anomaly_threshold; +# endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS int cts_pin; diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index b619065ceeb0..a1b4f4eebd06 100644 --- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -57,6 +57,9 @@ struct bfin_serial_port { struct work_struct tx_dma_workqueue; #else struct work_struct cts_workqueue; +# if ANOMALY_05000230 + unsigned int anomaly_threshold; +# endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS int cts_pin; From 1ba7a3ee310138015e744444043ce3e947429fce Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 11 Jan 2008 15:56:26 +0800 Subject: [PATCH 029/880] [Blackfin] serial driver: use simpler comment headers and strip out information that is maintained in the scm's log Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 50aa3b2a19b8..a07df539e525 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -1,30 +1,11 @@ /* - * File: drivers/serial/bfin_5xx.c - * Based on: Based on drivers/serial/sa1100.c - * Author: Aubrey Li + * Blackfin On-Chip Serial Driver * - * Created: - * Description: Driver for blackfin 5xx serial ports + * Copyright 2006-2007 Analog Devices Inc. * - * Modified: - * Copyright 2006 Analog Devices Inc. + * Enter bugs at http://blackfin.uclinux.org/ * - * 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 + * Licensed under the GPL-2 or later. */ #if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) From 095455682e29dbbc9f93ad83db459df524524992 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Sat, 2 Feb 2008 15:58:30 +0800 Subject: [PATCH 030/880] [Blackfin] serial driver: ADSP-BF52x arch/mach support Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- drivers/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b82595cf13e8..202fb5c99b83 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -686,7 +686,7 @@ config UART0_RTS_PIN config SERIAL_BFIN_UART1 bool "Enable UART1" - depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x) + depends on SERIAL_BFIN && (!BF531 && !BF532 && !BF533 && !BF561) help Enable UART1 From 4cb4f22b19237e63c460c53fbd1c417cdaf63014 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 2 Feb 2008 14:29:25 +0800 Subject: [PATCH 031/880] [Blackfin] serial driver: Fix bug Poll RTS/CTS status in DMA mode as well https://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3858 Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 16 +++++----------- .../asm-blackfin/mach-bf527/bfin_serial_5xx.h | 3 +-- .../asm-blackfin/mach-bf533/bfin_serial_5xx.h | 2 +- .../asm-blackfin/mach-bf537/bfin_serial_5xx.h | 3 +-- .../asm-blackfin/mach-bf548/bfin_serial_5xx.h | 3 +-- .../asm-blackfin/mach-bf561/bfin_serial_5xx.h | 2 +- 6 files changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index a07df539e525..af866ab3f5a1 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -53,7 +53,6 @@ #ifdef CONFIG_SERIAL_BFIN_DMA static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); #else -static void bfin_serial_do_work(struct work_struct *work); static void bfin_serial_tx_chars(struct bfin_serial_port *uart); #endif @@ -372,8 +371,9 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) return IRQ_HANDLED; } +#endif - +#ifdef CONFIG_SERIAL_BFIN_CTSRTS static void bfin_serial_do_work(struct work_struct *work) { struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue); @@ -607,22 +607,17 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) { #ifdef CONFIG_SERIAL_BFIN_CTSRTS unsigned int status; -# ifdef CONFIG_SERIAL_BFIN_DMA struct uart_info *info = uart->port.info; struct tty_struct *tty = info->tty; status = bfin_serial_get_mctrl(&uart->port); + uart_handle_cts_change(&uart->port, status & TIOCM_CTS); if (!(status & TIOCM_CTS)) { tty->hw_stopped = 1; + schedule_work(&uart->cts_workqueue); } else { tty->hw_stopped = 0; } -# else - status = bfin_serial_get_mctrl(&uart->port); - uart_handle_cts_change(&uart->port, status & TIOCM_CTS); - if (!(status & TIOCM_CTS)) - schedule_work(&uart->cts_workqueue); -# endif #endif } @@ -939,10 +934,9 @@ static void __init bfin_serial_init_ports(void) bfin_serial_ports[i].rx_dma_channel = bfin_serial_resource[i].uart_rx_dma_channel; init_timer(&(bfin_serial_ports[i].rx_dma_timer)); -#else - INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); bfin_serial_ports[i].cts_pin = bfin_serial_resource[i].uart_cts_pin; bfin_serial_ports[i].rts_pin = diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h index 233c585efc1e..c0694ecd2ecd 100644 --- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h @@ -67,10 +67,9 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index a1b4f4eebd06..b6f513bee56e 100644 --- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -56,12 +56,12 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else - struct work_struct cts_workqueue; # if ANOMALY_05000230 unsigned int anomaly_threshold; # endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h index f18c517cc935..8fc672d31057 100644 --- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h @@ -67,10 +67,9 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index 8733d47747e5..c459c4846469 100644 --- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h @@ -69,10 +69,9 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index a1b4f4eebd06..b6f513bee56e 100644 --- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -56,12 +56,12 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else - struct work_struct cts_workqueue; # if ANOMALY_05000230 unsigned int anomaly_threshold; # endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif From db288381e26e592b11572ce8199bedeadf0c0830 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sat, 2 Feb 2008 17:05:02 +0800 Subject: [PATCH 032/880] [Blackfin] serial driver: Add flow control support to bf54x Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/Kconfig | 4 ++-- drivers/serial/bfin_5xx.c | 12 ++++++++++++ include/asm-blackfin/mach-bf548/bfin_serial_5xx.h | 3 +++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 202fb5c99b83..cf627cd1b4c8 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -699,14 +699,14 @@ config BFIN_UART1_CTSRTS config UART1_CTS_PIN int "UART1 CTS pin" - depends on BFIN_UART1_CTSRTS && (BF53x || BF561) + depends on BFIN_UART1_CTSRTS && !BF54x default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. config UART1_RTS_PIN int "UART1 RTS pin" - depends on BFIN_UART1_CTSRTS && (BF53x || BF561) + depends on BFIN_UART1_CTSRTS && !BF54x default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index af866ab3f5a1..69ac7007682e 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -579,7 +579,11 @@ static unsigned int bfin_serial_get_mctrl(struct uart_port *port) if (uart->cts_pin < 0) return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +# ifdef BF54x + if (UART_GET_MSR(uart) & CTS) +# else if (gpio_get_value(uart->cts_pin)) +# endif return TIOCM_DSR | TIOCM_CAR; else #endif @@ -594,9 +598,17 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) return; if (mctrl & TIOCM_RTS) +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) & ~MRTS); +# else gpio_set_value(uart->rts_pin, 0); +# endif else +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) | MRTS); +# else gpio_set_value(uart->rts_pin, 1); +# endif #endif } diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index c459c4846469..7e6339f62a50 100644 --- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h @@ -24,6 +24,8 @@ #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) #define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) +#define UART_GET_MSR(uart) bfin_read16(((uart)->port.membase + OFFSET_MSR)) +#define UART_GET_MCR(uart) bfin_read16(((uart)->port.membase + OFFSET_MCR)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) #define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) @@ -34,6 +36,7 @@ #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) #define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) +#define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v) #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS From a235ef2c632a096cdb2b02379c89b49e97faaaa4 Mon Sep 17 00:00:00 2001 From: Alex Bounine Date: Mon, 11 Feb 2008 14:33:40 -0500 Subject: [PATCH 033/880] Tsi108_eth: add missing linking to driver data Bug fix for tsi108_eth network driver. This patch adds missing linking to driver data. Signed-off-by: Alexandre Bounine Signed-off-by: Jeff Garzik --- drivers/net/tsi108_eth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 35d15e850075..6f222d7e9126 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -1629,6 +1629,7 @@ tsi108_init_one(struct platform_device *pdev) goto register_fail; } + platform_set_drvdata(pdev, dev); printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n", dev->name, print_mac(mac, dev->dev_addr)); #ifdef DEBUG From 6a87155a39f538f9d13cebf2c9b7c19bd41d7da9 Mon Sep 17 00:00:00 2001 From: Alex Bounine Date: Mon, 11 Feb 2008 14:35:26 -0500 Subject: [PATCH 034/880] Tsi108_eth: fix detection of 1000Mb mode Bug fix for tsi108_eth network driver. This patch fixes a problem with detection of 1000Mb speed. Signed-off-by: Alexandre Bounine Signed-off-by: Jeff Garzik --- drivers/net/tsi108_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 6f222d7e9126..2e87876d6626 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -1287,6 +1287,7 @@ static void tsi108_init_phy(struct net_device *dev) spin_lock_irqsave(&phy_lock, flags); } + data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if); printk(KERN_DEBUG "PHY_STAT reg contains %08x\n", phyval); data->phy_ok = 1; data->init_media = 1; @@ -1584,7 +1585,6 @@ tsi108_init_one(struct platform_device *pdev) data->mii_if.phy_id = einfo->phy; data->mii_if.phy_id_mask = 0x1f; data->mii_if.reg_num_mask = 0x1f; - data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if); data->phy = einfo->phy; data->phy_type = einfo->phy_type; From 85bbe2158340dafb060fc7fe55a8208fe08cae26 Mon Sep 17 00:00:00 2001 From: Alex Bounine Date: Mon, 11 Feb 2008 14:35:49 -0500 Subject: [PATCH 035/880] Tsi108_eth: remove not needed code Code clean-up for tsi108_eth network driver. This patch removes not needed dummy read and the corresponding comment. The PHY logic requires two reads from the status register to get current link status. This is done correctly inside mii_check_media(). Signed-off-by: Alexandre Bounine Signed-off-by: Jeff Garzik --- drivers/net/tsi108_eth.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 2e87876d6626..5a730ba8b1a2 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -297,18 +297,11 @@ static void tsi108_check_phy(struct net_device *dev) u32 speed; unsigned long flags; - /* Do a dummy read, as for some reason the first read - * after a link becomes up returns link down, even if - * it's been a while since the link came up. - */ - spin_lock_irqsave(&phy_lock, flags); if (!data->phy_ok) goto out; - tsi108_read_mii(data, MII_BMSR); - duplex = mii_check_media(&data->mii_if, netif_msg_link(data), data->init_media); data->init_media = 0; From b1aefe58c21de4265223b563ae923b50f4c4be08 Mon Sep 17 00:00:00 2001 From: Alex Bounine Date: Mon, 11 Feb 2008 14:36:12 -0500 Subject: [PATCH 036/880] Tsi108_eth: fix link recovery after disconnect Bug fix for tsi108_eth network driver. This patch fixes a problem with link recovery after connection was lost. Signed-off-by: Alexandre Bounine Signed-off-by: Jeff Garzik --- drivers/net/tsi108_eth.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 5a730ba8b1a2..bc3848962bb1 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -338,22 +338,21 @@ static void tsi108_check_phy(struct net_device *dev) TSI_WRITE(TSI108_MAC_CFG2, mac_cfg2_reg); TSI_WRITE(TSI108_EC_PORTCTRL, portctrl_reg); + } - if (data->link_up == 0) { - /* The manual says it can take 3-4 usecs for the speed change - * to take effect. - */ - udelay(5); + if (data->link_up == 0) { + /* The manual says it can take 3-4 usecs for the speed change + * to take effect. + */ + udelay(5); - spin_lock(&data->txlock); - if (is_valid_ether_addr(dev->dev_addr) && data->txfree) - netif_wake_queue(dev); + spin_lock(&data->txlock); + if (is_valid_ether_addr(dev->dev_addr) && data->txfree) + netif_wake_queue(dev); - data->link_up = 1; - spin_unlock(&data->txlock); - } + data->link_up = 1; + spin_unlock(&data->txlock); } - } else { if (data->link_up == 1) { netif_stop_queue(dev); @@ -1267,12 +1266,11 @@ static void tsi108_init_phy(struct net_device *dev) * PHY_STAT register before the link up status bit is set. */ - data->link_up = 1; + data->link_up = 0; while (!((phyval = tsi108_read_mii(data, MII_BMSR)) & BMSR_LSTATUS)) { if (i++ > (MII_READ_DELAY / 10)) { - data->link_up = 0; break; } spin_unlock_irqrestore(&phy_lock, flags); From 9dde447a09ec8fc0ba8375a16fe6bed2470f0d14 Mon Sep 17 00:00:00 2001 From: Alex Bounine Date: Mon, 11 Feb 2008 14:36:37 -0500 Subject: [PATCH 037/880] Tsi108_eth: Add ethtool support Add ethtool support to tsi108_eth network driver. Signed-off-by: Alexandre Bounine Signed-off-by: Jeff Garzik --- drivers/net/tsi108_eth.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index bc3848962bb1..6f33f84d37b0 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1519,12 +1520,46 @@ static void tsi108_init_mac(struct net_device *dev) TSI_WRITE(TSI108_EC_INTMASK, ~0); } +static int tsi108_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tsi108_prv_data *data = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(&data->txlock, flags); + rc = mii_ethtool_gset(&data->mii_if, cmd); + spin_unlock_irqrestore(&data->txlock, flags); + + return rc; +} + +static int tsi108_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct tsi108_prv_data *data = netdev_priv(dev); + unsigned long flags; + int rc; + + spin_lock_irqsave(&data->txlock, flags); + rc = mii_ethtool_sset(&data->mii_if, cmd); + spin_unlock_irqrestore(&data->txlock, flags); + + return rc; +} + static int tsi108_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct tsi108_prv_data *data = netdev_priv(dev); + if (!netif_running(dev)) + return -EINVAL; return generic_mii_ioctl(&data->mii_if, if_mii(rq), cmd, NULL); } +static const struct ethtool_ops tsi108_ethtool_ops = { + .get_link = ethtool_op_get_link, + .get_settings = tsi108_get_settings, + .set_settings = tsi108_set_settings, +}; + static int tsi108_init_one(struct platform_device *pdev) { @@ -1589,6 +1624,7 @@ tsi108_init_one(struct platform_device *pdev) dev->get_stats = tsi108_get_stats; netif_napi_add(dev, &data->napi, tsi108_poll, 64); dev->do_ioctl = tsi108_do_ioctl; + dev->ethtool_ops = &tsi108_ethtool_ops; /* Apparently, the Linux networking code won't use scatter-gather * if the hardware doesn't do checksums. However, it's faster From 030ed68bf063e99cea6371d1fb771a870cab1c1d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 11 Feb 2008 09:25:40 -0800 Subject: [PATCH 038/880] replace code with FIELD_SIZEOF Signed-off-by: Julia Lawall Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 2 +- drivers/net/igb/igb_ethtool.c | 2 +- drivers/net/ixgb/ixgb_ethtool.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index d876787ce336..85e66f4c7886 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -50,7 +50,7 @@ struct e1000_stats { int stat_offset; }; -#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ +#define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \ offsetof(struct e1000_adapter, m) static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_packets", E1000_STAT(stats.gprc) }, diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index f69721e4eaa1..0447f9bcd27a 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -43,7 +43,7 @@ struct igb_stats { int stat_offset; }; -#define IGB_STAT(m) sizeof(((struct igb_adapter *)0)->m), \ +#define IGB_STAT(m) FIELD_SIZEOF(struct igb_adapter, m), \ offsetof(struct igb_adapter, m) static const struct igb_stats igb_gstrings_stats[] = { { "rx_packets", IGB_STAT(stats.gprc) }, diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index a267dd862520..53a9fd086f96 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -49,7 +49,7 @@ struct ixgb_stats { int stat_offset; }; -#define IXGB_STAT(m) sizeof(((struct ixgb_adapter *)0)->m), \ +#define IXGB_STAT(m) FIELD_SIZEOF(struct ixgb_adapter, m), \ offsetof(struct ixgb_adapter, m) static struct ixgb_stats ixgb_gstrings_stats[] = { {"rx_packets", IXGB_STAT(net_stats.rx_packets)}, From 14782ca8262818921a460c80a761a93740b838a2 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 11 Feb 2008 09:25:46 -0800 Subject: [PATCH 039/880] e1000: warn if this driver is used for e1000e devices We're already starting to see reports from users still using e1000 where they should be using e1000e now that this is actually possible. Just to prevent some of this thrash, add a big warning on load on these devices that people should switch to e1000e. Signed-off-by: Auke Kok Acked-by: Jesse Brandeburg Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index d4ee8ec34b56..0991648c53dc 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1195,6 +1195,14 @@ e1000_probe(struct pci_dev *pdev, printk("%s\n", print_mac(mac, netdev->dev_addr)); + if (adapter->hw.bus_type == e1000_bus_type_pci_express) { + DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no " + "longer be supported by this driver in the future.\n", + pdev->vendor, pdev->device); + DPRINTK(PROBE, WARNING, "please use the \"e1000e\" " + "driver instead.\n"); + } + /* reset the hardware with the new settings */ e1000_reset(adapter); From 23b66e2bc2bcebacab7292d7731b7372065b3f98 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 11 Feb 2008 09:25:51 -0800 Subject: [PATCH 040/880] e1000e: Fix logic reversal keeping link active A logic mishap caused the adapter to keep link while we can disable it due to WoL not being active, and vice versa. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index f58f017ee47a..b9b0d321e70b 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2008,7 +2008,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter) u16 mii_reg; /* WoL is enabled */ - if (!adapter->wol) + if (adapter->wol) return; /* non-copper PHY? */ From 0c254d863338ceff630814bf17cf8e4b61cb8aa3 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 11 Feb 2008 09:25:56 -0800 Subject: [PATCH 041/880] ixgbe: warn when device is in a x4 or lower width slot It's easy to oversee this issue when working with this card as evrything will work OK but performance is severely limited (something like 1.5gbit on a x1 link) if the pci-express slot does not offer more bandwidth. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index ead49e54f31b..576fb51eb748 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2778,6 +2778,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, hw->mac.type, hw->phy.type, (part_num >> 8), (part_num & 0xff)); + if (link_width <= IXGBE_PCI_LINK_WIDTH_4) { + dev_warn(&pdev->dev, "PCI-Express bandwidth available for " + "this card is not sufficient for optimal " + "performance.\n"); + dev_warn(&pdev->dev, "For optimal performance a x8 " + "PCI-Express slot is required.\n"); + } + /* reset the hardware with the new settings */ ixgbe_start_hw(hw); From 4bebfaa56b72c94fe4997240ee73ad1c1fcf96c9 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 11 Feb 2008 09:26:01 -0800 Subject: [PATCH 042/880] ixgbe: Disallow device reset during ethtool test Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 576fb51eb748..a4aeaec1b298 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1942,6 +1942,10 @@ static int ixgbe_open(struct net_device *netdev) int err; u32 num_rx_queues = adapter->num_rx_queues; + /* disallow open during test */ + if (test_bit(__IXGBE_TESTING, &adapter->state)) + return -EBUSY; + try_intr_reinit: /* allocate transmit descriptors */ err = ixgbe_setup_all_tx_resources(adapter); From 4a75834644ae32ded9bed14db39834d6d3bc4793 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 11 Feb 2008 09:26:06 -0800 Subject: [PATCH 043/880] ixgbe: remove accidentally added #ifdef Let's not add these #ifdef NETIF_F_TSO's back. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_main.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a4aeaec1b298..540b647eb825 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -220,7 +220,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, tx_ring->stats.bytes += tx_buffer_info->length; if (cleaned) { struct sk_buff *skb = tx_buffer_info->skb; -#ifdef NETIF_F_TSO unsigned int segs, bytecount; segs = skb_shinfo(skb)->gso_segs ?: 1; /* multiply data chunks by size of headers */ @@ -228,10 +227,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, skb->len; total_tx_packets += segs; total_tx_bytes += bytecount; -#else - total_tx_packets++; - total_tx_bytes += skb->len; -#endif } ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); From 631a9dca60ddd7d84a08171a14828e9cfb667d48 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 12 Feb 2008 18:23:31 -0800 Subject: [PATCH 044/880] [SPARC]: video/cg14.c and video/sbuslib.c build fixes Apparently these drivers now need uaccess.h Signed-off-by: Robert Reif Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/video/cg14.c | 1 + drivers/video/sbuslib.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 41f6dbf61be7..fdc9f43ec30a 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c index 963a454b7074..4deaac05b938 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/sbuslib.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include From b3dd5b82560eef53a537e409f50261d0b33c75ce Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 12 Feb 2008 22:08:55 -0800 Subject: [PATCH 045/880] [SPARC]: Use shorter form of "get_zeroed_page". Signed-off-by: Robert P. J. Day Signed-off-by: David S. Miller --- arch/sparc/mm/sun4c.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index c0442e8c4b15..2375fe9dc312 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1941,9 +1941,7 @@ static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long add if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL) return pte; - pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); - if (pte) - memset(pte, 0, PAGE_SIZE); + pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); return pte; } From b83ebf566b64d3702c6b50dbee2052623cd55ce5 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 12 Feb 2008 22:09:29 -0800 Subject: [PATCH 046/880] [SPARC64]: Use shorter "get_zeroed_page" call. Signed-off-by: Robert P. J. Day Signed-off-by: David S. Miller --- arch/sparc64/kernel/iommu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c index d3276ebcfb47..0e347ff812a3 100644 --- a/arch/sparc64/kernel/iommu.c +++ b/arch/sparc64/kernel/iommu.c @@ -200,12 +200,11 @@ int iommu_table_init(struct iommu *iommu, int tsbsize, /* Allocate and initialize the dummy page which we * set inactive IO PTEs to point to. */ - iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); + iommu->dummy_page = get_zeroed_page(GFP_KERNEL); if (!iommu->dummy_page) { printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n"); goto out_free_map; } - memset((void *)iommu->dummy_page, 0, PAGE_SIZE); iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page); /* Now allocate and setup the IOMMU page table itself. */ From 0f78e7542e94e8f64ed393289d7bfac032634620 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 13 Feb 2008 01:00:26 -0800 Subject: [PATCH 047/880] [SPARC64]: Remove DEBUG_BOOTMEM. We'll replace it in the future with better logging facilities that can be enabled at run time. Signed-off-by: David S. Miller --- arch/sparc64/Kconfig.debug | 4 ---- arch/sparc64/defconfig | 1 - arch/sparc64/mm/init.c | 43 +------------------------------------- 3 files changed, 1 insertion(+), 47 deletions(-) diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug index a5faa3683bd6..6a4d28a4076d 100644 --- a/arch/sparc64/Kconfig.debug +++ b/arch/sparc64/Kconfig.debug @@ -23,10 +23,6 @@ config STACK_DEBUG depends on DEBUG_KERNEL bool "Stack Overflow Detection Support" -config DEBUG_BOOTMEM - depends on DEBUG_KERNEL - bool "Debug BOOTMEM initialization" - config DEBUG_PAGEALLOC bool "Debug page memory allocations" depends on DEBUG_KERNEL && !HIBERNATION diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 833d74b2b192..50dc09055783 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1396,7 +1396,6 @@ CONFIG_FORCED_INLINING=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_DCFLUSH is not set # CONFIG_STACK_DEBUG is not set -# CONFIG_DEBUG_BOOTMEM is not set # CONFIG_DEBUG_PAGEALLOC is not set # diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index e726c45645ff..035c73243adc 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -739,11 +739,6 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn, avoid_end = PAGE_ALIGN(initrd_end); #endif -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("choose_bootmap_pfn: kern[%lx:%lx] avoid[%lx:%lx]\n", - kern_base, PAGE_ALIGN(kern_base + kern_size), - avoid_start, avoid_end); -#endif for (i = 0; i < pavail_ents; i++) { unsigned long start, end; @@ -777,10 +772,6 @@ static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn, } /* OK, it doesn't overlap anything, use it. */ -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("choose_bootmap_pfn: Using %lx [%lx]\n", - start >> PAGE_SHIFT, start); -#endif return start >> PAGE_SHIFT; } } @@ -920,10 +911,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, unsigned long bootmap_pfn, bytes_avail, size; int i; -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("bootmem_init: Scan pavail, "); -#endif - bytes_avail = 0UL; for (i = 0; i < pavail_ents; i++) { end_of_phys_memory = pavail[i].phys_addr + @@ -970,33 +957,20 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, bootmap_pfn = choose_bootmap_pfn(min_low_pfn, end_pfn); -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("init_bootmem(min[%lx], bootmap[%lx], max[%lx])\n", - min_low_pfn, bootmap_pfn, max_low_pfn); -#endif bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, min_low_pfn, end_pfn); /* Now register the available physical memory with the * allocator. */ - for (i = 0; i < pavail_ents; i++) { -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("free_bootmem(pavail:%d): base[%lx] size[%lx]\n", - i, pavail[i].phys_addr, pavail[i].reg_size); -#endif + for (i = 0; i < pavail_ents; i++) free_bootmem(pavail[i].phys_addr, pavail[i].reg_size); - } #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) { size = initrd_end - initrd_start; /* Reserve the initrd image area. */ -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("reserve_bootmem(initrd): base[%llx] size[%lx]\n", - initrd_start, initrd_end); -#endif reserve_bootmem(initrd_start, size, BOOTMEM_DEFAULT); initrd_start += PAGE_OFFSET; @@ -1004,9 +978,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, } #endif /* Reserve the kernel text/data/bss. */ -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size); -#endif reserve_bootmem(kern_base, kern_size, BOOTMEM_DEFAULT); *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT; @@ -1020,10 +991,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, * in free_all_bootmem. */ size = bootmap_size; -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n", - (bootmap_pfn << PAGE_SHIFT), size); -#endif reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size, BOOTMEM_DEFAULT); for (i = 0; i < pavail_ents; i++) { @@ -1031,10 +998,6 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, start_pfn = pavail[i].phys_addr >> PAGE_SHIFT; end_pfn = (start_pfn + (pavail[i].reg_size >> PAGE_SHIFT)); -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("memory_present(0, %lx, %lx)\n", - start_pfn, end_pfn); -#endif memory_present(0, start_pfn, end_pfn); } @@ -1549,10 +1512,6 @@ void __init mem_init(void) high_memory = __va(last_valid_pfn << PAGE_SHIFT); -#ifdef CONFIG_DEBUG_BOOTMEM - prom_printf("mem_init: Calling free_all_bootmem().\n"); -#endif - /* We subtract one to account for the mem_map_zero page * allocated below. */ From e48a411fa097c386c6081f4ed5a952aa3e21ca2b Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 11 Feb 2008 16:55:19 +0100 Subject: [PATCH 048/880] AVR32: Define PAGE_SHARED The virtual framebuffer driver needs PAGE_SHARED, which is not defined on avr32. Define it. Reported-by: Oliver Zander Signed-off-by: Haavard Skinnemoen --- include/asm-avr32/pgtable.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h index 018f6e2a0242..3ae7b548fce7 100644 --- a/include/asm-avr32/pgtable.h +++ b/include/asm-avr32/pgtable.h @@ -157,6 +157,7 @@ extern struct page *empty_zero_page; #define _PAGE_S(x) _PAGE_NORMAL(x) #define PAGE_COPY _PAGE_P(PAGE_WRITE | PAGE_READ) +#define PAGE_SHARED _PAGE_S(PAGE_WRITE | PAGE_READ) #ifndef __ASSEMBLY__ /* From 32019828d9012e584017a824f84798248c0060dd Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 13 Feb 2008 12:32:34 +0100 Subject: [PATCH 049/880] avr32: Fix broken pte dump code in do_page_fault() The per-task page tables only cover the first 2GiB of the address space. For kernel addresses, we need to do the lookup in init's page tables. This is a temporary workaround until we modify the per-task page tables to cover the whole 4GiB address space. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mm/fault.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index 6560cb18b4e3..ce4e4296b954 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -189,6 +189,8 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) page = sysreg_read(PTBR); printk(KERN_ALERT "ptbr = %08lx", page); + if (address >= TASK_SIZE) + page = (unsigned long)swapper_pg_dir; if (page) { page = ((unsigned long *)page)[address >> 22]; printk(" pgd = %08lx", page); From f059267e7fa9e3efa1498eb963ba18ec25665c42 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 13 Feb 2008 14:29:30 +0100 Subject: [PATCH 050/880] avr32: Use correct config symbol in atstk1004 board code CONFIG_BOARD_ATSTK1002_SW2_CUSTOM should be CONFIG_BOARD_ATSTK100X_SW2_CUSTOM. Spotted by Robert P. J. Day. Signed-off-by: Haavard Skinnemoen --- arch/avr32/boards/atstk1000/atstk1004.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c index 5a77030e07a0..e765a8652b3e 100644 --- a/arch/avr32/boards/atstk1000/atstk1004.c +++ b/arch/avr32/boards/atstk1000/atstk1004.c @@ -129,7 +129,7 @@ static int __init atstk1004_init(void) #ifdef CONFIG_BOARD_ATSTK100X_SPI1 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif -#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM +#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM at32_add_device_mci(0); #endif at32_add_device_lcdc(0, &atstk1000_lcdc_data, From 587c90616a5b44e6ccfac38e64d4fecee51d588c Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Mon, 11 Feb 2008 21:13:47 +0100 Subject: [PATCH 051/880] kconfig: fix select in combination with default > The attached .config (with current -git) results in a compile > error since it contains: > > CONFIG_X86=y > # CONFIG_EMBEDDED is not set > CONFIG_SERIO=m > CONFIG_SERIO_I8042=y > > Looking at drivers/input/serio/Kconfig I simply don't get how this > can happen. You've hit the rather subtle rules of select vs default. What happened is that SERIO is selected to m, but SERIO_I8042 isn't selected so the default of y is used instead. We already had the problem in the past that select and default don't work well together, so this patch cleans this up and makes the rule hopefully more straightforward. Basically now the value is calculated like this: (value && dependency) || select where the value is the user choice (if available and the symbol is visible) or default. In this case it means SERIO and SERIO_I8042 are both set to y due to their default and if SERIO didn't had the default, then the SERIO_I8042 value would be limited to m due to the dependency. I tested this patch with more 10000 random configs and above case is the only the difference that showed up, so I hope there is nothing that depended on the old more complex and subtle rules. Signed-off-by: Roman Zippel Tested-by: Adrian Bunk Signed-off-by: Sam Ravnborg --- scripts/kconfig/symbol.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 3929e5b35e79..4a03191ad176 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -298,22 +298,30 @@ void sym_calc_value(struct symbol *sym) if (sym_is_choice_value(sym) && sym->visible == yes) { prop = sym_get_choice_prop(sym); newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; - } else if (EXPR_OR(sym->visible, sym->rev_dep.tri) != no) { - sym->flags |= SYMBOL_WRITE; - if (sym_has_value(sym)) - newval.tri = sym->def[S_DEF_USER].tri; - else if (!sym_is_choice(sym)) { - prop = sym_get_default_prop(sym); - if (prop) - newval.tri = expr_calc_value(prop->expr); + } else { + if (sym->visible != no) { + /* if the symbol is visible use the user value + * if available, otherwise try the default value + */ + sym->flags |= SYMBOL_WRITE; + if (sym_has_value(sym)) { + newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, + sym->visible); + goto calc_newval; + } } - newval.tri = EXPR_OR(EXPR_AND(newval.tri, sym->visible), sym->rev_dep.tri); - } else if (!sym_is_choice(sym)) { - prop = sym_get_default_prop(sym); - if (prop) { + if (sym->rev_dep.tri != no) sym->flags |= SYMBOL_WRITE; - newval.tri = expr_calc_value(prop->expr); + if (!sym_is_choice(sym)) { + prop = sym_get_default_prop(sym); + if (prop) { + sym->flags |= SYMBOL_WRITE; + newval.tri = EXPR_AND(expr_calc_value(prop->expr), + prop->visible.tri); + } } + calc_newval: + newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) newval.tri = yes; From 1e12e3919ea83ce28f8c017b83f68739485fef81 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Fri, 18 Jan 2008 14:26:55 -0800 Subject: [PATCH 052/880] [XTENSA] Remove duplicate includes. Signed-off-by: Lucas Woods Signed-off-by: Andrew Morton Signed-off-by: Christian Zankel --- arch/xtensa/kernel/asm-offsets.c | 1 - arch/xtensa/mm/cache.c | 1 - arch/xtensa/platform-iss/network.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index d5ffe7b6443e..5d9ef515ca1e 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -21,7 +21,6 @@ #include #include -#include #include #define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val)) diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index 9a1fa9478ae7..42bfb695a170 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index f21b9b0899a8..d89fb18d7971 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include From 78c5bbc15bc467ec98cf4db55ae9c57522c1b77b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 7 Dec 2007 17:14:47 -0800 Subject: [PATCH 053/880] [XTENSA] Remove dead code reported by Robert P. J. Day. Signed-off-by: Adrian Bunk Signed-off-by: Christian Zankel Signed-off-by: Andrew Morton --- arch/xtensa/kernel/setup.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index b80f2cb1b4fb..5e6d75c9f92b 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -60,11 +60,6 @@ struct ide_ops *ide_ops; extern struct rtc_ops no_rtc_ops; struct rtc_ops *rtc_ops; -#ifdef CONFIG_PC_KEYB -extern struct kbd_ops no_kbd_ops; -struct kbd_ops *kbd_ops; -#endif - #ifdef CONFIG_BLK_DEV_INITRD extern void *initrd_start; extern void *initrd_end; From e584d85fb1cba2b08c266348b58eb4a881a88b40 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 13 Feb 2008 16:25:09 -0800 Subject: [PATCH 054/880] [XTENSA] Fix non-existent pte_token_t typedef to pgtable_t This bug was introduced in 2f569afd9ced9ebec9a6eb3dbf6f83429be0a7b4. (CONFIG_HIGHPTE vs. sub-page page tables) Signed-off-by: Chris Zankel --- include/asm-xtensa/pgalloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h index 8d1544eb461e..4f4a7987eded 100644 --- a/include/asm-xtensa/pgalloc.h +++ b/include/asm-xtensa/pgalloc.h @@ -47,7 +47,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); } -static inline pte_token_t pte_alloc_one(struct mm_struct *mm, +static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr) { struct page *page; From 4f8d98ff4825336b23372bb552852625fc90d3b1 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 13 Feb 2008 16:44:19 -0800 Subject: [PATCH 055/880] [XTENSA] Add .literal sections for various init sectiont to linker script Xtensa requires separate .literal section for each .text section. Adding addition init sections for cpuinit, meminit, and devinit, broke the Xtensa linker script, so, add these literal sections manually for now. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/vmlinux.lds.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 7d0f55a4982d..4b717bf48fb7 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -136,7 +136,9 @@ SECTIONS __init_begin = .; .init.text : { _sinittext = .; - *(.init.literal) INIT_TEXT + *(.init.literal) *(.cpuinit.literal) + *(.devinit.literal) *(.meminit.literal) + INIT_TEXT _einittext = .; } From b26d0ab0e6fa3a886d2799bf89eb05dd52f8b7c2 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 13 Sep 2007 13:44:07 -0700 Subject: [PATCH 056/880] [XTENSA] Concentrate platforms into one platforms directory. Create arch/xtensa/platforms/ directory to concentrate all platforms under that subdirectory and moves the ISS platform to that directory. Signed-off-by: Chris Zankel --- arch/xtensa/Makefile | 2 +- arch/xtensa/{platform-iss => platforms/iss}/Makefile | 0 arch/xtensa/{platform-iss => platforms/iss}/console.c | 0 arch/xtensa/{platform-iss => platforms/iss}/io.c | 0 arch/xtensa/{platform-iss => platforms/iss}/network.c | 0 arch/xtensa/{platform-iss => platforms/iss}/setup.c | 0 6 files changed, 1 insertion(+), 1 deletion(-) rename arch/xtensa/{platform-iss => platforms/iss}/Makefile (100%) rename arch/xtensa/{platform-iss => platforms/iss}/console.c (100%) rename arch/xtensa/{platform-iss => platforms/iss}/io.c (100%) rename arch/xtensa/{platform-iss => platforms/iss}/network.c (100%) rename arch/xtensa/{platform-iss => platforms/iss}/setup.c (100%) diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 56685a883347..4bd1e14c6b90 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -59,7 +59,7 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) head-y := arch/xtensa/kernel/head.o core-y += arch/xtensa/kernel/ arch/xtensa/mm/ ifneq ($(PLATFORM),) -core-y += arch/xtensa/platform-$(PLATFORM)/ +core-y += arch/xtensa/platforms/$(PLATFORM)/ endif libs-y += arch/xtensa/lib/ $(LIBGCC) diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platforms/iss/Makefile similarity index 100% rename from arch/xtensa/platform-iss/Makefile rename to arch/xtensa/platforms/iss/Makefile diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platforms/iss/console.c similarity index 100% rename from arch/xtensa/platform-iss/console.c rename to arch/xtensa/platforms/iss/console.c diff --git a/arch/xtensa/platform-iss/io.c b/arch/xtensa/platforms/iss/io.c similarity index 100% rename from arch/xtensa/platform-iss/io.c rename to arch/xtensa/platforms/iss/io.c diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platforms/iss/network.c similarity index 100% rename from arch/xtensa/platform-iss/network.c rename to arch/xtensa/platforms/iss/network.c diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platforms/iss/setup.c similarity index 100% rename from arch/xtensa/platform-iss/setup.c rename to arch/xtensa/platforms/iss/setup.c From 49883224f6665e2b056fc3e7325b3bba9d1ff2c4 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 14 Nov 2007 13:39:40 -0800 Subject: [PATCH 057/880] [XTENSA] Fix argument list for pgd_ctor constructor. The argument list for ctor function element in the kmem_cache structure has changed. Signed-off-by: Chris Zankel --- arch/xtensa/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index b3086f34a8e7..81d0560eaea2 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(void *addr, struct kmem_cache *cache, unsigned long flags) +static void pgd_ctor(struct kmem_cache *cache, void* addr) { pte_t* ptep = (pte_t*)addr; int i; From b67360db143448be1f6d68835c6d0cc43837667f Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 6 Sep 2007 01:38:18 -0700 Subject: [PATCH 058/880] [XTENSA] Flush the page-address in update-mmu instead of user-address The TLB entry for the user address doesn't exist at the time we want to flush the caches, so use the page address. Note that processor configurations with cache-aliasing issues are treated separately. Signed-off-by: Chris Zankel --- arch/xtensa/mm/cache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index 42bfb695a170..3ba990c67676 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c @@ -180,9 +180,9 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte) #else if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags) && (vma->vm_flags & VM_EXEC) != 0) { - unsigned long vaddr = addr & PAGE_MASK; - __flush_dcache_page(vaddr); - __invalidate_icache_page(vaddr); + unsigned long paddr = (unsigned long) page_address(page); + __flush_dcache_page(paddr); + __invalidate_icache_page(paddr); set_bit(PG_arch_1, &page->flags); } #endif From c865415838146d83c92e4c1ae69aff45ef9f35f8 Mon Sep 17 00:00:00 2001 From: Marc Gauthier Date: Fri, 21 Sep 2007 16:38:09 -0700 Subject: [PATCH 059/880] [XTENSA] Prevent inlining ISS platform asm constructs The simcall asm macro assumes Windowed ABI parameter passing in registers, and doesn't work if its containing function gets inlined. This fix prevents that from happening. Signed-off-by: Marc Gauthier --- arch/xtensa/platforms/iss/console.c | 1 + arch/xtensa/platforms/iss/network.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 854677d0c3f6..9141e3690731 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -43,6 +43,7 @@ static DEFINE_SPINLOCK(timer_lock); int errno; +static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__)); static int __simc (int a, int b, int c, int d, int e, int f) { int ret; diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index d89fb18d7971..a2e252217428 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -107,6 +107,7 @@ struct iss_net_private { static int errno; +static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__)); static int __simc (int a, int b, int c, int d, int e, int f) { int ret; From 70e137eb48f62e59dfa5e06d0d01f123e9464f9a Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 23 Oct 2007 10:58:53 -0700 Subject: [PATCH 060/880] [XTENSA] Fix clobbered register in asm macro We dangerously re-used an input operand to an asm macro without defining a constraint. By defining a separate output operand (instead of input/output operand), the compiler is more flexible during register allocation. Signed-off-by: Chris Zankel --- include/asm-xtensa/uaccess.h | 99 +++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h index d6352da05b10..b8528426ab1f 100644 --- a/include/asm-xtensa/uaccess.h +++ b/include/asm-xtensa/uaccess.h @@ -26,6 +26,7 @@ #include #include #include +#include /* * These assembly macros mirror the C macros that follow below. They @@ -118,7 +119,7 @@ * destroyed (actually, (TASK_SIZE + 1 - size)) */ .macro user_ok aa, as, at, error - movi \at, (TASK_SIZE+1) + movi \at, __XTENSA_UL_CONST(TASK_SIZE) bgeu \as, \at, \error sub \at, \at, \as bgeu \aa, \at, \error @@ -226,20 +227,21 @@ extern long __put_user_bad(void); __pu_err; \ }) -#define __put_user_size(x,ptr,size,retval) \ -do { \ - retval = 0; \ - switch (size) { \ - case 1: __put_user_asm(x,ptr,retval,1,"s8i"); break; \ - case 2: __put_user_asm(x,ptr,retval,2,"s16i"); break; \ - case 4: __put_user_asm(x,ptr,retval,4,"s32i"); break; \ - case 8: { \ - __typeof__(*ptr) __v64 = x; \ - retval = __copy_to_user(ptr,&__v64,8); \ - break; \ - } \ - default: __put_user_bad(); \ - } \ +#define __put_user_size(x,ptr,size,retval) \ +do { \ + int __cb; \ + retval = 0; \ + switch (size) { \ + case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ + case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ + case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ + case 8: { \ + __typeof__(*ptr) __v64 = x; \ + retval = __copy_to_user(ptr,&__v64,8); \ + break; \ + } \ + default: __put_user_bad(); \ + } \ } while (0) @@ -267,14 +269,14 @@ do { \ #define __check_align_1 "" #define __check_align_2 \ - " _bbci.l %2, 0, 1f \n" \ - " movi %0, %3 \n" \ + " _bbci.l %3, 0, 1f \n" \ + " movi %0, %4 \n" \ " _j 2f \n" #define __check_align_4 \ - " _bbsi.l %2, 0, 0f \n" \ - " _bbci.l %2, 1, 1f \n" \ - "0: movi %0, %3 \n" \ + " _bbsi.l %3, 0, 0f \n" \ + " _bbci.l %3, 1, 1f \n" \ + "0: movi %0, %4 \n" \ " _j 2f \n" @@ -286,24 +288,24 @@ do { \ * WARNING: If you modify this macro at all, verify that the * __check_align_* macros still work. */ -#define __put_user_asm(x, addr, err, align, insn) \ - __asm__ __volatile__( \ - __check_align_##align \ - "1: "insn" %1, %2, 0 \n" \ - "2: \n" \ - " .section .fixup,\"ax\" \n" \ - " .align 4 \n" \ - "4: \n" \ - " .long 2b \n" \ - "5: \n" \ - " l32r %2, 4b \n" \ - " movi %0, %3 \n" \ - " jx %2 \n" \ - " .previous \n" \ - " .section __ex_table,\"a\" \n" \ - " .long 1b, 5b \n" \ - " .previous" \ - :"=r" (err) \ +#define __put_user_asm(x, addr, err, align, insn, cb) \ + __asm__ __volatile__( \ + __check_align_##align \ + "1: "insn" %2, %3, 0 \n" \ + "2: \n" \ + " .section .fixup,\"ax\" \n" \ + " .align 4 \n" \ + "4: \n" \ + " .long 2b \n" \ + "5: \n" \ + " l32r %1, 4b \n" \ + " movi %0, %4 \n" \ + " jx %1 \n" \ + " .previous \n" \ + " .section __ex_table,\"a\" \n" \ + " .long 1b, 5b \n" \ + " .previous" \ + :"=r" (err), "=r" (cb) \ :"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err)) #define __get_user_nocheck(x,ptr,size) \ @@ -328,11 +330,12 @@ extern long __get_user_bad(void); #define __get_user_size(x,ptr,size,retval) \ do { \ + int __cb; \ retval = 0; \ switch (size) { \ - case 1: __get_user_asm(x,ptr,retval,1,"l8ui"); break; \ - case 2: __get_user_asm(x,ptr,retval,2,"l16ui"); break; \ - case 4: __get_user_asm(x,ptr,retval,4,"l32i"); break; \ + case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ + case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ + case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ case 8: retval = __copy_from_user(&x,ptr,8); break; \ default: (x) = __get_user_bad(); \ } \ @@ -343,25 +346,25 @@ do { \ * WARNING: If you modify this macro at all, verify that the * __check_align_* macros still work. */ -#define __get_user_asm(x, addr, err, align, insn) \ +#define __get_user_asm(x, addr, err, align, insn, cb) \ __asm__ __volatile__( \ __check_align_##align \ - "1: "insn" %1, %2, 0 \n" \ + "1: "insn" %2, %3, 0 \n" \ "2: \n" \ " .section .fixup,\"ax\" \n" \ " .align 4 \n" \ "4: \n" \ " .long 2b \n" \ "5: \n" \ - " l32r %2, 4b \n" \ - " movi %1, 0 \n" \ - " movi %0, %3 \n" \ - " jx %2 \n" \ + " l32r %1, 4b \n" \ + " movi %2, 0 \n" \ + " movi %0, %4 \n" \ + " jx %1 \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .long 1b, 5b \n" \ " .previous" \ - :"=r" (err), "=r" (x) \ + :"=r" (err), "=r" (cb), "=r" (x) \ :"r" (addr), "i" (-EFAULT), "0" (err)) From 0b2c3afdaaaa3e577300b2235df43eb8af00020b Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 12 Feb 2008 10:11:45 -0800 Subject: [PATCH 061/880] [XTENSA] Fix icache flush for cache aliasing Set the execution bit in the temporary TLB when we flush the instruction cache. Signed-off-by: Chris Zankel --- arch/xtensa/mm/misc.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index e1f880368e32..c885664211d1 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S @@ -295,7 +295,7 @@ ENTRY(__tlbtemp_mapping_itlb) ENTRY(__invalidate_icache_page_alias) entry sp, 16 - addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE) + addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE) mov a4, a2 witlb a6, a2 isync From 8d7e8240e66cecc84a375aceb26942d02b291198 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 12 Feb 2008 11:55:32 -0800 Subject: [PATCH 062/880] [XTENSA] Clean up elf-gregset. Remove additional registers from the ELF gregset structure that are only used by the kernel or are not required or invalid in user-space. The ar registers are always aligned to a windowbase value of 0, and the WB register is always assumed to be 0. Increase the size of the structure to 128 entries. This will provide enough space in future. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/process.c | 63 +++--------------------- arch/xtensa/kernel/traps.c | 4 +- include/asm-xtensa/elf.h | 92 ++---------------------------------- 3 files changed, 11 insertions(+), 148 deletions(-) diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index f53d7bd9dfb2..026138d641a4 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -194,51 +194,18 @@ unsigned long get_wchan(struct task_struct *p) void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, struct task_struct *tsk) { - int i, n, wb_offset; - - elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0; - elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1; - - __asm__ __volatile__ ("rsr %0, 176\n" : "=a" (i)); - elfregs->cpux = i; - __asm__ __volatile__ ("rsr %0, 208\n" : "=a" (i)); - elfregs->cpuy = i; - /* Note: PS.EXCM is not set while user task is running; its * being set in regs->ps is for exception handling convenience. */ elfregs->pc = regs->pc; elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT)); - elfregs->exccause = regs->exccause; - elfregs->excvaddr = regs->excvaddr; - elfregs->windowbase = regs->windowbase; - elfregs->windowstart = regs->windowstart; elfregs->lbeg = regs->lbeg; elfregs->lend = regs->lend; elfregs->lcount = regs->lcount; elfregs->sar = regs->sar; - elfregs->syscall = regs->syscall; - - /* Copy register file. - * The layout looks like this: - * - * | a0 ... a15 | Z ... Z | arX ... arY | - * current window unused saved frames - */ - - memset (elfregs->ar, 0, sizeof(elfregs->ar)); - - wb_offset = regs->windowbase * 4; - n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16; - - for (i = 0; i < n; i++) - elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i]; - n = (regs->wmask >> 4) * 4; - - for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--) - elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i]; + memcpy (elfregs->a, regs->areg, sizeof(elfregs->a)); } void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) @@ -252,40 +219,22 @@ void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, struct task_struct *tsk) { - int i, n, wb_offset; + const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; + unsigned long ps; /* Note: PS.EXCM is not set while user task is running; it * needs to be set in regs->ps is for exception handling convenience. */ + ps = (regs->ps & ~ps_mask) | (elfregs->ps & ps_mask) | (1<ps = ps; regs->pc = elfregs->pc; - regs->ps = (elfregs->ps | (1 << PS_EXCM_BIT)); - regs->exccause = elfregs->exccause; - regs->excvaddr = elfregs->excvaddr; - regs->windowbase = elfregs->windowbase; - regs->windowstart = elfregs->windowstart; regs->lbeg = elfregs->lbeg; regs->lend = elfregs->lend; regs->lcount = elfregs->lcount; regs->sar = elfregs->sar; - regs->syscall = elfregs->syscall; - - /* Clear everything. */ - - memset (regs->areg, 0, sizeof(regs->areg)); - - /* Copy regs from live window frame. */ - - wb_offset = regs->windowbase * 4; - n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16; - - for (i = 0; i < n; i++) - regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i]; - - n = (regs->wmask >> 4) * 4; - for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--) - regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i]; + memcpy (regs->areg, elfregs->a, sizeof(regs->areg)); } /* diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 397bcd6ad08d..6f722f91ba92 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -349,9 +349,7 @@ void show_regs(struct pt_regs * regs) wmask = regs->wmask & ~1; - for (i = 0; i < 32; i++) { - if (wmask & (1 << (i / 4))) - break; + for (i = 0; i < 16; i++) { if ((i % 8) == 0) printk ("\n" KERN_INFO "a%02d: ", i); printk("%08lx ", regs->areg[i]); diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h index 467384542502..0444507b438d 100644 --- a/include/asm-xtensa/elf.h +++ b/include/asm-xtensa/elf.h @@ -72,109 +72,25 @@ /* ELF register definitions. This is needed for core dump support. */ -/* - * elf_gregset_t contains the application-level state in the following order: - * Processor info: config_version, cpuxy - * Processor state: pc, ps, exccause, excvaddr, wb, ws, - * lbeg, lend, lcount, sar - * GP regs: ar0 - arXX - */ - typedef unsigned long elf_greg_t; typedef struct { - elf_greg_t xchal_config_id0; - elf_greg_t xchal_config_id1; - elf_greg_t cpux; - elf_greg_t cpuy; elf_greg_t pc; elf_greg_t ps; - elf_greg_t exccause; - elf_greg_t excvaddr; - elf_greg_t windowbase; - elf_greg_t windowstart; elf_greg_t lbeg; elf_greg_t lend; elf_greg_t lcount; elf_greg_t sar; - elf_greg_t syscall; - elf_greg_t ar[64]; + elf_greg_t windowstart; + elf_greg_t reserved[9+48]; + elf_greg_t a[64]; } xtensa_gregset_t; #define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -/* - * Compute the size of the coprocessor and extra state layout (register info) - * table (in bytes). - * This is actually the maximum size of the table, as opposed to the size, - * which is available from the _xtensa_reginfo_table_size global variable. - * - * (See also arch/xtensa/kernel/coprocessor.S) - * - */ - -#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM -# define XTENSA_CPE_LTABLE_SIZE 0 -#else -# define XTENSA_CPE_SEGMENT(num) (num ? (1+num) : 0) -# define XTENSA_CPE_LTABLE_ENTRIES \ - ( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM) \ - + XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM) \ - + 1 /* final entry */ \ - ) -# define XTENSA_CPE_LTABLE_SIZE (XTENSA_CPE_LTABLE_ENTRIES * 8) -#endif - - -/* - * Instantiations of the elf_fpregset_t type contain, in most - * architectures, the floating point (FPU) register set. - * For Xtensa, this type is extended to contain all custom state, - * ie. coprocessor and "extra" (non-coprocessor) state (including, - * for example, TIE-defined states and register files; as well - * as other optional processor state). - * This includes FPU state if a floating-point coprocessor happens - * to have been configured within the Xtensa processor. - * - * TOTAL_FPREGS_SIZE is the required size (without rounding) - * of elf_fpregset_t. It provides space for the following: - * - * a) 32-bit mask of active coprocessors for this task (similar - * to CPENABLE in single-threaded Xtensa processor systems) - * - * b) table describing the layout of custom states (ie. of - * individual registers, etc) within the save areas - * - * c) save areas for each coprocessor and for non-coprocessor - * ("extra") state - * - * Note that save areas may require up to 16-byte alignment when - * accessed by save/restore sequences. We do not need to ensure - * such alignment in an elf_fpregset_t structure because custom - * state is not directly loaded/stored into it; rather, save area - * contents are copied to elf_fpregset_t from the active save areas - * (see 'struct task_struct' definition in processor.h for that) - * using memcpy(). But we do allow space for such alignment, - * to allow optimizations of layout and copying. - */ -#if 0 -#define TOTAL_FPREGS_SIZE \ - (4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE) -#define ELF_NFPREG \ - ((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t)) -#else -#define TOTAL_FPREGS_SIZE 0 -#define ELF_NFPREG 0 -#endif +#define ELF_NFPREG 18 typedef unsigned int elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; From 3befce8f0f79be8322aba885ed052b8ad927913d Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 12 Feb 2008 12:22:15 -0800 Subject: [PATCH 063/880] [XTENSA] Remove oldmask from sigcontext and fix register flush Remove oldmask from the sigcontext structure. Also update wmask and windowstart when we flush the AR registers to stack. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/signal.c | 12 +++++------- include/asm-xtensa/sigcontext.h | 3 --- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 033aae0336d2..42d9fd8a4225 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -49,8 +49,6 @@ struct rt_sigframe /* * Flush register windows stored in pt_regs to stack. * Returns 1 for errors. - * - * Note that windowbase, windowstart, and wmask are not updated! */ int @@ -116,6 +114,9 @@ flush_window_regs_user(struct pt_regs *regs) base += inc; } + regs->wmask = 1; + regs->windowstart = 1 << wb; + return 0; errout: @@ -132,7 +133,7 @@ flush_window_regs_user(struct pt_regs *regs) static int setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate, - struct pt_regs *regs, unsigned long mask) + struct pt_regs *regs) { int err = 0; @@ -155,8 +156,6 @@ setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate, err |= save_cpextra(cpstate); err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); #endif - /* non-iBCS2 extensions.. */ - err |= __put_user(mask, &sc->oldmask); return err; } @@ -360,8 +359,7 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(sas_ss_flags(regs->areg[1]), &frame->uc.uc_stack.ss_flags); err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate, - regs, set->sig[0]); + err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate, regs); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); /* Create sys_rt_sigreturn syscall in stack frame */ diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h index e3381cee5059..dff3c54a3c12 100644 --- a/include/asm-xtensa/sigcontext.h +++ b/include/asm-xtensa/sigcontext.h @@ -13,9 +13,6 @@ struct sigcontext { - unsigned long oldmask; - - /* CPU registers */ unsigned long sc_pc; unsigned long sc_ps; unsigned long sc_lbeg; From ed3174d93c342b8b2eeba6bbd124707d55304a7b Mon Sep 17 00:00:00 2001 From: Marc Gauthier Date: Tue, 23 Oct 2007 16:40:24 -0700 Subject: [PATCH 064/880] [XTENSA] adjust boot linker script start addresses Move boot-redboot load address from 0xD0200000 to 0xD1000000 to make space for larger kernel images, in particular those with an embedded initramfs filesystem. Also properly set the ELF start address in boot-elf images so that PC need not be set manually when loading them using GDB. Signed-off-by: Marc Gauthier --- arch/xtensa/boot/boot-elf/boot.ld | 1 + arch/xtensa/boot/boot-redboot/boot.ld | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/xtensa/boot/boot-elf/boot.ld b/arch/xtensa/boot/boot-elf/boot.ld index 4ab06a0a7a6b..e33855c167bf 100644 --- a/arch/xtensa/boot/boot-elf/boot.ld +++ b/arch/xtensa/boot/boot-elf/boot.ld @@ -1,4 +1,5 @@ OUTPUT_ARCH(xtensa) +ENTRY(_ResetVector) SECTIONS { diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld index 65b726410e8a..774db20d11f7 100644 --- a/arch/xtensa/boot/boot-redboot/boot.ld +++ b/arch/xtensa/boot/boot-redboot/boot.ld @@ -2,7 +2,7 @@ OUTPUT_ARCH(xtensa) SECTIONS { - .start 0xD0200000 : { *(.start) } + .start 0xD1000000 : { *(.start) } .text : { From 50c0716aa2f49a9d34589e380fad73402464c088 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 14 Nov 2007 13:47:02 -0800 Subject: [PATCH 065/880] [XTENSA] Add missing a2 register restore in register spill routine Register a2 is saved in depc but wasn't getting restored before returning from _spill_registers when there weren't any registers to spill. The mask to cut the top bit from the rotated WINDOWMASK register was also one bit short. Signed-off-by: CHris Zankel --- arch/xtensa/kernel/entry.S | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 91a689eca43d..401b33bfd9c0 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1344,7 +1344,7 @@ ENTRY(_spill_registers) /* We are done if there are no more than the current register frame. */ - extui a3, a3, 1, WSBITS-2 # a3 = 0yyxxxwww + extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww movi a2, (1 << (WSBITS-1)) _beqz a3, .Lnospill # only one active frame? jump @@ -1394,6 +1394,10 @@ ENTRY(_spill_registers) l32e a4, a1, -16 j .Lc12c +.Lnospill: + rsr a2, DEPC # restore a2 and 'return' + jx a0 + .Lloop: _bbsi.l a3, 1, .Lc4 _bbci.l a3, 2, .Lc12 @@ -1419,8 +1423,6 @@ ENTRY(_spill_registers) movi a3, 1 sll a3, a3 wsr a3, WINDOWSTART - -.Lnospill: jx a0 .Lc4: s32e a4, a9, -16 From ea0b6b066304d9f7e24b273c71fab5d67ce54f96 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 9 Jan 2008 09:22:36 -0800 Subject: [PATCH 066/880] [XTENSA] Fix comments regarding the number of frames to save Signed-off-by: Marc Gauthier Signed-off-by: Chris Zankel --- arch/xtensa/kernel/entry.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 401b33bfd9c0..b4b14a579a3c 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1336,11 +1336,11 @@ ENTRY(_spill_registers) wsr a2, DEPC # preserve a2 rsr a2, WINDOWBASE - rsr a3, WINDOWSTART + rsr a3, WINDOWSTART # a3 = xxxwww1yy ssr a2 # holds WB slli a2, a3, WSBITS - or a3, a3, a2 # a2 = xxxwww1yyxxxwww1yy - srl a3, a3 + or a3, a3, a2 # a3 = xxxwww1yyxxxwww1yy + srl a3, a3 # a3 = 00xxxwww1yyxxxwww1 /* We are done if there are no more than the current register frame. */ @@ -1395,8 +1395,8 @@ ENTRY(_spill_registers) j .Lc12c .Lnospill: - rsr a2, DEPC # restore a2 and 'return' - jx a0 + rsr a2, DEPC + ret .Lloop: _bbsi.l a3, 1, .Lc4 _bbci.l a3, 2, .Lc12 @@ -1423,7 +1423,7 @@ ENTRY(_spill_registers) movi a3, 1 sll a3, a3 wsr a3, WINDOWSTART - jx a0 + ret .Lc4: s32e a4, a9, -16 s32e a5, a9, -12 From 3e92501a4e10e640786de10786c434834a0c1651 Mon Sep 17 00:00:00 2001 From: Marc Gauthier Date: Tue, 11 Dec 2007 15:28:07 -0800 Subject: [PATCH 067/880] [XTENSA] Add missing cast in elf.h ELF_CORE_COPY_REGS() Avoids compiler warning. Signed-off-by: Marc Gauthier --- include/asm-xtensa/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h index 0444507b438d..86479b86c02e 100644 --- a/include/asm-xtensa/elf.h +++ b/include/asm-xtensa/elf.h @@ -96,7 +96,7 @@ typedef unsigned int elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_CORE_COPY_REGS(_eregs, _pregs) \ - xtensa_elf_core_copy_regs (&_eregs, _pregs); + xtensa_elf_core_copy_regs ((xtensa_gregset_t*)&(_eregs), _pregs); extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *); From 3b4a49e21b0d8a69629623815a8caff3eb4cf9f7 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Mon, 7 Jan 2008 16:42:21 -0800 Subject: [PATCH 068/880] [XTENSA] Fix modules for non-exec processor configurations We need to use vmalloc_exec for module loading. Also remove the definitions MODULE_START and MODULE_END, which wasn't used, and increase the VMALLOC memory range accordingly. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/module.c | 2 +- include/asm-xtensa/module.h | 4 +++- include/asm-xtensa/pgtable.h | 8 +++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c index ddf14dcf2ad9..3981a466c779 100644 --- a/arch/xtensa/kernel/module.c +++ b/arch/xtensa/kernel/module.c @@ -28,7 +28,7 @@ void *module_alloc(unsigned long size) { if (size == 0) return NULL; - return vmalloc(size); + return vmalloc_exec(size); } void module_free(struct module *mod, void *module_region) diff --git a/include/asm-xtensa/module.h b/include/asm-xtensa/module.h index ffb25bfdf6a1..d9b34bee4d42 100644 --- a/include/asm-xtensa/module.h +++ b/include/asm-xtensa/module.h @@ -15,9 +15,11 @@ struct mod_arch_specific { - /* Module support is not completely implemented. */ + /* No special elements, yet. */ }; +#define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " " + #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h index c0fcc1c9660c..c8b024a48b4d 100644 --- a/include/asm-xtensa/pgtable.h +++ b/include/asm-xtensa/pgtable.h @@ -66,11 +66,9 @@ */ #define VMALLOC_START 0xC0000000 -#define VMALLOC_END 0xC6FEFFFF -#define TLBTEMP_BASE_1 0xC6FF0000 -#define TLBTEMP_BASE_2 0xC6FF8000 -#define MODULE_START 0xC7000000 -#define MODULE_END 0xC7FFFFFF +#define VMALLOC_END 0xC7FEFFFF +#define TLBTEMP_BASE_1 0xC7FF0000 +#define TLBTEMP_BASE_2 0xC7FF8000 /* * Xtensa Linux config PTE layout (when present): From 03dfa442e5aaf644bb9b3b506abbd76786867eb1 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 12 Feb 2008 13:10:40 -0800 Subject: [PATCH 069/880] [XTENSA] Remove unused code We will never (need to) support signal handling coming from a double exception. There are too many things that could go wrong and delivering signals is not the fastest method for IPC, anyway. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/entry.S | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index b4b14a579a3c..b51ddb0dcf28 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -28,7 +28,6 @@ /* Unimplemented features. */ -#undef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION #undef KERNEL_STACK_OVERFLOW_CHECK #undef PREEMPTIBLE_KERNEL #undef ALLOCA_EXCEPTION_IN_IRAM @@ -431,11 +430,8 @@ common_exception_return: _bbsi.l a4, TIF_NEED_RESCHED, 3f _bbci.l a4, TIF_SIGPENDING, 4f -#ifndef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION l32i a4, a1, PT_DEPC bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f -#endif - /* Reenable interrupts and call do_signal() */ wsr a3, PS @@ -1247,16 +1243,6 @@ fast_syscall_spill_registers_fixup: * Note: This frame might be the same as above. */ -#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION - /* Restore registers we precautiously saved. - * We have the value of the 'right' a3 - */ - - l32i a7, a2, PT_AREG5 - l32i a11, a2, PT_AREG6 - l32i a15, a2, PT_AREG7 -#endif - /* Setup stack pointer. */ addi a2, a2, -PT_USER_SIZE @@ -1290,14 +1276,6 @@ fast_syscall_spill_registers_fixup_return: s32i a2, a3, EXC_TABLE_PARAM l32i a2, a3, EXC_TABLE_KSTK -#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION - /* Save registers again that might be clobbered. */ - - s32i a7, a2, PT_AREG5 - s32i a11, a2, PT_AREG6 - s32i a15, a2, PT_AREG7 -#endif - /* Load WB at the time the exception occurred. */ rsr a3, SAR # WB is still in SAR From de6b03456e2e11cbff9f4bb147177374b260d04e Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 19 Dec 2007 10:21:50 -0800 Subject: [PATCH 070/880] [XTENSA] Add volatile keyword to asm statements accessing counter registers The compiler get's sometimes to smart and doesn't reread the counter registers and the kernel doesn't schedule until the counter wraps around. Signed-off-by: Chris Zankel --- include/asm-xtensa/timex.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h index a5fca59fba9e..b83a8181d448 100644 --- a/include/asm-xtensa/timex.h +++ b/include/asm-xtensa/timex.h @@ -63,10 +63,10 @@ extern cycles_t cacheflush_time; * Register access. */ -#define WSR_CCOUNT(r) __asm__("wsr %0,"__stringify(CCOUNT) :: "a" (r)) -#define RSR_CCOUNT(r) __asm__("rsr %0,"__stringify(CCOUNT) : "=a" (r)) -#define WSR_CCOMPARE(x,r) __asm__("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r)) -#define RSR_CCOMPARE(x,r) __asm__("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r)) +#define WSR_CCOUNT(r) asm volatile ("wsr %0,"__stringify(CCOUNT) :: "a" (r)) +#define RSR_CCOUNT(r) asm volatile ("rsr %0,"__stringify(CCOUNT) : "=a" (r)) +#define WSR_CCOMPARE(x,r) asm volatile ("wsr %0,"__stringify(CCOMPARE)"+"__stringify(x) :: "a"(r)) +#define RSR_CCOMPARE(x,r) asm volatile ("rsr %0,"__stringify(CCOMPARE)"+"__stringify(x) : "=a"(r)) static inline unsigned long get_ccount (void) { From 6d15d109632ff01e13c26893030e2ed9e6c4e3fd Mon Sep 17 00:00:00 2001 From: Marc Gauthier Date: Sun, 30 Dec 2007 22:00:54 -0800 Subject: [PATCH 071/880] [XTENSA] Add missing RELOCATE_ENTRY for debug vector We also need to relocate the debug vector if in RAM. Signed-off-by: Marc Gauthier --- arch/xtensa/kernel/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 4b717bf48fb7..51f4fb6f16f9 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -163,6 +163,8 @@ SECTIONS .DoubleExceptionVector.literal); RELOCATE_ENTRY(_DoubleExceptionVector_text, .DoubleExceptionVector.text); + RELOCATE_ENTRY(_DebugInterruptVector_text, + .DebugInterruptVector.text); __boot_reloc_table_end = ABSOLUTE(.) ; } From 36dffadb7f19671aab58be43c5896ea87d5fb1bf Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 12 Feb 2008 13:14:17 -0800 Subject: [PATCH 072/880] [XTENSA] Use preprocessor to generate the linker script for the ELF boot image Signed-off-by: Marc Gauthier Signed-off-by: Chris Zankel --- arch/xtensa/boot/boot-elf/Makefile | 5 +++-- arch/xtensa/boot/boot-elf/{boot.ld => boot.lds.S} | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) rename arch/xtensa/boot/boot-elf/{boot.ld => boot.lds.S} (91%) diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index 734db7f76583..9cf50ef465c1 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -14,12 +14,13 @@ OBJCOPY_ARGS := -O elf32-xtensa-le endif export OBJCOPY_ARGS +export CPPFLAGS_boot.lds += -P -C boot-y := bootstrap.o OBJS := $(addprefix $(obj)/,$(boot-y)) -Image: vmlinux $(OBJS) +Image: vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ vmlinux vmlinux.tmp $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ @@ -27,7 +28,7 @@ Image: vmlinux $(OBJS) --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ + -T arch/$(ARCH)/boot/boot-elf/boot.lds \ -o arch/$(ARCH)/boot/$@.elf $@.tmp rm -f $@.tmp vmlinux.tmp diff --git a/arch/xtensa/boot/boot-elf/boot.ld b/arch/xtensa/boot/boot-elf/boot.lds.S similarity index 91% rename from arch/xtensa/boot/boot-elf/boot.ld rename to arch/xtensa/boot/boot-elf/boot.lds.S index e33855c167bf..849dfcafd518 100644 --- a/arch/xtensa/boot/boot-elf/boot.ld +++ b/arch/xtensa/boot/boot-elf/boot.lds.S @@ -1,3 +1,4 @@ +#include OUTPUT_ARCH(xtensa) ENTRY(_ResetVector) @@ -62,7 +63,7 @@ SECTIONS _end = .; _param_start = .; - .ResetVector.text 0xfe000020 : + .ResetVector.text XCHAL_RESET_VECTOR_VADDR : { *(.ResetVector.text) } From 71d28e6c285548106f551fde13ca6d589433d843 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 16 Oct 2007 16:43:00 -0700 Subject: [PATCH 073/880] [XTENSA] Clean up stat structs. Avoid using typedefs for stat fields. Make stat64.st_blocks an unsigned long long to avoid endian-specific padding with 32-bit values. Clean up signed vs. unsigned and int vs. long types to be consistent with other uses of these values. Signed-off-by: Bob Wilson Signed-off-by: Chris Zankel --- include/asm-xtensa/stat.h | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/include/asm-xtensa/stat.h b/include/asm-xtensa/stat.h index 149f4bce092f..c4992038cee0 100644 --- a/include/asm-xtensa/stat.h +++ b/include/asm-xtensa/stat.h @@ -5,25 +5,23 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001 - 2007 Tensilica Inc. */ #ifndef _XTENSA_STAT_H #define _XTENSA_STAT_H -#include - #define STAT_HAVE_NSEC 1 struct stat { unsigned long st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - unsigned int st_rdev; - off_t st_size; + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned long st_rdev; + long st_size; unsigned long st_blksize; unsigned long st_blocks; unsigned long st_atime; @@ -36,8 +34,6 @@ struct stat { unsigned long __unused5; }; -/* This matches struct stat64 in glibc-2.3 */ - struct stat64 { unsigned long long st_dev; /* Device */ unsigned long long st_ino; /* File serial number */ @@ -47,20 +43,14 @@ struct stat64 { unsigned int st_gid; /* Group ID of the file's group. */ unsigned long long st_rdev; /* Device number, if device. */ long long st_size; /* Size of file, in bytes. */ - long st_blksize; /* Optimal block size for I/O. */ + unsigned long st_blksize; /* Optimal block size for I/O. */ unsigned long __unused2; -#ifdef __XTENSA_EB__ - unsigned long __unused3; - long st_blocks; /* Number 512-byte blocks allocated. */ -#else - long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long __unused3; -#endif - long st_atime; /* Time of last access. */ + unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long st_atime; /* Time of last access. */ unsigned long st_atime_nsec; - long st_mtime; /* Time of last modification. */ + unsigned long st_mtime; /* Time of last modification. */ unsigned long st_mtime_nsec; - long st_ctime; /* Time of last status change. */ + unsigned long st_ctime; /* Time of last status change. */ unsigned long st_ctime_nsec; unsigned long __unused4; unsigned long __unused5; From c658eac628aa8df040dfe614556d95e6da3a9ffb Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 12 Feb 2008 13:17:07 -0800 Subject: [PATCH 074/880] [XTENSA] Add support for configurable registers and coprocessors The Xtensa architecture allows to define custom instructions and registers. Registers that are bound to a coprocessor are only accessible if the corresponding enable bit is set, which allows to implement a 'lazy' context switch mechanism. Other registers needs to be saved and restore at the time of the context switch or during interrupt handling. This patch adds support for these additional states: - save and restore registers that are used by the compiler upon interrupt entry and exit. - context switch additional registers unbound to any coprocessor - 'lazy' context switch of registers bound to a coprocessor - ptrace interface to provide access to additional registers - update configuration files in include/asm-xtensa/variant-fsf Signed-off-by: Chris Zankel --- arch/xtensa/kernel/asm-offsets.c | 16 +- arch/xtensa/kernel/coprocessor.S | 443 +++++++++++++++-------- arch/xtensa/kernel/entry.S | 295 ++++----------- arch/xtensa/kernel/process.c | 261 ++++++------- arch/xtensa/kernel/ptrace.c | 347 +++++++++--------- arch/xtensa/kernel/signal.c | 65 ++-- arch/xtensa/kernel/traps.c | 16 +- include/asm-xtensa/coprocessor.h | 209 +++++++---- include/asm-xtensa/elf.h | 15 + include/asm-xtensa/processor.h | 13 +- include/asm-xtensa/ptrace.h | 44 ++- include/asm-xtensa/regs.h | 9 +- include/asm-xtensa/sigcontext.h | 1 + include/asm-xtensa/system.h | 39 +- include/asm-xtensa/thread_info.h | 21 ++ include/asm-xtensa/variant-fsf/tie-asm.h | 70 ++++ include/asm-xtensa/variant-fsf/tie.h | 75 +++- 17 files changed, 1065 insertions(+), 874 deletions(-) create mode 100644 include/asm-xtensa/variant-fsf/tie-asm.h diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 5d9ef515ca1e..ef63adadf7f4 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -63,6 +63,8 @@ int main(void) DEFINE(PT_SIZE, sizeof(struct pt_regs)); DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS])); DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS])); + DEFINE(PT_XTREGS_OPT, offsetof(struct pt_regs, xtregs_opt)); + DEFINE(XTREGS_OPT_SIZE, sizeof(xtregs_opt_t)); /* struct task_struct */ DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace)); @@ -76,7 +78,19 @@ int main(void) /* struct thread_info (offset from start_struct) */ DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra)); DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp)); - DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save)); + DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable)); +#if XTENSA_HAVE_COPROCESSORS + DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp)); +#endif + DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); + DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds)); /* struct mm_struct */ diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index 01bcb9fcfcbd..2bc1e145c0a4 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S @@ -8,193 +8,328 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003 - 2005 Tensilica Inc. - * - * Marc Gauthier + * Copyright (C) 2003 - 2007 Tensilica Inc. */ -/* - * This module contains a table that describes the layout of the various - * custom registers and states associated with each coprocessor, as well - * as those not associated with any coprocessor ("extra state"). - * This table is included with core dumps and is available via the ptrace - * interface, allowing the layout of such register/state information to - * be modified in the kernel without affecting the debugger. Each - * register or state is identified using a 32-bit "libdb target number" - * assigned when the Xtensa processor is generated. - */ #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#if XCHAL_HAVE_CP +/* + * Entry condition: + * + * a0: trashed, original value saved on stack (PT_AREG0) + * a1: a1 + * a2: new stack pointer, original in DEPC + * a3: dispatch table + * depc: a2, original value saved on stack (PT_DEPC) + * excsave_1: a3 + * + * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC + * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception + */ -#define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE) +/* IO protection is currently unsupported. */ -ENTRY(release_coprocessors) +ENTRY(fast_io_protect) + wsr a0, EXCSAVE_1 + movi a0, unrecoverable_exception + callx0 a0 - entry a1, 16 - # a2: task - movi a3, 1 << XCHAL_CP_MAX # a3: coprocessor-bit - movi a4, coprocessor_info+CP_LAST # a4: owner-table - # a5: tmp - movi a6, 0 # a6: 0 - rsil a7, LOCKLEVEL # a7: PS +#if XTENSA_HAVE_COPROCESSORS -1: /* Check if task is coprocessor owner of coprocessor[i]. */ +/* + * Macros for lazy context switch. + */ - l32i a5, a4, COPROCESSOR_INFO_OWNER - srli a3, a3, 1 - beqz a3, 1f - addi a4, a4, -8 - beq a2, a5, 1b +#define SAVE_CP_REGS(x) \ + .align 4; \ + .Lsave_cp_regs_cp##x: \ + .if XTENSA_HAVE_COPROCESSOR(x); \ + xchal_cp##x##_store a2 a4 a5 a6 a7; \ + .endif; \ + jx a0 - /* Found an entry: Clear entry CPENABLE bit to disable CP. */ +#define SAVE_CP_REGS_TAB(x) \ + .if XTENSA_HAVE_COPROCESSOR(x); \ + .long .Lsave_cp_regs_cp##x - .Lsave_cp_regs_jump_table; \ + .else; \ + .long 0; \ + .endif; \ + .long THREAD_XTREGS_CP##x - rsr a5, CPENABLE - s32i a6, a4, COPROCESSOR_INFO_OWNER - xor a5, a3, a5 - wsr a5, CPENABLE - bnez a3, 1b +#define LOAD_CP_REGS(x) \ + .align 4; \ + .Lload_cp_regs_cp##x: \ + .if XTENSA_HAVE_COPROCESSOR(x); \ + xchal_cp##x##_load a2 a4 a5 a6 a7; \ + .endif; \ + jx a0 -1: wsr a7, PS - rsync - retw +#define LOAD_CP_REGS_TAB(x) \ + .if XTENSA_HAVE_COPROCESSOR(x); \ + .long .Lload_cp_regs_cp##x - .Lload_cp_regs_jump_table; \ + .else; \ + .long 0; \ + .endif; \ + .long THREAD_XTREGS_CP##x + SAVE_CP_REGS(0) + SAVE_CP_REGS(1) + SAVE_CP_REGS(2) + SAVE_CP_REGS(3) + SAVE_CP_REGS(4) + SAVE_CP_REGS(5) + SAVE_CP_REGS(6) + SAVE_CP_REGS(7) -ENTRY(disable_coprocessor) - entry sp, 16 - rsil a7, LOCKLEVEL - rsr a3, CPENABLE - movi a4, 1 - ssl a2 - sll a4, a4 - and a4, a3, a4 - xor a3, a3, a4 - wsr a3, CPENABLE - wsr a7, PS - rsync - retw + LOAD_CP_REGS(0) + LOAD_CP_REGS(1) + LOAD_CP_REGS(2) + LOAD_CP_REGS(3) + LOAD_CP_REGS(4) + LOAD_CP_REGS(5) + LOAD_CP_REGS(6) + LOAD_CP_REGS(7) -ENTRY(enable_coprocessor) - entry sp, 16 - rsil a7, LOCKLEVEL - rsr a3, CPENABLE - movi a4, 1 - ssl a2 - sll a4, a4 - or a3, a3, a4 - wsr a3, CPENABLE - wsr a7, PS - rsync - retw + .align 4 +.Lsave_cp_regs_jump_table: + SAVE_CP_REGS_TAB(0) + SAVE_CP_REGS_TAB(1) + SAVE_CP_REGS_TAB(2) + SAVE_CP_REGS_TAB(3) + SAVE_CP_REGS_TAB(4) + SAVE_CP_REGS_TAB(5) + SAVE_CP_REGS_TAB(6) + SAVE_CP_REGS_TAB(7) +.Lload_cp_regs_jump_table: + LOAD_CP_REGS_TAB(0) + LOAD_CP_REGS_TAB(1) + LOAD_CP_REGS_TAB(2) + LOAD_CP_REGS_TAB(3) + LOAD_CP_REGS_TAB(4) + LOAD_CP_REGS_TAB(5) + LOAD_CP_REGS_TAB(6) + LOAD_CP_REGS_TAB(7) -ENTRY(save_coprocessor_extra) - entry sp, 16 - xchal_extra_store_funcbody - retw +/* + * coprocessor_save(buffer, index) + * a2 a3 + * coprocessor_load(buffer, index) + * a2 a3 + * + * Save or load coprocessor registers for coprocessor 'index'. + * The register values are saved to or loaded from them 'buffer' address. + * + * Note that these functions don't update the coprocessor_owner information! + * + */ -ENTRY(restore_coprocessor_extra) - entry sp, 16 - xchal_extra_load_funcbody +ENTRY(coprocessor_save) + entry a1, 32 + s32i a0, a1, 0 + movi a0, .Lsave_cp_regs_jump_table + addx8 a3, a3, a0 + l32i a3, a3, 0 + beqz a3, 1f + add a0, a0, a3 + callx0 a0 +1: l32i a0, a1, 0 retw -ENTRY(save_coprocessor_registers) - entry sp, 16 - xchal_cpi_store_funcbody +ENTRY(coprocessor_load) + entry a1, 32 + s32i a0, a1, 0 + movi a0, .Lload_cp_regs_jump_table + addx4 a3, a3, a0 + l32i a3, a3, 0 + beqz a3, 1f + add a0, a0, a3 + callx0 a0 +1: l32i a0, a1, 0 retw -ENTRY(restore_coprocessor_registers) - entry sp, 16 - xchal_cpi_load_funcbody +/* + * coprocessor_flush(struct task_info*, index) + * a2 a3 + * coprocessor_restore(struct task_info*, index) + * a2 a3 + * + * Save or load coprocessor registers for coprocessor 'index'. + * The register values are saved to or loaded from the coprocessor area + * inside the task_info structure. + * + * Note that these functions don't update the coprocessor_owner information! + * + */ + + +ENTRY(coprocessor_flush) + entry a1, 32 + s32i a0, a1, 0 + movi a0, .Lsave_cp_regs_jump_table + addx8 a3, a3, a0 + l32i a4, a3, 4 + l32i a3, a3, 0 + add a2, a2, a4 + beqz a3, 1f + add a0, a0, a3 + callx0 a0 +1: l32i a0, a1, 0 retw +ENTRY(coprocessor_restore) + entry a1, 32 + s32i a0, a1, 0 + movi a0, .Lload_cp_regs_jump_table + addx4 a3, a3, a0 + l32i a4, a3, 4 + l32i a3, a3, 0 + add a2, a2, a4 + beqz a3, 1f + add a0, a0, a3 + callx0 a0 +1: l32i a0, a1, 0 + retw /* - * The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros - * describe the contents of coprocessor & extra save areas in terms of - * undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros. We define these - * latter macros here; they expand into a table of the format we want. - * The general format is: + * Entry condition: * - * CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum, - * bitmask, rsv2, rsv3) - * CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum, - * bitmask, rsv2, rsv3) - * CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, - * numentries, contentsize, regname_base, - * regfile_name, rsv2, rsv3) + * a0: trashed, original value saved on stack (PT_AREG0) + * a1: a1 + * a2: new stack pointer, original in DEPC + * a3: dispatch table + * depc: a2, original value saved on stack (PT_DEPC) + * excsave_1: a3 * - * For this table, we only care about the , and - * fields. + * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC + * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception */ -/* Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below: */ - -#define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum, \ - bitmask, rsv2, rsv3) \ - reg_entry libdbnum, offset, size ; -#define CONTENTS_LIBDB_UREG(libdbnum,offset,size,align,rsv1,name,uregnum, \ - bitmask, rsv2, rsv3) \ - reg_entry libdbnum, offset, size ; -#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, \ - numentries, contentsize, regname_base, \ - regfile_name, rsv2, rsv3) \ - reg_entry libdbnum, offset, size ; - -/* A single table entry: */ - .macro reg_entry libdbnum, offset, size - .ifne (__last_offset-(__last_group_offset+\offset)) - /* padding entry */ - .word (0xFC000000+__last_offset-(__last_group_offset+\offset)) - .endif - .word \libdbnum /* actual entry */ - .set __last_offset, __last_group_offset+\offset+\size - .endm /* reg_entry */ - - -/* Table entry that marks the beginning of a group (coprocessor or "extra"): */ - .macro reg_group cpnum, num_entries, align - .set __last_group_offset, (__last_offset + \align- 1) & -\align - .ifne \num_entries - .word 0xFD000000+(\cpnum<<16)+\num_entries - .endif - .endm /* reg_group */ +ENTRY(fast_coprocessor_double) + wsr a0, EXCSAVE_1 + movi a0, unrecoverable_exception + callx0 a0 -/* - * Register info tables. - */ - .section .rodata, "a" - .globl _xtensa_reginfo_tables - .globl _xtensa_reginfo_table_size - .align 4 -_xtensa_reginfo_table_size: - .word _xtensa_reginfo_table_end - _xtensa_reginfo_tables - -_xtensa_reginfo_tables: - .set __last_offset, 0 - reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN - XCHAL_EXTRA_SA_CONTENTS_LIBDB - reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN - XCHAL_CP0_SA_CONTENTS_LIBDB - reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN - XCHAL_CP1_SA_CONTENTS_LIBDB - reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN - XCHAL_CP2_SA_CONTENTS_LIBDB - reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN - XCHAL_CP3_SA_CONTENTS_LIBDB - reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN - XCHAL_CP4_SA_CONTENTS_LIBDB - reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN - XCHAL_CP5_SA_CONTENTS_LIBDB - reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN - XCHAL_CP6_SA_CONTENTS_LIBDB - reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN - XCHAL_CP7_SA_CONTENTS_LIBDB - .word 0xFC000000 /* invalid register number,marks end of table*/ -_xtensa_reginfo_table_end: -#endif +ENTRY(fast_coprocessor) + + /* Save remaining registers a1-a3 and SAR */ + + xsr a3, EXCSAVE_1 + s32i a3, a2, PT_AREG3 + rsr a3, SAR + s32i a1, a2, PT_AREG1 + s32i a3, a2, PT_SAR + mov a1, a2 + rsr a2, DEPC + s32i a2, a1, PT_AREG2 + + /* + * The hal macros require up to 4 temporary registers. We use a3..a6. + */ + + s32i a4, a1, PT_AREG4 + s32i a5, a1, PT_AREG5 + s32i a6, a1, PT_AREG6 + + /* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */ + + rsr a3, EXCCAUSE + addi a3, a3, -EXCCAUSE_COPROCESSOR0_DISABLED + + /* Set corresponding CPENABLE bit -> (sar:cp-index, a3: 1< #include #include +#include /* Unimplemented features. */ @@ -213,19 +214,7 @@ _user_exception: /* We are back to the original stack pointer (a1) */ -2: -#if XCHAL_EXTRA_SA_SIZE - - /* For user exceptions, save the extra state into the user's TCB. - * Note: We must assume that xchal_extra_store_funcbody destroys a2..a15 - */ - - GET_CURRENT(a2,a1) - addi a2, a2, THREAD_CP_SAVE - xchal_extra_store_funcbody -#endif - - /* Now, jump to the common exception handler. */ +2: /* Now, jump to the common exception handler. */ j common_exception @@ -381,6 +370,10 @@ common_exception: s32i a2, a1, PT_LBEG s32i a3, a1, PT_LEND + /* Save optional registers. */ + + save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT + /* Go to second-level dispatcher. Set up parameters to pass to the * exception handler and call the exception handler. */ @@ -452,22 +445,6 @@ common_exception_return: 4: /* a2 holds GET_CURRENT(a2,a1) */ -#if XCHAL_EXTRA_SA_SIZE - - /* For user exceptions, restore the extra state from the user's TCB. */ - - /* Note: a2 still contains GET_CURRENT(a2,a1) */ - addi a2, a2, THREAD_CP_SAVE - xchal_extra_load_funcbody - - /* We must assume that xchal_extra_store_funcbody destroys - * registers a2..a15. FIXME, this list can eventually be - * reduced once real register requirements of the macro are - * finalized. */ - -#endif /* XCHAL_EXTRA_SA_SIZE */ - - /* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */ l32i a2, a1, PT_WINDOWBASE @@ -614,6 +591,12 @@ kernel_exception_exit: common_exception_exit: + /* Restore optional registers. */ + + load_xtregs_opt a1 a3 a4 a5 a6 a7 PT_XTREGS_OPT + + /* Restore address registers. */ + _bbsi.l a2, 1, 1f l32i a4, a1, PT_AREG4 l32i a5, a1, PT_AREG5 @@ -1146,7 +1129,6 @@ CATCH * excsave_1: a3 * * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler. - * Note: We don't need to save a2 in depc (return value) */ ENTRY(fast_syscall_spill_registers) @@ -1162,29 +1144,31 @@ ENTRY(fast_syscall_spill_registers) rsr a0, SAR xsr a3, EXCSAVE_1 # restore a3 and excsave_1 - s32i a0, a2, PT_AREG4 # store SAR to PT_AREG4 s32i a3, a2, PT_AREG3 + s32i a4, a2, PT_AREG4 + s32i a0, a2, PT_AREG5 # store SAR to PT_AREG5 /* The spill routine might clobber a7, a11, and a15. */ - s32i a7, a2, PT_AREG5 - s32i a11, a2, PT_AREG6 - s32i a15, a2, PT_AREG7 + s32i a7, a2, PT_AREG7 + s32i a11, a2, PT_AREG11 + s32i a15, a2, PT_AREG15 - call0 _spill_registers # destroys a3, DEPC, and SAR + call0 _spill_registers # destroys a3, a4, and SAR /* Advance PC, restore registers and SAR, and return from exception. */ - l32i a3, a2, PT_AREG4 + l32i a3, a2, PT_AREG5 + l32i a4, a2, PT_AREG4 l32i a0, a2, PT_AREG0 wsr a3, SAR l32i a3, a2, PT_AREG3 /* Restore clobbered registers. */ - l32i a7, a2, PT_AREG5 - l32i a11, a2, PT_AREG6 - l32i a15, a2, PT_AREG7 + l32i a7, a2, PT_AREG7 + l32i a11, a2, PT_AREG11 + l32i a15, a2, PT_AREG15 movi a2, 0 rfe @@ -1257,9 +1241,9 @@ fast_syscall_spill_registers_fixup: movi a3, exc_table rsr a0, EXCCAUSE - addx4 a0, a0, a3 # find entry in table - l32i a0, a0, EXC_TABLE_FAST_USER # load handler - jx a0 + addx4 a0, a0, a3 # find entry in table + l32i a0, a0, EXC_TABLE_FAST_USER # load handler + jx a0 fast_syscall_spill_registers_fixup_return: @@ -1297,7 +1281,7 @@ fast_syscall_spill_registers_fixup_return: * This is not a real function. The following conditions must be met: * * - must be called with call0. - * - uses DEPC, a3 and SAR. + * - uses a3, a4 and SAR. * - the last 'valid' register of each frame are clobbered. * - the caller must have registered a fixup handler * (or be inside a critical section) @@ -1309,41 +1293,39 @@ ENTRY(_spill_registers) /* * Rotate ws so that the current windowbase is at bit 0. * Assume ws = xxxwww1yy (www1 current window frame). - * Rotate ws right so that a2 = yyxxxwww1. + * Rotate ws right so that a4 = yyxxxwww1. */ - wsr a2, DEPC # preserve a2 - rsr a2, WINDOWBASE + rsr a4, WINDOWBASE rsr a3, WINDOWSTART # a3 = xxxwww1yy - ssr a2 # holds WB - slli a2, a3, WSBITS - or a3, a3, a2 # a3 = xxxwww1yyxxxwww1yy + ssr a4 # holds WB + slli a4, a3, WSBITS + or a3, a3, a4 # a3 = xxxwww1yyxxxwww1yy srl a3, a3 # a3 = 00xxxwww1yyxxxwww1 /* We are done if there are no more than the current register frame. */ extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww - movi a2, (1 << (WSBITS-1)) + movi a4, (1 << (WSBITS-1)) _beqz a3, .Lnospill # only one active frame? jump /* We want 1 at the top, so that we return to the current windowbase */ - or a3, a3, a2 # 1yyxxxwww + or a3, a3, a4 # 1yyxxxwww /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */ wsr a3, WINDOWSTART # save shifted windowstart - neg a2, a3 - and a3, a2, a3 # first bit set from right: 000010000 + neg a4, a3 + and a3, a4, a3 # first bit set from right: 000010000 - ffs_ws a2, a3 # a2: shifts to skip empty frames + ffs_ws a4, a3 # a4: shifts to skip empty frames movi a3, WSBITS - sub a2, a3, a2 # WSBITS-a2:number of 0-bits from right - ssr a2 # save in SAR for later. + sub a4, a3, a4 # WSBITS-a4:number of 0-bits from right + ssr a4 # save in SAR for later. rsr a3, WINDOWBASE - add a3, a3, a2 - rsr a2, DEPC # restore a2 + add a3, a3, a4 wsr a3, WINDOWBASE rsync @@ -1373,7 +1355,6 @@ ENTRY(_spill_registers) j .Lc12c .Lnospill: - rsr a2, DEPC ret .Lloop: _bbsi.l a3, 1, .Lc4 @@ -1810,154 +1791,6 @@ ENTRY(fast_store_prohibited) 1: j _user_exception -#if XCHAL_EXTRA_SA_SIZE - -#warning fast_coprocessor untested - -/* - * Entry condition: - * - * a0: trashed, original value saved on stack (PT_AREG0) - * a1: a1 - * a2: new stack pointer, original in DEPC - * a3: dispatch table - * depc: a2, original value saved on stack (PT_DEPC) - * excsave_1: a3 - * - * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC - * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception - */ - -ENTRY(fast_coprocessor_double) - wsr a0, EXCSAVE_1 - movi a0, unrecoverable_exception - callx0 a0 - -ENTRY(fast_coprocessor) - - /* Fatal if we are in a double exception. */ - - l32i a0, a2, PT_DEPC - _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_coprocessor_double - - /* Save some registers a1, a3, a4, SAR */ - - xsr a3, EXCSAVE_1 - s32i a3, a2, PT_AREG3 - rsr a3, SAR - s32i a4, a2, PT_AREG4 - s32i a1, a2, PT_AREG1 - s32i a5, a1, PT_AREG5 - s32i a3, a2, PT_SAR - mov a1, a2 - - /* Currently, the HAL macros only guarantee saving a0 and a1. - * These can and will be refined in the future, but for now, - * just save the remaining registers of a2...a15. - */ - s32i a6, a1, PT_AREG6 - s32i a7, a1, PT_AREG7 - s32i a8, a1, PT_AREG8 - s32i a9, a1, PT_AREG9 - s32i a10, a1, PT_AREG10 - s32i a11, a1, PT_AREG11 - s32i a12, a1, PT_AREG12 - s32i a13, a1, PT_AREG13 - s32i a14, a1, PT_AREG14 - s32i a15, a1, PT_AREG15 - - /* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */ - - rsr a0, EXCCAUSE - addi a3, a0, -XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED - - /* Set corresponding CPENABLE bit */ - - movi a4, 1 - ssl a3 # SAR: 32 - coprocessor_number - rsr a5, CPENABLE - sll a4, a4 - or a4, a5, a4 - wsr a4, CPENABLE - rsync - movi a5, coprocessor_info # list of owner and offset into cp_save - addx8 a0, a4, a5 # entry for CP - - bne a4, a5, .Lload # bit wasn't set before, cp not in use - - /* Now compare the current task with the owner of the coprocessor. - * If they are the same, there is no reason to save or restore any - * coprocessor state. Having already enabled the coprocessor, - * branch ahead to return. - */ - GET_CURRENT(a5,a1) - l32i a4, a0, COPROCESSOR_INFO_OWNER # a4: current owner for this CP - beq a4, a5, .Ldone - - /* Find location to dump current coprocessor state: - * task_struct->task_cp_save_offset + coprocessor_offset[coprocessor] - * - * Note: a0 pointer to the entry in the coprocessor owner table, - * a3 coprocessor number, - * a4 current owner of coprocessor. - */ - l32i a5, a0, COPROCESSOR_INFO_OFFSET - addi a2, a4, THREAD_CP_SAVE - add a2, a2, a5 - - /* Store current coprocessor states. (a5 still has CP number) */ - - xchal_cpi_store_funcbody - - /* The macro might have destroyed a3 (coprocessor number), but - * SAR still has 32 - coprocessor_number! - */ - movi a3, 32 - rsr a4, SAR - sub a3, a3, a4 - -.Lload: /* A new task now owns the corpocessors. Save its TCB pointer into - * the coprocessor owner table. - * - * Note: a0 pointer to the entry in the coprocessor owner table, - * a3 coprocessor number. - */ - GET_CURRENT(a4,a1) - s32i a4, a0, 0 - - /* Find location from where to restore the current coprocessor state.*/ - - l32i a5, a0, COPROCESSOR_INFO_OFFSET - addi a2, a4, THREAD_CP_SAVE - add a2, a2, a4 - - xchal_cpi_load_funcbody - - /* We must assume that the xchal_cpi_store_funcbody macro destroyed - * registers a2..a15. - */ - -.Ldone: l32i a15, a1, PT_AREG15 - l32i a14, a1, PT_AREG14 - l32i a13, a1, PT_AREG13 - l32i a12, a1, PT_AREG12 - l32i a11, a1, PT_AREG11 - l32i a10, a1, PT_AREG10 - l32i a9, a1, PT_AREG9 - l32i a8, a1, PT_AREG8 - l32i a7, a1, PT_AREG7 - l32i a6, a1, PT_AREG6 - l32i a5, a1, PT_AREG5 - l32i a4, a1, PT_AREG4 - l32i a3, a1, PT_AREG3 - l32i a2, a1, PT_AREG2 - l32i a0, a1, PT_AREG0 - l32i a1, a1, PT_AREG1 - - rfe - -#endif /* XCHAL_EXTRA_SA_SIZE */ - /* * System Calls. * @@ -2066,20 +1899,36 @@ ENTRY(_switch_to) entry a1, 16 - mov a4, a3 # preserve a3 + mov a12, a2 # preserve 'prev' (a2) + mov a13, a3 # and 'next' (a3) - s32i a0, a2, THREAD_RA # save return address - s32i a1, a2, THREAD_SP # save stack pointer + l32i a4, a2, TASK_THREAD_INFO + l32i a5, a3, TASK_THREAD_INFO - /* Disable ints while we manipulate the stack pointer; spill regs. */ + save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER - movi a5, (1 << PS_EXCM_BIT) | LOCKLEVEL - xsr a5, PS + s32i a0, a12, THREAD_RA # save return address + s32i a1, a12, THREAD_SP # save stack pointer + + /* Disable ints while we manipulate the stack pointer. */ + + movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL + xsr a14, PS rsr a3, EXCSAVE_1 rsync s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */ - call0 _spill_registers + /* Switch CPENABLE */ + +#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) + l32i a3, a5, THREAD_CPENABLE + xsr a3, CPENABLE + s32i a3, a4, THREAD_CPENABLE +#endif + + /* Flush register file. */ + + call0 _spill_registers # destroys a3, a4, and SAR /* Set kernel stack (and leave critical section) * Note: It's save to set it here. The stack will not be overwritten @@ -2087,19 +1936,21 @@ ENTRY(_switch_to) * we return from kernel space. */ - l32i a0, a4, TASK_THREAD_INFO rsr a3, EXCSAVE_1 # exc_table - movi a1, 0 - addi a0, a0, PT_REGS_OFFSET - s32i a1, a3, EXC_TABLE_FIXUP - s32i a0, a3, EXC_TABLE_KSTK + movi a6, 0 + addi a7, a5, PT_REGS_OFFSET + s32i a6, a3, EXC_TABLE_FIXUP + s32i a7, a3, EXC_TABLE_KSTK /* restore context of the task that 'next' addresses */ - l32i a0, a4, THREAD_RA /* restore return address */ - l32i a1, a4, THREAD_SP /* restore stack pointer */ + l32i a0, a13, THREAD_RA # restore return address + l32i a1, a13, THREAD_SP # restore stack pointer + + load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER - wsr a5, PS + wsr a14, PS + mov a2, a12 # return 'prev' rsync retw diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 026138d641a4..9185597eb6a0 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -52,6 +52,55 @@ void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); +#if XTENSA_HAVE_COPROCESSORS + +void coprocessor_release_all(struct thread_info *ti) +{ + unsigned long cpenable; + int i; + + /* Make sure we don't switch tasks during this operation. */ + + preempt_disable(); + + /* Walk through all cp owners and release it for the requested one. */ + + cpenable = ti->cpenable; + + for (i = 0; i < XCHAL_CP_MAX; i++) { + if (coprocessor_owner[i] == ti) { + coprocessor_owner[i] = 0; + cpenable &= ~(1 << i); + } + } + + ti->cpenable = cpenable; + coprocessor_clear_cpenable(); + + preempt_enable(); +} + +void coprocessor_flush_all(struct thread_info *ti) +{ + unsigned long cpenable; + int i; + + preempt_disable(); + + cpenable = ti->cpenable; + + for (i = 0; i < XCHAL_CP_MAX; i++) { + if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti) + coprocessor_flush(ti, i); + cpenable >>= 1; + } + + preempt_enable(); +} + +#endif + + /* * Powermanagement idle function, if any is provided by the platform. */ @@ -71,15 +120,36 @@ void cpu_idle(void) } /* - * Free current thread data structures etc.. + * This is called when the thread calls exit(). */ - void exit_thread(void) { +#if XTENSA_HAVE_COPROCESSORS + coprocessor_release_all(current_thread_info()); +#endif } +/* + * Flush thread state. This is called when a thread does an execve() + * Note that we flush coprocessor registers for the case execve fails. + */ void flush_thread(void) { +#if XTENSA_HAVE_COPROCESSORS + struct thread_info *ti = current_thread_info(); + coprocessor_flush_all(ti); + coprocessor_release_all(ti); +#endif +} + +/* + * This is called before the thread is copied. + */ +void prepare_to_copy(struct task_struct *tsk) +{ +#if XTENSA_HAVE_COPROCESSORS + coprocessor_flush_all(task_thread_info(tsk)); +#endif } /* @@ -107,6 +177,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct task_struct * p, struct pt_regs * regs) { struct pt_regs *childregs; + struct thread_info *ti; unsigned long tos; int user_mode = user_mode(regs); @@ -128,13 +199,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, p->set_child_tid = p->clear_child_tid = NULL; p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); p->thread.sp = (unsigned long)childregs; + if (user_mode(regs)) { int len = childregs->wmask & ~0xf; childregs->areg[1] = usp; memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], ®s->areg[XCHAL_NUM_AREGS - len/4], len); - +// FIXME: we need to set THREADPTR in thread_info... if (clone_flags & CLONE_SETTLS) childregs->areg[2] = childregs->areg[6]; @@ -142,6 +214,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, /* In kernel space, we start a new thread with a new stack. */ childregs->wmask = 1; } + +#if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) + ti = task_thread_info(p); + ti->cpenable = 0; +#endif + return 0; } @@ -179,10 +257,6 @@ unsigned long get_wchan(struct task_struct *p) } /* - * do_copy_regs() gathers information from 'struct pt_regs' and - * 'current->thread.areg[]' to fill in the xtensa_gregset_t - * structure. - * * xtensa_gregset_t and 'struct pt_regs' are vastly different formats * of processor registers. Besides different ordering, * xtensa_gregset_t contains non-live register information that @@ -191,9 +265,20 @@ unsigned long get_wchan(struct task_struct *p) * */ -void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, - struct task_struct *tsk) +void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) { + unsigned long wb, ws, wm; + int live, last; + + wb = regs->windowbase; + ws = regs->windowstart; + wm = regs->wmask; + ws = ((ws >> wb) | (ws << (WSBITS - wb))) & ((1 << WSBITS) - 1); + + /* Don't leak any random bits. */ + + memset(elfregs, 0, sizeof (elfregs)); + /* Note: PS.EXCM is not set while user task is running; its * being set in regs->ps is for exception handling convenience. */ @@ -204,159 +289,18 @@ void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, elfregs->lend = regs->lend; elfregs->lcount = regs->lcount; elfregs->sar = regs->sar; + elfregs->windowstart = ws; - memcpy (elfregs->a, regs->areg, sizeof(elfregs->a)); -} - -void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs) -{ - do_copy_regs ((xtensa_gregset_t *)elfregs, regs, current); -} - - -/* The inverse of do_copy_regs(). No error or sanity checking. */ - -void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, - struct task_struct *tsk) -{ - const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; - unsigned long ps; - - /* Note: PS.EXCM is not set while user task is running; it - * needs to be set in regs->ps is for exception handling convenience. - */ - - ps = (regs->ps & ~ps_mask) | (elfregs->ps & ps_mask) | (1<ps = ps; - regs->pc = elfregs->pc; - regs->lbeg = elfregs->lbeg; - regs->lend = elfregs->lend; - regs->lcount = elfregs->lcount; - regs->sar = elfregs->sar; - - memcpy (regs->areg, elfregs->a, sizeof(regs->areg)); -} - -/* - * do_save_fpregs() gathers information from 'struct pt_regs' and - * 'current->thread' to fill in the elf_fpregset_t structure. - * - * Core files and ptrace use elf_fpregset_t. - */ - -void do_save_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs, - struct task_struct *tsk) -{ -#if XCHAL_HAVE_CP - - extern unsigned char _xtensa_reginfo_tables[]; - extern unsigned _xtensa_reginfo_table_size; - int i; - unsigned long flags; - - /* Before dumping coprocessor state from memory, - * ensure any live coprocessor contents for this - * task are first saved to memory: - */ - local_irq_save(flags); - - for (i = 0; i < XCHAL_CP_MAX; i++) { - if (tsk == coprocessor_info[i].owner) { - enable_coprocessor(i); - save_coprocessor_registers( - tsk->thread.cp_save+coprocessor_info[i].offset,i); - disable_coprocessor(i); - } - } - - local_irq_restore(flags); - - /* Now dump coprocessor & extra state: */ - memcpy((unsigned char*)fpregs, - _xtensa_reginfo_tables, _xtensa_reginfo_table_size); - memcpy((unsigned char*)fpregs + _xtensa_reginfo_table_size, - tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE); -#endif + live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; + last = XCHAL_NUM_AREGS - (wm >> 4) * 4; + memcpy(elfregs->a, regs->areg, live * 4); + memcpy(elfregs->a + last, regs->areg + last, (wm >> 4) * 16); } -/* - * The inverse of do_save_fpregs(). - * Copies coprocessor and extra state from fpregs into regs and tsk->thread. - * Returns 0 on success, non-zero if layout doesn't match. - */ - -int do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs, - struct task_struct *tsk) +int dump_fpu(void) { -#if XCHAL_HAVE_CP - - extern unsigned char _xtensa_reginfo_tables[]; - extern unsigned _xtensa_reginfo_table_size; - int i; - unsigned long flags; - - /* Make sure save area layouts match. - * FIXME: in the future we could allow restoring from - * a different layout of the same registers, by comparing - * fpregs' table with _xtensa_reginfo_tables and matching - * entries and copying registers one at a time. - * Not too sure yet whether that's very useful. - */ - - if( memcmp((unsigned char*)fpregs, - _xtensa_reginfo_tables, _xtensa_reginfo_table_size) ) { - return -1; - } - - /* Before restoring coprocessor state from memory, - * ensure any live coprocessor contents for this - * task are first invalidated. - */ - - local_irq_save(flags); - - for (i = 0; i < XCHAL_CP_MAX; i++) { - if (tsk == coprocessor_info[i].owner) { - enable_coprocessor(i); - save_coprocessor_registers( - tsk->thread.cp_save+coprocessor_info[i].offset,i); - coprocessor_info[i].owner = 0; - disable_coprocessor(i); - } - } - - local_irq_restore(flags); - - /* Now restore coprocessor & extra state: */ - - memcpy(tsk->thread.cp_save, - (unsigned char*)fpregs + _xtensa_reginfo_table_size, - XTENSA_CP_EXTRA_SIZE); -#endif return 0; } -/* - * Fill in the CP structure for a core dump for a particular task. - */ - -int -dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r) -{ - return 0; /* no coprocessors active on this processor */ -} - -/* - * Fill in the CP structure for a core dump. - * This includes any FPU coprocessor. - * Here, we dump all coprocessors, and other ("extra") custom state. - * - * This function is called by elf_core_dump() in fs/binfmt_elf.c - * (in which case 'regs' comes from calls to do_coredump, see signals.c). - */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) -{ - return dump_task_fpu(regs, current, r); -} asmlinkage long xtensa_clone(unsigned long clone_flags, unsigned long newsp, @@ -370,8 +314,8 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, } /* - * * xtensa_execve() executes a new program. - * */ + * xtensa_execve() executes a new program. + */ asmlinkage long xtensa_execve(char __user *name, char __user * __user *argv, @@ -386,7 +330,6 @@ long xtensa_execve(char __user *name, char __user * __user *argv, error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - // FIXME: release coprocessor?? error = do_execve(filename, argv, envp, regs); if (error == 0) { task_lock(current); diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 5533c7850d53..f6669d605125 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -4,7 +4,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001 - 2007 Tensilica Inc. * * Joe Taylor * Chris Zankel @@ -28,14 +28,10 @@ #include #include #include - -#define TEST_KERNEL // verify kernel operations FIXME: remove - +#include /* - * Called by kernel/ptrace.c when detaching.. - * - * Make sure single step bits etc are not set. + * Called by kernel/ptrace.c when detaching to disable single stepping. */ void ptrace_disable(struct task_struct *child) @@ -43,136 +39,233 @@ void ptrace_disable(struct task_struct *child) /* Nothing to do.. */ } -long arch_ptrace(struct task_struct *child, long request, long addr, long data) +int ptrace_getregs(struct task_struct *child, void __user *uregs) { - int ret = -EPERM; + struct pt_regs *regs = task_pt_regs(child); + xtensa_gregset_t __user *gregset = uregs; + unsigned long wb = regs->windowbase; + unsigned long ws = regs->windowstart; + unsigned long wm = regs->wmask; + int ret = 0; + int live, last; + + if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) + return -EIO; + + /* Norm windowstart to a windowbase of 0. */ + + ws = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<pc, &gregset->pc); + ret |= __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps); + ret |= __put_user(regs->lbeg, &gregset->lbeg); + ret |= __put_user(regs->lend, &gregset->lend); + ret |= __put_user(regs->lcount, &gregset->lcount); + ret |= __put_user(ws, &gregset->windowstart); + + live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; + last = XCHAL_NUM_AREGS - (wm >> 4) * 4; + ret |= __copy_to_user(gregset->a, regs->areg, live * 4); + ret |= __copy_to_user(gregset->a + last, regs->areg + last, (wm>>4)*16); + + return ret ? -EFAULT : 0; +} - switch (request) { - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - goto out; +int ptrace_setregs(struct task_struct *child, void __user *uregs) +{ + struct pt_regs *regs = task_pt_regs(child); + xtensa_gregset_t *gregset = uregs; + const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; + unsigned long wm = regs->wmask; + unsigned long ps; + int ret = 0; + int live, last; + + if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) + return -EIO; + + ret |= __get_user(regs->pc, &gregset->pc); + ret |= __get_user(ps, &gregset->ps); + ret |= __get_user(regs->lbeg, &gregset->lbeg); + ret |= __get_user(regs->lend, &gregset->lend); + ret |= __get_user(regs->lcount, &gregset->lcount); + + regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT); + + live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; + last = XCHAL_NUM_AREGS - (wm >> 4) * 4; + ret |= __copy_from_user(regs->areg, gregset->a, live * 4); + ret |= __copy_from_user(regs->areg+last, gregset->a+last, (wm>>4)*16); + + return ret ? -EFAULT : 0; +} - /* Read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: - { - struct pt_regs *regs; - unsigned long tmp; +int ptrace_getxregs(struct task_struct *child, void __user *uregs) +{ + struct pt_regs *regs = task_pt_regs(child); + struct thread_info *ti = task_thread_info(child); + elf_xtregs_t __user *xtregs = uregs; + int ret = 0; + + if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t))) + return -EIO; + +#if XTENSA_HAVE_COPROCESSORS + /* Flush all coprocessor registers to memory. */ + coprocessor_flush_all(ti); + ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp, + sizeof(xtregs_coprocessor_t)); +#endif + ret |= __copy_to_user(&xtregs->opt, ®s->xtregs_opt, + sizeof(xtregs->opt)); + ret |= __copy_to_user(&xtregs->user,&ti->xtregs_user, + sizeof(xtregs->user)); - regs = task_pt_regs(child); - tmp = 0; /* Default return value. */ + return ret ? -EFAULT : 0; +} + +int ptrace_setxregs(struct task_struct *child, void __user *uregs) +{ + struct thread_info *ti = task_thread_info(child); + struct pt_regs *regs = task_pt_regs(child); + elf_xtregs_t *xtregs = uregs; + int ret = 0; + +#if XTENSA_HAVE_COPROCESSORS + /* Flush all coprocessors before we overwrite them. */ + coprocessor_flush_all(ti); + coprocessor_release_all(ti); + + ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, + sizeof(xtregs_coprocessor_t)); +#endif + ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, + sizeof(xtregs->opt)); + ret |= __copy_from_user(&ti->xtregs_user, &xtregs->user, + sizeof(xtregs->user)); + + return ret ? -EFAULT : 0; +} + +int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret) +{ + struct pt_regs *regs; + unsigned long tmp; + + regs = task_pt_regs(child); + tmp = 0; /* Default return value. */ - switch(addr) { + switch(regno) { case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: - { - int ar = addr - REG_AR_BASE - regs->windowbase * 4; - ar &= (XCHAL_NUM_AREGS - 1); - if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0) - tmp = regs->areg[ar]; - else - ret = -EIO; + tmp = regs->areg[regno - REG_AR_BASE]; break; - } + case REG_A_BASE ... REG_A_BASE + 15: - tmp = regs->areg[addr - REG_A_BASE]; + tmp = regs->areg[regno - REG_A_BASE]; break; + case REG_PC: tmp = regs->pc; break; + case REG_PS: /* Note: PS.EXCM is not set while user task is running; * its being set in regs is for exception handling * convenience. */ tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); break; + case REG_WB: - tmp = regs->windowbase; - break; + break; /* tmp = 0 */ + case REG_WS: - tmp = regs->windowstart; + { + unsigned long wb = regs->windowbase; + unsigned long ws = regs->windowstart; + tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<lbeg; break; + case REG_LEND: tmp = regs->lend; break; + case REG_LCOUNT: tmp = regs->lcount; break; + case REG_SAR: tmp = regs->sar; break; - case REG_DEPC: - tmp = regs->depc; - break; - case REG_EXCCAUSE: - tmp = regs->exccause; - break; - case REG_EXCVADDR: - tmp = regs->excvaddr; - break; + case SYSCALL_NR: tmp = regs->syscall; break; - default: - tmp = 0; - ret = -EIO; - goto out; - } - ret = put_user(tmp, (unsigned long *) data); - goto out; - } - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - goto out; + default: + return -EIO; + } + return put_user(tmp, ret); +} - case PTRACE_POKEUSR: - { - struct pt_regs *regs; - regs = task_pt_regs(child); +int ptrace_pokeusr(struct task_struct *child, long regno, long val) +{ + struct pt_regs *regs; + regs = task_pt_regs(child); - switch (addr) { + switch (regno) { case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: - { - int ar = addr - REG_AR_BASE - regs->windowbase * 4; - if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0) - regs->areg[ar & (XCHAL_NUM_AREGS - 1)] = data; - else - ret = -EIO; + regs->areg[regno - REG_AR_BASE] = val; break; - } + case REG_A_BASE ... REG_A_BASE + 15: - regs->areg[addr - REG_A_BASE] = data; + regs->areg[regno - REG_A_BASE] = val; break; + case REG_PC: - regs->pc = data; + regs->pc = val; break; + case SYSCALL_NR: - regs->syscall = data; - break; -#ifdef TEST_KERNEL - case REG_WB: - regs->windowbase = data; + regs->syscall = val; break; - case REG_WS: - regs->windowstart = data; - break; -#endif default: - /* The rest are not allowed. */ - ret = -EIO; - break; - } + return -EIO; + } + return 0; +} + +long arch_ptrace(struct task_struct *child, long request, long addr, long data) +{ + int ret = -EPERM; + + switch (request) { + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: + ret = generic_ptrace_peekdata(child, addr, data); + break; + + case PTRACE_PEEKUSR: /* read register specified by addr. */ + ret = ptrace_peekusr(child, addr, (void __user *) data); + break; + + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + ret = generic_ptrace_pokedata(child, addr, data); + break; + + case PTRACE_POKEUSR: /* write register specified by addr. */ + ret = ptrace_pokeusr(child, addr, data); break; - } /* continue and stop at next (return from) syscall */ + case PTRACE_SYSCALL: case PTRACE_CONT: /* restart after signal. */ { @@ -217,98 +310,26 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_GETREGS: - { - /* 'data' points to user memory in which to write. - * Mainly due to the non-live register values, we - * reformat the register values into something more - * standard. For convenience, we use the handy - * elf_gregset_t format. */ - - xtensa_gregset_t format; - struct pt_regs *regs = task_pt_regs(child); - - do_copy_regs (&format, regs, child); - - /* Now, copy to user space nice and easy... */ - ret = 0; - if (copy_to_user((void *)data, &format, sizeof(elf_gregset_t))) - ret = -EFAULT; + ret = ptrace_getregs(child, (void __user *) data); break; - } case PTRACE_SETREGS: - { - /* 'data' points to user memory that contains the new - * values in the elf_gregset_t format. */ - - xtensa_gregset_t format; - struct pt_regs *regs = task_pt_regs(child); - - if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){ - ret = -EFAULT; - break; - } - - /* FIXME: Perhaps we want some sanity checks on - * these user-space values? See ARM version. Are - * debuggers a security concern? */ - - do_restore_regs (&format, regs, child); - - ret = 0; - break; - } - - case PTRACE_GETFPREGS: - { - /* 'data' points to user memory in which to write. - * For convenience, we use the handy - * elf_fpregset_t format. */ - - elf_fpregset_t fpregs; - struct pt_regs *regs = task_pt_regs(child); - - do_save_fpregs (&fpregs, regs, child); - - /* Now, copy to user space nice and easy... */ - ret = 0; - if (copy_to_user((void *)data, &fpregs, sizeof(elf_fpregset_t))) - ret = -EFAULT; - + ret = ptrace_setregs(child, (void __user *) data); break; - } - - case PTRACE_SETFPREGS: - { - /* 'data' points to user memory that contains the new - * values in the elf_fpregset_t format. - */ - elf_fpregset_t fpregs; - struct pt_regs *regs = task_pt_regs(child); - ret = 0; - if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) { - ret = -EFAULT; - break; - } - - if (do_restore_fpregs (&fpregs, regs, child)) - ret = -EIO; + case PTRACE_GETXTREGS: + ret = ptrace_getxregs(child, (void __user *) data); break; - } - case PTRACE_GETFPREGSIZE: - /* 'data' points to 'unsigned long' set to the size - * of elf_fpregset_t - */ - ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data); + case PTRACE_SETXTREGS: + ret = ptrace_setxregs(child, (void __user *) data); break; default: ret = ptrace_request(child, request, addr, data); - goto out; + break; } - out: + return ret; } diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 42d9fd8a4225..299be42d116b 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -35,13 +35,17 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); extern struct task_struct *coproc_owners[]; -extern void release_all_cp (struct task_struct *); - struct rt_sigframe { struct siginfo info; struct ucontext uc; - cp_state_t cpstate; + struct { + xtregs_opt_t opt; + xtregs_user_t user; +#if XTENSA_HAVE_COPROCESSORS + xtregs_coprocessor_t cp; +#endif + } xtregs; unsigned char retcode[6]; unsigned int window[4]; }; @@ -132,9 +136,10 @@ flush_window_regs_user(struct pt_regs *regs) */ static int -setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate, - struct pt_regs *regs) +setup_sigcontext(struct rt_sigframe __user *frame, struct pt_regs *regs) { + struct sigcontext __user *sc = &frame->uc.uc_mcontext; + struct thread_info *ti = current_thread_info(); int err = 0; #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) @@ -148,21 +153,32 @@ setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate, err |= flush_window_regs_user(regs); err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4); + err |= __put_user(0, &sc->sc_xtregs); - // err |= __copy_to_user (sc->sc_a, regs->areg, XCHAL_NUM_AREGS * 4) + if (err) + return err; -#if XCHAL_HAVE_CP -# error Coprocessors unsupported - err |= save_cpextra(cpstate); - err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); +#if XTENSA_HAVE_COPROCESSORS + coprocessor_flush_all(ti); + coprocessor_release_all(ti); + err |= __copy_to_user(&frame->xtregs.cp, &ti->xtregs_cp, + sizeof (frame->xtregs.cp)); #endif + err |= __copy_to_user(&frame->xtregs.opt, ®s->xtregs_opt, + sizeof (xtregs_opt_t)); + err |= __copy_to_user(&frame->xtregs.user, &ti->xtregs_user, + sizeof (xtregs_user_t)); + + err |= __put_user(err ? NULL : &frame->xtregs, &sc->sc_xtregs); return err; } static int -restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) +restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame) { + struct sigcontext __user *sc = &frame->uc.uc_mcontext; + struct thread_info *ti = current_thread_info(); unsigned int err = 0; unsigned long ps; @@ -180,6 +196,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) regs->windowbase = 0; regs->windowstart = 1; + regs->syscall = -1; /* disable syscall checks */ + /* For PS, restore only PS.CALLINC. * Assume that all other bits are either the same as for the signal * handler, or the user mode value doesn't matter (e.g. PS.OWB). @@ -195,8 +213,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4); -#if XCHAL_HAVE_CP -# error Coprocessors unsupported + if (err) + return err; + /* The signal handler may have used coprocessors in which * case they are still enabled. We disable them to force a * reloading of the original task's CP state by the lazy @@ -204,20 +223,20 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) * Also, we essentially discard any coprocessor state that the * signal handler created. */ - if (!err) { - struct task_struct *tsk = current; - release_all_cp(tsk); - err |= __copy_from_user(tsk->thread.cpextra, sc->sc_cpstate, - XTENSA_CP_EXTRA_SIZE); - } +#if XTENSA_HAVE_COPROCESSORS + coprocessor_release_all(ti); + err |= __copy_from_user(&ti->xtregs_cp, &frame->xtregs.cp, + sizeof (frame->xtregs.cp)); #endif + err |= __copy_from_user(&ti->xtregs_user, &frame->xtregs.user, + sizeof (xtregs_user_t)); + err |= __copy_from_user(®s->xtregs_opt, &frame->xtregs.opt, + sizeof (xtregs_opt_t)); - regs->syscall = -1; /* disable syscall checks */ return err; } - /* * Do a signal return; undo the signal stack. */ @@ -246,7 +265,7 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) + if (restore_sigcontext(regs, frame)) goto badframe; ret = regs->areg[2]; @@ -359,7 +378,7 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(sas_ss_flags(regs->areg[1]), &frame->uc.uc_stack.ss_flags); err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate, regs); + err |= setup_sigcontext(frame, regs); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); /* Create sys_rt_sigreturn syscall in stack frame */ diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 6f722f91ba92..c7a021d9f696 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -118,28 +118,28 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = { { EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault }, { EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault }, /* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */ -#if (XCHAL_CP_MASK & 1) +#if XTENSA_HAVE_COPROCESSOR(0) COPROCESSOR(0), #endif -#if (XCHAL_CP_MASK & 2) +#if XTENSA_HAVE_COPROCESSOR(1) COPROCESSOR(1), #endif -#if (XCHAL_CP_MASK & 4) +#if XTENSA_HAVE_COPROCESSOR(2) COPROCESSOR(2), #endif -#if (XCHAL_CP_MASK & 8) +#if XTENSA_HAVE_COPROCESSOR(3) COPROCESSOR(3), #endif -#if (XCHAL_CP_MASK & 16) +#if XTENSA_HAVE_COPROCESSOR(4) COPROCESSOR(4), #endif -#if (XCHAL_CP_MASK & 32) +#if XTENSA_HAVE_COPROCESSOR(5) COPROCESSOR(5), #endif -#if (XCHAL_CP_MASK & 64) +#if XTENSA_HAVE_COPROCESSOR(6) COPROCESSOR(6), #endif -#if (XCHAL_CP_MASK & 128) +#if XTENSA_HAVE_COPROCESSOR(7) COPROCESSOR(7), #endif { EXCCAUSE_MAPPED_DEBUG, 0, do_debug }, diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h index aa2121034558..e5849bb9f6cf 100644 --- a/include/asm-xtensa/coprocessor.h +++ b/include/asm-xtensa/coprocessor.h @@ -5,81 +5,168 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003 - 2005 Tensilica Inc. + * Copyright (C) 2003 - 2007 Tensilica Inc. */ + #ifndef _XTENSA_COPROCESSOR_H #define _XTENSA_COPROCESSOR_H -#include +#include #include +#include + +#ifdef __ASSEMBLY__ +# include + +.macro xchal_sa_start a b + .set .Lxchal_pofs_, 0 + .set .Lxchal_ofs_, 0 +.endm + +.macro xchal_sa_align ptr minofs maxofs ofsalign totalign + .set .Lxchal_ofs_, .Lxchal_ofs_ + .Lxchal_pofs_ + \totalign - 1 + .set .Lxchal_ofs_, (.Lxchal_ofs_ & -\totalign) - .Lxchal_pofs_ +.endm + +#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \ + | XTHAL_SAS_CC \ + | XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB ) + +.macro save_xtregs_opt ptr clb at1 at2 at3 at4 offset + .if XTREGS_OPT_SIZE > 0 + addi \clb, \ptr, \offset + xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT + .endif +.endm + +.macro load_xtregs_opt ptr clb at1 at2 at3 at4 offset + .if XTREGS_OPT_SIZE > 0 + addi \clb, \ptr, \offset + xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT + .endif +.endm +#undef _SELECT + +#define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \ + | XTHAL_SAS_NOCC \ + | XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB ) + +.macro save_xtregs_user ptr clb at1 at2 at3 at4 offset + .if XTREGS_USER_SIZE > 0 + addi \clb, \ptr, \offset + xchal_ncp_store \clb \at1 \at2 \at3 \at4 select=_SELECT + .endif +.endm + +.macro load_xtregs_user ptr clb at1 at2 at3 at4 offset + .if XTREGS_USER_SIZE > 0 + addi \clb, \ptr, \offset + xchal_ncp_load \clb \at1 \at2 \at3 \at4 select=_SELECT + .endif +.endm +#undef _SELECT + + + +#endif /* __ASSEMBLY__ */ -#if !XCHAL_HAVE_CP - -#define XTENSA_CP_EXTRA_OFFSET 0 -#define XTENSA_CP_EXTRA_ALIGN 1 /* must be a power of 2 */ -#define XTENSA_CP_EXTRA_SIZE 0 - -#else - -#define XTOFS(last_start,last_size,align) \ - ((last_start+last_size+align-1) & -align) - -#define XTENSA_CP_EXTRA_OFFSET 0 -#define XTENSA_CP_EXTRA_ALIGN XCHAL_EXTRA_SA_ALIGN - -#define XTENSA_CPE_CP0_OFFSET \ - XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN) -#define XTENSA_CPE_CP1_OFFSET \ - XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN) -#define XTENSA_CPE_CP2_OFFSET \ - XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN) -#define XTENSA_CPE_CP3_OFFSET \ - XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN) -#define XTENSA_CPE_CP4_OFFSET \ - XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN) -#define XTENSA_CPE_CP5_OFFSET \ - XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN) -#define XTENSA_CPE_CP6_OFFSET \ - XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN) -#define XTENSA_CPE_CP7_OFFSET \ - XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN) -#define XTENSA_CP_EXTRA_SIZE \ - XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16) - -#if XCHAL_CP_NUM > 0 -# ifndef __ASSEMBLY__ /* - * Tasks that own contents of (last user) each coprocessor. - * Entries are 0 for not-owned or non-existent coprocessors. - * Note: The size of this structure is fixed to 8 bytes in entry.S + * XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured. + * + * XTENSA_HAVE_IO_PORT(x) returns 1 if io-port x is configured. + * */ -typedef struct { - struct task_struct *owner; /* owner */ - int offset; /* offset in cpextra space. */ -} coprocessor_info_t; -# else -# define COPROCESSOR_INFO_OWNER 0 -# define COPROCESSOR_INFO_OFFSET 4 -# define COPROCESSOR_INFO_SIZE 8 -# endif -#endif -#endif /* XCHAL_HAVE_CP */ +#define XTENSA_HAVE_COPROCESSOR(x) \ + ((XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK) & (1 << (x))) +#define XTENSA_HAVE_COPROCESSORS \ + (XCHAL_CP_MASK ^ XCHAL_CP_PORT_MASK) +#define XTENSA_HAVE_IO_PORT(x) \ + (XCHAL_CP_PORT_MASK & (1 << (x))) +#define XTENSA_HAVE_IO_PORTS \ + XCHAL_CP_PORT_MASK #ifndef __ASSEMBLY__ -# if XCHAL_CP_NUM > 0 -struct task_struct; -extern void release_coprocessors (struct task_struct*); -extern void save_coprocessor_registers(void*, int); -# else -# define release_coprocessors(task) -# endif -typedef unsigned char cp_state_t[XTENSA_CP_EXTRA_SIZE] - __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN))); -#endif /* !__ASSEMBLY__ */ +#if XCHAL_HAVE_CP +#define RSR_CPENABLE(x) do { \ + __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \ + } while(0); +#define WSR_CPENABLE(x) do { \ + __asm__ __volatile__("wsr %0," __stringify(CPENABLE) "; rsync" \ + :: "a" (x)); \ + } while(0); +#endif /* XCHAL_HAVE_CP */ + + +/* + * Additional registers. + * We define three types of additional registers: + * ext: extra registers that are used by the compiler + * cpn: optional registers that can be used by a user application + * cpX: coprocessor registers that can only be used if the corresponding + * CPENABLE bit is set. + */ + +#define XCHAL_SA_REG(list,compiler,x,type,y,name,z,align,size,...) \ + __REG ## list (compiler, type, name, size, align) + +#define __REG0(compiler,t,name,s,a) __REG0_ ## compiler (name) +#define __REG1(compiler,t,name,s,a) __REG1_ ## compiler (name) +#define __REG2(c,type,...) __REG2_ ## type (__VA_ARGS__) + +#define __REG0_0(name) +#define __REG0_1(name) __u32 name; +#define __REG1_0(name) __u32 name; +#define __REG1_1(name) +#define __REG2_0(n,s,a) __u32 name; +#define __REG2_1(n,s,a) unsigned char n[s] __attribute__ ((aligned(a))); +#define __REG2_2(n,s,a) unsigned char n[s] __attribute__ ((aligned(a))); + +typedef struct { XCHAL_NCP_SA_LIST(0) } xtregs_opt_t + __attribute__ ((aligned (XCHAL_NCP_SA_ALIGN))); +typedef struct { XCHAL_NCP_SA_LIST(1) } xtregs_user_t + __attribute__ ((aligned (XCHAL_NCP_SA_ALIGN))); + +#if XTENSA_HAVE_COPROCESSORS + +typedef struct { XCHAL_CP0_SA_LIST(2) } xtregs_cp0_t + __attribute__ ((aligned (XCHAL_CP0_SA_ALIGN))); +typedef struct { XCHAL_CP1_SA_LIST(2) } xtregs_cp1_t + __attribute__ ((aligned (XCHAL_CP1_SA_ALIGN))); +typedef struct { XCHAL_CP2_SA_LIST(2) } xtregs_cp2_t + __attribute__ ((aligned (XCHAL_CP2_SA_ALIGN))); +typedef struct { XCHAL_CP3_SA_LIST(2) } xtregs_cp3_t + __attribute__ ((aligned (XCHAL_CP3_SA_ALIGN))); +typedef struct { XCHAL_CP4_SA_LIST(2) } xtregs_cp4_t + __attribute__ ((aligned (XCHAL_CP4_SA_ALIGN))); +typedef struct { XCHAL_CP5_SA_LIST(2) } xtregs_cp5_t + __attribute__ ((aligned (XCHAL_CP5_SA_ALIGN))); +typedef struct { XCHAL_CP6_SA_LIST(2) } xtregs_cp6_t + __attribute__ ((aligned (XCHAL_CP6_SA_ALIGN))); +typedef struct { XCHAL_CP7_SA_LIST(2) } xtregs_cp7_t + __attribute__ ((aligned (XCHAL_CP7_SA_ALIGN))); + +extern struct thread_info* coprocessor_owner[XCHAL_CP_MAX]; +extern void coprocessor_save(void*, int); +extern void coprocessor_load(void*, int); +extern void coprocessor_flush(struct thread_info*, int); +extern void coprocessor_restore(struct thread_info*, int); + +extern void coprocessor_release_all(struct thread_info*); +extern void coprocessor_flush_all(struct thread_info*); + +static inline void coprocessor_clear_cpenable(void) +{ + unsigned long i = 0; + WSR_CPENABLE(i); +} + +#endif /* XTENSA_HAVE_COPROCESSORS */ + +#endif /* !__ASSEMBLY__ */ #endif /* _XTENSA_COPROCESSOR_H */ diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h index 86479b86c02e..11103e07d028 100644 --- a/include/asm-xtensa/elf.h +++ b/include/asm-xtensa/elf.h @@ -173,6 +173,21 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *); _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ } while (0) +typedef struct { + xtregs_opt_t opt; + xtregs_user_t user; +#if XTENSA_HAVE_COPROCESSORS + xtregs_cp0_t cp0; + xtregs_cp1_t cp1; + xtregs_cp2_t cp2; + xtregs_cp3_t cp3; + xtregs_cp4_t cp4; + xtregs_cp5_t cp5; + xtregs_cp6_t cp6; + xtregs_cp7_t cp7; +#endif +} elf_xtregs_t; + #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) struct task_struct; diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h index 96408f436624..4918a4e96d42 100644 --- a/include/asm-xtensa/processor.h +++ b/include/asm-xtensa/processor.h @@ -103,10 +103,6 @@ struct thread_struct { unsigned long dbreaka[XCHAL_NUM_DBREAK]; unsigned long dbreakc[XCHAL_NUM_DBREAK]; - /* Allocate storage for extra state and coprocessor state. */ - unsigned char cp_save[XTENSA_CP_EXTRA_SIZE] - __attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN))); - /* Make structure 16 bytes aligned. */ int align[0] __attribute__ ((aligned(16))); }; @@ -162,21 +158,16 @@ struct thread_struct { struct task_struct; struct mm_struct; -// FIXME: do we need release_thread for CP?? /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) -// FIXME: do we need prepare_to_copy (lazy status) for CP?? /* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) +extern void prepare_to_copy(struct task_struct*); -/* - * create a kernel thread without removing it from tasklists - */ +/* Create a kernel thread without removing it from tasklists */ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); /* Copy and release all segment info associated with a VM */ - #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) #define forget_segments() do { } while (0) diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h index 77ff02d307bb..422c73e26937 100644 --- a/include/asm-xtensa/ptrace.h +++ b/include/asm-xtensa/ptrace.h @@ -53,33 +53,30 @@ /* Registers used by strace */ -#define REG_A_BASE 0xfc000000 -#define REG_AR_BASE 0x04000000 -#define REG_PC 0x14000000 -#define REG_PS 0x080000e6 -#define REG_WB 0x08000048 -#define REG_WS 0x08000049 -#define REG_LBEG 0x08000000 -#define REG_LEND 0x08000001 -#define REG_LCOUNT 0x08000002 -#define REG_SAR 0x08000003 -#define REG_DEPC 0x080000c0 -#define REG_EXCCAUSE 0x080000e8 -#define REG_EXCVADDR 0x080000ee -#define SYSCALL_NR 0x1 - -#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1) +#define REG_A_BASE 0x0000 +#define REG_AR_BASE 0x0100 +#define REG_PC 0x0020 +#define REG_PS 0x02e6 +#define REG_WB 0x0248 +#define REG_WS 0x0249 +#define REG_LBEG 0x0200 +#define REG_LEND 0x0201 +#define REG_LCOUNT 0x0202 +#define REG_SAR 0x0203 + +#define SYSCALL_NR 0x00ff /* Other PTRACE_ values defined in using values 0-9,16,17,24 */ -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 -#define PTRACE_GETFPREGS 14 -#define PTRACE_SETFPREGS 15 -#define PTRACE_GETFPREGSIZE 18 +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETXTREGS 18 +#define PTRACE_SETXTREGS 19 #ifndef __ASSEMBLY__ +#ifdef __KERNEL__ + /* * This struct defines the way the registers are stored on the * kernel stack during a system call or other kernel entry. @@ -102,6 +99,9 @@ struct pt_regs { unsigned long icountlevel; /* 60 */ int reserved[1]; /* 64 */ + /* Additional configurable registers that are used by the compiler. */ + xtregs_opt_t xtregs_opt; + /* Make sure the areg field is 16 bytes aligned. */ int align[0] __attribute__ ((aligned(16))); @@ -111,8 +111,6 @@ struct pt_regs { unsigned long areg[16]; /* 128 (64) */ }; -#ifdef __KERNEL__ - #include # define task_pt_regs(tsk) ((struct pt_regs*) \ diff --git a/include/asm-xtensa/regs.h b/include/asm-xtensa/regs.h index c913d259faaa..d4baed246928 100644 --- a/include/asm-xtensa/regs.h +++ b/include/asm-xtensa/regs.h @@ -100,7 +100,14 @@ #define EXCCAUSE_DTLB_SIZE_RESTRICTION 27 #define EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28 #define EXCCAUSE_STORE_CACHE_ATTRIBUTE 29 -#define EXCCAUSE_FLOATING_POINT 40 +#define EXCCAUSE_COPROCESSOR0_DISABLED 32 +#define EXCCAUSE_COPROCESSOR1_DISABLED 33 +#define EXCCAUSE_COPROCESSOR2_DISABLED 34 +#define EXCCAUSE_COPROCESSOR3_DISABLED 35 +#define EXCCAUSE_COPROCESSOR4_DISABLED 36 +#define EXCCAUSE_COPROCESSOR5_DISABLED 37 +#define EXCCAUSE_COPROCESSOR6_DISABLED 38 +#define EXCCAUSE_COPROCESSOR7_DISABLED 39 /* PS register fields. */ diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h index dff3c54a3c12..03383af8c3b7 100644 --- a/include/asm-xtensa/sigcontext.h +++ b/include/asm-xtensa/sigcontext.h @@ -22,6 +22,7 @@ struct sigcontext { unsigned long sc_acclo; unsigned long sc_acchi; unsigned long sc_a[16]; + void *sc_xtregs; }; #endif /* _XTENSA_SIGCONTEXT_H */ diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h index e0cb9116d8ab..62b1e8f3c13c 100644 --- a/include/asm-xtensa/system.h +++ b/include/asm-xtensa/system.h @@ -46,42 +46,6 @@ static inline int irqs_disabled(void) return flags & 0xf; } -#define RSR_CPENABLE(x) do { \ - __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \ - } while(0); -#define WSR_CPENABLE(x) do { \ - __asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" \ - :: "a" (x));} while(0); - -#define clear_cpenable() __clear_cpenable() - -static inline void __clear_cpenable(void) -{ -#if XCHAL_HAVE_CP - unsigned long i = 0; - WSR_CPENABLE(i); -#endif -} - -static inline void enable_coprocessor(int i) -{ -#if XCHAL_HAVE_CP - int cp; - RSR_CPENABLE(cp); - cp |= 1 << i; - WSR_CPENABLE(cp); -#endif -} - -static inline void disable_coprocessor(int i) -{ -#if XCHAL_HAVE_CP - int cp; - RSR_CPENABLE(cp); - cp &= ~(1 << i); - WSR_CPENABLE(cp); -#endif -} #define smp_read_barrier_depends() do { } while(0) #define read_barrier_depends() do { } while(0) @@ -111,7 +75,6 @@ extern void *_switch_to(void *last, void *next); #define switch_to(prev,next,last) \ do { \ - clear_cpenable(); \ (last) = _switch_to(prev, next); \ } while(0) @@ -244,7 +207,7 @@ static inline void spill_registers(void) "wsr a13," __stringify(SAR) "\n\t" "wsr a14," __stringify(PS) "\n\t" :: "a" (&a0), "a" (&ps) - : "a2", "a3", "a12", "a13", "a14", "a15", "memory"); + : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory"); } #define arch_align_stack(x) (x) diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h index 52c958285bcb..a2c640682ed9 100644 --- a/include/asm-xtensa/thread_info.h +++ b/include/asm-xtensa/thread_info.h @@ -27,6 +27,21 @@ #ifndef __ASSEMBLY__ +#if XTENSA_HAVE_COPROCESSORS + +typedef struct xtregs_coprocessor { + xtregs_cp0_t cp0; + xtregs_cp1_t cp1; + xtregs_cp2_t cp2; + xtregs_cp3_t cp3; + xtregs_cp4_t cp4; + xtregs_cp5_t cp5; + xtregs_cp6_t cp6; + xtregs_cp7_t cp7; +} xtregs_coprocessor_t; + +#endif + struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ @@ -38,7 +53,13 @@ struct thread_info { mm_segment_t addr_limit; /* thread address space */ struct restart_block restart_block; + unsigned long cpenable; + /* Allocate storage for extra user states and coprocessor states. */ +#if XTENSA_HAVE_COPROCESSORS + xtregs_coprocessor_t xtregs_cp; +#endif + xtregs_user_t xtregs_user; }; #else /* !__ASSEMBLY__ */ diff --git a/include/asm-xtensa/variant-fsf/tie-asm.h b/include/asm-xtensa/variant-fsf/tie-asm.h new file mode 100644 index 000000000000..68a73bf4ffc5 --- /dev/null +++ b/include/asm-xtensa/variant-fsf/tie-asm.h @@ -0,0 +1,70 @@ +/* + * This header file contains assembly-language definitions (assembly + * macros, etc.) for this specific Xtensa processor's TIE extensions + * and options. It is customized to this Xtensa processor configuration. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999-2008 Tensilica Inc. + */ + +#ifndef _XTENSA_CORE_TIE_ASM_H +#define _XTENSA_CORE_TIE_ASM_H + +/* Selection parameter values for save-area save/restore macros: */ +/* Option vs. TIE: */ +#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ +#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ +/* Whether used automatically by compiler: */ +#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ +#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ +/* ABI handling across function calls: */ +#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ +#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ +#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ +/* Misc */ +#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ + + + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (1 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + rur \at1, THREADPTR // threadptr option + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .endm // xchal_ncp_store + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (1 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + wur \at1, THREADPTR // threadptr option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .endm // xchal_ncp_load + + + +#define XCHAL_NCP_NUM_ATMPS 1 + + +#define XCHAL_SA_NUM_ATMPS 1 + +#endif /*_XTENSA_CORE_TIE_ASM_H*/ + diff --git a/include/asm-xtensa/variant-fsf/tie.h b/include/asm-xtensa/variant-fsf/tie.h index a73c71664918..bf4020116df5 100644 --- a/include/asm-xtensa/variant-fsf/tie.h +++ b/include/asm-xtensa/variant-fsf/tie.h @@ -1,22 +1,77 @@ /* - * Xtensa processor core configuration information. + * This header file describes this specific Xtensa processor's TIE extensions + * that extend basic Xtensa core functionality. It is customized to this + * Xtensa processor configuration. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1999-2006 Tensilica Inc. + * Copyright (C) 1999-2007 Tensilica Inc. */ -#ifndef XTENSA_TIE_H -#define XTENSA_TIE_H - -/*---------------------------------------------------------------------- - COPROCESSORS and EXTRA STATE - ----------------------------------------------------------------------*/ +#ifndef _XTENSA_CORE_TIE_H +#define _XTENSA_CORE_TIE_H #define XCHAL_CP_NUM 0 /* number of coprocessors */ -#define XCHAL_CP_MASK 0x00 +#define XCHAL_CP_MAX 0 /* max CP ID + 1 (0 if none) */ +#define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */ +#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ + +/* Basic parameters of each coprocessor: */ +#define XCHAL_CP7_NAME "XTIOP" +#define XCHAL_CP7_IDENT XTIOP +#define XCHAL_CP7_SA_SIZE 0 /* size of state save area */ +#define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */ +#define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */ + +/* Filler info for unassigned coprocessors, to simplify arrays etc: */ +#define XCHAL_NCP_SA_SIZE 0 +#define XCHAL_NCP_SA_ALIGN 1 +#define XCHAL_CP0_SA_SIZE 0 +#define XCHAL_CP0_SA_ALIGN 1 +#define XCHAL_CP1_SA_SIZE 0 +#define XCHAL_CP1_SA_ALIGN 1 +#define XCHAL_CP2_SA_SIZE 0 +#define XCHAL_CP2_SA_ALIGN 1 +#define XCHAL_CP3_SA_SIZE 0 +#define XCHAL_CP3_SA_ALIGN 1 +#define XCHAL_CP4_SA_SIZE 0 +#define XCHAL_CP4_SA_ALIGN 1 +#define XCHAL_CP5_SA_SIZE 0 +#define XCHAL_CP5_SA_ALIGN 1 +#define XCHAL_CP6_SA_SIZE 0 +#define XCHAL_CP6_SA_ALIGN 1 + +/* Save area for non-coprocessor optional and custom (TIE) state: */ +#define XCHAL_NCP_SA_SIZE 0 +#define XCHAL_NCP_SA_ALIGN 1 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 0 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 1 /* actual minimum alignment */ + +#define XCHAL_NCP_SA_NUM 0 +#define XCHAL_NCP_SA_LIST(s) +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) +#define XCHAL_CP1_SA_NUM 0 +#define XCHAL_CP1_SA_LIST(s) +#define XCHAL_CP2_SA_NUM 0 +#define XCHAL_CP2_SA_LIST(s) +#define XCHAL_CP3_SA_NUM 0 +#define XCHAL_CP3_SA_LIST(s) +#define XCHAL_CP4_SA_NUM 0 +#define XCHAL_CP4_SA_LIST(s) +#define XCHAL_CP5_SA_NUM 0 +#define XCHAL_CP5_SA_LIST(s) +#define XCHAL_CP6_SA_NUM 0 +#define XCHAL_CP6_SA_LIST(s) +#define XCHAL_CP7_SA_NUM 0 +#define XCHAL_CP7_SA_LIST(s) + +/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ +#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3 -#endif /*XTENSA_CONFIG_TIE_H*/ +#endif /*_XTENSA_CORE_TIE_H*/ From 44c64e6b15ceab6a4927f54e1081a74ba096b95a Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Fri, 11 Jan 2008 11:44:17 -0800 Subject: [PATCH 075/880] [XTENSA] Add support for the sa_restorer function Supporting the sa_restorer function allows for better security since the sigreturn system call doesn't need to be placed on the stack, so the stack doesn't need to be executable. This requires support from the c-library as it has to provide the restorer function. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/signal.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 299be42d116b..f2220b5bdce6 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -381,14 +381,19 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= setup_sigcontext(frame, regs); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - /* Create sys_rt_sigreturn syscall in stack frame */ + if (ka->sa.sa_flags & SA_RESTORER) { + ra = (unsigned long)ka->sa.sa_restorer; + } else { - err |= gen_return_code(frame->retcode); + /* Create sys_rt_sigreturn syscall in stack frame */ - if (err) { - goto give_sigsegv; + err |= gen_return_code(frame->retcode); + + if (err) { + goto give_sigsegv; + } + ra = (unsigned long) frame->retcode; } - /* * Create signal handler execution context. @@ -402,7 +407,6 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up a stack frame for a call4 * Note: PS.CALLINC is set to one by start_thread */ - ra = (unsigned long) frame->retcode; regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000; regs->areg[6] = (unsigned long) signal; regs->areg[7] = (unsigned long) &frame->info; From 679262578ba975037901556b2ddc6b17a77cf671 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 15 Jan 2008 09:49:18 -0800 Subject: [PATCH 076/880] [XTENSA] Exclude thread-global registers from the xtregs structures. Signed-off-by: Chris Zankel --- include/asm-xtensa/coprocessor.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h index e5849bb9f6cf..1cbcf9001a41 100644 --- a/include/asm-xtensa/coprocessor.h +++ b/include/asm-xtensa/coprocessor.h @@ -31,7 +31,7 @@ #define _SELECT ( XTHAL_SAS_TIE | XTHAL_SAS_OPT \ | XTHAL_SAS_CC \ - | XTHAL_SAS_CALR | XTHAL_SAS_CALE | XTHAL_SAS_GLOB ) + | XTHAL_SAS_CALR | XTHAL_SAS_CALE ) .macro save_xtregs_opt ptr clb at1 at2 at3 at4 offset .if XTREGS_OPT_SIZE > 0 @@ -112,17 +112,22 @@ * CPENABLE bit is set. */ -#define XCHAL_SA_REG(list,compiler,x,type,y,name,z,align,size,...) \ - __REG ## list (compiler, type, name, size, align) +#define XCHAL_SA_REG(list,cc,abi,type,y,name,z,align,size,...) \ + __REG ## list (cc, abi, type, name, size, align) + +#define __REG0(cc,abi,t,name,s,a) __REG0_ ## cc (abi,name) +#define __REG1(cc,abi,t,name,s,a) __REG1_ ## cc (name) +#define __REG2(cc,abi,type,...) __REG2_ ## type (__VA_ARGS__) -#define __REG0(compiler,t,name,s,a) __REG0_ ## compiler (name) -#define __REG1(compiler,t,name,s,a) __REG1_ ## compiler (name) -#define __REG2(c,type,...) __REG2_ ## type (__VA_ARGS__) +#define __REG0_0(abi,name) +#define __REG0_1(abi,name) __REG0_1 ## abi (name) +#define __REG0_10(name) __u32 name; +#define __REG0_11(name) __u32 name; +#define __REG0_12(name) -#define __REG0_0(name) -#define __REG0_1(name) __u32 name; #define __REG1_0(name) __u32 name; #define __REG1_1(name) + #define __REG2_0(n,s,a) __u32 name; #define __REG2_1(n,s,a) unsigned char n[s] __attribute__ ((aligned(a))); #define __REG2_2(n,s,a) unsigned char n[s] __attribute__ ((aligned(a))); From 9f8fcf38e8928cccf8c7b32668d146e457f2ccf2 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Fri, 18 Jan 2008 16:15:29 -0800 Subject: [PATCH 077/880] [XTENSA] Fix cache flush macro for D$/I$ aliasing/non-aliasing For configurations that have aliasing in the data cache but not in the instruction cache, we don't need to flush the instruction cache. Thus, we didn't define the macros to flush the instruction cache. Some cache-flush functions, howerver, were using those macros. Signed-off-by: Chris Zankel --- include/asm-xtensa/cacheflush.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h index b773c57e75a5..94c4c53a099e 100644 --- a/include/asm-xtensa/cacheflush.h +++ b/include/asm-xtensa/cacheflush.h @@ -70,6 +70,8 @@ extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long); #endif #if (ICACHE_WAY_SIZE > PAGE_SIZE) extern void __invalidate_icache_page_alias(unsigned long, unsigned long); +#else +# define __invalidate_icache_page_alias(v,p) do { } while(0) #endif /* From e1088430626b2ec4cd64f2fb7d9fd7c6df5d5824 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 22 Jan 2008 00:45:25 -0800 Subject: [PATCH 078/880] [XTENSA] Fix register corruption for certain processor configurations For processor configurations that have optional registers (compiler-used but non-coprocessor), user space registers might get corrupted when there are only 4 registers in the current window-frame, ie. register a4 belongs to the oldest frame in the register file. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/entry.S | 44 +++++++++++++------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 24770b6a5e4c..dfd35dcc1cb5 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -395,55 +395,49 @@ common_exception_return: /* Jump if we are returning from kernel exceptions. */ 1: l32i a3, a1, PT_PS - _bbsi.l a3, PS_UM_BIT, 2f - j kernel_exception_exit + _bbci.l a3, PS_UM_BIT, 4f /* Specific to a user exception exit: * We need to check some flags for signal handling and rescheduling, * and have to restore WB and WS, extra states, and all registers * in the register file that were in use in the user task. - */ - -2: wsr a3, PS /* disable interrupts */ - - /* Check for signals (keep interrupts disabled while we read TI_FLAGS) - * Note: PS.INTLEVEL = 0, PS.EXCM = 1 + * Note that we don't disable interrupts here. */ GET_THREAD_INFO(a2,a1) l32i a4, a2, TI_FLAGS - /* Enable interrupts again. - * Note: When we get here, we certainly have handled any interrupts. - * (Hint: There is only one user exception frame on stack) - */ - - movi a3, 1 << PS_WOE_BIT - _bbsi.l a4, TIF_NEED_RESCHED, 3f _bbci.l a4, TIF_SIGPENDING, 4f l32i a4, a1, PT_DEPC bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f - /* Reenable interrupts and call do_signal() */ - wsr a3, PS + /* Call do_signal() */ + movi a4, do_signal # int do_signal(struct pt_regs*, sigset_t*) mov a6, a1 movi a7, 0 callx4 a4 j 1b -3: /* Reenable interrupts and reschedule */ +3: /* Reschedule */ - wsr a3, PS movi a4, schedule # void schedule (void) callx4 a4 j 1b - /* Restore the state of the task and return from the exception. */ +4: /* Restore optional registers. */ + + load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT -4: /* a2 holds GET_CURRENT(a2,a1) */ + wsr a3, PS /* disable interrupts */ + + _bbci.l a3, PS_UM_BIT, kernel_exception_exit + +user_exception_exit: + + /* Restore the state of the task and return from the exception. */ /* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */ @@ -509,10 +503,6 @@ common_exception_return: kernel_exception_exit: - /* Disable interrupts (a3 holds PT_PS) */ - - wsr a3, PS - #ifdef PREEMPTIBLE_KERNEL #ifdef CONFIG_PREEMPT @@ -591,10 +581,6 @@ kernel_exception_exit: common_exception_exit: - /* Restore optional registers. */ - - load_xtregs_opt a1 a3 a4 a5 a6 a7 PT_XTREGS_OPT - /* Restore address registers. */ _bbsi.l a2, 1, 1f From bdd362ff4ff8dc0c697ce87dbb337f3b7341fc46 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Fri, 1 Feb 2008 16:56:32 -0800 Subject: [PATCH 079/880] [XTENSA] Fix makefile to work with binutils-2.18. When building with binutils-2.18, vmlinux includes .note.gnu.build-id sections that need to be stripped out when building the binary image. The old .xt.insn sections haven't been used for a long time, so don't bother stripping them. Signed-off-by: Bob Wilson Signed-off-by: Chris Zankel --- arch/xtensa/boot/boot-elf/Makefile | 4 ++-- arch/xtensa/boot/boot-redboot/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index 9cf50ef465c1..08e8814f8c71 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -21,7 +21,7 @@ boot-y := bootstrap.o OBJS := $(addprefix $(obj)/,$(boot-y)) Image: vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds - $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ + $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ vmlinux vmlinux.tmp $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ --add-section image=vmlinux.tmp \ @@ -33,7 +33,7 @@ Image: vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds rm -f $@.tmp vmlinux.tmp Image.initrd: vmlinux $(OBJS) - $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ + $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ --add-section .initrd=arch/$(ARCH)/boot/ramdisk \ --set-section-flags .initrd=contents,alloc,load,load,data \ vmlinux vmlinux.tmp diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index 74d15d08077b..872029b84435 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile @@ -22,7 +22,7 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) zImage: vmlinux $(OBJS) $(LIBS) - $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ + $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ vmlinux vmlinux.tmp gzip -vf9 vmlinux.tmp $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ From 42086cec3263b8c015ca3faa01e8190f0e3ff445 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Mon, 28 Jan 2008 15:55:01 -0800 Subject: [PATCH 080/880] [XTENSA] Allow debugger to modify the WINDOWBASE register. For the 'return' command, GDB needs to adjust WINDOWBASE. In case WB is different from 0, we need to rotate the window register file and update WINDOWSTART and WMASK. This patch also removes some ret|= statements for __get_user/__put_user as the address range was alrady checked a couple of lines earlier. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/ptrace.c | 66 ++++++++++++++++++++----------------- include/asm-xtensa/elf.h | 3 +- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index f6669d605125..9486882ef0af 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -43,32 +43,29 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs) { struct pt_regs *regs = task_pt_regs(child); xtensa_gregset_t __user *gregset = uregs; - unsigned long wb = regs->windowbase; - unsigned long ws = regs->windowstart; unsigned long wm = regs->wmask; - int ret = 0; - int live, last; + unsigned long wb = regs->windowbase; + int live, i; if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) return -EIO; - /* Norm windowstart to a windowbase of 0. */ - - ws = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<pc, &gregset->pc); - ret |= __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps); - ret |= __put_user(regs->lbeg, &gregset->lbeg); - ret |= __put_user(regs->lend, &gregset->lend); - ret |= __put_user(regs->lcount, &gregset->lcount); - ret |= __put_user(ws, &gregset->windowstart); + __put_user(regs->pc, &gregset->pc); + __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps); + __put_user(regs->lbeg, &gregset->lbeg); + __put_user(regs->lend, &gregset->lend); + __put_user(regs->lcount, &gregset->lcount); + __put_user(regs->windowstart, &gregset->windowstart); + __put_user(regs->windowbase, &gregset->windowbase); live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; - last = XCHAL_NUM_AREGS - (wm >> 4) * 4; - ret |= __copy_to_user(gregset->a, regs->areg, live * 4); - ret |= __copy_to_user(gregset->a + last, regs->areg + last, (wm>>4)*16); - return ret ? -EFAULT : 0; + for (i = 0; i < live; i++) + __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS)); + for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++) + __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS)); + + return 0; } int ptrace_setregs(struct task_struct *child, void __user *uregs) @@ -76,28 +73,35 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs) struct pt_regs *regs = task_pt_regs(child); xtensa_gregset_t *gregset = uregs; const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; - unsigned long wm = regs->wmask; unsigned long ps; - int ret = 0; - int live, last; + unsigned long wb; if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) return -EIO; - ret |= __get_user(regs->pc, &gregset->pc); - ret |= __get_user(ps, &gregset->ps); - ret |= __get_user(regs->lbeg, &gregset->lbeg); - ret |= __get_user(regs->lend, &gregset->lend); - ret |= __get_user(regs->lcount, &gregset->lcount); + __get_user(regs->pc, &gregset->pc); + __get_user(ps, &gregset->ps); + __get_user(regs->lbeg, &gregset->lbeg); + __get_user(regs->lend, &gregset->lend); + __get_user(regs->lcount, &gregset->lcount); + __get_user(regs->windowstart, &gregset->windowstart); + __get_user(wb, &gregset->windowbase); regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT); - live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; - last = XCHAL_NUM_AREGS - (wm >> 4) * 4; - ret |= __copy_from_user(regs->areg, gregset->a, live * 4); - ret |= __copy_from_user(regs->areg+last, gregset->a+last, (wm>>4)*16); + if (wb >= XCHAL_NUM_AREGS / 4) + return -EFAULT; - return ret ? -EFAULT : 0; + regs->windowbase = wb; + + if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, + gregset->a, wb * 16)) + return -EFAULT; + + if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16)) + return -EFAULT; + + return 0; } diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h index 11103e07d028..ca6e5101a2cb 100644 --- a/include/asm-xtensa/elf.h +++ b/include/asm-xtensa/elf.h @@ -82,7 +82,8 @@ typedef struct { elf_greg_t lcount; elf_greg_t sar; elf_greg_t windowstart; - elf_greg_t reserved[9+48]; + elf_greg_t windowbase; + elf_greg_t reserved[8+48]; elf_greg_t a[64]; } xtensa_gregset_t; From 208c70a45624400fafd7511b96bc426bf01f8f5e Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 14 Feb 2008 15:58:47 -0500 Subject: [PATCH 081/880] ACPI: EC: Use proper handle for boot EC Fall back to ACPI_ROOT_HANDLE only in case of error. ACPI: EC: EC description table is found, configuring boot EC ACPI Error (evregion-0316): No handler for Region [ECOR] (ffff81007a651620) [EmbeddedControl] [20070126] ACPI Error (exfldio-0289): Region EmbeddedControl(3) has no handler [20070126] http://bugzilla.kernel.org/show_bug.cgi?id=9916 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 7222a18a0319..caf873c14bfb 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -943,7 +943,11 @@ int __init acpi_ec_ecdt_probe(void) boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->gpe = ecdt_ptr->gpe; - boot_ec->handle = ACPI_ROOT_OBJECT; + if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id, + &boot_ec->handle))) { + pr_info("Failed to locate handle for boot EC\n"); + boot_ec->handle = ACPI_ROOT_OBJECT; + } } else { /* This workaround is needed only on some broken machines, * which require early EC, but fail to provide ECDT */ From e06b8b98da071f7dd78fb7822991694288047df0 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 13 Feb 2008 22:43:28 +0100 Subject: [PATCH 082/880] kbuild: allow -fstack-protector to take effect Arjan van de Ven wrote: === I just read the excellent LWN writeup of the vmsplice security thing, and that got me wondering why this attack wasn't stopped by the CONFIG_CC_STACKPROTECTOR option... because it plain should have been... Some analysis later.. it turns out that the following line in the top level Makefile, added by you in October 2007, entirely disables CONFIG_CC_STACKPROTECTOR ;( With this line removed the exploit will be nicely stopped. CFLAGS += $(call cc-option, -fno-stack-protector) Now I realize that certain distros have patched gcc to compensate for their lack of distro wide CFLAGS, and it's great to work around that... but would there be a way to NOT disable this for CONFIG_CC_STACKPROTECTOR please? It would have made this exploit not possible for those kernels that enable this feature (and that includes distros like Fedora) === Move the assignment to KBUILD_CFLAGS up before including the arch specific Makefile so arch makefiles may override the setting. Signed-off-by: Sam Ravnborg Cc: Arjan van de Ven Cc: stable@kernel.org --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c162370c7367..d73865188372 100644 --- a/Makefile +++ b/Makefile @@ -507,6 +507,10 @@ else KBUILD_CFLAGS += -O2 endif +# Force gcc to behave correct even for buggy distributions +# Arch Makefiles may override this setting +KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) + include $(srctree)/arch/$(SRCARCH)/Makefile ifdef CONFIG_FRAME_POINTER @@ -525,9 +529,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) endif -# Force gcc to behave correct even for buggy distributions -KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) - # arch Makefile may override CC so keep this after arch Makefile is included NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) CHECKFLAGS += $(NOSTDINC_FLAGS) From cf87dcd14064e7660f2b11b35b9e4949e9812fd2 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 13 Feb 2008 22:50:24 +0100 Subject: [PATCH 083/880] kbuild: fix building vmlinux.o Ingo Molnar wrote: > > i've got a build log from a weird build error below: > > LD init/built-in.o > distcc[12023] ERROR: compile (null) on localhost failed > make: *** [vmlinux.o] Error 1 > make: *** Waiting for unfinished jobs.... > LD .tmp_vmlinux1 > Building vmlinux.o were moved up in the dependency chain so we started to build it before the kallsym stuff. This was done to let modpost report section mismatch bugs even when the final link failed. Originally I had expected the dependency of $(kallsyms.o) to cover this but it turns out that we need to be even more explicit. Fix this by adding a conditional dependency on firat target used in the kallsyms serie of builds. Signed-off-by: Sam Ravnborg Cc: Ingo Molnar Cc: Roland McGrath --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d73865188372..0d585c09d60c 100644 --- a/Makefile +++ b/Makefile @@ -811,7 +811,9 @@ endif $(Q)rm -f .old_version # build vmlinux.o first to catch section mismatch errors early -$(kallsyms.o): vmlinux.o +ifdef CONFIG_KALLSYMS +.tmp_vmlinux1: vmlinux.o +endif vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE $(call if_changed_rule,vmlinux-modpost) From f881d8290c59beb472062142aab54af2554d0d9c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 15 Feb 2008 19:15:05 +0800 Subject: [PATCH 084/880] [HIFN]: Fix invalid config ifdefs for RNG support The CRYPTO_DEV_HIFN_795X_RNG ifdefs are missing the CONFIG_ prefix. Signed-off-by: Patrick McHardy Signed-off-by: Herbert Xu --- drivers/crypto/hifn_795x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index dfbf24c4033c..3110bf7014f7 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -463,7 +463,7 @@ struct hifn_device unsigned int pk_clk_freq; -#ifdef CRYPTO_DEV_HIFN_795X_RNG +#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG unsigned int rng_wait_time; ktime_t rngtime; struct hwrng rng; @@ -795,7 +795,7 @@ static struct pci2id { } }; -#ifdef CRYPTO_DEV_HIFN_795X_RNG +#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG static int hifn_rng_data_present(struct hwrng *rng, int wait) { struct hifn_device *dev = (struct hifn_device *)rng->priv; @@ -880,7 +880,7 @@ static int hifn_init_pubrng(struct hifn_device *dev) dprintk("Chip %s: RNG engine has been successfully initialised.\n", dev->name); -#ifdef CRYPTO_DEV_HIFN_795X_RNG +#ifdef CONFIG_CRYPTO_DEV_HIFN_795X_RNG /* First value must be discarded */ hifn_read_1(dev, HIFN_1_RNG_DATA); dev->rngtime = ktime_get(); From 242f1a343776a621ad5c3446d6f2718d37863cb5 Mon Sep 17 00:00:00 2001 From: Frederik Deweerdt Date: Fri, 15 Feb 2008 19:19:33 +0800 Subject: [PATCH 085/880] [CRYPTO] tcrypt: Add missing Kconfig dependency on BLKCIPHER Building latest git fails with the following error: ERROR: "crypto_alloc_ablkcipher" [crypto/tcrypt.ko] undefined! This appears to happen because CONFIG_CRYPTO_TEST is set while CONFIG_CRYPTO_BLKCIPHER is not. The following patch fixes the problem for me. Signed-off-by: Frederik Deweerdt Signed-off-by: Herbert Xu --- crypto/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index c3166a1a5bb6..d0287ce56daf 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -567,6 +567,7 @@ config CRYPTO_TEST depends on m select CRYPTO_ALGAPI select CRYPTO_AEAD + select CRYPTO_BLKCIPHER help Quick & dirty crypto test module. From fa2144ba9a31d1d0dc9607508576c3850e0d95b1 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 15 Feb 2008 13:53:11 +0100 Subject: [PATCH 086/880] kbuild: explain why DEBUG_SECTION_MISMATCH is UNDEFINED We started to see patches enabling this - so explain why it is disabled and the condition to enable it again. Signed-off-by: Sam Ravnborg --- lib/Kconfig.debug | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index a370fe828a79..ab408aa9b6d6 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -82,6 +82,9 @@ config HEADERS_CHECK config DEBUG_SECTION_MISMATCH bool "Enable full Section mismatch analysis" depends on UNDEFINED + # This option is on purpose disabled for now. + # It will be enabled when we are down to a resonable number + # of section mismatch warnings (< 10 for an allyesconfig build) help The section mismatch analysis checks if there are illegal references from one section to another section. From d45ad06273f797f6239b97fd9962ecd81eec847f Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 15 Feb 2008 14:38:40 +0100 Subject: [PATCH 087/880] avr32: Call tick_nohz_{stop,restart}_sched_tick() in idle loop This fixes a hang on boot with nohz enabled. nohz is not actually supported in mainline yet, but patches that add support for it are currently under review. When nohz is compiled out, the functions are no-ops, so this patch results in no functional change, but it arguably makes the code more correct. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/process.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index eaaa69bbdc38..faf8d0e76801 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -30,8 +31,10 @@ void cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { + tick_nohz_stop_sched_tick(); while (!need_resched()) cpu_idle_sleep(); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); From a1a98b72dbd17e53cd92b8e78f404525ebcfd981 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Wed, 13 Feb 2008 19:47:11 -0500 Subject: [PATCH 088/880] Fix station address detection in smc Megahertz EM1144 PCMCIA ethernet adapter needs special handling because it has two VERS_1 tuples and the station address is in the second one. Conversion to generic handling of these fields broke it. Reverting that fixes the device. https://bugzilla.redhat.com/show_bug.cgi?id=233255 Thanks go to Jon Stanley for not giving up on this one until the problem was found. Signed-off-by: Chuck Ebbert Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/smc91c92_cs.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index f18eca9831e8..250eb1954c34 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -559,8 +559,16 @@ static int mhz_setup(struct pcmcia_device *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ - if (link->prod_id[3]) { - station_addr = link->prod_id[3]; + tuple->DesiredTuple = CISTPL_VERS_1; + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + rc = -1; + goto free_cfg_mem; + } + /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ + if (next_tuple(link, tuple, parse) != CS_SUCCESS) + first_tuple(link, tuple, parse); + if (parse->version_1.ns > 3) { + station_addr = parse->version_1.str + parse->version_1.ofs[3]; if (cvt_ascii_address(dev, station_addr) == 0) { rc = 0; goto free_cfg_mem; From 9f30c768c00fd0f0a2ab37ef29d8c8c5a7abdf2e Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Wed, 13 Feb 2008 11:17:58 +0000 Subject: [PATCH 089/880] mkiss: ax_bump() locking fix According to one of OOPSes reported by Jann softirq can break while skb is prepared for netif_rx. The report isn't complete, so the real reason of the later bug could be different, but IMHO this locking break in ax_bump is unsafe and unnecessary. Reported-and-tested-by: Jann Traschewski Signed-off-by: Jarek Poplawski Signed-off-by: Jeff Garzik --- drivers/net/hamradio/mkiss.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index cfcd15af501e..30c9b3b0d131 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -289,7 +289,6 @@ static void ax_bump(struct mkiss *ax) *ax->rbuff &= ~0x20; } } - spin_unlock_bh(&ax->buflock); count = ax->rcount; @@ -297,17 +296,17 @@ static void ax_bump(struct mkiss *ax) printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name); ax->stats.rx_dropped++; + spin_unlock_bh(&ax->buflock); return; } - spin_lock_bh(&ax->buflock); memcpy(skb_put(skb,count), ax->rbuff, count); - spin_unlock_bh(&ax->buflock); skb->protocol = ax25_type_trans(skb, ax->dev); netif_rx(skb); ax->dev->last_rx = jiffies; ax->stats.rx_packets++; ax->stats.rx_bytes += count; + spin_unlock_bh(&ax->buflock); } static void kiss_unesc(struct mkiss *ax, unsigned char s) From fdb26629f31b898c2c4a4127c7d5c2401fb5ac60 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 13 Feb 2008 03:58:36 +0000 Subject: [PATCH 090/880] gianfar iomem misannotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/gianfar.c | 4 ++-- drivers/net/gianfar_mii.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 0431e9ed0fac..4244fc282f21 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -130,8 +130,8 @@ static void free_skb_resources(struct gfar_private *priv); static void gfar_set_multi(struct net_device *dev); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); static void gfar_configure_serdes(struct net_device *dev); -extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value); -extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum); +extern int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int regnum, u16 value); +extern int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); #ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct napi_struct *napi, int budget); #endif diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index 6a647d95e6ea..24327629bf03 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -51,7 +51,7 @@ * the local mdio pins, which may not be the same as system mdio bus, used for * controlling the external PHYs, for example. */ -int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, +int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, int regnum, u16 value) { /* Set the PHY address and the register address we want to write */ @@ -77,7 +77,7 @@ int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, * and are always tied to the local mdio pins, which may not be the * same as system mdio bus, used for controlling the external PHYs, for eg. */ -int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum) +int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum) { u16 value; From 5918bd88effd0233a048983570ec5803f5f753dc Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 12 Feb 2008 15:20:24 -0800 Subject: [PATCH 091/880] e1000e: Fix CRC stripping in hardware context bug CRC stripping was only correctly enabled for packet split recieves which is used when receiving jumbo frames. Correctly enable SECRC also for normal buffer packet receives. Tested by Andy Gospodarek and Johan Andersson, see bugzilla #9940. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index b9b0d321e70b..ea4ecc3bf82e 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1690,6 +1690,9 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) else rctl |= E1000_RCTL_LPE; + /* Enable hardware CRC frame stripping */ + rctl |= E1000_RCTL_SECRC; + /* Setup buffer sizes */ rctl &= ~E1000_RCTL_SZ_4096; rctl |= E1000_RCTL_BSEX; @@ -1755,9 +1758,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) /* Enable Packet split descriptors */ rctl |= E1000_RCTL_DTYP_PS; - - /* Enable hardware CRC frame stripping */ - rctl |= E1000_RCTL_SECRC; psrctl |= adapter->rx_ps_bsize0 >> E1000_PSRCTL_BSIZE0_SHIFT; From 41825d7158d4ca6488d562d73279392a886b9e7c Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 12 Feb 2008 15:20:33 -0800 Subject: [PATCH 092/880] ixgbe: Correctly obtain protocol information on transmit In reply to "RE: [Fwd: [PATCH 2.6.25] ixgbe/igb: correctly obtain protocol information on transmit]" from Andy Gospodarek: The driver was incorrectly looking at socket headers for protocol information, needed for checksumming offload. Fix this by not looking at the socket but frame headers instead. This disregards extension headers but it's unclear that linux generates those anyway. Tested by Andy Gospodarek. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_main.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 540b647eb825..23d0a4afe0e1 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2277,11 +2277,29 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, IXGBE_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (skb->protocol == htons(ETH_P_IP)) + switch (skb->protocol) { + case __constant_htons(ETH_P_IP): type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; + if (ip_hdr(skb)->protocol == IPPROTO_TCP) + type_tucmd_mlhl |= + IXGBE_ADVTXD_TUCMD_L4T_TCP; + break; + + case __constant_htons(ETH_P_IPV6): + /* XXX what about other V6 headers?? */ + if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) + type_tucmd_mlhl |= + IXGBE_ADVTXD_TUCMD_L4T_TCP; + break; - if (skb->sk->sk_protocol == IPPROTO_TCP) - type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + default: + if (unlikely(net_ratelimit())) { + DPRINTK(PROBE, WARNING, + "partial checksum but proto=%x!\n", + skb->protocol); + } + break; + } } context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); From aa20c6c6d22efcca76c6225eb46f5903ce14c7c8 Mon Sep 17 00:00:00 2001 From: David Graham Date: Thu, 14 Feb 2008 10:17:12 -0800 Subject: [PATCH 093/880] igb: PCIe devices do not need to unset MANC_ARP_ENA Users reported that ARP's were lost with igb. The problem is fixed by not enabling this manageability configuration bit. None of the release_manageability code is actually needed as the normal device reset during a shutdown returns everthing to the right condition automatically. Signed-off-by: David Graham Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/igb/igb_main.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index d4eb8e2d8720..bff280eff5e3 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -606,9 +606,6 @@ static void igb_init_manageability(struct igb_adapter *adapter) u32 manc2h = rd32(E1000_MANC2H); u32 manc = rd32(E1000_MANC); - /* disable hardware interception of ARP */ - manc &= ~(E1000_MANC_ARP_EN); - /* enable receiving management packets to the host */ /* this will probably generate destination unreachable messages * from the host OS, but the packets will be handled on SMBUS */ @@ -623,25 +620,6 @@ static void igb_init_manageability(struct igb_adapter *adapter) } } -static void igb_release_manageability(struct igb_adapter *adapter) -{ - struct e1000_hw *hw = &adapter->hw; - - if (adapter->en_mng_pt) { - u32 manc = rd32(E1000_MANC); - - /* re-enable hardware interception of ARP */ - manc |= E1000_MANC_ARP_EN; - manc &= ~E1000_MANC_EN_MNG2HOST; - - /* don't explicitly have to mess with MANC2H since - * MANC has an enable disable that gates MANC2H */ - - /* XXX stop the hardware watchdog ? */ - wr32(E1000_MANC, manc); - } -} - /** * igb_configure - configure the hardware for RX and TX * @adapter: private board structure @@ -844,7 +822,6 @@ void igb_reset(struct igb_adapter *adapter) igb_reset_adaptive(&adapter->hw); adapter->hw.phy.ops.get_phy_info(&adapter->hw); - igb_release_manageability(adapter); } /** @@ -1178,9 +1155,6 @@ static void __devexit igb_remove(struct pci_dev *pdev) flush_scheduled_work(); - - igb_release_manageability(adapter); - /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ igb_release_hw_control(adapter); @@ -3955,8 +3929,6 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - igb_release_manageability(adapter); - /* make sure adapter isn't asleep if manageability is enabled */ if (adapter->en_mng_pt) { pci_enable_wake(pdev, PCI_D3hot, 1); From e8ef7f295b9f02c1522da405ac545318174239d5 Mon Sep 17 00:00:00 2001 From: David Graham Date: Thu, 14 Feb 2008 10:17:20 -0800 Subject: [PATCH 094/880] e1000e: PCIe devices do not need to unset MANC_ARP_ENA Users reported that ARP's were lost with e1000e. The problem is fixed by not enabling this manageability configuration bit. None of the release_manageability code is actually needed as the normal device reset during a shutdown returns everthing to the right condition automatically. Signed-off-by: David Graham Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index ea4ecc3bf82e..3031d6d16247 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1055,23 +1055,6 @@ static void e1000_release_hw_control(struct e1000_adapter *adapter) } } -static void e1000_release_manageability(struct e1000_adapter *adapter) -{ - if (adapter->flags & FLAG_MNG_PT_ENABLED) { - struct e1000_hw *hw = &adapter->hw; - - u32 manc = er32(MANC); - - /* re-enable hardware interception of ARP */ - manc |= E1000_MANC_ARP_EN; - manc &= ~E1000_MANC_EN_MNG2HOST; - - /* don't explicitly have to mess with MANC2H since - * MANC has an enable disable that gates MANC2H */ - ew32(MANC, manc); - } -} - /** * @e1000_alloc_ring - allocate memory for a ring structure **/ @@ -1561,9 +1544,6 @@ static void e1000_init_manageability(struct e1000_adapter *adapter) manc = er32(MANC); - /* disable hardware interception of ARP */ - manc &= ~(E1000_MANC_ARP_EN); - /* enable receiving management packets to the host. this will probably * generate destination unreachable messages from the host OS, but * the packets will be handled on SMBUS */ @@ -2140,8 +2120,6 @@ void e1000e_reset(struct e1000_adapter *adapter) phy_data &= ~IGP02E1000_PM_SPD; e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); } - - e1000_release_manageability(adapter); } int e1000e_up(struct e1000_adapter *adapter) @@ -3487,8 +3465,6 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - e1000_release_manageability(adapter); - /* make sure adapter isn't asleep if manageability is enabled */ if (adapter->flags & FLAG_MNG_PT_ENABLED) { pci_enable_wake(pdev, PCI_D3hot, 1); @@ -4054,8 +4030,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev) flush_scheduled_work(); - e1000_release_manageability(adapter); - /* Release control of h/w to f/w. If f/w is AMT enabled, this * would have already happened in close and is redundant. */ e1000_release_hw_control(adapter); From 642be6ec218b956fbae88304449720f76ba0d578 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 25 Feb 2008 17:20:46 -0500 Subject: [PATCH 095/880] Remove incorrect BKL comments in ext4 Signed-off-by: Andi Kleen Signed-off-by: "Theodore Ts'o" --- fs/ext4/dir.c | 2 +- fs/ext4/inode.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 33888bb58144..2c23bade9aa6 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -46,7 +46,7 @@ const struct file_operations ext4_dir_operations = { #ifdef CONFIG_COMPAT .compat_ioctl = ext4_compat_ioctl, #endif - .fsync = ext4_sync_file, /* BKL held */ + .fsync = ext4_sync_file, .release = ext4_release_dir, }; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7dd9b50d5ebc..d3c6f58a9def 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -768,7 +768,6 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode, * * `handle' can be NULL if create == 0. * - * The BKL may not be held on entry here. Be sure to take it early. * return > 0, # of blocks mapped or allocated. * return = 0, if plain lookup failed. * return < 0, error case. From 55bd725aa3a83b3935988f37275b5a80e10d4169 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 15 Feb 2008 12:47:21 -0500 Subject: [PATCH 096/880] ext4: Fix locking hierarchy violation in ext4_fallocate() ext4_fallocate() was trying to acquire i_data_sem outside of jbd2_start_transaction/jbd2_journal_stop, which violates ext4's locking hierarchy. So we take i_mutex to prevent writes and truncates during the complete fallocate operation, and use ext4_get_block_wrap() which acquires and releases i_data_sem for each block allocation. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bc7081f1fbe8..e856f660fc30 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2623,7 +2623,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) * modify 1 super block, 1 block bitmap and 1 group descriptor. */ credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; - down_write((&EXT4_I(inode)->i_data_sem)); + mutex_lock(&inode->i_mutex); retry: while (ret >= 0 && ret < max_blocks) { block = block + ret; @@ -2634,7 +2634,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) break; } - ret = ext4_ext_get_blocks(handle, inode, block, + ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, EXT4_CREATE_UNINITIALIZED_EXT, 0); WARN_ON(ret <= 0); @@ -2680,7 +2680,6 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; - up_write((&EXT4_I(inode)->i_data_sem)); /* * Time to update the file size. * Update only when preallocation was requested beyond the file size. @@ -2692,21 +2691,18 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) * if no error, we assume preallocation succeeded * completely */ - mutex_lock(&inode->i_mutex); i_size_write(inode, offset + len); EXT4_I(inode)->i_disksize = i_size_read(inode); - mutex_unlock(&inode->i_mutex); } else if (ret < 0 && nblocks) { /* Handle partial allocation scenario */ loff_t newsize; - mutex_lock(&inode->i_mutex); newsize = (nblocks << blkbits) + i_size_read(inode); i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); EXT4_I(inode)->i_disksize = i_size_read(inode); - mutex_unlock(&inode->i_mutex); } } + mutex_unlock(&inode->i_mutex); return ret > 0 ? ret2 : ret; } From b73fce69ecb091a178ef9286027c370a63eb25aa Mon Sep 17 00:00:00 2001 From: Valerie Clement Date: Fri, 15 Feb 2008 13:48:51 -0500 Subject: [PATCH 097/880] ext4: Fix kernel BUG at fs/ext4/mballoc.c:910! With the flex_bg feature enabled, a large file creation oopses the kernel. The BUG_ON is: BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb)); As the allocation of the bitmaps and the inode table can be done outside the block group with flex_bg, this allows to allocate up to EXT4_BLOCKS_PER_GROUP blocks in a group. This patch fixes the oops. Signed-off-by: Valerie Clement Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dd0fcfcb35ce..2121184a3fa5 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -906,7 +906,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, unsigned short chunk; unsigned short border; - BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb)); + BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb)); border = 2 << sb->s_blocksize_bits; From 4cdeed861b5f797b3fa661eb331a6bd6ad669c6a Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 22 Feb 2008 06:17:31 -0500 Subject: [PATCH 098/880] ext4: Don't leave behind a half-created inode if ext4_mkdir() fails If ext4_mkdir() fails to allocate the initial block for the directory, don't leave behind a half-created directory inode with the link count left at one. This was caused by an inappropriate call to ext4_dec_count(). Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/namei.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a9347fb43bcc..fffd0807a01b 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1804,12 +1804,8 @@ static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode) inode->i_fop = &ext4_dir_operations; inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; dir_block = ext4_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - ext4_dec_count(handle, inode); /* is this nlink == 0? */ - ext4_mark_inode_dirty(handle, inode); - iput (inode); - goto out_stop; - } + if (!dir_block) + goto out_clear_inode; BUFFER_TRACE(dir_block, "get_write_access"); ext4_journal_get_write_access(handle, dir_block); de = (struct ext4_dir_entry_2 *) dir_block->b_data; @@ -1832,7 +1828,8 @@ static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode) ext4_mark_inode_dirty(handle, inode); err = ext4_add_entry (handle, dentry, inode); if (err) { - inode->i_nlink = 0; +out_clear_inode: + clear_nlink(inode); ext4_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; From b35905c16ad6428551eb9e49525011bd2700cf56 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 25 Feb 2008 16:54:37 -0500 Subject: [PATCH 099/880] ext4: Fix memory and buffer head leak in callers to ext4_ext_find_extent() The path variable returned via ext4_ext_find_extent is a kmalloc variable and needs to be freeded. It also contains a reference to buffer_head which needs to be dropped. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 6 +++--- fs/ext4/migrate.c | 5 +++++ include/linux/ext4_fs_extents.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e856f660fc30..995ac16102a9 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -349,7 +349,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) #define ext4_ext_show_leaf(inode,path) #endif -static void ext4_ext_drop_refs(struct ext4_ext_path *path) +void ext4_ext_drop_refs(struct ext4_ext_path *path) { int depth = path->p_depth; int i; @@ -2200,10 +2200,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, newdepth = ext_depth(inode); if (newdepth != depth) { depth = newdepth; - path = ext4_ext_find_extent(inode, iblock, NULL); + ext4_ext_drop_refs(path); + path = ext4_ext_find_extent(inode, iblock, path); if (IS_ERR(path)) { err = PTR_ERR(path); - path = NULL; goto out; } eh = path[depth].p_hdr; diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 8c6c685b9d22..5c1e27de7755 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -43,6 +43,7 @@ static int finish_range(handle_t *handle, struct inode *inode, if (IS_ERR(path)) { retval = PTR_ERR(path); + path = NULL; goto err_out; } @@ -74,6 +75,10 @@ static int finish_range(handle_t *handle, struct inode *inode, } retval = ext4_ext_insert_extent(handle, inode, path, &newext); err_out: + if (path) { + ext4_ext_drop_refs(path); + kfree(path); + } lb->first_pblock = 0; return retval; } diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h index 697da4bce6c5..1285c583b2d8 100644 --- a/include/linux/ext4_fs_extents.h +++ b/include/linux/ext4_fs_extents.h @@ -227,5 +227,6 @@ extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *, ext4_lblk_t *, ext4_fsblk_t *); extern int ext4_ext_search_right(struct inode *, struct ext4_ext_path *, ext4_lblk_t *, ext4_fsblk_t *); +extern void ext4_ext_drop_refs(struct ext4_ext_path *); #endif /* _LINUX_EXT4_EXTENTS */ From 9df5643ad135c7f8c02d3b69020de4ec910f9fc0 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 22 Feb 2008 06:17:31 -0500 Subject: [PATCH 100/880] ext4: Get journal write access before modifying the extent tree When the user was writing into an unitialized extent, ext4_ext_convert_to_initialize() was not requesting journal write access before it started to modify the extent tree. Fix this oversight. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 995ac16102a9..c4d6f19faf37 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2168,6 +2168,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, newblock = iblock - ee_block + ext_pblock(ex); ex2 = ex; + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) + goto out; + /* ex1: ee_block to iblock - 1 : uninitialized */ if (iblock > ee_block) { ex1 = ex; @@ -2210,6 +2214,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ex = path[depth].p_ext; if (ex2 != &newex) ex2 = ex; + + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) + goto out; } allocated = max_blocks; } @@ -2230,9 +2238,6 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ex2->ee_len = cpu_to_le16(allocated); if (ex2 != ex) goto insert; - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) - goto out; /* * New (initialized) extent starts from the first block * in the current extent. i.e., ex2 == ex From e56eb6590693a5a340e8f596db2768a6e1b9e236 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 15 Feb 2008 13:48:21 -0500 Subject: [PATCH 101/880] ext4: Don't claim block from group which has corrupt bitmap In ext4_mb_complex_scan_group, if the extent length of the newly found extentet is greater than than the total free blocks counted in group info, break without claiming the block. Document different ext4_error usage, explaining the state with which we continue if we mount with errors=continue Signed-off-by: Aneesh Kumar K.V Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 2121184a3fa5..6968c53e62ad 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -967,6 +967,10 @@ static void ext4_mb_generate_buddy(struct super_block *sb, ext4_error(sb, __FUNCTION__, "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n", group, free, grp->bb_free); + /* + * If we intent to continue, we consider group descritor + * corrupt and update bb_free using bitmap value + */ grp->bb_free = free; } @@ -1822,7 +1826,7 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, EXT4_BLOCKS_PER_GROUP(sb), i); if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { /* - * IF we corrupt the bitmap we won't find any + * IF we have corrupt bitmap, we won't find any * free blocks even though group info says we * we have free blocks */ @@ -1838,6 +1842,12 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, ext4_error(sb, __FUNCTION__, "%d free blocks as per " "group info. But got %d blocks\n", free, ex.fe_len); + /* + * The number of free blocks differs. This mostly + * indicate that the bitmap is corrupt. So exit + * without claiming the space. + */ + break; } ext4_mb_measure_extent(ac, &ex, e4b); @@ -3771,6 +3781,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, (unsigned long) pa->pa_len); ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n", free, pa->pa_free); + /* + * pa is already deleted so we use the value obtained + * from the bitmap and continue. + */ } atomic_add(free, &sbi->s_mb_discarded); if (ac) From 74d3487fc8aa58cec16dff7239dea1ca59bdab0e Mon Sep 17 00:00:00 2001 From: Valerie Clement Date: Fri, 15 Feb 2008 13:43:07 -0500 Subject: [PATCH 102/880] ext4: modify block allocation algorithm for the last group When a directory inode is allocated in the last group and the last group contains less than s_blocks_per_group blocks, the initial block allocated for the directory is not always allocated in the same group as the directory inode, but in one of the first groups of the filesystem (group 1 for example). Depending on the current process's pid, ext4_find_near() and ext4_ext_find_goal() can return a block number greater than the maximum blocks count in the filesystem and in that case the block will be not allocated in the same group as the inode. The following patch fixes the problem. Should the modification also be done in ext2/3 code? Signed-off-by: Valerie Clement Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 8 +++++++- fs/ext4/inode.c | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c4d6f19faf37..8a59f7ba30e6 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -148,6 +148,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, { struct ext4_inode_info *ei = EXT4_I(inode); ext4_fsblk_t bg_start; + ext4_fsblk_t last_block; ext4_grpblk_t colour; int depth; @@ -169,8 +170,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, /* OK. use inode's group */ bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block); - colour = (current->pid % 16) * + last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; + + if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) + colour = (current->pid % 16) * (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); + else + colour = (current->pid % 16) * ((last_block - bg_start) / 16); return bg_start + colour + block; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d3c6f58a9def..34f3eb615fd5 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -403,6 +403,7 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data; __le32 *p; ext4_fsblk_t bg_start; + ext4_fsblk_t last_block; ext4_grpblk_t colour; /* Try to find previous block */ @@ -420,8 +421,13 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) * into the same cylinder group then. */ bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group); - colour = (current->pid % 16) * + last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; + + if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) + colour = (current->pid % 16) * (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); + else + colour = (current->pid % 16) * ((last_block - bg_start) / 16); return bg_start + colour; } From bd196ec7f03fff6935f66a9a3cf27accd34a75b9 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 7 Feb 2008 15:46:01 -0500 Subject: [PATCH 103/880] wavelan: mark hardware interfacing structures as packed With assists from Russell King and Andrew Morton ... Signed-off-by: John W. Linville --- drivers/net/wireless/wavelan.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wavelan.h b/drivers/net/wireless/wavelan.h index 27172cde5a39..9ab360558ffd 100644 --- a/drivers/net/wireless/wavelan.h +++ b/drivers/net/wireless/wavelan.h @@ -85,7 +85,7 @@ union hacs_u #define HASR_MMC_INTR 0x0002 /* Interrupt request from MMC */ #define HASR_MMC_BUSY 0x0004 /* MMC busy indication */ #define HASR_PSA_BUSY 0x0008 /* LAN parameter storage area busy */ -}; +} __attribute__ ((packed)); typedef struct ha_t ha_t; struct ha_t @@ -292,7 +292,7 @@ struct mmw_t #define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */ #define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */ #define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */ -}; +} __attribute__ ((packed)); #define MMW_SIZE 37 @@ -347,7 +347,7 @@ struct mmr_t unsigned char mmr_unused4[1]; /* unused */ unsigned char mmr_fee_data_l; /* Read data from EEPROM (low) */ unsigned char mmr_fee_data_h; /* Read data from EEPROM (high) */ -}; +} __attribute__ ((packed)); #define MMR_SIZE 36 From 281c56dd276e587a7b4a65764ac68ae250e73235 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 5 Feb 2008 18:44:55 +0900 Subject: [PATCH 104/880] ath5k: correct padding in tx descriptors when setting up the tx descriptors for the hardware we must account for any padding between the header and the data we might have added previously. frame len is the length of the frame in the air (including FCS but no padding) and buffer len is the length of the buffer (including padding, but without FCS). changing the way ah_setup_tx_desc is called: now excluding the FCS, since it's easier to add that in the function where we need it. before this fix we sent trailing zero bytes after the packet (because frame len included the padding) which was not a big problem without WEP, but with WEP this resultes in a wrong WEP checksum and the packet is discarded - which is how i noticed at all ;) an easy way to run into header padding problems, btw, is to connect to a QoS (WME) enabled access point (eg. madwifi) - QoS data frames are 2 byte longer and will require padding. this patch applies on top of luis latest patch series from 04.02.2008. drivers/net/wireless/ath5k/base.c: Changes-licensed-under: 3-Clause-BSD drivers/net/wireless/ath5k/hw.c: Changes-licensed-under: ISC Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 4 ++-- drivers/net/wireless/ath5k/hw.c | 34 ++++++++++++++++++------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index ddc87149fe31..dfdaec020739 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1256,7 +1256,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, if (ctl->flags & IEEE80211_TXCTL_NO_ACK) flags |= AR5K_TXDESC_NOACK; - pktlen = skb->len + FCS_LEN; + pktlen = skb->len; if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) { keyidx = ctl->key_idx; @@ -1952,7 +1952,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, } ds->ds_data = bf->skbaddr; - ret = ah->ah_setup_tx_desc(ah, ds, skb->len + FCS_LEN, + ret = ah->ah_setup_tx_desc(ah, ds, skb->len, ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1, AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0); diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 3a4bf4035a23..1ab57aa6e4dc 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c @@ -3506,7 +3506,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, { u32 frame_type; struct ath5k_hw_2w_tx_desc *tx_desc; - unsigned int buff_len; + unsigned int frame_len; tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0; @@ -3537,22 +3537,25 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, /* Setup control descriptor */ /* Verify and set frame length */ - if (pkt_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) + + /* remove padding we might have added before */ + frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; + + if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_desc->tx_control_0 = pkt_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; + tx_desc->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ - buff_len = pkt_len - FCS_LEN; /* NB: beacon's BufLen must be a multiple of 4 bytes */ if(type == AR5K_PKT_TYPE_BEACON) - buff_len = roundup(buff_len, 4); + pkt_len = roundup(pkt_len, 4); - if (buff_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) + if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_desc->tx_control_1 = buff_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; + tx_desc->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; /* * Verify and set header length @@ -3634,7 +3637,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_desc *tx_desc; struct ath5k_hw_tx_status *tx_status; - unsigned int buff_len; + unsigned int frame_len; ATH5K_TRACE(ah->ah_sc); tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; @@ -3669,22 +3672,25 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* Setup control descriptor */ /* Verify and set frame length */ - if (pkt_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) + + /* remove padding we might have added before */ + frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; + + if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_desc->tx_control_0 = pkt_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; + tx_desc->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ - buff_len = pkt_len - FCS_LEN; /* NB: beacon's BufLen must be a multiple of 4 bytes */ if(type == AR5K_PKT_TYPE_BEACON) - buff_len = roundup(buff_len, 4); + pkt_len = roundup(pkt_len, 4); - if (buff_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) + if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_desc->tx_control_1 = buff_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; + tx_desc->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; tx_desc->tx_control_0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | From a97b1f3d203d0fe5503578c6ee8bfdb89ed72679 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Wed, 6 Feb 2008 15:36:10 +0200 Subject: [PATCH 105/880] rndis_wlan: enable stall workaround by link quality instead of link speed Enable workaround for poor link stalls by link quality instead of link speed. Using link speed caused workaround be active always on 802.11b networks which reduced performance and not even catch all stalls. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d3ecf89abd93..8ce2ddf8024f 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2300,7 +2300,7 @@ static void rndis_update_wireless_stats(struct work_struct *work) struct usbnet *usbdev = priv->usbdev; struct iw_statistics iwstats; __le32 rssi, tmp; - int len, ret, bitrate, j; + int len, ret, j; unsigned long flags; int update_jiffies = STATS_UPDATE_JIFFIES; void *buf; @@ -2352,14 +2352,10 @@ static void rndis_update_wireless_stats(struct work_struct *work) if (ret == 0) iwstats.discard.misc += le32_to_cpu(tmp); - /* Workaround transfer stalls on poor quality links. */ - len = sizeof(tmp); - ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len); - if (ret == 0) { - bitrate = le32_to_cpu(tmp) * 100; - if (bitrate > 11000000) - goto end; - + /* Workaround transfer stalls on poor quality links. + * TODO: find right way to fix these stalls (as stalls do not happen + * with ndiswrapper/windows driver). */ + if (iwstats.qual.qual <= 25) { /* Decrease stats worker interval to catch stalls. * faster. Faster than 400-500ms causes packet loss, * Slower doesn't catch stalls fast enough. From 9788864e2169ed3611e61c097efe4944c23fe7e9 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Wed, 6 Feb 2008 11:20:38 -0800 Subject: [PATCH 106/880] iwlwifi: do not clear GEO_CONFIGURED bit when calling _down The geos information is set up during probe and should only be removed during pci_remove, not during _down. This is a temporary fix until the setting of the status bits have been cleaned up (to explicitly match all setting with clearing of status bits). Signed-off-by: Reinette Chatre Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 5ee1ad69898b..b6f19a52b783 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6256,6 +6256,8 @@ static void __iwl3945_down(struct iwl3945_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND; goto exit; @@ -6267,6 +6269,8 @@ static void __iwl3945_down(struct iwl3945_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND | test_bit(STATUS_FW_ERROR, &priv->status) << diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index f423241b9567..8bedc0c311fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -6680,6 +6680,8 @@ static void __iwl4965_down(struct iwl4965_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND; goto exit; @@ -6691,6 +6693,8 @@ static void __iwl4965_down(struct iwl4965_priv *priv) STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | test_bit(STATUS_IN_SUSPEND, &priv->status) << STATUS_IN_SUSPEND | test_bit(STATUS_FW_ERROR, &priv->status) << From c342a1b91f6ccd317c68defd3b4c7bb75397d967 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Wed, 6 Feb 2008 11:20:40 -0800 Subject: [PATCH 107/880] iwlwifi: Don't send host commands on rfkill This patch prevents sending host commands when rfkill is on Signed-off-by: Gregory Greenman Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 6 ++++++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index b6f19a52b783..66520e85e79c 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -687,6 +687,12 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && !(cmd->meta.flags & CMD_SIZE_HUGE)); + + if (iwl3945_is_rfkill(priv)) { + IWL_DEBUG_INFO("Not sending command - RF KILL"); + return -EIO; + } + if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERROR("No space for Tx\n"); return -ENOSPC; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 8bedc0c311fb..855cc97d04a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -692,6 +692,11 @@ static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_c BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && !(cmd->meta.flags & CMD_SIZE_HUGE)); + if (iwl4965_is_rfkill(priv)) { + IWL_DEBUG_INFO("Not sending command - RF KILL"); + return -EIO; + } + if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERROR("No space for Tx\n"); return -ENOSPC; From d68ab68066805fdfee1f5f29ec2ec0179fd92fe1 Mon Sep 17 00:00:00 2001 From: Mohamed Abbas Date: Thu, 7 Feb 2008 13:16:33 -0800 Subject: [PATCH 108/880] iwlwifi: earlier rx allocation Value of count is used to decide when to replenish rx buffers. If it is equal or above 8 we replenish the buffers. Ensure there is no starvation by initializing count to 8 - thus forcing replenish at first iteration. This is helpful when rx receives batches of buffers smaller than 8. Signed-off-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 66520e85e79c..74b1099ff8aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4287,7 +4287,7 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) int reclaim; unsigned long flags; u8 fill_rx = 0; - u32 count = 0; + u32 count = 8; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 855cc97d04a8..14a11bd83e82 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -4669,7 +4669,7 @@ static void iwl4965_rx_handle(struct iwl4965_priv *priv) int reclaim; unsigned long flags; u8 fill_rx = 0; - u32 count = 0; + u32 count = 8; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ From 8e118f0ed866afab654a438b85643d4f1472f28b Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Fri, 8 Feb 2008 06:31:53 +0100 Subject: [PATCH 109/880] b43legacy: fix DMA for 30/32-bit DMA engines This checks if the DMA address is bigger than what the controller can manage. It will reallocate the buffers in the GFP_DMA zone in that case. The patch by Michael Buesch has been ported to b43legacy. Thanks to Matti Viljanen for reporting this. Cc: Matti Viljanen Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/dma.c | 167 +++++++++++++++++---------- drivers/net/wireless/b43legacy/dma.h | 33 ++---- 2 files changed, 113 insertions(+), 87 deletions(-) diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 6e08405e8026..e87b427d5e43 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -354,7 +354,8 @@ return 0; } -u16 b43legacy_dmacontroller_base(int dma64bit, int controller_idx) +static u16 b43legacy_dmacontroller_base(enum b43legacy_dmatype type, + int controller_idx) { static const u16 map64[] = { B43legacy_MMIO_DMA64_BASE0, @@ -373,7 +374,7 @@ u16 b43legacy_dmacontroller_base(int dma64bit, int controller_idx) B43legacy_MMIO_DMA32_BASE5, }; - if (dma64bit) { + if (type == B43legacy_DMA_64BIT) { B43legacy_WARN_ON(!(controller_idx >= 0 && controller_idx < ARRAY_SIZE(map64))); return map64[controller_idx]; @@ -480,8 +481,9 @@ static void free_ringmemory(struct b43legacy_dmaring *ring) } /* Reset the RX DMA channel */ -int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, - u16 mmio_base, int dma64) +static int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, + u16 mmio_base, + enum b43legacy_dmatype type) { int i; u32 value; @@ -489,13 +491,14 @@ int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, might_sleep(); - offset = dma64 ? B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL; + offset = (type == B43legacy_DMA_64BIT) ? + B43legacy_DMA64_RXCTL : B43legacy_DMA32_RXCTL; b43legacy_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { - offset = dma64 ? B43legacy_DMA64_RXSTATUS : - B43legacy_DMA32_RXSTATUS; + offset = (type == B43legacy_DMA_64BIT) ? + B43legacy_DMA64_RXSTATUS : B43legacy_DMA32_RXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (dma64) { + if (type == B43legacy_DMA_64BIT) { value &= B43legacy_DMA64_RXSTAT; if (value == B43legacy_DMA64_RXSTAT_DISABLED) { i = -1; @@ -519,8 +522,9 @@ int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, } /* Reset the RX DMA channel */ -int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, - u16 mmio_base, int dma64) +static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, + u16 mmio_base, + enum b43legacy_dmatype type) { int i; u32 value; @@ -529,10 +533,10 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, might_sleep(); for (i = 0; i < 10; i++) { - offset = dma64 ? B43legacy_DMA64_TXSTATUS : - B43legacy_DMA32_TXSTATUS; + offset = (type == B43legacy_DMA_64BIT) ? + B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (dma64) { + if (type == B43legacy_DMA_64BIT) { value &= B43legacy_DMA64_TXSTAT; if (value == B43legacy_DMA64_TXSTAT_DISABLED || value == B43legacy_DMA64_TXSTAT_IDLEWAIT || @@ -547,13 +551,14 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, } msleep(1); } - offset = dma64 ? B43legacy_DMA64_TXCTL : B43legacy_DMA32_TXCTL; + offset = (type == B43legacy_DMA_64BIT) ? B43legacy_DMA64_TXCTL : + B43legacy_DMA32_TXCTL; b43legacy_write32(dev, mmio_base + offset, 0); for (i = 0; i < 10; i++) { - offset = dma64 ? B43legacy_DMA64_TXSTATUS : - B43legacy_DMA32_TXSTATUS; + offset = (type == B43legacy_DMA_64BIT) ? + B43legacy_DMA64_TXSTATUS : B43legacy_DMA32_TXSTATUS; value = b43legacy_read32(dev, mmio_base + offset); - if (dma64) { + if (type == B43legacy_DMA_64BIT) { value &= B43legacy_DMA64_TXSTAT; if (value == B43legacy_DMA64_TXSTAT_DISABLED) { i = -1; @@ -578,6 +583,32 @@ int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, return 0; } +/* Check if a DMA mapping address is invalid. */ +static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, + dma_addr_t addr, + size_t buffersize) +{ + if (unlikely(dma_mapping_error(addr))) + return 1; + + switch (ring->type) { + case B43legacy_DMA_30BIT: + if ((u64)addr + buffersize > (1ULL << 30)) + return 1; + break; + case B43legacy_DMA_32BIT: + if ((u64)addr + buffersize > (1ULL << 32)) + return 1; + break; + case B43legacy_DMA_64BIT: + /* Currently we can't have addresses beyond 64 bits in the kernel. */ + break; + } + + /* The address is OK. */ + return 0; +} + static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, struct b43legacy_dmadesc_generic *desc, struct b43legacy_dmadesc_meta *meta, @@ -595,7 +626,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, return -ENOMEM; dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); - if (dma_mapping_error(dmaaddr)) { + if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { /* ugh. try to realloc in zone_dma */ gfp_flags |= GFP_DMA; @@ -608,7 +639,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, ring->rx_buffersize, 0); } - if (dma_mapping_error(dmaaddr)) { + if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { dev_kfree_skb_any(skb); return -EIO; } @@ -674,7 +705,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring) u32 trans = ssb_dma_translation(ring->dev->dev); if (ring->tx) { - if (ring->dma64) { + if (ring->type == B43legacy_DMA_64BIT) { u64 ringbase = (u64)(ring->dmabase); addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) @@ -709,7 +740,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring) err = alloc_initial_descbuffers(ring); if (err) goto out; - if (ring->dma64) { + if (ring->type == B43legacy_DMA_64BIT) { u64 ringbase = (u64)(ring->dmabase); addrext = ((ringbase >> 32) & SSB_DMA_TRANSLATION_MASK) @@ -760,16 +791,16 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring) { if (ring->tx) { b43legacy_dmacontroller_tx_reset(ring->dev, ring->mmio_base, - ring->dma64); - if (ring->dma64) { + ring->type); + if (ring->type == B43legacy_DMA_64BIT) { b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGLO, 0); b43legacy_dma_write(ring, B43legacy_DMA64_TXRINGHI, 0); } else b43legacy_dma_write(ring, B43legacy_DMA32_TXRING, 0); } else { b43legacy_dmacontroller_rx_reset(ring->dev, ring->mmio_base, - ring->dma64); - if (ring->dma64) { + ring->type); + if (ring->type == B43legacy_DMA_64BIT) { b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGLO, 0); b43legacy_dma_write(ring, B43legacy_DMA64_RXRINGHI, 0); } else @@ -824,11 +855,10 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev) /* Main initialization function. */ static -struct b43legacy_dmaring *b43legacy_setup_dmaring( - struct b43legacy_wldev *dev, - int controller_index, - int for_tx, - int dma64) +struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, + int controller_index, + int for_tx, + enum b43legacy_dmatype type) { struct b43legacy_dmaring *ring; int err; @@ -838,6 +868,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring( ring = kzalloc(sizeof(*ring), GFP_KERNEL); if (!ring) goto out; + ring->type = type; nr_slots = B43legacy_RXRING_SLOTS; if (for_tx) @@ -855,12 +886,12 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring( goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = dma_map_single(dev->dev->dev, - ring->txhdr_cache, - sizeof(struct b43legacy_txhdr_fw3), - DMA_TO_DEVICE); + dma_test = dma_map_single(dev->dev->dev, ring->txhdr_cache, + sizeof(struct b43legacy_txhdr_fw3), + DMA_TO_DEVICE); - if (dma_mapping_error(dma_test)) { + if (b43legacy_dma_mapping_error(ring, dma_test, + sizeof(struct b43legacy_txhdr_fw3))) { /* ugh realloc */ kfree(ring->txhdr_cache); ring->txhdr_cache = kcalloc(nr_slots, @@ -874,7 +905,8 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring( sizeof(struct b43legacy_txhdr_fw3), DMA_TO_DEVICE); - if (dma_mapping_error(dma_test)) + if (b43legacy_dma_mapping_error(ring, dma_test, + sizeof(struct b43legacy_txhdr_fw3))) goto err_kfree_txhdr_cache; } @@ -885,11 +917,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring( ring->dev = dev; ring->nr_slots = nr_slots; - ring->mmio_base = b43legacy_dmacontroller_base(dma64, - controller_index); + ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); ring->index = controller_index; - ring->dma64 = !!dma64; - if (dma64) + if (type == B43legacy_DMA_64BIT) ring->ops = &dma64_ops; else ring->ops = &dma32_ops; @@ -939,10 +969,10 @@ static void b43legacy_destroy_dmaring(struct b43legacy_dmaring *ring) if (!ring) return; - b43legacydbg(ring->dev->wl, "DMA-%s 0x%04X (%s) max used slots:" - " %d/%d\n", (ring->dma64) ? "64" : "32", ring->mmio_base, - (ring->tx) ? "TX" : "RX", - ring->max_used_slots, ring->nr_slots); + b43legacydbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots:" + " %d/%d\n", (unsigned int)(ring->type), ring->mmio_base, + (ring->tx) ? "TX" : "RX", ring->max_used_slots, + ring->nr_slots); /* Device IRQs are disabled prior entering this function, * so no need to take care of concurrency with rx handler stuff. */ @@ -988,11 +1018,22 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev) struct b43legacy_dmaring *ring; int err; u64 dmamask; - int dma64 = 0; + enum b43legacy_dmatype type; dmamask = supported_dma_mask(dev); - if (dmamask == DMA_64BIT_MASK) - dma64 = 1; + switch (dmamask) { + default: + B43legacy_WARN_ON(1); + case DMA_30BIT_MASK: + type = B43legacy_DMA_30BIT; + break; + case DMA_32BIT_MASK: + type = B43legacy_DMA_32BIT; + break; + case DMA_64BIT_MASK: + type = B43legacy_DMA_64BIT; + break; + } err = ssb_dma_set_mask(dev->dev, dmamask); if (err) { @@ -1010,52 +1051,50 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev) err = -ENOMEM; /* setup TX DMA channels. */ - ring = b43legacy_setup_dmaring(dev, 0, 1, dma64); + ring = b43legacy_setup_dmaring(dev, 0, 1, type); if (!ring) goto out; dma->tx_ring0 = ring; - ring = b43legacy_setup_dmaring(dev, 1, 1, dma64); + ring = b43legacy_setup_dmaring(dev, 1, 1, type); if (!ring) goto err_destroy_tx0; dma->tx_ring1 = ring; - ring = b43legacy_setup_dmaring(dev, 2, 1, dma64); + ring = b43legacy_setup_dmaring(dev, 2, 1, type); if (!ring) goto err_destroy_tx1; dma->tx_ring2 = ring; - ring = b43legacy_setup_dmaring(dev, 3, 1, dma64); + ring = b43legacy_setup_dmaring(dev, 3, 1, type); if (!ring) goto err_destroy_tx2; dma->tx_ring3 = ring; - ring = b43legacy_setup_dmaring(dev, 4, 1, dma64); + ring = b43legacy_setup_dmaring(dev, 4, 1, type); if (!ring) goto err_destroy_tx3; dma->tx_ring4 = ring; - ring = b43legacy_setup_dmaring(dev, 5, 1, dma64); + ring = b43legacy_setup_dmaring(dev, 5, 1, type); if (!ring) goto err_destroy_tx4; dma->tx_ring5 = ring; /* setup RX DMA channels. */ - ring = b43legacy_setup_dmaring(dev, 0, 0, dma64); + ring = b43legacy_setup_dmaring(dev, 0, 0, type); if (!ring) goto err_destroy_tx5; dma->rx_ring0 = ring; if (dev->dev->id.revision < 5) { - ring = b43legacy_setup_dmaring(dev, 3, 0, dma64); + ring = b43legacy_setup_dmaring(dev, 3, 0, type); if (!ring) goto err_destroy_rx0; dma->rx_ring3 = ring; } - b43legacydbg(dev->wl, "%d-bit DMA initialized\n", - (dmamask == DMA_64BIT_MASK) ? 64 : - (dmamask == DMA_32BIT_MASK) ? 32 : 30); + b43legacydbg(dev->wl, "%u-bit DMA initialized\n", (unsigned int)type); err = 0; out: return err; @@ -1194,9 +1233,13 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, } meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, - sizeof(struct b43legacy_txhdr_fw3), 1); - if (dma_mapping_error(meta_hdr->dmaaddr)) + sizeof(struct b43legacy_txhdr_fw3), 1); + if (b43legacy_dma_mapping_error(ring, meta_hdr->dmaaddr, + sizeof(struct b43legacy_txhdr_fw3))) { + ring->current_slot = old_top_slot; + ring->used_slots = old_used_slots; return -EIO; + } ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr, sizeof(struct b43legacy_txhdr_fw3), 1, 0, 0); @@ -1211,7 +1254,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ - if (dma_mapping_error(meta->dmaaddr)) { + if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) { ring->current_slot = old_top_slot; @@ -1225,7 +1268,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, skb = bounce_skb; meta->skb = skb; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); - if (dma_mapping_error(meta->dmaaddr)) { + if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; err = -EIO; diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h index 26f6ab08de75..2dd488c5be2d 100644 --- a/drivers/net/wireless/b43legacy/dma.h +++ b/drivers/net/wireless/b43legacy/dma.h @@ -218,6 +218,12 @@ struct b43legacy_dma_ops { void (*set_current_rxslot)(struct b43legacy_dmaring *ring, int slot); }; +enum b43legacy_dmatype { + B43legacy_DMA_30BIT = 30, + B43legacy_DMA_32BIT = 32, + B43legacy_DMA_64BIT = 64, +}; + struct b43legacy_dmaring { /* Lowlevel DMA ops. */ const struct b43legacy_dma_ops *ops; @@ -250,8 +256,8 @@ struct b43legacy_dmaring { int index; /* Boolean. Is this a TX ring? */ bool tx; - /* Boolean. 64bit DMA if true, 32bit DMA otherwise. */ - bool dma64; + /* The type of DMA engine used. */ + enum b43legacy_dmatype type; /* Boolean. Is this ring stopped at ieee80211 level? */ bool stopped; /* Lock, only used for TX. */ @@ -284,15 +290,6 @@ void b43legacy_dma_write(struct b43legacy_dmaring *ring, int b43legacy_dma_init(struct b43legacy_wldev *dev); void b43legacy_dma_free(struct b43legacy_wldev *dev); -int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, - u16 dmacontroller_mmio_base, - int dma64); -int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, - u16 dmacontroller_mmio_base, - int dma64); - -u16 b43legacy_dmacontroller_base(int dma64bit, int dmacontroller_idx); - void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev); void b43legacy_dma_tx_resume(struct b43legacy_wldev *dev); @@ -320,20 +317,6 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev) { } static inline -int b43legacy_dmacontroller_rx_reset(struct b43legacy_wldev *dev, - u16 dmacontroller_mmio_base, - int dma64) -{ - return 0; -} -static inline -int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, - u16 dmacontroller_mmio_base, - int dma64) -{ - return 0; -} -static inline void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev, struct ieee80211_tx_queue_stats *stats) { From 26bc783f8cf7227718f8b4cbc32f0c3a898b128f Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 9 Feb 2008 00:18:35 +0100 Subject: [PATCH 110/880] b43: Add driver load messages This adds printk messages with basic information about the driver being loaded. This information includes a summary of the compiled-in features, which simplifies bug-reporting and debugging a lot. Also a firmware ID is printed. This is a unique identifier blob for a specific version of the firmware. This ID is attached to a specific version of the firmware blob in b43-fwcutter (see fwcutter git). This helps users to select the right firmware for their device. This also makes it possible to use automated scripts to fetch and extract the right firmware for the driver. (the script will grep the .ko for the "Firmware-ID: xxx" string. While the driver might still support other versions of the firmware for backward compatibility, this will always print out the officially supported version, which people _should_ use. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 6 ++++++ drivers/net/wireless/b43/main.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 08a011f0834a..f13346ba9dd2 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -14,6 +14,12 @@ #include "lo.h" #include "phy.h" + +/* The unique identifier of the firmware that's officially supported by + * this driver version. */ +#define B43_SUPPORTED_FIRMWARE_ID "FW13" + + #ifdef CONFIG_B43_DEBUG # define B43_DEBUG 1 #else diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index ef65c41af00f..e55823cc3027 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4200,6 +4200,33 @@ static struct ssb_driver b43_ssb_driver = { .resume = b43_resume, }; +static void b43_print_driverinfo(void) +{ + const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", + *feat_leds = "", *feat_rfkill = ""; + +#ifdef CONFIG_B43_PCI_AUTOSELECT + feat_pci = "P"; +#endif +#ifdef CONFIG_B43_PCMCIA + feat_pcmcia = "M"; +#endif +#ifdef CONFIG_B43_NPHY + feat_nphy = "N"; +#endif +#ifdef CONFIG_B43_LEDS + feat_leds = "L"; +#endif +#ifdef CONFIG_B43_RFKILL + feat_rfkill = "R"; +#endif + printk(KERN_INFO "Broadcom 43xx driver loaded " + "[ Features: %s%s%s%s%s, Firmware-ID: " + B43_SUPPORTED_FIRMWARE_ID " ]\n", + feat_pci, feat_pcmcia, feat_nphy, + feat_leds, feat_rfkill); +} + static int __init b43_init(void) { int err; @@ -4211,6 +4238,7 @@ static int __init b43_init(void) err = ssb_driver_register(&b43_ssb_driver); if (err) goto err_pcmcia_exit; + b43_print_driverinfo(); return err; From 9c7d99d6fba1f26b95fb70b43f7954e9684cad3e Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 9 Feb 2008 10:23:49 +0100 Subject: [PATCH 111/880] b43: Add firmware information to modinfo This adds the firmware ID to modinfo. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index e55823cc3027..ab6d6088e198 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -58,6 +58,8 @@ MODULE_AUTHOR("Stefano Brivio"); MODULE_AUTHOR("Michael Buesch"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); + static int modparam_bad_frames_preempt; module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); From 588e6cdfccb847661c62a2cc0f301d689b94ee64 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 9 Feb 2008 17:53:41 +0100 Subject: [PATCH 112/880] b43: Fix firmware load message level The firmware version information should always get printed. Not only on a debug build. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index ab6d6088e198..51dfce16178a 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1861,11 +1861,11 @@ static int b43_upload_microcode(struct b43_wldev *dev) err = -EOPNOTSUPP; goto error; } - b43dbg(dev->wl, "Loading firmware version %u.%u " - "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", - fwrev, fwpatch, - (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, - (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F); + b43info(dev->wl, "Loading firmware version %u.%u " + "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", + fwrev, fwpatch, + (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, + (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F); dev->fw.rev = fwrev; dev->fw.patch = fwpatch; From db433febbadaf1fa9862fb5068b119be1d312d76 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 10 Feb 2008 11:21:57 +0100 Subject: [PATCH 113/880] rt2x00: Add new USB ID to rt2500usb Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 86ded4066f5b..4ca9730e5e92 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1839,11 +1839,11 @@ static struct usb_device_id rt2500usb_device_table[] = { /* Hercules */ { USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) }, /* Melco */ + { USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) }, - /* MSI */ { USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) }, From ceffefd15aac78841432230627308b8a382dbcfc Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 10 Feb 2008 14:16:52 +0100 Subject: [PATCH 114/880] mac80211: Fix initial hardware configuration On the initial device-open we need to defer the hardware reconfiguration after we incremented the open_count, because the hw_config checks this flag and won't call the lowlevel driver in case it is zero. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- net/mac80211/ieee80211.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 67b7c75c430d..28bcdf9fc3df 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -165,6 +165,7 @@ static int ieee80211_open(struct net_device *dev) struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_if_init_conf conf; int res; + bool need_hw_reconfig = 0; sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -218,7 +219,7 @@ static int ieee80211_open(struct net_device *dev) res = local->ops->start(local_to_hw(local)); if (res) return res; - ieee80211_hw_config(local); + need_hw_reconfig = 1; ieee80211_led_radio(local, local->hw.conf.radio_enabled); } @@ -282,6 +283,8 @@ static int ieee80211_open(struct net_device *dev) atomic_inc(&local->iff_promiscs); local->open_count++; + if (need_hw_reconfig) + ieee80211_hw_config(local); netif_start_queue(dev); From 1a1c360d73e5100a4dda1010ce0f1ebd71e03811 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Tue, 12 Feb 2008 03:09:00 +0100 Subject: [PATCH 115/880] b43legacy: add firmware information to modinfo This adds the firmware ID to modinfo. The patch by Michael Buesch has been ported to b43legacy. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 53f7f2e97615..25b9b06870bc 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -60,6 +60,8 @@ MODULE_AUTHOR("Stefano Brivio"); MODULE_AUTHOR("Michael Buesch"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID); + #if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO) static int modparam_pio; module_param_named(pio, modparam_pio, int, 0444); From cfbc35b62700447b6b14b744554f5dca17bdfa45 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Tue, 12 Feb 2008 03:09:10 +0100 Subject: [PATCH 116/880] b43legacy: fix firmware load message level The firmware version information should always get printed. Not only on a debug build. The patch by Michael Buesch has been ported to b43legacy. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 25b9b06870bc..794c2fa44b90 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1642,10 +1642,11 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) err = -EOPNOTSUPP; goto error; } - b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u " - "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch, - (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, - (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F); + b43legacyinfo(dev->wl, "Loading firmware version 0x%X, patch level %u " + "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch, + (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, + (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, + fwtime & 0x1F); dev->fw.rev = fwrev; dev->fw.patch = fwpatch; From 58ff6d4db9b51533656173282de8d21f72080a49 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 13 Feb 2008 02:47:54 +0200 Subject: [PATCH 117/880] iwlwifi: reverting 'misc wireless annotations' patch for iwlwifi This patch revert commit blow that wrongly suppressed sparse warning in iwlwifi eeprom reading In addtion it suppresses correctly the iwlwifi eeprom register reading anomaly. commit 45883ae47a0a4700c0f4716dc75a255cccdc3a76 misc wireless annotations Signed-off-by: Al Viro Signed-off-by: Tomas Winkler Cc: Al Viro Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl4965-base.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 74b1099ff8aa..03a0756f7ef4 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1586,7 +1586,7 @@ static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv) */ int iwl3945_eeprom_init(struct iwl3945_priv *priv) { - __le16 *e = (__le16 *)&priv->eeprom; + u16 *e = (u16 *)&priv->eeprom; u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP); u32 r; int sz = sizeof(priv->eeprom); @@ -1629,7 +1629,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) IWL_ERROR("Time out reading EEPROM[%d]", addr); return -ETIMEDOUT; } - e[addr / 2] = cpu_to_le16(r >> 16); + e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); } return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 14a11bd83e82..2c6756261856 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1659,7 +1659,7 @@ static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv) */ int iwl4965_eeprom_init(struct iwl4965_priv *priv) { - __le16 *e = (__le16 *)&priv->eeprom; + u16 *e = (u16 *)&priv->eeprom; u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP); u32 r; int sz = sizeof(priv->eeprom); @@ -1703,7 +1703,7 @@ int iwl4965_eeprom_init(struct iwl4965_priv *priv) rc = -ETIMEDOUT; goto done; } - e[addr / 2] = cpu_to_le16(r >> 16); + e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); } rc = 0; From a6477249b4a1c2da6376f47fc175882be9adb844 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Thu, 14 Feb 2008 10:40:28 -0800 Subject: [PATCH 118/880] iwlwifi: only check for association id when associating with AP There is no association process in IBSS mode - so testing the association id is not needed. Signed-off-by: Reinette Chatre Signed-off-by: Tomas Winkler CC: Richard Scherping Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 ++- drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 03a0756f7ef4..40b71bc2c4a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2812,7 +2812,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, #endif /* drop all data frame if we are not associated */ - if ((!iwl3945_is_associated(priv) || !priv->assoc_id) && + if ((!iwl3945_is_associated(priv) || + ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); goto drop_unlock; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 2c6756261856..a23d4798653b 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -2940,7 +2940,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, /* drop all data frame if we are not associated */ if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && (!iwl4965_is_associated(priv) || - !priv->assoc_id || + ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || !priv->assoc_station_added)) { IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n"); goto drop_unlock; From 943dbef4b84b9cee3501e45b654e38335900570b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 14 Feb 2008 17:49:41 -0500 Subject: [PATCH 119/880] ipw2200: fix ucode assertion for RX queue overrun Restock the RX queue when there are a lot of unused frames so that the RX ring buffer doesn't overrun, causing a ucode assertion. Backport of patch "iwlwifi: fix ucode assertion for RX queue overrun". Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2200.c | 45 +++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 3e6ad7b92c83..a56d9fc6354f 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -3365,7 +3365,6 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv, /* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; - rxq->processed = RX_QUEUE_SIZE - 1; rxq->free_count = 0; spin_unlock_irqrestore(&rxq->lock, flags); } @@ -3607,7 +3606,22 @@ static int ipw_load(struct ipw_priv *priv) * Driver allocates buffers of this size for Rx */ -static inline int ipw_queue_space(const struct clx2_queue *q) +/** + * ipw_rx_queue_space - Return number of free slots available in queue. + */ +static int ipw_rx_queue_space(const struct ipw_rx_queue *q) +{ + int s = q->read - q->write; + if (s <= 0) + s += RX_QUEUE_SIZE; + /* keep some buffer to not confuse full and empty queue */ + s -= 2; + if (s < 0) + s = 0; + return s; +} + +static inline int ipw_tx_queue_space(const struct clx2_queue *q) { int s = q->last_used - q->first_empty; if (s <= 0) @@ -4947,7 +4961,7 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv, priv->tx_packets++; } done: - if ((ipw_queue_space(q) > q->low_mark) && + if ((ipw_tx_queue_space(q) > q->low_mark) && (qindex >= 0) && (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev)) netif_wake_queue(priv->net_dev); @@ -4965,7 +4979,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf, struct clx2_queue *q = &txq->q; struct tfd_frame *tfd; - if (ipw_queue_space(q) < (sync ? 1 : 2)) { + if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) { IPW_ERROR("No space for Tx\n"); return -EBUSY; } @@ -5070,7 +5084,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv) spin_lock_irqsave(&rxq->lock, flags); write = rxq->write; - while ((rxq->write != rxq->processed) && (rxq->free_count)) { + while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) { element = rxq->rx_free.next; rxb = list_entry(element, struct ipw_rx_mem_buffer, list); list_del(element); @@ -5187,7 +5201,6 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv) /* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; - rxq->processed = RX_QUEUE_SIZE - 1; rxq->free_count = 0; return rxq; @@ -8223,13 +8236,17 @@ static void ipw_rx(struct ipw_priv *priv) struct ieee80211_hdr_4addr *header; u32 r, w, i; u8 network_packet; + u8 fill_rx = 0; DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac2); DECLARE_MAC_BUF(mac3); r = ipw_read32(priv, IPW_RX_READ_INDEX); w = ipw_read32(priv, IPW_RX_WRITE_INDEX); - i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE; + i = priv->rxq->read; + + if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2)) + fill_rx = 1; while (i != r) { rxb = priv->rxq->queue[i]; @@ -8404,11 +8421,17 @@ static void ipw_rx(struct ipw_priv *priv) list_add_tail(&rxb->list, &priv->rxq->rx_used); i = (i + 1) % RX_QUEUE_SIZE; + + /* If there are a lot of unsued frames, restock the Rx queue + * so the ucode won't assert */ + if (fill_rx) { + priv->rxq->read = i; + ipw_rx_queue_replenish(priv); + } } /* Backtrack one entry */ - priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1; - + priv->rxq->read = i; ipw_rx_queue_restock(priv); } @@ -10336,7 +10359,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); ipw_write32(priv, q->reg_w, q->first_empty); - if (ipw_queue_space(q) < q->high_mark) + if (ipw_tx_queue_space(q) < q->high_mark) netif_stop_queue(priv->net_dev); return NETDEV_TX_OK; @@ -10357,7 +10380,7 @@ static int ipw_net_is_queue_full(struct net_device *dev, int pri) struct clx2_tx_queue *txq = &priv->txq[0]; #endif /* CONFIG_IPW2200_QOS */ - if (ipw_queue_space(&txq->q) < txq->q.high_mark) + if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark) return 1; return 0; From 6fff1c64ffd899e0b70fbb0201c6603f078ea942 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Sat, 9 Feb 2008 07:20:43 +0100 Subject: [PATCH 120/880] b43legacy: Add driver load messages This adds printk messages with basic information about the driver being loaded. This information includes a summary of the compiled-in features, which simplifies bug-reporting and debugging a lot. Also a firmware ID is printed. This is a unique identifier blob for a specific version of the firmware. This ID is attached to a specific version of the firmware blob in b43-fwcutter (see fwcutter git). This helps users to select the right firmware for their device. This also makes it possible to use automated scripts to fetch and extract the right firmware for the driver. (The script will grep the .ko for the "Firmware-ID: xxx" string.) While the driver might still support other versions of the firmware for backward compatibility, this will always print out the officially supported version, which people _should_ use. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/b43legacy.h | 4 +++ drivers/net/wireless/b43legacy/main.c | 30 +++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index c80edd2b9044..93d45b71799a 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -23,6 +23,10 @@ #include "phy.h" +/* The unique identifier of the firmware that's officially supported by this + * driver version. */ +#define B43legacy_SUPPORTED_FIRMWARE_ID "FW10" + #define B43legacy_IRQWAIT_MAX_RETRIES 20 #define B43legacy_RX_MAX_SSI 60 /* best guess at max ssi */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 794c2fa44b90..c39de422e220 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -3,7 +3,7 @@ * Broadcom B43legacy wireless driver * * Copyright (c) 2005 Martin Langer - * Copyright (c) 2005-2007 Stefano Brivio + * Copyright (c) 2005-2008 Stefano Brivio * Copyright (c) 2005, 2006 Michael Buesch * Copyright (c) 2005 Danny van Dyk * Copyright (c) 2005 Andreas Jaggi @@ -3809,6 +3809,32 @@ static struct ssb_driver b43legacy_ssb_driver = { .resume = b43legacy_resume, }; +static void b43legacy_print_driverinfo(void) +{ + const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "", + *feat_pio = "", *feat_dma = ""; + +#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT + feat_pci = "P"; +#endif +#ifdef CONFIG_B43LEGACY_LEDS + feat_leds = "L"; +#endif +#ifdef CONFIG_B43LEGACY_RFKILL + feat_rfkill = "R"; +#endif +#ifdef CONFIG_B43LEGACY_PIO + feat_pio = "I"; +#endif +#ifdef CONFIG_B43LEGACY_DMA + feat_dma = "D"; +#endif + printk(KERN_INFO "Broadcom 43xx driver loaded " + "[ Features: %s%s%s%s%s, Firmware-ID: " + B43legacy_SUPPORTED_FIRMWARE_ID " ]\n", + feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma); +} + static int __init b43legacy_init(void) { int err; @@ -3819,6 +3845,8 @@ static int __init b43legacy_init(void) if (err) goto err_dfs_exit; + b43legacy_print_driverinfo(); + return err; err_dfs_exit: From 08f01058fe8fcf0d4d69d96d667c51d52859b31d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 14 Feb 2008 10:45:20 -0800 Subject: [PATCH 121/880] ata: make ata_scsiop_inq_89 static in libata-scsi.c Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c02c490122dc..1cea18f62abc 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1862,7 +1862,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, * spin_lock_irqsave(host lock) */ -unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf, +static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen) { u8 pbuf[60]; From eeb37ac87459f8e86d53243bd97e0c086de7eb87 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 14 Feb 2008 10:45:23 -0800 Subject: [PATCH 122/880] ata: fix sparse warning in libata-core.c rc is used to test the return value and possibly return an error. No need to redeclare inside the loop. drivers/ata/libata-core.c:7089:7: warning: symbol 'rc' shadows an earlier one drivers/ata/libata-core.c:7030:9: originally declared here Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 004dae4ea5bc..beaa3a9d8b6d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -7086,7 +7086,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) DPRINTK("probe begin\n"); for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; - int rc; /* probe */ if (ap->ops->error_handler) { From 018d982721209241ede1180aa795d68833c26b10 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:05 -0800 Subject: [PATCH 123/880] ata: fix sparse warning in ata_piix.c drivers/ata/ata_piix.c:1655:8: warning: symbol 'rc' shadows an earlier one drivers/ata/ata_piix.c:1616:6: originally declared here Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 9c2515f67de5..752e7d2f3b2f 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1652,7 +1652,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, u8 tmp; pci_read_config_byte(pdev, PIIX_SCC, &tmp); if (tmp == PIIX_AHCI_DEVICE) { - int rc = piix_disable_ahci(pdev); + rc = piix_disable_ahci(pdev); if (rc) return rc; } From 6903c0f7efe907ada1b9636b52c5ae11fd51ab68 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:08 -0800 Subject: [PATCH 124/880] ata: fix sparse warning in sata_promise.c drivers/ata/sata_promise.c:546:15: warning: symbol 'len' shadows an earlier one drivers/ata/sata_promise.c:538:6: originally declared here len is set again immediately after the loop, so this is safe. Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/sata_promise.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index a07d319f6e8c..f251a5f569d5 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -543,7 +543,7 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc) idx = 0; for_each_sg(qc->sg, sg, qc->n_elem, si) { u32 addr, offset; - u32 sg_len, len; + u32 sg_len; /* determine if physical DMA addr spans 64K boundary. * Note h/w doesn't support 64-bit, so we unconditionally From 48e1f800eaa08eefe00476b83a7983b707d31848 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:11 -0800 Subject: [PATCH 125/880] ata: fix sparse warning in sata_via.c drivers/ata/sata_via.c:336:2: warning: returning void-valued expression Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 30caa0337190..0d03f44824fb 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -333,8 +333,8 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline) static void vt6420_error_handler(struct ata_port *ap) { - return ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset, - NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset, NULL, + ata_std_postreset); } static int vt6421_pata_cable_detect(struct ata_port *ap) From 5ab063e397d9f6fcadb37a07465efcc87f9e9345 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:14 -0800 Subject: [PATCH 126/880] ata: fix sparse warnings in sata_mv.c pp is never used again in this function, no need to declare a new one. drivers/ata/sata_mv.c:1545:24: warning: symbol 'pp' shadows an earlier one drivers/ata/sata_mv.c:1501:22: originally declared here drivers/ata/sata_mv.c:1553:24: warning: symbol 'pp' shadows an earlier one drivers/ata/sata_mv.c:1501:22: originally declared here Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 04b571764aff..2ecd44db4142 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1542,7 +1542,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) eh_freeze_mask = EDMA_EH_FREEZE_5; if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { - struct mv_port_priv *pp = ap->private_data; + pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; ata_ehi_push_desc(ehi, "EDMA self-disable"); } @@ -1550,7 +1550,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) eh_freeze_mask = EDMA_EH_FREEZE; if (edma_err_cause & EDMA_ERR_SELF_DIS) { - struct mv_port_priv *pp = ap->private_data; + pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; ata_ehi_push_desc(ehi, "EDMA self-disable"); } From 7a3a16fe7ddf0570e2fcf286d7e244a5e1e16f6a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 13 Feb 2008 18:20:19 +0900 Subject: [PATCH 127/880] pata_legacy: don't call ata_host_detach() after initialization failure ata_host_detach() detaches an attached port and shouldn't be called on a port which hasn't been attached yet. pata_legacy incorrectly calls ata_host_detach() on unattached port after initialization failure causing oops. Fix it. Signed-off-by: Tejun Heo Cc: Alan Cox Cc: Ingo Molnar Cc: Arjan van de Ven Signed-off-by: Jeff Garzik --- drivers/ata/pata_legacy.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 6c59969fd50b..d2177f75078a 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -1278,8 +1278,6 @@ static __init int legacy_init_one(struct legacy_probe *probe) } } fail: - if (host) - ata_host_detach(host); platform_device_unregister(pdev); return ret; } From b6966a61a8b5df2987856c81f39a8fd014d32a80 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 13 Feb 2008 01:41:44 -0500 Subject: [PATCH 128/880] pata_cs5536.c bugfix Fix speed negotiation for secondary device. Signed-off-by: Martin K. Petersen Signed-off-by: Jeff Garzik --- drivers/ata/pata_cs5536.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index d753e568588e..89fc8db1fb32 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -40,7 +40,7 @@ #include #define DRV_NAME "pata_cs5536" -#define DRV_VERSION "0.0.6" +#define DRV_VERSION "0.0.7" enum { CFG = 0, @@ -153,8 +153,8 @@ static void cs5536_set_piomode(struct ata_port *ap, struct ata_device *adev) struct ata_device *pair = ata_dev_pair(adev); int mode = adev->pio_mode - XFER_PIO_0; int cmdmode = mode; - int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT; - int cshift = ap->port_no ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT; + int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT; + int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT; u32 dtc, cast, etc; if (pair) @@ -201,7 +201,7 @@ static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev) struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 dtc, etc; int mode = adev->dma_mode; - int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT; + int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT; if (mode >= XFER_UDMA_0) { cs5536_read(pdev, ETC, &etc); From 1ec414ecc0fe09a610dfafcc6958103a37b7eb0f Mon Sep 17 00:00:00 2001 From: Akira Iguchi Date: Wed, 13 Feb 2008 11:55:07 +0900 Subject: [PATCH 129/880] pata_scc.c: add thaw ops This patch adds default thaw ops and fixes the freeze/thaw inconsistency. Signed-off-by: Kou Ishizaki Signed-off-by: Akira Iguchi Signed-off-by: Jeff Garzik --- drivers/ata/pata_scc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 55055b27524c..6c016deeaed8 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -1007,6 +1007,8 @@ static const struct ata_port_operations scc_pata_ops = { .qc_issue = ata_qc_issue_prot, .freeze = scc_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = scc_error_handler, .post_internal_cmd = scc_bmdma_stop, From d98f88c222bf56cfa5839930fb0d0af22d1c36bf Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:20 -0800 Subject: [PATCH 130/880] ata: sparse fixes for pata_amd.c drop return statement. drivers/ata/pata_amd.c:149:2: warning: returning void-valued expression Commit ce54d1616302117fa98513ae916bb3333e1c02ea pata_amd: update mode selection for NV PATAs added the initializer for nv_mode_filter but missed deleting the previously set mode_filter drivers/ata/pata_amd.c:509:3: warning: Initializer entry defined twice drivers/ata/pata_amd.c:521:3: also defined here drivers/ata/pata_amd.c:544:3: warning: Initializer entry defined twice drivers/ata/pata_amd.c:556:3: also defined here Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/pata_amd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index ea567e2b1703..4b8d9b592ca4 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -146,9 +146,8 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline) static void amd_error_handler(struct ata_port *ap) { - return ata_bmdma_drive_eh(ap, amd_pre_reset, - ata_std_softreset, NULL, - ata_std_postreset); + ata_bmdma_drive_eh(ap, amd_pre_reset, ata_std_softreset, NULL, + ata_std_postreset); } static int amd_cable_detect(struct ata_port *ap) @@ -506,7 +505,6 @@ static struct ata_port_operations amd133_port_ops = { static struct ata_port_operations nv100_port_ops = { .set_piomode = nv100_set_piomode, .set_dmamode = nv100_set_dmamode, - .mode_filter = ata_pci_default_filter, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, @@ -541,7 +539,6 @@ static struct ata_port_operations nv100_port_ops = { static struct ata_port_operations nv133_port_ops = { .set_piomode = nv133_set_piomode, .set_dmamode = nv133_set_dmamode, - .mode_filter = ata_pci_default_filter, .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, From 2072fb55cf2400f2f7f4b47849b69f440bb9808f Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:23 -0800 Subject: [PATCH 131/880] ata: fix sparse warning in pata_cs5536.c Everybody passes in a u32...why fight it. drivers/ata/pata_cs5536.c:124:26: warning: incorrect type in argument 3 (different signedness) drivers/ata/pata_cs5536.c:124:26: expected int *val drivers/ata/pata_cs5536.c:124:26: got unsigned int * Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/pata_cs5536.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 89fc8db1fb32..1c4ff9b52b5c 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -85,7 +85,7 @@ static const u8 pci_reg[4] = { PCI_IDE_CFG, PCI_IDE_DTC, PCI_IDE_CAST, PCI_IDE_ETC, }; -static inline int cs5536_read(struct pci_dev *pdev, int reg, int *val) +static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val) { if (unlikely(use_msr)) { u32 dummy; From ef2f2e4911654f0bc3b432b3d27e7c4d992efb7b Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:26 -0800 Subject: [PATCH 132/880] ata: fix sparse warning in pata_jmicron.c drivers/ata/pata_jmicron.c:118:2: warning: returning void-valued expression Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/pata_jmicron.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 5b8174d94067..00bbbbd50e97 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -115,7 +115,8 @@ static int jmicron_pre_reset(struct ata_link *link, unsigned long deadline) static void jmicron_error_handler(struct ata_port *ap) { - return ata_bmdma_drive_eh(ap, jmicron_pre_reset, ata_std_softreset, NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, jmicron_pre_reset, ata_std_softreset, NULL, + ata_std_postreset); } /* No PIO or DMA methods needed for this device */ From 42268e26aa9d2b6d0d1f890c354447f185fc2624 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:29 -0800 Subject: [PATCH 133/880] ata: fix sparse warning in pata_marvell.c drivers/ata/pata_marvell.c:88:2: warning: returning void-valued expression Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/pata_marvell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 9afc8a32b226..a81f25d87235 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -85,8 +85,8 @@ static int marvell_cable_detect(struct ata_port *ap) static void marvell_error_handler(struct ata_port *ap) { - return ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset, - NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset, NULL, + ata_std_postreset); } /* No PIO or DMA methods needed for this device */ From 5410f729e331bd607d99057ece59f6d7866cd3dc Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 21:14:31 -0800 Subject: [PATCH 134/880] ata: fix sparse warning in pata_acpi.c drivers/ata/pata_acpi.c:80:2: warning: returning void-valued expression Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/pata_acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 244098a80ce4..bdc3b9d7395c 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -77,8 +77,8 @@ static int pacpi_cable_detect(struct ata_port *ap) static void pacpi_error_handler(struct ata_port *ap) { - return ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset, - NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset, NULL, + ata_std_postreset); } /** From 825f1481ead4ce40671089bae7412ac3519e8caa Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 15 Feb 2008 15:00:38 -0500 Subject: [PATCH 135/880] ext4: Don't use ext4_dec_count() if not needed The ext4_dec_count() function is only needed when dropping the i_nlink count on inodes which are (or which could be) directories. If we *know* that the inode in question can't possibly be a directory, use drop_nlink or clear_nlink() if we know i_nlink is 1. Signed-off-by: "Theodore Ts'o" --- fs/ext4/namei.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index fffd0807a01b..5a79c6b6dc69 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2161,7 +2161,7 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry) dir->i_ctime = dir->i_mtime = ext4_current_time(dir); ext4_update_dx_flag(dir); ext4_mark_inode_dirty(handle, dir); - ext4_dec_count(handle, inode); + drop_nlink(inode); if (!inode->i_nlink) ext4_orphan_add(handle, inode); inode->i_ctime = ext4_current_time(inode); @@ -2211,7 +2211,7 @@ static int ext4_symlink (struct inode * dir, err = __page_symlink(inode, symname, l, mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); if (err) { - ext4_dec_count(handle, inode); + clear_nlink(inode); ext4_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; @@ -2404,7 +2404,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, ext4_dec_count(handle, old_dir); if (new_inode) { /* checked empty_dir above, can't have another parent, - * ext3_dec_count() won't work for many-linked dirs */ + * ext4_dec_count() won't work for many-linked dirs */ new_inode->i_nlink = 0; } else { ext4_inc_count(handle, new_dir); From c7482b81c8b524193d736488c149adbe27a7eb7f Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 15 Feb 2008 10:24:49 +0800 Subject: [PATCH 136/880] IB: Fix return value in ib_device_register_sysfs() If kobject_create_and_add() fails and returns NULL, the current code in ib_device_register_sysfs() does not set ret and hence returns 0. Set ret to -ENOMEM for this failure, so that the caller knows that ib_device_register_sysfs() actually failed. Signed-off-by: Li Zefan Signed-off-by: Roland Dreier --- drivers/infiniband/core/sysfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index c864ef70fdf9..5a4b2e65534b 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -686,8 +686,10 @@ int ib_device_register_sysfs(struct ib_device *device) device->ports_parent = kobject_create_and_add("ports", kobject_get(&class_dev->kobj)); - if (!device->ports_parent) + if (!device->ports_parent) { + ret = -ENOMEM; goto err_put; + } if (device->node_type == RDMA_NODE_IB_SWITCH) { ret = add_port(device, 0); From 11e0704b7ec3abfeaee7e3a56f11c82024d1ae01 Mon Sep 17 00:00:00 2001 From: Glenn Streiff Date: Fri, 15 Feb 2008 11:41:27 -0600 Subject: [PATCH 137/880] RDMA/nes: Fix MAC interrupt erroneously masked on ifdown Only mask out MAC interrupt if necessary and re-enable on ifup. There could be multiple netdevs going through the same MAC. MAC interrupts should not be masked off until the last netdev is downed. Signed-off-by: Chien Tung Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_nic.c | 52 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index b6cc265aa9a4..67827ad894e9 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -148,14 +148,15 @@ static int nes_netdev_open(struct net_device *netdev) struct nes_device *nesdev = nesvnic->nesdev; int ret; int i; - struct nes_vnic *first_nesvnic; + struct nes_vnic *first_nesvnic = NULL; u32 nic_active_bit; u32 nic_active; + struct list_head *list_pos, *list_temp; assert(nesdev != NULL); - first_nesvnic = list_entry(nesdev->nesadapter->nesvnic_list[nesdev->mac_index].next, - struct nes_vnic, list); + if (nesvnic->netdev_open == 1) + return 0; if (netif_msg_ifup(nesvnic)) printk(KERN_INFO PFX "%s: enabling interface\n", netdev->name); @@ -225,7 +226,18 @@ static int nes_netdev_open(struct net_device *netdev) nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT | nesvnic->nic_cq.cq_number); nes_read32(nesdev->regs+NES_CQE_ALLOC); - + list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) { + first_nesvnic = container_of(list_pos, struct nes_vnic, list); + if (first_nesvnic->netdev_open == 1) + break; + } + if (first_nesvnic->netdev_open == 0) { + nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n"); + nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index), + ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT | + NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR)); + first_nesvnic = nesvnic; + } if (first_nesvnic->linkup) { /* Enable network packets */ nesvnic->linkup = 1; @@ -248,6 +260,8 @@ static int nes_netdev_stop(struct net_device *netdev) struct nes_device *nesdev = nesvnic->nesdev; u32 nic_active_mask; u32 nic_active; + struct nes_vnic *first_nesvnic = NULL; + struct list_head *list_pos, *list_temp; nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n", nesvnic, nesdev, netdev, netdev->name); @@ -260,9 +274,20 @@ static int nes_netdev_stop(struct net_device *netdev) /* Disable network packets */ napi_disable(&nesvnic->napi); netif_stop_queue(netdev); - if ((nesdev->netdev[0] == netdev) & (nesvnic->logical_port == nesdev->mac_index)) { - nes_write_indexed(nesdev, - NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff); + list_for_each_safe(list_pos, list_temp, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]) { + first_nesvnic = container_of(list_pos, struct nes_vnic, list); + if ((first_nesvnic->netdev_open == 1) && (first_nesvnic != nesvnic)) + break; + } + + if (first_nesvnic->netdev_open == 0) + nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff); + else if ((first_nesvnic != nesvnic) && + (PCI_FUNC(first_nesvnic->nesdev->pcidev->devfn) != PCI_FUNC(nesvnic->nesdev->pcidev->devfn))) { + nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK + (0x200 * nesdev->mac_index), 0xffffffff); + nes_write_indexed(first_nesvnic->nesdev, NES_IDX_MAC_INT_MASK + (0x200 * first_nesvnic->nesdev->mac_index), + ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT | + NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR)); } nic_active_mask = ~((u32)(1 << nesvnic->nic_index)); @@ -859,7 +884,6 @@ void nes_netdev_set_multicast_list(struct net_device *netdev) for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) { while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0)) multicast_addr = multicast_addr->next; - if (mc_nic_index < 0) mc_nic_index = nesvnic->nic_index; if (multicast_addr) { @@ -1610,7 +1634,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); if ((nesdev->netdev_count == 0) && - (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { + (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1))); u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + @@ -1648,18 +1672,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, nesvnic->linkup = 1; } } - nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n"); /* clear the MAC interrupt status, assumes direct logical to physical mapping */ - u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port)); + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); - nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port), u32temp); + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); - if (nesdev->nesadapter->phy_type[nesvnic->logical_port] != NES_PHY_TYPE_IRIS) + if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_IRIS) nes_init_phy(nesdev); - nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesvnic->logical_port), - ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT | - NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR)); } return netdev; From 5958f1a4da39581074bab50cabd0a582e651b90f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 3 Feb 2008 15:06:25 -0800 Subject: [PATCH 138/880] kernel-doc: fix pci-acpi warning Fix PCI kernel-doc warning: Warning(linux-2.6.24-git12//drivers/pci/pci-acpi.c:166): No description found for parameter 'hid' Signed-off-by: Randy Dunlap Signed-off-by: Len Brown --- drivers/pci/pci-acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e569645d59e2..2f2d308c9aa3 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -158,6 +158,7 @@ acpi_run_osc ( /** * __pci_osc_support_set - register OS support to Firmware * @flags: OS support bits + * @hid: hardware ID * * Update OS support fields and doing a _OSC Query to obtain an update * from Firmware on supported control bits. From c751670902c3dd9abbed279170a832e6a1e6cf94 Mon Sep 17 00:00:00 2001 From: Thomas Sujith Date: Fri, 15 Feb 2008 00:58:50 -0500 Subject: [PATCH 139/880] thermal: validate input parameters Added sanity check to make sure that thermal zone and cooling device exists. Signed-off-by: Thomas Sujith Signed-off-by: Len Brown --- drivers/thermal/thermal.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c index e782b3e7fcdb..5f1d318f0574 100644 --- a/drivers/thermal/thermal.c +++ b/drivers/thermal/thermal.c @@ -306,12 +306,23 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, { struct thermal_cooling_device_instance *dev; struct thermal_cooling_device_instance *pos; + struct thermal_zone_device *pos1; + struct thermal_cooling_device *pos2; int result; if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE)) return -EINVAL; - if (!tz || !cdev) + list_for_each_entry(pos1, &thermal_tz_list, node) { + if (pos1 == tz) + break; + } + list_for_each_entry(pos2, &thermal_cdev_list, node) { + if (pos2 == cdev) + break; + } + + if (tz != pos1 || cdev != pos2) return -EINVAL; dev = From 3e6fda5c1159823fc02463eceb564c8bfc0e7a0e Mon Sep 17 00:00:00 2001 From: Thomas Sujith Date: Fri, 15 Feb 2008 00:59:50 -0500 Subject: [PATCH 140/880] thermal: use ERR_PTR for returning error Need to return using ERR_PTR instead of NULL in case of errors. Signed-off-by: Thomas Sujith Signed-off-by: Len Brown --- drivers/thermal/thermal.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c index 5f1d318f0574..8b86e53ccf7a 100644 --- a/drivers/thermal/thermal.c +++ b/drivers/thermal/thermal.c @@ -448,20 +448,20 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, int result; if (strlen(type) >= THERMAL_NAME_LENGTH) - return NULL; + return ERR_PTR(-EINVAL); if (!ops || !ops->get_max_state || !ops->get_cur_state || !ops->set_cur_state) - return NULL; + return ERR_PTR(-EINVAL); cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL); if (!cdev) - return NULL; + return ERR_PTR(-ENOMEM); result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id); if (result) { kfree(cdev); - return NULL; + return ERR_PTR(result); } strcpy(cdev->type, type); @@ -473,7 +473,7 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, if (result) { release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); kfree(cdev); - return NULL; + return ERR_PTR(result); } /* sys I/F */ @@ -509,7 +509,7 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, unregister: release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); device_unregister(&cdev->device); - return NULL; + return ERR_PTR(result); } EXPORT_SYMBOL(thermal_cooling_device_register); @@ -581,17 +581,17 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, int count; if (strlen(type) >= THERMAL_NAME_LENGTH) - return NULL; + return ERR_PTR(-EINVAL); if (trips > THERMAL_MAX_TRIPS || trips < 0) - return NULL; + return ERR_PTR(-EINVAL); if (!ops || !ops->get_temp) - return NULL; + return ERR_PTR(-EINVAL); tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL); if (!tz) - return NULL; + return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&tz->cooling_devices); idr_init(&tz->idr); @@ -599,7 +599,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id); if (result) { kfree(tz); - return NULL; + return ERR_PTR(result); } strcpy(tz->type, type); @@ -612,7 +612,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, if (result) { release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); kfree(tz); - return NULL; + return ERR_PTR(result); } /* sys I/F */ @@ -654,7 +654,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, unregister: release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); device_unregister(&tz->device); - return NULL; + return ERR_PTR(result); } EXPORT_SYMBOL(thermal_zone_device_register); From 19b36780ee7ddeb5080e3f1f858a83c4824f1fdc Mon Sep 17 00:00:00 2001 From: Thomas Sujith Date: Fri, 15 Feb 2008 01:01:52 -0500 Subject: [PATCH 141/880] ACPI fan: extract return values using PTR_ERR Need to extract errors using PTR_ERR macro and process accordingly. thermal_cooling_device_register returning NULL means that CONFIG_THERMAL=n and in that case no need to create symbolic links. Signed-off-by: Thomas Sujith Signed-off-by: Len Brown --- drivers/acpi/fan.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 48cb705b274a..c8e3cba423ef 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -256,22 +256,28 @@ static int acpi_fan_add(struct acpi_device *device) cdev = thermal_cooling_device_register("Fan", device, &fan_cooling_ops); - if (cdev) + if (IS_ERR(cdev)) { + result = PTR_ERR(cdev); + goto end; + } + if (cdev) { printk(KERN_INFO PREFIX "%s is registered as cooling_device%d\n", device->dev.bus_id, cdev->id); - else - goto end; - acpi_driver_data(device) = cdev; - result = sysfs_create_link(&device->dev.kobj, &cdev->device.kobj, - "thermal_cooling"); - if (result) - return result; - result = sysfs_create_link(&cdev->device.kobj, &device->dev.kobj, - "device"); - if (result) - return result; + acpi_driver_data(device) = cdev; + result = sysfs_create_link(&device->dev.kobj, + &cdev->device.kobj, + "thermal_cooling"); + if (result) + return result; + + result = sysfs_create_link(&cdev->device.kobj, + &device->dev.kobj, + "device"); + if (result) + return result; + } result = acpi_fan_add_fs(device); if (result) From f28bb45e2863173a7464d98907677e903f42c68b Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Fri, 15 Feb 2008 08:34:37 +0800 Subject: [PATCH 142/880] ACPI: thermal: Check whether cooling device exists before unregistering OS should check whether the cooling device exists before it is unregistered. If it doesn't exists, it is unnecessary to remove the sysfs link and call the function of thermal_cooling_device_unregister. http://bugzilla.kernel.org/show_bug.cgi?id=9982 Signed-off-by: Zhao Yakui Tested-by : Dhaval Giani Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 75ccf5d18bf4..697335c8423e 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -809,10 +809,12 @@ static int acpi_processor_remove(struct acpi_device *device, int type) acpi_processor_remove_fs(device); - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); - sysfs_remove_link(&pr->cdev->device.kobj, "device"); - thermal_cooling_device_unregister(pr->cdev); - pr->cdev = NULL; + if (pr->cdev) { + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); + sysfs_remove_link(&pr->cdev->device.kobj, "device"); + thermal_cooling_device_unregister(pr->cdev); + pr->cdev = NULL; + } processors[pr->id] = NULL; From d76628c67cdeebf84766a19c67c821c2e518baa4 Mon Sep 17 00:00:00 2001 From: Thomas Sujith Date: Fri, 15 Feb 2008 18:26:54 -0500 Subject: [PATCH 143/880] ACPI thermal: extract return values using PTR_ERR Need to extract errors using PTR_ERR macro and process accordingly.thermal_cooling_device_register returning NULL means that CONFIG_THERMAL=n and in that case no need to create symbolic links. Signed-off-by: Thomas Sujith Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 37 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 75ccf5d18bf4..b02006951cd0 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -670,21 +670,26 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) pr->cdev = thermal_cooling_device_register("Processor", device, &processor_cooling_ops); - if (pr->cdev) + if (IS_ERR(pr->cdev)) { + result = PTR_ERR(pr->cdev); + goto end; + } + if (pr->cdev) { printk(KERN_INFO PREFIX "%s is registered as cooling_device%d\n", device->dev.bus_id, pr->cdev->id); - else - goto end; - result = sysfs_create_link(&device->dev.kobj, &pr->cdev->device.kobj, - "thermal_cooling"); - if (result) - return result; - result = sysfs_create_link(&pr->cdev->device.kobj, &device->dev.kobj, - "device"); - if (result) - return result; + result = sysfs_create_link(&device->dev.kobj, + &pr->cdev->device.kobj, + "thermal_cooling"); + if (result) + return result; + result = sysfs_create_link(&pr->cdev->device.kobj, + &device->dev.kobj, + "device"); + if (result) + return result; + } if (pr->flags.throttling) { printk(KERN_INFO PREFIX "%s [%s] (supports", @@ -809,10 +814,12 @@ static int acpi_processor_remove(struct acpi_device *device, int type) acpi_processor_remove_fs(device); - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); - sysfs_remove_link(&pr->cdev->device.kobj, "device"); - thermal_cooling_device_unregister(pr->cdev); - pr->cdev = NULL; + if (pr->cdev) { + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); + sysfs_remove_link(&pr->cdev->device.kobj, "device"); + thermal_cooling_device_unregister(pr->cdev); + pr->cdev = NULL; + } processors[pr->id] = NULL; From 43ff39f2f6450fa2e9a566f8bf007a26d76f2c9d Mon Sep 17 00:00:00 2001 From: Thomas Sujith Date: Fri, 15 Feb 2008 18:29:18 -0500 Subject: [PATCH 144/880] ACPI video: check for error from thermal_cooling_device_register Need to check whether thermal_cooling_device_register returned ERROR or not. Signed-off-by: Thomas Sujith Signed-off-by: Len Brown --- drivers/acpi/video.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 7f714fa2a454..12cce69b5441 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -731,6 +731,9 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->cdev = thermal_cooling_device_register("LCD", device->dev, &video_cooling_ops); + if (IS_ERR(device->cdev)) + return; + if (device->cdev) { printk(KERN_INFO PREFIX "%s is registered as cooling_device%d\n", From 69f6b8dd6b94ac594b6920b4530a3390fb1d3fd6 Mon Sep 17 00:00:00 2001 From: Thomas Sujith Date: Fri, 15 Feb 2008 01:05:23 -0500 Subject: [PATCH 145/880] intel_menlo: extract return values using PTR_ERR Need to extract errors using PTR_ERR macro and process accordingly.thermal_cooling_device_register returning NULL means that CONFIG_THERMAL=n and in that case no need to create symbolic links. Signed-off-by: Thomas Sujith Signed-off-by: Len Brown --- drivers/misc/intel_menlow.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c index f70984ab1e1b..de16e88eb8d3 100644 --- a/drivers/misc/intel_menlow.c +++ b/drivers/misc/intel_menlow.c @@ -170,10 +170,13 @@ static int intel_menlow_memory_add(struct acpi_device *device) cdev = thermal_cooling_device_register("Memory controller", device, &memory_cooling_ops); - acpi_driver_data(device) = cdev; - if (!cdev) - result = -ENODEV; - else { + if (IS_ERR(cdev)) { + result = PTR_ERR(cdev); + goto end; + } + + if (cdev) { + acpi_driver_data(device) = cdev; result = sysfs_create_link(&device->dev.kobj, &cdev->device.kobj, "thermal_cooling"); if (result) From 2278e8119d9465b498763af7c1077b558f7599b1 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 6 Feb 2008 23:21:59 +1100 Subject: [PATCH 146/880] [POWERPC] net: NEWEMAC: Remove "rgmii-interface" from rgmii matching table With the removal the the "rgmii-interface" device_type property from the dts files, the newemac driver needs an update to only rely on compatible property. Signed-off-by: Stefan Roese Acked-by: Benjamin Herrenschmidt Acked-by: Jeff Garzik Signed-off-by: Josh Boyer --- drivers/net/ibm_newemac/rgmii.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 9bc1132fa788..5757788227be 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -302,7 +302,6 @@ static int __devexit rgmii_remove(struct of_device *ofdev) static struct of_device_id rgmii_match[] = { { - .type = "rgmii-interface", .compatible = "ibm,rgmii", }, { From 7fe5f10ed032251f35258be2ee5296bca4299471 Mon Sep 17 00:00:00 2001 From: Wolfgang Ocker Date: Mon, 11 Feb 2008 06:24:02 +1100 Subject: [PATCH 147/880] [POWERPC] PPC440EP Interrupt Triggering and Level Settings Corrected IRQ triggering and level settings according to latest revision of the 440EP User Manual (rev 1.24 nov 16, 2007). The incorrect settings might cause a failure of the network if both onchip ethernet ports are under heavy load. Signed-off-by: Wolfgang Ocker Acked-by: Stefan Roese Signed-off-by: Josh Boyer --- arch/ppc/platforms/4xx/ibm440ep.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c index 1fed6638c81f..0de91532aabb 100644 --- a/arch/ppc/platforms/4xx/ibm440ep.c +++ b/arch/ppc/platforms/4xx/ibm440ep.c @@ -172,11 +172,11 @@ struct ocp_def core_ocp[] = { /* Polarity and triggering settings for internal interrupt sources */ struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = { { .polarity = 0xffbffe03, - .triggering = 0xfffffe00, + .triggering = 0x00000000, .ext_irq_mask = 0x000001fc, /* IRQ0 - IRQ6 */ }, - { .polarity = 0xffffc6ef, - .triggering = 0xffffc7ff, + { .polarity = 0xffffc6af, + .triggering = 0x06000140, .ext_irq_mask = 0x00003800, /* IRQ7 - IRQ9 */ }, }; From e563db977f58836c30ce3ee7cb6719c47feac4be Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 16 Jan 2008 20:00:00 +1100 Subject: [PATCH 148/880] [POWERPC] 4xx: Remove "i2c" and "xxmii-interface" device_types from dts Remove all "i2c" and "xxmii-interface" (rgmii etc) device_type entries from the 4xx dts files. Signed-off-by: Stefan Roese Signed-off-by: Josh Boyer --- arch/powerpc/boot/dts/bamboo.dts | 3 --- arch/powerpc/boot/dts/ebony.dts | 2 -- arch/powerpc/boot/dts/katmai.dts | 2 -- arch/powerpc/boot/dts/kilauea.dts | 3 --- arch/powerpc/boot/dts/makalu.dts | 3 --- arch/powerpc/boot/dts/rainier.dts | 4 ---- arch/powerpc/boot/dts/sequoia.dts | 4 ---- arch/powerpc/boot/dts/taishan.dts | 4 ---- 8 files changed, 25 deletions(-) diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts index 29f1a6f3e373..7dc37c9a7446 100644 --- a/arch/powerpc/boot/dts/bamboo.dts +++ b/arch/powerpc/boot/dts/bamboo.dts @@ -185,7 +185,6 @@ }; IIC0: i2c@ef600700 { - device_type = "i2c"; compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -193,7 +192,6 @@ }; IIC1: i2c@ef600800 { - device_type = "i2c"; compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -201,7 +199,6 @@ }; ZMII0: emac-zmii@ef600d00 { - device_type = "zmii-interface"; compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii"; reg = ; }; diff --git a/arch/powerpc/boot/dts/ebony.dts b/arch/powerpc/boot/dts/ebony.dts index 7aad135a44b0..0b000cb7ed8b 100644 --- a/arch/powerpc/boot/dts/ebony.dts +++ b/arch/powerpc/boot/dts/ebony.dts @@ -216,7 +216,6 @@ IIC0: i2c@40000400 { /* FIXME */ - device_type = "i2c"; compatible = "ibm,iic-440gp", "ibm,iic"; reg = <40000400 14>; interrupt-parent = <&UIC0>; @@ -224,7 +223,6 @@ }; IIC1: i2c@40000500 { /* FIXME */ - device_type = "i2c"; compatible = "ibm,iic-440gp", "ibm,iic"; reg = <40000500 14>; interrupt-parent = <&UIC0>; diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts index 9bdfc0ff3c24..bc32ac7250ec 100644 --- a/arch/powerpc/boot/dts/katmai.dts +++ b/arch/powerpc/boot/dts/katmai.dts @@ -187,7 +187,6 @@ }; IIC0: i2c@10000400 { - device_type = "i2c"; compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; reg = <10000400 14>; interrupt-parent = <&UIC0>; @@ -195,7 +194,6 @@ }; IIC1: i2c@10000500 { - device_type = "i2c"; compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; reg = <10000500 14>; interrupt-parent = <&UIC0>; diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts index 67c7ea179a07..8baef61f31cd 100644 --- a/arch/powerpc/boot/dts/kilauea.dts +++ b/arch/powerpc/boot/dts/kilauea.dts @@ -182,7 +182,6 @@ }; IIC0: i2c@ef600400 { - device_type = "i2c"; compatible = "ibm,iic-405ex", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -190,7 +189,6 @@ }; IIC1: i2c@ef600500 { - device_type = "i2c"; compatible = "ibm,iic-405ex", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -199,7 +197,6 @@ RGMII0: emac-rgmii@ef600b00 { - device_type = "rgmii-interface"; compatible = "ibm,rgmii-405ex", "ibm,rgmii"; reg = ; has-mdio; diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts index bdd70e4596ae..710c01168179 100644 --- a/arch/powerpc/boot/dts/makalu.dts +++ b/arch/powerpc/boot/dts/makalu.dts @@ -182,7 +182,6 @@ }; IIC0: i2c@ef600400 { - device_type = "i2c"; compatible = "ibm,iic-405ex", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -190,7 +189,6 @@ }; IIC1: i2c@ef600500 { - device_type = "i2c"; compatible = "ibm,iic-405ex", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -199,7 +197,6 @@ RGMII0: emac-rgmii@ef600b00 { - device_type = "rgmii-interface"; compatible = "ibm,rgmii-405ex", "ibm,rgmii"; reg = ; has-mdio; diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts index d3c2ac394ce9..f947c75a2e94 100644 --- a/arch/powerpc/boot/dts/rainier.dts +++ b/arch/powerpc/boot/dts/rainier.dts @@ -229,7 +229,6 @@ }; IIC0: i2c@ef600700 { - device_type = "i2c"; compatible = "ibm,iic-440grx", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -237,7 +236,6 @@ }; IIC1: i2c@ef600800 { - device_type = "i2c"; compatible = "ibm,iic-440grx", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -245,13 +243,11 @@ }; ZMII0: emac-zmii@ef600d00 { - device_type = "zmii-interface"; compatible = "ibm,zmii-440grx", "ibm,zmii"; reg = ; }; RGMII0: emac-rgmii@ef601000 { - device_type = "rgmii-interface"; compatible = "ibm,rgmii-440grx", "ibm,rgmii"; reg = ; has-mdio; diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts index 5c13d46f441d..8db9515d7dc3 100644 --- a/arch/powerpc/boot/dts/sequoia.dts +++ b/arch/powerpc/boot/dts/sequoia.dts @@ -244,7 +244,6 @@ }; IIC0: i2c@ef600700 { - device_type = "i2c"; compatible = "ibm,iic-440epx", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -252,7 +251,6 @@ }; IIC1: i2c@ef600800 { - device_type = "i2c"; compatible = "ibm,iic-440epx", "ibm,iic"; reg = ; interrupt-parent = <&UIC0>; @@ -260,13 +258,11 @@ }; ZMII0: emac-zmii@ef600d00 { - device_type = "zmii-interface"; compatible = "ibm,zmii-440epx", "ibm,zmii"; reg = ; }; RGMII0: emac-rgmii@ef601000 { - device_type = "rgmii-interface"; compatible = "ibm,rgmii-440epx", "ibm,rgmii"; reg = ; has-mdio; diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts index 0706a4a13b9f..8278068c802c 100644 --- a/arch/powerpc/boot/dts/taishan.dts +++ b/arch/powerpc/boot/dts/taishan.dts @@ -203,7 +203,6 @@ IIC0: i2c@40000400 { /* FIXME */ - device_type = "i2c"; compatible = "ibm,iic-440gp", "ibm,iic"; reg = <40000400 14>; interrupt-parent = <&UIC0>; @@ -211,7 +210,6 @@ }; IIC1: i2c@40000500 { /* FIXME */ - device_type = "i2c"; compatible = "ibm,iic-440gp", "ibm,iic"; reg = <40000500 14>; interrupt-parent = <&UIC0>; @@ -225,13 +223,11 @@ }; ZMII0: emac-zmii@40000780 { - device_type = "zgmii-interface"; compatible = "ibm,zmii-440gx", "ibm,zmii"; reg = <40000780 c>; }; RGMII0: emac-rgmii@40000790 { - device_type = "rgmii-interface"; compatible = "ibm,rgmii"; reg = <40000790 8>; }; From 8eb70ea2dbba1d0b15f693a85b60d1f56c527ff2 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Fri, 15 Feb 2008 22:00:19 -0600 Subject: [PATCH 149/880] [POWERPC] 4xx: Update defconfigs for 2.6.25 Update the 4xx defconfigs to remove WANT_DEVICE_TREE and add MTD_OF_PARTS where appropriate. Signed-off-by: Josh Boyer --- arch/powerpc/configs/bamboo_defconfig | 81 +++++++++----- arch/powerpc/configs/ebony_defconfig | 79 +++++++++----- arch/powerpc/configs/ep405_defconfig | 92 +++++++++------- arch/powerpc/configs/kilauea_defconfig | 69 ++++++++---- arch/powerpc/configs/makalu_defconfig | 69 ++++++++---- arch/powerpc/configs/rainier_defconfig | 82 ++++++++++----- arch/powerpc/configs/sequoia_defconfig | 77 ++++++++++---- arch/powerpc/configs/taishan_defconfig | 81 +++++++++----- arch/powerpc/configs/walnut_defconfig | 81 +++++++++----- arch/powerpc/configs/warp_defconfig | 139 +++++++++++++++++-------- 10 files changed, 568 insertions(+), 282 deletions(-) diff --git a/arch/powerpc/configs/bamboo_defconfig b/arch/powerpc/configs/bamboo_defconfig index 1ed9afc9b281..c44db554cdc6 100644 --- a/arch/powerpc/configs/bamboo_defconfig +++ b/arch/powerpc/configs/bamboo_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 10:49:50 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:36:39 2008 # # CONFIG_PPC64 is not set @@ -30,6 +30,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -68,17 +69,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -92,11 +94,13 @@ 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_VM_EVENT_COUNTERS=y @@ -104,6 +108,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -131,13 +142,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -147,8 +160,10 @@ CONFIG_BAMBOO=y # CONFIG_TAISHAN is not set # CONFIG_KATMAI is not set # CONFIG_RAINIER is not set +# CONFIG_WARP is not set CONFIG_440EP=y CONFIG_IBM440EP_ERR42=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -159,7 +174,6 @@ CONFIG_IBM440EP_ERR42=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -175,13 +189,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -201,8 +220,6 @@ CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="" CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="bamboo.dts" CONFIG_ISA_DMA_API=y # @@ -302,6 +319,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -348,7 +366,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set @@ -357,6 +375,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -385,7 +405,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -414,6 +433,9 @@ CONFIG_NETDEV_1000=y # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -438,6 +460,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -450,7 +473,6 @@ CONFIG_NETDEV_10000=y # CONFIG_HIPPI 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 @@ -473,6 +495,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -518,6 +541,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -566,12 +590,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -596,12 +617,10 @@ CONFIG_EXT2_FS=y # 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 @@ -643,8 +662,10 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -675,7 +696,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -692,10 +712,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_KPROBES is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -705,7 +721,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -714,6 +730,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -726,9 +743,9 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set @@ -737,6 +754,7 @@ CONFIG_FORCED_INLINING=y CONFIG_DEBUGGER=y # CONFIG_KGDB is not set # CONFIG_XMON is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -749,6 +767,7 @@ CONFIG_DEBUGGER=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -766,6 +785,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -780,11 +802,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/ebony_defconfig b/arch/powerpc/configs/ebony_defconfig index cf860f166659..07c8d4ce175a 100644 --- a/arch/powerpc/configs/ebony_defconfig +++ b/arch/powerpc/configs/ebony_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 11:16:26 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:50:44 2008 # # CONFIG_PPC64 is not set @@ -29,6 +29,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -67,17 +68,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -91,11 +93,13 @@ 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_VM_EVENT_COUNTERS=y @@ -103,6 +107,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -130,13 +141,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -146,7 +159,9 @@ CONFIG_EBONY=y # CONFIG_TAISHAN is not set # CONFIG_KATMAI is not set # CONFIG_RAINIER is not set +# CONFIG_WARP is not set CONFIG_440GP=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -157,8 +172,8 @@ CONFIG_440GP=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set +CONFIG_OF_RTC=y # # Kernel options @@ -173,13 +188,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_MATH_EMULATION=y +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -198,8 +218,6 @@ CONFIG_VIRT_TO_BUS=y CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="ebony.dts" CONFIG_ISA_DMA_API=y # @@ -299,6 +317,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -335,6 +354,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -420,7 +440,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set @@ -429,6 +449,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -457,7 +479,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -486,6 +507,9 @@ CONFIG_NETDEV_1000=y # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -510,6 +534,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -522,7 +547,6 @@ CONFIG_NETDEV_10000=y # CONFIG_HIPPI 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 @@ -545,6 +569,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -590,6 +615,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -638,12 +664,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -668,12 +691,10 @@ CONFIG_EXT2_FS=y # 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 @@ -726,8 +747,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -758,7 +781,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -776,7 +798,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -# CONFIG_INSTRUMENTATION is not set # # Kernel hacking @@ -786,7 +807,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -795,6 +816,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -807,15 +829,16 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -828,6 +851,7 @@ CONFIG_FORCED_INLINING=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -845,6 +869,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -859,11 +886,13 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set # CONFIG_CRYPTO_HW is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/ep405_defconfig b/arch/powerpc/configs/ep405_defconfig index 3829c9166256..e24240a9a047 100644 --- a/arch/powerpc/configs/ep405_defconfig +++ b/arch/powerpc/configs/ep405_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 11:17:13 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:50:09 2008 # # CONFIG_PPC64 is not set @@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -64,17 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -88,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y @@ -100,6 +104,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -127,13 +138,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -145,6 +158,7 @@ CONFIG_EP405=y CONFIG_405GP=y CONFIG_IBM405_ERR77=y CONFIG_IBM405_ERR51=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -155,7 +169,6 @@ CONFIG_IBM405_ERR51=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -171,13 +184,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -196,11 +214,7 @@ CONFIG_VIRT_TO_BUS=y CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_HIBERNATION_UP_POSSIBLE=y CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="ep405.dts" CONFIG_ISA_DMA_API=y # @@ -300,6 +314,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -336,6 +351,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -423,7 +439,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set @@ -432,6 +448,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -460,7 +478,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -489,6 +506,9 @@ CONFIG_NETDEV_1000=y # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -513,6 +533,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -534,7 +555,6 @@ CONFIG_NETDEV_10000=y # CONFIG_HIPPI 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 @@ -557,6 +577,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -602,6 +623,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -647,6 +669,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options @@ -697,10 +720,6 @@ CONFIG_USB_MON=y # # USB port drivers # - -# -# USB Serial Converter support -# # CONFIG_USB_SERIAL is not set # @@ -725,16 +744,9 @@ CONFIG_USB_MON=y # 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_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -759,12 +771,10 @@ CONFIG_EXT2_FS=y # 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 @@ -807,8 +817,10 @@ CONFIG_TMPFS=y # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -839,7 +851,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -856,10 +867,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_KPROBES is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -869,7 +876,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -878,6 +885,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -890,15 +898,16 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -911,6 +920,7 @@ CONFIG_FORCED_INLINING=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -928,6 +938,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -942,11 +955,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/kilauea_defconfig b/arch/powerpc/configs/kilauea_defconfig index 8dca3d451c0e..2f475391f1d1 100644 --- a/arch/powerpc/configs/kilauea_defconfig +++ b/arch/powerpc/configs/kilauea_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Thu Jan 3 14:21:31 2008 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:51:43 2008 # # CONFIG_PPC64 is not set @@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -64,15 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y # CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -86,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y @@ -98,6 +104,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -125,13 +138,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set CONFIG_PPC4xx_PCI_EXPRESS=y # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -141,6 +156,7 @@ CONFIG_KILAUEA=y # CONFIG_WALNUT is not set # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set CONFIG_405EX=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -151,7 +167,6 @@ CONFIG_405EX=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -167,13 +182,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -192,11 +212,7 @@ CONFIG_VIRT_TO_BUS=y CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_HIBERNATION_UP_POSSIBLE=y CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="kilauea.dts" CONFIG_ISA_DMA_API=y # @@ -296,6 +312,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -332,6 +349,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -418,11 +436,12 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -451,7 +470,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -489,7 +507,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y # CONFIG_HIPPI 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 @@ -512,6 +529,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -557,6 +575,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -598,6 +617,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -622,12 +642,10 @@ CONFIG_EXT2_FS=y # 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 @@ -670,8 +688,10 @@ CONFIG_TMPFS=y # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -702,7 +722,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -719,7 +738,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -# CONFIG_INSTRUMENTATION is not set # # Kernel hacking @@ -729,7 +747,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -738,6 +756,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -750,15 +769,16 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -771,6 +791,7 @@ CONFIG_FORCED_INLINING=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -788,6 +809,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -802,11 +826,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/makalu_defconfig b/arch/powerpc/configs/makalu_defconfig index c5db0265e5d8..9ef4d8a312c8 100644 --- a/arch/powerpc/configs/makalu_defconfig +++ b/arch/powerpc/configs/makalu_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 11:18:32 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:52:30 2008 # # CONFIG_PPC64 is not set @@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -64,15 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y # CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -86,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y @@ -98,6 +104,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -125,13 +138,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set CONFIG_PPC4xx_PCI_EXPRESS=y # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -141,6 +156,7 @@ CONFIG_MAKALU=y # CONFIG_WALNUT is not set # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set CONFIG_405EX=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -151,7 +167,6 @@ CONFIG_405EX=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -167,13 +182,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -192,11 +212,7 @@ CONFIG_VIRT_TO_BUS=y CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_HIBERNATION_UP_POSSIBLE=y CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="kilauea.dts" CONFIG_ISA_DMA_API=y # @@ -296,6 +312,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -332,6 +349,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -418,11 +436,12 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -451,7 +470,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -489,7 +507,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y # CONFIG_HIPPI 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 @@ -512,6 +529,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -557,6 +575,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -598,6 +617,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -622,12 +642,10 @@ CONFIG_EXT2_FS=y # 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 @@ -670,8 +688,10 @@ CONFIG_TMPFS=y # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -702,7 +722,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -719,7 +738,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -# CONFIG_INSTRUMENTATION is not set # # Kernel hacking @@ -729,7 +747,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -738,6 +756,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -750,15 +769,16 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -771,6 +791,7 @@ CONFIG_FORCED_INLINING=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -788,6 +809,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -802,11 +826,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/rainier_defconfig b/arch/powerpc/configs/rainier_defconfig index 7b95001a22a8..dec18ca73519 100644 --- a/arch/powerpc/configs/rainier_defconfig +++ b/arch/powerpc/configs/rainier_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 11:22:40 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:53:10 2008 # # CONFIG_PPC64 is not set @@ -29,6 +29,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -67,17 +68,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -91,11 +93,13 @@ 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_VM_EVENT_COUNTERS=y @@ -103,6 +107,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -130,13 +141,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -146,7 +159,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_TAISHAN is not set # CONFIG_KATMAI is not set CONFIG_RAINIER=y +# CONFIG_WARP is not set CONFIG_440GRX=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -157,7 +172,6 @@ CONFIG_440GRX=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -173,13 +187,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_MATH_EMULATION=y +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -199,8 +218,6 @@ CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="" CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="rainier.dts" CONFIG_ISA_DMA_API=y # @@ -300,6 +317,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -336,6 +354,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -422,7 +441,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set @@ -431,6 +450,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -461,7 +482,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_NET_ETHERNET is not set CONFIG_IBM_NEW_EMAC_ZMII=y @@ -472,6 +492,9 @@ CONFIG_NETDEV_1000=y # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -496,6 +519,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -508,7 +532,6 @@ CONFIG_NETDEV_10000=y # CONFIG_HIPPI 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 @@ -531,6 +554,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -576,6 +600,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -624,12 +649,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -654,12 +676,10 @@ CONFIG_EXT2_FS=y # 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 @@ -712,8 +732,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -744,7 +766,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -762,10 +783,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_KPROBES is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -775,7 +792,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -784,6 +801,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -796,9 +814,9 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set @@ -807,6 +825,7 @@ CONFIG_FORCED_INLINING=y CONFIG_DEBUGGER=y # CONFIG_KGDB is not set # CONFIG_XMON is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set CONFIG_PPC_EARLY_DEBUG=y # CONFIG_PPC_EARLY_DEBUG_LPAR is not set @@ -832,6 +851,7 @@ CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1 CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -849,6 +869,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -863,11 +886,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/sequoia_defconfig b/arch/powerpc/configs/sequoia_defconfig index abbfed6582e1..dd5d6303c396 100644 --- a/arch/powerpc/configs/sequoia_defconfig +++ b/arch/powerpc/configs/sequoia_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 11:23:22 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:53:46 2008 # # CONFIG_PPC64 is not set @@ -30,6 +30,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -68,15 +69,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y # CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -90,11 +94,13 @@ 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_VM_EVENT_COUNTERS=y @@ -102,6 +108,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -129,13 +142,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -145,7 +160,9 @@ CONFIG_SEQUOIA=y # CONFIG_TAISHAN is not set # CONFIG_KATMAI is not set # CONFIG_RAINIER is not set +# CONFIG_WARP is not set CONFIG_440EPX=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -156,7 +173,6 @@ CONFIG_440EPX=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -172,13 +188,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -198,8 +219,6 @@ CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="" CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="sequoia.dts" CONFIG_ISA_DMA_API=y # @@ -299,6 +318,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -335,6 +355,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -421,7 +442,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set @@ -430,6 +451,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -458,7 +481,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -487,6 +509,9 @@ CONFIG_NETDEV_1000=y # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -511,6 +536,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -523,7 +549,6 @@ CONFIG_NETDEV_10000=y # CONFIG_HIPPI 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 @@ -546,6 +571,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -591,6 +617,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -639,12 +666,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -669,12 +693,10 @@ CONFIG_EXT2_FS=y # 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 @@ -727,8 +749,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -759,7 +783,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -777,7 +800,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -# CONFIG_INSTRUMENTATION is not set # # Kernel hacking @@ -787,7 +809,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -796,6 +818,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -808,9 +831,9 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set @@ -819,6 +842,7 @@ CONFIG_FORCED_INLINING=y CONFIG_DEBUGGER=y # CONFIG_KGDB is not set # CONFIG_XMON is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set CONFIG_PPC_EARLY_DEBUG=y # CONFIG_PPC_EARLY_DEBUG_LPAR is not set @@ -844,6 +868,7 @@ CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1 CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -861,6 +886,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -875,11 +903,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/taishan_defconfig b/arch/powerpc/configs/taishan_defconfig index ade84b92877e..087aedce1338 100644 --- a/arch/powerpc/configs/taishan_defconfig +++ b/arch/powerpc/configs/taishan_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 11:23:39 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:40:44 2008 # # CONFIG_PPC64 is not set @@ -29,6 +29,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -67,17 +68,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -91,11 +93,13 @@ 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_VM_EVENT_COUNTERS=y @@ -103,6 +107,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -130,13 +141,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -146,7 +159,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_TAISHAN=y # CONFIG_KATMAI is not set # CONFIG_RAINIER is not set +# CONFIG_WARP is not set CONFIG_440GX=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -157,7 +172,6 @@ CONFIG_440GX=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -173,13 +187,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -199,8 +218,6 @@ CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="" CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="taishan.dts" CONFIG_ISA_DMA_API=y # @@ -300,6 +317,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -346,7 +364,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set @@ -355,6 +373,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -385,7 +405,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -414,6 +433,9 @@ CONFIG_NETDEV_1000=y # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -438,6 +460,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -450,7 +473,6 @@ CONFIG_NETDEV_10000=y # CONFIG_HIPPI 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 @@ -473,6 +495,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -518,6 +541,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -566,12 +590,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -596,12 +617,10 @@ CONFIG_EXT2_FS=y # 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 @@ -643,8 +662,10 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -675,7 +696,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -692,10 +712,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_KPROBES is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -705,7 +721,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -714,6 +730,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -726,9 +743,9 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set @@ -737,6 +754,7 @@ CONFIG_FORCED_INLINING=y CONFIG_DEBUGGER=y # CONFIG_KGDB is not set # CONFIG_XMON is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -749,6 +767,7 @@ CONFIG_DEBUGGER=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -766,6 +785,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -780,11 +802,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/walnut_defconfig b/arch/powerpc/configs/walnut_defconfig index e431128e8e9e..3b2689e5002a 100644 --- a/arch/powerpc/configs/walnut_defconfig +++ b/arch/powerpc/configs/walnut_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Mon Dec 24 11:23:58 2007 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:54:12 2008 # # CONFIG_PPC64 is not set @@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -64,17 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -88,11 +90,13 @@ 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_VM_EVENT_COUNTERS=y @@ -100,6 +104,13 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -127,13 +138,15 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -145,6 +158,7 @@ CONFIG_WALNUT=y CONFIG_405GP=y CONFIG_IBM405_ERR77=y CONFIG_IBM405_ERR51=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -155,8 +169,8 @@ CONFIG_IBM405_ERR51=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set +CONFIG_OF_RTC=y # # Kernel options @@ -171,13 +185,18 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -196,11 +215,7 @@ CONFIG_VIRT_TO_BUS=y CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_HIBERNATION_UP_POSSIBLE=y CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="walnut.dts" CONFIG_ISA_DMA_API=y # @@ -300,6 +315,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -336,6 +352,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -422,7 +439,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE is not set @@ -431,6 +448,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -459,7 +478,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -488,6 +506,9 @@ CONFIG_NETDEV_1000=y # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -512,6 +533,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -524,7 +546,6 @@ CONFIG_NETDEV_10000=y # CONFIG_HIPPI 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 @@ -547,6 +568,7 @@ CONFIG_NETDEV_10000=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -592,6 +614,7 @@ CONFIG_DEVPORT=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -640,12 +663,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_EDAC is not set @@ -670,12 +690,10 @@ CONFIG_EXT2_FS=y # 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 @@ -718,8 +736,10 @@ CONFIG_TMPFS=y # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -750,7 +770,6 @@ CONFIG_SUNRPC=y CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -767,7 +786,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -# CONFIG_INSTRUMENTATION is not set # # Kernel hacking @@ -777,7 +795,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -786,6 +804,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -798,15 +817,16 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -819,6 +839,7 @@ CONFIG_FORCED_INLINING=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -836,6 +857,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -850,11 +874,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # CONFIG_PPC_CLOCK is not set diff --git a/arch/powerpc/configs/warp_defconfig b/arch/powerpc/configs/warp_defconfig index 312557b5df53..2313c3e8ef61 100644 --- a/arch/powerpc/configs/warp_defconfig +++ b/arch/powerpc/configs/warp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Tue Jan 8 12:23:23 2008 +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:54:43 2008 # # CONFIG_PPC64 is not set @@ -30,6 +30,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -68,17 +69,18 @@ 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -92,17 +94,26 @@ CONFIG_KALLSYMS=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_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_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -130,12 +141,14 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PQ2ADS is not set @@ -148,6 +161,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_WARP=y CONFIG_440EP=y CONFIG_IBM440EP_ERR42=y +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -158,7 +172,6 @@ CONFIG_IBM440EP_ERR42=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set # CONFIG_FSL_ULI1575 is not set # @@ -174,13 +187,18 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -200,8 +218,6 @@ CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="ip=on" CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="warp.dts" CONFIG_ISA_DMA_API=y # @@ -244,6 +260,7 @@ 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 @@ -279,12 +296,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y # # Core Netfilter Configuration # -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NF_CONNTRACK_ENABLED is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set # CONFIG_NF_CONNTRACK is not set # CONFIG_NETFILTER_XTABLES is not set @@ -315,6 +333,7 @@ CONFIG_VLAN_8021Q=y # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -348,6 +367,7 @@ CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_OF_PARTS=y # # User Modules And Translation Layers @@ -414,11 +434,11 @@ CONFIG_MTD_NAND=y CONFIG_MTD_NAND_ECC_SMC=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y -CONFIG_MTD_NAND_NDFC=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_NAND_FSL_ELBC is not set # CONFIG_MTD_ONENAND is not set # @@ -436,12 +456,14 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XILINX_SYSACE 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 # @@ -471,7 +493,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set -# CONFIG_SCSI_WAIT_SCAN is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -528,7 +550,6 @@ CONFIG_IBM_NEW_EMAC_ZMII=y # 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 @@ -596,7 +617,6 @@ CONFIG_I2C_BOARDINFO=y # # I2C Hardware Bus support # -CONFIG_I2C_IBM_IIC=y # CONFIG_I2C_MPC is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -608,14 +628,12 @@ CONFIG_I2C_IBM_IIC=y # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set # CONFIG_DS1682 is not set CONFIG_SENSORS_EEPROM=y # CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_M41T00 is not set +# CONFIG_TPS65010 is not set # CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set @@ -632,7 +650,6 @@ CONFIG_SENSORS_EEPROM=y # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -CONFIG_SENSORS_AD7414=y # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -668,6 +685,7 @@ CONFIG_SENSORS_AD7414=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set @@ -675,9 +693,11 @@ CONFIG_SENSORS_AD7414=y # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -721,6 +741,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_USB_ARCH_HAS_EHCI is not set CONFIG_USB=y # CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options @@ -781,10 +802,6 @@ CONFIG_USB_MON=y # # USB port drivers # - -# -# USB Serial Converter support -# # CONFIG_USB_SERIAL is not set # @@ -808,14 +825,6 @@ CONFIG_USB_MON=y # 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=m # CONFIG_MMC_DEBUG is not set @@ -832,6 +841,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD Host Controller Drivers # # CONFIG_MMC_WBSD is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_EDAC is not set # CONFIG_RTC_CLASS is not set @@ -855,12 +865,10 @@ CONFIG_EXT2_FS=y # 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 @@ -915,8 +923,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -986,7 +996,6 @@ CONFIG_NLS_ISO8859_15=y # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -1004,7 +1013,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -# CONFIG_INSTRUMENTATION is not set # # Kernel hacking @@ -1014,7 +1022,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # 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=y # CONFIG_DEBUG_SHIRQ is not set @@ -1035,15 +1043,16 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_VIRQ_DEBUG is not set CONFIG_BDI_SWITCH=y # CONFIG_PPC_EARLY_DEBUG is not set @@ -1053,5 +1062,49 @@ CONFIG_BDI_SWITCH=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_MANAGER is not set +# 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 is not set +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD 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 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y # CONFIG_PPC_CLOCK is not set From 4b63c3b9a636b02793d2edb878e83840d4cdb25f Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Fri, 15 Feb 2008 22:05:03 -0600 Subject: [PATCH 150/880] [POWERPC] 44x: Fix Kconfig formatting Clean up some whitespace issues in the 44x Kconfig file. Signed-off-by: Josh Boyer --- arch/powerpc/platforms/44x/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index c062c4cbbed5..1bfb2191010a 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -61,7 +61,7 @@ config WARP select 440EP help This option enables support for the PIKA Warp(tm) Appliance. The Warp - is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP + is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP stations and trunks. See http://www.pikatechnologies.com/ and follow the "PIKA for Computer @@ -110,17 +110,17 @@ config 440GP config 440GX bool - select IBM_NEW_EMAC_EMAC4 + select IBM_NEW_EMAC_EMAC4 select IBM_NEW_EMAC_RGMII - select IBM_NEW_EMAC_ZMII #test only - select IBM_NEW_EMAC_TAH #test only + select IBM_NEW_EMAC_ZMII #test only + select IBM_NEW_EMAC_TAH #test only config 440SP bool config 440SPe - select IBM_NEW_EMAC_EMAC4 bool + select IBM_NEW_EMAC_EMAC4 # 44x errata/workaround config symbols, selected by the CPU models above config IBM440EP_ERR42 From cbb14842137ff78df10038da8ca8a97917a5a926 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:50 -0200 Subject: [PATCH 151/880] ACPI: thinkpad-acpi: trivial fix to module_desc typo Thanks to Damjan for noticing this one. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index e2c7edd206a6..723d37b9e6a2 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -5918,7 +5918,7 @@ MODULE_PARM_DESC(hotkey_report_mode, #define TPACPI_PARAM(feature) \ module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ - MODULE_PARM_DESC(feature, "Simulates thinkpad-aci procfs command " \ + MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \ "at module load, see documentation") TPACPI_PARAM(hotkey); From 5f24927f48c63e79ff8e286fc8530f4525b4182a Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:51 -0200 Subject: [PATCH 152/880] ACPI: thinkpad-acpi: trivial fix to documentation Fix a stray ibm-acpi that should have been replaced with thinkpad-acpi. Thanks to Damjan for noticing this one. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 6c2477754a2a..33d6e5afcca6 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -1309,7 +1309,7 @@ Enabling debugging output The module takes a debug parameter which can be used to selectively enable various classes of debugging output, for example: - modprobe ibm_acpi debug=0xffff + modprobe thinkpad_acpi debug=0xffff will enable all debugging output classes. It takes a bitmask, so to enable more than one output class, just add their values. From 1bc6b9cdd5e608f0b7e6160a823c9dcd51820410 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:52 -0200 Subject: [PATCH 153/880] ACPI: thinkpad-acpi: always track input device open/close The open() and close() hooks for the input device are useful even when hotkey NVRAM polling support is not in use, so it is better to always have them around. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 723d37b9e6a2..6da3f40ac9f6 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1417,6 +1417,14 @@ static void hotkey_poll_setup_safe(int may_warn) mutex_unlock(&hotkey_mutex); } +#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ + +static void hotkey_poll_setup_safe(int __unused) +{ +} + +#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ + static int hotkey_inputdev_open(struct input_dev *dev) { switch (tpacpi_lifecycle) { @@ -1444,7 +1452,6 @@ static void hotkey_inputdev_close(struct input_dev *dev) if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) hotkey_poll_setup_safe(0); } -#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ /* sysfs hotkey enable ------------------------------------------------- */ static ssize_t hotkey_enable_show(struct device *dev, @@ -2023,12 +2030,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) (hotkey_report_mode < 2) ? "enabled" : "disabled"); -#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL tpacpi_inputdev->open = &hotkey_inputdev_open; tpacpi_inputdev->close = &hotkey_inputdev_close; hotkey_poll_setup_safe(1); -#endif } return (tp_features.hotkey)? 0 : 1; @@ -2221,9 +2226,7 @@ static void hotkey_resume(void) hotkey_radio_sw_notify_change(); hotkey_wakeup_reason_notify_change(); hotkey_wakeup_hotunplug_complete_notify_change(); -#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL hotkey_poll_setup_safe(0); -#endif } /* procfs -------------------------------------------------------------- */ From 7526696a013f33d4926fdc080c26fe6af07ba30f Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:53 -0200 Subject: [PATCH 154/880] ACPI: thinkpad-acpi: synchronize input device switches Issue EV_SW events at module init time to synchronize the input device with the current state of the switch, otherwise we might lose the first event. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 6da3f40ac9f6..02f946516584 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -2034,6 +2034,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) tpacpi_inputdev->close = &hotkey_inputdev_close; hotkey_poll_setup_safe(1); + tpacpi_input_send_radiosw(); } return (tp_features.hotkey)? 0 : 1; From d7c1d17dfed996e84212fc1ce617b2586dd70ec2 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:54 -0200 Subject: [PATCH 155/880] ACPI: thinkpad-acpi: make the video output feature optional The video output port control feature is not very useful on many ThinkPads (especially when a X server is running), and lately userspace is getting better and better at it, so it makes sense to allow users to stripe out the thinkpad-acpi video feature from their kernels and save at least 2KB. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/Kconfig | 17 +++++++++++++++++ drivers/misc/thinkpad_acpi.c | 20 +++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1abc95ca9dfa..982e27b86d10 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -258,6 +258,23 @@ config THINKPAD_ACPI_BAY If you are not sure, say Y here. +config THINKPAD_ACPI_VIDEO + bool "Video output control support" + depends on THINKPAD_ACPI + default y + ---help--- + Allows the thinkpad_acpi driver to provide an interface to control + the various video output ports. + + This feature often won't work well, depending on ThinkPad model, + display state, video output devices in use, whether there is a X + server running, phase of the moon, and the current mood of + Schroedinger's cat. If you can use X.org's RandR to control + your ThinkPad's video output ports instead of this feature, + don't think twice: do it and say N here to save some memory. + + If you are not sure, say Y here. + config THINKPAD_ACPI_HOTKEY_POLL bool "Suport NVRAM polling for hot keys" depends on THINKPAD_ACPI diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 02f946516584..4ea3866ddf90 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -301,6 +301,13 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ "HKEY", /* all others */ ); /* 570 */ +TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ + "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ + "\\_SB.PCI0.VID0", /* 770e */ + "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ + "\\_SB.PCI0.AGP.VID", /* all others */ + ); /* R30, R31 */ + /************************************************************************* * ACPI helpers @@ -2680,6 +2687,8 @@ static struct ibm_struct wan_driver_data = { * Video subdriver */ +#ifdef CONFIG_THINKPAD_ACPI_VIDEO + enum video_access_mode { TPACPI_VIDEO_NONE = 0, TPACPI_VIDEO_570, /* 570 */ @@ -2707,13 +2716,6 @@ static int video_orig_autosw; static int video_autosw_get(void); static int video_autosw_set(int enable); -TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ - "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ - "\\_SB.PCI0.VID0", /* 770e */ - "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ - "\\_SB.PCI0.AGP.VID", /* all others */ - ); /* R30, R31 */ - TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ static int __init video_init(struct ibm_init_struct *iibm) @@ -3023,6 +3025,8 @@ static struct ibm_struct video_driver_data = { .exit = video_exit, }; +#endif /* CONFIG_THINKPAD_ACPI_VIDEO */ + /************************************************************************* * Light (thinklight) subdriver */ @@ -5807,10 +5811,12 @@ static struct ibm_init_struct ibms_init[] __initdata = { .init = wan_init, .data = &wan_driver_data, }, +#ifdef CONFIG_THINKPAD_ACPI_VIDEO { .init = video_init, .data = &video_driver_data, }, +#endif { .init = light_init, .data = &light_driver_data, From b3ec6f911a681f38e4630ef8bf20b3d3cb0f63c2 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:55 -0200 Subject: [PATCH 156/880] ACPI: thinkpad-acpi: issue input events for tablet swivel events Issue EV_SW SW_TABLET_MODE events for HKEY events 0x5009 and 0x500A on the X41t/X60t/X61t. As usual, we suppress the HKEY events on the netlink interface to avoid sending duplicate events to userspace. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 4 ++-- drivers/misc/thinkpad_acpi.c | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 33d6e5afcca6..0ae5708ea0ad 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -491,6 +491,8 @@ generate input device EV_KEY events. Non hot-key ACPI HKEY event map: 0x5001 Lid closed 0x5002 Lid opened +0x5009 Tablet swivel: switched to tablet mode +0x500A Tablet swivel: switched to normal mode 0x7000 Radio Switch may have changed state The above events are not propagated by the driver, except for legacy @@ -505,8 +507,6 @@ The above events are never propagated by the driver. 0x3003 Bay ejection (see 0x2x05) complete, can sleep again 0x4003 Undocked (see 0x2x04), can sleep again -0x5009 Tablet swivel: switched to tablet mode -0x500A Tablet swivel: switched to normal mode 0x500B Tablet pen insterted into its storage bay 0x500C Tablet pen removed from its storage bay 0x5010 Brightness level changed (newer Lenovo BIOSes) diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 4ea3866ddf90..35483502a117 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1172,6 +1172,17 @@ static void tpacpi_input_send_radiosw(void) mutex_unlock(&tpacpi_inputdev_send_mutex); } +static void tpacpi_input_send_tabletsw(unsigned int state) +{ + mutex_lock(&tpacpi_inputdev_send_mutex); + + input_report_switch(tpacpi_inputdev, + SW_TABLET_MODE, !!state); + input_sync(tpacpi_inputdev); + + mutex_unlock(&tpacpi_inputdev_send_mutex); +} + static void tpacpi_input_send_key(unsigned int scancode) { unsigned int keycode; @@ -2020,6 +2031,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) set_bit(EV_SW, tpacpi_inputdev->evbit); set_bit(SW_RADIO, tpacpi_inputdev->swbit); } + if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { + set_bit(EV_SW, tpacpi_inputdev->evbit); + set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); + } dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); @@ -2169,11 +2184,14 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) /* 0x5000-0x5FFF: human interface helpers */ switch (hkey) { case 0x5010: /* Lenovo new BIOS: brightness changed */ - case 0x5009: /* X61t: swivel up (tablet mode) */ - case 0x500a: /* X61t: swivel down (normal mode) */ case 0x500b: /* X61t: tablet pen inserted into bay */ case 0x500c: /* X61t: tablet pen removed from bay */ break; + case 0x5009: /* X61t: swivel up (tablet mode) */ + case 0x500a: /* X61t: swivel down (normal mode) */ + tpacpi_input_send_tabletsw((hkey == 0x5009)); + send_acpi_ev = 0; + break; case 0x5001: case 0x5002: /* LID switch events. Do not propagate */ From d0788cfbae0eddf13d5f2591acb1b407ba041d71 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:56 -0200 Subject: [PATCH 157/880] ACPI: thinkpad-acpi: improve thinkpad-acpi input device documentation Fix a few spelling errors, and also document the EV_SW events thinkpad-acpi can issue. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 48 ++++++++++++++----------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 0ae5708ea0ad..91f688c30185 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -160,7 +160,7 @@ Hot keys procfs: /proc/acpi/ibm/hotkey sysfs device attribute: hotkey_* -In a ThinkPad, the ACPI HKEY handler is responsible for comunicating +In a ThinkPad, the ACPI HKEY handler is responsible for communicating some important events and also keyboard hot key presses to the operating system. Enabling the hotkey functionality of thinkpad-acpi signals the firmware that such a driver is present, and modifies how the ThinkPad @@ -193,7 +193,7 @@ Not all bits in the mask can be modified. Not all bits that can be modified do anything. Not all hot keys can be individually controlled by the mask. Some models do not support the mask at all, and in those models, hot keys cannot be controlled individually. The behaviour of -the mask is, therefore, higly dependent on the ThinkPad model. +the mask is, therefore, highly dependent on the ThinkPad model. Note that unmasking some keys prevents their default behavior. For example, if Fn+F5 is unmasked, that key will no longer enable/disable @@ -288,7 +288,7 @@ sysfs notes: in ACPI event mode, volume up/down/mute are reported as separate events, but this behaviour may be corrected in future releases of this driver, in which case the - ThinkPad volume mixer user interface semanthics will be + ThinkPad volume mixer user interface semantics will be enforced. hotkey_poll_freq: @@ -308,7 +308,7 @@ sysfs notes: hotkey_radio_sw: if the ThinkPad has a hardware radio switch, this attribute will read 0 if the switch is in the "radios - disabled" postition, and 1 if the switch is in the + disabled" position, and 1 if the switch is in the "radios enabled" position. This attribute has poll()/select() support. @@ -339,7 +339,7 @@ sysfs notes: wakeup_hotunplug_complete: Set to 1 if the system was waken up because of an undock or bay ejection request, and that request - was sucessfully completed. At this point, it might + was successfully completed. At this point, it might be useful to send the system back to sleep, at the user's choice. Refer to HKEY events 0x4003 and 0x3003, below. @@ -392,7 +392,7 @@ event code Key Notes Lenovo: battery 0x1004 0x03 FN+F4 Sleep button (ACPI sleep button - semanthics, i.e. sleep-to-RAM). + semantics, i.e. sleep-to-RAM). It is always generate some kind of event, either the hot key event or a ACPI sleep button @@ -403,12 +403,12 @@ event code Key Notes time passes. 0x1005 0x04 FN+F5 Radio. Enables/disables - the internal BlueTooth hardware + the internal Bluetooth hardware and W-WAN card if left in control of the firmware. Does not affect the WLAN card. Should be used to turn on/off all - radios (bluetooth+W-WAN+WLAN), + radios (Bluetooth+W-WAN+WLAN), really. 0x1006 0x05 FN+F6 - @@ -417,7 +417,7 @@ event code Key Notes Do you feel lucky today? 0x1008 0x07 FN+F8 IBM: toggle screen expand - Lenovo: configure ultranav + Lenovo: configure UltraNav 0x1009 0x08 FN+F9 - .. .. .. @@ -447,7 +447,7 @@ event code Key Notes 0x1011 0x10 FN+END Brightness down. See brightness up for details. -0x1012 0x11 FN+PGUP Thinklight toggle. This key is +0x1012 0x11 FN+PGUP ThinkLight toggle. This key is always handled by the firmware, even when unmasked. @@ -469,7 +469,7 @@ event code Key Notes key is always handled by the firmware, even when unmasked. -0x1018 0x17 THINKPAD Thinkpad/Access IBM/Lenovo key +0x1018 0x17 THINKPAD ThinkPad/Access IBM/Lenovo key 0x1019 0x18 unknown .. .. .. @@ -488,6 +488,12 @@ If a key is mapped to KEY_UNKNOWN, it generates an input event that includes an scan code. If a key is mapped to anything else, it will generate input device EV_KEY events. +In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW +events for switches: + +SW_RADIO T60 and later hardare rfkill rocker switch +SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A + Non hot-key ACPI HKEY event map: 0x5001 Lid closed 0x5002 Lid opened @@ -507,7 +513,7 @@ The above events are never propagated by the driver. 0x3003 Bay ejection (see 0x2x05) complete, can sleep again 0x4003 Undocked (see 0x2x04), can sleep again -0x500B Tablet pen insterted into its storage bay +0x500B Tablet pen inserted into its storage bay 0x500C Tablet pen removed from its storage bay 0x5010 Brightness level changed (newer Lenovo BIOSes) @@ -539,7 +545,7 @@ sysfs (it is read-only). If the hotkey_report_mode module parameter is set to 1 or 2, it cannot be changed later through sysfs (any writes will return -EPERM to signal that hotkey_report_mode was locked. On 2.6.23 and later, where -hotkey_report_mode cannot be changed at all, writes will return -EACES). +hotkey_report_mode cannot be changed at all, writes will return -EACCES). hotkey_report_mode set to 1 makes the driver export through the procfs ACPI event interface all hot key presses (which are *also* sent to the @@ -584,7 +590,7 @@ Sysfs notes: 0: disables Bluetooth / Bluetooth is disabled 1: enables Bluetooth / Bluetooth is enabled. - Note: this interface will be probably be superseeded by the + Note: this interface will be probably be superseded by the generic rfkill class, so it is NOT to be considered stable yet. Video output control -- /proc/acpi/ibm/video @@ -791,12 +797,12 @@ on the X40 (tpb is the ThinkPad Buttons utility): 1 - Related to "Volume up" key press 2 - Related to "Mute on" key press 3 - Related to "Access IBM" key press - 4 - Related to "LCD brightness up" key pess + 4 - Related to "LCD brightness up" key press 5 - Related to "LCD brightness down" key press 11 - Related to "toggle screen expansion" key press/function 12 - Related to "ThinkLight on" 13 - Related to "ThinkLight off" - 14 - Related to "ThinkLight" key press (toggle thinklight) + 14 - Related to "ThinkLight" key press (toggle ThinkLight) The cmos command interface is prone to firmware split-brain problems, as in newer ThinkPads it is just a compatibility layer. Do not use it, it is @@ -1024,7 +1030,7 @@ There are two interfaces to the firmware for direct brightness control, EC and CMOS. To select which one should be used, use the brightness_mode module parameter: brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC -and CMOS. The driver tries to autodetect which interface to use. +and CMOS. The driver tries to auto-detect which interface to use. When display backlight brightness controls are available through the standard ACPI interface, it is best to use it instead of this direct @@ -1266,8 +1272,8 @@ experimental=1 parameter when loading the module. This feature shows the presence and current state of a W-WAN (Sierra Wireless EV-DO) device. -It was tested on a Lenovo Thinkpad X60. It should probably work on other -Thinkpad models which come with this module installed. +It was tested on a Lenovo ThinkPad X60. It should probably work on other +ThinkPad models which come with this module installed. Procfs notes: @@ -1286,7 +1292,7 @@ Sysfs notes: 0: disables WWAN card / WWAN card is disabled 1: enables WWAN card / WWAN card is enabled. - Note: this interface will be probably be superseeded by the + Note: this interface will be probably be superseded by the generic rfkill class, so it is NOT to be considered stable yet. Multiple Commands, Module Parameters @@ -1356,7 +1362,7 @@ Sysfs interface changelog: NVRAM is compiled out by the user because it is unneeded/undesired in the first place). 0x020101: Marker for thinkpad-acpi with hot key NVRAM polling - and proper hotkey_mask semanthics (version 8 of the + and proper hotkey_mask semantics (version 8 of the NVRAM polling patch). Some development snapshots of 0.18 had an earlier version that did strange things to hotkey_mask. From d147da73c9a3f617e4685c6a7762961fe19833e7 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:57 -0200 Subject: [PATCH 158/880] ACPI: thinkpad-acpi: minor hotkey_radio_sw fixes Fixes some minor points in the radio switch code and docs. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 2 +- drivers/misc/thinkpad_acpi.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 91f688c30185..606af1628382 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -306,7 +306,7 @@ sysfs notes: The recommended polling frequency is 10Hz. hotkey_radio_sw: - if the ThinkPad has a hardware radio switch, this + If the ThinkPad has a hardware radio switch, this attribute will read 0 if the switch is in the "radios disabled" position, and 1 if the switch is in the "radios enabled" position. diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 35483502a117..c119cf23e1ff 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1161,15 +1161,15 @@ static void tpacpi_input_send_radiosw(void) { int wlsw; - mutex_lock(&tpacpi_inputdev_send_mutex); - if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { + mutex_lock(&tpacpi_inputdev_send_mutex); + input_report_switch(tpacpi_inputdev, SW_RADIO, !!wlsw); input_sync(tpacpi_inputdev); - } - mutex_unlock(&tpacpi_inputdev_send_mutex); + mutex_unlock(&tpacpi_inputdev_send_mutex); + } } static void tpacpi_input_send_tabletsw(unsigned int state) From 6c231bd5eb07ce546517019f334652b9ecfc329a Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 16 Feb 2008 02:17:58 -0200 Subject: [PATCH 159/880] ACPI: thinkpad-acpi: add tablet-mode reporting A quick study of the 0x5009/0x500A HKEY event on the X61t DSDT revealed the existence of the EC HTAB register (EC 0x0f, bit 7), and a compare with the X41t DSDT shows that HKEY.MHKG can be used to verify if the ThinkPad is tablet-capable (MHKG present), and in tablet mode (bit 3 of MHKG return is set). Add an attribute to report this information, "hotkey_tablet_mode". This attribute has poll()/select() support, and can be used along with EV_SW SW_TABLET_MODE to hook userspace to tablet events. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 7 +++ drivers/misc/thinkpad_acpi.c | 79 +++++++++++++++++++++---- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 606af1628382..76cb428435da 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -313,6 +313,13 @@ sysfs notes: This attribute has poll()/select() support. + hotkey_tablet_mode: + If the ThinkPad has tablet capabilities, this attribute + will read 0 if the ThinkPad is in normal mode, and + 1 if the ThinkPad is in tablet mode. + + This attribute has poll()/select() support. + hotkey_report_mode: Returns the state of the procfs ACPI event report mode filter for hot keys. If it is set to 1 (the default), diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index c119cf23e1ff..bb269d0c677e 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -221,6 +221,7 @@ static struct { u32 hotkey:1; u32 hotkey_mask:1; u32 hotkey_wlsw:1; + u32 hotkey_tablet:1; u32 light:1; u32 light_status:1; u32 bright_16levels:1; @@ -1060,6 +1061,9 @@ static struct attribute_set *hotkey_dev_attributes; #define HOTKEY_CONFIG_CRITICAL_END #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ +/* HKEY.MHKG() return bits */ +#define TP_HOTKEY_TABLET_MASK (1 << 3) + static int hotkey_get_wlsw(int *status) { if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) @@ -1067,6 +1071,16 @@ static int hotkey_get_wlsw(int *status) return 0; } +static int hotkey_get_tablet_mode(int *status) +{ + int s; + + if (!acpi_evalf(hkey_handle, &s, "MHKG", "d")) + return -EIO; + + return ((s & TP_HOTKEY_TABLET_MASK) != 0); +} + /* * Call with hotkey_mutex held */ @@ -1172,15 +1186,20 @@ static void tpacpi_input_send_radiosw(void) } } -static void tpacpi_input_send_tabletsw(unsigned int state) +static void tpacpi_input_send_tabletsw(void) { - mutex_lock(&tpacpi_inputdev_send_mutex); + int state; - input_report_switch(tpacpi_inputdev, - SW_TABLET_MODE, !!state); - input_sync(tpacpi_inputdev); + if (tp_features.hotkey_tablet && + !hotkey_get_tablet_mode(&state)) { + mutex_lock(&tpacpi_inputdev_send_mutex); - mutex_unlock(&tpacpi_inputdev_send_mutex); + input_report_switch(tpacpi_inputdev, + SW_TABLET_MODE, !!state); + input_sync(tpacpi_inputdev); + + mutex_unlock(&tpacpi_inputdev_send_mutex); + } } static void tpacpi_input_send_key(unsigned int scancode) @@ -1691,6 +1710,29 @@ static void hotkey_radio_sw_notify_change(void) "hotkey_radio_sw"); } +/* sysfs hotkey tablet mode (pollable) --------------------------------- */ +static ssize_t hotkey_tablet_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int res, s; + res = hotkey_get_tablet_mode(&s); + if (res < 0) + return res; + + return snprintf(buf, PAGE_SIZE, "%d\n", !!s); +} + +static struct device_attribute dev_attr_hotkey_tablet_mode = + __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL); + +static void hotkey_tablet_mode_notify_change(void) +{ + if (tp_features.hotkey_tablet) + sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, + "hotkey_tablet_mode"); +} + /* sysfs hotkey report_mode -------------------------------------------- */ static ssize_t hotkey_report_mode_show(struct device *dev, struct device_attribute *attr, @@ -1903,7 +1945,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) str_supported(tp_features.hotkey)); if (tp_features.hotkey) { - hotkey_dev_attributes = create_attr_set(12, NULL); + hotkey_dev_attributes = create_attr_set(13, NULL); if (!hotkey_dev_attributes) return -ENOMEM; res = add_many_to_attr_set(hotkey_dev_attributes, @@ -1982,6 +2024,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) &dev_attr_hotkey_radio_sw.attr); } + /* For X41t, X60t, X61t Tablets... */ + if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { + tp_features.hotkey_tablet = 1; + printk(TPACPI_INFO + "possible tablet mode switch found; " + "ThinkPad in %s mode\n", + (status & TP_HOTKEY_TABLET_MASK)? + "tablet" : "laptop"); + res = add_to_attr_set(hotkey_dev_attributes, + &dev_attr_hotkey_tablet_mode.attr); + } + if (!res) res = register_attr_set_with_sysfs( hotkey_dev_attributes, @@ -2031,7 +2085,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) set_bit(EV_SW, tpacpi_inputdev->evbit); set_bit(SW_RADIO, tpacpi_inputdev->swbit); } - if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { + if (tp_features.hotkey_tablet) { set_bit(EV_SW, tpacpi_inputdev->evbit); set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); } @@ -2057,6 +2111,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) hotkey_poll_setup_safe(1); tpacpi_input_send_radiosw(); + tpacpi_input_send_tabletsw(); } return (tp_features.hotkey)? 0 : 1; @@ -2187,9 +2242,10 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) case 0x500b: /* X61t: tablet pen inserted into bay */ case 0x500c: /* X61t: tablet pen removed from bay */ break; - case 0x5009: /* X61t: swivel up (tablet mode) */ - case 0x500a: /* X61t: swivel down (normal mode) */ - tpacpi_input_send_tabletsw((hkey == 0x5009)); + case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ + case 0x500a: /* X41t-X61t: swivel down (normal mode) */ + tpacpi_input_send_tabletsw(); + hotkey_tablet_mode_notify_change(); send_acpi_ev = 0; break; case 0x5001: @@ -2250,6 +2306,7 @@ static void hotkey_resume(void) "from firmware\n"); tpacpi_input_send_radiosw(); hotkey_radio_sw_notify_change(); + hotkey_tablet_mode_notify_change(); hotkey_wakeup_reason_notify_change(); hotkey_wakeup_hotunplug_complete_notify_change(); hotkey_poll_setup_safe(0); From 4fd7f5188c377c1e9aa8f224f6edf96d170a7d32 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 15 Feb 2008 17:07:19 -0800 Subject: [PATCH 160/880] ACPI: sparse fix, replace macro with static function replace acpi_util_eval_error macro with static function. Avoid these sparse warnings due to using buffer within the macro. drivers/acpi/utils.c:273:3: warning: symbol 'buffer' shadows an earlier one drivers/acpi/utils.c:259:21: originally declared here drivers/acpi/utils.c:279:3: warning: symbol 'buffer' shadows an earlier one drivers/acpi/utils.c:259:21: originally declared here drivers/acpi/utils.c:368:3: warning: symbol 'buffer' shadows an earlier one drivers/acpi/utils.c:348:21: originally declared here drivers/acpi/utils.c:375:3: warning: symbol 'buffer' shadows an earlier one drivers/acpi/utils.c:348:21: originally declared here drivers/acpi/utils.c:382:3: warning: symbol 'buffer' shadows an earlier one drivers/acpi/utils.c:348:21: originally declared here drivers/acpi/utils.c:402:4: warning: symbol 'buffer' shadows an earlier one drivers/acpi/utils.c:348:21: originally declared here Signed-off-by: Harvey Harrison Signed-off-by: Len Brown --- drivers/acpi/utils.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 34f157571080..eba55b7d6c95 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -36,16 +36,20 @@ ACPI_MODULE_NAME("utils"); /* -------------------------------------------------------------------------- Object Evaluation Helpers -------------------------------------------------------------------------- */ +static void +acpi_util_eval_error(acpi_handle h, acpi_string p, acpi_status s) +{ #ifdef ACPI_DEBUG_OUTPUT -#define acpi_util_eval_error(h,p,s) {\ - char prefix[80] = {'\0'};\ - struct acpi_buffer buffer = {sizeof(prefix), prefix};\ - acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\ - (char *) prefix, p, acpi_format_exception(s))); } + char prefix[80] = {'\0'}; + struct acpi_buffer buffer = {sizeof(prefix), prefix}; + acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n", + (char *) prefix, p, acpi_format_exception(s))); #else -#define acpi_util_eval_error(h,p,s) + return; #endif +} + acpi_status acpi_extract_package(union acpi_object *package, struct acpi_buffer *format, struct acpi_buffer *buffer) From 262ee35be6a3aae9b4a7aafafc2dba901fc36620 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 16 Feb 2008 00:02:56 +0000 Subject: [PATCH 161/880] acer-wmi: Add DMI match for mail LED on Acer TravelMate 4200 series The TM4200 series use the same method as the TM2490 series to control the mail LED, so add a DMI based quirk for these laptops. Signed-off-by: Carlos Corbacho Signed-off-by: Len Brown --- drivers/misc/acer-wmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index d7aea93081f2..74d12b4a3abd 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -271,6 +271,15 @@ static struct dmi_system_id acer_quirks[] = { }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .callback = dmi_matched, + .ident = "Acer TravelMate 4200", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"), + }, + .driver_data = &quirk_acer_travelmate_2490, + }, { .callback = dmi_matched, .ident = "Medion MD 98300", From e85ff4b53eb4252d967922bd75cb6d10863955f3 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Sat, 16 Feb 2008 01:01:13 -0500 Subject: [PATCH 162/880] ACPI: remove is_processor_present prototype The function itself is defined just below, so this prototype is not really useful. Signed-off-by: Glauber Costa Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/processor_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 75ccf5d18bf4..923fddb2caa3 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -826,8 +826,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type) * Acpi processor hotplug support * ****************************************************************************/ -static int is_processor_present(acpi_handle handle); - static int is_processor_present(acpi_handle handle) { acpi_status status; From 13dbf42210565418e925f883e9217b9eda5244a2 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Sat, 16 Feb 2008 08:01:10 -0600 Subject: [PATCH 163/880] [POWERPC] 44x: Add multiplatform defconfig Add a multiboard defconfig for PowerPC 44x now that the wrapper can create the proper zImages for multiple boards. Signed-off-by: Josh Boyer --- arch/powerpc/configs/ppc44x_defconfig | 904 ++++++++++++++++++++++++++ 1 file changed, 904 insertions(+) create mode 100644 arch/powerpc/configs/ppc44x_defconfig diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig new file mode 100644 index 000000000000..57bd775ef777 --- /dev/null +++ b/arch/powerpc/configs/ppc44x_defconfig @@ -0,0 +1,904 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.25-rc2 +# Fri Feb 15 21:57:35 2008 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_6xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +CONFIG_44x=y +# CONFIG_E200 is not set +CONFIG_PPC_FPU=y +CONFIG_4xx=y +CONFIG_BOOKE=y +CONFIG_PTE_64BIT=y +CONFIG_PHYS_64BIT=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=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_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS 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=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES 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_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +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_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +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=y +# 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=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set +CONFIG_PPC4xx_PCI_EXPRESS=y + +# +# Platform support +# +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +CONFIG_BAMBOO=y +CONFIG_EBONY=y +CONFIG_SEQUOIA=y +CONFIG_TAISHAN=y +CONFIG_KATMAI=y +CONFIG_RAINIER=y +CONFIG_WARP=y +CONFIG_440EP=y +CONFIG_440EPX=y +CONFIG_440GRX=y +CONFIG_440GP=y +CONFIG_440GX=y +CONFIG_440SPe=y +CONFIG_IBM440EP_ERR42=y +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_FSL_ULI1575 is not set +CONFIG_OF_RTC=y + +# +# Kernel options +# +# CONFIG_HIGHMEM 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 +# 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_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_RCU_TRACE is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MATH_EMULATION=y +# CONFIG_IOMMU_HELPER is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +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=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_BOOT_LOAD=0x01000000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# 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=y +CONFIG_IP_PNP_BOOTP=y +# 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 is not set +# 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# 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_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_CAN 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=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +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 +CONFIG_MTD_OF_PARTS=y + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +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=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# 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=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 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_OF_DEVICE=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# 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_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_XILINX_SYSACE is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE 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 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_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +# CONFIG_MACINTOSH_DRIVERS 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_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_IBM_NEW_EMAC=y +CONFIG_IBM_NEW_EMAC_RXB=128 +CONFIG_IBM_NEW_EMAC_TXB=64 +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +# CONFIG_IBM_NEW_EMAC_DEBUG is not set +CONFIG_IBM_NEW_EMAC_ZMII=y +CONFIG_IBM_NEW_EMAC_RGMII=y +CONFIG_IBM_NEW_EMAC_TAH=y +CONFIG_IBM_NEW_EMAC_EMAC4=y +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP 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_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG 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_AGP is not set +# CONFIG_DRM is not set +# 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=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP 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_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA 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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL 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_JFFS2_FS=y +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=y +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 +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_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS 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 is not set +# CONFIG_DLM is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# 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=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUGGER is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_MANAGER=y +# 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=y +# 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=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# 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 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_HW is not set +# CONFIG_PPC_CLOCK is not set From 05cca7381429e12d66c5b5c8b5c5848055b88bf7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 26 Jan 2008 17:42:45 +0100 Subject: [PATCH 164/880] firewire: fw-sbp2: unsigned int vs. unsigned Standardize on "unsigned int" style. Sort some struct members thematically. Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 19ece9b6d742..f2a9a33b47a1 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -141,15 +141,13 @@ struct sbp2_logical_unit { struct sbp2_target { struct kref kref; struct fw_unit *unit; + struct list_head lu_list; u64 management_agent_address; int directory_id; int node_id; int address_high; - - unsigned workarounds; - struct list_head lu_list; - + unsigned int workarounds; unsigned int mgt_orb_timeout; }; @@ -160,7 +158,7 @@ struct sbp2_target { */ #define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */ #define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */ -#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */ +#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */ #define SBP2_ORB_NULL 0x80000000 #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 @@ -297,7 +295,7 @@ struct sbp2_command_orb { static const struct { u32 firmware_revision; u32 model; - unsigned workarounds; + unsigned int workarounds; } sbp2_workarounds_table[] = { /* DViCO Momobay CX-1 with TSB42AA9 bridge */ { .firmware_revision = 0x002800, @@ -836,7 +834,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, u32 firmware_revision) { int i; - unsigned w = sbp2_param_workarounds; + unsigned int w = sbp2_param_workarounds; if (w) fw_notify("Please notify linux1394-devel@lists.sourceforge.net " @@ -1197,7 +1195,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) struct sbp2_logical_unit *lu = cmd->device->hostdata; struct fw_device *device = fw_device(lu->tgt->unit->device.parent); struct sbp2_command_orb *orb; - unsigned max_payload; + unsigned int max_payload; int retval = SCSI_MLQUEUE_HOST_BUSY; /* From 1b9c12ba2fdf802a23630f70eddb0e821296634e Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 26 Jan 2008 17:43:23 +0100 Subject: [PATCH 165/880] firewire: fw-sbp2: fix logout before login retry This fixes a "can't recognize device" kind of bug. If the SCSI INQUIRY failed and hence __scsi_add_device failed due to a bus reset, we tried a logout and then waited for the already scheduled login work to happen. So far so good, but the generation used for the logout was outdated, hence the logout never reached the target. The target might therefore deny the subsequent relogin attempt, which would also leave the target inaccessible. Therefore fetch a fresh device->generation for the logout. Use memory barriers to prevent our plan being foiled by compiler or hardware optimizations. Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index f2a9a33b47a1..a15e3c7d21d3 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -716,7 +716,11 @@ static void sbp2_login(struct work_struct *work) sdev = __scsi_add_device(shost, 0, 0, scsilun_to_int(&eight_bytes_lun), lu); if (IS_ERR(sdev)) { - sbp2_send_management_orb(lu, node_id, generation, + smp_rmb(); /* generation may have changed */ + generation = device->generation; + smp_rmb(); /* node_id must not be older than generation */ + + sbp2_send_management_orb(lu, device->node_id, generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); /* * Set this back to sbp2_login so we fall back and From 96b19062e741b715cf399312c30e0672d8889569 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 2 Feb 2008 15:01:09 +0100 Subject: [PATCH 166/880] firewire: fix "kobject_add failed for fw* with -EEXIST" There is a race between shutdown and creation of devices: fw-core may attempt to add a device with the same name of an already existing device. http://bugzilla.kernel.org/show_bug.cgi?id=9828 Impact of the bug: Happens rarely (when shutdown of a device coincides with creation of another), forces the user to unplug and replug the new device to get it working. The fix is obvious: Free the minor number *after* instead of *before* device_unregister(). This requires to take an additional reference of the fw_device as long as the IDR tree points to it. And while we are at it, we fix an additional race condition: fw_device_op_open() took its reference of the fw_device a little bit too late, hence was in danger to access an already invalid fw_device. Signed-off-by: Stefan Richter --- drivers/firewire/fw-cdev.c | 8 +++++--- drivers/firewire/fw-device.c | 20 ++++++++++++++------ drivers/firewire/fw-device.h | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 7e73cbaa4121..44ccee26c368 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -109,15 +109,17 @@ static int fw_device_op_open(struct inode *inode, struct file *file) struct client *client; unsigned long flags; - device = fw_device_from_devt(inode->i_rdev); + device = fw_device_get_by_devt(inode->i_rdev); if (device == NULL) return -ENODEV; client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) + if (client == NULL) { + fw_device_put(device); return -ENOMEM; + } - client->device = fw_device_get(device); + client->device = device; INIT_LIST_HEAD(&client->event_list); INIT_LIST_HEAD(&client->resource_list); spin_lock_init(&client->lock); diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index de9066e69adf..c04c28800f1d 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -610,12 +610,14 @@ static DECLARE_RWSEM(idr_rwsem); static DEFINE_IDR(fw_device_idr); int fw_cdev_major; -struct fw_device *fw_device_from_devt(dev_t devt) +struct fw_device *fw_device_get_by_devt(dev_t devt) { struct fw_device *device; down_read(&idr_rwsem); device = idr_find(&fw_device_idr, MINOR(devt)); + if (device) + fw_device_get(device); up_read(&idr_rwsem); return device; @@ -627,13 +629,14 @@ static void fw_device_shutdown(struct work_struct *work) container_of(work, struct fw_device, work.work); int minor = MINOR(device->device.devt); - down_write(&idr_rwsem); - idr_remove(&fw_device_idr, minor); - up_write(&idr_rwsem); - fw_device_cdev_remove(device); device_for_each_child(&device->device, NULL, shutdown_unit); device_unregister(&device->device); + + down_write(&idr_rwsem); + idr_remove(&fw_device_idr, minor); + up_write(&idr_rwsem); + fw_device_put(device); } static struct device_type fw_device_type = { @@ -682,10 +685,13 @@ static void fw_device_init(struct work_struct *work) } err = -ENOMEM; + + fw_device_get(device); down_write(&idr_rwsem); if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) err = idr_get_new(&fw_device_idr, device, &minor); up_write(&idr_rwsem); + if (err < 0) goto error; @@ -741,7 +747,9 @@ static void fw_device_init(struct work_struct *work) idr_remove(&fw_device_idr, minor); up_write(&idr_rwsem); error: - put_device(&device->device); + fw_device_put(device); /* fw_device_idr's reference */ + + put_device(&device->device); /* our reference */ } static int update_unit(struct device *dev, void *data) diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index 0854fe2bc110..43808c02793e 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -77,13 +77,13 @@ fw_device_is_shutdown(struct fw_device *device) } struct fw_device *fw_device_get(struct fw_device *device); +struct fw_device *fw_device_get_by_devt(dev_t devt); void fw_device_put(struct fw_device *device); int fw_device_enable_phys_dma(struct fw_device *device); void fw_device_cdev_update(struct fw_device *device); void fw_device_cdev_remove(struct fw_device *device); -struct fw_device *fw_device_from_devt(dev_t devt); extern int fw_cdev_major; struct fw_unit { From be6f48b0174584c9c415012ca14803c7e941e27e Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 27 Jan 2008 19:14:44 +0100 Subject: [PATCH 167/880] firewire: fw-sbp2: don't retry login or reconnect after unplug If a device is being unplugged while fw-sbp2 had a login or reconnect on schedule, it would take about half a minute to shut the fw_unit down: Jan 27 18:34:54 stein firewire_sbp2: logged in to fw2.0 LUN 0000 (0 retries) Jan 27 18:34:59 stein firewire_sbp2: sbp2_scsi_abort Jan 27 18:34:59 stein scsi 25:0:0:0: Device offlined - not ready after error recovery Jan 27 18:35:01 stein firewire_sbp2: orb reply timed out, rcode=0x11 Jan 27 18:35:06 stein firewire_sbp2: orb reply timed out, rcode=0x11 Jan 27 18:35:12 stein firewire_sbp2: orb reply timed out, rcode=0x11 Jan 27 18:35:17 stein firewire_sbp2: orb reply timed out, rcode=0x11 Jan 27 18:35:22 stein firewire_sbp2: orb reply timed out, rcode=0x11 Jan 27 18:35:27 stein firewire_sbp2: orb reply timed out, rcode=0x11 Jan 27 18:35:32 stein firewire_sbp2: orb reply timed out, rcode=0x11 Jan 27 18:35:32 stein firewire_sbp2: failed to login to fw2.0 LUN 0000 Jan 27 18:35:32 stein firewire_sbp2: released fw2.0 After this patch, typically only a few seconds spent in __scsi_add_device remain: Jan 27 19:05:50 stein firewire_sbp2: logged in to fw2.0 LUN 0000 (0 retries) Jan 27 19:05:56 stein firewire_sbp2: sbp2_scsi_abort Jan 27 19:05:56 stein scsi 33:0:0:0: Device offlined - not ready after error recovery Jan 27 19:05:56 stein firewire_sbp2: released fw2.0 The benefit of this is less noise in the syslog. It furthermore avoids a few wasted CPU cycles and needlessly prolonged lifetime of a few driver objects. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-sbp2.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index a15e3c7d21d3..72fddf5a12a3 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -499,6 +499,9 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, unsigned int timeout; int retval = -ENOMEM; + if (function == SBP2_LOGOUT_REQUEST && fw_device_is_shutdown(device)) + return 0; + orb = kzalloc(sizeof(*orb), GFP_ATOMIC); if (orb == NULL) return -ENOMEM; @@ -619,16 +622,13 @@ static void sbp2_release_target(struct kref *kref) struct sbp2_logical_unit *lu, *next; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); - struct fw_device *device = fw_device(tgt->unit->device.parent); list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { if (lu->sdev) scsi_remove_device(lu->sdev); - if (!fw_device_is_shutdown(device)) - sbp2_send_management_orb(lu, tgt->node_id, - lu->generation, SBP2_LOGOUT_REQUEST, - lu->login_id, NULL); + sbp2_send_management_orb(lu, tgt->node_id, lu->generation, + SBP2_LOGOUT_REQUEST, lu->login_id, NULL); fw_core_remove_address_handler(&lu->address_handler); list_del(&lu->link); @@ -673,6 +673,9 @@ static void sbp2_login(struct work_struct *work) struct sbp2_login_response response; int generation, node_id, local_node_id; + if (fw_device_is_shutdown(device)) + goto out; + generation = device->generation; smp_rmb(); /* node_id must not be older than generation */ node_id = device->node_id; @@ -944,6 +947,9 @@ static void sbp2_reconnect(struct work_struct *work) struct fw_device *device = fw_device(unit->device.parent); int generation, node_id, local_node_id; + if (fw_device_is_shutdown(device)) + goto out; + generation = device->generation; smp_rmb(); /* node_id must not be older than generation */ node_id = device->node_id; From fa6e697b85d705d37b3b03829095c22bcbe95ab6 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:03:00 +0100 Subject: [PATCH 168/880] firewire: log GUID of new devices This should help to interpret user reports. E.g. one can look up the vendor OUI (first three bytes of the GUID) and thus tell what is what. Also simplifies the math in the GUID sysfs attribute. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-device.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index c04c28800f1d..2ab13e0f3469 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -358,12 +358,9 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct fw_device *device = fw_device(dev); - u64 guid; - guid = ((u64)device->config_rom[3] << 32) | device->config_rom[4]; - - return snprintf(buf, PAGE_SIZE, "0x%016llx\n", - (unsigned long long)guid); + return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", + device->config_rom[3], device->config_rom[4]); } static struct device_attribute fw_device_attributes[] = { @@ -723,13 +720,22 @@ static void fw_device_init(struct work_struct *work) */ if (atomic_cmpxchg(&device->state, FW_DEVICE_INITIALIZING, - FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) + FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { fw_device_shutdown(&device->work.work); - else - fw_notify("created new fw device %s " - "(%d config rom retries, S%d00)\n", - device->device.bus_id, device->config_rom_retries, - 1 << device->max_speed); + } else { + if (device->config_rom_retries) + fw_notify("created device %s: GUID %08x%08x, S%d00, " + "%d config ROM retries\n", + device->device.bus_id, + device->config_rom[3], device->config_rom[4], + 1 << device->max_speed, + device->config_rom_retries); + else + fw_notify("created device %s: GUID %08x%08x, S%d00\n", + device->device.bus_id, + device->config_rom[3], device->config_rom[4], + 1 << device->max_speed); + } /* * Reschedule the IRM work if we just finished reading the From 9220f1946209a5b3335ea2d28f8462695885791b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:04:38 +0100 Subject: [PATCH 169/880] firewire: fw-sbp2: add INQUIRY delay workaround Several different SBP-2 bridges accept a login early while the IDE device is still powering up. They are therefore unable to respond to SCSI INQUIRY immediately, and the SCSI core has to retry the INQUIRY. One of these retries is typically successful, and all is well. But in case of Momobay FX-3A, the INQUIRY retries tend to fail entirely. This can usually be avoided by waiting a little while after login before letting the SCSI core send the INQUIRY. The old sbp2 driver handles this more gracefully for as yet unknown reasons (perhaps because it waits for fetch agent resets to complete, unlike fw-sbp2 which quickly proceeds after requesting the agent reset). Therefore the workaround is not as much necessary for sbp2. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-sbp2.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 72fddf5a12a3..4a118fbc7b24 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " * Avoids access beyond actual disk limits on devices with an off-by-one bug. * Don't use this with devices which don't have this bug. * + * - delay inquiry + * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. + * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. @@ -91,6 +95,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " #define SBP2_WORKAROUND_INQUIRY_36 0x2 #define SBP2_WORKAROUND_MODE_SENSE_8 0x4 #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 +#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10 +#define SBP2_INQUIRY_DELAY 12 #define SBP2_WORKAROUND_OVERRIDE 0x100 static int sbp2_param_workarounds; @@ -100,6 +106,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) + ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); @@ -303,6 +310,11 @@ static const struct { .workarounds = SBP2_WORKAROUND_INQUIRY_36 | SBP2_WORKAROUND_MODE_SENSE_8, }, + /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { + .firmware_revision = 0x002800, + .model = 0x000000, + .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY, + }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model = ~0, @@ -712,6 +724,9 @@ static void sbp2_login(struct work_struct *work) PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); sbp2_agent_reset(lu); + if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) + ssleep(SBP2_INQUIRY_DELAY); + memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff; eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff; From d94a983526cb868658c958ab689410dc1c6a31f3 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:07:44 +0100 Subject: [PATCH 170/880] ieee1394: sbp2: add INQUIRY delay workaround Add the same workaround as found in fw-sbp2 for feature parity and compatibility of the workarounds module parameter. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/ieee1394/sbp2.c | 12 ++++++++++++ drivers/ieee1394/sbp2.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 28e155a9e2a5..accb2ad8b561 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -183,6 +183,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " * Avoids access beyond actual disk limits on devices with an off-by-one bug. * Don't use this with devices which don't have this bug. * + * - delay inquiry + * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. + * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. @@ -195,6 +198,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) + ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); @@ -357,6 +361,11 @@ static const struct { .workarounds = SBP2_WORKAROUND_INQUIRY_36 | SBP2_WORKAROUND_MODE_SENSE_8, }, + /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { + .firmware_revision = 0x002800, + .model_id = 0x000000, + .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY, + }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model_id = SBP2_ROM_VALUE_WILDCARD, @@ -914,6 +923,9 @@ static int sbp2_start_device(struct sbp2_lu *lu) sbp2_agent_reset(lu, 1); sbp2_max_speed_and_size(lu); + if (lu->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) + ssleep(SBP2_INQUIRY_DELAY); + error = scsi_add_device(lu->shost, 0, lu->ud->id, 0); if (error) { SBP2_ERR("scsi_add_device failed"); diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index d2ecb0d8a1bb..80d8e097b065 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h @@ -343,6 +343,8 @@ enum sbp2lu_state_types { #define SBP2_WORKAROUND_INQUIRY_36 0x2 #define SBP2_WORKAROUND_MODE_SENSE_8 0x4 #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 +#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10 +#define SBP2_INQUIRY_DELAY 12 #define SBP2_WORKAROUND_OVERRIDE 0x100 #endif /* SBP2_H */ From e0e60215552d4d40caf581a8d3247203fe948fe7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:08:58 +0100 Subject: [PATCH 171/880] firewire: fw-sbp2: wait for completion of fetch agent reset Like the old sbp2 driver, wait for the write transaction to the AGENT_RESET to complete before proceeding (after login, after reconnect, or in SCSI error handling). There is one occasion where AGENT_RESET is written to from atomic context when getting DEAD status for a command ORB. There we still continue without waiting for the transaction to complete because this is more difficult to fix... Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 39 +++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 4a118fbc7b24..32b50f13e7a8 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -603,29 +603,46 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, static void complete_agent_reset_write(struct fw_card *card, int rcode, - void *payload, size_t length, void *data) + void *payload, size_t length, void *done) { - struct fw_transaction *t = data; + complete(done); +} + +static void sbp2_agent_reset(struct sbp2_logical_unit *lu) +{ + struct fw_device *device = fw_device(lu->tgt->unit->device.parent); + DECLARE_COMPLETION_ONSTACK(done); + struct fw_transaction t; + static u32 z; - kfree(t); + fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, + lu->tgt->node_id, lu->generation, device->max_speed, + lu->command_block_agent_address + SBP2_AGENT_RESET, + &z, sizeof(z), complete_agent_reset_write, &done); + wait_for_completion(&done); } -static int sbp2_agent_reset(struct sbp2_logical_unit *lu) +static void +complete_agent_reset_write_no_wait(struct fw_card *card, int rcode, + void *payload, size_t length, void *data) +{ + kfree(data); +} + +static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) { struct fw_device *device = fw_device(lu->tgt->unit->device.parent); struct fw_transaction *t; - static u32 zero; + static u32 z; - t = kzalloc(sizeof(*t), GFP_ATOMIC); + t = kmalloc(sizeof(*t), GFP_ATOMIC); if (t == NULL) - return -ENOMEM; + return; fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, lu->tgt->node_id, lu->generation, device->max_speed, lu->command_block_agent_address + SBP2_AGENT_RESET, - &zero, sizeof(zero), complete_agent_reset_write, t); - - return 0; + &z, sizeof(z), complete_agent_reset_write_no_wait, t); } static void sbp2_release_target(struct kref *kref) @@ -1086,7 +1103,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) if (status != NULL) { if (STATUS_GET_DEAD(*status)) - sbp2_agent_reset(orb->lu); + sbp2_agent_reset_no_wait(orb->lu); switch (STATUS_GET_RESPONSE(*status)) { case SBP2_STATUS_REQUEST_COMPLETE: From 48f18c761c001a66ef1928b42799c717368b1d64 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:09:50 +0100 Subject: [PATCH 172/880] firewire: fw-sbp2: log bus_id at management request failures for easier readable logs if more than one SBP-2 device is present. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-sbp2.c | 66 +++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 32b50f13e7a8..077f1c09dad4 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -148,6 +148,7 @@ struct sbp2_logical_unit { struct sbp2_target { struct kref kref; struct fw_unit *unit; + const char *bus_id; struct list_head lu_list; u64 management_agent_address; @@ -566,20 +567,20 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, retval = -EIO; if (sbp2_cancel_orbs(lu) == 0) { - fw_error("orb reply timed out, rcode=0x%02x\n", - orb->base.rcode); + fw_error("%s: orb reply timed out, rcode=0x%02x\n", + lu->tgt->bus_id, orb->base.rcode); goto out; } if (orb->base.rcode != RCODE_COMPLETE) { - fw_error("management write failed, rcode 0x%02x\n", - orb->base.rcode); + fw_error("%s: management write failed, rcode 0x%02x\n", + lu->tgt->bus_id, orb->base.rcode); goto out; } if (STATUS_GET_RESPONSE(orb->status) != 0 || STATUS_GET_SBP_STATUS(orb->status) != 0) { - fw_error("error status: %d:%d\n", + fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id, STATUS_GET_RESPONSE(orb->status), STATUS_GET_SBP_STATUS(orb->status)); goto out; @@ -664,7 +665,7 @@ static void sbp2_release_target(struct kref *kref) kfree(lu); } scsi_remove_host(shost); - fw_notify("released %s\n", tgt->unit->device.bus_id); + fw_notify("released %s\n", tgt->bus_id); put_device(&tgt->unit->device); scsi_host_put(shost); @@ -693,12 +694,11 @@ static void sbp2_login(struct work_struct *work) { struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); - struct Scsi_Host *shost = - container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]); + struct sbp2_target *tgt = lu->tgt; + struct fw_device *device = fw_device(tgt->unit->device.parent); + struct Scsi_Host *shost; struct scsi_device *sdev; struct scsi_lun eight_bytes_lun; - struct fw_unit *unit = lu->tgt->unit; - struct fw_device *device = fw_device(unit->device.parent); struct sbp2_login_response response; int generation, node_id, local_node_id; @@ -715,14 +715,14 @@ static void sbp2_login(struct work_struct *work) if (lu->retries++ < 5) sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); else - fw_error("failed to login to %s LUN %04x\n", - unit->device.bus_id, lu->lun); + fw_error("%s: failed to login to LUN %04x\n", + tgt->bus_id, lu->lun); goto out; } - lu->generation = generation; - lu->tgt->node_id = node_id; - lu->tgt->address_high = local_node_id << 16; + lu->generation = generation; + tgt->node_id = node_id; + tgt->address_high = local_node_id << 16; /* Get command block agent offset and login id. */ lu->command_block_agent_address = @@ -730,8 +730,8 @@ static void sbp2_login(struct work_struct *work) response.command_block_agent.low; lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response); - fw_notify("logged in to %s LUN %04x (%d retries)\n", - unit->device.bus_id, lu->lun, lu->retries); + fw_notify("%s: logged in to LUN %04x (%d retries)\n", + tgt->bus_id, lu->lun, lu->retries); #if 0 /* FIXME: The linux1394 sbp2 does this last step. */ @@ -747,6 +747,7 @@ static void sbp2_login(struct work_struct *work) memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff; eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff; + shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); sdev = __scsi_add_device(shost, 0, 0, scsilun_to_int(&eight_bytes_lun), lu); @@ -767,7 +768,7 @@ static void sbp2_login(struct work_struct *work) scsi_device_put(sdev); } out: - sbp2_target_put(lu->tgt); + sbp2_target_put(tgt); } static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) @@ -850,7 +851,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory, if (timeout > tgt->mgt_orb_timeout) fw_notify("%s: config rom contains %ds " "management ORB timeout, limiting " - "to %ds\n", tgt->unit->device.bus_id, + "to %ds\n", tgt->bus_id, timeout / 1000, tgt->mgt_orb_timeout / 1000); break; @@ -878,7 +879,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, if (w) fw_notify("Please notify linux1394-devel@lists.sourceforge.net " "if you need the workarounds parameter for %s\n", - tgt->unit->device.bus_id); + tgt->bus_id); if (w & SBP2_WORKAROUND_OVERRIDE) goto out; @@ -900,8 +901,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, if (w) fw_notify("Workarounds for %s: 0x%x " "(firmware_revision 0x%06x, model_id 0x%06x)\n", - tgt->unit->device.bus_id, - w, firmware_revision, model); + tgt->bus_id, w, firmware_revision, model); tgt->workarounds = w; } @@ -925,6 +925,7 @@ static int sbp2_probe(struct device *dev) tgt->unit = unit; kref_init(&tgt->kref); INIT_LIST_HEAD(&tgt->lu_list); + tgt->bus_id = unit->device.bus_id; if (fw_device_enable_phys_dma(device) < 0) goto fail_shost_put; @@ -975,8 +976,8 @@ static void sbp2_reconnect(struct work_struct *work) { struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); - struct fw_unit *unit = lu->tgt->unit; - struct fw_device *device = fw_device(unit->device.parent); + struct sbp2_target *tgt = lu->tgt; + struct fw_device *device = fw_device(tgt->unit->device.parent); int generation, node_id, local_node_id; if (fw_device_is_shutdown(device)) @@ -991,8 +992,7 @@ static void sbp2_reconnect(struct work_struct *work) SBP2_RECONNECT_REQUEST, lu->login_id, NULL) < 0) { if (lu->retries++ >= 5) { - fw_error("failed to reconnect to %s\n", - unit->device.bus_id); + fw_error("%s: failed to reconnect\n", tgt->bus_id); /* Fall back and try to log in again. */ lu->retries = 0; PREPARE_DELAYED_WORK(&lu->work, sbp2_login); @@ -1001,17 +1001,17 @@ static void sbp2_reconnect(struct work_struct *work) goto out; } - lu->generation = generation; - lu->tgt->node_id = node_id; - lu->tgt->address_high = local_node_id << 16; + lu->generation = generation; + tgt->node_id = node_id; + tgt->address_high = local_node_id << 16; - fw_notify("reconnected to %s LUN %04x (%d retries)\n", - unit->device.bus_id, lu->lun, lu->retries); + fw_notify("%s: reconnected to LUN %04x (%d retries)\n", + tgt->bus_id, lu->lun, lu->retries); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); out: - sbp2_target_put(lu->tgt); + sbp2_target_put(tgt); } static void sbp2_update(struct fw_unit *unit) @@ -1359,7 +1359,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd) { struct sbp2_logical_unit *lu = cmd->device->hostdata; - fw_notify("sbp2_scsi_abort\n"); + fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); From 0fa6dfdb0a2768541e998a5dab10b368de56c60a Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:10:47 +0100 Subject: [PATCH 173/880] firewire: fw-sbp2: don't add scsi_device twice When a reconnect failed but re-login succeeded, __scsi_add_device was called again. In those cases, __scsi_add_device succeeded and returned the pointer to the existing scsi_device. fw-sbp2 then continued orderly, except that it missed to call sbp2_cancel_orbs. SCSI core would call fw-sbp2's eh_abort_handler eventually if there had been an outstanding command. This patch avoids the needless lookups and temporary allocations in SCSI core and I/O stall and timeout until eh_abort_handler hits. Also, __scsi_add_device tolerating calls for devices which already exist is undocumented behavior on which we shouldn't rely. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-sbp2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 077f1c09dad4..914170bb50a8 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -741,6 +741,12 @@ static void sbp2_login(struct work_struct *work) PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); sbp2_agent_reset(lu); + /* This was a re-login. */ + if (lu->sdev) { + sbp2_cancel_orbs(lu); + goto out; + } + if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) ssleep(SBP2_INQUIRY_DELAY); From ce896d95cc7886ae05859c5b409a7b2f3b606ec1 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:11:39 +0100 Subject: [PATCH 174/880] firewire: fw-sbp2: logout and login after failed reconnect If fw-sbp2 was too late with requesting the reconnect, the target would reject this. In this case, log out before attempting the reconnect. Else several firmwares will deny the re-login because they somehow didn't invalidate the old login. Also, don't retry reconnects in this situation. The retries won't succeed either. These changes improve chances for successful re-login and shorten the period during which the logical unit is inaccessible. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-sbp2.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 914170bb50a8..80ab65161750 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -710,6 +710,11 @@ static void sbp2_login(struct work_struct *work) node_id = device->node_id; local_node_id = device->card->node_id; + /* If this is a re-login attempt, log out, or we might be rejected. */ + if (lu->sdev) + sbp2_send_management_orb(lu, device->node_id, generation, + SBP2_LOGOUT_REQUEST, lu->login_id, NULL); + if (sbp2_send_management_orb(lu, node_id, generation, SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) { if (lu->retries++ < 5) @@ -997,9 +1002,17 @@ static void sbp2_reconnect(struct work_struct *work) if (sbp2_send_management_orb(lu, node_id, generation, SBP2_RECONNECT_REQUEST, lu->login_id, NULL) < 0) { - if (lu->retries++ >= 5) { + /* + * If reconnect was impossible even though we are in the + * current generation, fall back and try to log in again. + * + * We could check for "Function rejected" status, but + * looking at the bus generation as simpler and more general. + */ + smp_rmb(); /* get current card generation */ + if (generation == device->card->generation || + lu->retries++ >= 5) { fw_error("%s: failed to reconnect\n", tgt->bus_id); - /* Fall back and try to log in again. */ lu->retries = 0; PREPARE_DELAYED_WORK(&lu->work, sbp2_login); } From 7bb6bf7c8ba0b4ccfecaa00d6faea51b0bd42c8c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 3 Feb 2008 23:12:17 +0100 Subject: [PATCH 175/880] firewire: fw-sbp2: sort includes Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 80ab65161750..323b03bacd29 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -28,15 +28,15 @@ * and many others. */ +#include +#include +#include +#include #include +#include #include #include -#include -#include -#include #include -#include -#include #include #include #include @@ -48,9 +48,9 @@ #include #include -#include "fw-transaction.h" -#include "fw-topology.h" #include "fw-device.h" +#include "fw-topology.h" +#include "fw-transaction.h" /* * So far only bridges from Oxford Semiconductor are known to support From e80de3704ac30ddb7f9a12447a2ecee32ccd7880 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 15 Feb 2008 21:29:02 +0100 Subject: [PATCH 176/880] firewire: fw-sbp2: enforce a retry of __scsi_add_device if bus generation changed fw-sbp2 is unable to reconnect while performing __scsi_add_device because there is only a single workqueue thread context available for both at the moment. This should be fixed eventually. An actual failure of __scsi_add_device is easy to handle, but an incomplete execution of __scsi_add_device with an sdev returned would remain undetected and leave the SBP-2 target unusable. Therefore we use a workaround: If there was a bus reset during __scsi_add_device (i.e. during the SCSI probe), we remove the new sdev immediately, log out, and attempt login and SCSI probe again. Tested-by: Jarod Wilson (earlier version) Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 49 +++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 323b03bacd29..6d10934c58f1 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -762,22 +762,43 @@ static void sbp2_login(struct work_struct *work) sdev = __scsi_add_device(shost, 0, 0, scsilun_to_int(&eight_bytes_lun), lu); - if (IS_ERR(sdev)) { - smp_rmb(); /* generation may have changed */ - generation = device->generation; - smp_rmb(); /* node_id must not be older than generation */ + /* + * FIXME: We are unable to perform reconnects while in sbp2_login(). + * Therefore __scsi_add_device() will get into trouble if a bus reset + * happens in parallel. It will either fail or leave us with an + * unusable sdev. As a workaround we check for this and retry the + * whole login and SCSI probing. + */ - sbp2_send_management_orb(lu, device->node_id, generation, - SBP2_LOGOUT_REQUEST, lu->login_id, NULL); - /* - * Set this back to sbp2_login so we fall back and - * retry login on bus reset. - */ - PREPARE_DELAYED_WORK(&lu->work, sbp2_login); - } else { - lu->sdev = sdev; - scsi_device_put(sdev); + /* Reported error during __scsi_add_device() */ + if (IS_ERR(sdev)) + goto out_logout_login; + + scsi_device_put(sdev); + + /* Unreported error during __scsi_add_device() */ + smp_rmb(); /* get current card generation */ + if (generation != device->card->generation) { + scsi_remove_device(sdev); + goto out_logout_login; } + + /* No error during __scsi_add_device() */ + lu->sdev = sdev; + goto out; + + out_logout_login: + smp_rmb(); /* generation may have changed */ + generation = device->generation; + smp_rmb(); /* node_id must not be older than generation */ + + sbp2_send_management_orb(lu, device->node_id, generation, + SBP2_LOGOUT_REQUEST, lu->login_id, NULL); + /* + * If a bus reset happened, sbp2_update will have requeued + * lu->work already. Reset the work from reconnect to login. + */ + PREPARE_DELAYED_WORK(&lu->work, sbp2_login); out: sbp2_target_put(tgt); } From edd2fd643c500c812cae5b0d314ab9db9f959898 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Fri, 15 Feb 2008 21:00:36 -0600 Subject: [PATCH 177/880] RDMA/nes: Fix VLAN support We need to account for the VLAN header size in nes_netdev_change_mtu() and nes_netdev_init(). Also, add spin lock/unlock during VLAN RX registration so only one process can assign VLAN group for a given interface at a time. Signed-off-by: Chien Tung Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_nic.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 67827ad894e9..eee77da61935 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -932,7 +932,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) return -EINVAL; netdev->mtu = new_mtu; - nesvnic->max_frame_size = new_mtu+ETH_HLEN; + nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN; if (netdev->mtu > 1500) { jumbomode=1; @@ -1494,10 +1494,15 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g { struct nes_vnic *nesvnic = netdev_priv(netdev); struct nes_device *nesdev = nesvnic->nesdev; + struct nes_adapter *nesadapter = nesdev->nesadapter; u32 u32temp; + unsigned long flags; + spin_lock_irqsave(&nesadapter->phy_lock, flags); nesvnic->vlan_grp = grp; + nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name); + /* Enable/Disable VLAN Stripping */ u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG); if (grp) @@ -1506,6 +1511,7 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g u32temp |= 0x02000000; nes_write_indexed(nesdev, NES_IDX_PCIX_DIAG, u32temp); + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); } @@ -1564,7 +1570,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, nesvnic->msg_enable = netif_msg_init(debug, default_msg); nesvnic->netdev_index = nesdev->netdev_count; nesvnic->perfect_filter_index = nesdev->nesadapter->netdev_count; - nesvnic->max_frame_size = netdev->mtu+netdev->hard_header_len; + nesvnic->max_frame_size = netdev->mtu + netdev->hard_header_len + VLAN_HLEN; curr_qp_map = nic_qp_mapping_per_function[PCI_FUNC(nesdev->pcidev->devfn)]; nesvnic->nic.qp_id = curr_qp_map[nesdev->netdev_count].qpid; From a0dd005d1d9f4c3beab52086f3844ef9342d1e67 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 17 Feb 2008 10:35:15 +0000 Subject: [PATCH 178/880] [ARM] pxa: fix clock lookup to find specific device clocks Ensure that the clock lookup always finds an entry for a specific device and ID before it falls back to finding just by ID. This fixes a problem reported by Holger Schurig where the BTUART was assigned the wrong clock. Tested-by: Holger Schurig Signed-off-by: Russell King --- arch/arm/mach-pxa/clock.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index 83ef5ecaf432..df5ae2710ab1 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -23,18 +23,27 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clocks_lock); +static struct clk *clk_lookup(struct device *dev, const char *id) +{ + struct clk *p; + + list_for_each_entry(p, &clocks, node) + if (strcmp(id, p->name) == 0 && p->dev == dev) + return p; + + return NULL; +} + struct clk *clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); mutex_lock(&clocks_mutex); - list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0 && - (p->dev == NULL || p->dev == dev)) { - clk = p; - break; - } - } + p = clk_lookup(dev, id); + if (!p) + p = clk_lookup(NULL, id); + if (p) + clk = p; mutex_unlock(&clocks_mutex); return clk; From 59e8ce574445c5e7a65ec36f47a54803de704e96 Mon Sep 17 00:00:00 2001 From: Byron Bradley Date: Sun, 10 Feb 2008 22:31:09 +0100 Subject: [PATCH 179/880] [ARM] 4826/1: Orion: Register the RTC interrupt on the TS-209 The QNAP TS-209 has its RTC interrupt on GPIO 3. Setup this as an interrupt and pass it to the i2c_board_info. Signed-off-by: Byron Bradley Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-orion/ts209-setup.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c index 306dbcd1e37b..b8cfe6813e9d 100644 --- a/arch/arm/mach-orion/ts209-setup.c +++ b/arch/arm/mach-orion/ts209-setup.c @@ -192,9 +192,13 @@ static struct mv643xx_eth_platform_data qnap_ts209_eth_data = { /***************************************************************************** * RTC S35390A on I2C bus ****************************************************************************/ + +#define TS209_RTC_GPIO 3 + static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = { .driver_name = "rtc-s35390a", .addr = 0x30, + .irq = 0, }; /**************************************************************************** @@ -328,7 +332,18 @@ static void __init qnap_ts209_init(void) platform_add_devices(qnap_ts209_devices, ARRAY_SIZE(qnap_ts209_devices)); + + /* Get RTC IRQ and register the chip */ + if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) { + if (gpio_direction_input(TS209_RTC_GPIO) == 0) + qnap_ts209_i2c_rtc.irq = gpio_to_irq(TS209_RTC_GPIO); + else + gpio_free(TS209_RTC_GPIO); + } + if (qnap_ts209_i2c_rtc.irq == 0) + pr_warning("qnap_ts209_init: failed to get RTC IRQ\n"); i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); + orion_eth_init(&qnap_ts209_eth_data); orion_sata_init(&qnap_ts209_sata_data); } From d6a7b5f84b5c15617010e06c95129fe8800e6b21 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 11 Feb 2008 16:51:41 +0100 Subject: [PATCH 180/880] [ARM] 4827/1: fix two warnings in drivers/i2c/busses/i2c-pxa.c This fixes two warnings: * unused static defined function decode_ICR() when compiled without CONFIG_I2C_PXA_SLAVE * a sparse warning about a void function returning something Signed-off-by: Holger Schurig Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pxa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 2598d29fd7a4..2b557bfd7f70 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -138,11 +138,13 @@ static const struct bits icr_bits[] = { PXA_BIT(ICR_UR, "UR", "ur"), }; +#ifdef CONFIG_I2C_PXA_SLAVE static void decode_ICR(unsigned int val) { decode_bits(KERN_DEBUG "ICR", icr_bits, ARRAY_SIZE(icr_bits), val); printk("\n"); } +#endif static unsigned int i2c_debug = DEBUG; @@ -1122,7 +1124,7 @@ static int __init i2c_adap_pxa_init(void) static void i2c_adap_pxa_exit(void) { - return platform_driver_unregister(&i2c_pxa_driver); + platform_driver_unregister(&i2c_pxa_driver); } MODULE_LICENSE("GPL"); From ac2bf5bdc6ab9d820152623122973ccb1c166031 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 11 Feb 2008 16:52:30 +0100 Subject: [PATCH 181/880] [ARM] 4828/1: fix 3 warnings in drivers/video/pxafb.c * Silence a debug output. * Silence three sparse warnings, one still left. Signed-off-by: Holger Schurig Signed-off-by: Russell King --- drivers/video/pxafb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 10f912df2dad..97facb121c73 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1046,7 +1046,7 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data) switch (val) { case CPUFREQ_ADJUST: case CPUFREQ_INCOMPATIBLE: - printk(KERN_DEBUG "min dma period: %d ps, " + pr_debug("min dma period: %d ps, " "new clock %d kHz\n", pxafb_display_dma_period(var), policy->max); // TODO: fill in min/max values @@ -1361,7 +1361,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options) } #endif -int __init pxafb_probe(struct platform_device *dev) +static int __init pxafb_probe(struct platform_device *dev) { struct pxafb_info *fbi; struct pxafb_mach_info *inf; @@ -1486,7 +1486,7 @@ static struct platform_driver pxafb_driver = { }; #ifndef MODULE -int __devinit pxafb_setup(char *options) +static int __devinit pxafb_setup(char *options) { # ifdef CONFIG_FB_PXA_PARAMETERS if (options) @@ -1501,7 +1501,7 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)"); # endif #endif -int __devinit pxafb_init(void) +static int __devinit pxafb_init(void) { #ifndef MODULE char *option = NULL; From ea833f0b5a8afcc698c5ccb06237902c0e21e032 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 11 Feb 2008 16:53:15 +0100 Subject: [PATCH 182/880] [ARM] 4829/1: add .get method to pxa-cpufreq to silence a warning The .get method is needed for suspend/resume. Otherwise you get this in dmesg: cpufreq: suspend failed to assert current frequency is what timing core thinks it is. cpufreq: resume failed to assert current frequency is what timing core thinks it is. Signed-off-by: Holger Schurig Signed-off-by: Russell King --- arch/arm/mach-pxa/cpu-pxa.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c index cbc583beedc8..939a3867f77c 100644 --- a/arch/arm/mach-pxa/cpu-pxa.c +++ b/arch/arm/mach-pxa/cpu-pxa.c @@ -134,7 +134,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, struct cpufreq_frequency_table *pxa_freqs_table; pxa_freqs_t *pxa_freq_settings; struct cpufreq_freqs freqs; - int idx; + unsigned int idx; unsigned long flags; unsigned int unused, preset_mdrefr, postset_mdrefr; void *ramstart = phys_to_virt(0xa0000000); @@ -233,6 +233,11 @@ static int pxa_set_target(struct cpufreq_policy *policy, return 0; } +static unsigned int pxa_cpufreq_get(unsigned int cpu) +{ + return get_clk_frequency_khz(0); +} + static int pxa_cpufreq_init(struct cpufreq_policy *policy) { int i; @@ -269,6 +274,7 @@ static struct cpufreq_driver pxa_cpufreq_driver = { .verify = pxa_verify_policy, .target = pxa_set_target, .init = pxa_cpufreq_init, + .get = pxa_cpufreq_get, .name = "PXA25x", }; From 6cb59e915d04f71c62a0ee8fab34de274aa3fe2a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:25:52 +0100 Subject: [PATCH 183/880] hwmon: (lm92) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/lm92.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index af5c77d568fe..a2b804115ce5 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,14 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input)); } +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct lm92_data *data = lm92_update_device(dev); + return sprintf(buf, "%d\n", (data->temp1_input >> bitnr) & 1); +} + static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL); static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit, set_temp1_crit); @@ -221,6 +230,9 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max, set_temp1_max); static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); /* @@ -297,7 +309,9 @@ static struct attribute *lm92_attributes[] = { &dev_attr_temp1_max.attr, &dev_attr_temp1_max_hyst.attr, &dev_attr_alarms.attr, - + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, NULL }; From 71062ffcd5173b8291ee80e84711b619b34a64eb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:27:59 +0100 Subject: [PATCH 184/880] hwmon: (max1619) Add individual alarm and fault files The new libsensors needs these individual alarm and fault files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/max1619.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 38a44c3d6cee..342803417973 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,14 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch return sprintf(buf, "%d\n", data->alarms); } +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct max1619_data *data = max1619_update_device(dev); + return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); +} + static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2, @@ -172,6 +181,10 @@ static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2, static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2, set_temp_hyst2); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); static struct attribute *max1619_attributes[] = { &dev_attr_temp1_input.attr, @@ -182,6 +195,10 @@ static struct attribute *max1619_attributes[] = { &dev_attr_temp2_crit_hyst.attr, &dev_attr_alarms.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, NULL }; From 1f08af7ea95e0f4ec632664b9f21a687426df658 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:36:13 +0100 Subject: [PATCH 185/880] hwmon: (smsc47m1) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/smsc47m1.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 0d7f0c4d06bb..d1b498548736 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -198,6 +198,14 @@ static ssize_t get_fan_div(struct device *dev, struct device_attribute return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); } +static ssize_t get_fan_alarm(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + int bitnr = to_sensor_dev_attr(devattr)->index; + struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); + return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); +} + static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -347,6 +355,8 @@ static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ get_fan_min, set_fan_min, offset - 1); \ static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ get_fan_div, set_fan_div, offset - 1); \ +static SENSOR_DEVICE_ATTR(fan##offset##_alarm, S_IRUGO, get_fan_alarm, \ + NULL, offset - 1); \ static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ get_pwm, set_pwm, offset - 1); \ static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ @@ -374,12 +384,15 @@ static struct attribute *smsc47m1_attributes[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan1_min.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan2_min.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, &sensor_dev_attr_fan3_input.dev_attr.attr, &sensor_dev_attr_fan3_min.dev_attr.attr, &sensor_dev_attr_fan3_div.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm1_enable.dev_attr.attr, @@ -533,7 +546,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sensor_dev_attr_fan1_min.dev_attr)) || (err = device_create_file(dev, - &sensor_dev_attr_fan1_div.dev_attr))) + &sensor_dev_attr_fan1_div.dev_attr)) + || (err = device_create_file(dev, + &sensor_dev_attr_fan1_alarm.dev_attr))) goto error_remove_files; } else dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n"); @@ -544,7 +559,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sensor_dev_attr_fan2_min.dev_attr)) || (err = device_create_file(dev, - &sensor_dev_attr_fan2_div.dev_attr))) + &sensor_dev_attr_fan2_div.dev_attr)) + || (err = device_create_file(dev, + &sensor_dev_attr_fan2_alarm.dev_attr))) goto error_remove_files; } else dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n"); @@ -555,7 +572,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sensor_dev_attr_fan3_min.dev_attr)) || (err = device_create_file(dev, - &sensor_dev_attr_fan3_div.dev_attr))) + &sensor_dev_attr_fan3_div.dev_attr)) + || (err = device_create_file(dev, + &sensor_dev_attr_fan3_alarm.dev_attr))) goto error_remove_files; } else if (data->type == smsc47m2) dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); From 13ff05e9f87101407445f79c7402aca087ddbd02 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:42:04 +0100 Subject: [PATCH 186/880] hwmon: (via686a) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/via686a.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 2635bba1e3fc..f1ee5e731968 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -533,6 +533,24 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct via686a_data *data = via686a_update_device(dev); + return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); +} +static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15); +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); + static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -557,6 +575,11 @@ static struct attribute *via686a_attributes[] = { &sensor_dev_attr_in2_max.dev_attr.attr, &sensor_dev_attr_in3_max.dev_attr.attr, &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in0_alarm.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, @@ -567,6 +590,9 @@ static struct attribute *via686a_attributes[] = { &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, @@ -574,6 +600,8 @@ static struct attribute *via686a_attributes[] = { &sensor_dev_attr_fan2_min.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, &dev_attr_alarms.attr, &dev_attr_name.attr, From 2d1374cad5a97d7c08a2c0e4282fb674b588b421 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:46:02 +0100 Subject: [PATCH 187/880] hwmon: (vt8231) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare CC: Roger Lucas Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/vt8231.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index f87661775fe0..ed4b89857673 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -541,6 +541,28 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct vt8231_data *data = vt8231_update_device(dev); + return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); +} +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); + static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -549,36 +571,42 @@ static ssize_t show_name(struct device *dev, struct device_attribute } static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -static struct attribute *vt8231_attributes_temps[6][4] = { +static struct attribute *vt8231_attributes_temps[6][5] = { { &dev_attr_temp1_input.attr, &dev_attr_temp1_max_hyst.attr, &dev_attr_temp1_max.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp3_input.dev_attr.attr, &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp4_input.dev_attr.attr, &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp5_input.dev_attr.attr, &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, &sensor_dev_attr_temp5_max.dev_attr.attr, + &sensor_dev_attr_temp5_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp6_input.dev_attr.attr, &sensor_dev_attr_temp6_max_hyst.dev_attr.attr, &sensor_dev_attr_temp6_max.dev_attr.attr, + &sensor_dev_attr_temp6_alarm.dev_attr.attr, NULL } }; @@ -592,36 +620,42 @@ static const struct attribute_group vt8231_group_temps[6] = { { .attrs = vt8231_attributes_temps[5] }, }; -static struct attribute *vt8231_attributes_volts[6][4] = { +static struct attribute *vt8231_attributes_volts[6][5] = { { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in0_min.dev_attr.attr, &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in0_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_min.dev_attr.attr, &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_in2_min.dev_attr.attr, &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in3_input.dev_attr.attr, &sensor_dev_attr_in3_min.dev_attr.attr, &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in4_input.dev_attr.attr, &sensor_dev_attr_in4_min.dev_attr.attr, &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, NULL }, { &dev_attr_in5_input.attr, &dev_attr_in5_min.attr, &dev_attr_in5_max.attr, + &sensor_dev_attr_in5_alarm.dev_attr.attr, NULL } }; @@ -642,6 +676,8 @@ static struct attribute *vt8231_attributes[] = { &sensor_dev_attr_fan2_min.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, &dev_attr_alarms.attr, &dev_attr_name.attr, NULL From af865765a9ee3e3510f0fe82a4f1308d2820b7f6 Mon Sep 17 00:00:00 2001 From: Roger Lucas Date: Wed, 13 Feb 2008 07:52:06 -0500 Subject: [PATCH 188/880] hwmon: (vt8231) Update maintainer email address Signed-off-by: Roger Lucas (modified MAINTAINERS entry also - MMH) Signed-off-by: Mark M. Hoffman --- MAINTAINERS | 2 +- drivers/hwmon/vt8231.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1d2edb491b34..4e60c94a43d2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4262,7 +4262,7 @@ S: Maintained VT8231 HARDWARE MONITOR DRIVER P: Roger Lucas -M: roger@planbit.co.uk +M: vt8231@hiddenengine.co.uk L: lm-sensors@lm-sensors.org S: Maintained diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index ed4b89857673..5bc57275cae8 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -2,7 +2,7 @@ vt8231.c - Part of lm_sensors, Linux kernel modules for hardware monitoring - Copyright (c) 2005 Roger Lucas + Copyright (c) 2005 Roger Lucas Copyright (c) 2002 Mark D. Studebaker Aaron M. Marsh @@ -999,7 +999,7 @@ static void __exit sm_vt8231_exit(void) } } -MODULE_AUTHOR("Roger Lucas "); +MODULE_AUTHOR("Roger Lucas "); MODULE_DESCRIPTION("VT8231 sensors"); MODULE_LICENSE("GPL"); From 1d5f2c16c6125ae6da1435ac5a190ae08429902a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 10 Feb 2008 19:01:15 +0100 Subject: [PATCH 189/880] hwmon: (adm1026) Properly terminate sysfs groups The missing NULL at the end of two sysfs file groups causes a kernel crash when calling sysfs_create_group(). Signed-off-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/adm1026.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 8002f68240c4..b3e6b06caf61 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -1624,6 +1624,7 @@ static struct attribute *adm1026_attributes_temp3[] = { &dev_attr_temp3_crit_enable.attr, &dev_attr_temp3_auto_point1_pwm.attr, &dev_attr_temp3_auto_point2_pwm.attr, + NULL }; static const struct attribute_group adm1026_group_temp3 = { @@ -1639,6 +1640,7 @@ static struct attribute *adm1026_attributes_in8_9[] = { &sensor_dev_attr_in9_max.dev_attr.attr, &sensor_dev_attr_in9_min.dev_attr.attr, &sensor_dev_attr_in9_alarm.dev_attr.attr, + NULL }; static const struct attribute_group adm1026_group_in8_9 = { From 6369a2887a1b35fde91573adc650528e3efea8e9 Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Fri, 18 Jan 2008 00:42:54 +0100 Subject: [PATCH 190/880] hwmon: (coretemp) Add maximum cooling temperature readout Following patch will add reporting of maximum temperature, at which all fans should spin full speed. It may be non-physical temperature on Desktop/Server CPUs. Signed-off-by: Rudolf Marek Acked-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- Documentation/hwmon/coretemp | 3 ++- drivers/hwmon/coretemp.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index 170bf862437b..7fb74419590f 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp @@ -25,7 +25,8 @@ may be raised, if the temperature grows enough (more than TjMax) to trigger the Out-Of-Spec bit. Following table summarizes the exported sysfs files: temp1_input - Core temperature (in millidegrees Celsius). -temp1_crit - Maximum junction temperature (in millidegrees Celsius). +temp1_max - All cooling devices should be turned on (on Core2). +temp1_crit - Maximum junction temperature (in millidegrees Celsius). temp1_crit_alarm - Set when Out-of-spec bit is set, never clears. Correct CPU operation is no longer guaranteed. temp1_label - Contains string "Core X", where X is processor diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 3ee60d26e3a2..52914e95e9dc 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -38,7 +38,8 @@ #define DRVNAME "coretemp" -typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW; +typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL, + SHOW_NAME } SHOW; /* * Functions declaration @@ -55,6 +56,7 @@ struct coretemp_data { unsigned long last_updated; /* in jiffies */ int temp; int tjmax; + int ttarget; u8 alarm; }; @@ -93,9 +95,10 @@ static ssize_t show_temp(struct device *dev, if (attr->index == SHOW_TEMP) err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN; - else + else if (attr->index == SHOW_TJMAX) err = sprintf(buf, "%d\n", data->tjmax); - + else + err = sprintf(buf, "%d\n", data->ttarget); return err; } @@ -103,6 +106,8 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, SHOW_TEMP); static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, SHOW_TJMAX); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, + SHOW_TTARGET); static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL); static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); @@ -223,8 +228,26 @@ static int __devinit coretemp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); + /* read the still undocumented IA32_TEMPERATURE_TARGET it exists + on older CPUs but not in this register */ + + if (c->x86_model > 0xe) { + err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); + if (err) { + dev_warn(&pdev->dev, "Unable to read" + " IA32_TEMPERATURE_TARGET MSR\n"); + } else { + data->ttarget = data->tjmax - + (((eax >> 8) & 0xff) * 1000); + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp1_max.dev_attr); + if (err) + goto exit_free; + } + } + if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) - goto exit_free; + goto exit_dev; data->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(data->hwmon_dev)) { @@ -238,6 +261,8 @@ static int __devinit coretemp_probe(struct platform_device *pdev) exit_class: sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); +exit_dev: + device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); exit_free: kfree(data); exit: @@ -250,6 +275,7 @@ static int __devexit coretemp_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); + device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); platform_set_drvdata(pdev, NULL); kfree(data); return 0; From ba7c1927aa69c4dfe1ecf646f03b306e49dc8e37 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:22:51 +0100 Subject: [PATCH 191/880] hwmon: (coretemp) fix section mismatch warning Fix following warning: WARNING: vmlinux.o(.text+0xebfd04): Section mismatch in reference from the function coretemp_cpu_callback() to the function .cpuinit.text:coretemp_device_add() coretemp_cpu_callback() are only used inside a HOTPLUG_CPU block so annotate it __cpuinit. The notifier referencing the function are annotated __refdata to silence warning from the exit function. The unregister function do not use the embedded pointer but clears the variable so the annotation is OK. Signed-off-by: Sam Ravnborg Signed-off-by: Mark M. Hoffman --- drivers/hwmon/coretemp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 52914e95e9dc..cbd047eac5b4 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -356,7 +356,7 @@ static void coretemp_device_remove(unsigned int cpu) mutex_unlock(&pdev_list_mutex); } -static int coretemp_cpu_callback(struct notifier_block *nfb, +static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long) hcpu; @@ -373,7 +373,7 @@ static int coretemp_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block coretemp_cpu_notifier = { +static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; #endif /* !CONFIG_HOTPLUG_CPU */ From db4315d6f53edc2cc0b0b06fce1beffebb119c71 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 5 Feb 2008 00:48:13 +0100 Subject: [PATCH 192/880] timer_list: print relative expiry time signed Relative expiry time can get negative, so it should be signed. Signed-off-by: Pavel Machek Signed-off-by: Thomas Gleixner --- kernel/time/timer_list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index d3d94c1a0fd2..67fe8fc21fb1 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c @@ -65,9 +65,9 @@ print_timer(struct seq_file *m, struct hrtimer *timer, int idx, u64 now) SEQ_printf(m, ", %s/%d", tmp, timer->start_pid); #endif SEQ_printf(m, "\n"); - SEQ_printf(m, " # expires at %Lu nsecs [in %Lu nsecs]\n", + SEQ_printf(m, " # expires at %Lu nsecs [in %Ld nsecs]\n", (unsigned long long)ktime_to_ns(timer->expires), - (unsigned long long)(ktime_to_ns(timer->expires) - now)); + (long long)(ktime_to_ns(timer->expires) - now)); } static void From 5910a9b2b1ff6205b39e5e03fdfd0ddb2a78386a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 17 Feb 2008 15:39:24 +0100 Subject: [PATCH 193/880] hwmon: (thmc50) Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Mark M. Hoffman --- drivers/hwmon/thmc50.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 04dd7699b3ac..a42a03c24367 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -52,9 +52,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs " */ #define THMC50_REG_INTR 0x41 -const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; -const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; -const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; +static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; +static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; +static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; #define THMC50_REG_CONF_nFANOFF 0x20 From cd19ba1391f93bc3741d298667c074d2d3fcc9fd Mon Sep 17 00:00:00 2001 From: Riki Oktarianto Date: Mon, 4 Feb 2008 23:41:58 -0800 Subject: [PATCH 194/880] hwmon: (applesmc) sensors set for MacBook2 On my mid-2007 MacBook2, reading Ts0P sensor always failed with this message: applesmc: wait status failed: 5 != 50. So I assume that there's no such Ts0p sensor in this model (please confirm, anyone). If there's the case, then we need a new set of sensors defined for MacBook2. Signed-off-by: Riki Oktarianto Cc: Nicolas Boichat Signed-off-by: Andrew Morton Signed-off-by: Mark M. Hoffman --- drivers/hwmon/applesmc.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 0c94770b7f83..aacc0c4b809c 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -84,12 +84,15 @@ static const char* temperature_sensors_sets[][36] = { /* Set 0: Macbook Pro */ { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, -/* Set 1: Macbook set */ +/* Set 1: Macbook2 set */ + { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H", + "Th0S", "Th1H", NULL }, +/* Set 2: Macbook set */ { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S", "Th1H", "Ts0P", NULL }, -/* Set 2: Macmini set */ +/* Set 3: Macmini set */ { "TC0D", "TC0P", NULL }, -/* Set 3: Mac Pro (2 x Quad-Core) */ +/* Set 4: Mac Pro (2 x Quad-Core) */ { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P", "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P", "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", @@ -1212,12 +1215,14 @@ static void applesmc_release_accelerometer(void) static __initdata struct dmi_match_data applesmc_dmi_data[] = { /* MacBook Pro: accelerometer, backlight and temperature set 0 */ { .accelerometer = 1, .light = 1, .temperature_set = 0 }, -/* MacBook: accelerometer and temperature set 1 */ +/* MacBook2: accelerometer and temperature set 1 */ { .accelerometer = 1, .light = 0, .temperature_set = 1 }, -/* MacMini: temperature set 2 */ - { .accelerometer = 0, .light = 0, .temperature_set = 2 }, -/* MacPro: temperature set 3 */ +/* MacBook: accelerometer and temperature set 2 */ + { .accelerometer = 1, .light = 0, .temperature_set = 2 }, +/* MacMini: temperature set 3 */ { .accelerometer = 0, .light = 0, .temperature_set = 3 }, +/* MacPro: temperature set 4 */ + { .accelerometer = 0, .light = 0, .temperature_set = 4 }, }; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". @@ -1229,16 +1234,20 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { (void*)&applesmc_dmi_data[0]}, { applesmc_dmi_match, "Apple MacBook", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, (void*)&applesmc_dmi_data[1]}, + { applesmc_dmi_match, "Apple MacBook", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, + (void*)&applesmc_dmi_data[2]}, { applesmc_dmi_match, "Apple Macmini", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, - (void*)&applesmc_dmi_data[2]}, + (void*)&applesmc_dmi_data[3]}, { applesmc_dmi_match, "Apple MacPro2", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, - (void*)&applesmc_dmi_data[3]}, + (void*)&applesmc_dmi_data[4]}, { .ident = NULL } }; From c8620c2590f43eff864fe597fcbe5b72ab7a7b94 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 09:00:05 +0800 Subject: [PATCH 195/880] [CRYPTO] null: Add missing Kconfig dependency on BLKCIPHER This patch fixes the following build error caused by commit 3631c650c495d61b1dabf32eb26b46873636e918: <-- snip --> ... LD .tmp_vmlinux1 crypto/built-in.o: In function `skcipher_null_crypt': crypto_null.c:(.text+0x3d14): undefined reference to `blkcipher_walk_virt' crypto_null.c:(.text+0x3d14): relocation truncated to fit: R_MIPS_26 against `blkcipher_walk_virt' crypto/built-in.o: In function `$L32': crypto_null.c:(.text+0x3d54): undefined reference to `blkcipher_walk_done' crypto_null.c:(.text+0x3d54): relocation truncated to fit: R_MIPS_26 against `blkcipher_walk_done' crypto/built-in.o:(.data+0x2e8): undefined reference to `crypto_blkcipher_type' make[1]: *** [.tmp_vmlinux1] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Herbert Xu --- crypto/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index d0287ce56daf..898acc5c1967 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -74,6 +74,7 @@ config CRYPTO_XCBC config CRYPTO_NULL tristate "Null algorithms" select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER help These are 'Null' algorithms, used by IPsec, which do nothing. From 58b7983d15a422d9616bdc4e245d5c31dfaefbe2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 27 Nov 2007 16:53:47 +1100 Subject: [PATCH 196/880] [XFS] Remove Makefile wrappers in XFS Makefile (and Kbuild) would include Makefile-linux-26 I doubt XFS will really still compile on 2.4; so drop that. This moves Makefile-linux-26 into Makefile and drops Kbuild. Also having wrappers as both Kbuild and Makefile seemed redundant anyways. The patch is relatively large because it renames a file, but no functional changes. SGI-PV: 971050 SGI-Modid: xfs-linux-melb:xfs-kern:29781a Signed-off-by: Andi Kleen Signed-off-by: Donald Douwsma Signed-off-by: Tim Shimmin Signed-off-by: Lachlan McIlroy --- fs/xfs/Kbuild | 6 -- fs/xfs/Makefile | 123 +++++++++++++++++++++++++++++++++++++- fs/xfs/Makefile-linux-2.6 | 117 ------------------------------------ 3 files changed, 122 insertions(+), 124 deletions(-) delete mode 100644 fs/xfs/Kbuild diff --git a/fs/xfs/Kbuild b/fs/xfs/Kbuild deleted file mode 100644 index 2566e96706f1..000000000000 --- a/fs/xfs/Kbuild +++ /dev/null @@ -1,6 +0,0 @@ -# -# The xfs people like to share Makefile with 2.6 and 2.4. -# Utilise file named Kbuild file which has precedence over Makefile. -# - -include $(srctree)/$(obj)/Makefile-linux-2.6 diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 49e3e7e5e3dc..6bf3ee2bea5d 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -1 +1,122 @@ -include $(TOPDIR)/fs/xfs/Makefile-linux-$(VERSION).$(PATCHLEVEL) +# +# Copyright (c) 2000-2005 Silicon Graphics, Inc. +# All Rights Reserved. +# +# 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. +# +# This program is distributed in the hope that it would 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, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char + +XFS_LINUX := linux-2.6 + +ifeq ($(CONFIG_XFS_DEBUG),y) + EXTRA_CFLAGS += -g +endif + +obj-$(CONFIG_XFS_FS) += xfs.o +obj-$(CONFIG_XFS_QUOTA) += quota/ +obj-$(CONFIG_XFS_DMAPI) += dmapi/ + +xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o +xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o +xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o +xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o +xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o + + +xfs-y += xfs_alloc.o \ + xfs_alloc_btree.o \ + xfs_attr.o \ + xfs_attr_leaf.o \ + xfs_bit.o \ + xfs_bmap.o \ + xfs_bmap_btree.o \ + xfs_btree.o \ + xfs_buf_item.o \ + xfs_da_btree.o \ + xfs_dir2.o \ + xfs_dir2_block.o \ + xfs_dir2_data.o \ + xfs_dir2_leaf.o \ + xfs_dir2_node.o \ + xfs_dir2_sf.o \ + xfs_error.o \ + xfs_extfree_item.o \ + xfs_filestream.o \ + xfs_fsops.o \ + xfs_ialloc.o \ + xfs_ialloc_btree.o \ + xfs_iget.o \ + xfs_inode.o \ + xfs_inode_item.o \ + xfs_iomap.o \ + xfs_itable.o \ + xfs_dfrag.o \ + xfs_log.o \ + xfs_log_recover.o \ + xfs_mount.o \ + xfs_mru_cache.o \ + xfs_rename.o \ + xfs_trans.o \ + xfs_trans_ail.o \ + xfs_trans_buf.o \ + xfs_trans_extfree.o \ + xfs_trans_inode.o \ + xfs_trans_item.o \ + xfs_utils.o \ + xfs_vfsops.o \ + xfs_vnodeops.o \ + xfs_rw.o \ + xfs_dmops.o \ + xfs_qmops.o + +xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o + +# Objects in linux/ +xfs-y += $(addprefix $(XFS_LINUX)/, \ + kmem.o \ + xfs_aops.o \ + xfs_buf.o \ + xfs_export.o \ + xfs_file.o \ + xfs_fs_subr.o \ + xfs_globals.o \ + xfs_ioctl.o \ + xfs_iops.o \ + xfs_lrw.o \ + xfs_super.o \ + xfs_vnode.o \ + xfs_ksyms.o) + +# Objects in support/ +xfs-y += $(addprefix support/, \ + debug.o \ + uuid.o) + +xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o + +# If both xfs and kdb modules are built in then xfsidbg is built in. If xfs is +# a module and kdb modules are being compiled then xfsidbg must be a module, to +# follow xfs. If xfs is built in then xfsidbg tracks the kdb module state. +# This must come after the main xfs code so xfs initialises before xfsidbg. +# KAO +ifneq ($(CONFIG_KDB_MODULES),) + ifeq ($(CONFIG_XFS_FS),y) + obj-$(CONFIG_KDB_MODULES) += xfsidbg.o + else + obj-$(CONFIG_XFS_FS) += xfsidbg.o + endif +endif + +CFLAGS_xfsidbg.o += -Iarch/$(ARCH)/kdb diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index 97316451fc6d..e69de29bb2d1 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 @@ -1,117 +0,0 @@ -# -# Copyright (c) 2000-2005 Silicon Graphics, Inc. -# All Rights Reserved. -# -# 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. -# -# This program is distributed in the hope that it would 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, write the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char - -XFS_LINUX := linux-2.6 - -ifeq ($(CONFIG_XFS_DEBUG),y) - EXTRA_CFLAGS += -g -endif - -obj-$(CONFIG_XFS_FS) += xfs.o - -xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \ - xfs_dquot.o \ - xfs_dquot_item.o \ - xfs_trans_dquot.o \ - xfs_qm_syscalls.o \ - xfs_qm_bhv.o \ - xfs_qm.o) - -ifeq ($(CONFIG_XFS_QUOTA),y) -xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o -endif - -xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o -xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o -xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o -xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o -xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o - - -xfs-y += xfs_alloc.o \ - xfs_alloc_btree.o \ - xfs_attr.o \ - xfs_attr_leaf.o \ - xfs_bit.o \ - xfs_bmap.o \ - xfs_bmap_btree.o \ - xfs_btree.o \ - xfs_buf_item.o \ - xfs_da_btree.o \ - xfs_dir2.o \ - xfs_dir2_block.o \ - xfs_dir2_data.o \ - xfs_dir2_leaf.o \ - xfs_dir2_node.o \ - xfs_dir2_sf.o \ - xfs_error.o \ - xfs_extfree_item.o \ - xfs_filestream.o \ - xfs_fsops.o \ - xfs_ialloc.o \ - xfs_ialloc_btree.o \ - xfs_iget.o \ - xfs_inode.o \ - xfs_inode_item.o \ - xfs_iomap.o \ - xfs_itable.o \ - xfs_dfrag.o \ - xfs_log.o \ - xfs_log_recover.o \ - xfs_mount.o \ - xfs_mru_cache.o \ - xfs_rename.o \ - xfs_trans.o \ - xfs_trans_ail.o \ - xfs_trans_buf.o \ - xfs_trans_extfree.o \ - xfs_trans_inode.o \ - xfs_trans_item.o \ - xfs_utils.o \ - xfs_vfsops.o \ - xfs_vnodeops.o \ - xfs_rw.o \ - xfs_dmops.o \ - xfs_qmops.o - -xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o - -# Objects in linux/ -xfs-y += $(addprefix $(XFS_LINUX)/, \ - kmem.o \ - xfs_aops.o \ - xfs_buf.o \ - xfs_export.o \ - xfs_file.o \ - xfs_fs_subr.o \ - xfs_globals.o \ - xfs_ioctl.o \ - xfs_iops.o \ - xfs_lrw.o \ - xfs_super.o \ - xfs_vnode.o) - -# Objects in support/ -xfs-y += $(addprefix support/, \ - debug.o \ - uuid.o) - -xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o - From 794f744b225aaf35742aac9e7b9dda96a9943413 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 27 Nov 2007 16:59:56 +1100 Subject: [PATCH 197/880] [XFS] Fix up xfs out-of-tree builds. (a.k.a. external modules) Change -I include directives to find headers in the out-of-tree spot. This allows a directory containing only xfs files to be built as: SGI-PV: 971186 SGI-Modid: xfs-linux-melb:xfs-kern:29878a Signed-off-by: Eric Sandeen Signed-off-by: Donald Douwsma Signed-off-by: Lachlan McIlroy --- fs/xfs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 6bf3ee2bea5d..57c923212d72 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -16,7 +16,7 @@ # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char +EXTRA_CFLAGS += -I$(src) -I$(src)/linux-2.6 -funsigned-char XFS_LINUX := linux-2.6 From 269cdfaf769f5cd831284cc831790c7c5038040f Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Wed, 28 Nov 2007 18:28:09 +1100 Subject: [PATCH 198/880] [XFS] Added quota targets and removed dmapi directory Fixes build failures introduced by bad merge to mainline. --- fs/xfs/Makefile | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 57c923212d72..36ec614e699a 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -25,8 +25,18 @@ ifeq ($(CONFIG_XFS_DEBUG),y) endif obj-$(CONFIG_XFS_FS) += xfs.o -obj-$(CONFIG_XFS_QUOTA) += quota/ -obj-$(CONFIG_XFS_DMAPI) += dmapi/ + +xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \ + xfs_dquot.o \ + xfs_dquot_item.o \ + xfs_trans_dquot.o \ + xfs_qm_syscalls.o \ + xfs_qm_bhv.o \ + xfs_qm.o) + +ifeq ($(CONFIG_XFS_QUOTA),y) +xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o +endif xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o @@ -96,8 +106,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \ xfs_iops.o \ xfs_lrw.o \ xfs_super.o \ - xfs_vnode.o \ - xfs_ksyms.o) + xfs_vnode.o) # Objects in support/ xfs-y += $(addprefix support/, \ @@ -106,17 +115,3 @@ xfs-y += $(addprefix support/, \ xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o -# If both xfs and kdb modules are built in then xfsidbg is built in. If xfs is -# a module and kdb modules are being compiled then xfsidbg must be a module, to -# follow xfs. If xfs is built in then xfsidbg tracks the kdb module state. -# This must come after the main xfs code so xfs initialises before xfsidbg. -# KAO -ifneq ($(CONFIG_KDB_MODULES),) - ifeq ($(CONFIG_XFS_FS),y) - obj-$(CONFIG_KDB_MODULES) += xfsidbg.o - else - obj-$(CONFIG_XFS_FS) += xfsidbg.o - endif -endif - -CFLAGS_xfsidbg.o += -Iarch/$(ARCH)/kdb From 93b2d4a208eeb19bff95e98c34503ce4b03cd0f9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Feb 2008 18:35:07 -0800 Subject: [PATCH 199/880] Revert "[RTNETLINK]: Send a single notification on device state changes." This reverts commit 45b503548210fe6f23e92b856421c2a3f05fd034. It break locking around dev->link_mode as well as cause other bootup problems. Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ecb02afd52dc..61ac8d06292c 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -504,7 +504,7 @@ int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo); -static int set_operstate(struct net_device *dev, unsigned char transition, bool send_notification) +static void set_operstate(struct net_device *dev, unsigned char transition) { unsigned char operstate = dev->operstate; @@ -527,12 +527,8 @@ static int set_operstate(struct net_device *dev, unsigned char transition, bool write_lock_bh(&dev_base_lock); dev->operstate = operstate; write_unlock_bh(&dev_base_lock); - - if (send_notification) - netdev_state_change(dev); - return 1; - } else - return 0; + netdev_state_change(dev); + } } static void copy_rtnl_link_stats(struct rtnl_link_stats *a, @@ -826,7 +822,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (tb[IFLA_BROADCAST]) { nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); send_addr_notify = 1; - modified = 1; } if (ifm->ifi_flags || ifm->ifi_change) { @@ -839,23 +834,16 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, dev_change_flags(dev, flags); } - if (tb[IFLA_TXQLEN]) { - if (dev->tx_queue_len != nla_get_u32(tb[IFLA_TXQLEN])) { - dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); - modified = 1; - } - } + if (tb[IFLA_TXQLEN]) + dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); if (tb[IFLA_OPERSTATE]) - modified |= set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), false); + set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); if (tb[IFLA_LINKMODE]) { - if (dev->link_mode != nla_get_u8(tb[IFLA_LINKMODE])) { - write_lock_bh(&dev_base_lock); - dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); - write_lock_bh(&dev_base_lock); - modified = 1; - } + write_lock_bh(&dev_base_lock); + dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); + write_unlock_bh(&dev_base_lock); } err = 0; @@ -869,10 +857,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - - if (modified) - netdev_state_change(dev); - return err; } @@ -990,7 +974,7 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname, if (tb[IFLA_TXQLEN]) dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); if (tb[IFLA_OPERSTATE]) - set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), true); + set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); if (tb[IFLA_LINKMODE]) dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); From 9ff566074689e3aed1488780b97714ec43ba361d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Feb 2008 18:39:54 -0800 Subject: [PATCH 200/880] Revert "[NDISC]: Fix race in generic address resolution" This reverts commit 69cc64d8d92bf852f933e90c888dfff083bd4fc9. It causes recursive locking in IPV6 because unlike other neighbour layer clients, it even needs neighbour cache entries to send neighbour soliciation messages :-( We'll have to find another way to fix this race. Signed-off-by: David S. Miller --- net/core/neighbour.c | 12 +++++++++--- net/ipv4/arp.c | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 7bb6a9a1256d..a16cf1ec5e5e 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -834,12 +834,18 @@ static void neigh_timer_handler(unsigned long arg) } if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { struct sk_buff *skb = skb_peek(&neigh->arp_queue); - + /* keep skb alive even if arp_queue overflows */ + if (skb) + skb_get(skb); + write_unlock(&neigh->lock); neigh->ops->solicit(neigh, skb); atomic_inc(&neigh->probes); - } + if (skb) + kfree_skb(skb); + } else { out: - write_unlock(&neigh->lock); + write_unlock(&neigh->lock); + } if (notify) neigh_update_notify(neigh); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index c663fa5339ee..8e17f65f4002 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -368,6 +368,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) if (!(neigh->nud_state&NUD_VALID)) printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n"); dst_ha = neigh->ha; + read_lock_bh(&neigh->lock); } else if ((probes -= neigh->parms->app_probes) < 0) { #ifdef CONFIG_ARPD neigh_app_ns(neigh); @@ -377,6 +378,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, dst_ha, dev->dev_addr, NULL); + if (dst_ha) + read_unlock_bh(&neigh->lock); } static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) From 163e3cb7daa8c3a6dde6a13a3d09a198930c6822 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 17 Feb 2008 18:42:03 -0800 Subject: [PATCH 201/880] net/rxrpc: Use BUG_ON if (...) BUG(); should be replaced with BUG_ON(...) when the test has no side-effects to allow a definition of BUG_ON that drops the code completely. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @ disable unlikely @ expression E,f; @@ ( if (<... f(...) ...>) { BUG(); } | - if (unlikely(E)) { BUG(); } + BUG_ON(E); ) @@ expression E,f; @@ ( if (<... f(...) ...>) { BUG(); } | - if (E) { BUG(); } + BUG_ON(E); ) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- net/rxrpc/ar-accept.c | 3 +-- net/rxrpc/ar-ack.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c index 92a87fde8bfe..bdfb77417794 100644 --- a/net/rxrpc/ar-accept.c +++ b/net/rxrpc/ar-accept.c @@ -156,8 +156,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local, false); spin_unlock(&call->lock); notification = NULL; - if (ret < 0) - BUG(); + BUG_ON(ret < 0); } spin_unlock(&call->conn->state_lock); diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c index 657ee69f2133..3ac1672e1070 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c @@ -814,8 +814,7 @@ static int rxrpc_post_message(struct rxrpc_call *call, u32 mark, u32 error, spin_lock_bh(&call->lock); ret = rxrpc_queue_rcv_skb(call, skb, true, fatal); spin_unlock_bh(&call->lock); - if (ret < 0) - BUG(); + BUG_ON(ret < 0); } return 0; From d6584f3a08055688b2344eb26379fb2f3147ce91 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 17 Feb 2008 18:42:53 -0800 Subject: [PATCH 202/880] net/9p/trans_virtio.c: Use BUG_ON if (...) BUG(); should be replaced with BUG_ON(...) when the test has no side-effects to allow a definition of BUG_ON that drops the code completely. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @ disable unlikely @ expression E,f; @@ ( if (<... f(...) ...>) { BUG(); } | - if (unlikely(E)) { BUG(); } + BUG_ON(E); ) @@ expression E,f; @@ ( if (<... f(...) ...>) { BUG(); } | - if (E) { BUG(); } + BUG_ON(E); ) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- net/9p/trans_virtio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 0117b9fb8480..9e3d81cb9f08 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -183,8 +183,7 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, sg_set_buf(&sg[index++], data, s); count -= s; data += s; - if (index > limit) - BUG(); + BUG_ON(index > limit); } return index-start; From 118a88718886a6cb7fb2cf7fb77ef2eea30c73a1 Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Sun, 17 Feb 2008 22:59:39 +0100 Subject: [PATCH 203/880] hwmon: (coretemp) Add TjMax detection for mobile CPUs Following patch will finally solve the detection of Intel Mobile CPUs which share same CPUID with Desktop/Server CPUs. We need this information to test some bit so we know if TjMax is 100C or 85C. Intel claims this works for mobiles only, respect that and set for desktops the TjMax to 100C. Intel provided some table on their wiki based on my chat with them at: http://softwarecommunity.intel.com/isn/Community/en-US/forums/30247249/ShowThread.aspx#30247249 Signed-off-by: Rudolf Marek Signed-off-by: Mark M. Hoffman --- drivers/hwmon/coretemp.c | 83 ++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index cbd047eac5b4..1f34ad84c557 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -152,6 +152,56 @@ static struct coretemp_data *coretemp_update_device(struct device *dev) return data; } +static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) +{ + /* The 100C is default for both mobile and non mobile CPUs */ + + int tjmax = 100000; + int ismobile = 1; + int err; + u32 eax, edx; + + /* Early chips have no MSR for TjMax */ + + if ((c->x86_model == 0xf) && (c->x86_mask < 4)) { + ismobile = 0; + } + + if ((c->x86_model > 0xe) && (ismobile)) { + + /* Now we can detect the mobile CPU using Intel provided table + http://softwarecommunity.intel.com/Wiki/Mobility/720.htm + For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU + */ + + err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx); + if (err) { + dev_warn(dev, + "Unable to access MSR 0x17, assuming desktop" + " CPU\n"); + ismobile = 0; + } else if (!(eax & 0x10000000)) { + ismobile = 0; + } + } + + if (ismobile) { + + err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx); + if (err) { + dev_warn(dev, + "Unable to access MSR 0xEE, for Tjmax, left" + " at default"); + } else if (eax & 0x40000000) { + tjmax = 85000; + } + } else { + dev_warn(dev, "Using relative temperature scale!\n"); + } + + return tjmax; +} + static int __devinit coretemp_probe(struct platform_device *pdev) { struct coretemp_data *data; @@ -168,8 +218,6 @@ static int __devinit coretemp_probe(struct platform_device *pdev) data->id = pdev->id; data->name = "coretemp"; mutex_init(&data->update_lock); - /* Tjmax default is 100 degrees C */ - data->tjmax = 100000; /* test if we can access the THERM_STATUS MSR */ err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); @@ -196,36 +244,7 @@ static int __devinit coretemp_probe(struct platform_device *pdev) } } - /* Some processors have Tjmax 85 following magic should detect it - Intel won't disclose the information without signed NDA, but - individuals cannot sign it. Catch(ed) 22. - */ - - if (((c->x86_model == 0xf) && (c->x86_mask > 3)) || - (c->x86_model == 0xe)) { - err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx); - if (err) { - dev_warn(&pdev->dev, - "Unable to access MSR 0xEE, Tjmax left at %d " - "degrees C\n", data->tjmax/1000); - } else if (eax & 0x40000000) { - data->tjmax = 85000; - } - } - - /* Intel says that above should not work for desktop Core2 processors, - but it seems to work. There is no other way how get the absolute - readings. Warn the user about this. First check if are desktop, - bit 50 of MSR_IA32_PLATFORM_ID should be 0. - */ - - rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx); - - if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) { - dev_warn(&pdev->dev, "Using undocumented features, absolute " - "temperature might be wrong!\n"); - } - + data->tjmax = adjust_tjmax(c, data->id, &pdev->dev); platform_set_drvdata(pdev, data); /* read the still undocumented IA32_TEMPERATURE_TARGET it exists From ae770152c801f10a91e5e86597a39b5f9ccf2d0d Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Fri, 18 Jan 2008 00:50:04 +0100 Subject: [PATCH 204/880] hwmon: (coretemp) Add Penryn CPU to coretemp This patch adds support for family 0x17, which has Penryn Core. It should also cover the 8 cores Xeons. Can someone test please? I think it should work. Signed-off-by: Rudolf Marek Acked-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- Documentation/hwmon/coretemp | 3 ++- drivers/hwmon/coretemp.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp index 7fb74419590f..dbbe6c7025b0 100644 --- a/Documentation/hwmon/coretemp +++ b/Documentation/hwmon/coretemp @@ -4,9 +4,10 @@ Kernel driver coretemp Supported chips: * All Intel Core family Prefix: 'coretemp' - CPUID: family 0x6, models 0xe, 0xf, 0x16 + CPUID: family 0x6, models 0xe, 0xf, 0x16, 0x17 Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide + http://softwarecommunity.intel.com/Wiki/Mobility/720.htm Author: Rudolf Marek diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 1f34ad84c557..70239acecc8e 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -413,10 +413,10 @@ static int __init coretemp_init(void) for_each_online_cpu(i) { struct cpuinfo_x86 *c = &cpu_data(i); - /* check if family 6, models e, f, 16 */ + /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */ if ((c->cpuid_level < 0) || (c->x86 != 0x6) || !((c->x86_model == 0xe) || (c->x86_model == 0xf) || - (c->x86_model == 0x16))) { + (c->x86_model == 0x16) || (c->x86_model == 0x17))) { /* supported CPU not found, but report the unknown family 6 CPU */ From 32b90fc8b11b94b719745512d7e58c0b25717260 Mon Sep 17 00:00:00 2001 From: Matti Linnanvuori Date: Sun, 17 Feb 2008 22:21:04 -0800 Subject: [PATCH 205/880] Documentation: fix tcp.txt Replace BIC with CUBIC as default congestion control. Fix grammar. Signed-off-by: Matti Linnanvuori Signed-off-by: David S. Miller --- Documentation/networking/tcp.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/networking/tcp.txt b/Documentation/networking/tcp.txt index 0121edc3ba06..7d11bb5dc30a 100644 --- a/Documentation/networking/tcp.txt +++ b/Documentation/networking/tcp.txt @@ -1,7 +1,7 @@ TCP protocol ============ -Last updated: 21 June 2005 +Last updated: 9 February 2008 Contents ======== @@ -52,9 +52,9 @@ research and RFC's before developing new modules. The method that is used to determine which congestion control mechanism is determined by the setting of the sysctl net.ipv4.tcp_congestion_control. The default congestion control will be the last one registered (LIFO); -so if you built everything as modules. the default will be reno. If you -build with the default's from Kconfig, then BIC will be builtin (not a module) -and it will end up the default. +so if you built everything as modules, the default will be reno. If you +build with the defaults from Kconfig, then CUBIC will be builtin (not a +module) and it will end up the default. If you really want a particular default value then you will need to set it with the sysctl. If you use a sysctl, the module will be autoloaded From 9c00409a2a677511506126634fbfd9f217989e57 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-Koenig Date: Sun, 17 Feb 2008 22:28:32 -0800 Subject: [PATCH 206/880] [IPV4]: fix alignment of IP-Config output Make the indented lines aligned in the output (not in the code). Signed-off-by: Uwe Kleine-Koenig Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/ipv4/ipconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index a52b5853aaa8..10013ccee8dd 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1390,7 +1390,7 @@ static int __init ip_auto_config(void) * Clue in the operator. */ printk("IP-Config: Complete:"); - printk("\n device=%s", ic_dev->name); + printk("\n device=%s", ic_dev->name); printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr)); printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask)); printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway)); From 9bf1d83e7ee653862ef740435a7f41e8fd6452a9 Mon Sep 17 00:00:00 2001 From: Kris Katterjohn Date: Sun, 17 Feb 2008 22:29:19 -0800 Subject: [PATCH 207/880] [TCP]: Fix tcp_v4_send_synack() comment Signed-off-by: Kris Katterjohn Signed-off-by: David S. Miller --- net/ipv4/tcp_ipv4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 63414ea427c5..00156bf421ca 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -719,7 +719,7 @@ static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, } /* - * Send a SYN-ACK after having received an ACK. + * Send a SYN-ACK after having received a SYN. * This still operates on a request_sock only, not on a big * socket. */ From f47b7257c7368698eabff6fd7b340071932af640 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Sun, 17 Feb 2008 22:31:19 -0800 Subject: [PATCH 208/880] [AX25] ax25_out: check skb for NULL in ax25_kick() According to some OOPS reports ax25_kick tries to clone NULL skbs sometimes. It looks like a race with ax25_clear_queues(). Probably there is no need to add more than a simple check for this yet. Another report suggested there are probably also cases where ax25 ->paclen == 0 can happen in ax25_output(); this wasn't confirmed during testing but let's leave this debugging check for some time. Reported-and-tested-by: Jann Traschewski Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- net/ax25/ax25_out.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c index 92b517af7260..bf706f83a5c9 100644 --- a/net/ax25/ax25_out.c +++ b/net/ax25/ax25_out.c @@ -117,6 +117,12 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb) unsigned char *p; int frontlen, len, fragno, ka9qfrag, first = 1; + if (paclen < 16) { + WARN_ON_ONCE(1); + kfree_skb(skb); + return; + } + if ((skb->len - 1) > paclen) { if (*skb->data == AX25_P_TEXT) { skb_pull(skb, 1); /* skip PID */ @@ -251,8 +257,6 @@ void ax25_kick(ax25_cb *ax25) if (start == end) return; - ax25->vs = start; - /* * Transmit data until either we're out of data to send or * the window is full. Send a poll on the final I frame if @@ -261,8 +265,13 @@ void ax25_kick(ax25_cb *ax25) /* * Dequeue the frame and copy it. + * Check for race with ax25_clear_queues(). */ skb = skb_dequeue(&ax25->write_queue); + if (!skb) + return; + + ax25->vs = start; do { if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { From 227c43c3bca76df704231324405980851dc7f528 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Sun, 17 Feb 2008 22:33:16 -0800 Subject: [PATCH 209/880] [NETLABEL]: Shrink the genl-ops registration code. Turning them to array and registration in a loop saves 80 lines of code and ~300 bytes from text section. Signed-off-by: Pavel Emelyanov Acked-by: Paul Moore Signed-off-by: David S. Miller --- net/netlabel/netlabel_cipso_v4.c | 43 ++++++---------- net/netlabel/netlabel_mgmt.c | 79 +++++++++------------------- net/netlabel/netlabel_unlabeled.c | 86 +++++++++---------------------- 3 files changed, 64 insertions(+), 144 deletions(-) diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index c7ad64d664ad..283ff4a527fd 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -718,36 +718,35 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) * NetLabel Generic NETLINK Command Definitions */ -static struct genl_ops netlbl_cipsov4_genl_c_add = { +static struct genl_ops netlbl_cipsov4_ops[] = { + { .cmd = NLBL_CIPSOV4_C_ADD, .flags = GENL_ADMIN_PERM, .policy = netlbl_cipsov4_genl_policy, .doit = netlbl_cipsov4_add, .dumpit = NULL, -}; - -static struct genl_ops netlbl_cipsov4_genl_c_remove = { + }, + { .cmd = NLBL_CIPSOV4_C_REMOVE, .flags = GENL_ADMIN_PERM, .policy = netlbl_cipsov4_genl_policy, .doit = netlbl_cipsov4_remove, .dumpit = NULL, -}; - -static struct genl_ops netlbl_cipsov4_genl_c_list = { + }, + { .cmd = NLBL_CIPSOV4_C_LIST, .flags = 0, .policy = netlbl_cipsov4_genl_policy, .doit = netlbl_cipsov4_list, .dumpit = NULL, -}; - -static struct genl_ops netlbl_cipsov4_genl_c_listall = { + }, + { .cmd = NLBL_CIPSOV4_C_LISTALL, .flags = 0, .policy = netlbl_cipsov4_genl_policy, .doit = NULL, .dumpit = netlbl_cipsov4_listall, + }, }; /* @@ -764,28 +763,18 @@ static struct genl_ops netlbl_cipsov4_genl_c_listall = { */ int netlbl_cipsov4_genl_init(void) { - int ret_val; + int ret_val, i; ret_val = genl_register_family(&netlbl_cipsov4_gnl_family); if (ret_val != 0) return ret_val; - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, - &netlbl_cipsov4_genl_c_add); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, - &netlbl_cipsov4_genl_c_remove); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, - &netlbl_cipsov4_genl_c_list); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, - &netlbl_cipsov4_genl_c_listall); - if (ret_val != 0) - return ret_val; + for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) { + ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, + &netlbl_cipsov4_ops[i]); + if (ret_val != 0) + return ret_val; + } return 0; } diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index e2258dc3c845..05d98862fbd4 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -517,68 +517,63 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info) * NetLabel Generic NETLINK Command Definitions */ -static struct genl_ops netlbl_mgmt_genl_c_add = { +static struct genl_ops netlbl_mgmt_genl_ops[] = { + { .cmd = NLBL_MGMT_C_ADD, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_add, .dumpit = NULL, -}; - -static struct genl_ops netlbl_mgmt_genl_c_remove = { + }, + { .cmd = NLBL_MGMT_C_REMOVE, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_remove, .dumpit = NULL, -}; - -static struct genl_ops netlbl_mgmt_genl_c_listall = { + }, + { .cmd = NLBL_MGMT_C_LISTALL, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = NULL, .dumpit = netlbl_mgmt_listall, -}; - -static struct genl_ops netlbl_mgmt_genl_c_adddef = { + }, + { .cmd = NLBL_MGMT_C_ADDDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_adddef, .dumpit = NULL, -}; - -static struct genl_ops netlbl_mgmt_genl_c_removedef = { + }, + { .cmd = NLBL_MGMT_C_REMOVEDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_removedef, .dumpit = NULL, -}; - -static struct genl_ops netlbl_mgmt_genl_c_listdef = { + }, + { .cmd = NLBL_MGMT_C_LISTDEF, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_listdef, .dumpit = NULL, -}; - -static struct genl_ops netlbl_mgmt_genl_c_protocols = { + }, + { .cmd = NLBL_MGMT_C_PROTOCOLS, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = NULL, .dumpit = netlbl_mgmt_protocols, -}; - -static struct genl_ops netlbl_mgmt_genl_c_version = { + }, + { .cmd = NLBL_MGMT_C_VERSION, .flags = 0, .policy = netlbl_mgmt_genl_policy, .doit = netlbl_mgmt_version, .dumpit = NULL, + }, }; /* @@ -595,44 +590,18 @@ static struct genl_ops netlbl_mgmt_genl_c_version = { */ int netlbl_mgmt_genl_init(void) { - int ret_val; + int ret_val, i; ret_val = genl_register_family(&netlbl_mgmt_gnl_family); if (ret_val != 0) return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_add); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_remove); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_listall); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_adddef); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_removedef); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_listdef); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_protocols); - if (ret_val != 0) - return ret_val; - ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, - &netlbl_mgmt_genl_c_version); - if (ret_val != 0) - return ret_val; + for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) { + ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, + &netlbl_mgmt_genl_ops[i]); + if (ret_val != 0) + return ret_val; + } return 0; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 3e745b72fded..f0f1322911de 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1553,68 +1553,63 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, * NetLabel Generic NETLINK Command Definitions */ -static struct genl_ops netlbl_unlabel_genl_c_staticadd = { +static struct genl_ops netlbl_unlabel_genl_ops[] = { + { .cmd = NLBL_UNLABEL_C_STATICADD, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticadd, .dumpit = NULL, -}; - -static struct genl_ops netlbl_unlabel_genl_c_staticremove = { + }, + { .cmd = NLBL_UNLABEL_C_STATICREMOVE, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticremove, .dumpit = NULL, -}; - -static struct genl_ops netlbl_unlabel_genl_c_staticlist = { + }, + { .cmd = NLBL_UNLABEL_C_STATICLIST, .flags = 0, .policy = netlbl_unlabel_genl_policy, .doit = NULL, .dumpit = netlbl_unlabel_staticlist, -}; - -static struct genl_ops netlbl_unlabel_genl_c_staticadddef = { + }, + { .cmd = NLBL_UNLABEL_C_STATICADDDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticadddef, .dumpit = NULL, -}; - -static struct genl_ops netlbl_unlabel_genl_c_staticremovedef = { + }, + { .cmd = NLBL_UNLABEL_C_STATICREMOVEDEF, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_staticremovedef, .dumpit = NULL, -}; - -static struct genl_ops netlbl_unlabel_genl_c_staticlistdef = { + }, + { .cmd = NLBL_UNLABEL_C_STATICLISTDEF, .flags = 0, .policy = netlbl_unlabel_genl_policy, .doit = NULL, .dumpit = netlbl_unlabel_staticlistdef, -}; - -static struct genl_ops netlbl_unlabel_genl_c_accept = { + }, + { .cmd = NLBL_UNLABEL_C_ACCEPT, .flags = GENL_ADMIN_PERM, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_accept, .dumpit = NULL, -}; - -static struct genl_ops netlbl_unlabel_genl_c_list = { + }, + { .cmd = NLBL_UNLABEL_C_LIST, .flags = 0, .policy = netlbl_unlabel_genl_policy, .doit = netlbl_unlabel_list, .dumpit = NULL, + }, }; /* @@ -1631,51 +1626,18 @@ static struct genl_ops netlbl_unlabel_genl_c_list = { */ int netlbl_unlabel_genl_init(void) { - int ret_val; + int ret_val, i; ret_val = genl_register_family(&netlbl_unlabel_gnl_family); if (ret_val != 0) return ret_val; - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_staticadd); - if (ret_val != 0) - return ret_val; - - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_staticremove); - if (ret_val != 0) - return ret_val; - - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_staticlist); - if (ret_val != 0) - return ret_val; - - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_staticadddef); - if (ret_val != 0) - return ret_val; - - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_staticremovedef); - if (ret_val != 0) - return ret_val; - - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_staticlistdef); - if (ret_val != 0) - return ret_val; - - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_accept); - if (ret_val != 0) - return ret_val; - - ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, - &netlbl_unlabel_genl_c_list); - if (ret_val != 0) - return ret_val; + for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) { + ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, + &netlbl_unlabel_genl_ops[i]); + if (ret_val != 0) + return ret_val; + } return 0; } From 05705e4e1158ad2c1a22817f27d91ff0758fd0a9 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Sun, 17 Feb 2008 22:33:57 -0800 Subject: [PATCH 210/880] [NETLABEL]: Move some initialization code into __init section. Everything that is called from netlbl_init() can be marked with __init. This moves 620 bytes from .text section to .text.init one. Signed-off-by: Pavel Emelyanov Acked-by: Paul Moore Signed-off-by: David S. Miller --- net/netlabel/netlabel_cipso_v4.c | 2 +- net/netlabel/netlabel_domainhash.c | 2 +- net/netlabel/netlabel_mgmt.c | 2 +- net/netlabel/netlabel_unlabeled.c | 6 +++--- net/netlabel/netlabel_user.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 283ff4a527fd..fdc14a0d21af 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -761,7 +761,7 @@ static struct genl_ops netlbl_cipsov4_ops[] = { * mechanism. Returns zero on success, negative values on failure. * */ -int netlbl_cipsov4_genl_init(void) +int __init netlbl_cipsov4_genl_init(void) { int ret_val, i; diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index fd462313471c..02c2f7c0b255 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -171,7 +171,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) * values on error. * */ -int netlbl_domhsh_init(u32 size) +int __init netlbl_domhsh_init(u32 size) { u32 iter; struct netlbl_domhsh_tbl *hsh_tbl; diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 05d98862fbd4..22c191267808 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -588,7 +588,7 @@ static struct genl_ops netlbl_mgmt_genl_ops[] = { * mechanism. Returns zero on success, negative values on failure. * */ -int netlbl_mgmt_genl_init(void) +int __init netlbl_mgmt_genl_init(void) { int ret_val, i; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index f0f1322911de..4478f2f6079d 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1624,7 +1624,7 @@ static struct genl_ops netlbl_unlabel_genl_ops[] = { * mechanism. Returns zero on success, negative values on failure. * */ -int netlbl_unlabel_genl_init(void) +int __init netlbl_unlabel_genl_init(void) { int ret_val, i; @@ -1661,7 +1661,7 @@ static struct notifier_block netlbl_unlhsh_netdev_notifier = { * non-zero values on error. * */ -int netlbl_unlabel_init(u32 size) +int __init netlbl_unlabel_init(u32 size) { u32 iter; struct netlbl_unlhsh_tbl *hsh_tbl; @@ -1765,7 +1765,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, * and to send unlabeled network traffic by default. * */ -int netlbl_unlabel_defconf(void) +int __init netlbl_unlabel_defconf(void) { int ret_val; struct netlbl_dom_map *entry; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 023fc8fe840d..b17d4203806e 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -59,7 +59,7 @@ * non-zero on failure. * */ -int netlbl_netlink_init(void) +int __init netlbl_netlink_init(void) { int ret_val; From 5ee46e562c9c10a5e25920c4406a42061cf27839 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Sun, 17 Feb 2008 22:34:53 -0800 Subject: [PATCH 211/880] [IPV6]: Fix hardcoded removing of old module code Rusty hardcoded the old module code. We can remove it now. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index bddac0e8780f..f0aa97738746 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -752,14 +752,6 @@ static int __init inet6_init(void) BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)); -#ifdef MODULE -#if 0 /* FIXME --RR */ - if (!mod_member_present(&__this_module, can_unload)) - return -EINVAL; - - __this_module.can_unload = &ipv6_unload; -#endif -#endif err = proto_register(&tcpv6_prot, 1); if (err) goto out; From 54cd6ddec77b75e6926d73d263aec72255b24030 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 14 Feb 2008 00:37:21 -0800 Subject: [PATCH 212/880] [SPARC64]: Remove Makefile code for ancient gcc and binutils. The kernel hasn't supported the compilers which need these tests for years. Signed-off-by: David S. Miller --- arch/sparc64/Makefile | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index 01159cb5f16d..848e33410b43 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile @@ -12,39 +12,12 @@ CHECKFLAGS += -D__sparc__ -D__sparc_v9__ -m64 CPPFLAGS_vmlinux.lds += -Usparc -CC := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo $(CC); else echo sparc64-linux-gcc; fi ) - -NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow) -NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi) -UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; ) - -ifneq ($(NEW_GAS),y) -AS = sparc64-linux-as -LD = sparc64-linux-ld -NM = sparc64-linux-nm -AR = sparc64-linux-ar -RANLIB = sparc64-linux-ranlib -else -AS := $(AS) -64 LDFLAGS := -m elf64_sparc -endif -ifneq ($(UNDECLARED_REGS),y) -CC_UNDECL = -else -CC_UNDECL = -Wa,--undeclared-regs -AS := $(AS) --undeclared-regs -endif - -ifneq ($(NEW_GCC),y) - KBUILD_CFLAGS += -pipe -mno-fpu -mtune=ultrasparc -mmedlow \ - -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare -else - KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ - -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ - $(CC_UNDECL) - KBUILD_AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL) -endif +KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ + -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ + -Wa,--undeclared-regs +KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs ifeq ($(CONFIG_MCOUNT),y) KBUILD_CFLAGS += -pg From 966d905634de4433cea465fdcea19503c4ae260f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 14 Feb 2008 00:58:44 -0800 Subject: [PATCH 213/880] [SPARC64]: Add -mtune=ultrasparc3 if possible. This gives better heuristics for the cost of a multiply (fixed 5 cycles), rather than the 'ultrasparc' setting (variable, and unpredictable if the second argument is non-constant). Example code size savings: text data bss dec hex filename 3823690 304040 448880 4576610 45d562 vmlinux 3824521 304040 448880 4577441 45d8a1 vmlinux.orig Signed-off-by: David S. Miller --- arch/sparc64/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index 848e33410b43..f0c22f826982 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile @@ -17,6 +17,7 @@ LDFLAGS := -m elf64_sparc KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \ -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \ -Wa,--undeclared-regs +KBUILD_CFLAGS += $(call cc-option,-mtune=ultrasparc3) KBUILD_AFLAGS += -m64 -mcpu=ultrasparc -Wa,--undeclared-regs ifeq ($(CONFIG_MCOUNT),y) From f6095a5176e17b510235e80ecfb542eaee6e5666 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Feb 2008 22:44:32 -0800 Subject: [PATCH 214/880] [SPARC64]: Update defconfig. Signed-off-by: David S. Miller --- arch/sparc64/defconfig | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 50dc09055783..250958d1e3cb 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24 -# Tue Feb 5 17:28:19 2008 +# Linux kernel version: 2.6.25-rc1 +# Sun Feb 17 22:44:12 2008 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -10,6 +10,7 @@ CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_64BIT=y CONFIG_MMU=y +CONFIG_IOMMU_HELPER=y CONFIG_QUICKLIST=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -21,6 +22,7 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_OF=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_SPARC64_PAGE_SIZE_8KB=y # CONFIG_SPARC64_PAGE_SIZE_64KB is not set # CONFIG_SPARC64_PAGE_SIZE_512KB is not set @@ -49,8 +51,6 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # 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 is not set CONFIG_LOG_BUF_SHIFT=18 @@ -60,6 +60,11 @@ CONFIG_FAIR_USER_SCHED=y # CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -74,6 +79,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y @@ -176,13 +182,13 @@ CONFIG_PCI_MSI=y CONFIG_SUN_OPENPROMFS=m CONFIG_SPARC32_COMPAT=y CONFIG_COMPAT=y -CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_AOUT32 is not set # # Executable file formats # CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y CONFIG_BINFMT_MISC=m CONFIG_SOLARIS_EMUL=y CONFIG_SCHED_SMT=y @@ -354,6 +360,8 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y CONFIG_IDE=y CONFIG_BLK_DEV_IDE=y @@ -376,6 +384,7 @@ CONFIG_IDE_PROC_FS=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y # # PCI IDE chipsets support @@ -775,7 +784,6 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_TPS65010 is not set # CONFIG_SENSORS_MAX6875 is not set @@ -831,6 +839,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set @@ -840,9 +849,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_THERMAL is not set # CONFIG_WATCHDOG is not set # @@ -1201,6 +1212,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_TEST is not set # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set # CONFIG_RTC_CLASS is not set @@ -1242,12 +1254,10 @@ CONFIG_FS_POSIX_ACL=y # 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 @@ -1291,8 +1301,10 @@ CONFIG_HUGETLB_PAGE=y # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 CONFIG_NETWORK_FILESYSTEMS=y @@ -1370,6 +1382,7 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1385,7 +1398,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_KPROBES_SANITY_TEST is not set From 3c62a2d3477ff7725210db57aec3d2806fa10c20 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Feb 2008 23:22:50 -0800 Subject: [PATCH 215/880] [SPARC64]: Always register a PROM based early console. Signed-off-by: David S. Miller --- arch/sparc64/kernel/prom.c | 1 - arch/sparc64/kernel/setup.c | 14 +++++++------- arch/sparc64/mm/init.c | 6 +++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index a246e962e5a7..68964ddcde1e 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -1716,7 +1716,6 @@ static void __init of_console_init(void) of_console_device = dp; - prom_printf(msg, of_console_path); printk(msg, of_console_path); } diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 5964d8653ade..ebad74bd88bb 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -83,10 +83,10 @@ unsigned int boot_flags = 0; /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size = 0; -static struct console prom_debug_console = { - .name = "debug", +static struct console prom_early_console = { + .name = "earlyprom", .write = prom_console_write, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1, }; @@ -112,8 +112,7 @@ static void __init process_switch(char c) prom_halt(); break; case 'p': - /* Use PROM debug console. */ - register_console(&prom_debug_console); + /* Just ignore, this behavior is now the default. */ break; case 'P': /* Force UltraSPARC-III P-Cache on. */ @@ -296,6 +295,9 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = prom_getbootargs(); strcpy(boot_command_line, *cmdline_p); + boot_flags_init(*cmdline_p); + register_console(&prom_early_console); + if (tlb_type == hypervisor) printk("ARCH: SUN4V\n"); else @@ -307,8 +309,6 @@ void __init setup_arch(char **cmdline_p) conswitchp = &prom_con; #endif - boot_flags_init(*cmdline_p); - idprom_init(); if (!root_flags) diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 035c73243adc..9e6bca266d88 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -618,9 +618,9 @@ static void __init inherit_prom_mappings(void) read_obp_translations(); /* Now fixup OBP's idea about where we really are mapped. */ - prom_printf("Remapping the kernel... "); + printk("Remapping the kernel... "); remap_kernel(); - prom_printf("done.\n"); + printk("done.\n"); } void prom_world(int enter) @@ -1414,7 +1414,7 @@ void __init paging_init(void) zholes_size); } - prom_printf("Booting Linux...\n"); + printk("Booting Linux...\n"); central_probe(); cpu_probe(); From cbc9fc5dec60f84b62e0144165c545abd24847c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=2E=C3=87a=C4=9Flar=20Onur?= Date: Sun, 17 Feb 2008 23:24:10 -0800 Subject: [PATCH 216/880] [SPARC64] arch/sparc64/kernel/unaligned.c: Use time_* macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functions time_before, time_before_eq, time_after, and time_after_eq are more robust for comparing jiffies against other values. So following patch implements usage of the time_after() macro, defined at linux/jiffies.h, which deals with wrapping correctly Signed-off-by: S.Çağlar Onur Signed-off-by: David S. Miller --- arch/sparc64/kernel/unaligned.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index dc7bf1b6321c..1a511e9f0d3e 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -7,6 +7,7 @@ */ +#include #include #include #include @@ -283,7 +284,7 @@ static void log_unaligned(struct pt_regs *regs) { static unsigned long count, last_time; - if (jiffies - last_time > 5 * HZ) + if (time_after(jiffies, last_time + 5 * HZ)) count = 0; if (count < 5) { last_time = jiffies; From 82453021b8be85171350c695d7ebafe7b517c812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=2E=C3=87a=C4=9Flar=20Onur?= Date: Sun, 17 Feb 2008 23:25:57 -0800 Subject: [PATCH 217/880] [BLUETOOTH] net/bluetooth/hci_core.c: Use time_* macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functions time_before, time_before_eq, time_after, and time_after_eq are more robust for comparing jiffies against other values. So following patch implements usage of the time_after() macro, defined at linux/jiffies.h, which deals with wrapping correctly Signed-off-by: S.Çağlar Onur Acked-by: Marcel Holtmann Signed-off-by: David S. Miller --- net/bluetooth/hci_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 372b0d3b75a8..930b58e7149a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -24,6 +24,7 @@ /* Bluetooth HCI core. */ +#include #include #include @@ -1321,7 +1322,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev) if (!test_bit(HCI_RAW, &hdev->flags)) { /* ACL tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ - if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45)) + if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45)) hci_acl_tx_to(hdev); } @@ -1543,7 +1544,7 @@ static void hci_cmd_task(unsigned long arg) BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); - if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) { + if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) { BT_ERR("%s command tx timeout", hdev->name); atomic_set(&hdev->cmd_cnt, 1); } From b791160b5af4ea95c72fb59d13079664beca1963 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Sun, 17 Feb 2008 23:29:30 -0800 Subject: [PATCH 218/880] [XFRM]: Fix ordering issue in xfrm_dst_hash_transfer(). Keep ordering of policy entries with same selector in xfrm_dst_hash_transfer(). Issue should not appear in usual cases because multiple policy entries with same selector are basically not allowed so far. Bug was pointed out by Sebastien Decugis . We could convert bydst from hlist to list and use list_add_tail() instead. Signed-off-by: YOSHIFUJI Hideaki Acked-by: Sebastien Decugis Signed-off-by: David S. Miller --- net/xfrm/xfrm_policy.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 47219f98053f..9fc4c315f6cd 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -331,15 +331,31 @@ static void xfrm_dst_hash_transfer(struct hlist_head *list, struct hlist_head *ndsttable, unsigned int nhashmask) { - struct hlist_node *entry, *tmp; + struct hlist_node *entry, *tmp, *entry0 = NULL; struct xfrm_policy *pol; + unsigned int h0 = 0; +redo: hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) { unsigned int h; h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr, pol->family, nhashmask); - hlist_add_head(&pol->bydst, ndsttable+h); + if (!entry0) { + hlist_del(entry); + hlist_add_head(&pol->bydst, ndsttable+h); + h0 = h; + } else { + if (h != h0) + continue; + hlist_del(entry); + hlist_add_after(entry0, &pol->bydst); + } + entry0 = entry; + } + if (!hlist_empty(list)) { + entry0 = NULL; + goto redo; } } From 235365f3aaaa10b7056293877c0ead50425f25c7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 17 Feb 2008 23:34:54 -0800 Subject: [PATCH 219/880] net/8021q/vlan_dev.c: Use print_mac. Remove direct use of MAC_FMT Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/8021q/vlan_dev.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 77f04e49a1a0..fc60c6d096b9 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -366,7 +366,8 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = &dev->stats; struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); - + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING @@ -404,11 +405,8 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) pr_debug("%s: about to send skb: %p to dev: %s\n", __FUNCTION__, skb, skb->dev->name); - pr_debug(" " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n", - veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], - veth->h_dest[3], veth->h_dest[4], veth->h_dest[5], - veth->h_source[0], veth->h_source[1], veth->h_source[2], - veth->h_source[3], veth->h_source[4], veth->h_source[5], + pr_debug(" %s %s %4hx %4hx %4hx\n", + print_mac(mac, veth->h_dest), print_mac(mac2, veth->h_source), veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto); From fea5fa875eb235dc186b1f5184eb36abc63e26cc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 17 Feb 2008 23:35:28 -0800 Subject: [PATCH 220/880] [NET]: Remove MAC_FMT MAC_FMT is no longer used Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/linux/if_ether.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index e157c1399b61..7a1e011b8a2c 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -130,7 +130,6 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); * Display a 6 byte device address (MAC) in a readable format. */ extern char *print_mac(char *buf, const unsigned char *addr); -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" #define MAC_BUF_SIZE 18 #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused From 988d0093f9cb2bf27c299e373f9cbaac47dab2c1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 00:20:50 -0800 Subject: [PATCH 221/880] [BLUETOOTH] hci_sysfs.c: Kill build warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/bluetooth/hci_sysfs.c: In function ‘del_conn’: net/bluetooth/hci_sysfs.c:339: warning: suggest parentheses around assignment used as truth value Signed-off-by: David S. Miller --- net/bluetooth/hci_sysfs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index e13cf5ef144c..f5aff6d0988a 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -333,10 +333,14 @@ static int __match_tty(struct device *dev, void *data) static void del_conn(struct work_struct *work) { - struct device *dev; struct hci_conn *conn = container_of(work, struct hci_conn, work); - while (dev = device_find_child(&conn->dev, NULL, __match_tty)) { + while (1) { + struct device *dev; + + dev = device_find_child(&conn->dev, NULL, __match_tty); + if (!dev) + break; device_move(dev, NULL); put_device(dev); } From a9254475bbfbed5f0596d952c6a3c9806e19dd0b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Jan 2008 18:32:35 -0300 Subject: [PATCH 222/880] V4L/DVB (7115): Fix bug #9833: regression when compiling V4L without I2C Adrian Bunk reported: > > Commit 8ffbc6559493c64d6194c92d856196fdaeb8a5fb causes the following > > compile error with CONFIG_VIDEO_DEV=y/m, CONFIG_I2C=n: > > > > <-- snip --> > > > > ... > > MODPOST 26 modules > > ERROR: "i2c_attach_client" [drivers/media/video/v4l2-common.ko] undefined! > > make[2]: *** [__modpost] Error 1 > > > > <-- snip --> ... And what should happen if CONFIG_VIDEO_DEV=y, CONFIG_I2C=m? CC: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 5 ++++ drivers/media/video/Makefile | 5 ++-- drivers/media/video/v4l2-common.c | 38 +++++++++++++------------------ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 8f4a45346de7..707b20d7efb7 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -25,6 +25,11 @@ config VIDEO_DEV To compile this driver as a module, choose M here: the module will be called videodev. +config VIDEO_V4L2_COMMON + tristate + depends on (I2C || I2C=n) && VIDEO_DEV + default (I2C || I2C=n) && VIDEO_DEV + config VIDEO_V4L1 bool "Enable Video For Linux API 1 (DEPRECATED)" depends on VIDEO_DEV diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 850b8c6f4577..3f209b32eeac 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -10,8 +10,9 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o stkwebcam-objs := stk-webcam.o stk-sensor.o -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \ - v4l2-int-device.o +obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o + +obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index c056ff6d810c..74d0a5996697 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -973,6 +973,18 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) return **ctrl_classes; } +int v4l2_chip_match_host(u32 match_type, u32 match_chip) +{ + switch (match_type) { + case V4L2_CHIP_MATCH_HOST: + return match_chip == 0; + default: + return 0; + } +} +EXPORT_SYMBOL(v4l2_chip_match_host); + +#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip) { switch (match_type) { @@ -984,6 +996,7 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c return 0; } } +EXPORT_SYMBOL(v4l2_chip_match_i2c_client); int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip, u32 ident, u32 revision) @@ -1000,16 +1013,7 @@ int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chi } return 0; } - -int v4l2_chip_match_host(u32 match_type, u32 match_chip) -{ - switch (match_type) { - case V4L2_CHIP_MATCH_HOST: - return match_chip == 0; - default: - return 0; - } -} +EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); /* ----------------------------------------------------------------- */ @@ -1038,6 +1042,8 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver } return err != -ENOMEM ? 0 : err; } +EXPORT_SYMBOL(v4l2_i2c_attach); +#endif /* ----------------------------------------------------------------- */ @@ -1061,15 +1067,3 @@ EXPORT_SYMBOL(v4l2_ctrl_get_menu); EXPORT_SYMBOL(v4l2_ctrl_query_menu); EXPORT_SYMBOL(v4l2_ctrl_query_fill); EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); - -EXPORT_SYMBOL(v4l2_chip_match_i2c_client); -EXPORT_SYMBOL(v4l2_chip_ident_i2c_client); -EXPORT_SYMBOL(v4l2_chip_match_host); - -EXPORT_SYMBOL(v4l2_i2c_attach); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ From 1a4e30c3eaffb83218977477bb83d54316844acb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 13:15:52 -0300 Subject: [PATCH 223/880] V4L/DVB (7119): Remove obsolete code from v4l2-common Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-common.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 74d0a5996697..4a8fc170138b 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -81,7 +81,6 @@ MODULE_LICENSE("GPL"); * Video Standard Operations (contributed by Michael Schimek) */ - char *v4l2_norm_to_name(v4l2_std_id id) { char *name; @@ -270,9 +269,6 @@ char *v4l2_type_names[] = { [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", }; - -#define prt_names(a,arr) (((a)>=0)&&((a) Date: Sat, 2 Feb 2008 11:25:31 -0300 Subject: [PATCH 224/880] V4L/DVB (7133): Fix Kconfig dependencies As pointed by Adrian Bunk, with I2C=m and VIDEO_DEV=y, videodev brokes. This patch moves the functions that videodev needs from v4l2-common. It also fixes some Kconfig changes. After this patch, I2C=m / VIDEO_DEV=y will make v4l2 core statically linked into kernel. v4l2-common will be m, and all V4L drivers will also be m. This approach is very conservative, since it is possible to have V4L drivers that don't need I2C or v4l2-common. The better is to map what drivers really need v4l2-common, making them to select v4l2-common, and allowing the others to be 'y', 'm' and 'n'. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 11 +- drivers/media/common/Kconfig | 2 +- drivers/media/radio/Kconfig | 4 +- drivers/media/video/Kconfig | 4 +- drivers/media/video/v4l2-common.c | 351 +---------------------- drivers/media/video/videodev.c | 444 ++++++++++++++++++++++++++---- include/media/v4l2-common.h | 2 - include/media/v4l2-dev.h | 2 + 8 files changed, 409 insertions(+), 411 deletions(-) diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 707b20d7efb7..888dcadff710 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -32,9 +32,9 @@ config VIDEO_V4L2_COMMON config VIDEO_V4L1 bool "Enable Video For Linux API 1 (DEPRECATED)" - depends on VIDEO_DEV + depends on VIDEO_DEV && VIDEO_V4L2_COMMON + default VIDEO_DEV && VIDEO_V4L2_COMMON select VIDEO_V4L1_COMPAT - default y ---help--- Enables a compatibility API used by most V4L2 devices to allow its usage with legacy applications that supports only V4L1 api. @@ -44,7 +44,7 @@ config VIDEO_V4L1 config VIDEO_V4L1_COMPAT bool "Enable Video For Linux API 1 compatible Layer" depends on VIDEO_DEV - default y + default VIDEO_DEV ---help--- This api were developed to be used at Kernel 2.2 and 2.4, but lacks support for several video standards. There are several @@ -60,8 +60,8 @@ config VIDEO_V4L1_COMPAT config VIDEO_V4L2 bool - depends on VIDEO_DEV - default y + depends on VIDEO_DEV && VIDEO_V4L2_COMMON + default VIDEO_DEV && VIDEO_V4L2_COMMON source "drivers/media/video/Kconfig" @@ -185,7 +185,6 @@ config VIDEO_TVEEPROM config DAB boolean "DAB adapters" - default y ---help--- Allow selecting support for for Digital Audio Broadcasting (DAB) Receiver adapters. diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig index 06ca75911b7f..769c6f8142d2 100644 --- a/drivers/media/common/Kconfig +++ b/drivers/media/common/Kconfig @@ -4,6 +4,6 @@ config VIDEO_SAA7146 config VIDEO_SAA7146_VV tristate - depends on VIDEO_DEV + depends on VIDEO_V4L2 select VIDEOBUF_DMA_SG select VIDEO_SAA7146 diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 8d5214f18cf0..1b41b3f77cf9 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -4,12 +4,12 @@ menuconfig RADIO_ADAPTERS bool "Radio Adapters" - depends on VIDEO_DEV + depends on VIDEO_V4L2 default y ---help--- Say Y here to enable selecting AM/FM radio adapters. -if RADIO_ADAPTERS && VIDEO_DEV +if RADIO_ADAPTERS && VIDEO_V4L2 config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index a2e8987a6195..37072a21d8c9 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -4,14 +4,14 @@ menuconfig VIDEO_CAPTURE_DRIVERS bool "Video capture adapters" - depends on VIDEO_DEV + depends on VIDEO_V4L2 default y ---help--- Say Y here to enable selecting the video adapters for webcams, analog TV, and hybrid analog/digital TV. Some of those devices also supports FM radio. -if VIDEO_CAPTURE_DRIVERS && VIDEO_DEV +if VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2 config VIDEO_ADV_DEBUG bool "Enable advanced debug functionality" diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 4a8fc170138b..34deb68ae568 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -56,7 +56,6 @@ #include #include #include -#include #define __OLD_VIDIOC_ /* To allow fixing old calls*/ #include #include @@ -81,107 +80,6 @@ MODULE_LICENSE("GPL"); * Video Standard Operations (contributed by Michael Schimek) */ -char *v4l2_norm_to_name(v4l2_std_id id) -{ - char *name; - u32 myid = id; - - /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle - 64 bit comparations. So, on that architecture, with some gcc variants, - compilation fails. Currently, the max value is 30bit wide. - */ - BUG_ON(myid != id); - - switch (myid) { - case V4L2_STD_PAL: - name="PAL"; break; - case V4L2_STD_PAL_BG: - name="PAL-BG"; break; - case V4L2_STD_PAL_DK: - name="PAL-DK"; break; - case V4L2_STD_PAL_B: - name="PAL-B"; break; - case V4L2_STD_PAL_B1: - name="PAL-B1"; break; - case V4L2_STD_PAL_G: - name="PAL-G"; break; - case V4L2_STD_PAL_H: - name="PAL-H"; break; - case V4L2_STD_PAL_I: - name="PAL-I"; break; - case V4L2_STD_PAL_D: - name="PAL-D"; break; - case V4L2_STD_PAL_D1: - name="PAL-D1"; break; - case V4L2_STD_PAL_K: - name="PAL-K"; break; - case V4L2_STD_PAL_M: - name="PAL-M"; break; - case V4L2_STD_PAL_N: - name="PAL-N"; break; - case V4L2_STD_PAL_Nc: - name="PAL-Nc"; break; - case V4L2_STD_PAL_60: - name="PAL-60"; break; - case V4L2_STD_NTSC: - name="NTSC"; break; - case V4L2_STD_NTSC_M: - name="NTSC-M"; break; - case V4L2_STD_NTSC_M_JP: - name="NTSC-M-JP"; break; - case V4L2_STD_NTSC_443: - name="NTSC-443"; break; - case V4L2_STD_NTSC_M_KR: - name="NTSC-M-KR"; break; - case V4L2_STD_SECAM: - name="SECAM"; break; - case V4L2_STD_SECAM_DK: - name="SECAM-DK"; break; - case V4L2_STD_SECAM_B: - name="SECAM-B"; break; - case V4L2_STD_SECAM_D: - name="SECAM-D"; break; - case V4L2_STD_SECAM_G: - name="SECAM-G"; break; - case V4L2_STD_SECAM_H: - name="SECAM-H"; break; - case V4L2_STD_SECAM_K: - name="SECAM-K"; break; - case V4L2_STD_SECAM_K1: - name="SECAM-K1"; break; - case V4L2_STD_SECAM_L: - name="SECAM-L"; break; - case V4L2_STD_SECAM_LC: - name="SECAM-LC"; break; - default: - name="Unknown"; break; - } - - return name; -} - -/* Fill in the fields of a v4l2_standard structure according to the - 'id' and 'transmission' parameters. Returns negative on error. */ -int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, char *name) -{ - u32 index = vs->index; - - memset(vs, 0, sizeof(struct v4l2_standard)); - vs->index = index; - vs->id = id; - if (id & V4L2_STD_525_60) { - vs->frameperiod.numerator = 1001; - vs->frameperiod.denominator = 30000; - vs->framelines = 525; - } else { - vs->frameperiod.numerator = 1; - vs->frameperiod.denominator = 25; - vs->framelines = 625; - } - strlcpy(vs->name,name,sizeof(vs->name)); - return 0; -} /* ----------------------------------------------------------------- */ /* priority handling */ @@ -195,6 +93,7 @@ int v4l2_prio_init(struct v4l2_prio_state *global) memset(global,0,sizeof(*global)); return 0; } +EXPORT_SYMBOL(v4l2_prio_init); int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, enum v4l2_priority new) @@ -210,11 +109,13 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, *local = new; return 0; } +EXPORT_SYMBOL(v4l2_prio_change); int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local) { return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT); } +EXPORT_SYMBOL(v4l2_prio_open); int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local) { @@ -222,6 +123,7 @@ int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local) atomic_dec(&global->prios[*local]); return 0; } +EXPORT_SYMBOL(v4l2_prio_close); enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global) { @@ -233,6 +135,7 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global) return V4L2_PRIORITY_BACKGROUND; return V4L2_PRIORITY_UNSET; } +EXPORT_SYMBOL(v4l2_prio_max); int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) { @@ -240,220 +143,7 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) return -EBUSY; return 0; } - - -/* ----------------------------------------------------------------- */ -/* some arrays for pretty-printing debug messages of enum types */ - -char *v4l2_field_names[] = { - [V4L2_FIELD_ANY] = "any", - [V4L2_FIELD_NONE] = "none", - [V4L2_FIELD_TOP] = "top", - [V4L2_FIELD_BOTTOM] = "bottom", - [V4L2_FIELD_INTERLACED] = "interlaced", - [V4L2_FIELD_SEQ_TB] = "seq-tb", - [V4L2_FIELD_SEQ_BT] = "seq-bt", - [V4L2_FIELD_ALTERNATE] = "alternate", - [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", - [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", -}; - -char *v4l2_type_names[] = { - [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", - [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", - [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", - [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", - [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", - [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", - [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", -}; - -/* ------------------------------------------------------------------ */ -/* debug help functions */ - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -static const char *v4l1_ioctls[] = { - [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", - [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", - [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", - [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", - [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", - [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", - [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", - [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", - [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", - [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", - [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", - [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", - [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", - [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", - [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", - [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", - [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", - [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", - [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", - [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", - [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", - [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", - [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", - [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", - [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", - [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", - [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", - [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", - [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" -}; -#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) -#endif - -static const char *v4l2_ioctls[] = { - [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", - [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", - [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", - [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", - [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", - [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", - [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", - [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", - [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", - [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", - [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", - [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", - [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", - [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", - [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", - [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", - [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", - [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", - [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", - [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", - [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", - [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", - [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", - [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", - [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", - [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", - [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", - [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", - [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", - [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", - [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", - [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", - [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", - [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", - [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", - [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", - [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", - [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", - [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", - [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", - [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", - [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", - [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", - [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", - [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", - [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", - [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", - [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", - [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", - [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", - [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", - [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", - [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", - [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", - [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", -#if 1 - [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", - [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", - [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", - [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", - [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", - - [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", - [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", - - [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", -#endif -}; -#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) - -static const char *v4l2_int_ioctls[] = { -#ifdef CONFIG_VIDEO_V4L1_COMPAT - [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", - [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", - [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", - [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", - [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", - [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", - [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", - [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", - [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", - [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", - [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", -#endif - [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", - - [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", - [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", - [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG", - - [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", - [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", - [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", - [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", - [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", - [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", - [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", - [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", - [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", - [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ", - [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT", - [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT", - [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT", -}; -#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) - -/* Common ioctl debug function. This function can be used by - external ioctl messages as well as internal V4L ioctl */ -void v4l_printk_ioctl(unsigned int cmd) -{ - char *dir; - - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "*ERR*"; break; - } - switch (_IOC_TYPE(cmd)) { - case 'd': - printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? - v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case 'v': - printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L1_IOCTLS) ? - v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; -#endif - case 'V': - printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_IOCTLS) ? - v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; - - default: - printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", - _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); - } -} +EXPORT_SYMBOL(v4l2_prio_check); /* ----------------------------------------------------------------- */ @@ -482,6 +172,7 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, } return 0; } +EXPORT_SYMBOL(v4l2_ctrl_check); /* Returns NULL or a character pointer array containing the menu for the given control ID. The pointer array ends with a NULL pointer. @@ -642,6 +333,7 @@ const char **v4l2_ctrl_get_menu(u32 id) return NULL; } } +EXPORT_SYMBOL(v4l2_ctrl_get_menu); /* Fill in a struct v4l2_queryctrl */ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def) @@ -764,6 +456,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste snprintf(qctrl->name, sizeof(qctrl->name), name); return 0; } +EXPORT_SYMBOL(v4l2_ctrl_query_fill); /* Fill in a struct v4l2_queryctrl with standard values based on the control ID. */ @@ -898,6 +591,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) return -EINVAL; } } +EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); /* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and the menu. The qctrl pointer may be NULL, in which case it is ignored. */ @@ -916,6 +610,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc qmenu->reserved = 0; return 0; } +EXPORT_SYMBOL(v4l2_ctrl_query_menu); /* ctrl_classes points to an array of u32 pointers, the last element is a NULL pointer. Each u32 array is a 0-terminated array of control IDs. @@ -966,6 +661,7 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) return 0; return **ctrl_classes; } +EXPORT_SYMBOL(v4l2_ctrl_next); int v4l2_chip_match_host(u32 match_type, u32 match_chip) { @@ -1038,26 +734,3 @@ int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver } EXPORT_SYMBOL(v4l2_i2c_attach); #endif - -/* ----------------------------------------------------------------- */ - -EXPORT_SYMBOL(v4l2_norm_to_name); -EXPORT_SYMBOL(v4l2_video_std_construct); - -EXPORT_SYMBOL(v4l2_prio_init); -EXPORT_SYMBOL(v4l2_prio_change); -EXPORT_SYMBOL(v4l2_prio_open); -EXPORT_SYMBOL(v4l2_prio_close); -EXPORT_SYMBOL(v4l2_prio_max); -EXPORT_SYMBOL(v4l2_prio_check); - -EXPORT_SYMBOL(v4l2_field_names); -EXPORT_SYMBOL(v4l2_type_names); -EXPORT_SYMBOL(v4l_printk_ioctl); - -EXPORT_SYMBOL(v4l2_ctrl_next); -EXPORT_SYMBOL(v4l2_ctrl_check); -EXPORT_SYMBOL(v4l2_ctrl_get_menu); -EXPORT_SYMBOL(v4l2_ctrl_query_menu); -EXPORT_SYMBOL(v4l2_ctrl_query_fill); -EXPORT_SYMBOL(v4l2_ctrl_query_fill_std); diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 28655f8983c6..0d9b63762a48 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -46,10 +46,373 @@ #include #endif #include +#include #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" +/* video4linux standard ID conversion to standard name + */ +char *v4l2_norm_to_name(v4l2_std_id id) +{ + char *name; + u32 myid = id; + + /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle + 64 bit comparations. So, on that architecture, with some gcc + variants, compilation fails. Currently, the max value is 30bit wide. + */ + BUG_ON(myid != id); + + switch (myid) { + case V4L2_STD_PAL: + name = "PAL"; + break; + case V4L2_STD_PAL_BG: + name = "PAL-BG"; + break; + case V4L2_STD_PAL_DK: + name = "PAL-DK"; + break; + case V4L2_STD_PAL_B: + name = "PAL-B"; + break; + case V4L2_STD_PAL_B1: + name = "PAL-B1"; + break; + case V4L2_STD_PAL_G: + name = "PAL-G"; + break; + case V4L2_STD_PAL_H: + name = "PAL-H"; + break; + case V4L2_STD_PAL_I: + name = "PAL-I"; + break; + case V4L2_STD_PAL_D: + name = "PAL-D"; + break; + case V4L2_STD_PAL_D1: + name = "PAL-D1"; + break; + case V4L2_STD_PAL_K: + name = "PAL-K"; + break; + case V4L2_STD_PAL_M: + name = "PAL-M"; + break; + case V4L2_STD_PAL_N: + name = "PAL-N"; + break; + case V4L2_STD_PAL_Nc: + name = "PAL-Nc"; + break; + case V4L2_STD_PAL_60: + name = "PAL-60"; + break; + case V4L2_STD_NTSC: + name = "NTSC"; + break; + case V4L2_STD_NTSC_M: + name = "NTSC-M"; + break; + case V4L2_STD_NTSC_M_JP: + name = "NTSC-M-JP"; + break; + case V4L2_STD_NTSC_443: + name = "NTSC-443"; + break; + case V4L2_STD_NTSC_M_KR: + name = "NTSC-M-KR"; + break; + case V4L2_STD_SECAM: + name = "SECAM"; + break; + case V4L2_STD_SECAM_DK: + name = "SECAM-DK"; + break; + case V4L2_STD_SECAM_B: + name = "SECAM-B"; + break; + case V4L2_STD_SECAM_D: + name = "SECAM-D"; + break; + case V4L2_STD_SECAM_G: + name = "SECAM-G"; + break; + case V4L2_STD_SECAM_H: + name = "SECAM-H"; + break; + case V4L2_STD_SECAM_K: + name = "SECAM-K"; + break; + case V4L2_STD_SECAM_K1: + name = "SECAM-K1"; + break; + case V4L2_STD_SECAM_L: + name = "SECAM-L"; + break; + case V4L2_STD_SECAM_LC: + name = "SECAM-LC"; + break; + default: + name = "Unknown"; + break; + } + + return name; +} +EXPORT_SYMBOL(v4l2_norm_to_name); + +/* Fill in the fields of a v4l2_standard structure according to the + 'id' and 'transmission' parameters. Returns negative on error. */ +int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, char *name) +{ + u32 index = vs->index; + + memset(vs, 0, sizeof(struct v4l2_standard)); + vs->index = index; + vs->id = id; + if (id & V4L2_STD_525_60) { + vs->frameperiod.numerator = 1001; + vs->frameperiod.denominator = 30000; + vs->framelines = 525; + } else { + vs->frameperiod.numerator = 1; + vs->frameperiod.denominator = 25; + vs->framelines = 625; + } + strlcpy(vs->name, name, sizeof(vs->name)); + return 0; +} +EXPORT_SYMBOL(v4l2_video_std_construct); + +/* ----------------------------------------------------------------- */ +/* some arrays for pretty-printing debug messages of enum types */ + +char *v4l2_field_names[] = { + [V4L2_FIELD_ANY] = "any", + [V4L2_FIELD_NONE] = "none", + [V4L2_FIELD_TOP] = "top", + [V4L2_FIELD_BOTTOM] = "bottom", + [V4L2_FIELD_INTERLACED] = "interlaced", + [V4L2_FIELD_SEQ_TB] = "seq-tb", + [V4L2_FIELD_SEQ_BT] = "seq-bt", + [V4L2_FIELD_ALTERNATE] = "alternate", + [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", + [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", +}; +EXPORT_SYMBOL(v4l2_field_names); + +char *v4l2_type_names[] = { + [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", + [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", + [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", + [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", + [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", + [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", + [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", + [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", +}; +EXPORT_SYMBOL(v4l2_type_names); + +static char *v4l2_memory_names[] = { + [V4L2_MEMORY_MMAP] = "mmap", + [V4L2_MEMORY_USERPTR] = "userptr", + [V4L2_MEMORY_OVERLAY] = "overlay", +}; + +#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \ + arr[a] : "unknown") + +/* ------------------------------------------------------------------ */ +/* debug help functions */ + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static const char *v4l1_ioctls[] = { + [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", + [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", + [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", + [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", + [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", + [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", + [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", + [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", + [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", + [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", + [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", + [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", + [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", + [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", + [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", + [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", + [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", + [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", + [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", + [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", + [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", + [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", + [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", + [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", + [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", + [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", + [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", + [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", + [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" +}; +#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) +#endif + +static const char *v4l2_ioctls[] = { + [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", + [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", + [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", + [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", + [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", + [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", + [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", + [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", + [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", + [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", + [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", + [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", + [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", + [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", + [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", + [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", + [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", + [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", + [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", + [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", + [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", + [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", + [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", + [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", + [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", + [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", + [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", + [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", + [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", + [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", + [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", + [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", + [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", + [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", + [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", + [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", + [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", + [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", + [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", + [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", + [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", + [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", + [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", + [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", + [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", + [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", + [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", + [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", + [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", + [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", + [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", + [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", + [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", + [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", + [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", +#if 1 + [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", + [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", + [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", + [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", + [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", + + [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", + [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", + + [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", +#endif +}; +#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) + +static const char *v4l2_int_ioctls[] = { +#ifdef CONFIG_VIDEO_V4L1_COMPAT + [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", + [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", + [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", + [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", + [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", + [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", + [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", + [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", + [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", + [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", + [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", +#endif + [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", + + [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", + [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", + [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG", + + [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", + [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", + [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", + [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", + [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", + [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", + [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", + [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", + [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ", + [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT", + [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT", + [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT", +}; +#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) + +/* Common ioctl debug function. This function can be used by + external ioctl messages as well as internal V4L ioctl */ +void v4l_printk_ioctl(unsigned int cmd) +{ + char *dir; + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "*ERR*"; break; + } + switch (_IOC_TYPE(cmd)) { + case 'd': + printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", + (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? + v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); + break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT + case 'v': + printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", + (_IOC_NR(cmd) < V4L1_IOCTLS) ? + v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); + break; +#endif + case 'V': + printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", + (_IOC_NR(cmd) < V4L2_IOCTLS) ? + v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); + break; + + default: + printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", + _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); + } +} +EXPORT_SYMBOL(v4l_printk_ioctl); + /* * sysfs stuff */ @@ -69,11 +432,13 @@ struct video_device *video_device_alloc(void) vfd = kzalloc(sizeof(*vfd),GFP_KERNEL); return vfd; } +EXPORT_SYMBOL(video_device_alloc); void video_device_release(struct video_device *vfd) { kfree(vfd); } +EXPORT_SYMBOL(video_device_release); static void video_release(struct device *cd) { @@ -110,6 +475,7 @@ struct video_device* video_devdata(struct file *file) { return video_device[iminor(file->f_path.dentry->d_inode)]; } +EXPORT_SYMBOL(video_devdata); /* * Open a video device - FIXME: Obsoleted @@ -278,6 +644,7 @@ video_usercopy(struct inode *inode, struct file *file, kfree(mbuf); return err; } +EXPORT_SYMBOL(video_usercopy); /* * open/release helper functions -- handle exclusive opens @@ -297,6 +664,7 @@ int video_exclusive_open(struct inode *inode, struct file *file) mutex_unlock(&vfl->lock); return retval; } +EXPORT_SYMBOL(video_exclusive_open); int video_exclusive_release(struct inode *inode, struct file *file) { @@ -305,41 +673,7 @@ int video_exclusive_release(struct inode *inode, struct file *file) vfl->users--; return 0; } - -static char *v4l2_memory_names[] = { - [V4L2_MEMORY_MMAP] = "mmap", - [V4L2_MEMORY_USERPTR] = "userptr", - [V4L2_MEMORY_OVERLAY] = "overlay", -}; - - -/* FIXME: Those stuff are replicated also on v4l2-common.c */ -static char *v4l2_type_names_FIXME[] = { - [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", - [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", - [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", - [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", - [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture", - [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", - [V4L2_BUF_TYPE_PRIVATE] = "private", -}; - -static char *v4l2_field_names_FIXME[] = { - [V4L2_FIELD_ANY] = "any", - [V4L2_FIELD_NONE] = "none", - [V4L2_FIELD_TOP] = "top", - [V4L2_FIELD_BOTTOM] = "bottom", - [V4L2_FIELD_INTERLACED] = "interlaced", - [V4L2_FIELD_SEQ_TB] = "seq-tb", - [V4L2_FIELD_SEQ_BT] = "seq-bt", - [V4L2_FIELD_ALTERNATE] = "alternate", - [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", - [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", -}; - -#define prt_names(a,arr) (((a)>=0)&&((a)timestamp.tv_sec%60), p->timestamp.tv_usec, p->index, - prt_names(p->type,v4l2_type_names_FIXME), - p->bytesused,p->flags, - p->field,p->sequence, - prt_names(p->memory,v4l2_memory_names), + prt_names(p->type, v4l2_type_names), + p->bytesused, p->flags, + p->field, p->sequence, + prt_names(p->memory, v4l2_memory_names), p->m.userptr, p->length); dbgarg2 ("timecode= %02d:%02d:%02d type=%d, " "flags=0x%08d, frames=%d, userbits=0x%08x\n", @@ -382,8 +716,8 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd, (fmt->pixelformat >> 8) & 0xff, (fmt->pixelformat >> 16) & 0xff, (fmt->pixelformat >> 24) & 0xff, - prt_names(fmt->field,v4l2_field_names_FIXME), - fmt->bytesperline,fmt->sizeimage,fmt->colorspace); + prt_names(fmt->field, v4l2_field_names), + fmt->bytesperline, fmt->sizeimage, fmt->colorspace); }; @@ -597,7 +931,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(type, - v4l2_type_names_FIXME)); + v4l2_type_names)); switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -650,7 +984,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names_FIXME)); + v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -702,7 +1036,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names_FIXME)); + v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (vfd->vidioc_try_fmt_cap) @@ -768,8 +1102,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_reqbufs(file, fh, p); dbgarg (cmd, "count=%d, type=%s, memory=%s\n", p->count, - prt_names(p->type,v4l2_type_names_FIXME), - prt_names(p->memory,v4l2_memory_names)); + prt_names(p->type, v4l2_type_names), + prt_names(p->memory, v4l2_memory_names)); break; } case VIDIOC_QUERYBUF: @@ -858,7 +1192,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, enum v4l2_buf_type i = *(int *)arg; if (!vfd->vidioc_streamon) break; - dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); ret=vfd->vidioc_streamon(file, fh,i); break; } @@ -868,7 +1202,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!vfd->vidioc_streamoff) break; - dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME)); + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); ret=vfd->vidioc_streamoff(file, fh, i); break; } @@ -1624,7 +1958,7 @@ int video_ioctl2 (struct inode *inode, struct file *file, kfree(mbuf); return err; } - +EXPORT_SYMBOL(video_ioctl2); static const struct file_operations video_fops; @@ -1743,6 +2077,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) mutex_unlock(&videodev_lock); return ret; } +EXPORT_SYMBOL(video_register_device); /** * video_unregister_device - unregister a video4linux device @@ -1762,6 +2097,7 @@ void video_unregister_device(struct video_device *vfd) device_unregister(&vfd->class_dev); mutex_unlock(&videodev_lock); } +EXPORT_SYMBOL(video_unregister_device); /* * Video fs operations @@ -1806,16 +2142,6 @@ static void __exit videodev_exit(void) module_init(videodev_init) module_exit(videodev_exit) -EXPORT_SYMBOL(video_register_device); -EXPORT_SYMBOL(video_unregister_device); -EXPORT_SYMBOL(video_devdata); -EXPORT_SYMBOL(video_usercopy); -EXPORT_SYMBOL(video_exclusive_open); -EXPORT_SYMBOL(video_exclusive_release); -EXPORT_SYMBOL(video_ioctl2); -EXPORT_SYMBOL(video_device_alloc); -EXPORT_SYMBOL(video_device_release); - MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab "); MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); MODULE_LICENSE("GPL"); diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 475d0d8275e0..316a58453134 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -61,8 +61,6 @@ v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \ } while (0) -/* Prints the ioctl in a human-readable format */ -extern void v4l_printk_ioctl(unsigned int cmd); /* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ #define v4l_print_ioctl(name, cmd) \ diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index c544c6f90893..f2114459995d 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -44,6 +44,8 @@ extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs); extern char *v4l2_norm_to_name(v4l2_std_id id); extern int v4l2_video_std_construct(struct v4l2_standard *vs, int id, char *name); +/* Prints the ioctl in a human-readable format */ +extern void v4l_printk_ioctl(unsigned int cmd); /* prority handling */ struct v4l2_prio_state { From a348d2005d4a76c8c84150329f926c255c994ead Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 18 Jan 2008 08:53:26 -0300 Subject: [PATCH 225/880] V4L/DVB (7049): Remove sound/driver.h sound/driver.h is already included by sound/core. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 941357c4f3f5..2c7343d3139d 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include From 46c9fc861f2a47ce806671933f96f03ab3bdda7a Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 19 Jan 2008 05:38:59 -0300 Subject: [PATCH 226/880] V4L/DVB (7076): bt878: include KERN_ facility level printk should use KERN_* levels. CC: Manu Abraham Signed-off-by: Akinobu Mita Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/bt8xx/bt878.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index c7bbb40223f5..56d8fab688bb 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c @@ -75,7 +75,11 @@ EXPORT_SYMBOL(bt878); #if defined(dprintk) #undef dprintk #endif -#define dprintk if(bt878_debug) printk +#define dprintk(fmt, arg...) \ + do { \ + if (bt878_debug) \ + printk(KERN_DEBUG fmt, ##arg); \ + } while (0) static void bt878_mem_free(struct bt878 *bt) { @@ -154,7 +158,7 @@ static int bt878_make_risc(struct bt878 *bt) } if (bt->line_count > 255) { - printk("bt878: buffer size error!\n"); + printk(KERN_ERR "bt878: buffer size error!\n"); return -EINVAL; } return 0; @@ -285,7 +289,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) if (astat & (BT878_ASCERR | BT878_AOCERR)) { if (bt878_verbose) { - printk("bt878(%d): irq%s%s risc_pc=%08x\n", + printk(KERN_INFO + "bt878(%d): irq%s%s risc_pc=%08x\n", bt->nr, (astat & BT878_ASCERR) ? " SCERR" : "", @@ -295,8 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) } if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) { if (bt878_verbose) { - printk - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", + printk(KERN_INFO + "bt878(%d): irq%s%s%s risc_pc=%08x\n", bt->nr, (astat & BT878_APABORT) ? " PABORT" : "", @@ -308,8 +313,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) } if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) { if (bt878_verbose) { - printk - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", + printk(KERN_INFO + "bt878(%d): irq%s%s%s risc_pc=%08x\n", bt->nr, (astat & BT878_AFDSR) ? " FDSR" : "", (astat & BT878_AFTRGT) ? " FTRGT" : @@ -510,7 +515,7 @@ static int __devinit bt878_probe(struct pci_dev *dev, */ if ((result = bt878_mem_alloc(bt))) { - printk("bt878: failed to allocate memory!\n"); + printk(KERN_ERR "bt878: failed to allocate memory!\n"); goto fail2; } @@ -536,7 +541,7 @@ static void __devexit bt878_remove(struct pci_dev *pci_dev) struct bt878 *bt = pci_get_drvdata(pci_dev); if (bt878_verbose) - printk("bt878(%d): unloading\n", bt->nr); + printk(KERN_INFO "bt878(%d): unloading\n", bt->nr); /* turn off all capturing, DMA and IRQs */ btand(~0x13, BT878_AGPIO_DMA_CTL); From e8e672c57736872ef0bd05640503ee04ff443890 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Fri, 25 Jan 2008 22:00:19 -0300 Subject: [PATCH 227/880] V4L/DVB (7079): zr364xx: fix typo in documentation Signed-off-by: Antoine Jacquet Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/zr364xx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt index 4d9a0c33f2fd..754099ce71b6 100644 --- a/Documentation/video4linux/zr364xx.txt +++ b/Documentation/video4linux/zr364xx.txt @@ -25,7 +25,7 @@ modprobe zr364xx debug=X mode=Y - debug : set to 1 to enable verbose debug messages - mode : 0 = 320x240, 1 = 160x120, 2 = 640x480 You can then use the camera with V4L2 compatible applications, for example Ekiga. -To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1 count=1 +To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M count=1 links : http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV) From 71c044752cdae89136862495f244d37073e2cf66 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Fri, 25 Jan 2008 22:01:53 -0300 Subject: [PATCH 228/880] V4L/DVB (7080): zr364xx: add support for Pentax Optio 50 Signed-off-by: Antoine Jacquet Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/zr364xx.txt | 1 + drivers/media/video/zr364xx.c | 1 + 2 files changed, 2 insertions(+) diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt index 754099ce71b6..9a1a8c559490 100644 --- a/Documentation/video4linux/zr364xx.txt +++ b/Documentation/video4linux/zr364xx.txt @@ -63,3 +63,4 @@ Vendor Product Distributor Model 0x06d6 0x0034 Trust Powerc@m 750 0x0a17 0x0062 Pentax Optio 50L 0x06d6 0x003b Trust Powerc@m 970Z +0x0a17 0x004e Pentax Optio 50 diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 1fdbb46de7f3..d8f847edf017 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -93,6 +93,7 @@ static struct usb_device_id device_table[] = { {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 }, {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 }, {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, + {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, {} /* Terminating entry */ }; From c0e0aff9779303c7e3ef7e6db4001dbc2bfdcbdd Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Fri, 25 Jan 2008 22:03:10 -0300 Subject: [PATCH 229/880] V4L/DVB (7081): zr364xx: add support for Creative DiVi CAM 516 Signed-off-by: Antoine Jacquet Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/zr364xx.txt | 1 + drivers/media/video/zr364xx.c | 1 + 2 files changed, 2 insertions(+) diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt index 9a1a8c559490..5c81e3ae6458 100644 --- a/Documentation/video4linux/zr364xx.txt +++ b/Documentation/video4linux/zr364xx.txt @@ -64,3 +64,4 @@ Vendor Product Distributor Model 0x0a17 0x0062 Pentax Optio 50L 0x06d6 0x003b Trust Powerc@m 970Z 0x0a17 0x004e Pentax Optio 50 +0x041e 0x405d Creative DiVi CAM 516 diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index d8f847edf017..1b44784d0efb 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -94,6 +94,7 @@ static struct usb_device_id device_table[] = { {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 }, {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 }, + {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 }, {} /* Terminating entry */ }; From 4ba243734a0363649c514353334ed3d6ca39a5fb Mon Sep 17 00:00:00 2001 From: Hermann Pitton Date: Sun, 20 Jan 2008 19:27:51 -0300 Subject: [PATCH 230/880] V4L/DVB (7082): support for Twinhan Hybrid DTV-DVB 3056 PCI S-Video is unconfirmed, but likely correct. The remote is not yet investigated. Thanks go to Sioux for providing code and asking to fix the auto detection. Signed-off-by: sioux Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 1 + drivers/media/video/saa7134/saa7134-cards.c | 41 ++++++++++++++++++++- drivers/media/video/saa7134/saa7134-dvb.c | 18 +++++++++ drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 5d3b6b4d2515..7a37594b7aa3 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -129,3 +129,4 @@ 128 -> Beholder BeholdTV Columbus TVFM [0000:5201] 129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093] 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193] +131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 7d7f383b404f..176543f723ca 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3912,6 +3912,36 @@ struct saa7134_board saa7134_boards[] = { }, .mpeg = SAA7134_MPEG_EMPRESS, }, + [SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = { + .name = "Twinhan Hybrid DTV-DVB 3056 PCI", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tuner_config = 2, + .mpeg = SAA7134_MPEG_DVB, + .gpiomask = 0x0200000, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, /* untested */ + .amux = LINE1, + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x0200000, + }, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -4843,7 +4873,13 @@ struct pci_device_id saa7134_pci_tbl[] = { .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x4e42, .subdevice = 0x3502, - .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS + .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/ + .subdevice = 0x0022, + .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056, },{ /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -5232,7 +5268,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: case SAA7134_BOARD_MEDION_MD8800_QUADRO: - case SAA7134_BOARD_AVERMEDIA_SUPER_007: + case SAA7134_BOARD_AVERMEDIA_SUPER_007: + case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: /* this is a hybrid board, initialize to analog mode * and configure firmware eeprom address */ diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index a9ca5730826f..90f495a67804 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -779,6 +779,21 @@ static struct tda1004x_config avermedia_super_007_config = { .request_firmware = philips_tda1004x_request_firmware }; +static struct tda1004x_config twinhan_dtv_dvb_3056_config = { + .demod_address = 0x08, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_16M, + .agc_config = TDA10046_AGC_TDA827X, + .gpio_config = TDA10046_GP01_I, + .if_freq = TDA10046_FREQ_045, + .i2c_gate = 0x42, + .tuner_address = 0x61, + .tuner_config = 2, + .antenna_switch = 1, + .request_firmware = philips_tda1004x_request_firmware +}; + /* ------------------------------------------------------------------ * special case: this card uses saa713x GPIO22 for the mode switch */ @@ -1044,6 +1059,9 @@ static int dvb_init(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_SUPER_007: configure_tda827x_fe(dev, &avermedia_super_007_config); break; + case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: + configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config); + break; default: wprintk("Huh? unknown DVB card?\n"); break; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index b88ca995fafb..27fb44332215 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -252,6 +252,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 #define SAA7134_BOARD_BEHOLD_607_9FM 129 #define SAA7134_BOARD_BEHOLD_M6 130 +#define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 From ad1ef131c35bb6967acd5ce3072a32ec1d27b482 Mon Sep 17 00:00:00 2001 From: Hermann Pitton Date: Sun, 20 Jan 2008 19:32:39 -0300 Subject: [PATCH 231/880] V4L/DVB (7083): saa7134: enable radio and external analog audio-in on the md2819 It also enumerates now the separate composite input at first and adds mute ability to radio and external audio-in. Many thanks to Daftcho Tabakov for reporting the flaws and testing. Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 31 ++++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 176543f723ca..0e8e8081f51c 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -928,27 +928,38 @@ struct saa7134_board saa7134_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0x03, .inputs = {{ .name = name_tv, .vmux = 1, .amux = TV, .tv = 1, - },{ + .gpio = 0x00, + }, { .name = name_comp1, - .vmux = 0, - .amux = LINE2, - },{ - .name = name_comp2, .vmux = 3, - .amux = LINE2, - },{ + .amux = LINE1, + .gpio = 0x02, + }, { + .name = name_comp2, + .vmux = 0, + .amux = LINE1, + .gpio = 0x02, + }, { .name = name_svideo, .vmux = 8, - .amux = LINE2, - }}, + .amux = LINE1, + .gpio = 0x02, + } }, .radio = { .name = name_radio, - .amux = LINE2, + .amux = LINE1, + .gpio = 0x01, + }, + .mute = { + .name = name_mute, + .amux = TV, + .gpio = 0x00, }, }, [SAA7134_BOARD_BMK_MPEX_TUNER] = { From 728b92a2301c705dc36419ab0e7163b129462696 Mon Sep 17 00:00:00 2001 From: Hermann Pitton Date: Sun, 20 Jan 2008 19:42:01 -0300 Subject: [PATCH 232/880] V4L/DVB (7084): saa7134: add support for the Medion / Creatix CTX948 card This adds support for analog inputs and DVB-T. Good sensitivity for DVB-T currently needs to use analog TV first. DVB-S support is not yet completed, but is on the way. Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 7a37594b7aa3..81566df13ae2 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -94,7 +94,7 @@ 93 -> Medion 7134 Bridge #2 [16be:0005] 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] - 96 -> Medion Md8800 Quadro [16be:0007,16be:0008] + 96 -> Medion Md8800 Quadro [16be:0007,16be:0008,16be:000d] 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] 98 -> Proteus Pro 2309 [0919:2003] 99 -> AVerMedia TV Hybrid A16AR [1461:2c00] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 0e8e8081f51c..c03784ee7f11 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4562,6 +4562,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x0008, .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x16be, + .subdevice = 0x000d, /* triple CTX948_V1.1.1 */ + .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO, + }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x1461, From 29e4e05041842bca57ec539e51cfeae8948e7320 Mon Sep 17 00:00:00 2001 From: Hermann Pitton Date: Sun, 20 Jan 2008 19:49:51 -0300 Subject: [PATCH 233/880] V4L/DVB (7085): saa7134: detect the LifeView FlyDVB-T Hybrid Mini PCI Thanks to Angelo Lisco for his initial patch we missed and to Ahmet Dogan Ugurel confirming such a device functional. Signed-off-by: Hermann Pitton Signed-off-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 81566df13ae2..1074925fb201 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -92,7 +92,7 @@ 91 -> AVerMedia A169 B [1461:7360] 92 -> AVerMedia A169 B1 [1461:6360] 93 -> Medion 7134 Bridge #2 [16be:0005] - 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502] + 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,5168:3307,4e42:3502] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] 96 -> Medion Md8800 Quadro [16be:0007,16be:0008,16be:000d] 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index c03784ee7f11..dcb601b803f9 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4550,6 +4550,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x3502, /* whats the difference to 0x3306 ?*/ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5168, + .subdevice = 0x3307, /* FlyDVB-T Hybrid Mini PCI */ + .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS, + }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x16be, From 0ed464e13e9321de9d1fff356eda58498574272e Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 26 Jan 2008 07:38:01 -0300 Subject: [PATCH 234/880] V4L/DVB (7086): driver: tcm825x - fix logical typo error This patch does fix potential NULL pointer dereference due to logical typo error. The issue is pointed out by Guennadi Liakhovetski Signed-off-by: Cyrill Gorcunov CC: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tcm825x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c index 41cd6a0b0485..fb895f6684a3 100644 --- a/drivers/media/video/tcm825x.c +++ b/drivers/media/video/tcm825x.c @@ -851,7 +851,7 @@ static int tcm825x_probe(struct i2c_client *client) sensor->platform_data = client->dev.platform_data; if (sensor->platform_data == NULL - && !sensor->platform_data->is_okay()) + || !sensor->platform_data->is_okay()) return -ENODEV; sensor->v4l2_int_device = &tcm825x_int_device; From 1112fb68ae9c838294d38e1f209fedbc0dbf11d5 Mon Sep 17 00:00:00 2001 From: Jaime Velasco Juan Date: Sun, 27 Jan 2008 12:24:58 -0300 Subject: [PATCH 235/880] V4L/DVB (7088): V4L: stkwebcam: Add support for YUYV format Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/stk-sensor.c | 19 ++++++++++++++++++- drivers/media/video/stk-webcam.c | 7 ++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/stk-sensor.c b/drivers/media/video/stk-sensor.c index 4a9a0b62efa3..1a8692d9ee5a 100644 --- a/drivers/media/video/stk-sensor.c +++ b/drivers/media/video/stk-sensor.c @@ -380,7 +380,7 @@ int stk_sensor_init(struct stk_camera *dev) STK_ERROR("Strange error reading sensor ID\n"); return -ENODEV; } - if (idh != 0x7F || idl != 0xA2) { + if (idh != 0x7f || idl != 0xa2) { STK_ERROR("Huh? you don't have a sensor from ovt\n"); return -ENODEV; } @@ -409,6 +409,19 @@ static struct regval ov_fmt_uyvy[] = { {REG_COM15, COM15_R00FF }, {0xff, 0xff}, /* END MARKER */ }; +/* V4L2_PIX_FMT_YUYV */ +static struct regval ov_fmt_yuyv[] = { + {REG_TSLB, 0 }, + { 0x4f, 0x80 }, /* "matrix coefficient 1" */ + { 0x50, 0x80 }, /* "matrix coefficient 2" */ + { 0x51, 0 }, /* vb */ + { 0x52, 0x22 }, /* "matrix coefficient 4" */ + { 0x53, 0x5e }, /* "matrix coefficient 5" */ + { 0x54, 0x80 }, /* "matrix coefficient 6" */ + {REG_COM13, COM13_UVSAT|COM13_CMATRIX}, + {REG_COM15, COM15_R00FF }, + {0xff, 0xff}, /* END MARKER */ +}; /* V4L2_PIX_FMT_RGB565X rrrrrggg gggbbbbb */ static struct regval ov_fmt_rgbr[] = { @@ -519,6 +532,10 @@ int stk_sensor_configure(struct stk_camera *dev) com7 |= COM7_YUV; rv = ov_fmt_uyvy; break; + case V4L2_PIX_FMT_YUYV: + com7 |= COM7_YUV; + rv = ov_fmt_yuyv; + break; case V4L2_PIX_FMT_RGB565: com7 |= COM7_RGB; rv = ov_fmt_rgbp; diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index d37e5e2594b4..ba4fe934ee9e 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -993,6 +993,10 @@ static int stk_vidioc_enum_fmt_cap(struct file *filp, fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8; strcpy(fmtd->description, "Raw bayer"); break; + case 4: + fmtd->pixelformat = V4L2_PIX_FMT_YUYV; + strcpy(fmtd->description, "yuv4:2:2"); + break; default: return -EINVAL; } @@ -1048,6 +1052,7 @@ static int stk_vidioc_try_fmt_cap(struct file *filp, case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_SBGGR8: break; default: @@ -1403,7 +1408,7 @@ static int stk_camera_probe(struct usb_interface *interface, dev->vsettings.brightness = 0x7fff; dev->vsettings.palette = V4L2_PIX_FMT_RGB565; dev->vsettings.mode = MODE_VGA; - dev->frame_size = 640*480*2; + dev->frame_size = 640 * 480 * 2; INIT_LIST_HEAD(&dev->sio_avail); INIT_LIST_HEAD(&dev->sio_full); From 1fdd61c0228a32b9a5e10593b225851d8920595b Mon Sep 17 00:00:00 2001 From: Jaime Velasco Juan Date: Sun, 27 Jan 2008 12:24:59 -0300 Subject: [PATCH 236/880] V4L/DVB (7089): V4L: stkwebcam: Power management support Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/stk-webcam.c | 92 +++++++++++++++++++++++++------- drivers/media/video/stk-webcam.h | 1 + 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index ba4fe934ee9e..f84e8d511763 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -682,6 +682,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp) return -ENXIO; fp->private_data = vdev; kref_get(&dev->kref); + usb_autopm_get_interface(dev->interface); return 0; } @@ -703,6 +704,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp) } if (dev->owner != fp) { + usb_autopm_put_interface(dev->interface); kref_put(&dev->kref, stk_camera_cleanup); return 0; } @@ -713,6 +715,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp) dev->owner = NULL; + usb_autopm_put_interface(dev->interface); kref_put(&dev->kref, stk_camera_cleanup); return 0; @@ -1085,6 +1088,42 @@ static int stk_vidioc_try_fmt_cap(struct file *filp, return 0; } +static int stk_setup_format(struct stk_camera *dev) +{ + int i = 0; + int depth; + if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8) + depth = 1; + else + depth = 2; + while (stk_sizes[i].m != dev->vsettings.mode + && i < ARRAY_SIZE(stk_sizes)) + i++; + if (i == ARRAY_SIZE(stk_sizes)) { + STK_ERROR("Something is broken in %s\n", __FUNCTION__); + return -EFAULT; + } + /* This registers controls some timings, not sure of what. */ + stk_camera_write_reg(dev, 0x001b, 0x0e); + if (dev->vsettings.mode == MODE_SXGA) + stk_camera_write_reg(dev, 0x001c, 0x0e); + else + stk_camera_write_reg(dev, 0x001c, 0x46); + /* + * Registers 0x0115 0x0114 are the size of each line (bytes), + * regs 0x0117 0x0116 are the heigth of the image. + */ + stk_camera_write_reg(dev, 0x0115, + ((stk_sizes[i].w * depth) >> 8) & 0xff); + stk_camera_write_reg(dev, 0x0114, + (stk_sizes[i].w * depth) & 0xff); + stk_camera_write_reg(dev, 0x0117, + (stk_sizes[i].h >> 8) & 0xff); + stk_camera_write_reg(dev, 0x0116, + stk_sizes[i].h & 0xff); + return stk_sensor_configure(dev); +} + static int stk_vidioc_s_fmt_cap(struct file *filp, void *priv, struct v4l2_format *fmtd) { @@ -1099,10 +1138,10 @@ static int stk_vidioc_s_fmt_cap(struct file *filp, return -EBUSY; if (dev->owner && dev->owner != filp) return -EBUSY; - dev->owner = filp; ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd); if (ret) return ret; + dev->owner = filp; dev->vsettings.palette = fmtd->fmt.pix.pixelformat; stk_free_buffers(dev); @@ -1110,25 +1149,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp, dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m; stk_initialise(dev); - /* This registers controls some timings, not sure of what. */ - stk_camera_write_reg(dev, 0x001b, 0x0e); - if (dev->vsettings.mode == MODE_SXGA) - stk_camera_write_reg(dev, 0x001c, 0x0e); - else - stk_camera_write_reg(dev, 0x001c, 0x46); - /* - * Registers 0x0115 0x0114 are the size of each line (bytes), - * regs 0x0117 0x0116 are the heigth of the image. - */ - stk_camera_write_reg(dev, 0x0115, - (fmtd->fmt.pix.bytesperline >> 8) & 0xff); - stk_camera_write_reg(dev, 0x0114, - fmtd->fmt.pix.bytesperline & 0xff); - stk_camera_write_reg(dev, 0x0117, - (fmtd->fmt.pix.height >> 8) & 0xff); - stk_camera_write_reg(dev, 0x0116, - fmtd->fmt.pix.height & 0xff); - return stk_sensor_configure(dev); + return stk_setup_format(dev); } static int stk_vidioc_reqbufs(struct file *filp, @@ -1422,6 +1443,7 @@ static int stk_camera_probe(struct usb_interface *interface, } stk_create_sysfs_files(&dev->vdev); + usb_autopm_enable(dev->interface); return 0; } @@ -1439,11 +1461,41 @@ static void stk_camera_disconnect(struct usb_interface *interface) kref_put(&dev->kref, stk_camera_cleanup); } +#ifdef CONFIG_PM +int stk_camera_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct stk_camera *dev = usb_get_intfdata(intf); + if (is_streaming(dev)) { + stk_stop_stream(dev); + /* yes, this is ugly */ + set_streaming(dev); + } + return 0; +} + +int stk_camera_resume(struct usb_interface *intf) +{ + struct stk_camera *dev = usb_get_intfdata(intf); + if (!is_initialised(dev)) + return 0; + unset_initialised(dev); + stk_initialise(dev); + stk_setup_format(dev); + if (is_streaming(dev)) + stk_start_stream(dev); + return 0; +} +#endif + static struct usb_driver stk_camera_driver = { .name = "stkwebcam", .probe = stk_camera_probe, .disconnect = stk_camera_disconnect, .id_table = stkwebcam_table, +#ifdef CONFIG_PM + .suspend = stk_camera_suspend, + .resume = stk_camera_resume, +#endif }; diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h index 7e989d1ac1e0..a2164cb1ad26 100644 --- a/drivers/media/video/stk-webcam.h +++ b/drivers/media/video/stk-webcam.h @@ -79,6 +79,7 @@ enum stk_status { #define unset_present(dev) ((dev)->status &= \ ~(S_PRESENT|S_INITIALISED|S_STREAMING)) #define set_initialised(dev) ((dev)->status |= S_INITIALISED) +#define unset_initialised(dev) ((dev)->status &= ~S_INITIALISED) #define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD) #define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD) #define set_streaming(dev) ((dev)->status |= S_STREAMING) From 2de3a5a5c52ae1550be537829bb487131430d74b Mon Sep 17 00:00:00 2001 From: Jaime Velasco Juan Date: Sun, 27 Jan 2008 12:25:00 -0300 Subject: [PATCH 237/880] V4L/DVB (7090): V4L: stkwebcam: use v4l_compat_ioctl32 Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/stk-webcam.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index f84e8d511763..94a366cc9976 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -1314,6 +1314,9 @@ static struct file_operations v4l_stk_fops = { .poll = v4l_stk_poll, .mmap = v4l_stk_mmap, .ioctl = video_ioctl2, +#ifdef CONFIG_COMPAT + .compat_ioctl = v4l_compat_ioctl32, +#endif .llseek = no_llseek }; From 0e3301ec23000ffbbe28771eb79628856a9a2f84 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Sun, 27 Jan 2008 14:54:07 -0300 Subject: [PATCH 238/880] V4L/DVB (7091): radio-si470x improvements and seldom problem fixed in tuning functions I updated the radio-si470x driver another time. Here are the commented history entries: - number of seek_retries changed to tune_timeout The last versions checked for the end of frequency tuning by polling a si470x register. Therefore polling depended on the usb utilization. This was changed to have a constant timeout now. - fixed problem with incomplete tune operations by own buffers The last version used a shared buffer to assembly the USB HID reports. It sometimes happened, that multiple functions were modifing this buffer simultanuously. When sending such reports, the hardware returned USB stalls (-EPIPE). Now buffers of the correct size (smaller than before) are allocated as local variables. - optimization of variables The size of some variables has been reduced to allow the compiler to generate more optimized code. - improved error logging At some important location, error checking was improved. Especially the usb transfers to access si470x registers and the tuning functions were modified. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 223 ++++++++++++++++++----------- 1 file changed, 143 insertions(+), 80 deletions(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 8e4bd4769048..a2975c8b0095 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -62,6 +62,12 @@ * - code cleaned of unnecessary rds_commands * - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified * (thanks to Guillaume RAMOUSSE) + * 2008-01-27 Tobias Lorenz + * Version 1.0.5 + * - number of seek_retries changed to tune_timeout + * - fixed problem with incomplete tune operations by own buffers + * - optimization of variables + * - improved error logging * * ToDo: * - add seeking support @@ -74,9 +80,10 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_VERSION KERNEL_VERSION(1, 0, 4) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 5) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" +#define DRIVER_VERSION "1.0.5" /* kernel includes */ @@ -119,56 +126,56 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr"); /* 0: 200 kHz (USA, Australia) */ /* 1: 100 kHz (Europe, Japan) */ /* 2: 50 kHz */ -static int space = 2; -module_param(space, int, 0); +static unsigned short space = 2; +module_param(space, ushort, 0); MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); /* Bottom of Band (MHz) */ /* 0: 87.5 - 108 MHz (USA, Europe)*/ /* 1: 76 - 108 MHz (Japan wide band) */ /* 2: 76 - 90 MHz (Japan) */ -static int band = 1; -module_param(band, int, 0); +static unsigned short band = 1; +module_param(band, ushort, 0); MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); /* De-emphasis */ /* 0: 75 us (USA) */ /* 1: 50 us (Europe, Australia, Japan) */ -static int de = 1; -module_param(de, int, 0); +static unsigned short de = 1; +module_param(de, ushort, 0); MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*"); /* USB timeout */ -static int usb_timeout = 500; -module_param(usb_timeout, int, 0); +static unsigned int usb_timeout = 500; +module_param(usb_timeout, uint, 0); MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); -/* Seek retries */ -static int seek_retries = 100; -module_param(seek_retries, int, 0); -MODULE_PARM_DESC(seek_retries, "Seek retries: *100*"); +/* Tune timeout */ +static unsigned int tune_timeout = 3000; +module_param(tune_timeout, uint, 0); +MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); /* RDS buffer blocks */ -static int rds_buf = 100; -module_param(rds_buf, int, 0); +static unsigned int rds_buf = 100; +module_param(rds_buf, uint, 0); MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); /* RDS maximum block errors */ -static int max_rds_errors = 1; +static unsigned short max_rds_errors = 1; /* 0 means 0 errors requiring correction */ /* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ /* 2 means 3-5 errors requiring correction */ /* 3 means 6+ errors or errors in checkword, correction not possible */ -module_param(max_rds_errors, int, 0); +module_param(max_rds_errors, ushort, 0); MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); /* RDS poll frequency */ -static int rds_poll_time = 40; +static unsigned int rds_poll_time = 40; /* 40 is used by the original USBRadio.exe */ /* 50 is used by radio-cadet */ /* 75 should be okay */ /* 80 is the usual RDS receive interval */ -module_param(rds_poll_time, int, 0); +module_param(rds_poll_time, uint, 0); MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); @@ -395,11 +402,8 @@ struct si470x_device { struct usb_device *usbdev; struct video_device *videodev; - /* are these really necessary ? */ - int users; - - /* report buffer (maximum 64 bytes) */ - unsigned char buf[64]; + /* driver management */ + unsigned int users; /* Silabs internal registers (0..15) */ unsigned short registers[RADIO_REGISTER_NUM]; @@ -434,28 +438,46 @@ struct si470x_device { /* * si470x_get_report - receive a HID report */ -static int si470x_get_report(struct si470x_device *radio, int size) +static int si470x_get_report(struct si470x_device *radio, void *buf, int size) { - return usb_control_msg(radio->usbdev, + unsigned char *report = (unsigned char *) buf; + int retval; + + retval = usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), HID_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - radio->buf[0], 2, - radio->buf, size, usb_timeout); + report[0], 2, + buf, size, usb_timeout); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": si470x_get_report: usb_control_msg returned %d\n", + retval); + + return retval; } /* * si470x_set_report - send a HID report */ -static int si470x_set_report(struct si470x_device *radio, int size) +static int si470x_set_report(struct si470x_device *radio, void *buf, int size) { - return usb_control_msg(radio->usbdev, + unsigned char *report = (unsigned char *) buf; + int retval; + + retval = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0), HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - radio->buf[0], 2, - radio->buf, size, usb_timeout); + report[0], 2, + buf, size, usb_timeout); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": si470x_set_report: usb_control_msg returned %d\n", + retval); + + return retval; } @@ -464,13 +486,15 @@ static int si470x_set_report(struct si470x_device *radio, int size) */ static int si470x_get_register(struct si470x_device *radio, int regnr) { + unsigned char buf[REGISTER_REPORT_SIZE]; int retval; - radio->buf[0] = REGISTER_REPORT(regnr); + buf[0] = REGISTER_REPORT(regnr); + + retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); - retval = si470x_get_report(radio, REGISTER_REPORT_SIZE); if (retval >= 0) - radio->registers[regnr] = (radio->buf[1] << 8) | radio->buf[2]; + radio->registers[regnr] = (buf[1] << 8) | buf[2]; return (retval < 0) ? -EINVAL : 0; } @@ -481,13 +505,14 @@ static int si470x_get_register(struct si470x_device *radio, int regnr) */ static int si470x_set_register(struct si470x_device *radio, int regnr) { + unsigned char buf[REGISTER_REPORT_SIZE]; int retval; - radio->buf[0] = REGISTER_REPORT(regnr); - radio->buf[1] = (radio->registers[regnr] & 0xff00) >> 8; - radio->buf[2] = (radio->registers[regnr] & 0x00ff); + buf[0] = REGISTER_REPORT(regnr); + buf[1] = (radio->registers[regnr] & 0xff00) >> 8; + buf[2] = (radio->registers[regnr] & 0x00ff); - retval = si470x_set_report(radio, REGISTER_REPORT_SIZE); + retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); return (retval < 0) ? -EINVAL : 0; } @@ -498,18 +523,19 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) */ static int si470x_get_all_registers(struct si470x_device *radio) { + unsigned char buf[ENTIRE_REPORT_SIZE]; int retval; - int regnr; + unsigned char regnr; - radio->buf[0] = ENTIRE_REPORT; + buf[0] = ENTIRE_REPORT; - retval = si470x_get_report(radio, ENTIRE_REPORT_SIZE); + retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); if (retval >= 0) for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) radio->registers[regnr] = - (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; + (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | + buf[regnr * RADIO_REGISTER_SIZE + 2]; return (retval < 0) ? -EINVAL : 0; } @@ -520,21 +546,28 @@ static int si470x_get_all_registers(struct si470x_device *radio) */ static int si470x_get_rds_registers(struct si470x_device *radio) { + unsigned char buf[RDS_REPORT_SIZE]; int retval; - int regnr; int size; + unsigned char regnr; - radio->buf[0] = RDS_REPORT; + buf[0] = RDS_REPORT; retval = usb_interrupt_msg(radio->usbdev, - usb_rcvctrlpipe(radio->usbdev, 1), - radio->buf, RDS_REPORT_SIZE, &size, usb_timeout); + usb_rcvintpipe(radio->usbdev, 1), + (void *) &buf, sizeof(buf), &size, usb_timeout); + if (size != sizeof(buf)) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " + "return size differs: %d != %d\n", size, sizeof(buf)); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " + "usb_interrupt_msg returned %d\n", retval); if (retval >= 0) for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) radio->registers[STATUSRSSI + regnr] = - (radio->buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - radio->buf[regnr * RADIO_REGISTER_SIZE + 2]; + (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | + buf[regnr * RADIO_REGISTER_SIZE + 2]; return (retval < 0) ? -EINVAL : 0; } @@ -543,9 +576,11 @@ static int si470x_get_rds_registers(struct si470x_device *radio) /* * si470x_set_chan - set the channel */ -static int si470x_set_chan(struct si470x_device *radio, int chan) +static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) { - int retval, i; + int retval; + unsigned long timeout; + bool timed_out = 0; /* start tuning */ radio->registers[CHANNEL] &= ~CHANNEL_CHAN; @@ -555,16 +590,17 @@ static int si470x_set_chan(struct si470x_device *radio, int chan) return retval; /* wait till seek operation has completed */ - i = 0; + timeout = jiffies + msecs_to_jiffies(tune_timeout); do { retval = si470x_get_register(radio, STATUSRSSI); if (retval < 0) return retval; - } while ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) && - (++i < seek_retries)); - if (i >= seek_retries) + timed_out = time_after(jiffies, timeout); + } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && + (!timed_out)); + if (timed_out) printk(KERN_WARNING DRIVER_NAME - ": seek does not finish after %d tries\n", i); + ": seek does not finish after %d ms\n", tune_timeout); /* stop tuning */ radio->registers[CHANNEL] &= ~CHANNEL_TUNE; @@ -575,9 +611,10 @@ static int si470x_set_chan(struct si470x_device *radio, int chan) /* * si470x_get_freq - get the frequency */ -static int si470x_get_freq(struct si470x_device *radio) +static unsigned int si470x_get_freq(struct si470x_device *radio) { - int spacing, band_bottom, chan, freq; + unsigned int spacing, band_bottom, freq; + unsigned short chan; int retval; /* Spacing (kHz) */ @@ -616,9 +653,10 @@ static int si470x_get_freq(struct si470x_device *radio) /* * si470x_set_freq - set the frequency */ -static int si470x_set_freq(struct si470x_device *radio, int freq) +static int si470x_set_freq(struct si470x_device *radio, unsigned int freq) { - int spacing, band_bottom, chan; + unsigned int spacing, band_bottom; + unsigned short chan; /* Spacing (kHz) */ switch (space) { @@ -725,12 +763,6 @@ static int si470x_rds_on(struct si470x_device *radio) */ static void si470x_rds(struct si470x_device *radio) { - unsigned char tmpbuf[3]; - unsigned char blocknum; - unsigned char bler; /* rds block errors */ - unsigned short rds; - unsigned int i; - /* get rds blocks */ if (si470x_get_rds_registers(radio) < 0) return; @@ -745,6 +777,12 @@ static void si470x_rds(struct si470x_device *radio) /* copy four RDS blocks to internal buffer */ if (spin_trylock(&radio->lock)) { + unsigned char blocknum; + unsigned short bler; /* rds block errors */ + unsigned short rds; + unsigned char tmpbuf[3]; + unsigned char i; + /* process each rds block */ for (blocknum = 0; blocknum < 4; blocknum++) { switch (blocknum) { @@ -847,7 +885,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; - unsigned int block_count = 0; /* switch on rds reception */ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { @@ -867,6 +904,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, /* copy RDS block out of internal buffer and to user buffer */ if (spin_trylock(&radio->lock)) { + unsigned int block_count = 0; while (block_count < count) { if (radio->rd_index == radio->wr_index) break; @@ -1030,7 +1068,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); sprintf(capability->bus_info, "USB"); - capability->version = DRIVER_VERSION; + capability->version = DRIVER_KERNEL_VERSION; capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; return 0; @@ -1067,16 +1105,21 @@ static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i) static int si470x_vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) { - int i; + unsigned char i; + int retval = -EINVAL; for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) { memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); - return 0; + retval = 0; + break; } } + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": query control failed with %d\n", retval); - return -EINVAL; + return retval; } @@ -1110,21 +1153,29 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME; radio->registers[SYSCONFIG2] |= ctrl->value; - return si470x_set_register(radio, SYSCONFIG2); + retval = si470x_set_register(radio, SYSCONFIG2); + break; case V4L2_CID_AUDIO_MUTE: if (ctrl->value == 1) radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; else radio->registers[POWERCFG] |= POWERCFG_DMUTE; - return si470x_set_register(radio, POWERCFG); + retval = si470x_set_register(radio, POWERCFG); + break; + default: + retval = -EINVAL; } + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set control failed with %d\n", retval); - return -EINVAL; + return retval; } @@ -1163,8 +1214,8 @@ static int si470x_vidioc_s_audio(struct file *file, void *priv, static int si470x_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { - int retval; struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (tuner->index > 0) return -EINVAL; @@ -1220,6 +1271,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (tuner->index > 0) return -EINVAL; @@ -1229,7 +1281,12 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, else radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ - return si470x_set_register(radio, POWERCFG); + retval = si470x_set_register(radio, POWERCFG); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set tuner failed with %d\n", retval); + + return retval; } @@ -1255,11 +1312,17 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *freq) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (freq->type != V4L2_TUNER_RADIO) return -EINVAL; - return si470x_set_freq(radio, freq->frequency); + retval = si470x_set_freq(radio, freq->frequency); + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set frequency failed with %d\n", retval); + + return 0; } @@ -1409,7 +1472,7 @@ static struct usb_driver si470x_usb_driver = { */ static int __init si470x_module_init(void) { - printk(KERN_INFO DRIVER_DESC "\n"); + printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n"); return usb_register(&si470x_usb_driver); } @@ -1429,4 +1492,4 @@ module_exit(si470x_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION("1.0.4"); +MODULE_VERSION(DRIVER_VERSION); From dd49f30ca032464839085ec3a54dd9917829c891 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 27 Jan 2008 14:29:51 -0300 Subject: [PATCH 239/880] V4L/DVB (7092): radio-sf16fmr2: fix request_region() validation [bugzilla 9699] This patch changed the request_region() validation to avoid invalid return. Thanks to Roland Kletzing for bug report and data collection. Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-sf16fmr2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index f7c8b000404f..ebc5fbbc38bb 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -470,9 +470,8 @@ static int __init fmr2_init(void) mutex_init(&lock); - if (request_region(io, 2, "sf16fmr2")) - { - printk(KERN_ERR "fmr2: port 0x%x already in use\n", io); + if (!request_region(io, 2, "sf16fmr2")) { + printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n"); return -EBUSY; } From e08a8c9dc7d247ec2a98ea2d7ac5ecea6af5593c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jan 2008 14:43:20 -0300 Subject: [PATCH 240/880] V4L/DVB (7093): radio-sf16fmi: fix request_region() isapnp_fmi_probe attaches device. However, if request_region() fails, the device isn't disattached. Reviewed-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-sf16fmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 3118bdab3183..53e114857377 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -361,6 +361,7 @@ static int __init fmi_init(void) } if (!request_region(io, 2, "radio-sf16fmi")) { printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io); + pnp_device_detach(dev); return -EBUSY; } From 0e8f4cc5c8bb782edbaee54a760ebc034252fab0 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Mon, 28 Jan 2008 12:01:11 -0300 Subject: [PATCH 241/880] V4L/DVB (7097): saa7134-dvb: add missing dvb_attach call (for tda10046_attach) saa7134-dvb: add missing dvb_attach around tda10046_attach This patch adds a possibly missing dvb_attach for tda10046_attach. This removes the hard dependency of saa7134-dvb on tda1004x module. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-dvb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 90f495a67804..e58f437ea9f7 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1022,8 +1022,9 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: - dev->dvb.frontend = tda10046_attach(&medion_cardbus, - &dev->i2c_adap); + dev->dvb.frontend = dvb_attach(tda10046_attach, + &medion_cardbus, + &dev->i2c_adap); if (dev->dvb.frontend) { dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; From 805d92dfa627acad3d4a78966bc5e4f8183d48b3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 28 Jan 2008 22:12:41 -0300 Subject: [PATCH 242/880] V4L/DVB (7100): frontends/tda18271-common.c: fix off-by-one This patch fixes an off-by-one error spotted by the Coverity checker. Signed-off-by: Adrian Bunk Reviewed-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda18271-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/frontends/tda18271-common.c b/drivers/media/dvb/frontends/tda18271-common.c index cebb6b90b7e0..bca570990613 100644 --- a/drivers/media/dvb/frontends/tda18271-common.c +++ b/drivers/media/dvb/frontends/tda18271-common.c @@ -171,7 +171,7 @@ int tda18271_read_extended(struct dvb_frontend *fe) if (ret != 2) tda_err("ERROR: i2c_transfer returned: %d\n", ret); - for (i = 0; i <= TDA18271_NUM_REGS; i++) { + for (i = 0; i < TDA18271_NUM_REGS; i++) { /* don't update write-only registers */ if ((i != R_EB9) && (i != R_EB16) && From c52c4d063eb163d2980c1884370da453662a1f31 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 28 Jan 2008 22:11:15 -0300 Subject: [PATCH 243/880] V4L/DVB (7102): make tuner-core.c:tuner_list static tuner_list can become static - and it's anyway a way too generic name for a global variable - see commit b00ef4b8d8c29bfb5f6f92ee60bc04b604f36ef2 for a completely different global variable of the same name I just made static... Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tuner-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index ba538f6fbcc3..78a09a2a4857 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1038,7 +1038,7 @@ static int tuner_resume(struct i2c_client *c) /* ---------------------------------------------------------------------- */ -LIST_HEAD(tuner_list); +static LIST_HEAD(tuner_list); /* Search for existing radio and/or TV tuners on the given I2C adapter. Note that when this function is called from tuner_probe you can be From beb9e780a45a2e21f3d62bd4c71d695aa195fe69 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 28 Jan 2008 22:11:01 -0300 Subject: [PATCH 244/880] V4L/DVB (7103): make stk_camera_cleanup() static stk_camera_cleanup() can become static. Signed-off-by: Adrian Bunk Acked-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/stk-webcam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 94a366cc9976..ceba45ad0294 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -63,7 +63,7 @@ static struct usb_device_id stkwebcam_table[] = { }; MODULE_DEVICE_TABLE(usb, stkwebcam_table); -void stk_camera_cleanup(struct kref *kref) +static void stk_camera_cleanup(struct kref *kref) { struct stk_camera *dev = to_stk_camera(kref); From fe2b8f50a336bcd51e3d209c5838c573b4b540b3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 28 Jan 2008 22:10:58 -0300 Subject: [PATCH 245/880] V4L/DVB (7104): stk-sensor.c: make 2 functions static This patch makes the following needlessly global functions static: - stk_sensor_outb() - stk_sensor_inb() Signed-off-by: Adrian Bunk Acked-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/stk-sensor.c | 4 ++-- drivers/media/video/stk-webcam.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/stk-sensor.c b/drivers/media/video/stk-sensor.c index 1a8692d9ee5a..e546b014d7ad 100644 --- a/drivers/media/video/stk-sensor.c +++ b/drivers/media/video/stk-sensor.c @@ -225,7 +225,7 @@ /* Returns 0 if OK */ -int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) +static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) { int i = 0; int tmpval = 0; @@ -250,7 +250,7 @@ int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val) return 0; } -int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) +static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val) { int i = 0; int tmpval = 0; diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h index a2164cb1ad26..df4dfefc5327 100644 --- a/drivers/media/video/stk-webcam.h +++ b/drivers/media/video/stk-webcam.h @@ -128,8 +128,6 @@ void stk_camera_delete(struct kref *); int stk_camera_write_reg(struct stk_camera *, u16, u8); int stk_camera_read_reg(struct stk_camera *, u16, int *); -int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val); -int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val); int stk_sensor_init(struct stk_camera *); int stk_sensor_configure(struct stk_camera *); int stk_sensor_sleep(struct stk_camera *dev); From 532fe65205253aef1ce5c0c76d2d8d303fb3fe71 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 28 Jan 2008 22:10:48 -0300 Subject: [PATCH 246/880] V4L/DVB (7106): em28xx/: make 2 functions static This patch makes the following needlessly global functions static: - em28xx-core.c:em28xx_write_reg_bits() - em28xx-video.c:em28xx_vdev_init() Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 2 +- drivers/media/video/em28xx/em28xx-video.c | 8 ++++---- drivers/media/video/em28xx/em28xx.h | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index f6b78357f0e5..41ed4be4ae01 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -237,7 +237,7 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) * sets only some bits (specified by bitmask) of a register, by first reading * the actual value */ -int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, +static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, u8 bitmask) { int oldval; diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index a0c334672488..c4126055bec3 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1796,10 +1796,10 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) } EXPORT_SYMBOL(em28xx_unregister_extension); -struct video_device *em28xx_vdev_init(struct em28xx *dev, - const struct video_device *template, - const int type, - const char *type_name) +static struct video_device *em28xx_vdev_init(struct em28xx *dev, + const struct video_device *template, + const int type, + const char *type_name) { struct video_device *vfd; diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index f3bad0c1c517..9759a7330a53 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -345,8 +345,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg); int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int len); int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); -int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, - u8 bitmask); int em28xx_set_audio_source(struct em28xx *dev); int em28xx_audio_analog_set(struct em28xx *dev); From c3f686f152767b84893e474acd1a7758988dc369 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Mon, 28 Jan 2008 22:43:13 -0300 Subject: [PATCH 247/880] V4L/DVB (7108): radio-si470x.c: check-after-use Adrian used the coverity checker against radio-si470x and found this: > The Coverity checker spotted the following check-after-use in > drivers/media/radio/radio-si470x.c: > > <-- snip --> > static void si470x_usb_driver_disconnect(struct usb_interface *intf) > { > struct si470x_device *radio = usb_get_intfdata(intf); > > del_timer_sync(&radio->timer); <------------------ > flush_scheduled_work(); > > usb_set_intfdata(intf, NULL); > if (radio) { <------------------ > video_unregister_device(radio->videodev); > kfree(radio->buffer); > kfree(radio); > } > } > <-- snip --> > > Either "radio" can be NULL and this case has to be properly handled or > the NULL check is not required. These two lines should indeed better be inside the if statement. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index a2975c8b0095..7fdee3cc6e02 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -1439,11 +1439,10 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) { struct si470x_device *radio = usb_get_intfdata(intf); - del_timer_sync(&radio->timer); - flush_scheduled_work(); - usb_set_intfdata(intf, NULL); if (radio) { + del_timer_sync(&radio->timer); + flush_scheduled_work(); video_unregister_device(radio->videodev); kfree(radio->buffer); kfree(radio); From 998cb0827d62f13a80e7f7b0ec993e98184cbc57 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Mon, 28 Jan 2008 22:49:14 -0300 Subject: [PATCH 248/880] V4L/DVB (7110): Trivial printf warning fix (radio-si470) Thanks to Darren Salt for pointing this issue. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 7fdee3cc6e02..204577eb287b 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -558,7 +558,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) (void *) &buf, sizeof(buf), &size, usb_timeout); if (size != sizeof(buf)) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " - "return size differs: %d != %d\n", size, sizeof(buf)); + "return size differs: %d != %ld\n", size, sizeof(buf)); if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " "usb_interrupt_msg returned %d\n", retval); From 03aa73c58704182298495569bbb613bf8fc770d1 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 29 Jan 2008 23:56:51 -0300 Subject: [PATCH 249/880] V4L/DVB (7116): budget-av: Add support for KNC TV Station Plus X4 Add support for KNC TV Station Plus X4, sub-system id 0x1894:0x0015. Based on a patch submitted by Johannes Deisenhofer. Thanks-to: Johannes Deisenhofer Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-av.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 3439c9864f67..15fa88a174a0 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -896,6 +896,7 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBS_CINERGY1200 0x1154 #define SUBID_DVBS_CYNERGY1200N 0x1155 #define SUBID_DVBS_TV_STAR 0x0014 +#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015 #define SUBID_DVBS_TV_STAR_CI 0x0016 #define SUBID_DVBS_EASYWATCH_1 0x001a #define SUBID_DVBS_EASYWATCH_2 0x001b @@ -957,6 +958,7 @@ static void frontend_init(struct budget_av *budget_av) break; case SUBID_DVBS_TV_STAR: + case SUBID_DVBS_TV_STAR_PLUS_X4: case SUBID_DVBS_TV_STAR_CI: case SUBID_DVBS_CYNERGY1200N: case SUBID_DVBS_EASYWATCH: @@ -1249,6 +1251,7 @@ MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); +MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3); MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3); @@ -1266,6 +1269,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011), MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), + MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015), MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), From 251130bf266000fe6e9fdccda50fe4b5c1d6cb24 Mon Sep 17 00:00:00 2001 From: Kim Sandberg Date: Wed, 30 Jan 2008 00:42:01 -0300 Subject: [PATCH 250/880] V4L/DVB (7117): budget-av: Add support for Satelco EasyWatch PCI DVB-T Add support for Satelco EasyWatch PCI DVB-T, sub-id 0x1894:0x003a. Signed-off-by: Kim Sandberg Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-av.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 15fa88a174a0..2d64d557b977 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -911,6 +911,7 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBC_CINERGY1200 0x1156 #define SUBID_DVBC_CINERGY1200_MK3 0x1176 +#define SUBID_DVBT_EASYWATCH 0x003a #define SUBID_DVBT_KNC1_PLUS 0x0031 #define SUBID_DVBT_KNC1 0x0030 #define SUBID_DVBT_CINERGY1200 0x1157 @@ -1020,6 +1021,7 @@ static void frontend_init(struct budget_av *budget_av) } break; + case SUBID_DVBT_EASYWATCH: case SUBID_DVBT_KNC1: case SUBID_DVBT_KNC1_PLUS: case SUBID_DVBT_CINERGY1200: @@ -1250,6 +1252,7 @@ MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); +MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T); MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); @@ -1276,6 +1279,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), + MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a), MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), From 0ed4a6ea9dbd9f5b77ce594f7f46be022d2c49ec Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 30 Jan 2008 01:07:20 -0300 Subject: [PATCH 251/880] V4L/DVB (7118): dvb-ttpci: Improved display of still pictures Improved display of still pictures (VIDEO_STILLPICTURE ioctl). Ensure that both fields are displayed for progressive frames. Thanks to Reinhard Nissl and Klaus Schmidinger for finding out that the FREEZE command does this. Thanks-to: Reinhard Nissl Thanks-to: Klaus Schmidinger Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_av.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index aef6e36d7c5c..3e6b650fbb81 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -966,6 +966,7 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) { int i, n; + int progressive = 0; dprintk(2, "av7110:%p, \n", av7110); @@ -974,6 +975,14 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len return -EBUSY; } + for (i = 0; i < len - 5; i++) { + /* get progressive flag from picture extension */ + if (buf[i] == 0x00 && buf[i+1] == 0x00 && + buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 && + (buf[i+4] & 0xf0) == 0x10) + progressive = buf[i+5] & 0x08; + } + /* setting n always > 1, fixes problems when playing stillframes consisting of I- and P-Frames */ n = MIN_IFRAME / len + 1; @@ -985,7 +994,11 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len dvb_play(av7110, buf, len, 0, 1); av7110_ipack_flush(&av7110->ipack[1]); - return 0; + + if (progressive) + return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); + else + return 0; } From ce3a35d3c00918296e552af5ecc7b771af766436 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 13:40:04 -0300 Subject: [PATCH 252/880] V4L/DVB (7120): videobuf lock is already initialized at videobuf-core.c Removes the duplicated mutex_init code. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_vbi.c | 1 - drivers/media/common/saa7146_video.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c index c32dda973e92..bfbd5a841ebf 100644 --- a/drivers/media/common/saa7146_vbi.c +++ b/drivers/media/common/saa7146_vbi.c @@ -413,7 +413,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) V4L2_FIELD_SEQ_TB, // FIXME: does this really work? sizeof(struct saa7146_buf), file); - mutex_init(&fh->vbi_q.lock); init_timer(&fh->vbi_read_timeout); fh->vbi_read_timeout.function = vbi_read_timeout; diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index c31ab480d8e1..66fdbd0e6a6d 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -1417,8 +1417,6 @@ static int video_open(struct saa7146_dev *dev, struct file *file) sizeof(struct saa7146_buf), file); - mutex_init(&fh->video_q.lock); - return 0; } From 64f9477f95bf5d4ba49dc3988d47a15bc06bb5da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 13:57:53 -0300 Subject: [PATCH 253/880] V4L/DVB (7121): Renames videobuf lock to vb_lock This helps to identify where vb_lock is being used, and find missusages of the locks. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 50 ++++++------ drivers/media/video/bt8xx/bttv-vbi.c | 4 +- drivers/media/video/saa7134/saa7134-empress.c | 8 +- drivers/media/video/saa7134/saa7134-video.c | 20 ++--- drivers/media/video/videobuf-core.c | 78 +++++++++---------- drivers/media/video/videobuf-dma-sg.c | 4 +- drivers/media/video/videobuf-vmalloc.c | 4 +- include/media/videobuf-core.h | 2 +- 8 files changed, 84 insertions(+), 86 deletions(-) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 907dc62c1783..d9ce9a48ef59 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -2354,8 +2354,8 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, BUG(); } - mutex_lock(&fh->cap.lock); - kfree(fh->ov.clips); + mutex_lock(&fh->cap.vb_lock); + kfree(fh->ov.clips); fh->ov.clips = clips; fh->ov.nclips = n; @@ -2376,7 +2376,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv, bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); retval = bttv_switch_overlay(btv,fh,new); } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -2576,7 +2576,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, fmt = format_by_fourcc(f->fmt.pix.pixelformat); /* update our state informations */ - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); fh->fmt = fmt; fh->cap.field = f->fmt.pix.field; fh->cap.last = V4L2_FIELD_NONE; @@ -2585,7 +2585,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, btv->init.fmt = fmt; btv->init.width = f->fmt.pix.width; btv->init.height = f->fmt.pix.height; - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return 0; } @@ -2611,11 +2611,11 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) unsigned int i; struct bttv_fh *fh = priv; - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, V4L2_MEMORY_MMAP); if (retval < 0) { - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -2627,7 +2627,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) for (i = 0; i < gbuffers; i++) mbuf->offsets[i] = i * gbufsize; - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return 0; } #endif @@ -2756,7 +2756,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) if (!check_alloc_btres(btv, fh, RESOURCE_OVERLAY)) return -EBUSY; - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (on) { fh->ov.tvnorm = btv->tvnorm; new = videobuf_pci_alloc(sizeof(*new)); @@ -2767,7 +2767,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) /* switch over */ retval = bttv_switch_overlay(btv, fh, new); - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -2806,7 +2806,7 @@ static int bttv_s_fbuf(struct file *file, void *f, } /* ok, accept it */ - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); btv->fbuf.base = fb->base; btv->fbuf.fmt.width = fb->fmt.width; btv->fbuf.fmt.height = fb->fmt.height; @@ -2838,7 +2838,7 @@ static int bttv_s_fbuf(struct file *file, void *f, retval = bttv_switch_overlay(btv, fh, new); } } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return retval; } @@ -3090,7 +3090,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) fh->do_crop = 1; - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (fh->width < c.min_scaled_width) { fh->width = c.min_scaled_width; @@ -3108,7 +3108,7 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) btv->init.height = c.max_scaled_height; } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); return 0; } @@ -3177,30 +3177,25 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); } else { /* read() capture */ - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (NULL == fh->cap.read_buf) { /* need to capture a new frame */ - if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } + if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) + goto err; fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize); - if (NULL == fh->cap.read_buf) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } + if (NULL == fh->cap.read_buf) + goto err; fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; field = videobuf_next_field(&fh->cap); if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { kfree (fh->cap.read_buf); fh->cap.read_buf = NULL; - mutex_unlock(&fh->cap.lock); - return POLLERR; + goto err; } fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); buf = (struct bttv_buffer*)fh->cap.read_buf; } @@ -3209,6 +3204,9 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) buf->vb.state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; +err: + mutex_unlock(&fh->cap.vb_lock); + return POLLERR; } static int bttv_open(struct inode *inode, struct file *file) diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 1f0cc79e2a33..75fa82c7c735 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c @@ -352,13 +352,13 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) because vbi_fmt.end counts field lines times two. */ end = max(frt->fmt.vbi.start[0], start1) * 2 + 2; - mutex_lock(&fh->vbi.lock); + mutex_lock(&fh->vbi.vb_lock); fh->vbi_fmt.fmt = frt->fmt.vbi; fh->vbi_fmt.tvnorm = tvnorm; fh->vbi_fmt.end = end; - mutex_unlock(&fh->vbi.lock); + mutex_unlock(&fh->vbi.vb_lock); rc = 0; diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index b1b01fa86720..94b81e1a7530 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -87,7 +87,7 @@ static int ts_open(struct inode *inode, struct file *file) dprintk("open minor=%d\n",minor); err = -EBUSY; - if (!mutex_trylock(&dev->empress_tsq.lock)) + if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; if (dev->empress_users) goto done_up; @@ -101,7 +101,7 @@ static int ts_open(struct inode *inode, struct file *file) err = 0; done_up: - mutex_unlock(&dev->empress_tsq.lock); + mutex_unlock(&dev->empress_tsq.vb_lock); done: return err; } @@ -110,7 +110,7 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.lock); + mutex_lock(&dev->empress_tsq.vb_lock); videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); dev->empress_users--; @@ -122,7 +122,7 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - mutex_unlock(&dev->empress_tsq.lock); + mutex_unlock(&dev->empress_tsq.vb_lock); return 0; } diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 1184d359e848..39c41ad97d0e 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1414,21 +1414,17 @@ video_poll(struct file *file, struct poll_table_struct *wait) if (!list_empty(&fh->cap.stream)) buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream); } else { - mutex_lock(&fh->cap.lock); + mutex_lock(&fh->cap.vb_lock); if (UNSET == fh->cap.read_off) { /* need to capture a new frame */ - if (res_locked(fh->dev,RESOURCE_VIDEO)) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } - if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { - mutex_unlock(&fh->cap.lock); - return POLLERR; - } + if (res_locked(fh->dev,RESOURCE_VIDEO)) + goto err; + if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) + goto err; fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; } - mutex_unlock(&fh->cap.lock); + mutex_unlock(&fh->cap.vb_lock); buf = fh->cap.read_buf; } @@ -1440,6 +1436,10 @@ video_poll(struct file *file, struct poll_table_struct *wait) buf->state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; + +err: + mutex_unlock(&fh->cap.vb_lock); + return POLLERR; } static int video_release(struct inode *inode, struct file *file) diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 80a14da9acef..eab79ffdf56a 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -147,7 +147,7 @@ void videobuf_queue_core_init(struct videobuf_queue *q, /* Having implementations for abstract methods are mandatory */ BUG_ON(!q->int_ops); - mutex_init(&q->lock); + mutex_init(&q->vb_lock); INIT_LIST_HEAD(&q->stream); } @@ -189,7 +189,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q) return 0; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ void videobuf_queue_cancel(struct videobuf_queue *q) { unsigned long flags = 0; @@ -220,7 +220,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q) /* --------------------------------------------------------------------- */ -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ enum v4l2_field videobuf_next_field(struct videobuf_queue *q) { enum v4l2_field field = q->field; @@ -239,7 +239,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q) return field; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, struct videobuf_buffer *vb, enum v4l2_buf_type type) { @@ -295,7 +295,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, b->sequence = vb->field_count >> 1; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_mmap_free(struct videobuf_queue *q) { int i; @@ -328,13 +328,13 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) int videobuf_mmap_free(struct videobuf_queue *q) { int ret; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); ret = __videobuf_mmap_free(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return ret; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_mmap_setup(struct videobuf_queue *q, unsigned int bcount, unsigned int bsize, enum v4l2_memory memory) @@ -384,9 +384,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q, enum v4l2_memory memory) { int ret; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); ret = __videobuf_mmap_setup(q, bcount, bsize, memory); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return ret; } @@ -408,7 +408,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, return -EINVAL; } - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (req->type != q->type) { dprintk(1, "reqbufs: queue type invalid\n"); retval = -EINVAL; @@ -444,7 +444,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, req->count = retval; done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } @@ -452,7 +452,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) { int ret = -EINVAL; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (unlikely(b->type != q->type)) { dprintk(1, "querybuf: Wrong type.\n"); goto done; @@ -470,7 +470,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) ret = 0; done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return ret; } @@ -487,7 +487,7 @@ int videobuf_qbuf(struct videobuf_queue *q, if (b->memory == V4L2_MEMORY_MMAP) down_read(¤t->mm->mmap_sem); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->reading) { dprintk(1, "qbuf: Reading running...\n"); @@ -573,7 +573,7 @@ int videobuf_qbuf(struct videobuf_queue *q, retval = 0; done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); if (b->memory == V4L2_MEMORY_MMAP) up_read(¤t->mm->mmap_sem); @@ -589,7 +589,7 @@ int videobuf_dqbuf(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->reading) { dprintk(1, "dqbuf: Reading running...\n"); @@ -632,7 +632,7 @@ int videobuf_dqbuf(struct videobuf_queue *q, videobuf_status(q, b, buf, q->type); done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } @@ -642,7 +642,7 @@ int videobuf_streamon(struct videobuf_queue *q) unsigned long flags = 0; int retval; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->reading) goto done; @@ -659,11 +659,11 @@ int videobuf_streamon(struct videobuf_queue *q) spin_unlock_irqrestore(q->irqlock, flags); done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_streamoff(struct videobuf_queue *q) { if (!q->streaming) @@ -679,14 +679,14 @@ int videobuf_streamoff(struct videobuf_queue *q) { int retval; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = __videobuf_streamoff(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos) @@ -745,7 +745,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); nbufs = 1; size = 0; q->ops->buf_setup(q, &nbufs, &size); @@ -817,11 +817,11 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, } done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } -/* Locking: Caller holds q->lock */ +/* Locking: Caller holds q->vb_lock */ static int __videobuf_read_start(struct videobuf_queue *q) { enum v4l2_field field; @@ -882,23 +882,23 @@ int videobuf_read_start(struct videobuf_queue *q) { int rc; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); rc = __videobuf_read_start(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return rc; } void videobuf_read_stop(struct videobuf_queue *q) { - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); __videobuf_read_stop(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); } void videobuf_stop(struct videobuf_queue *q) { - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (q->streaming) __videobuf_streamoff(q); @@ -906,7 +906,7 @@ void videobuf_stop(struct videobuf_queue *q) if (q->reading) __videobuf_read_stop(q); - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); } @@ -920,7 +920,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); dprintk(2, "%s\n", __FUNCTION__); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->streaming) goto done; @@ -980,7 +980,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, } done: - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } @@ -991,7 +991,7 @@ unsigned int videobuf_poll_stream(struct file *file, struct videobuf_buffer *buf = NULL; unsigned int rc = 0; - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); if (q->streaming) { if (!list_empty(&q->stream)) buf = list_entry(q->stream.next, @@ -1019,7 +1019,7 @@ unsigned int videobuf_poll_stream(struct file *file, buf->state == VIDEOBUF_ERROR) rc = POLLIN|POLLRDNORM; } - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return rc; } @@ -1030,10 +1030,10 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); retval = CALL(q, mmap_mapper, q, vma); q->is_mmapped = 1; - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); return retval; } diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 98efd7ab1f50..53fed4b74ce9 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -356,7 +356,7 @@ videobuf_vm_close(struct vm_area_struct *vma) map->count--; if (0 == map->count) { dprintk(1,"munmap %p q=%p\n",map,q); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -373,7 +373,7 @@ videobuf_vm_close(struct vm_area_struct *vma) q->bufs[i]->baddr = 0; q->ops->buf_release(q,q->bufs[i]); } - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); kfree(map); } return; diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index 9b3898347ca5..03b3b41cbb62 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c @@ -70,7 +70,7 @@ videobuf_vm_close(struct vm_area_struct *vma) map->count--; if (0 == map->count) { dprintk(1,"munmap %p q=%p\n",map,q); - mutex_lock(&q->lock); + mutex_lock(&q->vb_lock); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -83,7 +83,7 @@ videobuf_vm_close(struct vm_area_struct *vma) q->bufs[i]->map = NULL; q->bufs[i]->baddr = 0; } - mutex_unlock(&q->lock); + mutex_unlock(&q->vb_lock); kfree(map); } return; diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 97f14d469595..99033945cdee 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h @@ -149,7 +149,7 @@ struct videobuf_qtype_ops { }; struct videobuf_queue { - struct mutex lock; + struct mutex vb_lock; spinlock_t *irqlock; void *dev; /* on pci, points to struct pci_dev */ From fb62a5953e9e6969f78adc7291c1a8845116f776 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 31 Jan 2008 13:59:29 -0300 Subject: [PATCH 254/880] V4L/DVB (7122): saa7134-empress: Remove back lock videobuf functions at close() method already locks videobuf. It makes no sense to keep the locking at empress close() method. There is also a lock at open() method. I'm not sure if it is safe to remove the locking there. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-empress.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 94b81e1a7530..3d2ec30de227 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -110,7 +110,6 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.vb_lock); videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); dev->empress_users--; @@ -122,7 +121,6 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - mutex_unlock(&dev->empress_tsq.vb_lock); return 0; } From 427d20c4e6321ed2482630900891e40b4f2de6a3 Mon Sep 17 00:00:00 2001 From: Luc Saillard Date: Wed, 30 Jan 2008 17:23:00 -0300 Subject: [PATCH 255/880] V4L/DVB (7132): Add USB ID for a newer variant of Hauppauge WinTV-HVR 900 Device description: WinTV-HVR-900 M/R: 65018/B3C0 ##4207 Signed-off-by: Luc Saillard Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 2 +- drivers/media/video/em28xx/em28xx-cards.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 6a8469f2bcae..f40e09296f30 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -8,7 +8,7 @@ 7 -> Leadtek Winfast USB II (em2800) 8 -> Kworld USB2800 (em2800) 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a] - 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] + 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502] 11 -> Terratec Hybrid XS (em2880) [0ccd:0042] 12 -> Kworld PVR TV 2800 RF (em2820/em2840) 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 2159d0160df2..fc160772930c 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -441,6 +441,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, + { USB_DEVICE(0x2040, 0x6502), + .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6513), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x0ccd, 0x0042), From 18c0ecf16e1caa266e12319b5ab82d80e8a3ccf0 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Sat, 2 Feb 2008 20:20:58 -0300 Subject: [PATCH 256/880] V4L/DVB (7139): add parentheses '!' has a higher priority than '&': bitanding has no effect. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvaudio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index a75560540e79..01ebcec040c4 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1571,14 +1571,14 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip, ctrl->value=chip->muted; return 0; case V4L2_CID_AUDIO_VOLUME: - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; ctrl->value = max(chip->left,chip->right); return 0; case V4L2_CID_AUDIO_BALANCE: { int volume; - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; volume = max(chip->left,chip->right); if (volume) @@ -1621,7 +1621,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip, { int volume,balance; - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; volume = max(chip->left,chip->right); @@ -1642,7 +1642,7 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip, case V4L2_CID_AUDIO_BALANCE: { int volume, balance; - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) break; volume = max(chip->left,chip->right); @@ -1702,7 +1702,7 @@ static int chip_command(struct i2c_client *client, break; case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_BALANCE: - if (!desc->flags & CHIP_HAS_VOLUME) + if (!(desc->flags & CHIP_HAS_VOLUME)) return -EINVAL; break; case V4L2_CID_AUDIO_BASS: From 384b835aed8acf341d99969b58d27434685bdd3d Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 4 Feb 2008 20:52:21 -0300 Subject: [PATCH 257/880] V4L/DVB (7150): [v4l] convert videbuf_vmalloc_memory to videobuf_vmalloc_memory Signed-off-by: Brandon Philips Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-vmalloc.c | 16 +++++++--------- include/media/videobuf-vmalloc.h | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index 03b3b41cbb62..5266ecc91dab 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c @@ -107,7 +107,7 @@ static struct vm_operations_struct videobuf_vm_ops = static void *__videobuf_alloc(size_t size) { - struct videbuf_vmalloc_memory *mem; + struct videobuf_vmalloc_memory *mem; struct videobuf_buffer *vb; vb = kzalloc(size+sizeof(*mem),GFP_KERNEL); @@ -127,9 +127,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, struct v4l2_framebuffer *fbuf) { int pages; - - struct videbuf_vmalloc_memory *mem=vb->priv; - + struct videobuf_vmalloc_memory *mem=vb->priv; BUG_ON(!mem); @@ -195,7 +193,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) static int __videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) { - struct videbuf_vmalloc_memory *mem; + struct videobuf_vmalloc_memory *mem; struct videobuf_mapping *map; unsigned int first; int retval; @@ -267,7 +265,7 @@ static int __videobuf_copy_to_user ( struct videobuf_queue *q, char __user *data, size_t count, int nonblocking ) { - struct videbuf_vmalloc_memory *mem=q->read_buf->priv; + struct videobuf_vmalloc_memory *mem=q->read_buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); @@ -288,7 +286,7 @@ static int __videobuf_copy_stream ( struct videobuf_queue *q, int vbihack, int nonblocking ) { unsigned int *fc; - struct videbuf_vmalloc_memory *mem=q->read_buf->priv; + struct videobuf_vmalloc_memory *mem=q->read_buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); @@ -341,7 +339,7 @@ EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init); void *videobuf_to_vmalloc (struct videobuf_buffer *buf) { - struct videbuf_vmalloc_memory *mem=buf->priv; + struct videobuf_vmalloc_memory *mem=buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); @@ -351,7 +349,7 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc); void videobuf_vmalloc_free (struct videobuf_buffer *buf) { - struct videbuf_vmalloc_memory *mem=buf->priv; + struct videobuf_vmalloc_memory *mem=buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h index 26a8958d23d1..ec63ab0fab93 100644 --- a/include/media/videobuf-vmalloc.h +++ b/include/media/videobuf-vmalloc.h @@ -17,7 +17,7 @@ /* --------------------------------------------------------------------- */ -struct videbuf_vmalloc_memory +struct videobuf_vmalloc_memory { u32 magic; From 1685a6fed210b110ac8abeff24e2ffd1713cb3fb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 5 Feb 2008 07:37:21 -0300 Subject: [PATCH 258/880] V4L/DVB (7156): em28xx/em28xx-core.c: fix use of potentially uninitialized variable drivers/media/video/em28xx/em28xx-core.c: In function 'em28xx_set_audio_source': drivers/media/video/em28xx/em28xx-core.c:276: warning: 'no_ac97' may be used uninitialized in this function This looks like a genuine bug to me. Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 41ed4be4ae01..33d323cbce7a 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -273,7 +273,8 @@ int em28xx_set_audio_source(struct em28xx *dev) static char *enable = "\x08\x08"; static char *disable = "\x08\x88"; char *video = enable, *line = disable; - int ret, no_ac97; + int ret; + int no_ac97 = 0; u8 input; if (dev->is_em2800) { From 7463dda2ae868d3e0a6c98f65d6331481fc73ca3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Feb 2008 22:29:26 -0300 Subject: [PATCH 259/880] V4L/DVB (7158): Fix em28xx audio initialization AC97 register initialization seem to always be needed. This patch fixes audio for Prolink/Pixelview USB2 board. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 6 +++--- drivers/media/video/em28xx/em28xx-core.c | 11 +++-------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index fc160772930c..aae7753fef11 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -393,15 +393,15 @@ struct em28xx_board em28xx_boards[] = { .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = SAA7115_COMPOSITE2, - .amux = 1, + .amux = EM28XX_AMUX_LINE_IN, }, { .type = EM28XX_VMUX_COMPOSITE1, .vmux = SAA7115_COMPOSITE0, - .amux = 1, + .amux = EM28XX_AMUX_LINE_IN, }, { .type = EM28XX_VMUX_SVIDEO, .vmux = SAA7115_SVIDEO3, - .amux = 1, + .amux = EM28XX_AMUX_LINE_IN, } }, }, }; diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 33d323cbce7a..4ffb8d0bc52a 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -274,7 +274,6 @@ int em28xx_set_audio_source(struct em28xx *dev) static char *disable = "\x08\x88"; char *video = enable, *line = disable; int ret; - int no_ac97 = 0; u8 input; if (dev->is_em2800) { @@ -294,11 +293,9 @@ int em28xx_set_audio_source(struct em28xx *dev) switch (dev->ctl_ainput) { case EM28XX_AMUX_VIDEO: input = EM28XX_AUDIO_SRC_TUNER; - no_ac97 = 1; break; case EM28XX_AMUX_LINE_IN: input = EM28XX_AUDIO_SRC_LINE; - no_ac97 = 1; break; case EM28XX_AMUX_AC97_VIDEO: input = EM28XX_AUDIO_SRC_LINE; @@ -315,11 +312,9 @@ int em28xx_set_audio_source(struct em28xx *dev) if (ret < 0) return ret; - if (no_ac97) - return 0; - - /* Sets AC97 mixer registers */ - + /* Sets AC97 mixer registers + This is seems to be needed, even for non-ac97 configs + */ ret = em28xx_write_ac97(dev, VIDEO_AC97, video); if (ret < 0) return ret; From 1e7ad56f1fef94a7d8c1050bf3548d957fe67c01 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 09:00:41 -0300 Subject: [PATCH 260/880] V4L/DVB (7160): em28xx: Allow register dump/setting for debug Adds vidioc_[g|s]_register handlers. This allows getting/setting register from em28xx. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-video.c | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index c4126055bec3..4c836ad5cf41 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -830,6 +830,64 @@ static int vidioc_s_frequency(struct file *file, void *priv, return 0; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int em28xx_reg_len(int reg) +{ + switch (reg) { + case AC97LSB_REG: + case HSCALELOW_REG: + case VSCALELOW_REG: + + return 2; + default: + return 1; + } +} + +static int vidioc_g_register(struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct em28xx_fh *fh = priv; + struct em28xx *dev = fh->dev; + int ret; + + if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return -EINVAL; + + if (em28xx_reg_len(reg->reg) == 1) { + ret = em28xx_read_reg(dev, reg->reg); + if (ret < 0) + return ret; + + reg->val = ret; + } else { + u16 val; + ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, + reg->reg, (char *)&val, 2); + if (ret < 0) + return ret; + + reg->val = val; + } + + return 0; +} + +static int vidioc_s_register(struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct em28xx_fh *fh = priv; + struct em28xx *dev = fh->dev; + u16 buf; + + buf = be16_to_cpu((__u16)reg->val); + + return em28xx_write_regs(dev, reg->reg, (char *)&buf, + em28xx_reg_len(reg->reg)); +} +#endif + + static int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cc) { @@ -1730,6 +1788,10 @@ static const struct video_device em28xx_video_template = { .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vidioc_g_register, + .vidioc_s_register = vidioc_s_register, +#endif .tvnorms = V4L2_STD_ALL, .current_norm = V4L2_STD_PAL, @@ -1752,6 +1814,10 @@ static struct video_device em28xx_radio_template = { .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vidioc_g_register, + .vidioc_s_register = vidioc_s_register, +#endif }; /******************************** usb interface *****************************************/ From 0da5176f4e0d5aea3e33a11a17c1847939df4dcc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 15:55:19 -0300 Subject: [PATCH 261/880] V4L/DVB (7161): em28xx: Fix printing debug values higher than 127 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 4ffb8d0bc52a..6965bafe54a1 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -150,7 +150,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, if (reg_debug){ printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); for (byte = 0; byte < len; byte++) { - printk(" %02x", buf[byte]); + printk(" %02x", (unsigned char)buf[byte]); } printk("\n"); } @@ -177,7 +177,8 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) 0x0000, reg, &val, 1, HZ); if (reg_debug) - printk(ret < 0 ? " failed!\n" : "%02x\n", val); + printk(ret < 0 ? " failed!\n" : + "%02x\n", (unsigned char) val); if (ret < 0) return ret; From 0df8130fe80ebde052516c1d729aa5d1c69ebc5c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 15:56:16 -0300 Subject: [PATCH 262/880] V4L/DVB (7162): em28xx: Fix endian and returns the correct values Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 4c836ad5cf41..f69f591eeaf6 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -861,13 +861,13 @@ static int vidioc_g_register(struct file *file, void *priv, reg->val = ret; } else { - u16 val; + u64 val = 0; ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, reg->reg, (char *)&val, 2); if (ret < 0) return ret; - reg->val = val; + reg->val = cpu_to_le64((__u64)val); } return 0; @@ -878,9 +878,9 @@ static int vidioc_s_register(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - u16 buf; + u64 buf; - buf = be16_to_cpu((__u16)reg->val); + buf = le64_to_cpu((__u64)reg->val); return em28xx_write_regs(dev, reg->reg, (char *)&buf, em28xx_reg_len(reg->reg)); From 00b8730f5db19f9ea0985d7f14f869df79a0bf76 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 18:34:13 -0300 Subject: [PATCH 263/880] V4L/DVB (7163): em28xx: makes audio settings more stable Improves audio configurations on em28xx: - mutes audio before changing amux; - adds a delay after setting audio src; - waits up to 50ms for ac97 busy. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 28 ++++++++++++++++------- drivers/media/video/em28xx/em28xx-video.c | 3 +-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 6965bafe54a1..275f1e936304 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -255,21 +255,26 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, */ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) { - int ret; + int ret, i; u8 addr = reg & 0x7f; if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0) return ret; if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0) return ret; - if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) - return ret; - else if (((u8) ret) & 0x01) { - em28xx_warn ("AC97 command still being executed: not handled properly!\n"); + + /* Wait up to 50 ms for AC97 command to complete */ + for (i = 0; i < 10; i++) { + if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) + return ret; + if (!((u8) ret) & 0x01) + return 0; + msleep(5); } + em28xx_warn ("AC97 command still being executed: not handled properly!\n"); return 0; } -int em28xx_set_audio_source(struct em28xx *dev) +static int em28xx_set_audio_source(struct em28xx *dev) { static char *enable = "\x08\x08"; static char *disable = "\x08\x88"; @@ -312,6 +317,7 @@ int em28xx_set_audio_source(struct em28xx *dev) ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0); if (ret < 0) return ret; + msleep(5); /* Sets AC97 mixer registers This is seems to be needed, even for non-ac97 configs @@ -334,9 +340,10 @@ int em28xx_audio_analog_set(struct em28xx *dev) s[0] |= 0x1f - dev->volume; s[1] |= 0x1f - dev->volume; - if (dev->mute) - s[1] |= 0x80; + /* Mute */ + s[1] |= 0x80; ret = em28xx_write_ac97(dev, MASTER_AC97, s); + if (ret < 0) return ret; @@ -354,6 +361,11 @@ int em28xx_audio_analog_set(struct em28xx *dev) /* Selects the proper audio input */ ret = em28xx_set_audio_source(dev); + /* Unmute device */ + if (!dev->mute) + s[1] &= ~0x80; + ret = em28xx_write_ac97(dev, MASTER_AC97, s); + return ret; } EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index f69f591eeaf6..eeda3b2faec8 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -189,7 +189,7 @@ static void video_mux(struct em28xx *dev, int index) em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route); } - em28xx_set_audio_source(dev); + em28xx_audio_analog_set(dev); } /* Usage lock check functions */ @@ -837,7 +837,6 @@ static int em28xx_reg_len(int reg) case AC97LSB_REG: case HSCALELOW_REG: case VSCALELOW_REG: - return 2; default: return 1; From 92ea42f442c4895e38f525a097d7d8ce2a55b9b9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Feb 2008 18:52:15 -0300 Subject: [PATCH 264/880] V4L/DVB (7164): em28xx-alsa: Add a missing mutex Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 5 +++++ drivers/media/video/em28xx/em28xx.h | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 2c7343d3139d..8c67f678266a 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -269,8 +269,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); /* Sets volume, mute, etc */ + dev->mute = 0; + mutex_lock(&dev->lock); ret = em28xx_audio_analog_set(dev); + mutex_unlock(&dev->lock); if (ret < 0) goto err; @@ -302,7 +305,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) dprintk("closing device\n"); dev->mute = 1; + mutex_lock(&dev->lock); em28xx_audio_analog_set(dev); + mutex_unlock(&dev->lock); if (dev->adev->users == 0 && dev->adev->shutdown == 1) { dprintk("audio users: %d\n", dev->adev->users); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 9759a7330a53..813c0af458d3 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -345,7 +345,6 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg); int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int len); int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); -int em28xx_set_audio_source(struct em28xx *dev); int em28xx_audio_analog_set(struct em28xx *dev); int em28xx_colorlevels_set_default(struct em28xx *dev); From 3687e1e67e4920a202d53cc24678fb34fcda8fc5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 8 Feb 2008 15:44:25 -0300 Subject: [PATCH 265/880] V4L/DVB (7179): Allow more than one em28xx board em28xx driver is capable of handling more than one usb device. However, isoc transfers require a large amount of data to be transfered. Before this patch, just one em28xx board were enough to allocate more than 50% URBs: T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8 B: Alloc=480/800 us (60%), #Int= 0, #Iso= 2 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 So, only one board could use an USB host at the same time. After the patch, it is possible to use more than one em28xx at the same time, on the same usb host, if the image size is slower or equal to 345600, since those images will require about 30% of the URBs: T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 8 B: Alloc=232/800 us (29%), #Int= 0, #Iso= 2 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 So, in thesis, after the patch, it would be possible to use up to 3 boards by each usb host, if the devices are generating small images. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 62 +++++++++++++++-------- drivers/media/video/em28xx/em28xx-video.c | 4 +- drivers/media/video/em28xx/em28xx.h | 2 +- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 275f1e936304..0966017ca745 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -72,7 +72,8 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count) const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ void *buff = NULL; u32 i; - em28xx_coredbg("requested %i buffers with size %zi", count, imagesize); + em28xx_coredbg("requested %i buffers with size %zi\n", + count, imagesize); if (count > EM28XX_NUM_FRAMES) count = EM28XX_NUM_FRAMES; @@ -676,7 +677,7 @@ static void em28xx_isocIrq(struct urb *urb) continue; } if (urb->iso_frame_desc[i].actual_length > - dev->max_pkt_size) { + urb->iso_frame_desc[i].length) { em28xx_isocdbg("packet bigger than packet size"); continue; } @@ -722,8 +723,11 @@ void em28xx_uninit_isoc(struct em28xx *dev) for (i = 0; i < EM28XX_NUM_BUFS; i++) { if (dev->urb[i]) { usb_kill_urb(dev->urb[i]); - if (dev->transfer_buffer[i]){ - usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma); + if (dev->transfer_buffer[i]) { + usb_buffer_free(dev->udev, + dev->urb[i]->transfer_buffer_length, + dev->transfer_buffer[i], + dev->urb[i]->transfer_dma); } usb_free_urb(dev->urb[i]); } @@ -741,7 +745,10 @@ int em28xx_init_isoc(struct em28xx *dev) { /* change interface to 3 which allows the biggest packet sizes */ int i, errCode; - const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; + int sb_size; + + em28xx_set_alternate(dev); + sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; /* reset streaming vars */ dev->frame_current = NULL; @@ -750,7 +757,7 @@ int em28xx_init_isoc(struct em28xx *dev) /* allocate urbs */ for (i = 0; i < EM28XX_NUM_BUFS; i++) { struct urb *urb; - int j, k; + int j; /* allocate transfer buffer */ urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL); if (!urb){ @@ -758,7 +765,9 @@ int em28xx_init_isoc(struct em28xx *dev) em28xx_uninit_isoc(dev); return -ENOMEM; } - dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma); + dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, + GFP_KERNEL, + &urb->transfer_dma); if (!dev->transfer_buffer[i]) { em28xx_errdev ("unable to allocate %i bytes for transfer buffer %i\n", @@ -777,16 +786,16 @@ int em28xx_init_isoc(struct em28xx *dev) urb->complete = em28xx_isocIrq; urb->number_of_packets = EM28XX_NUM_PACKETS; urb->transfer_buffer_length = sb_size; - for (j = k = 0; j < EM28XX_NUM_PACKETS; - j++, k += dev->max_pkt_size) { - urb->iso_frame_desc[j].offset = k; - urb->iso_frame_desc[j].length = - dev->max_pkt_size; + for (j = 0; j < EM28XX_NUM_PACKETS; j++) { + urb->iso_frame_desc[j].offset = j * dev->max_pkt_size; + urb->iso_frame_desc[j].length = dev->max_pkt_size; } dev->urb[i] = urb; } /* submit urbs */ + em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n", + EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size); for (i = 0; i < EM28XX_NUM_BUFS; i++) { errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); if (errCode) { @@ -803,22 +812,31 @@ int em28xx_init_isoc(struct em28xx *dev) int em28xx_set_alternate(struct em28xx *dev) { int errCode, prev_alt = dev->alt; - dev->alt = alt; - if (dev->alt == 0) { - int i; - for(i=0;i< dev->num_alt; i++) - if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt]) - dev->alt=i; - } + int i; + unsigned int min_pkt_size = dev->bytesperline+4; + + /* When image size is bigger than a ceirtain value, + the frame size should be increased, otherwise, only + green screen will be received. + */ + if (dev->frame_size > 720*240*2) + min_pkt_size *= 2; + + for (i = 0; i < dev->num_alt; i++) + if (dev->alt_max_pkt_size[i] >= min_pkt_size) + break; + dev->alt = i; if (dev->alt != prev_alt) { + em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", + min_pkt_size, dev->alt); dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; - em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt, - dev->max_pkt_size); + em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", + dev->alt, dev->max_pkt_size); errCode = usb_set_interface(dev->udev, 0, dev->alt); if (errCode < 0) { em28xx_errdev ("cannot change alternate number to %d (error=%i)\n", - dev->alt, errCode); + dev->alt, errCode); return errCode; } } diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index eeda3b2faec8..4abe6701a770 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1352,8 +1352,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) filp->private_data = fh; if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { - em28xx_set_alternate(dev); - dev->width = norm_maxw(dev); dev->height = norm_maxh(dev); dev->frame_size = dev->width * dev->height * 2; @@ -1362,6 +1360,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) dev->hscale = 0; dev->vscale = 0; + em28xx_set_alternate(dev); em28xx_capture_start(dev, 1); em28xx_resolution_set(dev); @@ -2129,6 +2128,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, snprintf(dev->name, 29, "em28xx #%d", nr); dev->devno = nr; dev->model = id->driver_info; + dev->alt = -1; /* Checks if audio is provided by some interface */ for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 813c0af458d3..04e0e48ecabe 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -33,7 +33,7 @@ #define UNSET -1 /* maximum number of em28xx boards */ -#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */ +#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ /* maximum number of frames that can be queued */ #define EM28XX_NUM_FRAMES 5 From 61b080d214c4dba91fb726169fb0c3f0e8de4b45 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 8 Feb 2008 16:07:04 -0300 Subject: [PATCH 266/880] V4L/DVB (7180): em28xx: add URB_NO_TRANSFER_DMA_MAP, since urb->transfer_dma is set Thanks to Alan Stern for pointing this issue. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 0966017ca745..7d1537cab867 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -780,7 +780,7 @@ int em28xx_init_isoc(struct em28xx *dev) urb->dev = dev->udev; urb->context = dev; urb->pipe = usb_rcvisocpipe(dev->udev, 0x82); - urb->transfer_flags = URB_ISO_ASAP; + urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = 1; urb->transfer_buffer = dev->transfer_buffer[i]; urb->complete = em28xx_isocIrq; From 83947d307d63dc0c30ab0809714f0bcbbdf8c3e2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 10 Feb 2008 20:13:25 -0300 Subject: [PATCH 267/880] V4L/DVB (7183): radio-si470x: fix build warning fix the following build warning: radio-si470x.c: In function 'si470x_get_rds_registers': radio-si470x.c:562: warning: format '%ld' expects type 'long int', but argument 3 has type 'unsigned int' Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 204577eb287b..d428c3aa2bf9 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -558,7 +558,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) (void *) &buf, sizeof(buf), &size, usb_timeout); if (size != sizeof(buf)) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " - "return size differs: %d != %ld\n", size, sizeof(buf)); + "return size differs: %d != %uld\n", size, sizeof(buf)); if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " "usb_interrupt_msg returned %d\n", retval); From ea75baf4b0f117564bd50827a49c4b14d61d24e9 Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Sat, 9 Feb 2008 23:54:24 -0300 Subject: [PATCH 268/880] V4L/DVB (7186): tda10086: make the 22kHz tone for DISEQC a config option Some cards need the diseqc signal modulated, while some just need the envelope to control the LNB supply. This fixes Bug 9887 Signed-off-by: Hartmut Hackmann Acked-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/ttusb2.c | 1 + drivers/media/dvb/frontends/tda10086.c | 28 ++++++++++++++++++----- drivers/media/dvb/frontends/tda10086.h | 3 +++ drivers/media/dvb/ttpci/budget.c | 1 + drivers/media/video/saa7134/saa7134-dvb.c | 5 ++-- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index 88dc4367a2e3..3b9da9c25c6e 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c @@ -144,6 +144,7 @@ static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff) static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 1, }; static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c index 9d26ace65151..0d2b69a99ad4 100644 --- a/drivers/media/dvb/frontends/tda10086.c +++ b/drivers/media/dvb/frontends/tda10086.c @@ -106,9 +106,12 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, static int tda10086_init(struct dvb_frontend* fe) { struct tda10086_state* state = fe->demodulator_priv; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; // reset tda10086_write_byte(state, 0x00, 0x00); msleep(10); @@ -158,7 +161,7 @@ static int tda10086_init(struct dvb_frontend* fe) tda10086_write_byte(state, 0x3d, 0x80); // setup SEC - tda10086_write_byte(state, 0x36, 0x80); // all SEC off, no 22k tone + tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // } @@ -180,16 +183,20 @@ static void tda10086_diseqc_wait(struct tda10086_state *state) static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { struct tda10086_state* state = fe->demodulator_priv; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + switch (tone) { case SEC_TONE_OFF: - tda10086_write_byte(state, 0x36, 0x80); + tda10086_write_byte(state, 0x36, t22k_off); break; case SEC_TONE_ON: - tda10086_write_byte(state, 0x36, 0x81); + tda10086_write_byte(state, 0x36, 0x01 + t22k_off); break; } @@ -202,9 +209,13 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe, struct tda10086_state* state = fe->demodulator_priv; int i; u8 oldval; + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + if (cmd->msg_len > 6) return -EINVAL; oldval = tda10086_read_byte(state, 0x36); @@ -212,7 +223,8 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe, for(i=0; i< cmd->msg_len; i++) { tda10086_write_byte(state, 0x48+i, cmd->msg[i]); } - tda10086_write_byte(state, 0x36, 0x88 | ((cmd->msg_len - 1) << 4)); + tda10086_write_byte(state, 0x36, (0x08 + t22k_off) + | ((cmd->msg_len - 1) << 4)); tda10086_diseqc_wait(state); @@ -225,16 +237,20 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic { struct tda10086_state* state = fe->demodulator_priv; u8 oldval = tda10086_read_byte(state, 0x36); + u8 t22k_off = 0x80; dprintk ("%s\n", __FUNCTION__); + if (state->config->diseqc_tone) + t22k_off = 0; + switch(minicmd) { case SEC_MINI_A: - tda10086_write_byte(state, 0x36, 0x84); + tda10086_write_byte(state, 0x36, 0x04 + t22k_off); break; case SEC_MINI_B: - tda10086_write_byte(state, 0x36, 0x86); + tda10086_write_byte(state, 0x36, 0x06 + t22k_off); break; } diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h index ed584a8f4a89..eeceaeee78ff 100644 --- a/drivers/media/dvb/frontends/tda10086.h +++ b/drivers/media/dvb/frontends/tda10086.h @@ -33,6 +33,9 @@ struct tda10086_config /* does the "inversion" need inverted? */ u8 invert; + + /* do we need the diseqc signal with carrier? */ + u8 diseqc_tone; }; #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 9268a82bada6..14b00f57b5de 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -351,6 +351,7 @@ static struct s5h1420_config s5h1420_config = { static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 1, }; static u8 read_pwm(struct budget* budget) diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index e58f437ea9f7..ea2be9eceeb8 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -841,6 +841,7 @@ static struct tda1004x_config ads_tech_duo_config = { static struct tda10086_config flydvbs = { .demod_address = 0x0e, .invert = 0, + .diseqc_tone = 0, }; /* ================================================================== @@ -955,9 +956,9 @@ static int dvb_init(struct saa7134_dev *dev) configure_tda827x_fe(dev, &tda827x_lifeview_config); break; case SAA7134_BOARD_FLYDVB_TRIO: - if(! use_frontend) { //terrestrial + if(! use_frontend) { /* terrestrial */ configure_tda827x_fe(dev, &lifeview_trio_config); - } else { //satellite + } else { /* satellite */ dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); if (dev->dvb.frontend) { if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, From 5caf51342c81c7cb2a8c3998e3f606ccfa79cee2 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Mon, 4 Feb 2008 22:26:08 -0300 Subject: [PATCH 269/880] V4L/DVB (7188): radio-si470x version 1.0.6 This patch combines all the finished discussions and its resulting patches from the mailing list. The version 1.0.6 is mainly influenced by Oliver Neukum. He found a lot of small issues, that are fixed with this patch now. For me the most interesting thing is, that it's now safer to use it on other architectures. The history for version 1.0.6 is: - fixed coverity checker warnings in *_usb_driver_disconnect - probe()/open() race by correct ordering in probe() - DMA coherency rules by separate allocation of all buffers - use of endianness macros - abuse of spinlock, replaced by mutex - racy handling of timer in disconnect, replaced by delayed_work - racy interruptible_sleep_on(), replaced with wait_event_interruptible() - handle signals in read() The driver is tested with all Debian/testing radio programs and rdsd. The patch is tested against checkpatch.pl v1.12. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 330 +++++++++++++++-------------- 1 file changed, 167 insertions(+), 163 deletions(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index d428c3aa2bf9..c72a9e7ad885 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -66,8 +66,21 @@ * Version 1.0.5 * - number of seek_retries changed to tune_timeout * - fixed problem with incomplete tune operations by own buffers - * - optimization of variables + * - optimization of variables and printf types * - improved error logging + * 2008-01-31 Tobias Lorenz + * Oliver Neukum + * Version 1.0.6 + * - fixed coverity checker warnings in *_usb_driver_disconnect + * - probe()/open() race by correct ordering in probe() + * - DMA coherency rules by separate allocation of all buffers + * - use of endianness macros + * - abuse of spinlock, replaced by mutex + * - racy handling of timer in disconnect, + * replaced by delayed_work + * - racy interruptible_sleep_on(), + * replaced with wait_event_interruptible() + * - handle signals in read() * * ToDo: * - add seeking support @@ -80,10 +93,10 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 5) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 6) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" -#define DRIVER_VERSION "1.0.5" +#define DRIVER_VERSION "1.0.6" /* kernel includes */ @@ -96,8 +109,10 @@ #include #include #include +#include #include #include +#include /* USB Device ID List */ @@ -409,10 +424,9 @@ struct si470x_device { unsigned short registers[RADIO_REGISTER_NUM]; /* RDS receive buffer */ - struct work_struct work; + struct delayed_work work; wait_queue_head_t read_queue; - struct timer_list timer; - spinlock_t lock; /* buffer locking */ + struct mutex lock; /* buffer locking */ unsigned char *buffer; /* size is always multiple of three */ unsigned int buf_size; unsigned int rd_index; @@ -494,7 +508,8 @@ static int si470x_get_register(struct si470x_device *radio, int regnr) retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); if (retval >= 0) - radio->registers[regnr] = (buf[1] << 8) | buf[2]; + radio->registers[regnr] = be16_to_cpu(get_unaligned( + (unsigned short *) &buf[1])); return (retval < 0) ? -EINVAL : 0; } @@ -509,8 +524,8 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) int retval; buf[0] = REGISTER_REPORT(regnr); - buf[1] = (radio->registers[regnr] & 0xff00) >> 8; - buf[2] = (radio->registers[regnr] & 0x00ff); + put_unaligned(cpu_to_be16(radio->registers[regnr]), + (unsigned short *) &buf[1]); retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); @@ -533,9 +548,9 @@ static int si470x_get_all_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) - radio->registers[regnr] = - (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - buf[regnr * RADIO_REGISTER_SIZE + 2]; + radio->registers[regnr] = be16_to_cpu(get_unaligned( + (unsigned short *) + &buf[regnr * RADIO_REGISTER_SIZE + 1])); return (retval < 0) ? -EINVAL : 0; } @@ -558,7 +573,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) (void *) &buf, sizeof(buf), &size, usb_timeout); if (size != sizeof(buf)) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_register: " - "return size differs: %d != %uld\n", size, sizeof(buf)); + "return size differs: %d != %zu\n", size, sizeof(buf)); if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " "usb_interrupt_msg returned %d\n", retval); @@ -566,8 +581,8 @@ static int si470x_get_rds_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) radio->registers[STATUSRSSI + regnr] = - (buf[regnr * RADIO_REGISTER_SIZE + 1] << 8) | - buf[regnr * RADIO_REGISTER_SIZE + 2]; + be16_to_cpu(get_unaligned((unsigned short *) + &buf[regnr * RADIO_REGISTER_SIZE + 1])); return (retval < 0) ? -EINVAL : 0; } @@ -600,7 +615,7 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) (!timed_out)); if (timed_out) printk(KERN_WARNING DRIVER_NAME - ": seek does not finish after %d ms\n", tune_timeout); + ": seek does not finish after %u ms\n", tune_timeout); /* stop tuning */ radio->registers[CHANNEL] &= ~CHANNEL_TUNE; @@ -763,6 +778,11 @@ static int si470x_rds_on(struct si470x_device *radio) */ static void si470x_rds(struct si470x_device *radio) { + unsigned char blocknum; + unsigned short bler; /* rds block errors */ + unsigned short rds; + unsigned char tmpbuf[3]; + /* get rds blocks */ if (si470x_get_rds_registers(radio) < 0) return; @@ -775,69 +795,58 @@ static void si470x_rds(struct si470x_device *radio) return; } - /* copy four RDS blocks to internal buffer */ - if (spin_trylock(&radio->lock)) { - unsigned char blocknum; - unsigned short bler; /* rds block errors */ - unsigned short rds; - unsigned char tmpbuf[3]; - unsigned char i; - - /* process each rds block */ - for (blocknum = 0; blocknum < 4; blocknum++) { - switch (blocknum) { - default: - bler = (radio->registers[STATUSRSSI] & - STATUSRSSI_BLERA) >> 9; - rds = radio->registers[RDSA]; - break; - case 1: - bler = (radio->registers[READCHAN] & - READCHAN_BLERB) >> 14; - rds = radio->registers[RDSB]; - break; - case 2: - bler = (radio->registers[READCHAN] & - READCHAN_BLERC) >> 12; - rds = radio->registers[RDSC]; - break; - case 3: - bler = (radio->registers[READCHAN] & - READCHAN_BLERD) >> 10; - rds = radio->registers[RDSD]; - break; - }; - - /* Fill the V4L2 RDS buffer */ - tmpbuf[0] = rds & 0x00ff; /* LSB */ - tmpbuf[1] = (rds & 0xff00) >> 8;/* MSB */ - tmpbuf[2] = blocknum; /* offset name */ - tmpbuf[2] |= blocknum << 3; /* received offset */ - if (bler > max_rds_errors) - tmpbuf[2] |= 0x80; /* uncorrectable errors */ - else if (bler > 0) - tmpbuf[2] |= 0x40; /* corrected error(s) */ - - /* copy RDS block to internal buffer */ - for (i = 0; i < 3; i++) { - radio->buffer[radio->wr_index] = tmpbuf[i]; - radio->wr_index++; - } - - /* wrap write pointer */ - if (radio->wr_index >= radio->buf_size) - radio->wr_index = 0; - - /* check for overflow */ - if (radio->wr_index == radio->rd_index) { - /* increment and wrap read pointer */ - radio->rd_index += 3; - if (radio->rd_index >= radio->buf_size) - radio->rd_index = 0; - } + /* copy all four RDS blocks to internal buffer */ + mutex_lock(&radio->lock); + for (blocknum = 0; blocknum < 4; blocknum++) { + switch (blocknum) { + default: + bler = (radio->registers[STATUSRSSI] & + STATUSRSSI_BLERA) >> 9; + rds = radio->registers[RDSA]; + break; + case 1: + bler = (radio->registers[READCHAN] & + READCHAN_BLERB) >> 14; + rds = radio->registers[RDSB]; + break; + case 2: + bler = (radio->registers[READCHAN] & + READCHAN_BLERC) >> 12; + rds = radio->registers[RDSC]; + break; + case 3: + bler = (radio->registers[READCHAN] & + READCHAN_BLERD) >> 10; + rds = radio->registers[RDSD]; + break; + }; + + /* Fill the V4L2 RDS buffer */ + put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf); + tmpbuf[2] = blocknum; /* offset name */ + tmpbuf[2] |= blocknum << 3; /* received offset */ + if (bler > max_rds_errors) + tmpbuf[2] |= 0x80; /* uncorrectable errors */ + else if (bler > 0) + tmpbuf[2] |= 0x40; /* corrected error(s) */ + + /* copy RDS block to internal buffer */ + memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3); + radio->wr_index += 3; + + /* wrap write pointer */ + if (radio->wr_index >= radio->buf_size) + radio->wr_index = 0; + + /* check for overflow */ + if (radio->wr_index == radio->rd_index) { + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; } - spin_unlock(&radio->lock); } + mutex_unlock(&radio->lock); /* wake up read queue */ if (radio->wr_index != radio->rd_index) @@ -845,30 +854,19 @@ static void si470x_rds(struct si470x_device *radio) } -/* - * si470x_timer - rds timer function - */ -static void si470x_timer(unsigned long data) -{ - struct si470x_device *radio = (struct si470x_device *) data; - - schedule_work(&radio->work); -} - - /* * si470x_work - rds work function */ static void si470x_work(struct work_struct *work) { struct si470x_device *radio = container_of(work, struct si470x_device, - work); + work.work); if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) return; si470x_rds(radio); - mod_timer(&radio->timer, jiffies + msecs_to_jiffies(rds_poll_time)); + schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time)); } @@ -885,49 +883,49 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; + unsigned int block_count = 0; /* switch on rds reception */ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { si470x_rds_on(radio); - schedule_work(&radio->work); + schedule_delayed_work(&radio->work, + msecs_to_jiffies(rds_poll_time)); } /* block if no new data available */ while (radio->wr_index == radio->rd_index) { if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; - interruptible_sleep_on(&radio->read_queue); + if (wait_event_interruptible(radio->read_queue, + radio->wr_index != radio->rd_index) < 0) + return -EINTR; } /* calculate block count from byte count */ count /= 3; /* copy RDS block out of internal buffer and to user buffer */ - if (spin_trylock(&radio->lock)) { - unsigned int block_count = 0; - while (block_count < count) { - if (radio->rd_index == radio->wr_index) - break; - - /* always transfer rds complete blocks */ - if (copy_to_user(buf, - &radio->buffer[radio->rd_index], 3)) - /* retval = -EFAULT; */ - break; + mutex_lock(&radio->lock); + while (block_count < count) { + if (radio->rd_index == radio->wr_index) + break; - /* increment and wrap read pointer */ - radio->rd_index += 3; - if (radio->rd_index >= radio->buf_size) - radio->rd_index = 0; + /* always transfer rds complete blocks */ + if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3)) + /* retval = -EFAULT; */ + break; - /* increment counters */ - block_count++; - buf += 3; - retval += 3; - } + /* increment and wrap read pointer */ + radio->rd_index += 3; + if (radio->rd_index >= radio->buf_size) + radio->rd_index = 0; - spin_unlock(&radio->lock); + /* increment counters */ + block_count++; + buf += 3; + retval += 3; } + mutex_unlock(&radio->lock); return retval; } @@ -944,7 +942,8 @@ static unsigned int si470x_fops_poll(struct file *file, /* switch on rds reception */ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { si470x_rds_on(radio); - schedule_work(&radio->work); + schedule_delayed_work(&radio->work, + msecs_to_jiffies(rds_poll_time)); } poll_wait(file, &radio->read_queue, pts); @@ -984,8 +983,7 @@ static int si470x_fops_release(struct inode *inode, struct file *file) radio->users--; if (radio->users == 0) { /* stop rds reception */ - del_timer_sync(&radio->timer); - flush_scheduled_work(); + cancel_delayed_work_sync(&radio->work); /* cancel read processes */ wake_up_interruptible(&radio->read_queue); @@ -1362,73 +1360,82 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct si470x_device *radio; + int retval = -ENOMEM; - /* memory and interface allocations */ - radio = kmalloc(sizeof(struct si470x_device), GFP_KERNEL); + /* private data allocation */ + radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); if (!radio) - return -ENOMEM; + goto err_initial; + + /* video device allocation */ radio->videodev = video_device_alloc(); - if (!radio->videodev) { - kfree(radio); - return -ENOMEM; - } + if (!radio->videodev) + goto err_radio; + + /* initial configuration */ memcpy(radio->videodev, &si470x_viddev_template, sizeof(si470x_viddev_template)); radio->users = 0; radio->usbdev = interface_to_usbdev(intf); + mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); - if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { - printk(KERN_WARNING DRIVER_NAME - ": Could not register video device\n"); - video_device_release(radio->videodev); - kfree(radio); - return -EIO; - } - usb_set_intfdata(intf, radio); /* show some infos about the specific device */ - if (si470x_get_all_registers(radio) < 0) { - video_device_release(radio->videodev); - kfree(radio); - return -EIO; - } - printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4x ChipID=0x%4.4x\n", + retval = -EIO; + if (si470x_get_all_registers(radio) < 0) + goto err_all; + printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", radio->registers[DEVICEID], radio->registers[CHIPID]); /* check if firmware is current */ if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) - < RADIO_SW_VERSION_CURRENT) + < RADIO_SW_VERSION_CURRENT) { + printk(KERN_WARNING DRIVER_NAME + ": This driver is known to work with " + "firmware version %hu,\n", RADIO_SW_VERSION_CURRENT); + printk(KERN_WARNING DRIVER_NAME + ": but the device has firmware version %hu.\n", + radio->registers[CHIPID] & CHIPID_FIRMWARE); + printk(KERN_WARNING DRIVER_NAME + ": If you have some trouble using this driver,\n"); printk(KERN_WARNING DRIVER_NAME - ": This driver is known to work with chip version %d, " - "but the device has firmware %d.\n" - DRIVER_NAME - "If you have some trouble using this driver, please " - "report to V4L ML at video4linux-list@redhat.com\n", - radio->registers[CHIPID] & CHIPID_FIRMWARE, - RADIO_SW_VERSION_CURRENT); + ": please report to V4L ML at " + "video4linux-list@redhat.com\n"); + } /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ - /* rds initialization */ + /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); - if (!radio->buffer) { - video_device_release(radio->videodev); - kfree(radio); - return -ENOMEM; - } + if (!radio->buffer) + goto err_all; + + /* rds buffer configuration */ radio->wr_index = 0; radio->rd_index = 0; init_waitqueue_head(&radio->read_queue); - /* prepare polling via eventd */ - INIT_WORK(&radio->work, si470x_work); - init_timer(&radio->timer); - radio->timer.function = si470x_timer; - radio->timer.data = (unsigned long) radio; + /* prepare rds work function */ + INIT_DELAYED_WORK(&radio->work, si470x_work); + + /* register video device */ + if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { + printk(KERN_WARNING DRIVER_NAME + ": Could not register video device\n"); + goto err_all; + } + usb_set_intfdata(intf, radio); return 0; +err_all: + video_device_release(radio->videodev); + kfree(radio->buffer); +err_radio: + kfree(radio); +err_initial: + return retval; } @@ -1439,14 +1446,11 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) { struct si470x_device *radio = usb_get_intfdata(intf); + cancel_delayed_work_sync(&radio->work); usb_set_intfdata(intf, NULL); - if (radio) { - del_timer_sync(&radio->timer); - flush_scheduled_work(); - video_unregister_device(radio->videodev); - kfree(radio->buffer); - kfree(radio); - } + video_unregister_device(radio->videodev); + kfree(radio->buffer); + kfree(radio); } From 57566ad2d83f58c02e191aa7f4d7cddad3f92618 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Sat, 9 Feb 2008 16:08:24 -0300 Subject: [PATCH 270/880] V4L/DVB (7189): autosuspend support Together with Oliver Neukum from Novell, USB autosuspend support was added. Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 83 +++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index c72a9e7ad885..649f14d2c013 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -81,6 +81,10 @@ * - racy interruptible_sleep_on(), * replaced with wait_event_interruptible() * - handle signals in read() + * 2008-02-08 Tobias Lorenz + * Oliver Neukum + * Version 1.0.7 + * - usb autosuspend support * * ToDo: * - add seeking support @@ -415,6 +419,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*"); struct si470x_device { /* reference to USB and video device */ struct usb_device *usbdev; + struct usb_interface *intf; struct video_device *videodev; /* driver management */ @@ -762,9 +767,17 @@ static int si470x_stop(struct si470x_device *radio) */ static int si470x_rds_on(struct si470x_device *radio) { + int retval; + /* sysconfig 1 */ + mutex_lock(&radio->lock); radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS; - return si470x_set_register(radio, SYSCONFIG1); + retval = si470x_set_register(radio, SYSCONFIG1); + if (retval < 0) + radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; + mutex_unlock(&radio->lock); + + return retval; } @@ -961,10 +974,22 @@ static unsigned int si470x_fops_poll(struct file *file, static int si470x_fops_open(struct inode *inode, struct file *file) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; radio->users++; - if (radio->users == 1) - return si470x_start(radio); + + retval = usb_autopm_get_interface(radio->intf); + if (retval < 0) { + radio->users--; + return -EIO; + } + + if (radio->users == 1) { + retval = si470x_start(radio); + if (retval < 0) + usb_autopm_put_interface(radio->intf); + return retval; + } return 0; } @@ -976,6 +1001,7 @@ static int si470x_fops_open(struct inode *inode, struct file *file) static int si470x_fops_release(struct inode *inode, struct file *file) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval; if (!radio) return -ENODEV; @@ -988,7 +1014,9 @@ static int si470x_fops_release(struct inode *inode, struct file *file) /* cancel read processes */ wake_up_interruptible(&radio->read_queue); - return si470x_stop(radio); + retval = si470x_stop(radio); + usb_autopm_put_interface(radio->intf); + return retval; } return 0; @@ -1377,6 +1405,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, sizeof(si470x_viddev_template)); radio->users = 0; radio->usbdev = interface_to_usbdev(intf); + radio->intf = intf; mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); @@ -1439,6 +1468,41 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, } +/* + * si470x_usb_driver_suspend - suspend the device + */ +static int si470x_usb_driver_suspend(struct usb_interface *intf, + pm_message_t message) +{ + struct si470x_device *radio = usb_get_intfdata(intf); + + printk(KERN_INFO DRIVER_NAME ": suspending now...\n"); + + cancel_delayed_work_sync(&radio->work); + + return 0; +} + + +/* + * si470x_usb_driver_resume - resume the device + */ +static int si470x_usb_driver_resume(struct usb_interface *intf) +{ + struct si470x_device *radio = usb_get_intfdata(intf); + + printk(KERN_INFO DRIVER_NAME ": resuming now...\n"); + + mutex_lock(&radio->lock); + if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) + schedule_delayed_work(&radio->work, + msecs_to_jiffies(rds_poll_time)); + mutex_unlock(&radio->lock); + + return 0; +} + + /* * si470x_usb_driver_disconnect - disconnect the device */ @@ -1458,10 +1522,13 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) * si470x_usb_driver - usb driver interface */ static struct usb_driver si470x_usb_driver = { - .name = DRIVER_NAME, - .probe = si470x_usb_driver_probe, - .disconnect = si470x_usb_driver_disconnect, - .id_table = si470x_usb_driver_id_table, + .name = DRIVER_NAME, + .probe = si470x_usb_driver_probe, + .disconnect = si470x_usb_driver_disconnect, + .suspend = si470x_usb_driver_suspend, + .resume = si470x_usb_driver_resume, + .id_table = si470x_usb_driver_id_table, + .supports_autosuspend = 1, }; From f0ba356c85c25c2732098885a6a089be4698da94 Mon Sep 17 00:00:00 2001 From: Adrian Pardini Date: Mon, 11 Feb 2008 12:40:53 -0300 Subject: [PATCH 271/880] V4L/DVB (7192): Adds support for Genius TVGo A11MCE Signed-off-by: Adrian Pardini Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 1 + drivers/media/common/ir-keymaps.c | 46 +++++++++++++++++++++ drivers/media/video/saa7134/saa7134-cards.c | 39 +++++++++++++++++ drivers/media/video/saa7134/saa7134-input.c | 6 +++ drivers/media/video/saa7134/saa7134.h | 1 + include/media/ir-common.h | 1 + 6 files changed, 94 insertions(+) diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 1074925fb201..0424901ebc78 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -130,3 +130,4 @@ 129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093] 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193] 131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] +132 -> Genius TVGO AM11MCE diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index a4a937c90534..2ab5a120470d 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c @@ -1987,3 +1987,49 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_behold); + +/* + * Remote control for the Genius TVGO A11MCE + * Adrian Pardini + */ +IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = { + /* Keys 0 to 9 */ + [0x48] = KEY_0, + [0x09] = KEY_1, + [0x1d] = KEY_2, + [0x1f] = KEY_3, + [0x19] = KEY_4, + [0x1b] = KEY_5, + [0x11] = KEY_6, + [0x17] = KEY_7, + [0x12] = KEY_8, + [0x16] = KEY_9, + + [0x54] = KEY_RECORD, /* recording */ + [0x06] = KEY_MUTE, /* mute */ + [0x10] = KEY_POWER, + [0x40] = KEY_LAST, /* recall */ + [0x4c] = KEY_CHANNELUP, /* channel / program + */ + [0x00] = KEY_CHANNELDOWN, /* channel / program - */ + [0x0d] = KEY_VOLUMEUP, + [0x15] = KEY_VOLUMEDOWN, + [0x4d] = KEY_OK, /* also labeled as Pause */ + [0x1c] = KEY_ZOOM, /* full screen and Stop*/ + [0x02] = KEY_MODE, /* AV Source or Rewind*/ + [0x04] = KEY_LIST, /* -/-- */ + /* small arrows above numbers */ + [0x1a] = KEY_NEXT, /* also Fast Forward */ + [0x0e] = KEY_PREVIOUS, /* also Rewind */ + /* these are in a rather non standard layout and have + an alternate name written */ + [0x1e] = KEY_UP, /* Video Setting */ + [0x0a] = KEY_DOWN, /* Video Default */ + [0x05] = KEY_LEFT, /* Snapshot */ + [0x0c] = KEY_RIGHT, /* Hide Panel */ + /* Four buttons without label */ + [0x49] = KEY_RED, + [0x0b] = KEY_GREEN, + [0x13] = KEY_YELLOW, + [0x50] = KEY_BLUE, +}; +EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce); diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index dcb601b803f9..262830da08c8 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3953,6 +3953,44 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x0200000, }, }, + [SAA7134_BOARD_GENIUS_TVGO_A11MCE] = { + /* Adrian Pardini */ + .name = "Genius TVGO AM11MCE", + .audio_clock = 0x00200000, + .tuner_type = TUNER_TNF_5335MF, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .gpiomask = 0xf000, + .inputs = {{ + .name = name_tv_mono, + .vmux = 1, + .amux = LINE2, + .gpio = 0x0000, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + .gpio = 0x2000, + .tv = 1 + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + .gpio = 0x2000, + } }, + .radio = { + .name = name_radio, + .amux = LINE2, + .gpio = 0x1000, + }, + .mute = { + .name = name_mute, + .amux = LINE2, + .gpio = 0x6000, + }, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -5054,6 +5092,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_BEHOLD_409: case SAA7134_BOARD_BEHOLD_505FM: case SAA7134_BOARD_BEHOLD_507_9FM: + case SAA7134_BOARD_GENIUS_TVGO_A11MCE: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 0db955c2d9b9..b4188819782f 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -406,6 +406,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keyup = 0x8000000; polling = 50; //ms break; + case SAA7134_BOARD_GENIUS_TVGO_A11MCE: + ir_codes = ir_codes_genius_tvgo_a11mce; + mask_keycode = 0xff; + mask_keydown = 0xf00000; + polling = 50; /* ms */ + break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 27fb44332215..f940d0254798 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -253,6 +253,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_607_9FM 129 #define SAA7134_BOARD_BEHOLD_M6 130 #define SAA7134_BOARD_TWINHAN_DTV_DVB_3056 131 +#define SAA7134_BOARD_GENIUS_TVGO_A11MCE 132 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 831547d79683..a4274203f252 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -142,6 +142,7 @@ extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE]; #endif From 968fb08912880e34a05a0cca7907392bac920aa2 Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Wed, 16 Jan 2008 19:56:55 -0300 Subject: [PATCH 272/880] V4L/DVB (7193): tveeprom: Add proper tuner mapping for hauppauge eeprom id 133 Do away with the need to set tuner=63 on cx88xx with recent HVR-1300 boards Signed-off-by: Ricardo Cerqueira Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tveeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 0b8fbad3c721..dc0da44a5af6 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -242,7 +242,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "TCL M2523_3DBH_E"}, { TUNER_ABSENT, "TCL M2523_3DIH_E"}, { TUNER_ABSENT, "TCL MFPE05_2_U"}, - { TUNER_ABSENT, "Philips FMD1216MEX"}, + { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216MEX"}, { TUNER_ABSENT, "Philips FRH2036B"}, { TUNER_ABSENT, "Panasonic ENGF75_01GF"}, { TUNER_ABSENT, "MaxLinear MXL5005"}, From 27d0fe189437803d5ad146d508ec2fd77252c73f Mon Sep 17 00:00:00 2001 From: Roland Stoll Date: Mon, 11 Feb 2008 13:00:34 -0300 Subject: [PATCH 273/880] V4L/DVB (7194): cx88-mpeg: Allow concurrent access to cx88-mpeg devices It currently isn't possible to open the frontend device of cx88-mpeg devices (DVB or Blackbird) multiple times concurrently. (for instance, to attach a signal monitoring tool while reading a stream, or to send a frequency change ioctl) This patch fixes that condition. Signed-off-by: Roland Stoll Signed-off-by: Ricardo Cerqueira Reviewed-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-mpeg.c | 16 ++++++++++++---- drivers/media/video/cx88/cx88.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 0aedbeaf94cd..f12733d6bf72 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -609,13 +609,19 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) struct cx88_core *core = drv->core; /* Fail a request for hardware if the device is busy. */ - if (core->active_type_id != CX88_BOARD_NONE) + if (core->active_type_id != CX88_BOARD_NONE && + core->active_type_id != drv->type_id) return -EBUSY; if (drv->advise_acquire) { - core->active_type_id = drv->type_id; - drv->advise_acquire(drv); + core->active_ref++; + mutex_lock(&drv->core->lock); + if (core->active_type_id == CX88_BOARD_NONE) { + core->active_type_id = drv->type_id; + drv->advise_acquire(drv); + } + mutex_unlock(&drv->core->lock); mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); } @@ -628,10 +634,12 @@ static int cx8802_request_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; - if (drv->advise_release) + if (drv->advise_release && --core->active_ref == 0) { + mutex_lock(&drv->core->lock); drv->advise_release(drv); core->active_type_id = CX88_BOARD_NONE; + mutex_unlock(&drv->core->lock); mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); } diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 4e823f2a539a..37e6d2e4002f 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -336,6 +336,7 @@ struct cx88_core { /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ struct cx8802_dev *dvbdev; enum cx88_board_type active_type_id; + int active_ref; }; struct cx8800_dev; From 691b4773aa556d0975dbc25c93e6c8b839dad325 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 13 Feb 2008 16:25:16 -0800 Subject: [PATCH 274/880] [SCSI] ses: fix data corruption one system: initrd get courrupted: RAMDISK: Compressed image found at block 0 RAMDISK: incomplete write (-28 != 2048) 134217728 crc error VFS: Mounted root (ext2 filesystem). Freeing unused kernel memory: 388k freed init_special_inode: bogus i_mode (177777) Warning: unable to open an initial console. init_special_inode: bogus i_mode (177777) init_special_inode: bogus i_mode (177777) Kernel panic - not syncing: No init found. Try passing init= option to kernel. bisected to commit 9927c68864e9c39cc317b4f559309ba29e642168 Author: James Bottomley Date: Sun Feb 3 15:48:56 2008 -0600 [SCSI] ses: add new Enclosure ULD changes: 1. change char to unsigned char to avoid type change later. 2. preserve len for page1 3. need to move desc_ptr even the entry is not enclosure_component_device/raid. so keep desc_ptr on right position 4. record page7 len, and double check if desc_ptr out of boundary before touch. 5. fix typo in subenclosure checking: should use hdr_buf instead. [jejb: style fixes] Signed-off-by: Yinghai Lu Signed-off-by: James Bottomley --- drivers/scsi/ses.c | 126 ++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index a57fed47b39d..a6d96694d0a5 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -33,9 +33,9 @@ #include struct ses_device { - char *page1; - char *page2; - char *page10; + unsigned char *page1; + unsigned char *page2; + unsigned char *page10; short page1_len; short page2_len; short page10_len; @@ -67,7 +67,7 @@ static int ses_probe(struct device *dev) static int ses_recv_diag(struct scsi_device *sdev, int page_code, void *buf, int bufflen) { - char cmd[] = { + unsigned char cmd[] = { RECEIVE_DIAGNOSTIC, 1, /* Set PCV bit */ page_code, @@ -85,7 +85,7 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code, { u32 result; - char cmd[] = { + unsigned char cmd[] = { SEND_DIAGNOSTIC, 0x10, /* Set PF bit */ 0, @@ -104,13 +104,13 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code, static int ses_set_page2_descriptor(struct enclosure_device *edev, struct enclosure_component *ecomp, - char *desc) + unsigned char *desc) { int i, j, count = 0, descriptor = ecomp->number; struct scsi_device *sdev = to_scsi_device(edev->cdev.dev); struct ses_device *ses_dev = edev->scratch; - char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; - char *desc_ptr = ses_dev->page2 + 8; + unsigned char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; + unsigned char *desc_ptr = ses_dev->page2 + 8; /* Clear everything */ memset(desc_ptr, 0, ses_dev->page2_len - 8); @@ -133,14 +133,14 @@ static int ses_set_page2_descriptor(struct enclosure_device *edev, return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len); } -static char *ses_get_page2_descriptor(struct enclosure_device *edev, +static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev, struct enclosure_component *ecomp) { int i, j, count = 0, descriptor = ecomp->number; struct scsi_device *sdev = to_scsi_device(edev->cdev.dev); struct ses_device *ses_dev = edev->scratch; - char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; - char *desc_ptr = ses_dev->page2 + 8; + unsigned char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; + unsigned char *desc_ptr = ses_dev->page2 + 8; ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len); @@ -160,17 +160,18 @@ static char *ses_get_page2_descriptor(struct enclosure_device *edev, static void ses_get_fault(struct enclosure_device *edev, struct enclosure_component *ecomp) { - char *desc; + unsigned char *desc; desc = ses_get_page2_descriptor(edev, ecomp); - ecomp->fault = (desc[3] & 0x60) >> 4; + if (desc) + ecomp->fault = (desc[3] & 0x60) >> 4; } static int ses_set_fault(struct enclosure_device *edev, struct enclosure_component *ecomp, enum enclosure_component_setting val) { - char desc[4] = {0 }; + unsigned char desc[4] = {0 }; switch (val) { case ENCLOSURE_SETTING_DISABLED: @@ -190,26 +191,28 @@ static int ses_set_fault(struct enclosure_device *edev, static void ses_get_status(struct enclosure_device *edev, struct enclosure_component *ecomp) { - char *desc; + unsigned char *desc; desc = ses_get_page2_descriptor(edev, ecomp); - ecomp->status = (desc[0] & 0x0f); + if (desc) + ecomp->status = (desc[0] & 0x0f); } static void ses_get_locate(struct enclosure_device *edev, struct enclosure_component *ecomp) { - char *desc; + unsigned char *desc; desc = ses_get_page2_descriptor(edev, ecomp); - ecomp->locate = (desc[2] & 0x02) ? 1 : 0; + if (desc) + ecomp->locate = (desc[2] & 0x02) ? 1 : 0; } static int ses_set_locate(struct enclosure_device *edev, struct enclosure_component *ecomp, enum enclosure_component_setting val) { - char desc[4] = {0 }; + unsigned char desc[4] = {0 }; switch (val) { case ENCLOSURE_SETTING_DISABLED: @@ -229,7 +232,7 @@ static int ses_set_active(struct enclosure_device *edev, struct enclosure_component *ecomp, enum enclosure_component_setting val) { - char desc[4] = {0 }; + unsigned char desc[4] = {0 }; switch (val) { case ENCLOSURE_SETTING_DISABLED: @@ -409,11 +412,11 @@ static int ses_intf_add(struct class_device *cdev, { struct scsi_device *sdev = to_scsi_device(cdev->dev); struct scsi_device *tmp_sdev; - unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr, - *addl_desc_ptr; + unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr = NULL, + *addl_desc_ptr = NULL; struct ses_device *ses_dev; u32 result; - int i, j, types, len, components = 0; + int i, j, types, len, page7_len = 0, components = 0; int err = -ENOMEM; struct enclosure_device *edev; struct ses_component *scomp = NULL; @@ -447,7 +450,7 @@ static int ses_intf_add(struct class_device *cdev, * traversal routines more complex */ sdev_printk(KERN_ERR, sdev, "FIXME driver has no support for subenclosures (%d)\n", - buf[1]); + hdr_buf[1]); goto err_free; } @@ -461,9 +464,8 @@ static int ses_intf_add(struct class_device *cdev, goto recv_failed; types = buf[10]; - len = buf[11]; - type_ptr = buf + 12 + len; + type_ptr = buf + 12 + buf[11]; for (i = 0; i < types; i++, type_ptr += 4) { if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE || @@ -494,22 +496,21 @@ static int ses_intf_add(struct class_device *cdev, /* The additional information page --- allows us * to match up the devices */ result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE); - if (result) - goto no_page10; - - len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; - buf = kzalloc(len, GFP_KERNEL); - if (!buf) - goto err_free; - - result = ses_recv_diag(sdev, 10, buf, len); - if (result) - goto recv_failed; - ses_dev->page10 = buf; - ses_dev->page10_len = len; - buf = NULL; + if (!result) { + + len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; + buf = kzalloc(len, GFP_KERNEL); + if (!buf) + goto err_free; + + result = ses_recv_diag(sdev, 10, buf, len); + if (result) + goto recv_failed; + ses_dev->page10 = buf; + ses_dev->page10_len = len; + buf = NULL; + } - no_page10: scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); if (!scomp) goto err_free; @@ -530,7 +531,7 @@ static int ses_intf_add(struct class_device *cdev, if (result) goto simple_populate; - len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; + page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; /* add 1 for trailing '\0' we'll use */ buf = kzalloc(len + 1, GFP_KERNEL); if (!buf) @@ -547,7 +548,8 @@ static int ses_intf_add(struct class_device *cdev, len = (desc_ptr[2] << 8) + desc_ptr[3]; /* skip past overall descriptor */ desc_ptr += len + 4; - addl_desc_ptr = ses_dev->page10 + 8; + if (ses_dev->page10) + addl_desc_ptr = ses_dev->page10 + 8; } type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; components = 0; @@ -557,29 +559,35 @@ static int ses_intf_add(struct class_device *cdev, struct enclosure_component *ecomp; if (desc_ptr) { - len = (desc_ptr[2] << 8) + desc_ptr[3]; - desc_ptr += 4; - /* Add trailing zero - pushes into - * reserved space */ - desc_ptr[len] = '\0'; - name = desc_ptr; + if (desc_ptr >= buf + page7_len) { + desc_ptr = NULL; + } else { + len = (desc_ptr[2] << 8) + desc_ptr[3]; + desc_ptr += 4; + /* Add trailing zero - pushes into + * reserved space */ + desc_ptr[len] = '\0'; + name = desc_ptr; + } } - if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE && - type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE) - continue; - ecomp = enclosure_component_register(edev, + if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE || + type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) { + + ecomp = enclosure_component_register(edev, components++, type_ptr[0], name); - if (desc_ptr) { - desc_ptr += len; - if (!IS_ERR(ecomp)) + + if (!IS_ERR(ecomp) && addl_desc_ptr) ses_process_descriptor(ecomp, addl_desc_ptr); - - if (addl_desc_ptr) - addl_desc_ptr += addl_desc_ptr[1] + 2; } + if (desc_ptr) + desc_ptr += len; + + if (addl_desc_ptr) + addl_desc_ptr += addl_desc_ptr[1] + 2; + } } kfree(buf); From cb84e2d2ff3b50c0da5a7604a6d8634294a00a01 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 15 Feb 2008 09:28:43 -0600 Subject: [PATCH 275/880] [SCSI] aic94xx: fix REQ_TASK_ABORT and REQ_DEVICE_RESET This driver has been failing under heavy load with aic94xx: escb_tasklet_complete: REQ_TASK_ABORT, reason=0x6 aic94xx: escb_tasklet_complete: Can't find task (tc=4) to abort! The second message is because the driver fails to identify the task it's being asked to abort. On closer inpection, there's a thinko in the for each task loop over pending tasks in both the REQ_TASK_ABORT and REQ_DEVICE_RESET cases where it doesn't look at the task on the pending list but at the one on the ESCB (which is always NULL). Fix by looking at the right task. Also add a print for the case where the pending SCB doesn't have a task attached. Not sure if this will fix all the problems, but it's a definite first step. Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_scb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 0febad4dd75f..ab350504ca5a 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c @@ -458,13 +458,19 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, tc_abort = le16_to_cpu(tc_abort); list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { - struct sas_task *task = ascb->uldd_task; + struct sas_task *task = a->uldd_task; + + if (a->tc_index != tc_abort) + continue; - if (task && a->tc_index == tc_abort) { + if (task) { failed_dev = task->dev; sas_task_abort(task); - break; + } else { + ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n", + a->scb->header.opcode); } + break; } if (!failed_dev) { @@ -478,7 +484,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, * that the EH will wake up and do something. */ list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { - struct sas_task *task = ascb->uldd_task; + struct sas_task *task = a->uldd_task; if (task && task->dev == failed_dev && From 2939deaab257924c9afd87575dbd9100ae08160d Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 17 Oct 2007 12:25:00 -0400 Subject: [PATCH 276/880] [SCSI] mpt fusion: kill warnings in mptbase.h on parisc64 Verified all the arches necessary select the CONFIG_64BIT symbol. This also kills the warning (since it was using the 32-bit case) on parisc64 and mips64. Signed-off-by: Kyle McMartin Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index d83ea96fe135..caadc68c3000 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -923,7 +923,7 @@ extern struct proc_dir_entry *mpt_proc_root_dir; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ -#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__) || defined(__powerpc__) +#ifdef CONFIG_64BIT #define CAST_U32_TO_PTR(x) ((void *)(u64)x) #define CAST_PTR_TO_U32(x) ((u32)(u64)x) #else From 7d1abbe82434d29dd0d7d69dc0e6acdf25a8c2b5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 8 Feb 2008 15:34:24 +0000 Subject: [PATCH 277/880] [SCSI] megaraid: outb_p extermination From conversations with the maintainers the _p isn't needed so kill it. That removes the last non ISA _p user from the SCSI layer to my knowledge. Signed-off-by: Alan Cox Acked-by: "Yang, Bo" Signed-off-by: James Bottomley --- drivers/scsi/megaraid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 4d59ae8491a4..b135a1ed4b2c 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -151,19 +151,19 @@ mega_setup_mailbox(adapter_t *adapter) */ if( adapter->flag & BOARD_IOMAP ) { - outb_p(adapter->mbox_dma & 0xFF, + outb(adapter->mbox_dma & 0xFF, adapter->host->io_port + MBOX_PORT0); - outb_p((adapter->mbox_dma >> 8) & 0xFF, + outb((adapter->mbox_dma >> 8) & 0xFF, adapter->host->io_port + MBOX_PORT1); - outb_p((adapter->mbox_dma >> 16) & 0xFF, + outb((adapter->mbox_dma >> 16) & 0xFF, adapter->host->io_port + MBOX_PORT2); - outb_p((adapter->mbox_dma >> 24) & 0xFF, + outb((adapter->mbox_dma >> 24) & 0xFF, adapter->host->io_port + MBOX_PORT3); - outb_p(ENABLE_MBOX_BYTE, + outb(ENABLE_MBOX_BYTE, adapter->host->io_port + ENABLE_MBOX_REGION); irq_ack(adapter); From 0e935c9ebacf2f54ab1226192d1a62f7ea1b9303 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 16 Feb 2008 15:53:21 -0600 Subject: [PATCH 278/880] [SCSI] fas216: fix up the previous fas216 commit Apparently the fix to [SCSI] fas216: Use scsi_eh API for REQUEST_SENSE invocation didn't show up in the final version sent to linus. Correct this omission. Cc: Russell King Signed-off-by: James Bottomley --- drivers/scsi/arm/fas216.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index 3e73e264972e..b65f4cf0eec9 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h @@ -313,7 +313,7 @@ typedef struct { /* miscellaneous */ int internal_done; /* flag to indicate request done */ - struct scsi_eh_save *ses; /* holds request sense restore info */ + struct scsi_eh_save ses; /* holds request sense restore info */ unsigned long magic_end; } FAS216_Info; From cbccc207128e8bbdb047f6c5fc261acf207749c1 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 16 Feb 2008 23:57:15 +0900 Subject: [PATCH 279/880] [SCSI] scsi_debug: disable clustering scsi_debug does at several places: for_each_sg(sdb->table.sgl, sg, sdb->table.nents, k) { kaddr = (unsigned char *) kmap_atomic(sg_page(sg), KM_USER0); We cannot do something like that with the clustering enabled (or we can use scsi_kmap_atomic_sg). Signed-off-by: FUJITA Tomonori Acked-by: Douglas Gilbert Signed-off-by: James Bottomley --- drivers/scsi/scsi_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 1541c174937a..d1777a9a9625 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -222,7 +222,7 @@ static struct scsi_host_template sdebug_driver_template = { .cmd_per_lun = 16, .max_sectors = 0xffff, .unchecked_isa_dma = 0, - .use_clustering = ENABLE_CLUSTERING, + .use_clustering = DISABLE_CLUSTERING, .module = THIS_MODULE, }; From 5e2f22d39ec29c33bc5a3a558ac545b952aab8b7 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 12 Feb 2008 15:55:48 -0600 Subject: [PATCH 280/880] [SCSI] aic7xx: mitigate HOST_MSG_LOOP invalid SCB ff panic The panic occurs if we get a MSGIN or MSGOUT for an unidentified SCB (meaning we didn't identify the outstanding command it was for). For MSGIN this is wrong because it could be an unsolicited negotiation MSGIN from the target. Still panic on unsolicited MSGOUT because this would represent a mistake in the negotiation phases. However, we should fix this as well. The specs say we should go to bus free for unexpected msgin. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 6d2ae641273c..64e62ce59c15 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -695,15 +695,16 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) scb_index = ahc_inb(ahc, SCB_TAG); scb = ahc_lookup_scb(ahc, scb_index); if (devinfo.role == ROLE_INITIATOR) { - if (scb == NULL) - panic("HOST_MSG_LOOP with " - "invalid SCB %x\n", scb_index); + if (bus_phase == P_MESGOUT) { + if (scb == NULL) + panic("HOST_MSG_LOOP with " + "invalid SCB %x\n", + scb_index); - if (bus_phase == P_MESGOUT) ahc_setup_initiator_msgout(ahc, &devinfo, scb); - else { + } else { ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN; ahc->msgin_index = 0; From 279e7f5425c5e6da6ca61b1d8576356a939789f9 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sat, 16 Feb 2008 15:24:41 +0900 Subject: [PATCH 281/880] [SCSI] qla2xxx: fix compile warning for printk format scsi/qla2xxx/qla_dfs.c: In function 'qla2x00_dfs_fce_show': scsi/qla2xxx/qla_dfs.c:26: warning: format '%llx' expects type 'long long unsigned int', but argument 3 has type 'uint64_t' Signed-off-by: FUJITA Tomonori Acked-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_dfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 1479c60441c8..2cd899bfe84b 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -23,7 +23,7 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused) mutex_lock(&ha->fce_mutex); seq_printf(s, "FCE Trace Buffer\n"); - seq_printf(s, "In Pointer = %llx\n\n", ha->fce_wr); + seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); seq_printf(s, "FCE Enable Registers\n"); seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", From ff83efacf2b77a1fe8942db6613825a4b80ee5e2 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 17 Feb 2008 11:24:51 -0600 Subject: [PATCH 282/880] [SCSI] gdth: don't call pci_free_consistent under spinlock The spinlock is held over too large a region: pscratch is a permanent address (it's allocated at boot time and never changes). All you need the smp lock for is mediating the scratch in use flag, so fix this by moving the spinlock into the case where we set the pscratch_busy flag to false. Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/gdth_proc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index de5773443c62..ce0228e26aec 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -694,15 +694,13 @@ static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr) { ulong flags; - spin_lock_irqsave(&ha->smp_lock, flags); - if (buf == ha->pscratch) { + spin_lock_irqsave(&ha->smp_lock, flags); ha->scratch_busy = FALSE; + spin_unlock_irqrestore(&ha->smp_lock, flags); } else { pci_free_consistent(ha->pdev, size, buf, paddr); } - - spin_unlock_irqrestore(&ha->smp_lock, flags); } #ifdef GDTH_IOCTL_PROC From c9fe1d6ba603ddc5f2ef0a6b84f9df2bb4c679f1 Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Tue, 12 Feb 2008 02:54:33 -0300 Subject: [PATCH 283/880] V4L/DVB (7195): xc5000: fix build error when built as module drivers/built-in.o: In function `set_type': tuner-core.c:(.text+0x8879d): undefined reference to `xc5000_attach' Signed-off-by: Tony Breeds Reviewed-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/xc5000.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb/frontends/xc5000.h b/drivers/media/dvb/frontends/xc5000.h index e0e84562aed1..32a5f1c86a16 100644 --- a/drivers/media/dvb/frontends/xc5000.h +++ b/drivers/media/dvb/frontends/xc5000.h @@ -45,7 +45,8 @@ struct xc5000_config { /* xc5000 callback command */ #define XC5000_TUNER_RESET 0 -#if defined(CONFIG_DVB_TUNER_XC5000) || defined(CONFIG_DVB_TUNER_XC5000_MODULE) +#if defined(CONFIG_DVB_TUNER_XC5000) || \ + (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE)) extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct xc5000_config *cfg); From 7c018804c0900e7be18507f1eb24e631aa9816ea Mon Sep 17 00:00:00 2001 From: Robert Fitzsimons Date: Wed, 13 Feb 2008 16:38:11 -0300 Subject: [PATCH 284/880] V4L/DVB (7197): bttv: Fix overlay divide error The initial work to convert the bttv driver to V4L2 "Partial conversion from V4L1 to V4L2" (e84619b17440ccca4e4db7583d126c4189b987e5), missed the line which set the appropriate overlay crop structure in the newly allocated bttv_buffer. This then causes a divide error in the bttv_calc_geo function. Signed-off-by: Robert Fitzsimons Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index d9ce9a48ef59..5404fcc5276d 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -2760,6 +2760,7 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) if (on) { fh->ov.tvnorm = btv->tvnorm; new = videobuf_pci_alloc(sizeof(*new)); + new->crop = btv->crop[!!fh->do_crop].rect; bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); } else { new = NULL; From 83db33a3e5c4200eaf5dec5b4883c0e73f468a3b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 13 Feb 2008 20:04:49 -0300 Subject: [PATCH 285/880] V4L/DVB (7198): V4L, include ioctl.h in videodev headers Fix compilation of user processes which includes videodev*.h but not includes linux/ioctl.h: v4l2ext_helper.c: In function 'process_ioctl': v4l2ext_helper.c:183: warning: implicit declaration of function '_IOWR' v4l2ext_helper.c:183: error: expected expression before 'struct' v4l2ext_helper.c:183: error: case label does not reduce to an integer constant Signed-off-by: Jiri Slaby Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev.h | 1 + include/linux/videodev2.h | 1 + 2 files changed, 2 insertions(+) diff --git a/include/linux/videodev.h b/include/linux/videodev.h index 52e3d5fd5be4..9385a566aed8 100644 --- a/include/linux/videodev.h +++ b/include/linux/videodev.h @@ -12,6 +12,7 @@ #ifndef __LINUX_VIDEODEV_H #define __LINUX_VIDEODEV_H +#include #include #if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 439474f24e34..17a80177a674 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -62,6 +62,7 @@ #define __user #include #endif +#include #include /* From 40ae91a758df916d7a5640fb2de20537ef7849fd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Feb 2008 01:52:48 -0300 Subject: [PATCH 286/880] V4L/DVB (7200): Fix FM firmware loading There's no need to load SCode table for FM. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tuner-xc2028.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c index f191f6a48070..50cf876f020f 100644 --- a/drivers/media/video/tuner-xc2028.c +++ b/drivers/media/video/tuner-xc2028.c @@ -754,6 +754,9 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, goto check_device; } + if (new_fw.type & FM) + goto check_device; + /* Load SCODE firmware, if exists */ tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); From baff6cdd3328e7b35c4e155d79105621812bceec Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Wed, 13 Feb 2008 22:41:15 -0300 Subject: [PATCH 287/880] V4L/DVB (7201): cx88-mpeg: Fix race condition in variable access There was a possible race condition in the increment/decrement of the active device references counter. Thanks to Trent Piepho (xyzzy@speakeasy.org) for bringing it up. Signed-off-by: Ricardo Cerqueira Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-mpeg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index f12733d6bf72..e357f415db06 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -615,8 +615,8 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) if (drv->advise_acquire) { - core->active_ref++; mutex_lock(&drv->core->lock); + core->active_ref++; if (core->active_type_id == CX88_BOARD_NONE) { core->active_type_id = drv->type_id; drv->advise_acquire(drv); @@ -634,14 +634,14 @@ static int cx8802_request_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; + mutex_lock(&drv->core->lock); if (drv->advise_release && --core->active_ref == 0) { - mutex_lock(&drv->core->lock); drv->advise_release(drv); core->active_type_id = CX88_BOARD_NONE; - mutex_unlock(&drv->core->lock); mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); } + mutex_unlock(&drv->core->lock); return 0; } From ea35e3a754b2ba5f712c3f4df55e426ae2e4d60a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Feb 2008 07:24:22 -0300 Subject: [PATCH 288/880] V4L/DVB (7205): tuner-xc2028 depends on FW_LOADER Signed-off-by: Paul Mundt Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 888dcadff710..11950698a2e7 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -98,7 +98,7 @@ if VIDEO_TUNER_CUSTOMIZE config TUNER_XC2028 tristate "XCeive xc2028/xc3028 tuners" - depends on I2C + depends on I2C && FW_LOADER default m if VIDEO_TUNER_CUSTOMIZE help Say Y here to include support for the xc2028/xc3028 tuners. From 6165894fb6293072848e5699f3fcbe88b7c60815 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Feb 2008 18:41:06 -0300 Subject: [PATCH 289/880] V4L/DVB (7219): zoran: Fix namespace conflicts with Zoran 'GPIO_MAX' enum Thanks to Martin Michlmayr for reporting this issue: The zoran driver fails to compile on the ARM Orion platform with: In file included from drivers/media/video/zoran_procfs.c:50: drivers/media/video/zoran.h:232: error: expected identifier before numeric constant The reason is that drivers/media/video/zoran.h defines an enum with GPIO_MAX in it, but Orion contains a #define GPIO_MAX 32 in include/asm-arm/arch-orion/orion.h Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran.h | 22 +++++++++++----------- drivers/media/video/zoran_device.c | 12 ++++++------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h index 937c4a616c0e..498a43c1f2b1 100644 --- a/drivers/media/video/zoran.h +++ b/drivers/media/video/zoran.h @@ -221,15 +221,15 @@ enum zoran_map_mode { }; enum gpio_type { - GPIO_JPEG_SLEEP = 0, - GPIO_JPEG_RESET, - GPIO_JPEG_FRAME, - GPIO_VID_DIR, - GPIO_VID_EN, - GPIO_VID_RESET, - GPIO_CLK_SEL1, - GPIO_CLK_SEL2, - GPIO_MAX, + ZR_GPIO_JPEG_SLEEP = 0, + ZR_GPIO_JPEG_RESET, + ZR_GPIO_JPEG_FRAME, + ZR_GPIO_VID_DIR, + ZR_GPIO_VID_EN, + ZR_GPIO_VID_RESET, + ZR_GPIO_CLK_SEL1, + ZR_GPIO_CLK_SEL2, + ZR_GPIO_MAX, }; enum gpcs_type { @@ -378,11 +378,11 @@ struct card_info { u32 jpeg_int; /* JPEG interrupt */ u32 vsync_int; /* VSYNC interrupt */ - s8 gpio[GPIO_MAX]; + s8 gpio[ZR_GPIO_MAX]; u8 gpcs[GPCS_MAX]; struct vfe_polarity vfe_pol; - u8 gpio_pol[GPIO_MAX]; + u8 gpio_pol[ZR_GPIO_MAX]; /* is the /GWS line conected? */ u8 gws_not_connected; diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index 68c7c505587e..f97c20692057 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c @@ -250,7 +250,7 @@ void jpeg_codec_sleep (struct zoran *zr, int sleep) { - GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep); if (!sleep) { dprintk(3, KERN_DEBUG @@ -277,9 +277,9 @@ jpeg_codec_reset (struct zoran *zr) 0); udelay(2); } else { - GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0); udelay(2); - GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1); udelay(2); } @@ -688,7 +688,7 @@ static inline void set_frame (struct zoran *zr, int val) { - GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val); + GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val); } static void @@ -704,8 +704,8 @@ set_videobus_dir (struct zoran *zr, GPIO(zr, 5, 1); break; default: - GPIO(zr, zr->card.gpio[GPIO_VID_DIR], - zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val); + GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR], + zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val); break; } } From 75c752e6c3147f596c13365b200b91d754b66f59 Mon Sep 17 00:00:00 2001 From: Andrew Sharp Date: Thu, 13 Dec 2007 16:16:42 -0800 Subject: [PATCH 290/880] [WATCHDOG] Add support for SB1 hardware watchdog Support watchdog timers built into SiByte MIPS SoCs. Signed-off-by: Andy Sharp Signed-off-by: Wim Van Sebroeck Cc: Ralf Baechle Signed-off-by: Andrew Morton --- drivers/watchdog/Kconfig | 13 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/sb_wdog.c | 353 +++++++++++++++++++++++++++++++++++++ 3 files changed, 367 insertions(+) create mode 100644 drivers/watchdog/sb_wdog.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index afcdc69e37d6..591e3f399114 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -633,6 +633,19 @@ config WDT_RM9K_GPI To compile this driver as a module, choose M here: the module will be called rm9k_wdt. +config SIBYTE_WDOG + tristate "Sibyte SoC hardware watchdog" + depends on CPU_SB1 + help + Watchdog driver for the built in watchdog hardware in Sibyte + SoC processors. There are apparently two watchdog timers + on such processors; this driver supports only the first one, + because currently Linux only supports exporting one watchdog + to userspace. + + To compile this driver as a loadable module, choose M here. + The module will be called sb_wdog. + config AR7_WDT tristate "TI AR7 Watchdog Timer" depends on AR7 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index ebc21146d40c..90e4bbffbbfd 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -92,6 +92,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o obj-$(CONFIG_INDYDOG) += indydog.o obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o +obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o obj-$(CONFIG_AR7_WDT) += ar7_wdt.o obj-$(CONFIG_TXX9_WDT) += txx9wdt.o diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c new file mode 100644 index 000000000000..b94431433695 --- /dev/null +++ b/drivers/watchdog/sb_wdog.c @@ -0,0 +1,353 @@ +/* + * Watchdog driver for SiByte SB1 SoCs + * + * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp + * + * This driver is intended to make the second of two hardware watchdogs + * on the Sibyte 12XX and 11XX SoCs available to the user. There are two + * such devices available on the SoC, but it seems that there isn't an + * enumeration class for watchdogs in Linux like there is for RTCs. + * The second is used rather than the first because it uses IRQ 1, + * thereby avoiding all that IRQ 0 problematic nonsense. + * + * I have not tried this driver on a 1480 processor; it might work + * just well enough to really screw things up. + * + * It is a simple timer, and there is an interrupt that is raised the + * first time the timer expires. The second time it expires, the chip + * is reset and there is no way to redirect that NMI. Which could + * be problematic in some cases where this chip is sitting on the HT + * bus and has just taken responsibility for providing a cache block. + * Since the reset can't be redirected to the external reset pin, it is + * possible that other HT connected processors might hang and not reset. + * For Linux, a soft reset would probably be even worse than a hard reset. + * There you have it. + * + * The timer takes 23 bits of a 64 bit register (?) as a count value, + * and decrements the count every microsecond, for a max value of + * 0x7fffff usec or about 8.3ish seconds. + * + * This watchdog borrows some user semantics from the softdog driver, + * in that if you close the fd, it leaves the watchdog running, unless + * you previously wrote a 'V' to the fd, in which case it disables + * the watchdog when you close the fd like some other drivers. + * + * Based on various other watchdog drivers, which are probably all + * loosely based on something Alan Cox wrote years ago. + * + * (c) Copyright 1996 Alan Cox , All Rights Reserved. + * http://www.redhat.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 1 or 2 as published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +/* + * set the initial count value of a timer + * + * wdog is the iomem address of the cfg register + */ +void sbwdog_set(char __iomem *wdog, unsigned long t) +{ + __raw_writeb(0, wdog - 0x10); + __raw_writeq(t & 0x7fffffUL, wdog); +} + +/* + * cause the timer to [re]load it's initial count and start counting + * all over again + * + * wdog is the iomem address of the cfg register + */ +void sbwdog_pet(char __iomem *wdog) +{ + __raw_writeb(__raw_readb(wdog) | 1, wdog); +} + +static unsigned long sbwdog_gate; /* keeps it to one thread only */ +static char __iomem *kern_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_0)); +static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1)); +static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ +static int expect_close; + +static struct watchdog_info ident = { + .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .identity = "SiByte Watchdog", +}; + +/* + * Allow only a single thread to walk the dog + */ +static int sbwdog_open(struct inode *inode, struct file *file) +{ + nonseekable_open(inode, file); + if (test_and_set_bit(0, &sbwdog_gate)) { + return -EBUSY; + } + __module_get(THIS_MODULE); + + /* + * Activate the timer + */ + sbwdog_set(user_dog, timeout); + __raw_writeb(1, user_dog); + + return 0; +} + +/* + * Put the dog back in the kennel. + */ +static int sbwdog_release(struct inode *inode, struct file *file) +{ + if (expect_close == 42) { + __raw_writeb(0, user_dog); + module_put(THIS_MODULE); + } else { + printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n", + ident.identity); + sbwdog_pet(user_dog); + } + clear_bit(0, &sbwdog_gate); + expect_close = 0; + + return 0; +} + +/* + * 42 - the answer + */ +static ssize_t sbwdog_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + int i; + + if (len) { + /* + * restart the timer + */ + expect_close = 0; + + for (i = 0; i != len; i++) { + char c; + + if (get_user(c, data + i)) { + return -EFAULT; + } + if (c == 'V') { + expect_close = 42; + } + } + sbwdog_pet(user_dog); + } + + return len; +} + +static int sbwdog_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret = -ENOTTY; + unsigned long time; + void __user *argp = (void __user *)arg; + int __user *p = argp; + + switch (cmd) { + case WDIOC_GETSUPPORT: + ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; + break; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + ret = put_user(0, p); + break; + + case WDIOC_SETTIMEOUT: + ret = get_user(time, p); + if (ret) { + break; + } + + time *= 1000000; + if (time > 0x7fffffUL) { + ret = -EINVAL; + break; + } + timeout = time; + sbwdog_set(user_dog, timeout); + sbwdog_pet(user_dog); + + case WDIOC_GETTIMEOUT: + /* + * get the remaining count from the ... count register + * which is 1*8 before the config register + */ + ret = put_user(__raw_readq(user_dog - 8) / 1000000, p); + break; + + case WDIOC_KEEPALIVE: + sbwdog_pet(user_dog); + ret = 0; + break; + } + return ret; +} + +/* + * Notifier for system down + */ +static int +sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf) +{ + if (code == SYS_DOWN || code == SYS_HALT) { + /* + * sit and sit + */ + __raw_writeb(0, user_dog); + __raw_writeb(0, kern_dog); + } + + return NOTIFY_DONE; +} + +static const struct file_operations sbwdog_fops = +{ + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = sbwdog_write, + .ioctl = sbwdog_ioctl, + .open = sbwdog_open, + .release = sbwdog_release, +}; + +static struct miscdevice sbwdog_miscdev = +{ + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &sbwdog_fops, +}; + +static struct notifier_block sbwdog_notifier = { + .notifier_call = sbwdog_notify_sys, +}; + +/* + * interrupt handler + * + * doesn't do a whole lot for user, but oh so cleverly written so kernel + * code can use it to re-up the watchdog, thereby saving the kernel from + * having to create and maintain a timer, just to tickle another timer, + * which is just so wrong. + */ +irqreturn_t sbwdog_interrupt(int irq, void *addr) +{ + unsigned long wd_init; + char *wd_cfg_reg = (char *)addr; + u8 cfg; + + cfg = __raw_readb(wd_cfg_reg); + wd_init = __raw_readq(wd_cfg_reg - 8) & 0x7fffff; + + /* + * if it's the second watchdog timer, it's for those users + */ + if (wd_cfg_reg == user_dog) { + printk(KERN_CRIT + "%s in danger of initiating system reset in %ld.%01ld seconds\n", + ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); + } else { + cfg |= 1; + } + + __raw_writeb(cfg, wd_cfg_reg); + + return IRQ_HANDLED; +} + +static int __init sbwdog_init(void) +{ + int ret; + + /* + * register a reboot notifier + */ + ret = register_reboot_notifier(&sbwdog_notifier); + if (ret) { + printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n", + ident.identity, ret); + return ret; + } + + /* + * get the resources + */ + ret = misc_register(&sbwdog_miscdev); + if (ret == 0) { + printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity, + timeout / 1000000, (timeout / 100000) % 10); + } + + ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, + ident.identity, (void *)user_dog); + if (ret) { + printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity, + ret); + misc_deregister(&sbwdog_miscdev); + } + + return ret; +} + +static void __exit sbwdog_exit(void) +{ + misc_deregister(&sbwdog_miscdev); +} + +module_init(sbwdog_init); +module_exit(sbwdog_exit); + +MODULE_AUTHOR("Andrew Sharp "); +MODULE_DESCRIPTION("SiByte Watchdog"); + +module_param(timeout, ulong, 0); +MODULE_PARM_DESC(timeout, + "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); + +/* + * example code that can be put in a platform code area to utilize the + * first watchdog timer for the kernels own purpose. + + void +platform_wd_setup(void) +{ + int ret; + + ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, + "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); + if (ret) { + printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n", + ret); + } +} + + + */ From 6ea8115bb6f359df4f45152f2b40e1d4d1891392 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 7 Jan 2008 19:08:49 +0100 Subject: [PATCH 291/880] [WATCHDOG] Convert mtx1 wdt to be a platform device and use generic GPIO API This patch converts the MTX-1 to be a platform device, use the available generic GPIO API for the MTX-1 board and register the miscdev alias. Signed-off-by: Florian Fainelli Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mtx-1_wdt.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 98451747d3cd..789831b3fa00 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -45,10 +45,13 @@ #include #include #include +#include + #include #include #include +#include #define MTX1_WDT_INTERVAL (5 * HZ) @@ -61,6 +64,7 @@ static struct { volatile int queue; int default_ticks; unsigned long inuse; + unsigned gpio; } mtx1_wdt_device; static void mtx1_wdt_trigger(unsigned long unused) @@ -73,7 +77,8 @@ static void mtx1_wdt_trigger(unsigned long unused) * toggle GPIO2_15 */ tmp = au_readl(GPIO2_DIR); - tmp = (tmp & ~(1<<15)) | ((~tmp) & (1<<15)); + tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | + ((~tmp) & (1 << mtx1_wdt_device.gpio)); au_writel (tmp, GPIO2_DIR); if (mtx1_wdt_device.queue && ticks) @@ -93,7 +98,7 @@ static void mtx1_wdt_start(void) { if (!mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 1; - au_writel (au_readl(GPIO2_DIR) | (u32)(1<<15), GPIO2_DIR); + gpio_set_value(mtx1_wdt_device.gpio, 1); mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); } mtx1_wdt_device.running++; @@ -103,7 +108,7 @@ static int mtx1_wdt_stop(void) { if (mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 0; - au_writel (au_readl(GPIO2_DIR) & ~((u32)(1<<15)), GPIO2_DIR); + gpio_set_value(mtx1_wdt_device.gpio, 0); } ticks = mtx1_wdt_device.default_ticks; @@ -197,10 +202,12 @@ static struct miscdevice mtx1_wdt_misc = { }; -static int __init mtx1_wdt_init(void) +static int mtx1_wdt_probe(struct platform_device *pdev) { int ret; + mtx1_wdt_device.gpio = pdev->resource[0].start; + if ((ret = misc_register(&mtx1_wdt_misc)) < 0) { printk(KERN_ERR " mtx-1_wdt : failed to register\n"); return ret; @@ -222,13 +229,30 @@ static int __init mtx1_wdt_init(void) return 0; } -static void __exit mtx1_wdt_exit(void) +static int mtx1_wdt_remove(struct platform_device *pdev) { if (mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 0; wait_for_completion(&mtx1_wdt_device.stop); } misc_deregister(&mtx1_wdt_misc); + return 0; +} + +static struct platform_driver mtx1_wdt = { + .probe = mtx1_wdt_probe, + .remove = mtx1_wdt_remove, + .driver.name = "mtx1-wdt", +}; + +static int __init mtx1_wdt_init(void) +{ + return platform_driver_register(&mtx1_wdt); +} + +static void __exit mtx1_wdt_exit(void) +{ + platform_driver_unregister(&mtx1_wdt); } module_init(mtx1_wdt_init); @@ -237,3 +261,4 @@ module_exit(mtx1_wdt_exit); MODULE_AUTHOR("Michael Stickel, Florian Fainelli"); MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); From bb59b5578a73d0e0e4e208a014fa7ea0c4f0ccb4 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 30 Jan 2008 17:38:21 +0800 Subject: [PATCH 292/880] [WATCHDOG] blackfin Watchdog driver: relocate all strings used in __init functions to __initdata Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/bfin_wdt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 472be10f0686..1237113dc14a 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c @@ -29,6 +29,7 @@ #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) #define stampit() stamp("here i am") +#define pr_init(fmt, args...) ({ static const __initdata char __fmt[] = fmt; printk(__fmt, ## args); }) #define WATCHDOG_NAME "bfin-wdt" #define PFX WATCHDOG_NAME ": " @@ -445,19 +446,19 @@ static int __init bfin_wdt_init(void) ret = register_reboot_notifier(&bfin_wdt_notifier); if (ret) { - printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); + pr_init(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); return ret; } ret = misc_register(&bfin_wdt_miscdev); if (ret) { - printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", + pr_init(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); unregister_reboot_notifier(&bfin_wdt_notifier); return ret; } - printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n", + pr_init(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n", timeout, nowayout); return 0; From 7f4da4745c34287938ce76b92b23409adeecb5b8 Mon Sep 17 00:00:00 2001 From: Thomas Mingarelli Date: Tue, 4 Dec 2007 17:41:54 +0000 Subject: [PATCH 293/880] [WATCHDOG] HP ProLiant WatchDog driver Hp is providing a Hardware WatchDog Timer driver that will only work with the specific HW Timer located in the HP ProLiant iLO 2 ASIC. The iLO 2 HW Timer will generate a Non-maskable Interrupt (NMI) 9 seconds before physically resetting the server, by removing power, so that the event can be logged to the HP Integrated Management Log (IML), a Non-Volatile Random Access Memory (NVRAM). The logging of the event is performed using the HP ProLiant ROM via an Industry Standard access known as a BIOS Service Directory Entry. Signed-off-by: Thomas Mingarelli Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 12 + drivers/watchdog/Makefile | 1 + drivers/watchdog/hpwdt.c | 926 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 939 insertions(+) create mode 100644 drivers/watchdog/hpwdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 591e3f399114..254d115cafab 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -402,6 +402,18 @@ config IT8712F_WDT To compile this driver as a module, choose M here: the module will be called it8712f_wdt. +config HP_WATCHDOG + tristate "HP Proliant iLO 2 Hardware Watchdog Timer" + depends on X86 + help + A software monitoring watchdog and NMI sourcing driver. This driver + will detect lockups and provide stack trace. Also, when an NMI + occurs this driver will make the necessary BIOS calls to log + the cause of the NMI. This is a driver that will only load on a + HP ProLiant system with a minimum of iLO2 support. + To compile this driver as a module, choose M here: the + module will be called hpwdt. + config SC1200_WDT tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" depends on X86 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 90e4bbffbbfd..f3fb170fe5c6 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o +obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c new file mode 100644 index 000000000000..a2e174b09fe7 --- /dev/null +++ b/drivers/watchdog/hpwdt.c @@ -0,0 +1,926 @@ +/* + * HP WatchDog Driver + * based on + * + * SoftDog 0.05: A Software Watchdog Device + * + * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. + * Thomas Mingarelli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ +#define CRU_BIOS_SIGNATURE_VALUE 0x55524324 +#define PCI_BIOS32_PARAGRAPH_LEN 16 +#define PCI_ROM_BASE1 0x000F0000 +#define ROM_SIZE 0x10000 + +struct bios32_service_dir { + u32 signature; + u32 entry_point; + u8 revision; + u8 length; + u8 checksum; + u8 reserved[5]; +}; + +/* + * smbios_entry_point - defines SMBIOS entry point structure + * + * anchor[4] - anchor string (_SM_) + * checksum - checksum of the entry point structure + * length - length of the entry point structure + * major_ver - major version (02h for revision 2.1) + * minor_ver - minor version (01h for revision 2.1) + * max_struct_size - size of the largest SMBIOS structure + * revision - entry point structure revision implemented + * formatted_area[5] - reserved + * intermediate_anchor[5] - intermediate anchor string (_DMI_) + * intermediate_checksum - intermediate checksum + * table_length - structure table length + * table_address - structure table address + * table_num_structs - number of SMBIOS structures present + * bcd_revision - BCD revision + */ +struct smbios_entry_point { + u8 anchor[4]; + u8 checksum; + u8 length; + u8 major_ver; + u8 minor_ver; + u16 max_struct_size; + u8 revision; + u8 formatted_area[5]; + u8 intermediate_anchor[5]; + u8 intermediate_checksum; + u16 table_length; + u64 table_address; + u16 table_num_structs; + u8 bcd_revision; +}; + +/* type 212 */ +struct smbios_cru64_info { + u8 type; + u8 byte_length; + u16 handle; + u32 signature; + u64 physical_address; + u32 double_length; + u32 double_offset; +}; +#define SMBIOS_CRU64_INFORMATION 212 + +struct cmn_registers { + union { + struct { + u8 ral; + u8 rah; + u16 rea2; + }; + u32 reax; + } u1; + union { + struct { + u8 rbl; + u8 rbh; + u8 reb2l; + u8 reb2h; + }; + u32 rebx; + } u2; + union { + struct { + u8 rcl; + u8 rch; + u16 rec2; + }; + u32 recx; + } u3; + union { + struct { + u8 rdl; + u8 rdh; + u16 red2; + }; + u32 redx; + } u4; + + u32 resi; + u32 redi; + u16 rds; + u16 res; + u32 reflags; +} __attribute__((packed)); + +#define DEFAULT_MARGIN 30 +static unsigned int soft_margin = DEFAULT_MARGIN; /* in seconds */ +static unsigned int reload; /* the computed soft_margin */ +static int nowayout = WATCHDOG_NOWAYOUT; +static char expect_release; +static unsigned long hpwdt_is_open; + +static void __iomem *pci_mem_addr; /* the PCI-memory address */ +static unsigned long __iomem *hpwdt_timer_reg; +static unsigned long __iomem *hpwdt_timer_con; + +static DEFINE_SPINLOCK(rom_lock); + +static void *cru_rom_addr; + +static struct cmn_registers cmn_regs; + +static struct pci_device_id hpwdt_devices[] = { + { + .vendor = PCI_VENDOR_ID_COMPAQ, + .device = 0xB203, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + {0}, /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, hpwdt_devices); + +/* + * bios_checksum + */ +static int __devinit bios_checksum(const char __iomem *ptr, int len) +{ + char sum = 0; + int i; + + /* + * calculate checksum of size bytes. This should add up + * to zero if we have a valid header. + */ + for (i = 0; i < len; i++) + sum += ptr[i]; + + return ((sum == 0) && (len > 0)); +} + +#ifndef CONFIG_X86_64 +/* --32 Bit Bios------------------------------------------------------------ */ + +#define HPWDT_ARCH 32 + +asmlinkage void asminline_call(struct cmn_registers *pi86Regs, + unsigned long *pRomEntry) +{ + asm("pushl %ebp \n\t" + "movl %esp, %ebp \n\t" + "pusha \n\t" + "pushf \n\t" + "push %es \n\t" + "push %ds \n\t" + "pop %es \n\t" + "movl 8(%ebp),%eax \n\t" + "movl 4(%eax),%ebx \n\t" + "movl 8(%eax),%ecx \n\t" + "movl 12(%eax),%edx \n\t" + "movl 16(%eax),%esi \n\t" + "movl 20(%eax),%edi \n\t" + "movl (%eax),%eax \n\t" + "push %cs \n\t" + "call *12(%ebp) \n\t" + "pushf \n\t" + "pushl %eax \n\t" + "movl 8(%ebp),%eax \n\t" + "movl %ebx,4(%eax) \n\t" + "movl %ecx,8(%eax) \n\t" + "movl %edx,12(%eax) \n\t" + "movl %esi,16(%eax) \n\t" + "movl %edi,20(%eax) \n\t" + "movw %ds,24(%eax) \n\t" + "movw %es,26(%eax) \n\t" + "popl %ebx \n\t" + "movl %ebx,(%eax) \n\t" + "popl %ebx \n\t" + "movl %ebx,28(%eax) \n\t" + "pop %es \n\t" + "popf \n\t" + "popa \n\t" + "leave \n\t" "ret"); +} + +/* + * cru_detect + * + * Routine Description: + * This function uses the 32-bit BIOS Service Directory record to + * search for a $CRU record. + * + * Return Value: + * 0 : SUCCESS + * <0 : FAILURE + */ +static int __devinit cru_detect(unsigned long map_entry, + unsigned long map_offset) +{ + void *bios32_map; + unsigned long *bios32_entrypoint; + unsigned long cru_physical_address; + unsigned long cru_length; + unsigned long physical_bios_base = 0; + unsigned long physical_bios_offset = 0; + int retval = -ENODEV; + + bios32_map = ioremap(map_entry, (2 * PAGE_SIZE)); + + if (bios32_map == NULL) + return -ENODEV; + + bios32_entrypoint = bios32_map + map_offset; + + cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; + + asminline_call(&cmn_regs, bios32_entrypoint); + + if (cmn_regs.u1.ral != 0) { + printk(KERN_WARNING + "hpwdt: Call succeeded but with an error: 0x%x\n", + cmn_regs.u1.ral); + } else { + physical_bios_base = cmn_regs.u2.rebx; + physical_bios_offset = cmn_regs.u4.redx; + cru_length = cmn_regs.u3.recx; + cru_physical_address = + physical_bios_base + physical_bios_offset; + + /* If the values look OK, then map it in. */ + if ((physical_bios_base + physical_bios_offset)) { + cru_rom_addr = + ioremap(cru_physical_address, cru_length); + if (cru_rom_addr) + retval = 0; + } + + printk(KERN_DEBUG "hpwdt: CRU Base Address: 0x%lx\n", + physical_bios_base); + printk(KERN_DEBUG "hpwdt: CRU Offset Address: 0x%lx\n", + physical_bios_offset); + printk(KERN_DEBUG "hpwdt: CRU Length: 0x%lx\n", + cru_length); + printk(KERN_DEBUG "hpwdt: CRU Mapped Address: 0x%x\n", + (unsigned int)&cru_rom_addr); + } + iounmap(bios32_map); + return retval; +} + +/* + * bios32_present + * + * Routine Description: + * This function finds the 32-bit BIOS Service Directory + * + * Return Value: + * 0 : SUCCESS + * <0 : FAILURE + */ +static int __devinit bios32_present(const char __iomem *p) +{ + struct bios32_service_dir *bios_32_ptr; + int length; + unsigned long map_entry, map_offset; + + bios_32_ptr = (struct bios32_service_dir *) p; + + /* + * Search for signature by checking equal to the swizzled value + * instead of calling another routine to perform a strcmp. + */ + if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) { + length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN; + if (bios_checksum(p, length)) { + /* + * According to the spec, we're looking for the + * first 4KB-aligned address below the entrypoint + * listed in the header. The Service Directory code + * is guaranteed to occupy no more than 2 4KB pages. + */ + map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1); + map_offset = bios_32_ptr->entry_point - map_entry; + + return cru_detect(map_entry, map_offset); + } + } + return -ENODEV; +} + +static int __devinit detect_cru_service(void) +{ + char __iomem *p, *q; + int rc = -1; + + /* + * Search from 0x0f0000 through 0x0fffff, inclusive. + */ + p = ioremap(PCI_ROM_BASE1, ROM_SIZE); + if (p == NULL) + return -ENOMEM; + + for (q = p; q < p + ROM_SIZE; q += 16) { + rc = bios32_present(q); + if (!rc) + break; + } + iounmap(p); + return rc; +} + +#else +/* --64 Bit Bios------------------------------------------------------------ */ + +#define HPWDT_ARCH 64 + +asmlinkage void asminline_call(struct cmn_registers *pi86Regs, + unsigned long *pRomEntry) +{ + asm("pushq %rbp \n\t" + "movq %rsp, %rbp \n\t" + "pushq %rax \n\t" + "pushq %rbx \n\t" + "pushq %rdx \n\t" + "pushq %r12 \n\t" + "pushq %r9 \n\t" + "movq %rsi, %r12 \n\t" + "movq %rdi, %r9 \n\t" + "movl 4(%r9),%ebx \n\t" + "movl 8(%r9),%ecx \n\t" + "movl 12(%r9),%edx \n\t" + "movl 16(%r9),%esi \n\t" + "movl 20(%r9),%edi \n\t" + "movl (%r9),%eax \n\t" + "call *%r12 \n\t" + "pushfq \n\t" + "popq %r12 \n\t" + "popfq \n\t" + "movl %eax, (%r9) \n\t" + "movl %ebx, 4(%r9) \n\t" + "movl %ecx, 8(%r9) \n\t" + "movl %edx, 12(%r9) \n\t" + "movl %esi, 16(%r9) \n\t" + "movl %edi, 20(%r9) \n\t" + "movq %r12, %rax \n\t" + "movl %eax, 28(%r9) \n\t" + "popq %r9 \n\t" + "popq %r12 \n\t" + "popq %rdx \n\t" + "popq %rbx \n\t" + "popq %rax \n\t" + "leave \n\t" "ret"); +} + +/* + * dmi_find_cru + * + * Routine Description: + * This function checks wether or not a SMBIOS/DMI record is + * the 64bit CRU info or not + * + * Return Value: + * 0 : SUCCESS - if record found + * <0 : FAILURE - if record not found + */ +static void __devinit dmi_find_cru(const struct dmi_header *dm) +{ + struct smbios_cru64_info *smbios_cru64_ptr; + unsigned long cru_physical_address; + + if (dm->type == SMBIOS_CRU64_INFORMATION) { + smbios_cru64_ptr = (struct smbios_cru64_info *) dm; + if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) { + cru_physical_address = + smbios_cru64_ptr->physical_address + + smbios_cru64_ptr->double_offset; + cru_rom_addr = ioremap(cru_physical_address, + smbios_cru64_ptr->double_length); + } + } +} + +/* + * dmi_table + * + * Routine Description: + * Decode the SMBIOS/DMI table and check if we have a 64bit CRU record + * or not. + * + * We have to be cautious here. We have seen BIOSes with DMI pointers + * pointing to completely the wrong place for example + */ +static void __devinit dmi_table(u8 *buf, int len, int num, + void (*decode)(const struct dmi_header *)) +{ + u8 *data = buf; + int i = 0; + + /* + * Stop when we see all the items the table claimed to have + * OR we run off the end of the table (also happens) + */ + while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { + const struct dmi_header *dm = (const struct dmi_header *)data; + + /* + * We want to know the total length (formated area and strings) + * before decoding to make sure we won't run off the table in + * dmi_decode or dmi_string + */ + data += dm->length; + while ((data - buf < len - 1) && (data[0] || data[1])) + data++; + if (data - buf < len - 1) + decode(dm); + data += 2; + i++; + } +} + +/* + * smbios_present + * + * Routine Description: + * This function parses the SMBIOS entry point table to retrieve + * the 64 bit CRU Service. + * + * Return Value: + * 0 : SUCCESS + * <0 : FAILURE + */ +static int __devinit smbios_present(const char __iomem *p) +{ + struct smbios_entry_point *eps = + (struct smbios_entry_point *) p; + int length; + u8 *buf; + + /* check if we have indeed the SMBIOS table entry point */ + if ((strncmp((char *)eps->anchor, "_SM_", + sizeof(eps->anchor))) == 0) { + length = eps->length; + + /* SMBIOS v2.1 implementation might use 0x1e */ + if ((length == 0x1e) && + (eps->major_ver == 2) && + (eps->minor_ver == 1)) + length = 0x1f; + + /* + * Now we will check: + * - SMBIOS checksum must be 0 + * - intermediate anchor should be _DMI_ + * - intermediate checksum should be 0 + */ + if ((bios_checksum(p, length)) && + (strncmp((char *)eps->intermediate_anchor, "_DMI_", + sizeof(eps->intermediate_anchor)) == 0) && + (bios_checksum(p+0x10, 15))) { + buf = ioremap(eps->table_address, eps->table_length); + if (buf == NULL) + return -ENODEV; + + + /* Scan the DMI table for the 64 bit CRU service */ + dmi_table(buf, eps->table_length, + eps->table_num_structs, dmi_find_cru); + + iounmap(buf); + return 0; + } + } + + return -ENODEV; +} + +static int __devinit smbios_scan_machine(void) +{ + char __iomem *p, *q; + int rc; + + if (efi_enabled) { + if (efi.smbios == EFI_INVALID_TABLE_ADDR) + return -ENODEV; + + p = ioremap(efi.smbios, 32); + if (p == NULL) + return -ENOMEM; + + rc = smbios_present(p); + iounmap(p); + } else { + /* + * Search from 0x0f0000 through 0x0fffff, inclusive. + */ + p = ioremap(PCI_ROM_BASE1, ROM_SIZE); + if (p == NULL) + return -ENOMEM; + + for (q = p; q < p + ROM_SIZE; q += 16) { + rc = smbios_present(q); + if (!rc) { + break; + } + } + iounmap(p); + } +} + +static int __devinit detect_cru_service(void) +{ + cru_rom_addr = NULL; + + smbios_scan_machine(); /* will become dmi_walk(dmi_find_cru); */ + + /* if cru_rom_addr has been set then we found a CRU service */ + return ((cru_rom_addr != NULL)? 0: -ENODEV); +} + +/* ------------------------------------------------------------------------- */ + +#endif + +/* + * NMI Handler + */ +static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, + void *data) +{ + static unsigned long rom_pl; + static int die_nmi_called; + + if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI) + return NOTIFY_OK; + + spin_lock_irqsave(&rom_lock, rom_pl); + if (!die_nmi_called) + asminline_call(&cmn_regs, cru_rom_addr); + die_nmi_called = 1; + spin_unlock_irqrestore(&rom_lock, rom_pl); + if (cmn_regs.u1.ral == 0) { + printk(KERN_WARNING "hpwdt: An NMI occurred, " + "but unable to determine source.\n"); + } else { + panic("An NMI occurred, please see the Integrated " + "Management Log for details.\n"); + } + + return NOTIFY_STOP; +} + +/* + * Watchdog operations + */ +static void hpwdt_start(void) +{ + reload = (soft_margin * 1000) / 128; + iowrite16(reload, hpwdt_timer_reg); + iowrite16(0x85, hpwdt_timer_con); +} + +static void hpwdt_stop(void) +{ + unsigned long data; + + data = ioread16(hpwdt_timer_con); + data &= 0xFE; + iowrite16(data, hpwdt_timer_con); +} + +static void hpwdt_ping(void) +{ + iowrite16(reload, hpwdt_timer_reg); +} + +static int hpwdt_change_timer(int new_margin) +{ + /* Arbitrary, can't find the card's limits */ + if (new_margin < 30 || new_margin > 600) { + printk(KERN_WARNING + "hpwdt: New value passed in is invalid: %d seconds.\n", + new_margin); + return -EINVAL; + } + + soft_margin = new_margin; + printk(KERN_DEBUG + "hpwdt: New timer passed in is %d seconds.\n", + new_margin); + reload = (soft_margin * 1000) / 128; + + return 0; +} + +/* + * /dev/watchdog handling + */ +static int hpwdt_open(struct inode *inode, struct file *file) +{ + /* /dev/watchdog can only be opened once */ + if (test_and_set_bit(0, &hpwdt_is_open)) + return -EBUSY; + + /* Start the watchdog */ + hpwdt_start(); + hpwdt_ping(); + + return nonseekable_open(inode, file); +} + +static int hpwdt_release(struct inode *inode, struct file *file) +{ + /* Stop the watchdog */ + if (expect_release == 42) { + hpwdt_stop(); + } else { + printk(KERN_CRIT + "hpwdt: Unexpected close, not stopping watchdog!\n"); + hpwdt_ping(); + } + + expect_release = 0; + + /* /dev/watchdog is being closed, make sure it can be re-opened */ + clear_bit(0, &hpwdt_is_open); + + return 0; +} + +static ssize_t hpwdt_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + /* See if we got the magic character 'V' and reload the timer */ + if (len) { + if (!nowayout) { + size_t i; + + /* note: just in case someone wrote the magic character + * five months ago... */ + expect_release = 0; + + /* scan to see whether or not we got the magic char. */ + for (i = 0; i != len; i++) { + char c; + if (get_user(c, data+i)) + return -EFAULT; + if (c == 'V') + expect_release = 42; + } + } + + /* someone wrote to us, we should reload the timer */ + hpwdt_ping(); + } + + return len; +} + +static struct watchdog_info ident = { + .options = WDIOF_SETTIMEOUT | + WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, + .identity = "HP iLO2 HW Watchdog Timer", +}; + +static long hpwdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int __user *p = argp; + int new_margin; + int ret = -ENOTTY; + + switch (cmd) { + case WDIOC_GETSUPPORT: + ret = 0; + if (copy_to_user(argp, &ident, sizeof(ident))) + ret = -EFAULT; + break; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + ret = put_user(0, p); + break; + + case WDIOC_KEEPALIVE: + hpwdt_ping(); + ret = 0; + break; + + case WDIOC_SETTIMEOUT: + ret = get_user(new_margin, p); + if (ret) + break; + + ret = hpwdt_change_timer(new_margin); + if (ret) + break; + + hpwdt_ping(); + /* Fall */ + case WDIOC_GETTIMEOUT: + ret = put_user(soft_margin, p); + break; + } + return ret; +} + +/* + * Kernel interfaces + */ +static struct file_operations hpwdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = hpwdt_write, + .unlocked_ioctl = hpwdt_ioctl, + .open = hpwdt_open, + .release = hpwdt_release, +}; + +static struct miscdevice hpwdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &hpwdt_fops, +}; + +static struct notifier_block die_notifier = { + .notifier_call = hpwdt_pretimeout, + .priority = 0x7FFFFFFF, +}; + +/* + * Init & Exit + */ + +static int __devinit hpwdt_init_one(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + int retval; + + /* + * First let's find out if we are on an iLO2 server. We will + * not run on a legacy ASM box. + */ + if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) { + dev_warn(&dev->dev, + "This server does not have an iLO2 ASIC.\n"); + return -ENODEV; + } + + if (pci_enable_device(dev)) { + dev_warn(&dev->dev, + "Not possible to enable PCI Device: 0x%x:0x%x.\n", + ent->vendor, ent->device); + return -ENODEV; + } + + pci_mem_addr = pci_iomap(dev, 1, 0x80); + if (!pci_mem_addr) { + dev_warn(&dev->dev, + "Unable to detect the iLO2 server memory.\n"); + retval = -ENOMEM; + goto error_pci_iomap; + } + hpwdt_timer_reg = pci_mem_addr + 0x70; + hpwdt_timer_con = pci_mem_addr + 0x72; + + /* Make sure that we have a valid soft_margin */ + if (hpwdt_change_timer(soft_margin)) + hpwdt_change_timer(DEFAULT_MARGIN); + + /* + * We need to map the ROM to get the CRU service. + * For 32 bit Operating Systems we need to go through the 32 Bit + * BIOS Service Directory + * For 64 bit Operating Systems we get that service through SMBIOS. + */ + retval = detect_cru_service(); + if (retval < 0) { + dev_warn(&dev->dev, + "Unable to detect the %d Bit CRU Service.\n", + HPWDT_ARCH); + goto error_get_cru; + } + + /* + * We know this is the only CRU call we need to make so lets keep as + * few instructions as possible once the NMI comes in. + */ + cmn_regs.u1.rah = 0x0D; + cmn_regs.u1.ral = 0x02; + + retval = register_die_notifier(&die_notifier); + if (retval != 0) { + dev_warn(&dev->dev, + "Unable to register a die notifier (err=%d).\n", + retval); + goto error_die_notifier; + } + + retval = misc_register(&hpwdt_miscdev); + if (retval < 0) { + dev_warn(&dev->dev, + "Unable to register miscdev on minor=%d (err=%d).\n", + WATCHDOG_MINOR, retval); + goto error_misc_register; + } + + printk(KERN_INFO + "hp Watchdog Timer Driver: 1.00" + ", timer margin: %d seconds( nowayout=%d).\n", + soft_margin, nowayout); + + return 0; + +error_misc_register: + unregister_die_notifier(&die_notifier); +error_die_notifier: + if (cru_rom_addr) + iounmap(cru_rom_addr); +error_get_cru: + pci_iounmap(dev, pci_mem_addr); +error_pci_iomap: + pci_disable_device(dev); + return retval; +} + +static void __devexit hpwdt_exit(struct pci_dev *dev) +{ + if (!nowayout) + hpwdt_stop(); + + misc_deregister(&hpwdt_miscdev); + unregister_die_notifier(&die_notifier); + + if (cru_rom_addr) + iounmap(cru_rom_addr); + pci_iounmap(dev, pci_mem_addr); + pci_disable_device(dev); +} + +static struct pci_driver hpwdt_driver = { + .name = "hpwdt", + .id_table = hpwdt_devices, + .probe = hpwdt_init_one, + .remove = __devexit_p(hpwdt_exit), +}; + +static void __exit hpwdt_cleanup(void) +{ + pci_unregister_driver(&hpwdt_driver); +} + +static int __init hpwdt_init(void) +{ + return pci_register_driver(&hpwdt_driver); +} + +MODULE_AUTHOR("Tom Mingarelli"); +MODULE_DESCRIPTION("hp watchdog driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); + +module_param(soft_margin, int, 0); +MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds"); + +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +module_init(hpwdt_init); +module_exit(hpwdt_cleanup); From 51af33e8e45b845d8ee85446f58e31bc4c118048 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Mon, 18 Feb 2008 10:33:59 -0800 Subject: [PATCH 294/880] RDMA/nes: Fix possible array overrun In nes_create_qp(), the test if (nesqp->mmap_sq_db_index > NES_MAX_USER_WQ_REGIONS) { is used to error out if the db_index is too large; however, if the test doesn't trigger, then the index is used as nes_ucontext->mmap_nesqp[nesqp->mmap_sq_db_index] = nesqp; and mmap_nesqp is declared as struct nes_qp *mmap_nesqp[NES_MAX_USER_WQ_REGIONS]; which leads to an array overrun if the index is exactly equal to NES_MAX_USER_WQ_REGIONS. Fix this by bailing out if the index is greater than or equal to NES_MAX_USER_WQ_REGIONS. This was spotted by the Coverity checker (CID 2162). Acked-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index ffd4b425567f..4dafbe16e82a 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1337,7 +1337,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, NES_MAX_USER_WQ_REGIONS, nes_ucontext->first_free_wq); /* nes_debug(NES_DBG_QP, "find_first_zero_biton wqs returned %u\n", nespd->mmap_db_index); */ - if (nesqp->mmap_sq_db_index > NES_MAX_USER_WQ_REGIONS) { + if (nesqp->mmap_sq_db_index >= NES_MAX_USER_WQ_REGIONS) { nes_debug(NES_DBG_QP, "db index > max user regions, failing create QP\n"); nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); From c31c7d4844ea4817692ae16bf70f9c96c05a50eb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 18 Feb 2008 20:54:14 +0100 Subject: [PATCH 295/880] x86: CPA, fix alias checks c_p_a() did not discover all aliases correctly. (such as when called on vmalloc()-ed areas or ioremap()-ed areas) Push the alias checks to the lower, physical level and consistently discover all aliases that might exist: the low direct mappings and the high linear kernel-text mappings (on 64-bit). Thanks to Andi Kleen for pointing out that this was buggy. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 192 ++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 100 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 4119379f80ff..7b4a17236972 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -16,6 +16,7 @@ #include #include #include +#include /* * The current flushing context - we pass it instead of 5 arguments: @@ -26,8 +27,23 @@ struct cpa_data { pgprot_t mask_clr; int numpages; int flushtlb; + unsigned long pfn; }; +#ifdef CONFIG_X86_64 + +static inline unsigned long highmap_start_pfn(void) +{ + return __pa(_text) >> PAGE_SHIFT; +} + +static inline unsigned long highmap_end_pfn(void) +{ + return __pa(round_up((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT; +} + +#endif + static inline int within(unsigned long addr, unsigned long start, unsigned long end) { @@ -123,29 +139,14 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache) } } -#define HIGH_MAP_START __START_KERNEL_map -#define HIGH_MAP_END (__START_KERNEL_map + KERNEL_TEXT_SIZE) - - -/* - * Converts a virtual address to a X86-64 highmap address - */ -static unsigned long virt_to_highmap(void *address) -{ -#ifdef CONFIG_X86_64 - return __pa((unsigned long)address) + HIGH_MAP_START - phys_base; -#else - return (unsigned long)address; -#endif -} - /* * Certain areas of memory on x86 require very specific protection flags, * for example the BIOS area or kernel text. Callers don't always get this * right (again, ioremap() on BIOS memory is not uncommon) so this function * checks and fixes these known static required protection bits. */ -static inline pgprot_t static_protections(pgprot_t prot, unsigned long address) +static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, + unsigned long pfn) { pgprot_t forbidden = __pgprot(0); @@ -153,30 +154,23 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address) * The BIOS area between 640k and 1Mb needs to be executable for * PCI BIOS based config access (CONFIG_PCI_GOBIOS) support. */ - if (within(__pa(address), BIOS_BEGIN, BIOS_END)) + if (within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> PAGE_SHIFT)) pgprot_val(forbidden) |= _PAGE_NX; /* * The kernel text needs to be executable for obvious reasons - * Does not cover __inittext since that is gone later on + * Does not cover __inittext since that is gone later on. On + * 64bit we do not enforce !NX on the low mapping */ if (within(address, (unsigned long)_text, (unsigned long)_etext)) pgprot_val(forbidden) |= _PAGE_NX; - /* - * Do the same for the x86-64 high kernel mapping - */ - if (within(address, virt_to_highmap(_text), virt_to_highmap(_etext))) - pgprot_val(forbidden) |= _PAGE_NX; - /* The .rodata section needs to be read-only */ - if (within(address, (unsigned long)__start_rodata, - (unsigned long)__end_rodata)) - pgprot_val(forbidden) |= _PAGE_RW; /* - * Do the same for the x86-64 high kernel mapping + * The .rodata section needs to be read-only. Using the pfn + * catches all aliases. */ - if (within(address, virt_to_highmap(__start_rodata), - virt_to_highmap(__end_rodata))) + if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT, + __pa((unsigned long)__end_rodata) >> PAGE_SHIFT)) pgprot_val(forbidden) |= _PAGE_RW; prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden)); @@ -253,7 +247,7 @@ static int try_preserve_large_page(pte_t *kpte, unsigned long address, struct cpa_data *cpa) { - unsigned long nextpage_addr, numpages, pmask, psize, flags, addr; + unsigned long nextpage_addr, numpages, pmask, psize, flags, addr, pfn; pte_t new_pte, old_pte, *tmp; pgprot_t old_prot, new_prot; int i, do_split = 1; @@ -301,7 +295,15 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr); pgprot_val(new_prot) |= pgprot_val(cpa->mask_set); - new_prot = static_protections(new_prot, address); + + /* + * old_pte points to the large page base address. So we need + * to add the offset of the virtual address: + */ + pfn = pte_pfn(old_pte) + ((address & (psize - 1)) >> PAGE_SHIFT); + cpa->pfn = pfn; + + new_prot = static_protections(new_prot, address, pfn); /* * We need to check the full range, whether @@ -309,8 +311,9 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, * the pages in the range we try to preserve: */ addr = address + PAGE_SIZE; - for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE) { - pgprot_t chk_prot = static_protections(new_prot, addr); + pfn++; + for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE, pfn++) { + pgprot_t chk_prot = static_protections(new_prot, addr, pfn); if (pgprot_val(chk_prot) != pgprot_val(new_prot)) goto out_unlock; @@ -505,46 +508,51 @@ static int split_large_page(pte_t *kpte, unsigned long address) return 0; } -static int __change_page_attr(unsigned long address, struct cpa_data *cpa) +static int __change_page_attr(struct cpa_data *cpa, int primary) { + unsigned long address = cpa->vaddr; int do_split, err; unsigned int level; struct page *kpte_page; - pte_t *kpte; + pte_t *kpte, old_pte; repeat: kpte = lookup_address(address, &level); if (!kpte) + return primary ? -EINVAL : 0; + + old_pte = *kpte; + if (!pte_val(old_pte)) { + if (!primary) + return 0; + printk(KERN_WARNING "CPA: called for zero pte. " + "vaddr = %lx cpa->vaddr = %lx\n", address, + cpa->vaddr); + WARN_ON(1); return -EINVAL; + } kpte_page = virt_to_page(kpte); BUG_ON(PageLRU(kpte_page)); BUG_ON(PageCompound(kpte_page)); if (level == PG_LEVEL_4K) { - pte_t new_pte, old_pte = *kpte; + pte_t new_pte; pgprot_t new_prot = pte_pgprot(old_pte); - - if(!pte_val(old_pte)) { - printk(KERN_WARNING "CPA: called for zero pte. " - "vaddr = %lx cpa->vaddr = %lx\n", address, - cpa->vaddr); - WARN_ON(1); - return -EINVAL; - } + unsigned long pfn = pte_pfn(old_pte); pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr); pgprot_val(new_prot) |= pgprot_val(cpa->mask_set); - new_prot = static_protections(new_prot, address); + new_prot = static_protections(new_prot, address, pfn); /* * We need to keep the pfn from the existing PTE, * after all we're only going to change it's attributes * not the memory it points to */ - new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot)); - + new_pte = pfn_pte(pfn, canon_pgprot(new_prot)); + cpa->pfn = pfn; /* * Do we really change anything ? */ @@ -581,67 +589,44 @@ static int __change_page_attr(unsigned long address, struct cpa_data *cpa) return err; } -/** - * change_page_attr_addr - Change page table attributes in linear mapping - * @address: Virtual address in linear mapping. - * @prot: New page table attribute (PAGE_*) - * - * Change page attributes of a page in the direct mapping. This is a variant - * of change_page_attr() that also works on memory holes that do not have - * mem_map entry (pfn_valid() is false). - * - * See change_page_attr() documentation for more details. - * - * Modules and drivers should use the set_memory_* APIs instead. - */ -static int change_page_attr_addr(struct cpa_data *cpa) +static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias); + +static int cpa_process_alias(struct cpa_data *cpa) { - int err; - unsigned long address = cpa->vaddr; + struct cpa_data alias_cpa; + int ret; -#ifdef CONFIG_X86_64 - unsigned long phys_addr = __pa(address); + if (cpa->pfn > max_pfn_mapped) + return 0; - /* - * If we are inside the high mapped kernel range, then we - * fixup the low mapping first. __va() returns the virtual - * address in the linear mapping: - */ - if (within(address, HIGH_MAP_START, HIGH_MAP_END)) - address = (unsigned long) __va(phys_addr); -#endif + alias_cpa = *cpa; + alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); - err = __change_page_attr(address, cpa); - if (err) - return err; + ret = __change_page_attr_set_clr(&alias_cpa, 0); #ifdef CONFIG_X86_64 + if (ret) + return ret; /* * If the physical address is inside the kernel map, we need * to touch the high mapped kernel as well: */ - if (within(phys_addr, 0, KERNEL_TEXT_SIZE)) { - /* - * Calc the high mapping address. See __phys_addr() - * for the non obvious details. - * - * Note that NX and other required permissions are - * checked in static_protections(). - */ - address = phys_addr + HIGH_MAP_START - phys_base; + if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) + return 0; - /* - * Our high aliases are imprecise, because we check - * everything between 0 and KERNEL_TEXT_SIZE, so do - * not propagate lookup failures back to users: - */ - __change_page_attr(address, cpa); - } + alias_cpa = *cpa; + alias_cpa.vaddr = + (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; + + /* + * The high mapping range is imprecise, so ignore the return value. + */ + __change_page_attr_set_clr(&alias_cpa, 0); #endif - return err; + return ret; } -static int __change_page_attr_set_clr(struct cpa_data *cpa) +static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) { int ret, numpages = cpa->numpages; @@ -651,10 +636,17 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa) * preservation check. */ cpa->numpages = numpages; - ret = change_page_attr_addr(cpa); + + ret = __change_page_attr(cpa, checkalias); if (ret) return ret; + if (checkalias) { + ret = cpa_process_alias(cpa); + if (ret) + return ret; + } + /* * Adjust the number of pages with the result of the * CPA operation. Either a large page has been @@ -703,7 +695,7 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, cpa.mask_clr = mask_clr; cpa.flushtlb = 0; - ret = __change_page_attr_set_clr(&cpa); + ret = __change_page_attr_set_clr(&cpa, 1); /* * Check whether we really changed something: @@ -841,7 +833,7 @@ static int __set_pages_p(struct page *page, int numpages) .mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW), .mask_clr = __pgprot(0)}; - return __change_page_attr_set_clr(&cpa); + return __change_page_attr_set_clr(&cpa, 1); } static int __set_pages_np(struct page *page, int numpages) @@ -851,7 +843,7 @@ static int __set_pages_np(struct page *page, int numpages) .mask_set = __pgprot(0), .mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW)}; - return __change_page_attr_set_clr(&cpa); + return __change_page_attr_set_clr(&cpa, 1); } void kernel_map_pages(struct page *page, int numpages, int enable) From 31eedd823c1bf3650c450346a0d0c39431034eb9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 15 Feb 2008 17:29:12 +0100 Subject: [PATCH 296/880] x86: zap invalid and unused pmds in early boot The early boot code maps KERNEL_TEXT_SIZE (currently 40MB) starting from __START_KERNEL_map. The kernel itself only needs _text to _end mapped in the high alias. On relocatible kernels the ASM setup code adjusts the compile time created high mappings to the relocation. This creates invalid pmd entries for negative offsets: 0xffffffff80000000 -> pmd entry: ffffffffff2001e3 It points outside of the physical address space and is marked present. This starts at the virtual address __START_KERNEL_map and goes up to the point where the first valid physical address (0x0) is mapped. Zap the mappings before _text and after _end right away in early boot. This removes also the invalid entries. Furthermore it simplifies the range check for high aliases. Signed-off-by: Thomas Gleixner Acked-by: H. Peter Anvin Signed-off-by: Ingo Molnar --- arch/x86/kernel/head64.c | 3 +++ arch/x86/kernel/head_64.S | 7 ++++++- arch/x86/mm/init_64.c | 27 +++++++++++++++++++++++++++ include/asm-x86/pgtable_64.h | 1 + 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 24dbf56928d7..ad2440832de0 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -88,6 +88,9 @@ void __init x86_64_start_kernel(char * real_mode_data) /* Make NULL pointers segfault */ zap_identity_mappings(); + /* Cleanup the over mapped high alias */ + cleanup_highmap(); + for (i = 0; i < IDT_ENTRIES; i++) { #ifdef CONFIG_EARLY_PRINTK set_intr_gate(i, &early_idt_handlers[i]); diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 09b38d539b09..53e5820d6054 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -107,8 +107,13 @@ startup_64: movq %rdx, 0(%rbx, %rax, 8) ident_complete: - /* Fixup the kernel text+data virtual addresses + /* + * Fixup the kernel text+data virtual addresses. Note that + * we might write invalid pmds, when the kernel is relocated + * cleanup_highmap() fixes this up along with the mappings + * beyond _end. */ + leaq level2_kernel_pgt(%rip), %rdi leaq 4096(%rdi), %r8 /* See if it is a valid page table entry */ diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index a4a9cccdd4f2..bb652f5a93fb 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -171,6 +171,33 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) __flush_tlb_one(vaddr); } +/* + * The head.S code sets up the kernel high mapping from: + * __START_KERNEL_map to __START_KERNEL_map + KERNEL_TEXT_SIZE + * + * phys_addr holds the negative offset to the kernel, which is added + * to the compile time generated pmds. This results in invalid pmds up + * to the point where we hit the physaddr 0 mapping. + * + * We limit the mappings to the region from _text to _end. _end is + * rounded up to the 2MB boundary. This catches the invalid pmds as + * well, as they are located before _text: + */ +void __init cleanup_highmap(void) +{ + unsigned long vaddr = __START_KERNEL_map; + unsigned long end = round_up((unsigned long)_end, PMD_SIZE) - 1; + pmd_t *pmd = level2_kernel_pgt; + pmd_t *last_pmd = pmd + PTRS_PER_PMD; + + for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) { + if (!pmd_present(*pmd)) + continue; + if (vaddr < (unsigned long) _text || vaddr > end) + set_pmd(pmd, __pmd(0)); + } +} + /* NOTE: this is meant to be run only at boot */ void __init __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index bd4740a60f29..7fd5e0e2361e 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -246,6 +246,7 @@ static inline int pud_large(pud_t pte) #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) extern int kern_addr_valid(unsigned long addr); +extern void cleanup_highmap(void); #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) From af96e4438a4b34a257f5318a296e0b9e182e7ab9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 15 Feb 2008 21:49:46 +0100 Subject: [PATCH 297/880] x86: CPA no alias checking for _NX NX settings are not required to be consistent across alias mappings. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 7b4a17236972..b8f53233151d 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -669,7 +669,7 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, pgprot_t mask_set, pgprot_t mask_clr) { struct cpa_data cpa; - int ret, cache; + int ret, cache, checkalias; /* * Check, if we are requested to change a not supported @@ -695,7 +695,10 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, cpa.mask_clr = mask_clr; cpa.flushtlb = 0; - ret = __change_page_attr_set_clr(&cpa, 1); + /* No alias checking for _NX bit modifications */ + checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX; + + ret = __change_page_attr_set_clr(&cpa, checkalias); /* * Check whether we really changed something: From f34b439f34c49d7de858234bab5e2dd03cfaf3c1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 15 Feb 2008 22:17:57 +0100 Subject: [PATCH 298/880] x86: CPA: avoid double checking of alias ranges When the CPA code is called with an virtual address in the range of the direct mapping or the high alias then we do not need to run through the alias check for this range. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index b8f53233151d..3ee14996c829 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -594,19 +594,34 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias); static int cpa_process_alias(struct cpa_data *cpa) { struct cpa_data alias_cpa; - int ret; + int ret = 0; if (cpa->pfn > max_pfn_mapped) return 0; - alias_cpa = *cpa; - alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); + /* + * No need to redo, when the primary call touched the direct + * mapping already: + */ + if (!within(cpa->vaddr, PAGE_OFFSET, + PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) { - ret = __change_page_attr_set_clr(&alias_cpa, 0); + alias_cpa = *cpa; + alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); + + ret = __change_page_attr_set_clr(&alias_cpa, 0); + } #ifdef CONFIG_X86_64 if (ret) return ret; + /* + * No need to redo, when the primary call touched the high + * mapping already: + */ + if (within(cpa->vaddr, (unsigned long) _text, (unsigned long) _end)) + return 0; + /* * If the physical address is inside the kernel map, we need * to touch the high mapped kernel as well: From b7ad149d62ffffaccb9f565dfe7e5bae739d6836 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 17 Feb 2008 02:02:21 -0800 Subject: [PATCH 299/880] x86: reenable support for system without on node0 One system doesn't have RAM for node0 installed. SRAT: PXM 0 -> APIC 0 -> Node 0 SRAT: PXM 0 -> APIC 1 -> Node 0 SRAT: PXM 1 -> APIC 2 -> Node 1 SRAT: PXM 1 -> APIC 3 -> Node 1 SRAT: Node 1 PXM 1 0-a0000 SRAT: Node 1 PXM 1 0-dd000000 SRAT: Node 1 PXM 1 0-123000000 ACPI: SLIT: nodes = 2 10 13 13 10 mapped APIC to ffffffffff5fb000 ( fee00000) Bootmem setup node 1 0000000000000000-0000000123000000 NODE_DATA [000000000000e000 - 0000000000014fff] bootmap [0000000000015000 - 00000000000395ff] pages 25 Could not find start_pfn for node 0 Pid: 0, comm: swapper Not tainted 2.6.24-smp-g5a514e21-dirty #14 Call Trace: [] free_area_init_node+0x22/0x381 [] generic_swap+0x0/0x17 [] find_zone_movable_pfns_for_nodes+0x54/0x271 [] free_area_init_nodes+0x239/0x287 [] paging_init+0x46/0x4c [] setup_arch+0x3c3/0x44e [] start_kernel+0x6f/0x2c7 [] _sinittext+0x1cc/0x1d3 This happens because node 0 is not online, but the node state in mm/page_alloc.c has node 0 set. nodemask_t node_states[NR_NODE_STATES] __read_mostly = { [N_POSSIBLE] = NODE_MASK_ALL, [N_ONLINE] = { { [0] = 1UL } }, So we need to clear node_online_map before initializing the memory. Signed-off-by: Yinghai Lu Cc: Andrew Morton Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/mm/numa_64.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 1aecc658cd7d..59898fb0a4aa 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -494,11 +494,13 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) int i; nodes_clear(node_possible_map); + nodes_clear(node_online_map); #ifdef CONFIG_NUMA_EMU if (cmdline && !numa_emulation(start_pfn, end_pfn)) return; nodes_clear(node_possible_map); + nodes_clear(node_online_map); #endif #ifdef CONFIG_ACPI_NUMA @@ -506,6 +508,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) end_pfn << PAGE_SHIFT)) return; nodes_clear(node_possible_map); + nodes_clear(node_online_map); #endif #ifdef CONFIG_K8_NUMA @@ -513,6 +516,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) end_pfn< Date: Mon, 4 Feb 2008 07:11:10 +1100 Subject: [PATCH 300/880] x86: fix lguest build failure drivers/lguest/x86/switcher_32.S:(.text+0x3815f8): undefined reference to `LGUEST_PAGES_regs_trapnum' This problem was caused by asm-offsets.c only having the offsets when lguest *guest* support was set, not lguest host (host support used to imply guest support, so now they're separate these bugs come out). Lguest guest support and host support are separate config options: they used to be tied together. Sort out which parts of asm-offsets are needed for Guest and Host. Signed-off-by: Rusty Russell Cc: Linus Torvalds Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/asm-offsets_32.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index afd84463b712..a33d53017997 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -20,10 +20,8 @@ #include -#ifdef CONFIG_LGUEST_GUEST #include #include "../../../drivers/lguest/lg.h" -#endif #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -134,6 +132,10 @@ void foo(void) BLANK(); OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled); OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir); +#endif + +#ifdef CONFIG_LGUEST + BLANK(); OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc); OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc); OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3); From 4ef110141b3e0758fe30d686417b5686b87eb25b Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 19 Feb 2008 10:05:35 +1100 Subject: [PATCH 301/880] [POWERPC] spufs: fix scheduler starvation by idle contexts 2.6.25 has a regression where we can starve the scheduler by creating (N_SPES+1) contexts, then running them one at a time. The final context will never be run, as the other contexts are loaded on the SPEs, none of which are repoted as free (ie, spu->alloc_state != SPU_FREE), so spu_get_idle() doesn't give us a spu to run on. Because all of the contexts are stopped, none are descheduled by the scheduler tick, as spusched_tick returns if spu_stopped(ctx). This change replaces the spu_stopped() check with checking for SCHED_IDLE in ctx->policy. We set a context's policy to SCHED_IDLE when we're not in spu_run(). We also favour SCHED_IDLE contexts when looking for contexts to unbind, but leave their timeslice intact for later resumption. This patch fixes the following test in the spufs-testsuite: tests/20-scheduler/02-yield-starvation Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/run.c | 1 + arch/powerpc/platforms/cell/spufs/sched.c | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index fca22e18069a..6221968c2a3c 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -234,6 +234,7 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc, *npc = ctx->ops->npc_read(ctx); spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); + ctx->policy = SCHED_IDLE; spu_release(ctx); if (signal_pending(current)) diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 5915343e2599..3a5972117de7 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -856,21 +856,18 @@ static noinline void spusched_tick(struct spu_context *ctx) { struct spu_context *new = NULL; struct spu *spu = NULL; - u32 status; if (spu_acquire(ctx)) BUG(); /* a kernel thread never has signals pending */ if (ctx->state != SPU_STATE_RUNNABLE) goto out; - if (spu_stopped(ctx, &status)) - goto out; if (ctx->flags & SPU_CREATE_NOSCHED) goto out; if (ctx->policy == SCHED_FIFO) goto out; - if (--ctx->time_slice) + if (--ctx->time_slice && ctx->policy != SCHED_IDLE) goto out; spu = ctx->spu; @@ -880,7 +877,8 @@ static noinline void spusched_tick(struct spu_context *ctx) new = grab_runnable_context(ctx->prio + 1, spu->node); if (new) { spu_unschedule(spu, ctx); - spu_add_to_rq(ctx); + if (ctx->policy != SCHED_IDLE) + spu_add_to_rq(ctx); } else { spu_context_nospu_trace(spusched_tick__newslice, ctx); ctx->time_slice++; From a3d41704d4647abfc2796e9c81f71e0902f78e09 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 15:13:48 -0800 Subject: [PATCH 302/880] [SPARC64]: Kill unused function 'kernel_enter_debugger'. Signed-off-by: David S. Miller --- arch/sparc64/kernel/setup.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index ebad74bd88bb..e6b57ba2b744 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -90,11 +90,6 @@ static struct console prom_early_console = { .index = -1, }; -/* XXX Implement this at some point... */ -void kernel_enter_debugger(void) -{ -} - /* * Process kernel command line switches that are specific to the * SPARC or that require special low-level processing. From 9a2f258ad5910c478a5c98989b9a26268b2e5488 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 15:16:20 -0800 Subject: [PATCH 303/880] [SPARC64]: Delete 'boot_flags'. It is write-only, nothing tests it's value. Signed-off-by: David S. Miller --- arch/sparc64/kernel/setup.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index e6b57ba2b744..9b892ff4e8ef 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -77,9 +77,6 @@ prom_console_write(struct console *con, const char *s, unsigned n) prom_write(s, n); } -unsigned int boot_flags = 0; -#define BOOTME_DEBUG 0x1 - /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size = 0; @@ -98,8 +95,6 @@ static void __init process_switch(char c) { switch (c) { case 'd': - boot_flags |= BOOTME_DEBUG; - break; case 's': break; case 'h': From 1d5509aa6985b256a426e67ae6952fd4b7664de7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 15:17:58 -0800 Subject: [PATCH 304/880] [SPARC]: Kill extern decl of 'panic_setup'. This was made static in kernel/panic.c a long time ago. Signed-off-by: David S. Miller --- arch/sparc/kernel/setup.c | 1 - arch/sparc64/kernel/setup.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 3cf78f160846..5f1508eeb84d 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -191,7 +191,6 @@ extern int prom_probe_memory(void); extern void sun4c_probe_vac(void); extern char cputypval; extern unsigned long start, end; -extern void panic_setup(char *, int *); extern unsigned short root_flags; extern unsigned short root_dev; diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 9b892ff4e8ef..82b4d091e4f4 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -157,8 +157,6 @@ static void __init boot_flags_init(char *commands) } } -extern void panic_setup(char *, int *); - extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; From 101788b0ab5464cf485c5d434ac30563e6f9e5fe Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 15:21:30 -0800 Subject: [PATCH 305/880] [SPARC64]: Kill 'prom_keyboard'. Nothing ever sets it, so it just takes up space. Signed-off-by: David S. Miller --- arch/sparc64/kernel/process.c | 7 ------- arch/sparc64/kernel/setup.c | 1 - 2 files changed, 8 deletions(-) diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 1b2379174988..d7e8e80d43a5 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -114,15 +114,12 @@ void cpu_idle(void) extern char reboot_command []; extern void (*prom_palette)(int); -extern void (*prom_keyboard)(void); void machine_halt(void) { sstate_halt(); if (prom_palette) prom_palette (1); - if (prom_keyboard) - prom_keyboard(); prom_halt(); panic("Halt failed!"); } @@ -132,8 +129,6 @@ void machine_alt_power_off(void) sstate_poweroff(); if (prom_palette) prom_palette(1); - if (prom_keyboard) - prom_keyboard(); prom_halt_power_off(); panic("Power-off failed!"); } @@ -147,8 +142,6 @@ void machine_restart(char * cmd) if (p) *p = 0; if (prom_palette) prom_palette (1); - if (prom_keyboard) - prom_keyboard(); if (cmd) prom_reboot(cmd); if (*reboot_command) diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 82b4d091e4f4..577c823b0529 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -69,7 +69,6 @@ struct screen_info screen_info = { }; void (*prom_palette)(int); -void (*prom_keyboard)(void); static void prom_console_write(struct console *con, const char *s, unsigned n) From 30b3cfe1f67550bb6ec6868507a78060ef98269a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 15:26:43 -0800 Subject: [PATCH 306/880] [ATYFB]: Kill 'prom_palette' sparc code. Signed-off-by: David S. Miller --- drivers/video/aty/atyfb_base.c | 64 ---------------------------------- 1 file changed, 64 deletions(-) diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index d775eb6590b6..62f9c6e387cc 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -1913,61 +1913,6 @@ static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma) par->mmaped = 1; return 0; } - -static struct { - u32 yoffset; - u8 r[2][256]; - u8 g[2][256]; - u8 b[2][256]; -} atyfb_save; - -static void atyfb_save_palette(struct atyfb_par *par, int enter) -{ - int i, tmp; - - for (i = 0; i < 256; i++) { - tmp = aty_ld_8(DAC_CNTL, par) & 0xfc; - if (M64_HAS(EXTRA_BRIGHT)) - tmp |= 0x2; - aty_st_8(DAC_CNTL, tmp, par); - aty_st_8(DAC_MASK, 0xff, par); - - aty_st_8(DAC_R_INDEX, i, par); - atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par); - atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par); - atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par); - aty_st_8(DAC_W_INDEX, i, par); - aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par); - aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par); - aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par); - } -} - -static void atyfb_palette(int enter) -{ - struct atyfb_par *par; - struct fb_info *info; - int i; - - for (i = 0; i < FB_MAX; i++) { - info = registered_fb[i]; - if (info && info->fbops == &atyfb_ops) { - par = (struct atyfb_par *) info->par; - - atyfb_save_palette(par, enter); - if (enter) { - atyfb_save.yoffset = info->var.yoffset; - info->var.yoffset = 0; - set_off_pitch(par, info); - } else { - info->var.yoffset = atyfb_save.yoffset; - set_off_pitch(par, info); - } - aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par); - break; - } - } -} #endif /* __sparc__ */ @@ -2670,10 +2615,6 @@ static int __devinit aty_init(struct fb_info *info) goto aty_init_exit; } -#ifdef __sparc__ - atyfb_save_palette(par, 0); -#endif - #ifdef CONFIG_FB_ATY_CT if (!noaccel && M64_HAS(INTEGRATED)) aty_init_cursor(info); @@ -2900,8 +2841,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, #ifdef __sparc__ -extern void (*prom_palette) (int); - static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, unsigned long addr) { @@ -3536,9 +3475,6 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi goto err_release_io; #ifdef __sparc__ - if (!prom_palette) - prom_palette = atyfb_palette; - /* * Add /dev/fb mmap values. */ From 667bc389c716389795c6cfa145ab5ef6279fbb62 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 15:28:16 -0800 Subject: [PATCH 307/880] [SPARC]: Kill 'prom_palette'. The idea of this thing is we could save/restore the firmware's palette when breaking in and out of the firmware prompt. Only one driver implemented this (atyfb) and it's value is questionable. If you're just debugging you don't really care that the characters end up being purple or whatever. And we can provide better debugging and firmware command facilities with minimal in-kernel console I/O drivers. Signed-off-by: David S. Miller --- arch/sparc/kernel/process.c | 6 ------ arch/sparc/kernel/setup.c | 3 --- arch/sparc/prom/misc.c | 7 ------- arch/sparc64/kernel/process.c | 8 -------- arch/sparc64/kernel/setup.c | 2 -- arch/sparc64/kernel/sparc64_ksyms.c | 3 --- arch/sparc64/prom/misc.c | 9 --------- 7 files changed, 38 deletions(-) diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 19186ce8850d..0bd69d0b5cd7 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -141,16 +141,12 @@ void cpu_idle(void) extern char reboot_command []; -extern void (*prom_palette)(int); - /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ void machine_halt(void) { local_irq_enable(); mdelay(8); local_irq_disable(); - if (prom_palette) - prom_palette (1); prom_halt(); panic("Halt failed!"); } @@ -165,8 +161,6 @@ void machine_restart(char * cmd) p = strchr (reboot_command, '\n'); if (p) *p = 0; - if (prom_palette) - prom_palette (1); if (cmd) prom_reboot(cmd); if (*reboot_command) diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 5f1508eeb84d..3c13137685da 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -65,7 +65,6 @@ struct screen_info screen_info = { */ extern unsigned long trapbase; -void (*prom_palette)(int); /* Pretty sick eh? */ void prom_sync_me(void) @@ -80,8 +79,6 @@ void prom_sync_me(void) "nop\n\t" "nop\n\t" : : "r" (&trapbase)); - if (prom_palette) - prom_palette(1); prom_printf("PROM SYNC COMMAND...\n"); show_free_areas(); if(current->pid != 0) { diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c index 37cff5f54704..d9fb3af41c1f 100644 --- a/arch/sparc/prom/misc.c +++ b/arch/sparc/prom/misc.c @@ -45,9 +45,6 @@ prom_feval(char *fstring) spin_unlock_irqrestore(&prom_lock, flags); } -/* We want to do this more nicely some day. */ -extern void (*prom_palette)(int); - /* Drop into the prom, with the chance to continue with the 'go' * prom command. */ @@ -58,8 +55,6 @@ prom_cmdline(void) extern void install_linux_ticker(void); unsigned long flags; - if (prom_palette) - prom_palette (1); spin_lock_irqsave(&prom_lock, flags); install_obp_ticker(); (*(romvec->pv_abort))(); @@ -69,8 +64,6 @@ prom_cmdline(void) #ifdef CONFIG_SUN_AUXIO set_auxio(AUXIO_LED, 0); #endif - if (prom_palette) - prom_palette (0); } /* Drop into the prom, but completely terminate the program. diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index d7e8e80d43a5..6eceac51ae62 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -113,13 +113,9 @@ void cpu_idle(void) extern char reboot_command []; -extern void (*prom_palette)(int); - void machine_halt(void) { sstate_halt(); - if (prom_palette) - prom_palette (1); prom_halt(); panic("Halt failed!"); } @@ -127,8 +123,6 @@ void machine_halt(void) void machine_alt_power_off(void) { sstate_poweroff(); - if (prom_palette) - prom_palette(1); prom_halt_power_off(); panic("Power-off failed!"); } @@ -140,8 +134,6 @@ void machine_restart(char * cmd) sstate_reboot(); p = strchr (reboot_command, '\n'); if (p) *p = 0; - if (prom_palette) - prom_palette (1); if (cmd) prom_reboot(cmd); if (*reboot_command) diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 577c823b0529..d036dbe72864 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -68,8 +68,6 @@ struct screen_info screen_info = { 16 /* orig-video-points */ }; -void (*prom_palette)(int); - static void prom_console_write(struct console *con, const char *s, unsigned n) { diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 68db08930399..51fa773f38c9 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -85,7 +85,6 @@ extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); extern long sparc32_open(const char __user * filename, int flags, int mode); extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); -extern void (*prom_palette)(int); extern int __ashrdi3(int, int); @@ -355,5 +354,3 @@ EXPORT_SYMBOL(xor_niagara_2); EXPORT_SYMBOL(xor_niagara_3); EXPORT_SYMBOL(xor_niagara_4); EXPORT_SYMBOL(xor_niagara_5); - -EXPORT_SYMBOL(prom_palette); diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index bbec7522826c..47a877a15abd 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c @@ -55,9 +55,6 @@ void prom_feval(const char *fstring) P1275_INOUT(1, 1), fstring); } -/* We want to do this more nicely some day. */ -extern void (*prom_palette)(int); - #ifdef CONFIG_SMP extern void smp_capture(void); extern void smp_release(void); @@ -72,9 +69,6 @@ void prom_cmdline(void) local_irq_save(flags); - if (prom_palette) - prom_palette(1); - #ifdef CONFIG_SMP smp_capture(); #endif @@ -85,9 +79,6 @@ void prom_cmdline(void) smp_release(); #endif - if (prom_palette) - prom_palette(0); - local_irq_restore(flags); } From 8c5b4a3f43c060662d83574a4c85fbb362419ddd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 16:40:10 -0800 Subject: [PATCH 308/880] [SPARC64]: Kill pcic_present(). And also it's helper function pci_is_controller(). Both are unused. I can't remove the equivalent from sparc32 yet as some ancient bus probing code still uses that platform's version. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index a61c38fe75ea..545356b00e2e 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -225,20 +225,6 @@ static int __init pci_controller_init(const char *model_name, int namelen, struc return 0; } -static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp) -{ - int i; - - for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { - if (!strncmp(model_name, - pci_controller_table[i].model_name, - namelen)) { - return 1; - } - } - return 0; -} - static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) { struct device_node *dp; @@ -273,13 +259,6 @@ static int __init pci_controller_scan(int (*handler)(const char *, int, struct d return count; } - -/* Is there some PCI controller in the system? */ -int __init pcic_present(void) -{ - return pci_controller_scan(pci_is_controller); -} - /* Find each controller in the system, attach and initialize * software state structure for each and link into the * pci_pbm_root. Setup the controller enough such From 899e1bc57340ad9acf5561b1eff7a684975ad800 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 19 Feb 2008 01:41:24 +0100 Subject: [PATCH 309/880] ide: Add missing base addresses for falconide and macide commit 29dd59755a849cc6475faa6a75f3b804e23a6fc2 ("ide: remove ide_setup_ports") forgot to take into account the base addresses for the CONTROL registers for falconide and macide, as pointed out by Michael Schmitz. Falconide was tested on Aranym. Signed-off-by: Geert Uytterhoeven Cc: Michael Schmitz Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/falconide.c | 2 +- drivers/ide/legacy/macide.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index f044048903b3..07bf1294a9db 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c @@ -54,7 +54,7 @@ static void __init falconide_setup_ports(hw_regs_t *hw) for (i = 1; i < 8; i++) hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4; - hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_CONTROL; + hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_BASE + ATA_HD_CONTROL; hw->irq = IRQ_MFP_IDE; hw->ack_intr = NULL; diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index a61e60737dc7..9a79098d9eb4 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c @@ -74,7 +74,7 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, for (i = 0; i < 8; i++) hw->io_ports[i] = base + i * 4; - hw->io_ports[IDE_CONTROL_OFFSET] = IDE_CONTROL; + hw->io_ports[IDE_CONTROL_OFFSET] = base + IDE_CONTROL; hw->irq = irq; hw->ack_intr = ack_intr; From b152fcd34108d07a1e682786af583fd3e080cab3 Mon Sep 17 00:00:00 2001 From: Mikko Rapeli Date: Tue, 19 Feb 2008 01:41:25 +0100 Subject: [PATCH 310/880] ide/libata: ST310211A has buggy HPA too Signed-off-by: Mikko Rapeli Tested-by: Bart Champagne Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ata/libata-core.c | 1 + drivers/ide/ide-disk.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index beaa3a9d8b6d..f46eb6f6dc9f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4190,6 +4190,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Devices which report 1 sector over size HPA */ { "ST340823A", NULL, ATA_HORKAGE_HPA_SIZE, }, { "ST320413A", NULL, ATA_HORKAGE_HPA_SIZE, }, + { "ST310211A", NULL, ATA_HORKAGE_HPA_SIZE, }, /* Devices which get the IVB wrong */ { "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, }, diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index aed8b31ca561..8f5bed471050 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -397,6 +397,7 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id) static const struct drive_list_entry hpa_list[] = { { "ST340823A", NULL }, { "ST320413A", NULL }, + { "ST310211A", NULL }, { NULL, NULL } }; From ef709165d8de1ba9dd3cd5e05dbabf71dc32d883 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 19 Feb 2008 01:41:25 +0100 Subject: [PATCH 311/880] MAINTAINERS: update ide-cd maintainer's email address Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1d2edb491b34..082d1ee154a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1924,7 +1924,7 @@ S: Maintained IDE/ATAPI CDROM DRIVER P: Borislav Petkov -M: bbpetkov@yahoo.de +M: petkovbb@gmail.com L: linux-ide@vger.kernel.org S: Maintained From d684b21f89b96af3adc06877f29fd9f5214b23c8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 19 Feb 2008 01:41:25 +0100 Subject: [PATCH 312/880] falconide: locking bugfix commit 8ac4ce742c66100931b6f2d7a36b0df08bc721fe ("ide: fix host drivers depending on ide_generic to probe for interfaces (take 2)") moved probing to falconide but forgot to take care of Atari specific locking - fix it. Cc: Geert Uytterhoeven Cc: Michael Schmitz Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-generic.c | 6 ------ drivers/ide/legacy/falconide.c | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 709b9e4d2871..9ebec08eefd9 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c @@ -17,9 +17,6 @@ static int __init ide_generic_init(void) u8 idx[MAX_HWIFS]; int i; - if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) - ide_get_lock(NULL, NULL); /* for atari only */ - for (i = 0; i < MAX_HWIFS; i++) { ide_hwif_t *hwif = &ide_hwifs[i]; @@ -31,9 +28,6 @@ static int __init ide_generic_init(void) ide_device_add_all(idx, NULL); - if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) - ide_release_lock(); /* for atari only */ - return 0; } diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 07bf1294a9db..8949ce71bddc 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c @@ -84,7 +84,9 @@ static int __init falconide_init(void) ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); + ide_get_lock(NULL, NULL); ide_device_add(idx, NULL); + ide_release_lock(); } return 0; From 84f7e451e9213d8c328752d0f39bc362519d53d2 Mon Sep 17 00:00:00 2001 From: Andrew Smith Date: Tue, 19 Feb 2008 01:41:26 +0100 Subject: [PATCH 313/880] via82cxxx: add new PCI id for cx700 [bart: manually ported it over via82cxxx changes] From: Andrew Smith Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/via82cxxx.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index f3f79f805813..9004e7521889 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -479,6 +479,7 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i static const struct pci_device_id via_pci_tbl[] = { { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 }, { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 }, + { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 }, { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 }, { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 }, { 0, }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index df6dd79a0d3b..0519e53d5eb2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1351,6 +1351,7 @@ #define PCI_DEVICE_ID_VIA_8231_4 0x8235 #define PCI_DEVICE_ID_VIA_8365_1 0x8305 #define PCI_DEVICE_ID_VIA_CX700 0x8324 +#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581 #define PCI_DEVICE_ID_VIA_VX800 0x8353 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 From f401fd55b5a9ef1a4572abaefaa6957af11ced61 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 19 Feb 2008 01:41:26 +0100 Subject: [PATCH 314/880] linux/hdsmart.h: fix goofups (take 2) Fix goofups of commit 76166952bbc81dda1c8a8c14e75a2aa06f6c052c (" is not used by kernel code"). Also update include/linux/Kbuild to reflect the fact that hdsmart.h uses __KERNEL__ ifdefs now. Reported-by: "Robert P. J. Day" Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/Kbuild | 2 +- include/linux/hdsmart.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 5cae9b5960ea..aada32fffec2 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -70,7 +70,6 @@ header-y += fuse.h header-y += genetlink.h header-y += gen_stats.h header-y += gigaset_dev.h -header-y += hdsmart.h header-y += hysdn_if.h header-y += i2o-dev.h header-y += i8k.h @@ -211,6 +210,7 @@ unifdef-y += hayesesp.h unifdef-y += hdlcdrv.h unifdef-y += hdlc.h unifdef-y += hdreg.h +unifdef-y += hdsmart.h unifdef-y += hiddev.h unifdef-y += hpet.h unifdef-y += i2c.h diff --git a/include/linux/hdsmart.h b/include/linux/hdsmart.h index e69192159d40..4f4faf9d4238 100644 --- a/include/linux/hdsmart.h +++ b/include/linux/hdsmart.h @@ -17,7 +17,7 @@ #ifndef _LINUX_HDSMART_H #define _LINUX_HDSMART_H -#ifndef __KERNEL +#ifndef __KERNEL__ #define OFFLINE_FULL_SCAN 0 #define SHORT_SELF_TEST 1 #define EXTEND_SELF_TEST 2 @@ -121,6 +121,6 @@ typedef struct ata_smart_selftestlog_s { unsigned char resevered[2]; unsigned char chksum; } __attribute__ ((packed)) ata_smart_selftestlog_t; -#endif /* __KERNEL__ * +#endif /* __KERNEL__ */ #endif /* _LINUX_HDSMART_H */ From 1a1990f5479b0c9055c133b7e0e7fedfcbe11512 Mon Sep 17 00:00:00 2001 From: Jan Evert van Grootheest Date: Tue, 19 Feb 2008 01:41:26 +0100 Subject: [PATCH 315/880] ht6560b can only do up to PIO mode 4 According to the datasheet, ht6560b only supports up to PIO mode 4. [bart: manually ported it over 2.6.25-rc2] Signed-off-by: Jan Evert van Grootheest Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/ht6560b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index 02d12c74764a..2701e7d6caff 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -323,7 +323,7 @@ static const struct ide_port_info ht6560b_port_info __initdata = { IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE | IDE_HFLAG_ABUSE_PREFETCH, - .pio_mask = ATA_PIO5, + .pio_mask = ATA_PIO4, }; static int __init ht6560b_init(void) From 0e7d8d480259319649f7a2c230622b98758d1c83 Mon Sep 17 00:00:00 2001 From: Jan Evert van Grootheest Date: Tue, 19 Feb 2008 01:41:26 +0100 Subject: [PATCH 316/880] ht6560b: force prefetch for some devices Prefetch needs to be set for some ide devices to work when connected to a ht6560b interface. This was not always done properly, causing a system with a HD and CD on the primary interface to not work properly. Or, in effect, hang hard. This patch forces prefetch on devices before checking whether it is necessary to change the settings in the interface This patch should also be applied to 2.4. I don't currently have a 2.4 tree around. (also change my email address) Signed-off-by: Jan Evert van Grootheest Cc: Sergei Shtylyov Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/ht6560b.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index 2701e7d6caff..78ca68e60f97 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -21,18 +21,21 @@ * "Prefetch" mode bit OFF for ide disks and * ON for anything else. * + * Version 0.08 Need to force prefetch for CDs and other non-disk + * devices. (not sure which devices exactly need + * prefetch) * * HT-6560B EIDE-controller support * To activate controller support use kernel parameter "ide0=ht6560b". * Use hdparm utility to enable PIO mode support. * * Author: Mikko Ala-Fossi - * Jan Evert van Grootheest + * Jan Evert van Grootheest * * Try: http://www.maf.iki.fi/~maf/ht6560b/ */ -#define HT6560B_VERSION "v0.07" +#define HT6560B_VERSION "v0.08" #include #include @@ -130,15 +133,20 @@ static void ht6560b_selectproc (ide_drive_t *drive) u8 select, timing; local_irq_save(flags); - + select = HT_CONFIG(drive); timing = HT_TIMING(drive); - + + /* + * Need to enforce prefetch sometimes because otherwise + * it'll hang (hard). + */ + if (drive->media != ide_disk || !drive->present) + select |= HT_PREFETCH_MODE; + if (select != current_select || timing != current_timing) { current_select = select; current_timing = timing; - if (drive->media != ide_disk || !drive->present) - select |= HT_PREFETCH_MODE; (void)inb(HT_CONFIG_PORT); (void)inb(HT_CONFIG_PORT); (void)inb(HT_CONFIG_PORT); @@ -188,11 +196,12 @@ static int __init try_to_init_ht6560b(void) outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */ (void) inb(0x1f7); /* IDE_STATUS_REG */ - printk("\nht6560b " HT6560B_VERSION + printk("ht6560b " HT6560B_VERSION ": chipset detected and initialized" #ifdef DEBUG " with debug enabled" #endif + "\n" ); return 1; } From 14e04c3f6e64bac468f0aa38c6d47aa95b60c074 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Tue, 19 Feb 2008 01:41:26 +0100 Subject: [PATCH 317/880] ide-cd: fix missing residual count setting in DMA mode This patch fixes the missing residual count setting in DMA mode, which was introduced during the conversion to blk-end-request. The residual count could be used by the request submitter. So if it isn't set correctly, some upper layers does not work. (e.g. wodim for CD burning.) The bug is in only DMA mode. In PIO mode, we are setting the residual count correctly, so no need to fix. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Reported-by: Andreas Schwab Tested-by: Andreas Schwab Tested-by: Laura Garcia Tested-by: Borislav Petkov Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 354c91d06a6d..310e497b5838 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1207,9 +1207,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) end_request: if (blk_pc_request(rq)) { unsigned long flags; + unsigned int dlen = rq->data_len; + + if (dma) + rq->data_len = 0; spin_lock_irqsave(&ide_lock, flags); - if (__blk_end_request(rq, 0, rq->data_len)) + if (__blk_end_request(rq, 0, dlen)) BUG(); HWGROUP(drive)->rq = NULL; spin_unlock_irqrestore(&ide_lock, flags); From 8f789c48448aed74fe1c07af76de8f04adacec7d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 16:50:22 -0800 Subject: [PATCH 318/880] [NET]: Elminate spurious print_mac() calls. Patrick McHardy notes that print_mac() can get invoked even if the result it unused (f.e. as an argument to pr_debug() when DEBUG is not defined). Mark this function as "__pure" to eliminate this problem. Signed-off-by: David S. Miller --- include/linux/if_ether.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 7a1e011b8a2c..42dc6a3571ec 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -129,7 +129,7 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); /* * Display a 6 byte device address (MAC) in a readable format. */ -extern char *print_mac(char *buf, const unsigned char *addr); +extern __pure char *print_mac(char *buf, const unsigned char *addr); #define MAC_BUF_SIZE 18 #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused From b0abcfc14605b2a8c686bd8e193ab05b01a7980b Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 18 Feb 2008 18:23:16 -0500 Subject: [PATCH 319/880] Audit: use == not = in if statements Clearly this was supposed to be an == not an = in the if statement. This patch also causes us to stop processing execve args once we have failed rather than continuing to loop on failure over and over and over. Signed-off-by: Eric Paris Acked-by: Al Viro Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- kernel/auditsc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index ac6d9b23b018..2087d6de67ea 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1000,9 +1000,10 @@ static int audit_log_single_execve_arg(struct audit_context *context, * for strings that are too long, we should not have created * any. */ - if (unlikely((len = -1) || len > MAX_ARG_STRLEN - 1)) { + if (unlikely((len == -1) || len > MAX_ARG_STRLEN - 1)) { WARN_ON(1); send_sig(SIGKILL, current, 0); + return -1; } /* walk the whole argument looking for non-ascii chars */ @@ -1020,6 +1021,7 @@ static int audit_log_single_execve_arg(struct audit_context *context, if (ret) { WARN_ON(1); send_sig(SIGKILL, current, 0); + return -1; } buf[to_send] = '\0'; has_cntl = audit_string_contains_control(buf, to_send); @@ -1083,6 +1085,7 @@ static int audit_log_single_execve_arg(struct audit_context *context, if (ret) { WARN_ON(1); send_sig(SIGKILL, current, 0); + return -1; } buf[to_send] = '\0'; From 57df46d6d9ccd6ced95f169020f79ae637423087 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 18 Feb 2008 13:33:23 -0800 Subject: [PATCH 320/880] hwmon: New driver for Analog Devices ADT7473 sensor chip This driver reports voltage, temperature and fan sensor readings on an ADT7473 chip. Signed-off-by: Darrick J. Wong Signed-off-by: Mark M. Hoffman --- Documentation/hwmon/adt7473 | 79 +++ drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/adt7473.c | 1157 +++++++++++++++++++++++++++++++++++ 4 files changed, 1247 insertions(+) create mode 100644 Documentation/hwmon/adt7473 create mode 100644 drivers/hwmon/adt7473.c diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473 new file mode 100644 index 000000000000..22d8b19046ab --- /dev/null +++ b/Documentation/hwmon/adt7473 @@ -0,0 +1,79 @@ +Kernel driver adt7473 +====================== + +Supported chips: + * Analog Devices ADT7473 + Prefix: 'adt7473' + Addresses scanned: I2C 0x2C, 0x2D, 0x2E + Datasheet: Publicly available at the Analog Devices website + +Author: Darrick J. Wong + +Description +----------- + +This driver implements support for the Analog Devices ADT7473 chip family. + +The LM85 uses the 2-wire interface compatible with the SMBUS 2.0 +specification. Using an analog to digital converter it measures three (3) +temperatures and two (2) voltages. It has three (3) 16-bit counters for +measuring fan speed. There are three (3) PWM outputs that can be used +to control fan speed. + +A sophisticated control system for the PWM outputs is designed into the +LM85 that allows fan speed to be adjusted automatically based on any of the +three temperature sensors. Each PWM output is individually adjustable and +programmable. Once configured, the ADT7473 will adjust the PWM outputs in +response to the measured temperatures without further host intervention. +This feature can also be disabled for manual control of the PWM's. + +Each of the measured inputs (voltage, temperature, fan speed) has +corresponding high/low limit values. The ADT7473 will signal an ALARM if +any measured value exceeds either limit. + +The ADT7473 samples all inputs continuously. The driver will not read +the registers more often than once every other second. Further, +configuration data is only read once per minute. + +Special Features +---------------- + +The ADT7473 have a 10-bit ADC and can therefore measure temperatures +with 0.25 degC resolution. Temperature readings can be configured either +for twos complement format or "Offset 64" format, wherein 63 is subtracted +from the raw value to get the temperature value. + +The Analog Devices datasheet is very detailed and describes a procedure for +determining an optimal configuration for the automatic PWM control. + +Hardware Configurations +----------------------- + +The ADT7473 chips have an optional SMBALERT output that can be used to +signal the chipset in case a limit is exceeded or the temperature sensors +fail. Individual sensor interrupts can be masked so they won't trigger +SMBALERT. The SMBALERT output if configured replaces the PWM2 function. + +Configuration Notes +------------------- + +Besides standard interfaces driver adds the following: + +* PWM Control + +* pwm#_auto_point1_pwm and pwm#_auto_point1_temp and +* pwm#_auto_point2_pwm and pwm#_auto_point2_temp - + +point1: Set the pwm speed at a lower temperature bound. +point2: Set the pwm speed at a higher temperature bound. + +The ADT7473 will scale the pwm between the lower and higher pwm speed when +the temperature is between the two temperature boundaries. PWM values range +from 0 (off) to 255 (full speed). + +Notes +----- + +The NVIDIA binary driver presents an ADT7473 chip via an on-card i2c bus. +Unfortunately, they fail to set the i2c adapter class, so this driver may +fail to find the chip until the nvidia driver is patched. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 410ffe4e9d80..368879ff5d8c 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -143,6 +143,16 @@ config SENSORS_ADT7470 This driver can also be built as a module. If so, the module will be called adt7470. +config SENSORS_ADT7473 + tristate "Analog Devices ADT7473" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Analog Devices + ADT7473 temperature monitoring chips. + + This driver can also be built as a module. If so, the module + will be called adt7473. + config SENSORS_K8TEMP tristate "AMD Athlon64/FX or Opteron temperature sensor" depends on X86 && PCI && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 824161337f1c..3bdb05a5cbd7 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o +obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_AMS) += ams/ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c new file mode 100644 index 000000000000..a3daeefff472 --- /dev/null +++ b/drivers/hwmon/adt7473.c @@ -0,0 +1,1157 @@ +/* + * A hwmon driver for the Analog Devices ADT7473 + * Copyright (C) 2007 IBM + * + * Author: Darrick J. Wong + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_1(adt7473); + +/* ADT7473 registers */ +#define ADT7473_REG_BASE_ADDR 0x20 + +#define ADT7473_REG_VOLT_BASE_ADDR 0x21 +#define ADT7473_REG_VOLT_MAX_ADDR 0x22 +#define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46 +#define ADT7473_REG_VOLT_MIN_MAX_ADDR 0x49 + +#define ADT7473_REG_TEMP_BASE_ADDR 0x25 +#define ADT7473_REG_TEMP_MAX_ADDR 0x27 +#define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E +#define ADT7473_REG_TEMP_LIMITS_MAX_ADDR 0x53 +#define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67 +#define ADT7473_REG_TEMP_TMIN_MAX_ADDR 0x69 +#define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A +#define ADT7473_REG_TEMP_TMAX_MAX_ADDR 0x6C + +#define ADT7473_REG_FAN_BASE_ADDR 0x28 +#define ADT7473_REG_FAN_MAX_ADDR 0x2F +#define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54 +#define ADT7473_REG_FAN_MIN_MAX_ADDR 0x5B + +#define ADT7473_REG_PWM_BASE_ADDR 0x30 +#define ADT7473_REG_PWM_MAX_ADDR 0x32 +#define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64 +#define ADT7473_REG_PWM_MIN_MAX_ADDR 0x66 +#define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38 +#define ADT7473_REG_PWM_MAX_MAX_ADDR 0x3A +#define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C +#define ADT7473_REG_PWM_BHVR_MAX_ADDR 0x5E +#define ADT7473_PWM_BHVR_MASK 0xE0 +#define ADT7473_PWM_BHVR_SHIFT 5 + +#define ADT7473_REG_CFG1 0x40 +#define ADT7473_CFG1_START 0x01 +#define ADT7473_CFG1_READY 0x04 +#define ADT7473_REG_CFG2 0x73 +#define ADT7473_REG_CFG3 0x78 +#define ADT7473_REG_CFG4 0x7D +#define ADT7473_CFG4_MAX_DUTY_AT_OVT 0x08 +#define ADT7473_REG_CFG5 0x7C +#define ADT7473_CFG5_TEMP_TWOS 0x01 +#define ADT7473_CFG5_TEMP_OFFSET 0x02 + +#define ADT7473_REG_DEVICE 0x3D +#define ADT7473_VENDOR 0x41 +#define ADT7473_REG_VENDOR 0x3E +#define ADT7473_DEVICE 0x73 +#define ADT7473_REG_REVISION 0x3F +#define ADT7473_REV_68 0x68 +#define ADT7473_REV_69 0x69 + +#define ADT7473_REG_ALARM1 0x41 +#define ADT7473_VCCP_ALARM 0x02 +#define ADT7473_VCC_ALARM 0x04 +#define ADT7473_R1T_ALARM 0x10 +#define ADT7473_LT_ALARM 0x20 +#define ADT7473_R2T_ALARM 0x40 +#define ADT7473_OOL 0x80 +#define ADT7473_REG_ALARM2 0x42 +#define ADT7473_OVT_ALARM 0x02 +#define ADT7473_FAN1_ALARM 0x04 +#define ADT7473_FAN2_ALARM 0x08 +#define ADT7473_FAN3_ALARM 0x10 +#define ADT7473_FAN4_ALARM 0x20 +#define ADT7473_R1T_SHORT 0x40 +#define ADT7473_R2T_SHORT 0x80 +#define ADT7473_REG_MAX_ADDR 0x80 + +#define ALARM2(x) ((x) << 8) + +#define ADT7473_VOLT_COUNT 2 +#define ADT7473_REG_VOLT(x) (ADT7473_REG_VOLT_BASE_ADDR + (x)) +#define ADT7473_REG_VOLT_MIN(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + ((x) * 2)) +#define ADT7473_REG_VOLT_MAX(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + \ + ((x) * 2) + 1) + +#define ADT7473_TEMP_COUNT 3 +#define ADT7473_REG_TEMP(x) (ADT7473_REG_TEMP_BASE_ADDR + (x)) +#define ADT7473_REG_TEMP_MIN(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2)) +#define ADT7473_REG_TEMP_MAX(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + \ + ((x) * 2) + 1) +#define ADT7473_REG_TEMP_TMIN(x) (ADT7473_REG_TEMP_TMIN_BASE_ADDR + (x)) +#define ADT7473_REG_TEMP_TMAX(x) (ADT7473_REG_TEMP_TMAX_BASE_ADDR + (x)) + +#define ADT7473_FAN_COUNT 4 +#define ADT7473_REG_FAN(x) (ADT7473_REG_FAN_BASE_ADDR + ((x) * 2)) +#define ADT7473_REG_FAN_MIN(x) (ADT7473_REG_FAN_MIN_BASE_ADDR + ((x) * 2)) + +#define ADT7473_PWM_COUNT 3 +#define ADT7473_REG_PWM(x) (ADT7473_REG_PWM_BASE_ADDR + (x)) +#define ADT7473_REG_PWM_MAX(x) (ADT7473_REG_PWM_MAX_BASE_ADDR + (x)) +#define ADT7473_REG_PWM_MIN(x) (ADT7473_REG_PWM_MIN_BASE_ADDR + (x)) +#define ADT7473_REG_PWM_BHVR(x) (ADT7473_REG_PWM_BHVR_BASE_ADDR + (x)) + +/* How often do we reread sensors values? (In jiffies) */ +#define SENSOR_REFRESH_INTERVAL (2 * HZ) + +/* How often do we reread sensor limit values? (In jiffies) */ +#define LIMIT_REFRESH_INTERVAL (60 * HZ) + +/* datasheet says to divide this number by the fan reading to get fan rpm */ +#define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) +#define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM +#define FAN_PERIOD_INVALID 65535 +#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) + +struct adt7473_data { + struct i2c_client client; + struct device *hwmon_dev; + struct attribute_group attrs; + struct mutex lock; + char sensors_valid; + char limits_valid; + unsigned long sensors_last_updated; /* In jiffies */ + unsigned long limits_last_updated; /* In jiffies */ + + u8 volt[ADT7473_VOLT_COUNT]; + s8 volt_min[ADT7473_VOLT_COUNT]; + s8 volt_max[ADT7473_VOLT_COUNT]; + + s8 temp[ADT7473_TEMP_COUNT]; + s8 temp_min[ADT7473_TEMP_COUNT]; + s8 temp_max[ADT7473_TEMP_COUNT]; + s8 temp_tmin[ADT7473_TEMP_COUNT]; + /* This is called the !THERM limit in the datasheet */ + s8 temp_tmax[ADT7473_TEMP_COUNT]; + + u16 fan[ADT7473_FAN_COUNT]; + u16 fan_min[ADT7473_FAN_COUNT]; + + u8 pwm[ADT7473_PWM_COUNT]; + u8 pwm_max[ADT7473_PWM_COUNT]; + u8 pwm_min[ADT7473_PWM_COUNT]; + u8 pwm_behavior[ADT7473_PWM_COUNT]; + + u8 temp_twos_complement; + u8 temp_offset; + + u16 alarm; + u8 max_duty_at_overheat; +}; + +static int adt7473_attach_adapter(struct i2c_adapter *adapter); +static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind); +static int adt7473_detach_client(struct i2c_client *client); + +static struct i2c_driver adt7473_driver = { + .driver = { + .name = "adt7473", + }, + .attach_adapter = adt7473_attach_adapter, + .detach_client = adt7473_detach_client, +}; + +/* + * 16-bit registers on the ADT7473 are low-byte first. The data sheet says + * that the low byte must be read before the high byte. + */ +static inline int adt7473_read_word_data(struct i2c_client *client, u8 reg) +{ + u16 foo; + foo = i2c_smbus_read_byte_data(client, reg); + foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); + return foo; +} + +static inline int adt7473_write_word_data(struct i2c_client *client, u8 reg, + u16 value) +{ + return i2c_smbus_write_byte_data(client, reg, value & 0xFF) + && i2c_smbus_write_byte_data(client, reg + 1, value >> 8); +} + +static void adt7473_init_client(struct i2c_client *client) +{ + int reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG1); + + if (!(reg & ADT7473_CFG1_READY)) { + dev_err(&client->dev, "Chip not ready.\n"); + } else { + /* start monitoring */ + i2c_smbus_write_byte_data(client, ADT7473_REG_CFG1, + reg | ADT7473_CFG1_START); + } +} + +static struct adt7473_data *adt7473_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + unsigned long local_jiffies = jiffies; + u8 cfg; + int i; + + mutex_lock(&data->lock); + if (time_before(local_jiffies, data->sensors_last_updated + + SENSOR_REFRESH_INTERVAL) + && data->sensors_valid) + goto no_sensor_update; + + for (i = 0; i < ADT7473_VOLT_COUNT; i++) + data->volt[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_VOLT(i)); + + /* Determine temperature encoding */ + cfg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG5); + data->temp_twos_complement = (cfg & ADT7473_CFG5_TEMP_TWOS); + + /* + * What does this do? it implies a variable temperature sensor + * offset, but the datasheet doesn't say anything about this bit + * and other parts of the datasheet imply that "offset64" mode + * means that you shift temp values by -64 if the above bit was set. + */ + data->temp_offset = (cfg & ADT7473_CFG5_TEMP_OFFSET); + + for (i = 0; i < ADT7473_TEMP_COUNT; i++) + data->temp[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP(i)); + + for (i = 0; i < ADT7473_FAN_COUNT; i++) + data->fan[i] = adt7473_read_word_data(client, + ADT7473_REG_FAN(i)); + + for (i = 0; i < ADT7473_PWM_COUNT; i++) + data->pwm[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM(i)); + + data->alarm = i2c_smbus_read_byte_data(client, ADT7473_REG_ALARM1); + if (data->alarm & ADT7473_OOL) + data->alarm |= ALARM2(i2c_smbus_read_byte_data(client, + ADT7473_REG_ALARM2)); + + data->sensors_last_updated = local_jiffies; + data->sensors_valid = 1; + +no_sensor_update: + if (time_before(local_jiffies, data->limits_last_updated + + LIMIT_REFRESH_INTERVAL) + && data->limits_valid) + goto out; + + for (i = 0; i < ADT7473_VOLT_COUNT; i++) { + data->volt_min[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_VOLT_MIN(i)); + data->volt_max[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_VOLT_MAX(i)); + } + + for (i = 0; i < ADT7473_TEMP_COUNT; i++) { + data->temp_min[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_MIN(i)); + data->temp_max[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_MAX(i)); + data->temp_tmin[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_TMIN(i)); + data->temp_tmax[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_TMAX(i)); + } + + for (i = 0; i < ADT7473_FAN_COUNT; i++) + data->fan_min[i] = adt7473_read_word_data(client, + ADT7473_REG_FAN_MIN(i)); + + for (i = 0; i < ADT7473_PWM_COUNT; i++) { + data->pwm_max[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_MAX(i)); + data->pwm_min[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_MIN(i)); + data->pwm_behavior[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_BHVR(i)); + } + + data->limits_last_updated = local_jiffies; + data->limits_valid = 1; + +out: + mutex_unlock(&data->lock); + return data; +} + +/* + * On this chip, voltages are given as a count of steps between a minimum + * and maximum voltage, not a direct voltage. + */ +static const int volt_convert_table[][2] = { + {2997, 3}, + {4395, 4}, +}; + +static int decode_volt(int volt_index, u8 raw) +{ + int cmax = volt_convert_table[volt_index][0]; + int cmin = volt_convert_table[volt_index][1]; + return ((raw * (cmax - cmin)) / 255) + cmin; +} + +static u8 encode_volt(int volt_index, int cooked) +{ + int cmax = volt_convert_table[volt_index][0]; + int cmin = volt_convert_table[volt_index][1]; + u8 x; + + if (cooked > cmax) + cooked = cmax; + else if (cooked < cmin) + cooked = cmin; + + x = ((cooked - cmin) * 255) / (cmax - cmin); + + return x; +} + +static ssize_t show_volt_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + decode_volt(attr->index, data->volt_min[attr->index])); +} + +static ssize_t set_volt_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); + + mutex_lock(&data->lock); + data->volt_min[attr->index] = volt; + i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MIN(attr->index), + volt); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_volt_max(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + decode_volt(attr->index, data->volt_max[attr->index])); +} + +static ssize_t set_volt_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); + + mutex_lock(&data->lock); + data->volt_max[attr->index] = volt; + i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MAX(attr->index), + volt); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_volt(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + return sprintf(buf, "%d\n", + decode_volt(attr->index, data->volt[attr->index])); +} + +/* + * This chip can report temperature data either as a two's complement + * number in the range -128 to 127, or as an unsigned number that must + * be offset by 64. + */ +static int decode_temp(struct adt7473_data *data, u8 raw) +{ + if (data->temp_twos_complement) + return (s8)raw; + return raw - 64; +} + +static u8 encode_temp(struct adt7473_data *data, int cooked) +{ + if (data->temp_twos_complement) + return (cooked & 0xFF); + return cooked + 64; +} + +static ssize_t show_temp_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_min[attr->index])); +} + +static ssize_t set_temp_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_min[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MIN(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp_max(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_max[attr->index])); +} + +static ssize_t set_temp_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_max[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MAX(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp[attr->index])); +} + +static ssize_t show_fan_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + if (FAN_DATA_VALID(data->fan_min[attr->index])) + return sprintf(buf, "%d\n", + FAN_PERIOD_TO_RPM(data->fan_min[attr->index])); + else + return sprintf(buf, "0\n"); +} + +static ssize_t set_fan_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + if (!temp) + return -EINVAL; + temp = FAN_RPM_TO_PERIOD(temp); + + mutex_lock(&data->lock); + data->fan_min[attr->index] = temp; + adt7473_write_word_data(client, ADT7473_REG_FAN_MIN(attr->index), temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + if (FAN_DATA_VALID(data->fan[attr->index])) + return sprintf(buf, "%d\n", + FAN_PERIOD_TO_RPM(data->fan[attr->index])); + else + return sprintf(buf, "0\n"); +} + +static ssize_t show_max_duty_at_crit(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->max_duty_at_overheat); +} + +static ssize_t set_max_duty_at_crit(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + u8 reg; + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + temp = temp && 0xFF; + + mutex_lock(&data->lock); + data->max_duty_at_overheat = temp; + reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4); + if (temp) + reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT; + else + reg &= ~ADT7473_CFG4_MAX_DUTY_AT_OVT; + i2c_smbus_write_byte_data(client, ADT7473_REG_CFG4, reg); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->pwm[attr->index]); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->lock); + data->pwm[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM(attr->index), temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_max(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->pwm_max[attr->index]); +} + +static ssize_t set_pwm_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->lock); + data->pwm_max[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MAX(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->pwm_min[attr->index]); +} + +static ssize_t set_pwm_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->lock); + data->pwm_min[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MIN(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp_tmax(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_tmax[attr->index])); +} + +static ssize_t set_temp_tmax(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_tmax[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMAX(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp_tmin(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_tmin[attr->index])); +} + +static ssize_t set_temp_tmin(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_tmin[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMIN(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_enable(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + switch (data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT) { + case 3: + return sprintf(buf, "0\n"); + case 7: + return sprintf(buf, "1\n"); + default: + return sprintf(buf, "2\n"); + } +} + +static ssize_t set_pwm_enable(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + u8 reg; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + switch (temp) { + case 0: + temp = 3; + break; + case 1: + temp = 7; + break; + case 2: + /* Enter automatic mode with fans off */ + temp = 4; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->lock); + reg = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_BHVR(attr->index)); + reg = (temp << ADT7473_PWM_BHVR_SHIFT) | + (reg & ~ADT7473_PWM_BHVR_MASK); + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index), + reg); + data->pwm_behavior[attr->index] = reg; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_auto_temp(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + int bhvr = data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT; + + switch (bhvr) { + case 3: + case 4: + case 7: + return sprintf(buf, "0\n"); + case 0: + case 1: + case 5: + case 6: + return sprintf(buf, "%d\n", bhvr + 1); + case 2: + return sprintf(buf, "4\n"); + } + /* shouldn't ever get here */ + BUG(); +} + +static ssize_t set_pwm_auto_temp(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + u8 reg; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + switch (temp) { + case 1: + case 2: + case 6: + case 7: + temp--; + break; + case 0: + temp = 4; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->lock); + reg = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_BHVR(attr->index)); + reg = (temp << ADT7473_PWM_BHVR_SHIFT) | + (reg & ~ADT7473_PWM_BHVR_MASK); + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index), + reg); + data->pwm_behavior[attr->index] = reg; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_alarm(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + if (data->alarm & attr->index) + return sprintf(buf, "1\n"); + else + return sprintf(buf, "0\n"); +} + + +static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max, + set_volt_max, 0); +static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max, + set_volt_max, 1); + +static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min, + set_volt_min, 0); +static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min, + set_volt_min, 1); + +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_volt, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_volt, NULL, 1); + +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_VCCP_ALARM); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_VCC_ALARM); + +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, + set_temp_max, 0); +static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, + set_temp_max, 1); +static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, + set_temp_max, 2); + +static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, + set_temp_min, 0); +static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, + set_temp_min, 1); +static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, + set_temp_min, 2); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); + +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_R1T_ALARM | ALARM2(ADT7473_R1T_SHORT)); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_LT_ALARM); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_R2T_ALARM | ALARM2(ADT7473_R2T_SHORT)); + +static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 0); +static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 1); +static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 2); +static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 3); + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); + +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN1_ALARM)); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN2_ALARM)); +static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN3_ALARM)); +static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN4_ALARM)); + +static SENSOR_DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO, + show_max_duty_at_crit, set_max_duty_at_crit, 0); + +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); + +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, + show_pwm_min, set_pwm_min, 0); +static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, + show_pwm_min, set_pwm_min, 1); +static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, + show_pwm_min, set_pwm_min, 2); + +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, + show_pwm_max, set_pwm_max, 0); +static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, + show_pwm_max, set_pwm_max, 1); +static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, + show_pwm_max, set_pwm_max, 2); + +static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO, + show_temp_tmin, set_temp_tmin, 0); +static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, + show_temp_tmin, set_temp_tmin, 1); +static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO, + show_temp_tmin, set_temp_tmin, 2); + +static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, + show_temp_tmax, set_temp_tmax, 0); +static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, + show_temp_tmax, set_temp_tmax, 1); +static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO, + show_temp_tmax, set_temp_tmax, 2); + +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + set_pwm_enable, 0); +static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + set_pwm_enable, 1); +static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + set_pwm_enable, 2); + +static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, + show_pwm_auto_temp, set_pwm_auto_temp, 0); +static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, + show_pwm_auto_temp, set_pwm_auto_temp, 1); +static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, + show_pwm_auto_temp, set_pwm_auto_temp, 2); + +static struct attribute *adt7473_attr[] = +{ + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, + + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, + &sensor_dev_attr_fan4_alarm.dev_attr.attr, + + &sensor_dev_attr_pwm_use_point2_pwm_at_crit.dev_attr.attr, + + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, + + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm2_enable.dev_attr.attr, + &sensor_dev_attr_pwm3_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, + + NULL +}; + +static int adt7473_attach_adapter(struct i2c_adapter *adapter) +{ + if (!(adapter->class & I2C_CLASS_HWMON)) + return 0; + return i2c_probe(adapter, &addr_data, adt7473_detect); +} + +static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *client; + struct adt7473_data *data; + int err = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + goto exit; + + data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + client = &data->client; + client->addr = address; + client->adapter = adapter; + client->driver = &adt7473_driver; + + i2c_set_clientdata(client, data); + + mutex_init(&data->lock); + + if (kind <= 0) { + int vendor, device, revision; + + vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR); + if (vendor != ADT7473_VENDOR) { + err = -ENODEV; + goto exit_free; + } + + device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE); + if (device != ADT7473_DEVICE) { + err = -ENODEV; + goto exit_free; + } + + revision = i2c_smbus_read_byte_data(client, + ADT7473_REG_REVISION); + if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69) { + err = -ENODEV; + goto exit_free; + } + } else + dev_dbg(&adapter->dev, "detection forced\n"); + + strlcpy(client->name, "adt7473", I2C_NAME_SIZE); + + err = i2c_attach_client(client); + if (err) + goto exit_free; + + dev_info(&client->dev, "%s chip found\n", client->name); + + /* Initialize the ADT7473 chip */ + adt7473_init_client(client); + + /* Register sysfs hooks */ + data->attrs.attrs = adt7473_attr; + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) + goto exit_detach; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->attrs); +exit_detach: + i2c_detach_client(client); +exit_free: + kfree(data); +exit: + return err; +} + +static int adt7473_detach_client(struct i2c_client *client) +{ + struct adt7473_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->attrs); + i2c_detach_client(client); + kfree(data); + return 0; +} + +static int __init adt7473_init(void) +{ + return i2c_add_driver(&adt7473_driver); +} + +static void __exit adt7473_exit(void) +{ + i2c_del_driver(&adt7473_driver); +} + +MODULE_AUTHOR("Darrick J. Wong "); +MODULE_DESCRIPTION("ADT7473 driver"); +MODULE_LICENSE("GPL"); + +module_init(adt7473_init); +module_exit(adt7473_exit); From 25e9c86d5a6d82ea45eb680fc66bf73ac5e50dff Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sun, 17 Feb 2008 22:28:03 -0500 Subject: [PATCH 321/880] hwmon: normal_i2c arrays should be const Signed-off-by: Mark M. Hoffman --- drivers/hwmon/ad7418.c | 2 +- drivers/hwmon/adm1021.c | 6 ++---- drivers/hwmon/adm1025.c | 2 +- drivers/hwmon/adm1026.c | 2 +- drivers/hwmon/adm1029.c | 6 ++---- drivers/hwmon/adm1031.c | 2 +- drivers/hwmon/adm9240.c | 2 +- drivers/hwmon/ads7828.c | 2 +- drivers/hwmon/adt7470.c | 2 +- drivers/hwmon/adt7473.c | 2 +- drivers/hwmon/asb100.c | 2 +- drivers/hwmon/atxp1.c | 2 +- drivers/hwmon/dme1737.c | 2 +- drivers/hwmon/ds1621.c | 2 +- drivers/hwmon/f75375s.c | 2 +- drivers/hwmon/fscher.c | 2 +- drivers/hwmon/fschmd.c | 2 +- drivers/hwmon/fscpos.c | 2 +- drivers/hwmon/gl518sm.c | 2 +- drivers/hwmon/gl520sm.c | 2 +- drivers/hwmon/lm63.c | 2 +- drivers/hwmon/lm75.c | 2 +- drivers/hwmon/lm77.c | 3 ++- drivers/hwmon/lm78.c | 4 ++-- drivers/hwmon/lm80.c | 4 ++-- drivers/hwmon/lm83.c | 6 ++---- drivers/hwmon/lm85.c | 2 +- drivers/hwmon/lm87.c | 2 +- drivers/hwmon/lm90.c | 6 ++---- drivers/hwmon/lm92.c | 4 ++-- drivers/hwmon/lm93.c | 2 +- drivers/hwmon/max1619.c | 6 ++---- drivers/hwmon/max6650.c | 3 ++- drivers/hwmon/smsc47m192.c | 2 +- drivers/hwmon/thmc50.c | 2 +- drivers/hwmon/w83781d.c | 4 ++-- drivers/hwmon/w83791d.c | 3 ++- drivers/hwmon/w83792d.c | 3 ++- drivers/hwmon/w83793.c | 3 ++- drivers/hwmon/w83l785ts.c | 2 +- drivers/hwmon/w83l786ng.c | 2 +- 41 files changed, 55 insertions(+), 60 deletions(-) diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index fcd7fe78f3f9..466b9ee92797 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c @@ -26,7 +26,7 @@ #define DRV_VERSION "0.3" /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_3(ad7416, ad7417, ad7418); diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index b96be772e498..ecbf69484bf5 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -31,10 +31,8 @@ /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index e96c3725203d..1d76de7d75c7 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -62,7 +62,7 @@ * NE1619 has two possible addresses: 0x2c and 0x2d. */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index b3e6b06caf61..904c6ce9d83f 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -35,7 +35,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(adm1026); diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 0bc897dffa27..2c6608d453c2 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -39,10 +39,8 @@ * Addresses to scan */ -static unsigned short normal_i2c[] = { - 0x28, 0x29, 0x2a, - 0x2b, 0x2c, 0x2d, - 0x2e, 0x2f, I2C_CLIENT_END +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; /* diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 5aaad3636c98..2bffcab7dc9f 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -61,7 +61,7 @@ #define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan)) /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(adm1030, adm1031); diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 7671d2bf7800..149ef25252e7 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -52,7 +52,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index 6b8a73ef404c..ed71a8bc70dc 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -44,7 +44,7 @@ #define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */ /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 747693ab2ff1..6b5325f33a2c 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -30,7 +30,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(adt7470); diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index a3daeefff472..9587869bdba0 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c @@ -30,7 +30,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(adt7473); diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 950cea8d1d65..84712a22acea 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -49,7 +49,7 @@ #include "lm75.h" /* I2C addresses to scan */ -static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(asb100); diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index cce3350e539e..01c17e387f03 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -42,7 +42,7 @@ MODULE_AUTHOR("Sebastian Witt "); #define ATXP1_VIDMASK 0x1f #define ATXP1_GPIO1MASK 0x0f -static unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; I2C_CLIENT_INSMOD_1(atxp1); diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index ddddd9f34c19..7673f65877e1 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -49,7 +49,7 @@ module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); /* Addresses to scan */ -static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; +static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(dme1737); diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 3f5163de13c1..5f300ffed657 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -34,7 +34,7 @@ #include "lm75.h" /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 6892f76fc18a..1464338e4e11 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -37,7 +37,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(f75373, f75375); diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index 721c70177b17..ed26b66e0831 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c @@ -40,7 +40,7 @@ * Addresses to scan */ -static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index b7c9eef0f928..bd89d270a5ed 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -44,7 +44,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd); diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 2f1075323a1e..00f48484e54b 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c @@ -43,7 +43,7 @@ /* * Addresses to scan */ -static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 3b1ac48fce23..33e9e8a8d1ce 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -44,7 +44,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80); diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 03ecdc334764..8984ef141627 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -39,7 +39,7 @@ module_param(extra_sensor_type, ushort, 0); MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=temperature, 2=voltage)"); /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(gl520sm); diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 650b07d5b902..116287008083 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -53,7 +53,7 @@ * Address is fully defined internally and cannot be changed. */ -static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index e5c35a355a57..115f4090b98e 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -31,7 +31,7 @@ /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 459b70ad6bee..36d5a8c3ad8c 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -36,7 +36,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm77); diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 0a9eb1f6f4e4..ed7859f0e16a 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -37,8 +37,8 @@ static struct platform_device *pdev; /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, - 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; static unsigned short isa_address = 0x290; /* Insmod parameters */ diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index a2ca055f3922..26c91c9d4769 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -32,8 +32,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm80); diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 6e8903a6e902..6a8642fa25fb 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -48,10 +48,8 @@ * addresses. */ -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 4bb0f291a6b8..182fe6a5605f 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -35,7 +35,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 8ee07c5c97a1..e1c183f0aae0 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -73,7 +73,7 @@ * LM87 has three possible addresses: 0x2c, 0x2d and 0x2e. */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index f7ec95bedbf6..d1a3da3dd8e0 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -101,10 +101,8 @@ * 0x4c, 0x4d or 0x4e. */ -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index a2b804115ce5..c31942e08246 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -51,8 +51,8 @@ /* The LM92 and MAX6635 have 2 two-state pins for address selection, resulting in 4 possible addresses. */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm92); diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index ea61946a4bf7..5e678f5c883d 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -142,7 +142,7 @@ I2C_FUNC_SMBUS_WORD_DATA) /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm93); diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 342803417973..7e7267a04544 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -37,10 +37,8 @@ #include #include -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 755570c1f4eb..52d528b76cc3 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -44,7 +44,8 @@ * Addresses to scan. There are four disjoint possibilities, by pin config. */ -static unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, I2C_CLIENT_END}; +static const unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, + I2C_CLIENT_END}; /* * Insmod parameters diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 8b0c188e60f6..3c9db6598ba7 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -34,7 +34,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(smsc47m192); diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index a42a03c24367..76a3859c3fbe 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(thmc50, adm1022); diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 7421f6ea53e1..5c85670e2d16 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -53,8 +53,8 @@ static struct platform_device *pdev; /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, - 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; static unsigned short isa_address = 0x290; /* Insmod parameters */ diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 85bd21ee3298..85077c4c8039 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -47,7 +47,8 @@ #define NUMBER_OF_TEMPIN 3 /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83791d); diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 007449d3e16e..299629d47ed6 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -46,7 +46,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83792d); diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 3ba1d6b33473..ee35af93b574 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -37,7 +37,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83793); diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 1d6259d29e74..77f2d482888b 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -49,7 +49,7 @@ * Address is fully defined internally and cannot be changed. */ -static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 1dbee4fa23ad..41e22ddb568a 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -35,7 +35,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83l786ng); From 0cd63c8089f0f6316df1393c3a93bdbc67ab314d Mon Sep 17 00:00:00 2001 From: Dave Young Date: Mon, 18 Feb 2008 20:44:01 -0800 Subject: [PATCH 322/880] bluetooth: put hci dev after del conn Move hci_dev_put to del_conn to avoid hci dev going away before hci conn. Signed-off-by: Dave Young Signed-off-by: David S. Miller --- net/bluetooth/hci_conn.c | 1 - net/bluetooth/hci_sysfs.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 5fc7be206f62..f8880261da0e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -260,7 +260,6 @@ int hci_conn_del(struct hci_conn *conn) tasklet_enable(&hdev->tx_task); skb_queue_purge(&conn->data_q); hci_conn_del_sysfs(conn); - hci_dev_put(hdev); return 0; } diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index f5aff6d0988a..767756c8fbcf 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -334,6 +334,7 @@ static int __match_tty(struct device *dev, void *data) static void del_conn(struct work_struct *work) { struct hci_conn *conn = container_of(work, struct hci_conn, work); + struct hci_dev *hdev = conn->hdev; while (1) { struct device *dev; @@ -344,8 +345,10 @@ static void del_conn(struct work_struct *work) device_move(dev, NULL); put_device(dev); } + device_del(&conn->dev); put_device(&conn->dev); + hci_dev_put(hdev); } void hci_conn_del_sysfs(struct hci_conn *conn) From b7d0640f9229a9426ba9223796329c4f0cc4acb9 Mon Sep 17 00:00:00 2001 From: Stuart Bennett Date: Tue, 8 Jan 2008 13:13:28 +0000 Subject: [PATCH 323/880] agp/sis: Clear bit 2 from aperture size byte as well SiS M650 has aperture size byte 0x44 Signed-off-by: Dave Airlie --- drivers/char/agp/sis-agp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index eb1a1c738190..aaa1883f076c 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -27,8 +27,8 @@ static int sis_fetch_size(void) values = A_SIZE_8(agp_bridge->driver->aperture_sizes); for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { if ((temp_size == values[i].size_value) || - ((temp_size & ~(0x03)) == - (values[i].size_value & ~(0x03)))) { + ((temp_size & ~(0x07)) == + (values[i].size_value & ~(0x07)))) { agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i); From 16469a0ea0f6b7562eac98ebb8a7c41ce902d0b1 Mon Sep 17 00:00:00 2001 From: Stuart Bennett Date: Tue, 8 Jan 2008 13:14:07 +0000 Subject: [PATCH 324/880] agp/sis: Suspend support for SiS AGP Tested on M650 chipset Signed-off-by: Dave Airlie --- drivers/char/agp/sis-agp.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index aaa1883f076c..6cf54fe60207 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -214,6 +214,26 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev) agp_put_bridge(bridge); } +#ifdef CONFIG_PM + +static int agp_sis_suspend(struct pci_dev *pdev, pm_message_t state) +{ + pci_save_state(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static int agp_sis_resume(struct pci_dev *pdev) +{ + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + return sis_driver.configure(); +} + +#endif /* CONFIG_PM */ + static struct pci_device_id agp_sis_pci_table[] = { { .class = (PCI_CLASS_BRIDGE_HOST << 8), @@ -393,6 +413,10 @@ static struct pci_driver agp_sis_pci_driver = { .id_table = agp_sis_pci_table, .probe = agp_sis_probe, .remove = agp_sis_remove, +#ifdef CONFIG_PM + .suspend = agp_sis_suspend, + .resume = agp_sis_resume, +#endif }; static int __init agp_sis_init(void) From 8ac62dc773c149d7b7124b4912b425842f905d3e Mon Sep 17 00:00:00 2001 From: Dave Young Date: Mon, 18 Feb 2008 20:45:41 -0800 Subject: [PATCH 325/880] bluetooth: do not move child device other than rfcomm hci conn child devices other than rfcomm tty should not be moved here. This is my lost, thanks for Barnaby's reporting and testing. Signed-off-by: Dave Young Signed-off-by: David S. Miller --- net/bluetooth/hci_sysfs.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 767756c8fbcf..84360c117d4e 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -320,15 +320,14 @@ void hci_conn_add_sysfs(struct hci_conn *conn) queue_work(btaddconn, &conn->work); } +/* + * The rfcomm tty device will possibly retain even when conn + * is down, and sysfs doesn't support move zombie device, + * so we should move the device before conn device is destroyed. + */ static int __match_tty(struct device *dev, void *data) { - /* The rfcomm tty device will possibly retain even when conn - * is down, and sysfs doesn't support move zombie device, - * so we should move the device before conn device is destroyed. - * Due to the only child device of hci_conn dev is rfcomm - * tty_dev, here just return 1 - */ - return 1; + return !strncmp(dev->bus_id, "rfcomm", 6); } static void del_conn(struct work_struct *work) From fcea424d31868a78366ad5ee0cb3cc2a4cbe689b Mon Sep 17 00:00:00 2001 From: Arjan van dev Ven Date: Wed, 6 Feb 2008 05:16:00 +0100 Subject: [PATCH 326/880] fix historic ioremap() abuse in AGP Several AGP drivers right now use ioremap_nocache() on kernel ram in order to turn a page of regular memory uncached. There are two problems with this: 1) This is a total nightmare for the ioremap() implementation to keep various mappings of the same page coherent. 2) It's a total nightmare for the AGP code since it adds a ton of complexity in terms of keeping track of 2 different pointers to the same thing, in terms of error handling etc etc. This patch fixes this by making the AGP drivers use the new set_memory_XX APIs instead. Note: amd-k7-agp.c is built on Alpha too, and generic.c is built on ia64 as well, which do not yet have the set_memory_*() APIs, so for them some we have a few ugly #ifdefs - hopefully they'll be fixed soon. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Dave Airlie --- arch/x86/mm/ioremap.c | 2 ++ drivers/char/agp/amd-k7-agp.c | 9 +++++++++ drivers/char/agp/ati-agp.c | 16 +++------------- drivers/char/agp/generic.c | 9 +++++++++ drivers/char/agp/sworks-agp.c | 18 +++++------------- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 9f42d7e9c158..69f4981db80f 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -126,6 +126,8 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, return NULL; } + WARN_ON_ONCE(page_is_ram(pfn)); + switch (mode) { case IOR_MODE_UNCACHED: default: diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 87be46406daf..fca4d7f30443 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -41,6 +41,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) if (page_map->real == NULL) return -ENOMEM; +#ifndef CONFIG_X86 SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), @@ -52,6 +53,10 @@ static int amd_create_page_map(struct amd_page_map *page_map) return -ENOMEM; } global_cache_flush(); +#else + set_memory_uc(page_map->real, 1); + page_map->remapped = page_map->real; +#endif for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { writel(agp_bridge->scratch_page, page_map->remapped+i); @@ -63,8 +68,12 @@ static int amd_create_page_map(struct amd_page_map *page_map) static void amd_free_page_map(struct amd_page_map *page_map) { +#ifndef CONFIG_X86 iounmap(page_map->remapped); ClearPageReserved(virt_to_page(page_map->real)); +#else + set_memory_wb(page_map->real, 1); +#endif free_page((unsigned long) page_map->real); } diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 2d46b713c8f2..9ac3bef3bb7a 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -60,18 +60,9 @@ static int ati_create_page_map(struct ati_page_map *page_map) if (page_map->real == NULL) return -ENOMEM; - SetPageReserved(virt_to_page(page_map->real)); + set_memory_uc(page_map->real, 1); err = map_page_into_agp(virt_to_page(page_map->real)); - page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), - PAGE_SIZE); - if (page_map->remapped == NULL || err) { - ClearPageReserved(virt_to_page(page_map->real)); - free_page((unsigned long) page_map->real); - page_map->real = NULL; - return -ENOMEM; - } - /*CACHE_FLUSH();*/ - global_cache_flush(); + page_map->remapped = page_map->real; for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { writel(agp_bridge->scratch_page, page_map->remapped+i); @@ -85,8 +76,7 @@ static int ati_create_page_map(struct ati_page_map *page_map) static void ati_free_page_map(struct ati_page_map *page_map) { unmap_page_from_agp(virt_to_page(page_map->real)); - iounmap(page_map->remapped); - ClearPageReserved(virt_to_page(page_map->real)); + set_memory_wb(page_map->real, 1); free_page((unsigned long) page_map->real); } diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 7484bc759c4c..7fc0c99a3a58 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -932,9 +932,14 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) agp_gatt_table = (void *)table; bridge->driver->cache_flush(); +#ifdef CONFIG_X86 + set_memory_uc((unsigned long)table, 1 << page_order); + bridge->gatt_table = (void *)table; +#else bridge->gatt_table = ioremap_nocache(virt_to_gart(table), (PAGE_SIZE * (1 << page_order))); bridge->driver->cache_flush(); +#endif if (bridge->gatt_table == NULL) { for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) @@ -991,7 +996,11 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge) * called, then all agp memory is deallocated and removed * from the table. */ +#ifdef CONFIG_X86 + set_memory_wb((unsigned long)bridge->gatt_table, 1 << page_order); +#else iounmap(bridge->gatt_table); +#endif table = (char *) bridge->gatt_table_real; table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 551ef25063ef..ae06f8982068 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -52,28 +52,20 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) if (page_map->real == NULL) { return -ENOMEM; } - SetPageReserved(virt_to_page(page_map->real)); - global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), - PAGE_SIZE); - if (page_map->remapped == NULL) { - ClearPageReserved(virt_to_page(page_map->real)); - free_page((unsigned long) page_map->real); - page_map->real = NULL; - return -ENOMEM; - } - global_cache_flush(); + + set_memory_uc(page_map->real, 1); + page_map->remapped = page_map->real; for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) writel(agp_bridge->scratch_page, page_map->remapped+i); + /* Red Pen: Everyone else does pci posting flush here */ return 0; } static void serverworks_free_page_map(struct serverworks_page_map *page_map) { - iounmap(page_map->remapped); - ClearPageReserved(virt_to_page(page_map->real)); + set_memory_wb(page_map->real, 1); free_page((unsigned long) page_map->real); } From 9937ded8e44de8865cba1509d24eea9d350cebf0 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Mon, 18 Feb 2008 20:49:36 -0800 Subject: [PATCH 327/880] [IPV6]: dst_entry leak in ip4ip6_err. (resend) The result of the ip_route_output is not assigned to skb. This means that - it is leaked - possible OOPS below dereferrencing skb->dst - no ICMP message for this case Signed-off-by: Denis V. Lunev Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9031e521c1df..cd940647bd12 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -550,6 +550,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ip_rt_put(rt); goto out; } + skb2->dst = (struct dst_entry *)rt; } else { ip_rt_put(rt); if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, From 2df96af03d97e98cbea9f9cb71fc56ea5fc544b2 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 18 Feb 2008 20:50:42 -0800 Subject: [PATCH 328/880] [IPV6]: Use BUG_ON instead of if + BUG in fib6_del_route. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv6/ip6_fib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f93407cf6515..bab72b6f1444 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1151,7 +1151,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, fn = fn->parent; } /* No more references are possible at this point. */ - if (atomic_read(&rt->rt6i_ref) != 1) BUG(); + BUG_ON(atomic_read(&rt->rt6i_ref) != 1); } inet6_rt_notify(RTM_DELROUTE, rt, info); From 31729363418ea25b01aa9410838c38e36792e44c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 18 Feb 2008 20:52:13 -0800 Subject: [PATCH 329/880] net: fix kernel-doc warnings in header files Add missing structure kernel-doc descriptions to sock.h & skbuff.h to fix kernel-doc warnings. (I think that Stephen H. sent a similar patch, but I can't find it. I just want to kill the warnings, with either patch.) Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 ++ include/net/sock.h | 1 + 2 files changed, 3 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 412672a79e8a..bbd8d0027e2f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -232,6 +232,8 @@ typedef unsigned char *sk_buff_data_t; * @mark: Generic packet mark * @nfct: Associated connection, if any * @ipvs_property: skbuff is owned by ipvs + * @peeked: this packet has been seen already, so stats have been + * done for it, don't do them again * @nf_trace: netfilter packet trace flag * @nfctinfo: Relationship of this skb to the connection * @nfct_reasm: netfilter conntrack re-assembly pointer diff --git a/include/net/sock.h b/include/net/sock.h index 8a7889b35810..fd9876087651 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -180,6 +180,7 @@ struct sock_common { * @sk_sndmsg_off: cached offset for sendmsg * @sk_send_head: front of stuff to transmit * @sk_security: used by security modules + * @sk_mark: generic packet mark * @sk_write_pending: a write to stream socket waits to start * @sk_state_change: callback to indicate change in the state of the sock * @sk_data_ready: callback to indicate there is data to be processed From 3b5bcedeeb755b6e813537fcf4c32f010b490aef Mon Sep 17 00:00:00 2001 From: Matheos Worku Date: Mon, 18 Feb 2008 21:30:03 -0800 Subject: [PATCH 330/880] [NIU]: Fix BMAC alternate MAC address indexing. BMAC port alternate MAC address index needs to start at 1. Index 0 is used for the main MAC address. Signed-off-by: Matheos Worku Signed-off-by: David S. Miller --- drivers/net/niu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 2fe14b0c5c67..1f1b815e0813 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -5147,7 +5147,12 @@ static void niu_set_rx_mode(struct net_device *dev) index++; } } else { - for (i = 0; i < niu_num_alt_addr(np); i++) { + int alt_start; + if (np->flags & NIU_FLAGS_XMAC) + alt_start = 0; + else + alt_start = 1; + for (i = alt_start; i < niu_num_alt_addr(np); i++) { err = niu_enable_alt_mac(np, i, 0); if (err) printk(KERN_WARNING PFX "%s: Error %d " From a442585952f137bd4cdb1f2f3166e4157d383b82 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 18 Feb 2008 21:30:48 -0800 Subject: [PATCH 331/880] [NIU]: Bump driver version and release date. Signed-off-by: David S. Miller --- drivers/net/niu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 1f1b815e0813..e98ce1e4965b 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -33,8 +33,8 @@ #define DRV_MODULE_NAME "niu" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.6" -#define DRV_MODULE_RELDATE "January 5, 2008" +#define DRV_MODULE_VERSION "0.7" +#define DRV_MODULE_RELDATE "February 18, 2008" static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; From f6d091e05199e67ba79c3ea29faa5c3b51d5daf4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Feb 2008 00:31:22 -0800 Subject: [PATCH 332/880] [SPARC64]: Add regs_return_value(). Needed for kretprobes. Noticed by Ananth N Mavinakayanahalli. Signed-off-by: David S. Miller --- include/asm-sparc64/ptrace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h index 8617c3a5143b..67341cff2e6b 100644 --- a/include/asm-sparc64/ptrace.h +++ b/include/asm-sparc64/ptrace.h @@ -102,6 +102,7 @@ do { current_thread_info()->syscall_noerror = 1; \ } while (0) #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) #define instruction_pointer(regs) ((regs)->tpc) +#define regs_return_value(regs) ((regs)->u_regs[UREG_I0]) #ifdef CONFIG_SMP extern unsigned long profile_pc(struct pt_regs *); #else From 5ece6c52ea52f9e94298e950a837ccff415c7687 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 13:45:51 +0100 Subject: [PATCH 333/880] make blk-core.c:request_cachep static again request_cachep needlessly became global. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- block/blk-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index e9754dc98ec4..c013ca22eb67 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -38,7 +38,7 @@ static int __make_request(struct request_queue *q, struct bio *bio); /* * For the allocated request tables */ -struct kmem_cache *request_cachep; +static struct kmem_cache *request_cachep; /* * For queue allocation From 13341598263011e079386b22ea35e482f97714c0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 13:45:53 +0100 Subject: [PATCH 334/880] make blk_ioc_init() static blk_ioc_init() can become static. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- block/blk-ioc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-ioc.c b/block/blk-ioc.c index 80245dc30c75..4ae0929c6e38 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -176,7 +176,7 @@ void copy_io_context(struct io_context **pdst, struct io_context **psrc) } EXPORT_SYMBOL(copy_io_context); -int __init blk_ioc_init(void) +static int __init blk_ioc_init(void) { iocontext_cachep = kmem_cache_create("blkdev_ioc", sizeof(struct io_context), 0, SLAB_PANIC, NULL); From 52ff4cae65b45dcdfa23de09619754d6f380f31e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 13:45:55 +0100 Subject: [PATCH 335/880] make blk_settings_init() static blk_settings_init() can become static. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- block/blk-settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-settings.c b/block/blk-settings.c index c8d0c5724098..13536a388d27 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -386,7 +386,7 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask) } EXPORT_SYMBOL(blk_queue_update_dma_alignment); -int __init blk_settings_init(void) +static int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; blk_max_pfn = max_pfn - 1; From 4c54ac62dceecedd82d4a865017bba0b738e2897 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 13:48:31 +0100 Subject: [PATCH 336/880] make struct def_blk_aops static This patch makes the needlessly global struct def_blk_aops static. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- fs/block_dev.c | 4 +++- include/linux/fs.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 67fe72ce6ac7..8335f0e1b0fb 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -31,6 +31,8 @@ struct bdev_inode { struct inode vfs_inode; }; +static const struct address_space_operations def_blk_aops; + static inline struct bdev_inode *BDEV_I(struct inode *inode) { return container_of(inode, struct bdev_inode, vfs_inode); @@ -1334,7 +1336,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); } -const struct address_space_operations def_blk_aops = { +static const struct address_space_operations def_blk_aops = { .readpage = blkdev_readpage, .writepage = blkdev_writepage, .sync_page = block_sync_page, diff --git a/include/linux/fs.h b/include/linux/fs.h index 98ffb6ead434..b84b848431f2 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1590,7 +1590,6 @@ extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern struct block_device *open_by_devnum(dev_t, unsigned); -extern const struct address_space_operations def_blk_aops; #else static inline void bd_forget(struct inode *inode) {} #endif From 86b6c7a7f78feca58d2d8615e53aee4d59ab9dc6 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 18 Feb 2008 13:48:32 +0100 Subject: [PATCH 337/880] fs/block_dev.c: remove #if 0'ed code Commit b2e895dbd80c420bfc0937c3729b4afe073b3848 #if 0'ed this code stating: <-- snip --> [PATCH] revert blockdev direct io back to 2.6.19 version Andrew Vasquez is reporting as-iosched oopses and a 65% throughput slowdown due to the recent special-casing of direct-io against blockdevs. We don't know why either of these things are occurring. The patch minimally reverts us back to the 2.6.19 code for a 2.6.20 release. <-- snip --> It has since been dead code, and unless someone wants to revive it now it's time to remove it. This patch also makes bio_release_pages() static again and removes the ki_bio_count member from struct kiocb, reverting changes that had been done for this dead code. Signed-off-by: Adrian Bunk Signed-off-by: Jens Axboe --- fs/bio.c | 2 +- fs/block_dev.c | 197 -------------------------------------------- include/linux/aio.h | 1 - include/linux/bio.h | 1 - 4 files changed, 1 insertion(+), 200 deletions(-) diff --git a/fs/bio.c b/fs/bio.c index 242e409dab4b..3312fcc3c098 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -903,7 +903,7 @@ void bio_set_pages_dirty(struct bio *bio) } } -void bio_release_pages(struct bio *bio) +static void bio_release_pages(struct bio *bio) { struct bio_vec *bvec = bio->bi_io_vec; int i; diff --git a/fs/block_dev.c b/fs/block_dev.c index 8335f0e1b0fb..7d822fae7765 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -173,203 +173,6 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, iov, offset, nr_segs, blkdev_get_blocks, NULL); } -#if 0 -static void blk_end_aio(struct bio *bio, int error) -{ - struct kiocb *iocb = bio->bi_private; - atomic_t *bio_count = &iocb->ki_bio_count; - - if (bio_data_dir(bio) == READ) - bio_check_pages_dirty(bio); - else { - bio_release_pages(bio); - bio_put(bio); - } - - /* iocb->ki_nbytes stores error code from LLDD */ - if (error) - iocb->ki_nbytes = -EIO; - - if (atomic_dec_and_test(bio_count)) { - if ((long)iocb->ki_nbytes < 0) - aio_complete(iocb, iocb->ki_nbytes, 0); - else - aio_complete(iocb, iocb->ki_left, 0); - } - - return 0; -} - -#define VEC_SIZE 16 -struct pvec { - unsigned short nr; - unsigned short idx; - struct page *page[VEC_SIZE]; -}; - -#define PAGES_SPANNED(addr, len) \ - (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE); - -/* - * get page pointer for user addr, we internally cache struct page array for - * (addr, count) range in pvec to avoid frequent call to get_user_pages. If - * internal page list is exhausted, a batch count of up to VEC_SIZE is used - * to get next set of page struct. - */ -static struct page *blk_get_page(unsigned long addr, size_t count, int rw, - struct pvec *pvec) -{ - int ret, nr_pages; - if (pvec->idx == pvec->nr) { - nr_pages = PAGES_SPANNED(addr, count); - nr_pages = min(nr_pages, VEC_SIZE); - down_read(¤t->mm->mmap_sem); - ret = get_user_pages(current, current->mm, addr, nr_pages, - rw == READ, 0, pvec->page, NULL); - up_read(¤t->mm->mmap_sem); - if (ret < 0) - return ERR_PTR(ret); - pvec->nr = ret; - pvec->idx = 0; - } - return pvec->page[pvec->idx++]; -} - -/* return a page back to pvec array */ -static void blk_unget_page(struct page *page, struct pvec *pvec) -{ - pvec->page[--pvec->idx] = page; -} - -static ssize_t -blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, - loff_t pos, unsigned long nr_segs) -{ - struct inode *inode = iocb->ki_filp->f_mapping->host; - unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode))); - unsigned blocksize_mask = (1 << blkbits) - 1; - unsigned long seg = 0; /* iov segment iterator */ - unsigned long nvec; /* number of bio vec needed */ - unsigned long cur_off; /* offset into current page */ - unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */ - - unsigned long addr; /* user iovec address */ - size_t count; /* user iovec len */ - size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */ - loff_t size; /* size of block device */ - struct bio *bio; - atomic_t *bio_count = &iocb->ki_bio_count; - struct page *page; - struct pvec pvec; - - pvec.nr = 0; - pvec.idx = 0; - - if (pos & blocksize_mask) - return -EINVAL; - - size = i_size_read(inode); - if (pos + nbytes > size) { - nbytes = size - pos; - iocb->ki_left = nbytes; - } - - /* - * check first non-zero iov alignment, the remaining - * iov alignment is checked inside bio loop below. - */ - do { - addr = (unsigned long) iov[seg].iov_base; - count = min(iov[seg].iov_len, nbytes); - if (addr & blocksize_mask || count & blocksize_mask) - return -EINVAL; - } while (!count && ++seg < nr_segs); - atomic_set(bio_count, 1); - - while (nbytes) { - /* roughly estimate number of bio vec needed */ - nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE; - nvec = max(nvec, nr_segs - seg); - nvec = min(nvec, (unsigned long) BIO_MAX_PAGES); - - /* bio_alloc should not fail with GFP_KERNEL flag */ - bio = bio_alloc(GFP_KERNEL, nvec); - bio->bi_bdev = I_BDEV(inode); - bio->bi_end_io = blk_end_aio; - bio->bi_private = iocb; - bio->bi_sector = pos >> blkbits; -same_bio: - cur_off = addr & ~PAGE_MASK; - cur_len = PAGE_SIZE - cur_off; - if (count < cur_len) - cur_len = count; - - page = blk_get_page(addr, count, rw, &pvec); - if (unlikely(IS_ERR(page))) - goto backout; - - if (bio_add_page(bio, page, cur_len, cur_off)) { - pos += cur_len; - addr += cur_len; - count -= cur_len; - nbytes -= cur_len; - - if (count) - goto same_bio; - while (++seg < nr_segs) { - addr = (unsigned long) iov[seg].iov_base; - count = iov[seg].iov_len; - if (!count) - continue; - if (unlikely(addr & blocksize_mask || - count & blocksize_mask)) { - page = ERR_PTR(-EINVAL); - goto backout; - } - count = min(count, nbytes); - goto same_bio; - } - } else { - blk_unget_page(page, &pvec); - } - - /* bio is ready, submit it */ - if (rw == READ) - bio_set_pages_dirty(bio); - atomic_inc(bio_count); - submit_bio(rw, bio); - } - -completion: - iocb->ki_left -= nbytes; - nbytes = iocb->ki_left; - iocb->ki_pos += nbytes; - - blk_run_address_space(inode->i_mapping); - if (atomic_dec_and_test(bio_count)) - aio_complete(iocb, nbytes, 0); - - return -EIOCBQUEUED; - -backout: - /* - * back out nbytes count constructed so far for this bio, - * we will throw away current bio. - */ - nbytes += bio->bi_size; - bio_release_pages(bio); - bio_put(bio); - - /* - * if no bio was submmitted, return the error code. - * otherwise, proceed with pending I/O completion. - */ - if (atomic_read(bio_count) == 1) - return PTR_ERR(page); - goto completion; -} -#endif - static int blkdev_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, blkdev_get_block, wbc); diff --git a/include/linux/aio.h b/include/linux/aio.h index a9931e2e5624..0d0b7f629bd3 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h @@ -105,7 +105,6 @@ struct kiocb { wait_queue_t ki_wait; loff_t ki_pos; - atomic_t ki_bio_count; /* num bio used for this iocb */ void *private; /* State that we remember to be able to restart/retry */ unsigned short ki_opcode; diff --git a/include/linux/bio.h b/include/linux/bio.h index 4da441337d6e..4c59bdccd3ee 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -326,7 +326,6 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int, gfp_t); extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); -extern void bio_release_pages(struct bio *bio); extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int); extern int bio_uncopy_user(struct bio *); void zero_fill_bio(struct bio *bio); From 84e9e03c55c2456799ab19f1d577e72f721fdd39 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 18 Feb 2008 13:51:56 +0100 Subject: [PATCH 338/880] block: make blk_rq_map_user() clear ->bio if it unmaps it That way the interface is symmetric, and calling blk_rq_unmap_user() on the request wont oops. Signed-off-by: Jens Axboe --- block/blk-map.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/blk-map.c b/block/blk-map.c index 955d75c1a58f..bc5ce60691c3 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -143,6 +143,7 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, return 0; unmap_rq: blk_rq_unmap_user(bio); + rq->bio = NULL; return ret; } EXPORT_SYMBOL(blk_rq_map_user); From ffc4e7595734cf768fa60cea8a4d545dfef8231a Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 19 Feb 2008 10:02:29 +0100 Subject: [PATCH 339/880] cfq-iosched: add hlist for browsing parallel to the radix tree It's cumbersome to browse a radix tree from start to finish, especially since we modify keys when a process exits. So add a hlist for the single purpose of browsing over all known cfq_io_contexts, used for exit, io prio change, etc. This fixes http://bugzilla.kernel.org/show_bug.cgi?id=9948 Signed-off-by: Jens Axboe --- block/blk-ioc.c | 35 +++++++++++++++-------------------- block/cfq-iosched.c | 38 ++++++++++++-------------------------- include/linux/iocontext.h | 2 ++ 3 files changed, 29 insertions(+), 46 deletions(-) diff --git a/block/blk-ioc.c b/block/blk-ioc.c index 4ae0929c6e38..e34df7c9fc36 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -17,17 +17,13 @@ static struct kmem_cache *iocontext_cachep; static void cfq_dtor(struct io_context *ioc) { - struct cfq_io_context *cic[1]; - int r; + if (!hlist_empty(&ioc->cic_list)) { + struct cfq_io_context *cic; - /* - * We don't have a specific key to lookup with, so use the gang - * lookup to just retrieve the first item stored. The cfq exit - * function will iterate the full tree, so any member will do. - */ - r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1); - if (r > 0) - cic[0]->dtor(ioc); + cic = list_entry(ioc->cic_list.first, struct cfq_io_context, + cic_list); + cic->dtor(ioc); + } } /* @@ -57,18 +53,16 @@ EXPORT_SYMBOL(put_io_context); static void cfq_exit(struct io_context *ioc) { - struct cfq_io_context *cic[1]; - int r; - rcu_read_lock(); - /* - * See comment for cfq_dtor() - */ - r = radix_tree_gang_lookup(&ioc->radix_root, (void **) cic, 0, 1); - rcu_read_unlock(); - if (r > 0) - cic[0]->exit(ioc); + if (!hlist_empty(&ioc->cic_list)) { + struct cfq_io_context *cic; + + cic = list_entry(ioc->cic_list.first, struct cfq_io_context, + cic_list); + cic->exit(ioc); + } + rcu_read_unlock(); } /* Called by the exitting task */ @@ -105,6 +99,7 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node) ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH); + INIT_HLIST_HEAD(&ret->cic_list); ret->ioc_data = NULL; } diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index ca198e61fa65..0f962ecae91f 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1145,38 +1145,19 @@ static void cfq_put_queue(struct cfq_queue *cfqq) /* * Call func for each cic attached to this ioc. Returns number of cic's seen. */ -#define CIC_GANG_NR 16 static unsigned int call_for_each_cic(struct io_context *ioc, void (*func)(struct io_context *, struct cfq_io_context *)) { - struct cfq_io_context *cics[CIC_GANG_NR]; - unsigned long index = 0; - unsigned int called = 0; - int nr; + struct cfq_io_context *cic; + struct hlist_node *n; + int called = 0; rcu_read_lock(); - - do { - int i; - - /* - * Perhaps there's a better way - this just gang lookups from - * 0 to the end, restarting after each CIC_GANG_NR from the - * last key + 1. - */ - nr = radix_tree_gang_lookup(&ioc->radix_root, (void **) cics, - index, CIC_GANG_NR); - if (!nr) - break; - - called += nr; - index = 1 + (unsigned long) cics[nr - 1]->key; - - for (i = 0; i < nr; i++) - func(ioc, cics[i]); - } while (nr == CIC_GANG_NR); - + hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) { + func(ioc, cic); + called++; + } rcu_read_unlock(); return called; @@ -1190,6 +1171,7 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) spin_lock_irqsave(&ioc->lock, flags); radix_tree_delete(&ioc->radix_root, cic->dead_key); + hlist_del_rcu(&cic->cic_list); spin_unlock_irqrestore(&ioc->lock, flags); kmem_cache_free(cfq_ioc_pool, cic); @@ -1280,6 +1262,7 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) if (cic) { cic->last_end_request = jiffies; INIT_LIST_HEAD(&cic->queue_list); + INIT_HLIST_NODE(&cic->cic_list); cic->dtor = cfq_free_io_context; cic->exit = cfq_exit_io_context; elv_ioc_count_inc(ioc_count); @@ -1501,6 +1484,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc, rcu_assign_pointer(ioc->ioc_data, NULL); radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd); + hlist_del_rcu(&cic->cic_list); spin_unlock_irqrestore(&ioc->lock, flags); cfq_cic_free(cic); @@ -1561,6 +1545,8 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, spin_lock_irqsave(&ioc->lock, flags); ret = radix_tree_insert(&ioc->radix_root, (unsigned long) cfqd, cic); + if (!ret) + hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list); spin_unlock_irqrestore(&ioc->lock, flags); radix_tree_preload_end(); diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index 593b222d9dcc..1b4ccf25b4d2 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h @@ -50,6 +50,7 @@ struct cfq_io_context { sector_t seek_mean; struct list_head queue_list; + struct hlist_node cic_list; void (*dtor)(struct io_context *); /* destructor */ void (*exit)(struct io_context *); /* called on task exit */ @@ -77,6 +78,7 @@ struct io_context { struct as_io_context *aic; struct radix_tree_root radix_root; + struct hlist_head cic_list; void *ioc_data; }; From e164094964e6e20fe7fce418e06a9dce952bb7a4 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 19 Feb 2008 10:20:37 +0100 Subject: [PATCH 340/880] elevator: make elevator_get() attempt to load the appropriate module Currently we fail if someone requests a valid io scheduler, but it's modular and not currently loaded. That can happen from a driver init asking for a different scheduler, or online switching through sysfs as requested by a user. This patch makes elevator_get() request_module() to attempt to load the appropriate module, instead of requiring that done manually. Signed-off-by: Jens Axboe --- block/elevator.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/block/elevator.c b/block/elevator.c index bafbae0344d3..88318c383608 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -134,6 +134,21 @@ static struct elevator_type *elevator_get(const char *name) spin_lock(&elv_list_lock); e = elevator_find(name); + if (!e) { + char elv[ELV_NAME_MAX + strlen("-iosched")]; + + spin_unlock(&elv_list_lock); + + if (!strcmp(name, "anticipatory")) + sprintf(elv, "as-iosched"); + else + sprintf(elv, "%s-iosched", name); + + request_module(elv); + spin_lock(&elv_list_lock); + e = elevator_find(name); + } + if (e && !try_module_get(e->elevator_owner)) e = NULL; From 188fd89d539d899bfca2bc83534e5508e0161139 Mon Sep 17 00:00:00 2001 From: "S.Caglar Onur" Date: Thu, 14 Feb 2008 17:36:51 +0200 Subject: [PATCH 341/880] genirq: spurious.c: use time_* macros The functions time_before, time_before_eq, time_after, and time_after_eq are more robust for comparing jiffies against other values. So following patch implements usage of the time_after() macro, defined at linux/jiffies.h, which deals with wrapping correctly Signed-off-by: S.Caglar Onur Acked-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/irq/spurious.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index a6b2bc831dd0..088dabbf2d6a 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -6,6 +6,7 @@ * This file contains spurious interrupt handling. */ +#include #include #include #include @@ -179,7 +180,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, * otherwise the couter becomes a doomsday timer for otherwise * working systems */ - if (jiffies - desc->last_unhandled > HZ/10) + if (time_after(jiffies, desc->last_unhandled + HZ/10)) desc->irqs_unhandled = 1; else desc->irqs_unhandled++; From 89d694b9dbe769ca1004e01db0ca43964806a611 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 18 Feb 2008 18:25:17 +0100 Subject: [PATCH 342/880] genirq: do not leave interupts enabled on free_irq The default_disable() function was changed in commit: 76d2160147f43f982dfe881404cfde9fd0a9da21 genirq: do not mask interrupts by default It removed the mask function in favour of the default delayed interrupt disabling. Unfortunately this also broke the shutdown in free_irq() when the last handler is removed from the interrupt for those architectures which rely on the default implementations. Now we can end up with a enabled interrupt line after the last handler was removed, which can result in spurious interrupts. Fix this by adding a default_shutdown function, which is only installed, when the irqchip implementation does provide neither a shutdown nor a disable function. [@stable: affected versions: .21 - .24 ] Pointed-out-by: Michael Hennerich Signed-off-by: Thomas Gleixner Acked-by: Ingo Molnar Cc: stable@kernel.org Tested-by: Michael Hennerich --- kernel/irq/chip.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index cc54c6276356..fdb3fbe2b0c4 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -245,6 +245,17 @@ static unsigned int default_startup(unsigned int irq) return 0; } +/* + * default shutdown function + */ +static void default_shutdown(unsigned int irq) +{ + struct irq_desc *desc = irq_desc + irq; + + desc->chip->mask(irq); + desc->status |= IRQ_MASKED; +} + /* * Fixup enable/disable function pointers */ @@ -256,8 +267,15 @@ void irq_chip_set_defaults(struct irq_chip *chip) chip->disable = default_disable; if (!chip->startup) chip->startup = default_startup; + /* + * We use chip->disable, when the user provided its own. When + * we have default_disable set for chip->disable, then we need + * to use default_shutdown, otherwise the irq line is not + * disabled on free_irq(): + */ if (!chip->shutdown) - chip->shutdown = chip->disable; + chip->shutdown = chip->disable != default_disable ? + chip->disable : default_shutdown; if (!chip->name) chip->name = chip->typename; if (!chip->end) From 56c819df77f96c3fc0c2a979e12b478403728790 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Feb 2008 11:35:37 +0100 Subject: [PATCH 343/880] libata: update ATAPI overflow draining For misc ATAPI commands which transfer variable length data to the host, overflow can occur due to application or hardware bug. Such overflows can be ignored safely as long as overflow data is properly drained. libata HSM implementation has this implemented in __atapi_pio_bytes() and recently updated for 2.6.24-rc but it requires further improvements. Improve drain logic such that... * Report overflow errors using ehi desc mechanism instead of printing directly. * Properly calculate the number of bytes to be drained considering actual number of consumed bytes for partial draining. Signed-off-by: Tejun Heo Acked-by: Albert Lee Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 76 +++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f46eb6f6dc9f..a109ccbda9ca 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4675,24 +4675,9 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) */ static int atapi_qc_may_overflow(struct ata_queued_cmd *qc) { - if (qc->tf.protocol != ATAPI_PROT_PIO && - qc->tf.protocol != ATAPI_PROT_DMA) - return 0; - - if (qc->tf.flags & ATA_TFLAG_WRITE) - return 0; - - switch (qc->cdb[0]) { - case READ_10: - case READ_12: - case WRITE_10: - case WRITE_12: - case GPCMD_READ_CD: - case GPCMD_READ_CD_MSF: - return 0; - } - - return 1; + return ata_is_atapi(qc->tf.protocol) && ata_is_data(qc->tf.protocol) && + atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC && + !(qc->tf.flags & ATA_TFLAG_WRITE); } /** @@ -5146,13 +5131,14 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) */ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) { - int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); + int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ; struct ata_port *ap = qc->ap; - struct ata_eh_info *ehi = &qc->dev->link->eh_info; + struct ata_device *dev = qc->dev; + struct ata_eh_info *ehi = &dev->link->eh_info; struct scatterlist *sg; struct page *page; unsigned char *buf; - unsigned int offset, count; + unsigned int offset, count, consumed; next_sg: sg = qc->cursg; @@ -5165,26 +5151,27 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) * - for write case, padding zero data to the device */ u16 pad_buf[1] = { 0 }; - unsigned int i; - if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) { + if (qc->curbytes + bytes > qc->nbytes + ATAPI_MAX_DRAIN) { ata_ehi_push_desc(ehi, "too much trailing data " "buf=%u cur=%u bytes=%u", qc->nbytes, qc->curbytes, bytes); return -1; } - /* overflow is exptected for misc ATAPI commands */ - if (bytes && !atapi_qc_may_overflow(qc)) - ata_dev_printk(qc->dev, KERN_WARNING, "ATAPI %u bytes " - "trailing data (cdb=%02x nbytes=%u)\n", - bytes, qc->cdb[0], qc->nbytes); + /* allow overflow only for misc ATAPI commands */ + if (!atapi_qc_may_overflow(qc)) { + ata_ehi_push_desc(ehi, "unexpected trailing data " + "%u bytes", bytes); + return -1; + } - for (i = 0; i < (bytes + 1) / 2; i++) - ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write); + consumed = 0; + while (consumed < bytes) + consumed += ap->ops->data_xfer(dev, + (unsigned char *)pad_buf, 2, rw); qc->curbytes += bytes; - return 0; } @@ -5211,18 +5198,16 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) buf = kmap_atomic(page, KM_IRQ0); /* do the actual data transfer */ - ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); + consumed = ap->ops->data_xfer(dev, buf + offset, count, rw); kunmap_atomic(buf, KM_IRQ0); local_irq_restore(flags); } else { buf = page_address(page); - ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); + consumed = ap->ops->data_xfer(dev, buf + offset, count, rw); } - bytes -= count; - if ((count & 1) && bytes) - bytes--; + bytes -= min(bytes, consumed); qc->curbytes += count; qc->cursg_ofs += count; @@ -5231,9 +5216,11 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) qc->cursg_ofs = 0; } + /* consumed can be larger than count only for the last transfer */ + WARN_ON(qc->cursg && count != consumed); + if (bytes) goto next_sg; - return 0; } @@ -5251,6 +5238,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ata_device *dev = qc->dev; + struct ata_eh_info *ehi = &dev->link->eh_info; unsigned int ireason, bc_lo, bc_hi, bytes; int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0; @@ -5268,26 +5256,28 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) /* shall be cleared to zero, indicating xfer of data */ if (unlikely(ireason & (1 << 0))) - goto err_out; + goto atapi_check; /* make sure transfer direction matches expected */ i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0; if (unlikely(do_write != i_write)) - goto err_out; + goto atapi_check; if (unlikely(!bytes)) - goto err_out; + goto atapi_check; VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); - if (__atapi_pio_bytes(qc, bytes)) + if (unlikely(__atapi_pio_bytes(qc, bytes))) goto err_out; ata_altstatus(ap); /* flush */ return; -err_out: - ata_dev_printk(dev, KERN_INFO, "ATAPI check failed\n"); + atapi_check: + ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)", + ireason, bytes); + err_out: qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; } From 40b01b9bbdf51ae543a04744283bf2d56c4a6afa Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Feb 2008 11:35:38 +0100 Subject: [PATCH 344/880] block: update bio according to DMA alignment padding DMA start address and transfer size alignment for PC requests are achieved using bio_copy_user() instead of bio_map_user(). This works because bio_copy_user() always uses full pages and block DMA alignment isn't allowed to go over PAGE_SIZE. However, the implementation didn't update the last bio of the request to make this padding visible to lower layers. This patch makes blk_rq_map_user() extend the last bio such that it includes the padding area and the size of area pointed to by the request is properly aligned. Signed-off-by: Tejun Heo Cc: James Bottomley Signed-off-by: Jens Axboe --- block/blk-map.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/block/blk-map.c b/block/blk-map.c index bc5ce60691c3..a7cf63ccb5cf 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -139,6 +139,23 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, ubuf += ret; } + /* + * __blk_rq_map_user() copies the buffers if starting address + * or length isn't aligned. As the copied buffer is always + * page aligned, we know that there's enough room for padding. + * Extend the last bio and update rq->data_len accordingly. + * + * On unmap, bio_uncopy_user() will use unmodified + * bio_map_data pointed to by bio->bi_private. + */ + if (len & queue_dma_alignment(q)) { + unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1; + struct bio *bio = rq->biotail; + + bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len; + bio->bi_size += pad_len; + } + rq->buffer = rq->data = NULL; return 0; unmap_rq: From 6b00769fe1502b4ad97bb327ef7ac971b208bfb5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Feb 2008 11:36:35 +0100 Subject: [PATCH 345/880] block: add request->raw_data_len With padding and draining moved into it, block layer now may extend requests as directed by queue parameters, so now a request has two sizes - the original request size and the extended size which matches the size of area pointed to by bios and later by sgs. The latter size is what lower layers are primarily interested in when allocating, filling up DMA tables and setting up the controller. Both padding and draining extend the data area to accomodate controller characteristics. As any controller which speaks SCSI can handle underflows, feeding larger data area is safe. So, this patch makes the primary data length field, request->data_len, indicate the size of full data area and add a separate length field, request->raw_data_len, for the unmodified request size. The latter is used to report to higher layer (userland) and where the original request size should be fed to the controller or device. Signed-off-by: Tejun Heo Cc: James Bottomley Signed-off-by: Jens Axboe --- block/blk-core.c | 2 ++ block/blk-map.c | 2 ++ block/blk-merge.c | 1 + block/bsg.c | 8 ++++---- block/scsi_ioctl.c | 3 ++- drivers/scsi/scsi_lib.c | 8 ++++---- include/linux/blkdev.h | 1 + 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index c013ca22eb67..775c8516abf5 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -127,6 +127,7 @@ void rq_init(struct request_queue *q, struct request *rq) rq->nr_hw_segments = 0; rq->ioprio = 0; rq->special = NULL; + rq->raw_data_len = 0; rq->buffer = NULL; rq->tag = -1; rq->errors = 0; @@ -2015,6 +2016,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq, rq->hard_cur_sectors = rq->current_nr_sectors; rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio); rq->buffer = bio_data(bio); + rq->raw_data_len = bio->bi_size; rq->data_len = bio->bi_size; rq->bio = rq->biotail = bio; diff --git a/block/blk-map.c b/block/blk-map.c index a7cf63ccb5cf..09f7fd0bcb73 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -19,6 +19,7 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq, rq->biotail->bi_next = bio; rq->biotail = bio; + rq->raw_data_len += bio->bi_size; rq->data_len += bio->bi_size; } return 0; @@ -154,6 +155,7 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len; bio->bi_size += pad_len; + rq->data_len += pad_len; } rq->buffer = rq->data = NULL; diff --git a/block/blk-merge.c b/block/blk-merge.c index d3b84bbb776a..39f2e077a014 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -228,6 +228,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, ((unsigned long)q->dma_drain_buffer) & (PAGE_SIZE - 1)); nsegs++; + rq->data_len += q->dma_drain_size; } if (sg) diff --git a/block/bsg.c b/block/bsg.c index 8917c5174dc2..7f3c09549e4b 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -437,14 +437,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, } if (rq->next_rq) { - hdr->dout_resid = rq->data_len; - hdr->din_resid = rq->next_rq->data_len; + hdr->dout_resid = rq->raw_data_len; + hdr->din_resid = rq->next_rq->raw_data_len; blk_rq_unmap_user(bidi_bio); blk_put_request(rq->next_rq); } else if (rq_data_dir(rq) == READ) - hdr->din_resid = rq->data_len; + hdr->din_resid = rq->raw_data_len; else - hdr->dout_resid = rq->data_len; + hdr->dout_resid = rq->raw_data_len; /* * If the request generated a negative error number, return it diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 9675b34638d4..e993cac4911d 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -266,7 +266,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, hdr->info = 0; if (hdr->masked_status || hdr->host_status || hdr->driver_status) hdr->info |= SG_INFO_CHECK; - hdr->resid = rq->data_len; + hdr->resid = rq->raw_data_len; hdr->sb_len_wr = 0; if (rq->sense_len && hdr->sbp) { @@ -528,6 +528,7 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, rq = blk_get_request(q, WRITE, __GFP_WAIT); rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->data = NULL; + rq->raw_data_len = 0; rq->data_len = 0; rq->timeout = BLK_DEFAULT_SG_TIMEOUT; memset(rq->cmd, 0, sizeof(rq->cmd)); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 135c1d054701..ba21d97d1855 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1014,10 +1014,6 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb, } req->buffer = NULL; - if (blk_pc_request(req)) - sdb->length = req->data_len; - else - sdb->length = req->nr_sectors << 9; /* * Next, walk the list, and fill in the addresses and sizes of @@ -1026,6 +1022,10 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb, count = blk_rq_map_sg(req->q, req, sdb->table.sgl); BUG_ON(count > sdb->table.nents); sdb->table.nents = count; + if (blk_pc_request(req)) + sdb->length = req->data_len; + else + sdb->length = req->nr_sectors << 9; return BLKPREP_OK; } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e1888cc5b8ae..f1fe9fbf1c0e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -216,6 +216,7 @@ struct request { unsigned int cmd_len; unsigned char cmd[BLK_MAX_CDB]; + unsigned int raw_data_len; unsigned int data_len; unsigned int sense_len; void *data; From 2fb98e8414c42cb14698833aac640b143b9ade4f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Feb 2008 11:36:53 +0100 Subject: [PATCH 346/880] block: implement request_queue->dma_drain_needed Draining shouldn't be done for commands where overflow may indicate data integrity issues. Add dma_drain_needed callback to request_queue. Drain buffer is appened iff this function returns non-zero. Signed-off-by: Tejun Heo Cc: James Bottomley Signed-off-by: Jens Axboe --- block/blk-merge.c | 2 +- block/blk-settings.c | 7 +++++-- include/linux/blkdev.h | 7 +++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/block/blk-merge.c b/block/blk-merge.c index 39f2e077a014..bef1b4d0fc02 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -220,7 +220,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, bvprv = bvec; } /* segments in rq */ - if (q->dma_drain_size) { + if (q->dma_drain_size && q->dma_drain_needed(rq)) { sg->page_link &= ~0x02; sg = sg_next(sg); sg_set_page(sg, virt_to_page(q->dma_drain_buffer), diff --git a/block/blk-settings.c b/block/blk-settings.c index 13536a388d27..9a8ffdd0ce3d 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -296,6 +296,7 @@ EXPORT_SYMBOL(blk_queue_stack_limits); * blk_queue_dma_drain - Set up a drain buffer for excess dma. * * @q: the request queue for the device + * @dma_drain_needed: fn which returns non-zero if drain is necessary * @buf: physically contiguous buffer * @size: size of the buffer in bytes * @@ -315,14 +316,16 @@ EXPORT_SYMBOL(blk_queue_stack_limits); * device can support otherwise there won't be room for the drain * buffer. */ -int blk_queue_dma_drain(struct request_queue *q, void *buf, - unsigned int size) +extern int blk_queue_dma_drain(struct request_queue *q, + dma_drain_needed_fn *dma_drain_needed, + void *buf, unsigned int size) { if (q->max_hw_segments < 2 || q->max_phys_segments < 2) return -EINVAL; /* make room for appending the drain */ --q->max_hw_segments; --q->max_phys_segments; + q->dma_drain_needed = dma_drain_needed; q->dma_drain_buffer = buf; q->dma_drain_size = size; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f1fe9fbf1c0e..6fe67d1939c2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -259,6 +259,7 @@ struct bio_vec; typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *); typedef void (prepare_flush_fn) (struct request_queue *, struct request *); typedef void (softirq_done_fn)(struct request *); +typedef int (dma_drain_needed_fn)(struct request *); enum blk_queue_state { Queue_down, @@ -295,6 +296,7 @@ struct request_queue merge_bvec_fn *merge_bvec_fn; prepare_flush_fn *prepare_flush_fn; softirq_done_fn *softirq_done_fn; + dma_drain_needed_fn *dma_drain_needed; /* * Dispatch queue sorting @@ -699,8 +701,9 @@ extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short); extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); -extern int blk_queue_dma_drain(struct request_queue *q, void *buf, - unsigned int size); +extern int blk_queue_dma_drain(struct request_queue *q, + dma_drain_needed_fn *dma_drain_needed, + void *buf, unsigned int size); extern void blk_queue_segment_boundary(struct request_queue *, unsigned long); extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn); extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *); From db0a2e0099be3a1cff55879225881465f16c67d3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 19 Feb 2008 11:36:55 +0100 Subject: [PATCH 347/880] block: clear drain buffer if draining for write command Clear drain buffer before chaining if the command in question is a write. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- block/blk-merge.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/block/blk-merge.c b/block/blk-merge.c index bef1b4d0fc02..7506c4fe0264 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -221,6 +221,9 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, } /* segments in rq */ if (q->dma_drain_size && q->dma_drain_needed(rq)) { + if (rq->cmd_flags & REQ_RW) + memset(q->dma_drain_buffer, 0, q->dma_drain_size); + sg->page_link &= ~0x02; sg = sg_next(sg); sg_set_page(sg, virt_to_page(q->dma_drain_buffer), From dde2020754aeb14e17052d61784dcb37f252aac2 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 19 Feb 2008 11:36:56 +0100 Subject: [PATCH 348/880] libata: eliminate the home grown dma padding in favour of that provided by the block layer ATA requires that all DMA transfers begin and end on word boundaries. Because of this, a large amount of machinery grew up in ide to adjust scatterlists on this basis. However, as of 2.5, the block layer has a dma_alignment variable which ensures both the beginning and length of a DMA transfer are aligned on the dma_alignment boundary. Although the block layer does adjust the beginning of the transfer to ensure this happens, it doesn't actually adjust the length, it merely makes sure that space is allocated for transfers beyond the declared length. The upshot of this is that scatterlists may be padded to any size between the actual length and the length adjusted to the dma_alignment safely knowing that memory is allocated in this region. Right at the moment, SCSI takes the default dma_aligment which is on a 512 byte boundary. Note that this aligment only applies to transfers coming in from user space. However, since all kernel allocations are automatically aligned on a minimum of 32 byte boundaries, it is safe to adjust them in this manner as well. tj: * Adjusting sg after padding is done in block layer. Make libata set queue alignment correctly for ATAPI devices and drop broken sg mangling from ata_sg_setup(). * Use request->raw_data_len for ATAPI transfer chunk size. * Killed qc->raw_nbytes. * Separated out killing qc->n_iter. Signed-off-by: James Bottomley Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/ata/ahci.c | 5 -- drivers/ata/libata-core.c | 145 +++------------------------------- drivers/ata/libata-scsi.c | 23 ++---- drivers/ata/pata_icside.c | 8 -- drivers/ata/sata_fsl.c | 13 --- drivers/ata/sata_mv.c | 6 +- drivers/ata/sata_sil24.c | 5 -- drivers/scsi/ipr.c | 4 +- drivers/scsi/libsas/sas_ata.c | 4 +- include/linux/libata.h | 28 +------ 10 files changed, 21 insertions(+), 220 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 29e71bddd6ff..3c06e457b4dc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1975,16 +1975,11 @@ static int ahci_port_start(struct ata_port *ap) struct ahci_port_priv *pp; void *mem; dma_addr_t mem_dma; - int rc; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; - rc = ata_pad_alloc(ap, dev); - if (rc) - return rc; - mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a109ccbda9ca..3587ac3fe3f3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4493,30 +4493,13 @@ void ata_sg_clean(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct scatterlist *sg = qc->sg; int dir = qc->dma_dir; - void *pad_buf = NULL; WARN_ON(sg == NULL); - VPRINTK("unmapping %u sg elements\n", qc->mapped_n_elem); + VPRINTK("unmapping %u sg elements\n", qc->n_elem); - /* if we padded the buffer out to 32-bit bound, and data - * xfer direction is from-device, we must copy from the - * pad buffer back into the supplied buffer - */ - if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE)) - pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); - - if (qc->mapped_n_elem) - dma_unmap_sg(ap->dev, sg, qc->mapped_n_elem, dir); - /* restore last sg */ - if (qc->last_sg) - *qc->last_sg = qc->saved_last_sg; - if (pad_buf) { - struct scatterlist *psg = &qc->extra_sg[1]; - void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); - memcpy(addr + psg->offset, pad_buf, qc->pad_len); - kunmap_atomic(addr, KM_IRQ0); - } + if (qc->n_elem) + dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); qc->flags &= ~ATA_QCFLAG_DMAMAP; qc->sg = NULL; @@ -4767,97 +4750,6 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, qc->cursg = qc->sg; } -static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc, - unsigned int *n_elem_extra, - unsigned int *nbytes_extra) -{ - struct ata_port *ap = qc->ap; - unsigned int n_elem = qc->n_elem; - struct scatterlist *lsg, *copy_lsg = NULL, *tsg = NULL, *esg = NULL; - - *n_elem_extra = 0; - *nbytes_extra = 0; - - /* needs padding? */ - qc->pad_len = qc->nbytes & 3; - - if (likely(!qc->pad_len)) - return n_elem; - - /* locate last sg and save it */ - lsg = sg_last(qc->sg, n_elem); - qc->last_sg = lsg; - qc->saved_last_sg = *lsg; - - sg_init_table(qc->extra_sg, ARRAY_SIZE(qc->extra_sg)); - - if (qc->pad_len) { - struct scatterlist *psg = &qc->extra_sg[1]; - void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); - unsigned int offset; - - WARN_ON(qc->dev->class != ATA_DEV_ATAPI); - - memset(pad_buf, 0, ATA_DMA_PAD_SZ); - - /* psg->page/offset are used to copy to-be-written - * data in this function or read data in ata_sg_clean. - */ - offset = lsg->offset + lsg->length - qc->pad_len; - sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT), - qc->pad_len, offset_in_page(offset)); - - if (qc->tf.flags & ATA_TFLAG_WRITE) { - void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); - memcpy(pad_buf, addr + psg->offset, qc->pad_len); - kunmap_atomic(addr, KM_IRQ0); - } - - sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); - sg_dma_len(psg) = ATA_DMA_PAD_SZ; - - /* Trim the last sg entry and chain the original and - * padding sg lists. - * - * Because chaining consumes one sg entry, one extra - * sg entry is allocated and the last sg entry is - * copied to it if the length isn't zero after padded - * amount is removed. - * - * If the last sg entry is completely replaced by - * padding sg entry, the first sg entry is skipped - * while chaining. - */ - lsg->length -= qc->pad_len; - if (lsg->length) { - copy_lsg = &qc->extra_sg[0]; - tsg = &qc->extra_sg[0]; - } else { - n_elem--; - tsg = &qc->extra_sg[1]; - } - - esg = &qc->extra_sg[1]; - - (*n_elem_extra)++; - (*nbytes_extra) += 4 - qc->pad_len; - } - - if (copy_lsg) - sg_set_page(copy_lsg, sg_page(lsg), lsg->length, lsg->offset); - - sg_chain(lsg, 1, tsg); - sg_mark_end(esg); - - /* sglist can't start with chaining sg entry, fast forward */ - if (qc->sg == lsg) { - qc->sg = tsg; - qc->cursg = tsg; - } - - return n_elem; -} - /** * ata_sg_setup - DMA-map the scatter-gather table associated with a command. * @qc: Command with scatter-gather table to be mapped. @@ -4874,26 +4766,17 @@ static unsigned int ata_sg_setup_extra(struct ata_queued_cmd *qc, static int ata_sg_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - unsigned int n_elem, n_elem_extra, nbytes_extra; + unsigned int n_elem; VPRINTK("ENTER, ata%u\n", ap->print_id); - n_elem = ata_sg_setup_extra(qc, &n_elem_extra, &nbytes_extra); + n_elem = dma_map_sg(ap->dev, qc->sg, qc->n_elem, qc->dma_dir); + if (n_elem < 1) + return -1; - if (n_elem) { - n_elem = dma_map_sg(ap->dev, qc->sg, n_elem, qc->dma_dir); - if (n_elem < 1) { - /* restore last sg */ - if (qc->last_sg) - *qc->last_sg = qc->saved_last_sg; - return -1; - } - DPRINTK("%d sg elements mapped\n", n_elem); - } + DPRINTK("%d sg elements mapped\n", n_elem); - qc->n_elem = qc->mapped_n_elem = n_elem; - qc->n_elem += n_elem_extra; - qc->nbytes += nbytes_extra; + qc->n_elem = n_elem; qc->flags |= ATA_QCFLAG_DMAMAP; return 0; @@ -5962,9 +5845,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc) */ BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); - /* ata_sg_setup() may update nbytes */ - qc->raw_nbytes = qc->nbytes; - if (ata_is_dma(prot) || (ata_is_pio(prot) && (ap->flags & ATA_FLAG_PIO_DMA))) if (ata_sg_setup(qc)) @@ -6573,19 +6453,12 @@ void ata_host_resume(struct ata_host *host) int ata_port_start(struct ata_port *ap) { struct device *dev = ap->dev; - int rc; ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); if (!ap->prd) return -ENOMEM; - rc = ata_pad_alloc(ap, dev); - if (rc) - return rc; - - DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, - (unsigned long long)ap->prd_dma); return 0; } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1cea18f62abc..6e15c5ddae6d 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -832,24 +832,16 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, /* configure max sectors */ blk_queue_max_sectors(sdev->request_queue, dev->max_sectors); - /* SATA DMA transfers must be multiples of 4 byte, so - * we need to pad ATAPI transfers using an extra sg. - * Decrement max hw segments accordingly. - */ - if (dev->class == ATA_DEV_ATAPI) { - struct request_queue *q = sdev->request_queue; - blk_queue_max_hw_segments(q, q->max_hw_segments - 1); - + if (dev->class == ATA_DEV_ATAPI) /* set the min alignment */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1); - } else + else { /* ATA devices must be sector aligned */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_SECT_SIZE - 1); - - if (dev->class == ATA_DEV_ATA) sdev->manage_start_stop = 1; + } if (dev->flags & ATA_DFLAG_AN) set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); @@ -2500,7 +2492,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) * want to set it properly, and for DMA where it is * effectively meaningless. */ - nbytes = min(qc->nbytes, (unsigned int)63 * 1024); + nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024); /* Most ATAPI devices which honor transfer chunk size don't * behave according to the spec when odd chunk size which @@ -3555,7 +3547,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc); * @ap: Port to initialize * * Called just after data structures for each port are - * initialized. Allocates DMA pad. + * initialized. * * May be used as the port_start() entry in ata_port_operations. * @@ -3564,7 +3556,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc); */ int ata_sas_port_start(struct ata_port *ap) { - return ata_pad_alloc(ap, ap->dev); + return 0; } EXPORT_SYMBOL_GPL(ata_sas_port_start); @@ -3572,8 +3564,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start); * ata_port_stop - Undo ata_sas_port_start() * @ap: Port to shut down * - * Frees the DMA pad. - * * May be used as the port_stop() entry in ata_port_operations. * * LOCKING: @@ -3582,7 +3572,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start); void ata_sas_port_stop(struct ata_port *ap) { - ata_pad_free(ap, ap->dev); } EXPORT_SYMBOL_GPL(ata_sas_port_stop); diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index 5b8586dac63b..f97068be2d79 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -304,12 +304,6 @@ static int icside_dma_init(struct pata_icside_info *info) } -static int pata_icside_port_start(struct ata_port *ap) -{ - /* No PRD to alloc */ - return ata_pad_alloc(ap, ap->dev); -} - static struct scsi_host_template pata_icside_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -389,8 +383,6 @@ static struct ata_port_operations pata_icside_port_ops = { .irq_clear = ata_dummy_noret, .irq_on = ata_irq_on, - .port_start = pata_icside_port_start, - .bmdma_stop = pata_icside_bmdma_stop, .bmdma_status = pata_icside_bmdma_status, }; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index efcb66b6ccef..9323dd0c7d8d 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -601,21 +601,9 @@ static int sata_fsl_port_start(struct ata_port *ap) if (!pp) return -ENOMEM; - /* - * allocate per command dma alignment pad buffer, which is used - * internally by libATA to ensure that all transfers ending on - * unaligned boundaries are padded, to align on Dword boundaries - */ - retval = ata_pad_alloc(ap, dev); - if (retval) { - kfree(pp); - return retval; - } - mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { - ata_pad_free(ap, dev); kfree(pp); return -ENOMEM; } @@ -694,7 +682,6 @@ static void sata_fsl_port_stop(struct ata_port *ap) dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, pp->cmdslot, pp->cmdslot_paddr); - ata_pad_free(ap, dev); kfree(pp); } diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 2ecd44db4142..1c1fbf375d9a 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1158,17 +1158,13 @@ static int mv_port_start(struct ata_port *ap) struct mv_port_priv *pp; void __iomem *port_mmio = mv_ap_base(ap); unsigned long flags; - int tag, rc; + int tag; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; ap->private_data = pp; - rc = ata_pad_alloc(ap, dev); - if (rc) - return rc; - pp->crqb = dma_pool_alloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma); if (!pp->crqb) return -ENOMEM; diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index b4b1f91ea693..df7988df7908 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -1234,7 +1234,6 @@ static int sil24_port_start(struct ata_port *ap) union sil24_cmd_block *cb; size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS; dma_addr_t cb_dma; - int rc; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) @@ -1247,10 +1246,6 @@ static int sil24_port_start(struct ata_port *ap) return -ENOMEM; memset(cb, 0, cb_size); - rc = ata_pad_alloc(ap, dev); - if (rc) - return rc; - pp->cmd_block = cb; pp->cmd_block_dma = cb_dma; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 2074701f7e76..c72014a3e7d4 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -5140,7 +5140,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_ioadl_desc *last_ioadl = NULL; - int len = qc->nbytes + qc->pad_len; + int len = qc->nbytes; struct scatterlist *sg; unsigned int si; @@ -5206,7 +5206,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; - ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; + ipr_cmd->dma_use_sg = qc->n_elem; ipr_build_ata_ioadl(ipr_cmd, qc); regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 0996f866f14c..7cd05b599a12 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -178,8 +178,8 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) task->uldd_task = qc; if (ata_is_atapi(qc->tf.protocol)) { memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); - task->total_xfer_len = qc->nbytes + qc->pad_len; - task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; + task->total_xfer_len = qc->nbytes; + task->num_scatter = qc->n_elem; } else { for_each_sg(qc->sg, sg, qc->n_elem, si) xfer += sg->length; diff --git a/include/linux/libata.h b/include/linux/libata.h index bc5a8d0c7090..2e098f940cec 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -278,7 +278,6 @@ enum { /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, - ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, /* ering size */ ATA_ERING_SIZE = 32, @@ -457,24 +456,18 @@ struct ata_queued_cmd { unsigned long flags; /* ATA_QCFLAG_xxx */ unsigned int tag; unsigned int n_elem; - unsigned int mapped_n_elem; int dma_dir; - unsigned int pad_len; unsigned int sect_size; unsigned int nbytes; - unsigned int raw_nbytes; unsigned int curbytes; struct scatterlist *cursg; unsigned int cursg_ofs; - struct scatterlist *last_sg; - struct scatterlist saved_last_sg; struct scatterlist sgent; - struct scatterlist extra_sg[2]; struct scatterlist *sg; @@ -619,9 +612,6 @@ struct ata_port { struct ata_prd *prd; /* our SG list */ dma_addr_t prd_dma; /* and its DMA mapping */ - void *pad; /* array of DMA pad buffers */ - dma_addr_t pad_dma; - struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ u8 ctl; /* cache of ATA control register */ @@ -1363,12 +1353,9 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->flags = 0; qc->cursg = NULL; qc->cursg_ofs = 0; - qc->nbytes = qc->raw_nbytes = qc->curbytes = 0; + qc->nbytes = qc->curbytes = 0; qc->n_elem = 0; - qc->mapped_n_elem = 0; qc->err_mask = 0; - qc->pad_len = 0; - qc->last_sg = NULL; qc->sect_size = ATA_SECT_SIZE; ata_tf_init(qc->dev, &qc->tf); @@ -1423,19 +1410,6 @@ static inline unsigned int __ac_err_mask(u8 status) return mask; } -static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev) -{ - ap->pad_dma = 0; - ap->pad = dmam_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, - &ap->pad_dma, GFP_KERNEL); - return (ap->pad == NULL) ? -ENOMEM : 0; -} - -static inline void ata_pad_free(struct ata_port *ap, struct device *dev) -{ - dmam_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); -} - static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host) { return *(struct ata_port **)&host->hostdata[0]; From fa2fc7f4813bfec1ae3232d49e3befbd601e8a6f Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 19 Feb 2008 11:36:57 +0100 Subject: [PATCH 349/880] libata: implement drain buffers This just updates the libata slave configure routine to take advantage of the block layer drain buffers. It also adjusts the size lengths in the atapi code to add the drain buffer to the DMA length so the driver knows it can rely on it. I suspect I should also be checking for AHCI as well as ATA_DEV_ATAPI, but I couldn't see how to do that easily. tj: * atapi_drain_needed() added such that draining is applied to only misc ATAPI commands. * q->bounce_gfp used when allocating drain buffer. * Now duplicate ATAPI PIO drain logic dropped. * ata_dev_printk() used instead of sdev_printk(). Signed-off-by: James Bottomley Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/ata/libata-core.c | 56 +++---------------------------------- drivers/ata/libata-scsi.c | 59 +++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 58 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3587ac3fe3f3..def3682f416a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4641,28 +4641,6 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) return 0; } -/** - * atapi_qc_may_overflow - Check whether data transfer may overflow - * @qc: ATA command in question - * - * ATAPI commands which transfer variable length data to host - * might overflow due to application error or hardare bug. This - * function checks whether overflow should be drained and ignored - * for @qc. - * - * LOCKING: - * None. - * - * RETURNS: - * 1 if @qc may overflow; otherwise, 0. - */ -static int atapi_qc_may_overflow(struct ata_queued_cmd *qc) -{ - return ata_is_atapi(qc->tf.protocol) && ata_is_data(qc->tf.protocol) && - atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC && - !(qc->tf.flags & ATA_TFLAG_WRITE); -} - /** * ata_std_qc_defer - Check whether a qc needs to be deferred * @qc: ATA command in question @@ -5026,36 +5004,10 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) next_sg: sg = qc->cursg; if (unlikely(!sg)) { - /* - * The end of qc->sg is reached and the device expects - * more data to transfer. In order not to overrun qc->sg - * and fulfill length specified in the byte count register, - * - for read case, discard trailing data from the device - * - for write case, padding zero data to the device - */ - u16 pad_buf[1] = { 0 }; - - if (qc->curbytes + bytes > qc->nbytes + ATAPI_MAX_DRAIN) { - ata_ehi_push_desc(ehi, "too much trailing data " - "buf=%u cur=%u bytes=%u", - qc->nbytes, qc->curbytes, bytes); - return -1; - } - - /* allow overflow only for misc ATAPI commands */ - if (!atapi_qc_may_overflow(qc)) { - ata_ehi_push_desc(ehi, "unexpected trailing data " - "%u bytes", bytes); - return -1; - } - - consumed = 0; - while (consumed < bytes) - consumed += ap->ops->data_xfer(dev, - (unsigned char *)pad_buf, 2, rw); - - qc->curbytes += bytes; - return 0; + ata_ehi_push_desc(ehi, "unexpected or too much trailing data " + "buf=%u cur=%u bytes=%u", + qc->nbytes, qc->curbytes, bytes); + return -1; } page = sg_page(sg); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6e15c5ddae6d..dd41b1a1b304 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -826,17 +826,56 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) sdev->max_device_blocked = 1; } -static void ata_scsi_dev_config(struct scsi_device *sdev, - struct ata_device *dev) +/** + * atapi_drain_needed - Check whether data transfer may overflow + * @request: request to be checked + * + * ATAPI commands which transfer variable length data to host + * might overflow due to application error or hardare bug. This + * function checks whether overflow should be drained and ignored + * for @request. + * + * LOCKING: + * None. + * + * RETURNS: + * 1 if ; otherwise, 0. + */ +static int atapi_drain_needed(struct request *rq) +{ + if (likely(!blk_pc_request(rq))) + return 0; + + if (!rq->data_len || (rq->cmd_flags & REQ_RW)) + return 0; + + return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC; +} + +static int ata_scsi_dev_config(struct scsi_device *sdev, + struct ata_device *dev) { /* configure max sectors */ blk_queue_max_sectors(sdev->request_queue, dev->max_sectors); - if (dev->class == ATA_DEV_ATAPI) + if (dev->class == ATA_DEV_ATAPI) { + struct request_queue *q = sdev->request_queue; + void *buf; + /* set the min alignment */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1); - else { + + /* configure draining */ + buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); + if (!buf) { + ata_dev_printk(dev, KERN_ERR, + "drain buffer allocation failed\n"); + return -ENOMEM; + } + + blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN); + } else { /* ATA devices must be sector aligned */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_SECT_SIZE - 1); @@ -853,6 +892,8 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, depth = min(ATA_MAX_QUEUE - 1, depth); scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); } + + return 0; } /** @@ -871,13 +912,14 @@ int ata_scsi_slave_config(struct scsi_device *sdev) { struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); + int rc = 0; ata_scsi_sdev_config(sdev); if (dev) - ata_scsi_dev_config(sdev, dev); + rc = ata_scsi_dev_config(sdev, dev); - return 0; + return rc; } /** @@ -897,6 +939,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev) void ata_scsi_slave_destroy(struct scsi_device *sdev) { struct ata_port *ap = ata_shost_to_port(sdev->host); + struct request_queue *q = sdev->request_queue; unsigned long flags; struct ata_device *dev; @@ -912,6 +955,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) ata_port_schedule_eh(ap); } spin_unlock_irqrestore(ap->lock, flags); + + kfree(q->dma_drain_buffer); + q->dma_drain_buffer = NULL; + q->dma_drain_size = 0; } /** From 486d0a0079eb782cdb73f18246e26076c615a020 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 19 Feb 2008 15:29:23 +0100 Subject: [PATCH 350/880] [S390] cio: Remember to initialize recovery_lock. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index d35dc3f25d06..676b47e07ed0 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -32,7 +32,7 @@ #include "io_sch.h" static struct timer_list recovery_timer; -static spinlock_t recovery_lock; +static DEFINE_SPINLOCK(recovery_lock); static int recovery_phase; static const unsigned long recovery_delay[] = { 3, 30, 300 }; From 4c629727cefe45abb2f7459836bfc4b41c5e55ba Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 19 Feb 2008 15:29:24 +0100 Subject: [PATCH 351/880] [S390] cio: Do timed recovery on workqueue. We can't do our recovery in softirq context, so we schedule it from our timer function. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 676b47e07ed0..fec004f62bcf 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1535,7 +1535,7 @@ static int recovery_check(struct device *dev, void *data) return 0; } -static void recovery_func(unsigned long data) +static void recovery_work_func(struct work_struct *unused) { int redo = 0; @@ -1553,6 +1553,17 @@ static void recovery_func(unsigned long data) CIO_MSG_EVENT(2, "recovery: end\n"); } +static DECLARE_WORK(recovery_work, recovery_work_func); + +static void recovery_func(unsigned long data) +{ + /* + * We can't do our recovery in softirq context and it's not + * performance critical, so we schedule it. + */ + schedule_work(&recovery_work); +} + void ccw_device_schedule_recovery(void) { unsigned long flags; From 057c5cb35ece6ae3a4c2cb849f3948c5ad6add32 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 19 Feb 2008 15:29:25 +0100 Subject: [PATCH 352/880] [S390] Let NR_CPUS default to 32/64 on s390/s390x. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 92a4f7b4323a..b21444b681b6 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -100,7 +100,8 @@ config NR_CPUS int "Maximum number of CPUs (2-64)" range 2 64 depends on SMP - default "32" + default "32" if !64BIT + default "64" if 64BIT help This allows you to specify the maximum number of CPUs which this kernel will support. The maximum supported value is 64 and the From 11ab244c9faead91683a12e4cb10d26b279bb4aa Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 19 Feb 2008 15:29:26 +0100 Subject: [PATCH 353/880] [S390] Make sure enabled wait psw is loaded in default_idle. If both NO_IDLE_HZ and VIRT_TIMER are disabled default_idle won't load an enabled wait psw and busy loop instead. This is because the idle_chain is empty and the return value of atomic_notifier_call_chain will be NOTIFY_DONE, which causes default_idle to return instead of loading an enabled wait psw. Fix this by calling __atomic_notifier_call_chain instead and add proper return value handling. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/process.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index a6a4729e0e94..1c59ec161cf8 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -114,24 +114,27 @@ extern void s390_handle_mcck(void); static void default_idle(void) { int cpu, rc; + int nr_calls = 0; + void *hcpu; #ifdef CONFIG_SMP struct s390_idle_data *idle; #endif /* CPU is going idle. */ cpu = smp_processor_id(); - + hcpu = (void *)(long)cpu; local_irq_disable(); if (need_resched()) { local_irq_enable(); return; } - rc = atomic_notifier_call_chain(&idle_chain, - S390_CPU_IDLE, (void *)(long) cpu); - if (rc != NOTIFY_OK && rc != NOTIFY_DONE) - BUG(); - if (rc != NOTIFY_OK) { + rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1, + &nr_calls); + if (rc == NOTIFY_BAD) { + nr_calls--; + __atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, + hcpu, nr_calls, NULL); local_irq_enable(); return; } From 03513bccad33667ed738cfd96dc5757e539e0bdb Mon Sep 17 00:00:00 2001 From: Stefan Weinhuber Date: Tue, 19 Feb 2008 15:29:27 +0100 Subject: [PATCH 354/880] [S390] dasd: fix locking in __dasd_device_process_final_queue After setting the status of the cqr and releasing the lock for the block cqr queue, we call the cqr callback function, which will usually just trigger the dasd_block_tasklet. But when the tasklet is already running the cqr might be processed before we invoke the callback function. In rare cases the callback pointer may already be invalid by the time we want to call it, which will result in a panic. Solution: Call the callback function first and then release the lock. Signed-off-by: Stefan Weinhuber Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index d984e0fae630..ccf46c96adb4 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1149,12 +1149,14 @@ static void __dasd_device_process_final_queue(struct dasd_device *device, { struct list_head *l, *n; struct dasd_ccw_req *cqr; + struct dasd_block *block; list_for_each_safe(l, n, final_queue) { cqr = list_entry(l, struct dasd_ccw_req, devlist); list_del_init(&cqr->devlist); - if (cqr->block) - spin_lock_bh(&cqr->block->queue_lock); + block = cqr->block; + if (block) + spin_lock_bh(&block->queue_lock); switch (cqr->status) { case DASD_CQR_SUCCESS: cqr->status = DASD_CQR_DONE; @@ -1172,15 +1174,13 @@ static void __dasd_device_process_final_queue(struct dasd_device *device, cqr, cqr->status); BUG(); } - if (cqr->block) - spin_unlock_bh(&cqr->block->queue_lock); if (cqr->callback != NULL) (cqr->callback)(cqr, cqr->callback_data); + if (block) + spin_unlock_bh(&block->queue_lock); } } - - /* * Take a look at the first request on the ccw queue and check * if it reached its expire time. If so, terminate the IO. From a22fb7ff1259e6ee87d0ba3559c9f7b7d0cb20d2 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 19 Feb 2008 15:29:28 +0100 Subject: [PATCH 355/880] [S390] find bit corner case. Fix [ext2_]find_first_[zero_]bit for the corner case of an all clear or all set bit field by always handling that last word of the bit field with __ffz_word/__ffs_word. Signed-off-by: Martin Schwidefsky --- include/asm-s390/bitops.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index ab83c844d04c..965394e69452 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h @@ -456,16 +456,18 @@ static inline unsigned long __ffz_word_loop(const unsigned long *addr, asm volatile( #ifndef __s390x__ - " ahi %1,31\n" - " srl %1,5\n" + " ahi %1,-1\n" + " sra %1,5\n" + " jz 1f\n" "0: c %2,0(%0,%3)\n" " jne 1f\n" " la %0,4(%0)\n" " brct %1,0b\n" "1:\n" #else - " aghi %1,63\n" - " srlg %1,%1,6\n" + " aghi %1,-1\n" + " srag %1,%1,6\n" + " jz 1f\n" "0: cg %2,0(%0,%3)\n" " jne 1f\n" " la %0,8(%0)\n" @@ -491,16 +493,18 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr, asm volatile( #ifndef __s390x__ - " ahi %1,31\n" - " srl %1,5\n" + " ahi %1,-1\n" + " sra %1,5\n" + " jz 1f\n" "0: c %2,0(%0,%3)\n" " jne 1f\n" " la %0,4(%0)\n" " brct %1,0b\n" "1:\n" #else - " aghi %1,63\n" - " srlg %1,%1,6\n" + " aghi %1,-1\n" + " srag %1,%1,6\n" + " jz 1f\n" "0: cg %2,0(%0,%3)\n" " jne 1f\n" " la %0,8(%0)\n" From 591bb4f637e48950d35e2ca01e6b962c519d96e5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 19 Feb 2008 15:29:29 +0100 Subject: [PATCH 356/880] [S390] Initialize per cpu lowcores on cpu hotplug. Just copy the first 512 read-only bytes of the current cpu lowcore if a new cpu gets onlined. The rest is zeroed out and must be explicitly initialized. Current code just copies the entire lowcore and initializes the needed fields. This should reveal bugs in future enhancements quite early. Also when the lowcore of the first cpu is replaced this is now done atomically (no interrupts, no machine checks). Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/smp.c | 53 ++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 85060659fb12..818bd09c0260 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -626,13 +626,17 @@ static int __cpuinit smp_alloc_lowcore(int cpu) if (!lowcore) return -ENOMEM; async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); - if (!async_stack) - goto out_async_stack; panic_stack = __get_free_page(GFP_KERNEL); - if (!panic_stack) - goto out_panic_stack; - - *lowcore = S390_lowcore; + if (!panic_stack || !async_stack) + goto out; + /* + * Only need to copy the first 512 bytes from address 0. But since + * the compiler emits a warning if src == NULL for memcpy use copy_page + * instead. Copies more than needed but this code is not performance + * critical. + */ + copy_page(lowcore, &S390_lowcore); + memset((void *)lowcore + 512, 0, sizeof(*lowcore) - 512); lowcore->async_stack = async_stack + ASYNC_SIZE; lowcore->panic_stack = panic_stack + PAGE_SIZE; @@ -653,9 +657,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu) out_save_area: free_page(panic_stack); #endif -out_panic_stack: +out: free_pages(async_stack, ASYNC_ORDER); -out_async_stack: free_pages((unsigned long) lowcore, lc_order); return -ENOMEM; } @@ -719,8 +722,8 @@ int __cpuinit __cpu_up(unsigned int cpu) cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; cpu_lowcore->current_task = (unsigned long) idle; cpu_lowcore->cpu_data.cpu_nr = cpu; - cpu_lowcore->softirq_pending = 0; - cpu_lowcore->ext_call_fast = 0; + cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce; + cpu_lowcore->ipl_device = S390_lowcore.ipl_device; eieio(); while (signal_processor(cpu, sigp_restart) == sigp_busy) @@ -797,23 +800,43 @@ void cpu_die(void) void __init smp_prepare_cpus(unsigned int max_cpus) { +#ifndef CONFIG_64BIT + unsigned long save_area = 0; +#endif + unsigned long async_stack, panic_stack; + struct _lowcore *lowcore; unsigned int cpu; + int lc_order; smp_detect_cpus(); /* request the 0x1201 emergency signal external interrupt */ if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) panic("Couldn't request external interrupt 0x1201"); - memset(lowcore_ptr, 0, sizeof(lowcore_ptr)); print_cpu_info(&S390_lowcore.cpu_data); - smp_alloc_lowcore(smp_processor_id()); + /* Reallocate current lowcore, but keep its contents. */ + lc_order = sizeof(long) == 8 ? 1 : 0; + lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order); + panic_stack = __get_free_page(GFP_KERNEL); + async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) - ctl_set_bit(14, 29); /* enable extended save area */ + save_area = get_zeroed_page(GFP_KERNEL); #endif - set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); - + local_irq_disable(); + local_mcck_disable(); + lowcore_ptr[smp_processor_id()] = lowcore; + *lowcore = S390_lowcore; + lowcore->panic_stack = panic_stack + PAGE_SIZE; + lowcore->async_stack = async_stack + ASYNC_SIZE; +#ifndef CONFIG_64BIT + if (MACHINE_HAS_IEEE) + lowcore->extended_save_area_addr = (u32) save_area; +#endif + set_prefix((u32)(unsigned long) lowcore); + local_mcck_enable(); + local_irq_enable(); for_each_possible_cpu(cpu) if (cpu != smp_processor_id()) smp_create_idle(cpu); From b32ecdb7257821e5e42d9b9b2a427b02c89f85e7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 19 Feb 2008 15:29:30 +0100 Subject: [PATCH 357/880] [S390] qdio: fix qdio_activate timeout handling. Current code in qdio_activate waits for at least 5 seconds until it returns. It may return earlier if an error occurs, but not if everything is ok. This large timeout value became visible with commit dfa77f611ff295598e218aa0eb6efa73a5cf26d0 "qdio: set QDIO_ACTIVATE_TIMEOUT to 5s", which intended to fix the timeout value which was zero. In turn setting an FCP adapter online took 5 seconds. In practice waiting for 5ms before continuing is sufficient as pointed out by Utz Bacher and Cornelia Huck. Cc: Utz Bacher Cc: Jan Glauber Cc: Ursula Braun Cc: Martin Peschke Acked-by: Cornelia Huck Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio.c | 10 ++-------- drivers/s390/cio/qdio.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 097fc0967e9d..cd9cfc1326d2 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -32,7 +32,7 @@ #include #include - +#include #include #include #include @@ -3332,13 +3332,7 @@ qdio_activate(struct ccw_device *cdev, int flags) } } - wait_event_interruptible_timeout(cdev->private->wait_q, - ((irq_ptr->state == - QDIO_IRQ_STATE_STOPPED) || - (irq_ptr->state == - QDIO_IRQ_STATE_ERR)), - QDIO_ACTIVATE_TIMEOUT); - + msleep(QDIO_ACTIVATE_TIMEOUT); switch (irq_ptr->state) { case QDIO_IRQ_STATE_STOPPED: case QDIO_IRQ_STATE_ERR: diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 37870e4e938e..da8a272fd75b 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -57,10 +57,10 @@ of the queue to 0 */ #define QDIO_ESTABLISH_TIMEOUT (1*HZ) -#define QDIO_ACTIVATE_TIMEOUT (5*HZ) #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) #define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) +#define QDIO_ACTIVATE_TIMEOUT (5) /* 5 ms */ enum qdio_irq_states { QDIO_IRQ_STATE_INACTIVE, From 06cb92ffe418c4a9d5a70c5dff4f283e8e8df6e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 19 Feb 2008 15:29:31 +0100 Subject: [PATCH 358/880] [S390] etr: fix compile error on !SMP Since a5fbb6d1064be885d2a6b82f625186753cf74848 "KVM: fix !SMP build error" smp_call_function isn't a define anymore that folds into nothing but a define that calls up_smp_call_function with all parameters. Hence we cannot #ifdef out the unused code anymore... This seems to be the preferred method, so do this for s390 as well. arch/s390/kernel/time.c: In function 'etr_sync_clock': arch/s390/kernel/time.c:825: error: 'clock_sync_cpu_start' undeclared arch/s390/kernel/time.c:862: error: 'clock_sync_cpu_end' undeclared Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/time.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 3bbac1293be4..76a5dd1b4ce9 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -744,7 +744,6 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay) } } -#ifdef CONFIG_SMP static void etr_sync_cpu_start(void *dummy) { int *in_sync = dummy; @@ -777,7 +776,6 @@ static void etr_sync_cpu_start(void *dummy) static void etr_sync_cpu_end(void *dummy) { } -#endif /* CONFIG_SMP */ /* * Sync the TOD clock using the port refered to by aibp. This port From d082d3ce32705a92bd86c2b061d6b0827a40a5b1 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Tue, 19 Feb 2008 15:29:32 +0100 Subject: [PATCH 359/880] [S390] sclp: clean up send/receive naming scheme Make state change events adjust the correct mask by cleaning up naming inconsistencies. Also remove chance for lockup by removing unnecessary mask related check before reading events. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp.c | 12 ++++++------ drivers/s390/char/sclp.h | 6 ++++-- drivers/s390/char/sclp_config.c | 2 +- drivers/s390/char/sclp_cpi_sys.c | 2 +- drivers/s390/char/sclp_rw.c | 4 ++-- drivers/s390/char/sclp_vt220.c | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 25629b92dec3..2c7a1ee6b041 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -29,10 +29,10 @@ static ext_int_info_t ext_int_info_hwc; /* Lock to protect internal data consistency. */ static DEFINE_SPINLOCK(sclp_lock); -/* Mask of events that we can receive from the sclp interface. */ +/* Mask of events that we can send to the sclp interface. */ static sccb_mask_t sclp_receive_mask; -/* Mask of events that we can send to the sclp interface. */ +/* Mask of events that we can receive from the sclp interface. */ static sccb_mask_t sclp_send_mask; /* List of registered event listeners and senders. */ @@ -380,7 +380,7 @@ sclp_interrupt_handler(__u16 code) } sclp_running_state = sclp_running_state_idle; } - if (evbuf_pending && sclp_receive_mask != 0 && + if (evbuf_pending && sclp_activation_state == sclp_activation_state_active) __sclp_queue_read_req(); spin_unlock(&sclp_lock); @@ -459,8 +459,8 @@ sclp_dispatch_state_change(void) reg = NULL; list_for_each(l, &sclp_reg_list) { reg = list_entry(l, struct sclp_register, list); - receive_mask = reg->receive_mask & sclp_receive_mask; - send_mask = reg->send_mask & sclp_send_mask; + receive_mask = reg->send_mask & sclp_receive_mask; + send_mask = reg->receive_mask & sclp_send_mask; if (reg->sclp_receive_mask != receive_mask || reg->sclp_send_mask != send_mask) { reg->sclp_receive_mask = receive_mask; @@ -615,8 +615,8 @@ struct init_sccb { u16 mask_length; sccb_mask_t receive_mask; sccb_mask_t send_mask; - sccb_mask_t sclp_send_mask; sccb_mask_t sclp_receive_mask; + sccb_mask_t sclp_send_mask; } __attribute__((packed)); /* Prepare init mask request. Called while sclp_lock is locked. */ diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index aa8186d18aee..bac80e856f97 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -122,11 +122,13 @@ struct sclp_req { /* of some routines it wants to be called from the low level driver */ struct sclp_register { struct list_head list; - /* event masks this user is registered for */ + /* User wants to receive: */ sccb_mask_t receive_mask; + /* User wants to send: */ sccb_mask_t send_mask; - /* actually present events */ + /* H/W can receive: */ sccb_mask_t sclp_receive_mask; + /* H/W can send: */ sccb_mask_t sclp_send_mask; /* called if event type availability changes */ void (*state_change_fn)(struct sclp_register *); diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 9dc77f14fa52..b8f35bc52b7b 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -64,7 +64,7 @@ static int __init sclp_conf_init(void) return rc; } - if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK)) { + if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) { printk(KERN_WARNING TAG "no configuration management.\n"); sclp_unregister(&sclp_conf_register); rc = -ENOSYS; diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index 41617032afdc..9f37456222e9 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -129,7 +129,7 @@ static int cpi_req(void) "to hardware console.\n"); goto out; } - if (!(sclp_cpi_event.sclp_send_mask & EVTYP_CTLPROGIDENT_MASK)) { + if (!(sclp_cpi_event.sclp_receive_mask & EVTYP_CTLPROGIDENT_MASK)) { printk(KERN_WARNING "cpi: no control program " "identification support\n"); rc = -EOPNOTSUPP; diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index ad7195d3de0c..da09781b32f7 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c @@ -452,10 +452,10 @@ sclp_emit_buffer(struct sclp_buffer *buffer, return -EIO; sccb = buffer->sccb; - if (sclp_rw_event.sclp_send_mask & EVTYP_MSG_MASK) + if (sclp_rw_event.sclp_receive_mask & EVTYP_MSG_MASK) /* Use normal write message */ sccb->msg_buf.header.type = EVTYP_MSG; - else if (sclp_rw_event.sclp_send_mask & EVTYP_PMSGCMD_MASK) + else if (sclp_rw_event.sclp_receive_mask & EVTYP_PMSGCMD_MASK) /* Use write priority message */ sccb->msg_buf.header.type = EVTYP_PMSGCMD; else diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index f47f4a768be5..92f527201792 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -202,7 +202,7 @@ sclp_vt220_callback(struct sclp_req *request, void *data) static int __sclp_vt220_emit(struct sclp_vt220_request *request) { - if (!(sclp_vt220_register.sclp_send_mask & EVTYP_VT220MSG_MASK)) { + if (!(sclp_vt220_register.sclp_receive_mask & EVTYP_VT220MSG_MASK)) { request->sclp_req.status = SCLP_REQ_FAILED; return -EIO; } From 39f73b2886be3a255d8f4cd669c8c7e7957afbd9 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Tue, 19 Feb 2008 15:29:33 +0100 Subject: [PATCH 360/880] [S390] dcss: Fix Unlikely(x) != y Fix Unlikely(x) != y Cc: Gerald Schaefer Cc: Stefan Weinhuber Cc: Carsten Otte Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dcssblk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 3faf0538b328..e6c94dbfdeaa 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -666,7 +666,7 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio) page_addr = (unsigned long) page_address(bvec->bv_page) + bvec->bv_offset; source_addr = dev_info->start + (index<<12) + bytes_done; - if (unlikely(page_addr & 4095) != 0 || (bvec->bv_len & 4095) != 0) + if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0) // More paranoia. goto fail; if (bio_data_dir(bio) == READ) { From d5b02b3ff1d9a2e1074f559c84ed378cfa6fc3c0 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 19 Feb 2008 15:29:34 +0100 Subject: [PATCH 361/880] [S390] Fix futex_atomic_cmpxchg_std inline assembly. Add missing exception table entry so that the kernel can handle proctection exceptions as well on the cs instruction. Currently only specification exceptions are handled correctly. The missing entry allows user space to crash the kernel. Cc: stable Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess_std.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 28c4500a58d0..d2ffbadb51a7 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c @@ -293,10 +293,10 @@ int futex_atomic_cmpxchg_std(int __user *uaddr, int oldval, int newval) asm volatile( " sacf 256\n" - " cs %1,%4,0(%5)\n" - "0: lr %0,%1\n" - "1: sacf 0\n" - EX_TABLE(0b,1b) + "0: cs %1,%4,0(%5)\n" + "1: lr %0,%1\n" + "2: sacf 0\n" + EX_TABLE(0b,2b) EX_TABLE(1b,2b) : "=d" (ret), "+d" (oldval), "=m" (*uaddr) : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr) : "cc", "memory" ); From e5fa443ea05f71b5253818890c6d32174cbab36f Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Tue, 19 Feb 2008 15:29:35 +0100 Subject: [PATCH 362/880] [S390] qdio: FCP/SCSI write I/O stagnates on LPAR If running on LPAR, qdio might overlook an incoming buffer in certain scenarios. The patch makes sure that incoming buffers are detected immediately in all situations. Signed-off-by: Ursula Braun Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index cd9cfc1326d2..2b5bfb7c69e5 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -1215,9 +1215,6 @@ tiqdio_is_inbound_q_done(struct qdio_q *q) if (!no_used) return 1; - if (!q->siga_sync && !irq->is_qebsm) - /* we'll check for more primed buffers in qeth_stop_polling */ - return 0; if (irq->is_qebsm) { count = 1; start_buf = q->first_to_check; From 08cd93f9e11ac8c3e42c72debe7dc55a761149c2 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 14 Feb 2008 23:23:37 +0200 Subject: [PATCH 363/880] remove mca-pentium This patch removes the mca-pentium boot option that was a noop. besides the source code cleanup factor, this saves some text as well: arch/x86/kernel/cpu/bugs.o: text data bss dec hex filename 651 77 4 732 2dc bugs.o.before 631 53 4 688 2b0 bugs.o.after Signed-off-by: Adrian Bunk Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- Documentation/kernel-parameters.txt | 2 -- arch/x86/kernel/cpu/bugs.c | 8 -------- arch/x86/kernel/setup_32.c | 1 - include/asm-x86/processor.h | 1 - 4 files changed, 12 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a4fc7fc21439..7278295f94d2 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1056,8 +1056,6 @@ and is between 256 and 4096 characters. It is defined in the file [SCSI] Maximum number of LUNs received. Should be between 1 and 16384. - mca-pentium [BUGS=X86-32] - mcatest= [IA-64] mce [X86-32] Machine Check Exception diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 9b95edcfc6ae..027e5c003b16 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -25,14 +25,6 @@ static int __init no_halt(char *s) __setup("no-hlt", no_halt); -static int __init mca_pentium(char *s) -{ - mca_pentium_flag = 1; - return 1; -} - -__setup("mca-pentium", mca_pentium); - static int __init no_387(char *s) { boot_cpu_data.hard_math = 0; diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 691ab4cb167b..a1d7071a51c9 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -164,7 +164,6 @@ unsigned long mmu_cr4_features = X86_CR4_PAE; unsigned int machine_id; unsigned int machine_submodel_id; unsigned int BIOS_revision; -unsigned int mca_pentium_flag; /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 149920dcd341..7b1ca1f90283 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -671,7 +671,6 @@ extern void init_gdt(int cpu); extern unsigned int machine_id; extern unsigned int machine_submodel_id; extern unsigned int BIOS_revision; -extern unsigned int mca_pentium_flag; /* Boot loader type from the setup header */ extern int bootloader_type; From f1452d424dc0e079fb97af8cb8d3a0f7b5fddd46 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 14 Feb 2008 15:23:53 -0800 Subject: [PATCH 364/880] x86, kprobes: remove sparse warnings from x86 arch/x86/kernel/kprobes.c:584:16: warning: symbol 'kretprobe_trampoline_holder' was not declared. Should it be static? arch/x86/kernel/kprobes.c:676:6: warning: symbol 'trampoline_handler' was not declared. Should it be static? Make them static and add the __used attribute, approach taken from the arm kprobes implementation. kretprobe_trampoline_holder uses inline assemly to define the global symbol kretprobe_trampoline, but nothing ever calls the holder explicitly. trampoline handler is only called from inline assembly in the same file, mark it used and static. Signed-off-by: Harvey Harrison Acked-by: Masami Hiramatsu Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/kprobes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index a99e764fd66a..34a591283f5d 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -581,7 +581,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) * When a retprobed function returns, this code saves registers and * calls trampoline_handler() runs, which calls the kretprobe's handler. */ -void __kprobes kretprobe_trampoline_holder(void) +static void __used __kprobes kretprobe_trampoline_holder(void) { asm volatile ( ".global kretprobe_trampoline\n" @@ -673,7 +673,7 @@ void __kprobes kretprobe_trampoline_holder(void) /* * Called from kretprobe_trampoline */ -void * __kprobes trampoline_handler(struct pt_regs *regs) +static __used __kprobes void *trampoline_handler(struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; struct hlist_head *head, empty_rp; From cc7e73f35dccba7503bdaf40bb5189225697664d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 13:26:39 -0800 Subject: [PATCH 365/880] x86: sparse error in efi_32.c arch/x86/kernel/efi_32.c:42:6: warning: symbol 'efi_call_phys_prelog' was not declared. Should it be static? arch/x86/kernel/efi_32.c:84:6: warning: symbol 'efi_call_phys_epilog' was not declared. Should it be static? Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/efi_32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c index cb91f985b4a1..5d23d85624d4 100644 --- a/arch/x86/kernel/efi_32.c +++ b/arch/x86/kernel/efi_32.c @@ -28,6 +28,7 @@ #include #include #include +#include /* * To make EFI call EFI runtime service in physical addressing mode we need From ecaea42eb8507735a97a496cc5068de06542e8b2 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 13:26:13 -0800 Subject: [PATCH 366/880] x86: sparse warning in efi.c Yes, it should. Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 0c0eeb163d90..759e02bec070 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c @@ -54,7 +54,7 @@ EXPORT_SYMBOL(efi); struct efi_memory_map memmap; -struct efi efi_phys __initdata; +static struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; static int __init setup_noefi(char *arg) From 148a142495f40d3da729d62cb7127ccb26223106 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 13 Feb 2008 23:29:33 +0200 Subject: [PATCH 367/880] x86: make mxcsr_feature_mask static again Signed-off-by: Adrian Bunk Cc: Roland McGrath Cc: hpa@zytor.com Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/i387.c | 2 +- include/asm-x86/i387.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 26719bd2c77c..763dfc407232 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -39,7 +39,7 @@ #define HAVE_HWFP 1 #endif -unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu; +static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu; void mxcsr_feature_mask_init(void) { diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index 6b1895ccd6b7..f377b76b2f34 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h @@ -20,7 +20,6 @@ #include extern void fpu_init(void); -extern unsigned int mxcsr_feature_mask; extern void mxcsr_feature_mask_init(void); extern void init_fpu(struct task_struct *child); extern asmlinkage void math_state_restore(void); From d3cfeb4fbe2a5e88fd5f98892f4dc49dcab8a9e7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 13 Feb 2008 23:29:42 +0200 Subject: [PATCH 368/880] x86: unexport io_delay_type Signed-off-by: Adrian Bunk Cc: hpa@zytor.com Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/io_delay.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c index bd49321034db..c706a3061553 100644 --- a/arch/x86/kernel/io_delay.c +++ b/arch/x86/kernel/io_delay.c @@ -13,7 +13,6 @@ #include int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE; -EXPORT_SYMBOL_GPL(io_delay_type); static int __initdata io_delay_override; From f7f3d791e61d7baf8b0aee0384fdd469c0d2ac9b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 13 Feb 2008 23:29:53 +0200 Subject: [PATCH 369/880] x86: don't make irq_return global Signed-off-by: Adrian Bunk Cc: hpa@zytor.com Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/entry_32.S | 2 +- arch/x86/kernel/entry_64.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 824e21b80aad..4b87c32b639f 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -409,7 +409,7 @@ restore_nocheck_notrace: RESTORE_REGS addl $4, %esp # skip orig_eax/error_code CFI_ADJUST_CFA_OFFSET -4 -ENTRY(irq_return) +irq_return: INTERRUPT_RETURN .section .fixup,"ax" iret_exc: diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 6be39a387c5a..2ad9a1bc6a73 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -583,7 +583,7 @@ retint_restore_args: /* return to kernel space */ restore_args: RESTORE_ARGS 0,8,0 -ENTRY(irq_return) +irq_return: INTERRUPT_RETURN .section __ex_table, "a" From aa65af3f92da39a686c8a3479426d15854fa27ab Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 13 Feb 2008 23:29:55 +0200 Subject: [PATCH 370/880] x86: don't make swapper_pg_fixmap global Signed-off-by: Adrian Bunk Cc: Ian Campbell Cc: hpa@zytor.com Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/head_32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 74ef4a41f224..25eb98540a41 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -612,7 +612,7 @@ ENTRY(swapper_pg_pmd) ENTRY(swapper_pg_dir) .fill 1024,4,0 #endif -ENTRY(swapper_pg_fixmap) +swapper_pg_fixmap: .fill 1024,4,0 ENTRY(empty_zero_page) .fill 4096,1,0 From 8e31c2ac1101b09ad6c6d3539b032d312cc3302b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 11 Feb 2008 10:50:21 +0100 Subject: [PATCH 371/880] x86: CPA: remove BUG_ON for LRU/Compound pages New implementation does not use lru for anything so there is no need to reject pages that are in the LRU. Similar for compound pages (which were checked because they also use page->lru) [ tglx@linutronix.de: removed unused variable ] Signed-off-by: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/mm/pageattr.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 3ee14996c829..e2a74ea11a53 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -513,7 +513,6 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) unsigned long address = cpa->vaddr; int do_split, err; unsigned int level; - struct page *kpte_page; pte_t *kpte, old_pte; repeat: @@ -532,10 +531,6 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) return -EINVAL; } - kpte_page = virt_to_page(kpte); - BUG_ON(PageLRU(kpte_page)); - BUG_ON(PageCompound(kpte_page)); - if (level == PG_LEVEL_4K) { pte_t new_pte; pgprot_t new_prot = pte_pgprot(old_pte); From a062bae9c443a8c0ab17f231eb83690dfb897524 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sun, 3 Feb 2008 15:40:30 +0800 Subject: [PATCH 372/880] x86: fix compile warning building without CONFIG_SYSCTL arch/x86/kernel/nmi_64.c:50: warning: 'unknown_nmi_panic_callback' declared 'static' but never defined This patch also fixes nmi_32.c Signed-off-by: Li Zefan Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/nmi_32.c | 21 +++++++++------------ arch/x86/kernel/nmi_64.c | 21 +++++++++------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c index edd413650b3b..6a0aa7038685 100644 --- a/arch/x86/kernel/nmi_32.c +++ b/arch/x86/kernel/nmi_32.c @@ -46,9 +46,6 @@ static unsigned int nmi_hz = HZ; static DEFINE_PER_CPU(short, wd_enabled); -/* local prototypes */ -static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); - static int endflag __initdata = 0; #ifdef CONFIG_SMP @@ -391,15 +388,6 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) return rc; } -int do_nmi_callback(struct pt_regs * regs, int cpu) -{ -#ifdef CONFIG_SYSCTL - if (unknown_nmi_panic) - return unknown_nmi_panic_callback(regs, cpu); -#endif - return 0; -} - #ifdef CONFIG_SYSCTL static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) @@ -453,6 +441,15 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif +int do_nmi_callback(struct pt_regs *regs, int cpu) +{ +#ifdef CONFIG_SYSCTL + if (unknown_nmi_panic) + return unknown_nmi_panic_callback(regs, cpu); +#endif + return 0; +} + void __trigger_all_cpu_backtrace(void) { int i; diff --git a/arch/x86/kernel/nmi_64.c b/arch/x86/kernel/nmi_64.c index fb99484d21cf..9a4fde74bee1 100644 --- a/arch/x86/kernel/nmi_64.c +++ b/arch/x86/kernel/nmi_64.c @@ -46,9 +46,6 @@ static unsigned int nmi_hz = HZ; static DEFINE_PER_CPU(short, wd_enabled); -/* local prototypes */ -static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); - /* Run after command line and cpu_init init, but before all other checks */ void nmi_watchdog_default(void) { @@ -394,15 +391,6 @@ asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) nmi_exit(); } -int do_nmi_callback(struct pt_regs * regs, int cpu) -{ -#ifdef CONFIG_SYSCTL - if (unknown_nmi_panic) - return unknown_nmi_panic_callback(regs, cpu); -#endif - return 0; -} - void stop_nmi(void) { acpi_nmi_disable(); @@ -464,6 +452,15 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif +int do_nmi_callback(struct pt_regs *regs, int cpu) +{ +#ifdef CONFIG_SYSCTL + if (unknown_nmi_panic) + return unknown_nmi_panic_callback(regs, cpu); +#endif + return 0; +} + void __trigger_all_cpu_backtrace(void) { int i; From 08acb672624ece2d9234817570a0b3332cc8dae3 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:22:46 +0100 Subject: [PATCH 373/880] x86: fix section mismatch warning in setup_64.c:nearby_node nearby_node() were only used by __cpuinit amd_detect_cmp() So annotating nearby_node() __cpuinit was the trivial fix. Signed-off-by: Sam Ravnborg Cc: Sam Ravnborg Cc: Andrew Morton Cc: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index c0d8208af12a..ff9029d34133 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -518,7 +518,7 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) } #ifdef CONFIG_NUMA -static int nearby_node(int apicid) +static int __cpuinit nearby_node(int apicid) { int i, node; From 04d733bd3588fda8934591fdb0a3d719c5ec8fa0 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:22:47 +0100 Subject: [PATCH 374/880] x86: fix section mismatch in setup_64.c:srat_detect_node srat_detect_node() is only used by __cpuinit init_intel(). So the trivial fix is to annotate srat_detect_node() with __cpuinit. Signed-off-by: Sam Ravnborg Cc: Sam Ravnborg Cc: Andrew Morton Cc: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index ff9029d34133..e1866172deb2 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -791,7 +791,7 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) return 1; } -static void srat_detect_node(void) +static void __cpuinit srat_detect_node(void) { #ifdef CONFIG_NUMA unsigned node; From 177c7715cd94a66d951fcafbacedd278a2d6fcab Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:22:49 +0100 Subject: [PATCH 375/880] x86: fix section mismatch warning in topology.c:arch_register_cpu arch_register_cpu() is only defined for HOTPLUG_CPU code so simple fix is to ignore references by annotating the function __ref. Signed-off-by: Sam Ravnborg Cc: Sam Ravnborg Cc: Andrew Morton Cc: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c index a40051b71d9b..0fcc95a354f7 100644 --- a/arch/x86/kernel/topology.c +++ b/arch/x86/kernel/topology.c @@ -34,7 +34,7 @@ static DEFINE_PER_CPU(struct x86_cpu, cpu_devices); #ifdef CONFIG_HOTPLUG_CPU -int arch_register_cpu(int num) +int __ref arch_register_cpu(int num) { /* * CPU0 cannot be offlined due to several From d01b9ad56e2cc7b6204b89ef10a53e78d70b5877 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:22:58 +0100 Subject: [PATCH 376/880] x86: fix section mismatch in srat_64.c:reserve_hotadd reserve_hotadd() are only used by __init acpi_numa_memory_affinity_init(). Annotate reserve_hotadd() with __init is the trivial fix. Signed-off-by: Sam Ravnborg Cc: Sam Ravnborg Cc: Andrew Morton Cc: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/mm/srat_64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index ecd91ea8a8ae..845001c617cc 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -166,7 +166,8 @@ static inline int save_add_info(void) {return 0;} * Both SPARSE and RESERVE need nodes_add information. * This code supports one contiguous hot add area per node. */ -static int reserve_hotadd(int node, unsigned long start, unsigned long end) +static int __init +reserve_hotadd(int node, unsigned long start, unsigned long end) { unsigned long s_pfn = start >> PAGE_SHIFT; unsigned long e_pfn = end >> PAGE_SHIFT; From da5968ae305ab5209ebc2502ef6a8fbf2cce536c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:22:59 +0100 Subject: [PATCH 377/880] x86: fix section mismatch in head_64.S:initial_code initial_code are initially used to hold a function pointer from __init and later from __cpuinit. This confuses modpost and changing initial_code to REFDATA silence the warning. (But now we do not discard the variable anymore). Signed-off-by: Sam Ravnborg Cc: Sam Ravnborg Cc: Andrew Morton Cc: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/head_64.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 53e5820d6054..eb415043a929 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -255,7 +255,7 @@ ENTRY(secondary_startup_64) lretq /* SMP bootup changes these two */ - __CPUINITDATA + __REFDATA .align 8 ENTRY(initial_code) .quad x86_64_start_kernel From 6871b76fb5197a4db28de7116baf834fa36b7bfe Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:23:00 +0100 Subject: [PATCH 378/880] x86: annotate pci/common.s:pci_scan_bus_with_sysdata with __devinit Signed-off-by: Sam Ravnborg Cc: Sam Ravnborg Cc: Andrew Morton Cc: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/pci/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index b7c67a187b6b..7b6e3bb9b28c 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -541,7 +541,7 @@ void pcibios_disable_device (struct pci_dev *dev) pcibios_disable_irq(dev); } -struct pci_bus *pci_scan_bus_with_sysdata(int busno) +struct pci_bus *__devinit pci_scan_bus_with_sysdata(int busno) { struct pci_bus *bus = NULL; struct pci_sysdata *sd; From 0fd707ef724a9e8b4a2ddfd3da4968c57e8614ff Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Fri, 8 Feb 2008 15:37:42 -0800 Subject: [PATCH 379/880] x86: minor cleanup of comments in processor.h Signed-off-by: Mike Travis Cc: Christoph Lameter Cc: Jack Steiner Cc: linux-mm@kvack.org Cc: Andrew Morton Cc: Andi Kleen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/processor.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 7b1ca1f90283..45a2f0ab33d0 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -302,10 +302,6 @@ union i387_union { }; #ifdef CONFIG_X86_32 -/* - * the following now lives in the per cpu area: - * extern int cpu_llc_id[NR_CPUS]; - */ DECLARE_PER_CPU(u8, cpu_llc_id); #else DECLARE_PER_CPU(struct orig_ist, orig_ist); From e00fc542eb694e448249361ef63c190e74f53574 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 19 Feb 2008 16:18:32 +0100 Subject: [PATCH 380/880] x86: add pgd_large() on 64-bit, for consistency In order to have it at all levels, add pgd_large() which only returns 0. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/pgtable_64.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 7fd5e0e2361e..0a0b77bc736a 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -188,6 +188,7 @@ static inline unsigned long pmd_bad(pmd_t pmd) #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) #define pgd_offset_k(address) (init_level4_pgt + pgd_index(address)) #define pgd_present(pgd) (pgd_val(pgd) & _PAGE_PRESENT) +static inline int pgd_large(pgd_t pgd) { return 0; } #define mk_kernel_pgd(address) ((pgd_t){ (address) | _KERNPG_TABLE }) /* PUD - Level3 access */ From e43eb7bab6e82e1aa93ce4d39546c54347a68077 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 08:38:49 +0100 Subject: [PATCH 381/880] x86: exclude vsyscall files from stackprotect Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 76ec0f8f138a..4eb5ce841106 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -6,7 +6,15 @@ extra-y := head_$(BITS).o init_task.o vmlinux.lds extra-$(CONFIG_X86_64) += head64.o CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) -CFLAGS_vsyscall_64.o := $(PROFILING) -g0 + +# +# vsyscalls (which work on the user stack) should have +# no stack-protector checks: +# +nostackp := $(call cc-option, -fno-stack-protector) +CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) +CFLAGS_hpet.o := $(nostackp) +CFLAGS_tsc_64.o := $(nostackp) obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o From 4b44f810166fb83ad1a817ee599006a7157ee54c Mon Sep 17 00:00:00 2001 From: Paolo Ciarrocchi Date: Sun, 17 Feb 2008 14:41:16 +0100 Subject: [PATCH 382/880] x86: coding style fixes in arch/x86/lib/io_64.c This simple patch makes the file error free (according to checkpatch.pl) no code changed: arch/x86/lib/io_64.o: text data bss dec hex filename 308 0 0 308 134 io_64.o.before 308 0 0 308 134 io_64.o.after md5: 3c64f9ed83d091678e849b36ca27bee3 io_64.o.before.asm 3c64f9ed83d091678e849b36ca27bee3 io_64.o.after.asm Signed-off-by: Paolo Ciarrocchi Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/lib/io_64.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/x86/lib/io_64.c b/arch/x86/lib/io_64.c index 87b4a4e18039..3f1eb59b5f08 100644 --- a/arch/x86/lib/io_64.c +++ b/arch/x86/lib/io_64.c @@ -1,23 +1,25 @@ #include -#include #include +#include -void __memcpy_toio(unsigned long dst,const void*src,unsigned len) +void __memcpy_toio(unsigned long dst, const void *src, unsigned len) { - __inline_memcpy((void *) dst,src,len); + __inline_memcpy((void *)dst, src, len); } EXPORT_SYMBOL(__memcpy_toio); -void __memcpy_fromio(void *dst,unsigned long src,unsigned len) +void __memcpy_fromio(void *dst, unsigned long src, unsigned len) { - __inline_memcpy(dst,(const void *) src,len); + __inline_memcpy(dst, (const void *)src, len); } EXPORT_SYMBOL(__memcpy_fromio); void memset_io(volatile void __iomem *a, int b, size_t c) { - /* XXX: memset can mangle the IO patterns quite a bit. - perhaps it would be better to use a dumb one */ - memset((void *)a,b,c); + /* + * TODO: memset can mangle the IO patterns quite a bit. + * perhaps it would be better to use a dumb one: + */ + memset((void *)a, b, c); } EXPORT_SYMBOL(memset_io); From 0df025b709ae09081e21545761a249ec2d969689 Mon Sep 17 00:00:00 2001 From: Paolo Ciarrocchi Date: Sun, 17 Feb 2008 14:56:50 +0100 Subject: [PATCH 383/880] x86: coding style fixes in arch/x86/lib/csum-wrappers_64.c no code changed: arch/x86/lib/csum-wrappers_64.o: text data bss dec hex filename 839 0 0 839 347 csum-wrappers_64.o.before 839 0 0 839 347 csum-wrappers_64.o.after md5: b31994226c33e0b52bef5a0e110b84b0 csum-wrappers_64.o.before.asm b31994226c33e0b52bef5a0e110b84b0 csum-wrappers_64.o.after.asm Signed-off-by: Paolo Ciarrocchi Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/lib/csum-wrappers_64.c | 80 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index fd42a4a095fc..95e45dcc5a29 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c @@ -1,117 +1,117 @@ /* Copyright 2002,2003 Andi Kleen, SuSE Labs. * Subject to the GNU Public License v.2 - * + * * Wrappers of assembly checksum functions for x86-64. */ #include #include -/** - * csum_partial_copy_from_user - Copy and checksum from user space. - * @src: source address (user space) +/** + * csum_partial_copy_from_user - Copy and checksum from user space. + * @src: source address (user space) * @dst: destination address * @len: number of bytes to be copied. * @isum: initial sum that is added into the result (32bit unfolded) * @errp: set to -EFAULT for an bad source address. - * + * * Returns an 32bit unfolded checksum of the buffer. - * src and dst are best aligned to 64bits. - */ + * src and dst are best aligned to 64bits. + */ __wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum isum, int *errp) -{ +{ might_sleep(); *errp = 0; - if (likely(access_ok(VERIFY_READ,src, len))) { + if (likely(access_ok(VERIFY_READ, src, len))) { /* Why 6, not 7? To handle odd addresses aligned we would need to do considerable complications to fix the checksum which is defined as an 16bit accumulator. The fix alignment code is primarily for performance compatibility with 32bit and that will handle odd addresses slowly too. */ - if (unlikely((unsigned long)src & 6)) { - while (((unsigned long)src & 6) && len >= 2) { - __u16 val16; + if (unlikely((unsigned long)src & 6)) { + while (((unsigned long)src & 6) && len >= 2) { + __u16 val16; *errp = __get_user(val16, (const __u16 __user *)src); if (*errp) return isum; *(__u16 *)dst = val16; isum = (__force __wsum)add32_with_carry( (__force unsigned)isum, val16); - src += 2; - dst += 2; + src += 2; + dst += 2; len -= 2; } } isum = csum_partial_copy_generic((__force const void *)src, dst, len, isum, errp, NULL); - if (likely(*errp == 0)) + if (likely(*errp == 0)) return isum; - } + } *errp = -EFAULT; - memset(dst,0,len); - return isum; -} + memset(dst, 0, len); + return isum; +} EXPORT_SYMBOL(csum_partial_copy_from_user); -/** - * csum_partial_copy_to_user - Copy and checksum to user space. +/** + * csum_partial_copy_to_user - Copy and checksum to user space. * @src: source address * @dst: destination address (user space) * @len: number of bytes to be copied. * @isum: initial sum that is added into the result (32bit unfolded) * @errp: set to -EFAULT for an bad destination address. - * + * * Returns an 32bit unfolded checksum of the buffer. * src and dst are best aligned to 64bits. - */ + */ __wsum csum_partial_copy_to_user(const void *src, void __user *dst, int len, __wsum isum, int *errp) -{ +{ might_sleep(); if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { *errp = -EFAULT; - return 0; + return 0; } if (unlikely((unsigned long)dst & 6)) { - while (((unsigned long)dst & 6) && len >= 2) { + while (((unsigned long)dst & 6) && len >= 2) { __u16 val16 = *(__u16 *)src; isum = (__force __wsum)add32_with_carry( (__force unsigned)isum, val16); *errp = __put_user(val16, (__u16 __user *)dst); if (*errp) return isum; - src += 2; - dst += 2; + src += 2; + dst += 2; len -= 2; } } *errp = 0; - return csum_partial_copy_generic(src, (void __force *)dst,len,isum,NULL,errp); -} + return csum_partial_copy_generic(src, (void __force *)dst, len, isum, NULL, errp); +} EXPORT_SYMBOL(csum_partial_copy_to_user); -/** +/** * csum_partial_copy_nocheck - Copy and checksum. * @src: source address * @dst: destination address * @len: number of bytes to be copied. * @isum: initial sum that is added into the result (32bit unfolded) - * + * * Returns an 32bit unfolded checksum of the buffer. - */ + */ __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL); -} +{ + return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); +} EXPORT_SYMBOL(csum_partial_copy_nocheck); __sum16 csum_ipv6_magic(const struct in6_addr *saddr, @@ -119,16 +119,16 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, __u32 len, unsigned short proto, __wsum sum) { __u64 rest, sum64; - + rest = (__force __u64)htonl(len) + (__force __u64)htons(proto) + (__force __u64)sum; asm(" addq (%[saddr]),%[sum]\n" " adcq 8(%[saddr]),%[sum]\n" - " adcq (%[daddr]),%[sum]\n" + " adcq (%[daddr]),%[sum]\n" " adcq 8(%[daddr]),%[sum]\n" " adcq $0,%[sum]\n" - : [sum] "=r" (sum64) - : "[sum]" (rest),[saddr] "r" (saddr), [daddr] "r" (daddr)); + : [sum] "=r" (sum64) + : "[sum]" (rest), [saddr] "r" (saddr), [daddr] "r" (daddr)); return csum_fold((__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32)); } From d76c1ae4d1f4f322d47e7c6e47a277384ba9d9cb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 17 Feb 2008 16:48:25 +0100 Subject: [PATCH 384/880] x86: clean up csum-wrappers_64.c some more no code changed: arch/x86/lib/csum-wrappers_64.o: text data bss dec hex filename 839 0 0 839 347 csum-wrappers_64.o.before 839 0 0 839 347 csum-wrappers_64.o.after md5: b31994226c33e0b52bef5a0e110b84b0 csum-wrappers_64.o.before.asm b31994226c33e0b52bef5a0e110b84b0 csum-wrappers_64.o.after.asm Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/lib/csum-wrappers_64.c | 87 +++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index 95e45dcc5a29..459b58a8a15c 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c @@ -1,9 +1,9 @@ -/* Copyright 2002,2003 Andi Kleen, SuSE Labs. +/* + * Copyright 2002, 2003 Andi Kleen, SuSE Labs. * Subject to the GNU Public License v.2 * * Wrappers of assembly checksum functions for x86-64. */ - #include #include @@ -24,37 +24,47 @@ csum_partial_copy_from_user(const void __user *src, void *dst, { might_sleep(); *errp = 0; - if (likely(access_ok(VERIFY_READ, src, len))) { - /* Why 6, not 7? To handle odd addresses aligned we - would need to do considerable complications to fix the - checksum which is defined as an 16bit accumulator. The - fix alignment code is primarily for performance - compatibility with 32bit and that will handle odd - addresses slowly too. */ - if (unlikely((unsigned long)src & 6)) { - while (((unsigned long)src & 6) && len >= 2) { - __u16 val16; - *errp = __get_user(val16, (const __u16 __user *)src); - if (*errp) - return isum; - *(__u16 *)dst = val16; - isum = (__force __wsum)add32_with_carry( - (__force unsigned)isum, val16); - src += 2; - dst += 2; - len -= 2; - } + + if (!likely(access_ok(VERIFY_READ, src, len))) + goto out_err; + + /* + * Why 6, not 7? To handle odd addresses aligned we + * would need to do considerable complications to fix the + * checksum which is defined as an 16bit accumulator. The + * fix alignment code is primarily for performance + * compatibility with 32bit and that will handle odd + * addresses slowly too. + */ + if (unlikely((unsigned long)src & 6)) { + while (((unsigned long)src & 6) && len >= 2) { + __u16 val16; + + *errp = __get_user(val16, (const __u16 __user *)src); + if (*errp) + return isum; + + *(__u16 *)dst = val16; + isum = (__force __wsum)add32_with_carry( + (__force unsigned)isum, val16); + src += 2; + dst += 2; + len -= 2; } - isum = csum_partial_copy_generic((__force const void *)src, - dst, len, isum, errp, NULL); - if (likely(*errp == 0)) - return isum; } + isum = csum_partial_copy_generic((__force const void *)src, + dst, len, isum, errp, NULL); + if (unlikely(*errp)) + goto out_err; + + return isum; + +out_err: *errp = -EFAULT; memset(dst, 0, len); + return isum; } - EXPORT_SYMBOL(csum_partial_copy_from_user); /** @@ -73,6 +83,7 @@ csum_partial_copy_to_user(const void *src, void __user *dst, int len, __wsum isum, int *errp) { might_sleep(); + if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { *errp = -EFAULT; return 0; @@ -81,6 +92,7 @@ csum_partial_copy_to_user(const void *src, void __user *dst, if (unlikely((unsigned long)dst & 6)) { while (((unsigned long)dst & 6) && len >= 2) { __u16 val16 = *(__u16 *)src; + isum = (__force __wsum)add32_with_carry( (__force unsigned)isum, val16); *errp = __put_user(val16, (__u16 __user *)dst); @@ -93,9 +105,9 @@ csum_partial_copy_to_user(const void *src, void __user *dst, } *errp = 0; - return csum_partial_copy_generic(src, (void __force *)dst, len, isum, NULL, errp); + return csum_partial_copy_generic(src, (void __force *)dst, + len, isum, NULL, errp); } - EXPORT_SYMBOL(csum_partial_copy_to_user); /** @@ -122,14 +134,17 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, rest = (__force __u64)htonl(len) + (__force __u64)htons(proto) + (__force __u64)sum; - asm(" addq (%[saddr]),%[sum]\n" - " adcq 8(%[saddr]),%[sum]\n" - " adcq (%[daddr]),%[sum]\n" - " adcq 8(%[daddr]),%[sum]\n" - " adcq $0,%[sum]\n" + + asm(" addq (%[saddr]),%[sum]\n" + " adcq 8(%[saddr]),%[sum]\n" + " adcq (%[daddr]),%[sum]\n" + " adcq 8(%[daddr]),%[sum]\n" + " adcq $0,%[sum]\n" + : [sum] "=r" (sum64) : "[sum]" (rest), [saddr] "r" (saddr), [daddr] "r" (daddr)); - return csum_fold((__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32)); -} + return csum_fold( + (__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32)); +} EXPORT_SYMBOL(csum_ipv6_magic); From d8ff0bbf564f7ebf6c33ef6662d8f00c7d43ba80 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Fri, 1 Feb 2008 21:31:51 +0100 Subject: [PATCH 385/880] x86: fix printout ugliness in cpu info printk fix print_cpu_info, because it produced on boot: CPU: <6>AMD Athlon(tm) 64 Processor 3200+ stepping 00 instead of: CPU: AMD Athlon(tm) 64 Processor 3200+ stepping 00 (broken since 04e1ba852132c9ad006affcd5b8c8606295170b0 - x86: cleanup kernel/setup_64.c) Signed-off-by: Marcin Slusarz Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index e1866172deb2..6fd804f07821 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -1046,7 +1046,7 @@ __setup("noclflush", setup_noclflush); void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) { if (c->x86_model_id[0]) - printk(KERN_INFO "%s", c->x86_model_id); + printk(KERN_CONT "%s", c->x86_model_id); if (c->x86_mask || c->cpuid_level >= 0) printk(KERN_CONT " stepping %02x\n", c->x86_mask); From 248fb89c12228190cecea553353e16cf21a67dc3 Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Sun, 17 Feb 2008 18:01:42 +1100 Subject: [PATCH 386/880] x86: docs fixes to Documentation/i386/IO-APIC.txt Clean up spelling and grammar of IO-APIC.txt Signed-off-by: Nick Andrew Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- Documentation/i386/IO-APIC.txt | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Documentation/i386/IO-APIC.txt b/Documentation/i386/IO-APIC.txt index 435e69e6e9aa..f95166645d29 100644 --- a/Documentation/i386/IO-APIC.txt +++ b/Documentation/i386/IO-APIC.txt @@ -1,12 +1,14 @@ Most (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC', -which is an enhanced interrupt controller, it enables us to route -hardware interrupts to multiple CPUs, or to CPU groups. +which is an enhanced interrupt controller. It enables us to route +hardware interrupts to multiple CPUs, or to CPU groups. Without an +IO-APIC, interrupts from hardware will be delivered only to the +CPU which boots the operating system (usually CPU#0). Linux supports all variants of compliant SMP boards, including ones with -multiple IO-APICs. (multiple IO-APICs are used in high-end servers to -distribute IRQ load further). +multiple IO-APICs. Multiple IO-APICs are used in high-end servers to +distribute IRQ load further. -There are (a few) known breakages in certain older boards, which bugs are +There are (a few) known breakages in certain older boards, such bugs are usually worked around by the kernel. If your MP-compliant SMP board does not boot Linux, then consult the linux-smp mailing list archives first. @@ -28,18 +30,18 @@ If your box boots fine with enabled IO-APIC IRQs, then your hell:~> <---------------------------- -some interrupts are still listed as 'XT PIC', but this is not a problem, +Some interrupts are still listed as 'XT PIC', but this is not a problem; none of those IRQ sources is performance-critical. -in the unlikely case that your board does not create a working mp-table, +In the unlikely case that your board does not create a working mp-table, you can use the pirq= boot parameter to 'hand-construct' IRQ entries. This -is nontrivial though and cannot be automated. One sample /etc/lilo.conf +is non-trivial though and cannot be automated. One sample /etc/lilo.conf entry: append="pirq=15,11,10" -the actual numbers depend on your system, on your PCI cards and on their +The actual numbers depend on your system, on your PCI cards and on their PCI slot position. Usually PCI slots are 'daisy chained' before they are connected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4 lines): @@ -54,7 +56,7 @@ lines): PIRQ1 ----| |- `----| |- `----| |- `----| |--------| | `-' `-' `-' `-' `-' -every PCI card emits a PCI IRQ, which can be INTA,INTB,INTC,INTD: +Every PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD: ,-. INTD--| | @@ -95,21 +97,21 @@ card (IRQ11) in Slot3, and have Slot1 empty: [value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting) slots.] -generally, it's always possible to find out the correct pirq= settings, just +Generally, it's always possible to find out the correct pirq= settings, just permute all IRQ numbers properly ... it will take some time though. An 'incorrect' pirq line will cause the booting process to hang, or a device -won't function properly (if it's inserted as eg. a module). +won't function properly (e.g. if it's inserted as a module). -If you have 2 PCI buses, then you can use up to 8 pirq values. Although such +If you have 2 PCI buses, then you can use up to 8 pirq values, although such boards tend to have a good configuration. Be prepared that it might happen that you need some strange pirq line: append="pirq=0,0,0,0,0,0,9,11" -use smart try-and-err techniques to find out the correct pirq line ... +Use smart trial-and-error techniques to find out the correct pirq line ... -good luck and mail to linux-smp@vger.kernel.org or +Good luck and mail to linux-smp@vger.kernel.org or linux-kernel@vger.kernel.org if you have any problems that are not covered by this document. From bbb1e57a1c0b732cfeb727bed7c61e80a79c6479 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 9 Feb 2008 00:49:13 +0300 Subject: [PATCH 387/880] x86 cleanup: suspend_asm_64.S - use X86_CR4_PGE instead of numeric value By including we're allowed to use X86_CR4_PGE instead of numeric constant. md5 sums of compiled files are differ due to this inclusion but .text section remains the same. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/power/hibernate_asm_64.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S index 1deb3244b99b..000415947d93 100644 --- a/arch/x86/power/hibernate_asm_64.S +++ b/arch/x86/power/hibernate_asm_64.S @@ -20,6 +20,7 @@ #include #include #include +#include ENTRY(swsusp_arch_suspend) movq $saved_context, %rax @@ -60,7 +61,7 @@ ENTRY(restore_image) /* Flush TLB */ movq mmu_cr4_features(%rip), %rax movq %rax, %rdx - andq $~(1<<7), %rdx # PGE + andq $~(X86_CR4_PGE), %rdx movq %rdx, %cr4; # turn off PGE movq %cr3, %rcx; # flush TLB movq %rcx, %cr3; @@ -112,7 +113,7 @@ ENTRY(restore_registers) /* Flush TLB, including "global" things (vmalloc) */ movq mmu_cr4_features(%rip), %rax movq %rax, %rdx - andq $~(1<<7), %rdx; # PGE + andq $~(X86_CR4_PGE), %rdx movq %rdx, %cr4; # turn off PGE movq %cr3, %rcx; # flush TLB movq %rcx, %cr3 From 3cdac41f2090ad9013dfefab7399b1debfb9275a Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sun, 17 Feb 2008 18:17:17 +0300 Subject: [PATCH 388/880] x86: lds - Use PAGE_SIZE instead of numeric constant It's much better to use PAGE_SIZE then magic 4096 (though it's almost synonym in most cases on x86 but not for *all* cases ;) Signed-off-by: Cyrill Gorcunov Acked-by: Sam Ravnborg Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/vmlinux_32.lds.S | 26 +++++++++++++------------- arch/x86/kernel/vmlinux_64.lds.S | 28 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S index f1148ac8abe3..2ffa9656fe7a 100644 --- a/arch/x86/kernel/vmlinux_32.lds.S +++ b/arch/x86/kernel/vmlinux_32.lds.S @@ -38,7 +38,7 @@ SECTIONS /* read-only */ .text : AT(ADDR(.text) - LOAD_OFFSET) { - . = ALIGN(4096); /* not really needed, already page aligned */ + . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */ *(.text.page_aligned) TEXT_TEXT SCHED_TEXT @@ -70,21 +70,21 @@ SECTIONS RODATA /* writeable */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ DATA_DATA CONSTRUCTORS } :data - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { __nosave_begin = .; *(.data.nosave) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __nosave_end = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { *(.data.page_aligned) *(.data.idt) @@ -108,7 +108,7 @@ SECTIONS } /* might get freed after init */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { __smp_locks = .; *(.smp_locks) @@ -120,10 +120,10 @@ SECTIONS * after boot. Always make sure that ALIGN() directive is present after * the section which contains __smp_alt_end. */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); /* will be freed after init */ - . = ALIGN(4096); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { __init_begin = .; _sinittext = .; @@ -174,23 +174,23 @@ SECTIONS EXIT_DATA } #if defined(CONFIG_BLK_DEV_INITRD) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { __initramfs_start = .; *(.init.ramfs) __initramfs_end = .; } #endif - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { __per_cpu_start = .; *(.data.percpu) *(.data.percpu.shared_aligned) __per_cpu_end = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); /* freed after init ends here */ - + .bss : AT(ADDR(.bss) - LOAD_OFFSET) { __init_end = .; __bss_start = .; /* BSS */ @@ -200,7 +200,7 @@ SECTIONS __bss_stop = .; _end = . ; /* This is where the kernel creates the early boot page tables */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); pg0 = . ; } diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index 0992b9946c6f..5e9ec1b33c10 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -37,7 +37,7 @@ SECTIONS KPROBES_TEXT *(.fixup) *(.gnu.warning) - _etext = .; /* End of text section */ + _etext = .; /* End of text section */ } :text = 0x9090 . = ALIGN(16); /* Exception table */ @@ -60,7 +60,7 @@ SECTIONS __tracedata_end = .; } - . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { DATA_DATA @@ -119,7 +119,7 @@ SECTIONS .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) } - . = VSYSCALL_VIRT_ADDR + 4096; + . = VSYSCALL_VIRT_ADDR + PAGE_SIZE; #undef VSYSCALL_ADDR #undef VSYSCALL_PHYS_ADDR @@ -134,23 +134,23 @@ SECTIONS *(.data.init_task) }:data.init - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { *(.data.page_aligned) } /* might get freed after init */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __smp_alt_begin = .; __smp_locks = .; .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { *(.smp_locks) } __smp_locks_end = .; - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __smp_alt_end = .; - . = ALIGN(4096); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { _sinittext = .; @@ -191,7 +191,7 @@ SECTIONS .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { *(.altinstructions) } - __alt_instructions_end = .; + __alt_instructions_end = .; .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { *(.altinstr_replacement) } @@ -207,25 +207,25 @@ SECTIONS /* vdso blob that is mapped into user space */ vdso_start = . ; .vdso : AT(ADDR(.vdso) - LOAD_OFFSET) { *(.vdso) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); vdso_end = .; #ifdef CONFIG_BLK_DEV_INITRD - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __initramfs_start = .; .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } __initramfs_end = .; #endif - PERCPU(4096) + PERCPU(PAGE_SIZE) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __init_end = .; - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __nosave_begin = .; .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __nosave_end = .; __bss_start = .; /* BSS */ From 85c42d0dbb129b6bff560dacabec753677d64081 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sun, 17 Feb 2008 18:17:18 +0300 Subject: [PATCH 389/880] x86: lds - Use THREAD_SIZE instead of numeric constant Though we use PDA for regular task stack but that is not acceptable for init_task wich is special one. We still have to allocate init_task's stack in that manner. Signed-off-by: Cyrill Gorcunov Acked-by: Sam Ravnborg Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/vmlinux_64.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index 5e9ec1b33c10..fab132299735 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -129,7 +129,7 @@ SECTIONS #undef VVIRT_OFFSET #undef VVIRT - . = ALIGN(8192); /* init_task */ + . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) }:data.init From fd59e9e9c8e35cd2a1834c0d1f67aedf0c5c68c2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 17 Feb 2008 20:20:24 +0100 Subject: [PATCH 390/880] x86: change IO delay back to 0x80 change back the IO delay to 0x80. Alan says that 0xed is known to break some older boxes, and given that the get-rid-of-outb-APIs efforts are well underway we should just let them be finished. Signed-off-by: Ingo Molnar Acked-by: Alan Cox Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 864affc9a7b0..702eb39901ca 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -156,7 +156,7 @@ config IO_DELAY_TYPE_NONE choice prompt "IO delay type" - default IO_DELAY_0XED + default IO_DELAY_0X80 config IO_DELAY_0X80 bool "port 0x80 based port-IO delay [recommended]" From 3f85d63ea4ff922f6abdb509f4aaf6993b3273a3 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 16 Feb 2008 12:36:10 +0100 Subject: [PATCH 391/880] x86: fix vdso_install breaks user "make install" I suggest to make the vdso_install step independent as in following patch. This solves the issue at ahnd and still gives us the posibility to install the files should they be needed. Signed-off-by: Sam Ravnborg Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/powerpc/Makefile | 2 +- arch/x86/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 6845482f0093..1c6ce3536e4c 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -176,7 +176,7 @@ define archhelp @echo ' *_defconfig - Select default config from arch/$(ARCH)/configs' endef -install: vdso_install +install: $(Q)$(MAKE) $(build)=$(boot) install vdso_install: diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 204af43535c5..f1e739a43d41 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -229,7 +229,7 @@ zdisk bzdisk: vmlinux fdimage fdimage144 fdimage288 isoimage: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ -install: vdso_install +install: $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install PHONY += vdso_install From 7c6357da1185d286adaa4452d829ac9b27c4d12f Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Mon, 18 Feb 2008 00:59:54 +0200 Subject: [PATCH 392/880] x86: i8259A: remove redundant irq_descinitialization Remove redundant irq_desc[NR_IRQS] element initialization in init_ISA_irqs(). irq_desc[NR_IRQS] is already statically initialized with the same values in kernel/irq/handle.c . besides the clean-up value this also saves some space: text data bss dec hex filename 1389 356 14 1759 6df i8259_32.o.before 1325 356 14 1695 69f i8259_32.o.after Signed-off-by: Ahmed S. Darwish Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/i8259_32.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c index 2d25b77102fe..fe631967d625 100644 --- a/arch/x86/kernel/i8259_32.c +++ b/arch/x86/kernel/i8259_32.c @@ -26,8 +26,6 @@ * present in the majority of PC/AT boxes. * plus some generic x86 specific things if generic specifics makes * any sense at all. - * this file should become arch/i386/kernel/irq.c when the old irq.c - * moves to arch independent land */ static int i8259A_auto_eoi; @@ -362,23 +360,12 @@ void __init init_ISA_irqs (void) #endif init_8259A(0); - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - - if (i < 16) { - /* - * 16 old-style INTA-cycle interrupts: - */ - set_irq_chip_and_handler_name(i, &i8259A_chip, - handle_level_irq, "XT"); - } else { - /* - * 'high' PCI IRQs filled in on demand - */ - irq_desc[i].chip = &no_irq_chip; - } + /* + * 16 old-style INTA-cycle interrupts: + */ + for (i = 0; i < 16; i++) { + set_irq_chip_and_handler_name(i, &i8259A_chip, + handle_level_irq, "XT"); } } From d8a9e6a51ec58486f850e3606e3fcb86b5b7da41 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 18 Feb 2008 09:54:33 -0800 Subject: [PATCH 393/880] x86: fix WARN_ON() message: teach page_is_ram() about the special 4Kb bios data page This patch teaches page_is_ram() about the fact that the first 4Kb of memory are special on x86, even though the E820 table normally doesn't exclude it. This fixes the WARN_ON() reported by Laurent Riffard who was also very helpful in diagnosing the issue. [ mingo@elte.hu: we are working on doing this properly in the e820 space, but for 2.6.25 this is the better fix. ] Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/mm/ioremap.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 9f42d7e9c158..7fb6eff644b3 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -42,6 +42,15 @@ int page_is_ram(unsigned long pagenr) unsigned long addr, end; int i; + /* + * A special case is the first 4Kb of memory; + * This is a BIOS owned area, not kernel ram, but generally + * not listed as such in the E820 table. + */ + if (pagenr == 0) + return 0; + + for (i = 0; i < e820.nr_map; i++) { /* * Not usable memory: From 156fbc3fbe4ab640297b1ae2092821363840aeb6 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 18 Feb 2008 09:58:45 -0800 Subject: [PATCH 394/880] x86: fix page_is_ram() thinko page_is_ram() has a special case for the 640k-1M bios area, however due to a thinko the special case checks the e820 table entry and not the memory the user has asked for. This patch fixes the bug. [ mingo@elte.hu: this too is better solved in the e820 space, but those fixes are too intrusive for v2.6.25. ] Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/mm/ioremap.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 7fb6eff644b3..f4c95aec5acb 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -50,6 +50,13 @@ int page_is_ram(unsigned long pagenr) if (pagenr == 0) return 0; + /* + * Second special case: Some BIOSen report the PC BIOS + * area (640->1Mb) as ram even though it is not. + */ + if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) && + pagenr < (BIOS_END >> PAGE_SHIFT)) + return 0; for (i = 0; i < e820.nr_map; i++) { /* @@ -60,14 +67,6 @@ int page_is_ram(unsigned long pagenr) addr = (e820.map[i].addr + PAGE_SIZE-1) >> PAGE_SHIFT; end = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT; - /* - * Sanity check: Some BIOSen report areas as RAM that - * are not. Notably the 640->1Mb area, which is the - * PCI BIOS area. - */ - if (addr >= (BIOS_BEGIN >> PAGE_SHIFT) && - end < (BIOS_END >> PAGE_SHIFT)) - continue; if ((pagenr >= addr) && (pagenr < end)) return 1; From 4bc87e62775052aac0be7574d5f84ff06f61c6b4 Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Fri, 15 Feb 2008 15:24:25 -0800 Subject: [PATCH 395/880] Smack: unlabeled outgoing ambient packets Smack uses CIPSO labeling, but allows for unlabeled packets by specifying an "ambient" label that is applied to incoming unlabeled packets. Because the other end of the connection may dislike IP options, and ssh is one know application that behaves thus, it is prudent to respond in kind. This patch changes the network labeling behavior such that an outgoing packet that would be given a CIPSO label that matches the ambient label is left unlabeled. An "unlbl" domain is added and the netlabel defaulting mechanism invoked rather than assuming that everything is CIPSO. Locking has been added around changes to the ambient label as the mechanisms used to do so are more involved. Signed-off-by: Casey Schaufler Acked-by: Paul Moore Signed-off-by: Linus Torvalds --- security/smack/smack_lsm.c | 36 +++++++++++++++++----- security/smack/smackfs.c | 61 ++++++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 2b5d6f72f678..25cbfa3f71f4 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1251,9 +1251,8 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) switch (smack_net_nltype) { case NETLBL_NLTYPE_CIPSOV4: - nlsp->domain = NULL; - nlsp->flags = NETLBL_SECATTR_DOMAIN; - nlsp->flags |= NETLBL_SECATTR_MLS_LVL; + nlsp->domain = kstrdup(smack, GFP_ATOMIC); + nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; rc = smack_to_cipso(smack, &cipso); if (rc == 0) { @@ -1282,15 +1281,14 @@ static int smack_netlabel(struct sock *sk) { struct socket_smack *ssp; struct netlbl_lsm_secattr secattr; - int rc = 0; + int rc; ssp = sk->sk_security; netlbl_secattr_init(&secattr); smack_to_secattr(ssp->smk_out, &secattr); - if (secattr.flags != NETLBL_SECATTR_NONE) - rc = netlbl_sock_setattr(sk, &secattr); - + rc = netlbl_sock_setattr(sk, &secattr); netlbl_secattr_destroy(&secattr); + return rc; } @@ -1313,6 +1311,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, struct inode_smack *nsp = inode->i_security; struct socket_smack *ssp; struct socket *sock; + int rc = 0; if (value == NULL || size > SMK_LABELLEN) return -EACCES; @@ -1341,7 +1340,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, ssp->smk_in = sp; else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { ssp->smk_out = sp; - return smack_netlabel(sock->sk); + rc = smack_netlabel(sock->sk); + if (rc != 0) + printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", + __func__, -rc); } else return -EOPNOTSUPP; @@ -2214,6 +2216,9 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) ssp->smk_packet[0] = '\0'; rc = smack_netlabel(sk); + if (rc != 0) + printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", + __func__, -rc); } /** @@ -2345,6 +2350,20 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) return 0; } +/* + * smack_secctx_to_secid - return the secid for a smack label + * @secdata: smack label + * @seclen: how long result is + * @secid: outgoing integer + * + * Exists for audit and networking code. + */ +static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) +{ + *secid = smack_to_secid(secdata); + return 0; +} + /* * smack_release_secctx - don't do anything. * @key_ref: unused @@ -2475,6 +2494,7 @@ static struct security_operations smack_ops = { .key_permission = smack_key_permission, #endif /* CONFIG_KEYS */ .secid_to_secctx = smack_secid_to_secctx, + .secctx_to_secid = smack_secctx_to_secid, .release_secctx = smack_release_secctx, }; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 15aa37f65b39..358c92c1a153 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "smack.h" /* @@ -45,6 +46,7 @@ enum smk_inos { */ static DEFINE_MUTEX(smack_list_lock); static DEFINE_MUTEX(smack_cipso_lock); +static DEFINE_MUTEX(smack_ambient_lock); /* * This is the "ambient" label for network traffic. @@ -342,6 +344,9 @@ void smk_cipso_doi(void) struct cipso_v4_doi *doip; struct netlbl_audit audit_info; + audit_info.loginuid = audit_get_loginuid(current); + audit_info.secid = smack_to_secid(current->security); + rc = netlbl_cfg_map_del(NULL, &audit_info); if (rc != 0) printk(KERN_WARNING "%s:%d remove rc = %d\n", @@ -363,6 +368,30 @@ void smk_cipso_doi(void) __func__, __LINE__, rc); } +/** + * smk_unlbl_ambient - initialize the unlabeled domain + */ +void smk_unlbl_ambient(char *oldambient) +{ + int rc; + struct netlbl_audit audit_info; + + audit_info.loginuid = audit_get_loginuid(current); + audit_info.secid = smack_to_secid(current->security); + + if (oldambient != NULL) { + rc = netlbl_cfg_map_del(oldambient, &audit_info); + if (rc != 0) + printk(KERN_WARNING "%s:%d remove rc = %d\n", + __func__, __LINE__, rc); + } + + rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info); + if (rc != 0) + printk(KERN_WARNING "%s:%d add rc = %d\n", + __func__, __LINE__, rc); +} + /* * Seq_file read operations for /smack/cipso */ @@ -709,7 +738,6 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, size_t cn, loff_t *ppos) { ssize_t rc; - char out[SMK_LABELLEN]; int asize; if (*ppos != 0) @@ -717,23 +745,18 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, /* * Being careful to avoid a problem in the case where * smack_net_ambient gets changed in midstream. - * Since smack_net_ambient is always set with a value - * from the label list, including initially, and those - * never get freed, the worst case is that the pointer - * gets changed just after this strncpy, in which case - * the value passed up is incorrect. Locking around - * smack_net_ambient wouldn't be any better than this - * copy scheme as by the time the caller got to look - * at the ambient value it would have cleared the lock - * and been changed. */ - strncpy(out, smack_net_ambient, SMK_LABELLEN); - asize = strlen(out) + 1; + mutex_lock(&smack_ambient_lock); - if (cn < asize) - return -EINVAL; + asize = strlen(smack_net_ambient) + 1; + + if (cn >= asize) + rc = simple_read_from_buffer(buf, cn, ppos, + smack_net_ambient, asize); + else + rc = -EINVAL; - rc = simple_read_from_buffer(buf, cn, ppos, out, asize); + mutex_unlock(&smack_ambient_lock); return rc; } @@ -751,6 +774,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char in[SMK_LABELLEN]; + char *oldambient; char *smack; if (!capable(CAP_MAC_ADMIN)) @@ -766,7 +790,13 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, if (smack == NULL) return -EINVAL; + mutex_lock(&smack_ambient_lock); + + oldambient = smack_net_ambient; smack_net_ambient = smack; + smk_unlbl_ambient(oldambient); + + mutex_unlock(&smack_ambient_lock); return count; } @@ -974,6 +1004,7 @@ static int __init init_smk_fs(void) sema_init(&smack_write_sem, 1); smk_cipso_doi(); + smk_unlbl_ambient(NULL); return err; } From 2b28a4721e068ac89bd5435472723a1bc44442fe Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 19 Feb 2008 17:02:27 +0900 Subject: [PATCH 396/880] [SCSI] ips: fix data buffer accessors conversion bug This fixes a bug that can't handle a passthru command with more than two sg entries. Big thanks to Tim Pepper for debugging the problem. Signed-off-by: FUJITA Tomonori Acked-by: Mark Salyzyn Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index bb152fb9fec7..7ed568f180ae 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -1576,7 +1576,7 @@ ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr) METHOD_TRACE("ips_make_passthru", 1); scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i) - length += sg[i].length; + length += sg->length; if (length < sizeof (ips_passthru_t)) { /* wrong size */ From 0e568536d94256819f17662c26c82a42e44a7a7c Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 4 Feb 2008 23:44:24 -0800 Subject: [PATCH 397/880] [MIPS] Use find_task_by_vpid in system calls There are some places left in mips, that lookup task in initial namespace, while the code doing so gets the pid from the user space and thus must treat it as virtual. Signed-off-by: Pavel Emelyanov Cc: "Eric W. Biederman" Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Ralf Baechle --- arch/mips/kernel/mips-mt-fpaff.c | 2 +- arch/mips/kernel/sysirix.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index bb4f00c0cbe9..df4d3f2f740c 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -36,7 +36,7 @@ unsigned long mt_fpemul_threshold = 0; */ static inline struct task_struct *find_process_by_pid(pid_t pid) { - return pid ? find_task_by_pid(pid) : current; + return pid ? find_task_by_vpid(pid) : current; } diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 672fba84b2cc..c357762b8012 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -111,7 +111,7 @@ asmlinkage int irix_prctl(unsigned option, ...) printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n", current->comm, current->pid); read_lock(&tasklist_lock); - task = find_task_by_pid(va_arg(args, pid_t)); + task = find_task_by_vpid(va_arg(args, pid_t)); error = -ESRCH; if (error) error = (task->run_list.next != NULL); From eaf7943cc53d9688aa10267a226165356e956ec5 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 8 Feb 2008 13:13:27 +0000 Subject: [PATCH 398/880] [MIPS] IP27: Add missing ~ in DMA code. Harmless since this function is not being called on I/O coherent systems such as IP27. Signed-off-by: Ralf Baechle --- include/asm-mips/mach-ip27/dma-coherence.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-mips/mach-ip27/dma-coherence.h b/include/asm-mips/mach-ip27/dma-coherence.h index 3fdbbf68e952..ed7e6222dc15 100644 --- a/include/asm-mips/mach-ip27/dma-coherence.h +++ b/include/asm-mips/mach-ip27/dma-coherence.h @@ -35,7 +35,7 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) { - return dma_addr & (0xffUL << 56); + return dma_addr & ~(0xffUL << 56); } static inline void plat_unmap_dma_mem(dma_addr_t dma_addr) From 2eaa7ec286db54cc1a864565ed9367966743bcbd Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 11 Feb 2008 14:51:40 +0000 Subject: [PATCH 399/880] [MIPS] Handle I-cache coherency in flush_cache_range() So far flush_cache_range() did't consider the I-cache largely because it did rarely ever matter to real world code. This was working primarily because normally code and data are don't share the same pages - with the exception of MIPS16 code which uses address constants embedded between the code. The following sequence of events may break the code: o MIPS16 executable being loaded o dynamic linker relocates the address constants embedded into the code: o Uses mprotect(2) to make code pages PROT_READ|PROT_WRITE o Performs the actual relocations by writing to the pages which likely are COW. Because no PROT_EXEC is set I-cache coherence will not be considered. o Uses mprotect(2) to switch code pages back to PROT_READ|PROT_EXEC. This results in a call to flush_cache_range() which also does not consider I-caches. o => executing the page just having been relocated may now result in the I-cache getting refilled with stale data from memory. Signed-off-by: Ralf Baechle --- arch/mips/mm/c-r4k.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 53ec05267a98..2c4f7e11f0d5 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -364,20 +364,23 @@ static inline int has_valid_asid(const struct mm_struct *mm) static inline void local_r4k_flush_cache_range(void * args) { struct vm_area_struct *vma = args; + int exec = vma->vm_flags & VM_EXEC; if (!(has_valid_asid(vma->vm_mm))) return; r4k_blast_dcache(); + if (exec) + r4k_blast_icache(); } static void r4k_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - if (!cpu_has_dc_aliases) - return; + int exec = vma->vm_flags & VM_EXEC; - r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1); + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1); } static inline void local_r4k_flush_cache_mm(void * args) From c42d95d6c49ce9c678a9d10aeb3f526c850d66dc Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Mon, 11 Feb 2008 23:42:12 +0100 Subject: [PATCH 400/880] [MIPS] Fix broken rm7000/rm9000 interrupt handling Properly acknowledge RM7K and RM9K interrupts. Before this, interrupts were permanently masked after their first occurrence, making them non-functional. Signed-off-by: Thomas Koeller Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq-rm7000.c | 1 + arch/mips/kernel/irq-rm9000.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 971adf6ef4f4..fb50cc78b28b 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -33,6 +33,7 @@ static struct irq_chip rm7k_irq_controller = { .mask = mask_rm7k_irq, .mask_ack = mask_rm7k_irq, .unmask = unmask_rm7k_irq, + .eoi = unmask_rm7k_irq }; void __init rm7k_cpu_irq_init(void) diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index 7b04583bd800..ed9febe63d72 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -75,6 +75,7 @@ static struct irq_chip rm9k_irq_controller = { .mask = mask_rm9k_irq, .mask_ack = mask_rm9k_irq, .unmask = unmask_rm9k_irq, + .eoi = unmask_rm9k_irq }; static struct irq_chip rm9k_perfcounter_irq = { From 9a74b3eb22f2d67a5681301f52aca5b7703382c8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 16 Feb 2008 22:34:25 +0000 Subject: [PATCH 401/880] [MIPS] Fix buggy invocations of kmap_coherent() kmap_coherent will only work correctly if the page it is called on is not marked dirty. If it's dirty the kernel address of the page should be used instead of a temporary mapping. Signed-off-by: Ralf Baechle --- arch/mips/mm/cache.c | 15 ++++++++++----- arch/mips/mm/init.c | 9 ++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 81f30ac2bff9..6a24651971df 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -92,12 +92,17 @@ EXPORT_SYMBOL(__flush_dcache_page); void __flush_anon_page(struct page *page, unsigned long vmaddr) { - if (pages_do_alias((unsigned long)page_address(page), vmaddr)) { - void *kaddr; + unsigned long addr = (unsigned long) page_address(page); - kaddr = kmap_coherent(page, vmaddr); - flush_data_cache_page((unsigned long)kaddr); - kunmap_coherent(); + if (pages_do_alias(addr, vmaddr)) { + if (page_mapped(page) && !Page_dcache_dirty(page)) { + void *kaddr; + + kaddr = kmap_coherent(page, vmaddr); + flush_data_cache_page((unsigned long)kaddr); + kunmap_coherent(); + } else + flush_data_cache_page(addr); } } diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 480dec04f552..c7aed133d11d 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -211,7 +211,8 @@ void copy_user_highpage(struct page *to, struct page *from, void *vfrom, *vto; vto = kmap_atomic(to, KM_USER1); - if (cpu_has_dc_aliases && page_mapped(from)) { + if (cpu_has_dc_aliases && + page_mapped(from) && !Page_dcache_dirty(from)) { vfrom = kmap_coherent(from, vaddr); copy_page(vto, vfrom); kunmap_coherent(); @@ -234,7 +235,8 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { - if (cpu_has_dc_aliases && page_mapped(page)) { + if (cpu_has_dc_aliases && + page_mapped(page) && !Page_dcache_dirty(page)) { void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(vto, src, len); kunmap_coherent(); @@ -253,7 +255,8 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { - if (cpu_has_dc_aliases && page_mapped(page)) { + if (cpu_has_dc_aliases && + page_mapped(page) && !Page_dcache_dirty(page)) { void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); memcpy(dst, vfrom, len); kunmap_coherent(); From af0c4f649dacb62d756de0f20914b3e90a3f21c4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 18 Feb 2008 18:49:48 +0000 Subject: [PATCH 402/880] [MIPS] BCM1480: Remove stray function call resulting in infinite recursion Signed-off-by: Ralf Baechle --- arch/mips/sibyte/bcm1480/smp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c index 183c460b9ca1..bd9eeb43ed0e 100644 --- a/arch/mips/sibyte/bcm1480/smp.c +++ b/arch/mips/sibyte/bcm1480/smp.c @@ -110,7 +110,6 @@ static void __cpuinit bcm1480_smp_finish(void) sb1480_clockevent_init(); local_irq_enable(); - bcm1480_smp_finish(); } /* From 345599ab12729ce1df26f20a42a1ffd8eb7e8a0a Mon Sep 17 00:00:00 2001 From: Thiemo Seufer Date: Thu, 14 Feb 2008 16:58:25 +0000 Subject: [PATCH 403/880] [MIPS] SB1: Fix CONFIG_SIBYTE_DMA_PAGEOPS build failure. Fix type mismatch warnings for 64-bit kernel builds which trigger -Werror. The problem affects only SB-1 kernels with CONFIG_SIBYTE_DMA_PAGEOPS enabled. Signed-off-by: Thiemo Seufer Signed-off-by: Ralf Baechle --- arch/mips/mm/pg-sb1.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c index a3e98c243a89..89925ec57d6a 100644 --- a/arch/mips/mm/pg-sb1.c +++ b/arch/mips/mm/pg-sb1.c @@ -216,7 +216,7 @@ void sb1_dma_init(void) int i; for (i = 0; i < DM_NUM_CHANNELS; i++) { - const u64 base_val = CPHYSADDR(&page_descr[i]) | + const u64 base_val = CPHYSADDR((unsigned long)&page_descr[i]) | V_DM_DSCR_BASE_RINGSZ(1); void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE)); @@ -228,11 +228,11 @@ void sb1_dma_init(void) void clear_page(void *page) { - u64 to_phys = CPHYSADDR(page); + u64 to_phys = CPHYSADDR((unsigned long)page); unsigned int cpu = smp_processor_id(); /* if the page is not in KSEG0, use old way */ - if ((long)KSEGX(page) != (long)CKSEG0) + if ((long)KSEGX((unsigned long)page) != (long)CKSEG0) return clear_page_cpu(page); page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM | @@ -252,13 +252,13 @@ void clear_page(void *page) void copy_page(void *to, void *from) { - u64 from_phys = CPHYSADDR(from); - u64 to_phys = CPHYSADDR(to); + u64 from_phys = CPHYSADDR((unsigned long)from); + u64 to_phys = CPHYSADDR((unsigned long)to); unsigned int cpu = smp_processor_id(); /* if any page is not in KSEG0, use old way */ - if ((long)KSEGX(to) != (long)CKSEG0 - || (long)KSEGX(from) != (long)CKSEG0) + if ((long)KSEGX((unsigned long)to) != (long)CKSEG0 + || (long)KSEGX((unsigned long)from) != (long)CKSEG0) return copy_page_cpu(to, from); page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST | From 84502f817b0b28f37e0a7355c75f05bb489d3a01 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 18 Feb 2008 22:38:32 +0100 Subject: [PATCH 404/880] [MIPS] IP28: Add defconfig file Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/configs/ip28_defconfig | 891 +++++++++++++++++++++++++++++++ 1 file changed, 891 insertions(+) create mode 100644 arch/mips/configs/ip28_defconfig diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig new file mode 100644 index 000000000000..ec188be9a67a --- /dev/null +++ b/arch/mips/configs/ip28_defconfig @@ -0,0 +1,891 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.25-rc1 +# Mon Feb 11 15:58:54 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +CONFIG_SGI_IP28=y +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_ARC=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_SGI_HAS_DS1286=y +CONFIG_SGI_HAS_INDYDOG=y +CONFIG_SGI_HAS_SEEQ=y +CONFIG_SGI_HAS_WD93=y +CONFIG_SGI_HAS_ZILOG=y +CONFIG_SGI_HAS_I8042=y +CONFIG_DEFAULT_SGI_PARTITION=y +CONFIG_MIPS_L1_CACHE_SHIFT=7 +CONFIG_ARC_CONSOLE=y +CONFIG_ARC_PROMLIB=y +CONFIG_ARC64=y +CONFIG_BOOT_ELF64=y + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +CONFIG_CPU_R10000=y +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_R10000=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +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=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_MIPS_INSANE_LARGE is not set +# CONFIG_KEXEC is not set +CONFIG_SECCOMP=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=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_SWAP=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_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=y +# 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_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_HOTPLUG is not set +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_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_KPROBES is not set +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_EISA=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ISA=y +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_MMU=y +CONFIG_I8253=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_SUSPEND is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# 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=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL 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_CAN 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_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP 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_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +CONFIG_SGIWD93_SCSI=y +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +CONFIG_DUMMY=m +# 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_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_AX88796 is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA 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_NET_PCI is not set +# CONFIG_B44 is not set +CONFIG_SGISEEQ=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP 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=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# 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_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_ALPS is not set +CONFIG_MOUSE_PS2_LOGIPS2PP=y +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +# CONFIG_MOUSE_PS2_LIFEBOOK is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IP22_ZILOG=y +CONFIG_SERIAL_IP22_ZILOG_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +CONFIG_SGI_DS1286=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_INDYDOG=y + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT 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 + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set +CONFIG_GENERIC_ACL=y + +# +# 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_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# 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_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_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 +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS 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=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# 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_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_MANAGER=y +# 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=y +# 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 is not set +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD 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 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 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_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_HW is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y From 6783fe6253045bf5cbdf25e4be296f91437c5523 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Tue, 19 Feb 2008 00:02:37 +0300 Subject: [PATCH 405/880] [MIPS] Wire up the timerfd_*() o32 system calls This patch enables the system calls timerfd_create(), timerfd_settime() and timerfd_gettime() for MIPS architecture. Please see the following Bugzilla entry for more details: http://bugzilla.kernel.org/show_bug.cgi?id=10038 This was tested using a Malta 4Kc board in both little-endian and big-endian modes. The unit test program is available from the URL above. Signed-off-by: Dmitri Vorobiev [Ralf: Added N64, N32 and O32 bits on 64-bit kernels.] Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall32-o32.S | 3 +++ arch/mips/kernel/scall64-64.S | 3 +++ arch/mips/kernel/scall64-n32.S | 3 +++ arch/mips/kernel/scall64-o32.S | 3 +++ include/asm-mips/unistd.h | 21 +++++++++++++++------ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index f798139e888e..08a9c5070ea8 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -663,6 +663,9 @@ einval: li v0, -EINVAL sys sys_ni_syscall 0 sys sys_eventfd 1 sys sys_fallocate 6 /* 4320 */ + sys sys_timerfd_create 2 + sys sys_timerfd_gettime 2 + sys sys_timerfd_settime 4 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index a626be6baea3..dc597b600c68 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -478,4 +478,7 @@ sys_call_table: PTR sys_ni_syscall PTR sys_eventfd PTR sys_fallocate + PTR sys_timerfd_create /* 5280 */ + PTR sys_timerfd_gettime + PTR sys_timerfd_settime .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 9d5bcaf1b389..12940eca7893 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -404,4 +404,7 @@ EXPORT(sysn32_call_table) PTR sys_ni_syscall PTR sys_eventfd PTR sys_fallocate + PTR sys_timerfd_create + PTR sys_timerfd_gettime /* 5285 */ + PTR sys_timerfd_settime .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index fd2019c1ec2d..9a275efb4f04 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -526,4 +526,7 @@ sys_call_table: PTR sys_ni_syscall PTR sys_eventfd PTR sys32_fallocate /* 4320 */ + PTR sys_timerfd_create + PTR sys_timerfd_gettime + PTR sys_timerfd_settime .size sys_call_table,.-sys_call_table diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index fa9a587b3bf1..4964c82f85f9 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -341,16 +341,19 @@ #define __NR_timerfd (__NR_Linux + 318) #define __NR_eventfd (__NR_Linux + 319) #define __NR_fallocate (__NR_Linux + 320) +#define __NR_timerfd_create (__NR_Linux + 321) +#define __NR_timerfd_gettime (__NR_Linux + 322) +#define __NR_timerfd_settime (__NR_Linux + 323) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 320 +#define __NR_Linux_syscalls 323 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 320 +#define __NR_O32_Linux_syscalls 323 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -638,16 +641,19 @@ #define __NR_timerfd (__NR_Linux + 277) #define __NR_eventfd (__NR_Linux + 278) #define __NR_fallocate (__NR_Linux + 279) +#define __NR_timerfd_create (__NR_Linux + 280) +#define __NR_timerfd_gettime (__NR_Linux + 281) +#define __NR_timerfd_settime (__NR_Linux + 282) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 279 +#define __NR_Linux_syscalls 282 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 279 +#define __NR_64_Linux_syscalls 282 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -939,16 +945,19 @@ #define __NR_timerfd (__NR_Linux + 281) #define __NR_eventfd (__NR_Linux + 282) #define __NR_fallocate (__NR_Linux + 283) +#define __NR_timerfd_create (__NR_Linux + 284) +#define __NR_timerfd_gettime (__NR_Linux + 285) +#define __NR_timerfd_settime (__NR_Linux + 286) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 283 +#define __NR_Linux_syscalls 286 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 283 +#define __NR_N32_Linux_syscalls 286 #ifdef __KERNEL__ From dc9175be76084367974732cac55d7b097c79d474 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 17 Feb 2008 22:09:51 +0200 Subject: [PATCH 406/880] [MIPS] Qemu: finish platform removal Two files were omitted from the recent removal of the qemu platform. Signed-off-by: Adrian Bunk Signed-off-by: Ralf Baechle --- arch/mips/configs/qemu_defconfig | 800 ------------------------------- include/asm-mips/qemu.h | 30 -- 2 files changed, 830 deletions(-) delete mode 100644 arch/mips/configs/qemu_defconfig delete mode 100644 include/asm-mips/qemu.h diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig deleted file mode 100644 index 72ca147f9422..000000000000 --- a/arch/mips/configs/qemu_defconfig +++ /dev/null @@ -1,800 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# Tue Feb 20 21:47:39 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MIPS_MTX1 is not set -# CONFIG_MIPS_BOSPORUS is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_MIPS_PB1550 is not set -# CONFIG_MIPS_PB1200 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_DB1550 is not set -# CONFIG_MIPS_DB1200 is not set -# CONFIG_MIPS_MIRAGE is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_WR_PPMC is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MOMENCO_JAGUAR_ATX is not set -# CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_MARKEINS is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_DMA_COHERENT=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_I8259=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_HAVE_STD_PC_SERIAL_PORT=y - -# -# CPU selection -# -CONFIG_CPU_MIPS32_R1=y -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_CPU_MIPS32=y -CONFIG_CPU_MIPSR1=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_SPARSEMEM_STATIC=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_HZ_48 is not set -CONFIG_HZ_100=y -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=100 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -# CONFIG_EXPERIMENTAL is not set -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -# CONFIG_SYSVIPC 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_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -# CONFIG_BUG is not set -CONFIG_ELF_CORE=y -# CONFIG_BASE_FULL is not set -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -# CONFIG_SHMEM is not set -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_ISA=y -CONFIG_MMU=y -CONFIG_PCSPEAKER=y - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_SYN_COOKIES is not set -# 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_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_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y -# CONFIG_NETFILTER 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 - -# -# QoS and/or fair queueing -# -# 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_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNP is not set -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# 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_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# 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_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_DM9000 is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -CONFIG_NET_ISA=y -# CONFIG_E2100 is not set -# CONFIG_EWRK3 is not set -# CONFIG_EEXPRESS is not set -# CONFIG_EEXPRESS_PRO is not set -# CONFIG_HPLAN_PLUS is not set -# CONFIG_HPLAN is not set -# CONFIG_LP486E is not set -# CONFIG_ETH16I is not set -CONFIG_NE2000=y -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP 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 - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# 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 -# - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_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=y -CONFIG_GENERIC_ACL=y - -# -# 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_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_HFSPLUS_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 - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_DIRECTIO=y -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# 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_CROSSCOMPILE=y -CONFIG_CMDLINE="" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/include/asm-mips/qemu.h b/include/asm-mips/qemu.h deleted file mode 100644 index 487ced4a40de..000000000000 --- a/include/asm-mips/qemu.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef __ASM_QEMU_H -#define __ASM_QEMU_H - -/* - * Interrupt numbers - */ -#define Q_PIC_IRQ_BASE 0 -#define Q_COUNT_COMPARE_IRQ 23 - -/* - * Qemu clock rate. Unlike on real MIPS this has no relation to the - * instruction issue rate, so the choosen value is pure fiction, just needs - * to match the value in Qemu itself. - */ -#define QEMU_C0_COUNTER_CLOCK 100000000 - -/* - * Magic qemu system control location. - */ -#define QEMU_RESTART_REG 0xBFBF0000 -#define QEMU_HALT_REG 0xBFBF0004 - -#endif /* __ASM_QEMU_H */ From 986c94854e5615000f39edfc788dffff7035ec7d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 19 Feb 2008 15:59:33 +0000 Subject: [PATCH 407/880] [MIPS] PCI: Port i386 PCI fixes. The MIPS version of pcibios_enalbe_resources did not have the fixes from ed6d14f9760857c745206c978b80352fc09cfd19 yet which under circumstances similar to x86 might result in failures. Signed-off-by: Ralf Baechle --- arch/mips/pci/pci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 6e6981fd7934..1d10d6544152 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -177,6 +177,11 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) continue; r = &dev->resource[idx]; + if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); return -EINVAL; @@ -186,8 +191,6 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) if (r->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); From 40d7c1aa6153605b3eae23990d4c2d4e8f807cb0 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 19 Feb 2008 16:01:20 +0000 Subject: [PATCH 408/880] [MIPS] PCI: Coding style fixes for pcibios_enable_resources. Signed-off-by: Ralf Baechle --- arch/mips/pci/pci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 1d10d6544152..f9471d77c096 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -183,7 +183,9 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) (!(r->flags & IORESOURCE_ROM_ENABLE))) continue; if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); + printk(KERN_ERR "PCI: Device %s not available " + "because of resource collisions\n", + pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -192,7 +194,8 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) cmd |= PCI_COMMAND_MEMORY; } if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } return 0; From b991b590dc2e54447644d34226dc355b7b6e2337 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 17 Feb 2008 23:59:48 +0200 Subject: [PATCH 409/880] [MIPS] RM: fix EISA=n compilation This patch fixes the following build error with CONFIG_EISA=n caused by commit 231a35d37293ab88d325a9cb94e5474c156282c0: <-- snip --> ... LD .tmp_vmlinux1 arch/mips/sni/built-in.o: In function `snirm_a20r_setup_devinit': a20r.c:(.init.text+0x42c): undefined reference to `sni_eisa_root_init' a20r.c:(.init.text+0x42c): relocation truncated to fit: R_MIPS_26 against `sni_eisa_root_init' arch/mips/sni/built-in.o: In function `snirm_setup_devinit': rm200.c:(.init.text+0x52c): undefined reference to `sni_eisa_root_init' rm200.c:(.init.text+0x52c): relocation truncated to fit: R_MIPS_26 against `sni_eisa_root_init' make[1]: *** [.tmp_vmlinux1] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Acked-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- include/asm-mips/sni.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h index e716447e5e03..8c1eb02c6d16 100644 --- a/include/asm-mips/sni.h +++ b/include/asm-mips/sni.h @@ -228,7 +228,14 @@ extern void sni_pcimt_irq_init(void); extern void sni_cpu_time_init(void); /* eisa init for RM200/400 */ +#ifdef CONFIG_EISA extern int sni_eisa_root_init(void); +#else +static inline int sni_eisa_root_init(void) +{ + return 0; +} +#endif /* common irq stuff */ extern void (*sni_hwint)(void); From e8248d6fe7092439b08588102ad668b7cf27ec05 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Mon, 18 Feb 2008 12:23:27 +0100 Subject: [PATCH 410/880] [MIPS] BCM47xx: Add defconfig file. Signed-off-by: Aurelien Jarno Signed-off-by: Ralf Baechle --- arch/mips/configs/bcm47xx_defconfig | 1939 +++++++++++++++++++++++++++ 1 file changed, 1939 insertions(+) create mode 100644 arch/mips/configs/bcm47xx_defconfig diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig new file mode 100644 index 000000000000..c0e42e74dfbd --- /dev/null +++ b/arch/mips/configs/bcm47xx_defconfig @@ -0,0 +1,1939 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.25-rc2 +# Mon Feb 18 11:55:24 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +CONFIG_BCM47XX=y +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_WR_PPMC is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K=y +CONFIG_CFE=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_GPIO=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +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=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y +CONFIG_KEXEC=y +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=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 is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_AUDIT=y +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_CGROUP_CPUACCT=y +# CONFIG_RESOURCE_COUNTERS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=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_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_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_KPROBES is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +CONFIG_LBD=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_LSF=y +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +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_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_TRAD_SIGNALS=y + +# +# Power management options +# +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_DEFAULT_BIC=y +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="bic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +CONFIG_TIPC_ADVANCED=y +CONFIG_TIPC_ZONES=3 +CONFIG_TIPC_CLUSTERS=1 +CONFIG_TIPC_NODES=255 +CONFIG_TIPC_SLAVE_NODES=0 +CONFIG_TIPC_PORTS=8191 +CONFIG_TIPC_LOG=0 +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set +CONFIG_LLC=m +# 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=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RR=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# 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=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_TOSHIBA_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +# CONFIG_BT_L2CAP is not set +# CONFIG_BT_SCO is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y + +# +# Wireless +# +CONFIG_CFG80211=m +CONFIG_NL80211=y +CONFIG_WIRELESS_EXT=y +CONFIG_MAC80211=m + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set +# CONFIG_MAC80211_RC_DEFAULT_NONE is not set + +# +# Selecting 'y' for an algorithm will +# + +# +# build the algorithm into mac80211. +# +CONFIG_MAC80211_RC_DEFAULT="pid" +CONFIG_MAC80211_RC_PID=y +# CONFIG_MAC80211_RC_SIMPLE is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set +# CONFIG_MAC80211_DEBUG is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_NET_9P=m +CONFIG_NET_9P_FD=m +# CONFIG_NET_9P_DEBUG 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=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +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=y +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=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# 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=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=y +CONFIG_MTD_ABSENT=y + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 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_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_SX8 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=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=m +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_IFB is not set +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_VETH=m +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_ICPLUS_PHY=m +# CONFIG_REALTEK_PHY is not set +# CONFIG_FIXED_PHY is not set +CONFIG_MDIO_BITBANG=m +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 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_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_B44=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +# CONFIG_FORCEDETH is not set +# CONFIG_TC35815 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_LIBERTAS is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_RTL8180 is not set +# CONFIG_RTL8187 is not set +# CONFIG_ADM8211 is not set +# CONFIG_P54_COMMON is not set +CONFIG_ATH5K=m +# CONFIG_IWL4965 is not set +# CONFIG_IWL3945 is not set +# CONFIG_HOSTAP is not set +# CONFIG_BCM43XX is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_RT2X00 is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +# CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +# CONFIG_ATM_ENI is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_ATM_NICSTAR is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_FORE200E_MAYBE is not set +# CONFIG_ATM_HE is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_PPPOL2TP is not set +CONFIG_SLIP=m +# CONFIG_SLIP_COMPRESSED is not set +CONFIG_SLHC=m +# CONFIG_SLIP_SMART is not set +# CONFIG_SLIP_MODE_SLIP6 is not set +# CONFIG_NET_FC is not set +CONFIG_NETCONSOLE=y +# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +# CONFIG_W1_MASTER_GPIO is not set + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_SERIAL=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_PCICORE_HOSTMODE=y +CONFIG_SSB_DRIVER_MIPS=y +CONFIG_SSB_DRIVER_EXTIF=y + +# +# 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=y +CONFIG_USB_DABUSB=m + +# +# Graphics support +# +# CONFIG_DRM is not set +# 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=m + +# +# Display hardware drivers +# + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# 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=m +CONFIG_SND_VIRMIDI=m +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# ALSA MIPS devices +# + +# +# USB devices +# +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# SoC Audio support for SuperH +# + +# +# ALSA SoC audio for Freescale SOCs +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + +# +# 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_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +CONFIG_USB_U132_HCD=m +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_R8A66597_HCD=m + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MON is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_TI is not set +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +CONFIG_USB_ADUTUX=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS 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=y +CONFIG_USB_NET2280=m +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X 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=y +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m +# CONFIG_USB_G_PRINTER is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_GPIO=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_INFINIBAND is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_NOLOCK=m +CONFIG_GFS2_FS_LOCKING_DLM=m +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_GENERIC_ACL=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +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=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +# 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=m +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_BIND34=y +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +# CONFIG_SMB_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set +# CONFIG_AFS_FS is not set +CONFIG_9P_FS=m + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +CONFIG_KARMA_PARTITION=y +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +CONFIG_DLM_DEBUG=y + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# 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_SAMPLES is not set +CONFIG_CMDLINE="" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=m +# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_XTS=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_SEED=m +# CONFIG_CRYPTO_SALSA20 is not set +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_AUTHENC=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y From 0788150e639623f44c5991dcd290f8cdcf7db43f Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Thu, 7 Feb 2008 03:17:16 +0100 Subject: [PATCH 411/880] [MIPS] WGT634U: Register MTD as platform device. Signed-off-by: Aurelien Jarno Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/wgt634u.c | 69 +++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c index 5a017eaee712..997e54001717 100644 --- a/arch/mips/bcm47xx/wgt634u.c +++ b/arch/mips/bcm47xx/wgt634u.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,61 @@ static struct platform_device wgt634u_gpio_leds = { } }; + +/* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U + firmware. */ +static struct mtd_partition wgt634u_partitions[] = { + { + .name = "cfe", + .offset = 0, + .size = 0x60000, /* 384k */ + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "config", + .offset = 0x60000, + .size = 0x20000 /* 128k */ + }, + { + .name = "linux", + .offset = 0x80000, + .size = 0x140000 /* 1280k */ + }, + { + .name = "jffs", + .offset = 0x1c0000, + .size = 0x620000 /* 6272k */ + }, + { + .name = "nvram", + .offset = 0x7e0000, + .size = 0x20000 /* 128k */ + }, +}; + +static struct physmap_flash_data wgt634u_flash_data = { + .parts = wgt634u_partitions, + .nr_parts = ARRAY_SIZE(wgt634u_partitions) +}; + +static struct resource wgt634u_flash_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device wgt634u_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { .platform_data = &wgt634u_flash_data, }, + .resource = &wgt634u_flash_resource, + .num_resources = 1, +}; + +/* Platform devices */ +static struct platform_device *wgt634u_devices[] __initdata = { + &wgt634u_flash, + &wgt634u_gpio_leds, +}; + static int __init wgt634u_init(void) { /* There is no easy way to detect that we are running on a WGT634U @@ -54,9 +110,16 @@ static int __init wgt634u_init(void) if (et0mac[0] == 0x00 && ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) || - (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) - return platform_device_register(&wgt634u_gpio_leds); - else + (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) { + struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; + wgt634u_flash_data.width = mcore->flash_buswidth; + wgt634u_flash_resource.start = mcore->flash_window; + wgt634u_flash_resource.end = mcore->flash_window + + mcore->flash_window_size + - 1; + return platform_add_devices(wgt634u_devices, + ARRAY_SIZE(wgt634u_devices)); + } else return -ENODEV; } From cc2d6f701bed8b5f120314e4df854827d8bac558 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Mon, 18 Feb 2008 11:04:31 +0100 Subject: [PATCH 412/880] [MIPS] BCM47XX: Use new SSB SPROM data structure Switch the BCM47XX code to the new SPROM data structure now that the old one has been removed. Signed-off-by: Aurelien Jarno Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/setup.c | 12 ++++++------ arch/mips/bcm47xx/wgt634u.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 1b6b0fa5028f..8d36f186890e 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -92,17 +92,17 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, iv->sprom.revision = 3; if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0) - str2eaddr(buf, iv->sprom.r1.et0mac); + str2eaddr(buf, iv->sprom.et0mac); if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0) - str2eaddr(buf, iv->sprom.r1.et1mac); + str2eaddr(buf, iv->sprom.et1mac); if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) - iv->sprom.r1.et0phyaddr = simple_strtoul(buf, NULL, 10); + iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10); if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) - iv->sprom.r1.et1phyaddr = simple_strtoul(buf, NULL, 10); + iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10); if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0) - iv->sprom.r1.et0mdcport = simple_strtoul(buf, NULL, 10); + iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10); if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0) - iv->sprom.r1.et1mdcport = simple_strtoul(buf, NULL, 10); + iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10); return 0; } diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c index 997e54001717..d1d90c9ef2fa 100644 --- a/arch/mips/bcm47xx/wgt634u.c +++ b/arch/mips/bcm47xx/wgt634u.c @@ -106,7 +106,7 @@ static int __init wgt634u_init(void) * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx. */ - u8 *et0mac = ssb_bcm47xx.sprom.r1.et0mac; + u8 *et0mac = ssb_bcm47xx.sprom.et0mac; if (et0mac[0] == 0x00 && ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) || From 00e962c5408b9f2d0bebd2308673fe982cb9a5fe Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 19 Feb 2008 09:08:49 -0800 Subject: [PATCH 413/880] Revert "SLUB: Alternate fast paths using cmpxchg_local" This reverts commit 1f84260c8ce3b1ce26d4c1d6dedc2f33a3a29c0c, which is suspected to be the reason for some very occasional and hard-to-trigger crashes that usually look related to memory allocation (mostly reported in networking, but since that's generally the most common source of shortlived allocations - and allocations in interrupt contexts - that in itself is not a big clue). See for example http://bugzilla.kernel.org/show_bug.cgi?id=9973 http://lkml.org/lkml/2008/2/19/278 etc. One promising suspicion for what the root cause of bug is (which also explains why it's so hard to trigger in practice) came from Eric Dumazet: "I wonder how SLUB_FASTPATH is supposed to work, since it is affected by a classical ABA problem of lockless algo. cmpxchg_local(&c->freelist, object, object[c->offset]) can succeed, while an interrupt came (on this cpu), and several allocations were done, and one free was performed at the end of this interruption, so 'object' was recycled. c->freelist can then contain the previous value (object), but object[c->offset] was changed by IRQ. We then put back in freelist an already allocated object." but another reason for the revert is simply that everybody agrees that this code was the main suspect just by virtue of the pattern of oopses. Cc: Torsten Kaiser Cc: Christoph Lameter Cc: Mathieu Desnoyers Cc: Pekka Enberg Cc: Ingo Molnar Cc: Eric Dumazet Signed-off-by: Linus Torvalds --- mm/slub.c | 87 +------------------------------------------------------ 1 file changed, 1 insertion(+), 86 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 4b3895cb90ee..74c65af0a54f 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -149,13 +149,6 @@ static inline void ClearSlabDebug(struct page *page) /* Enable to test recovery from slab corruption on boot */ #undef SLUB_RESILIENCY_TEST -/* - * Currently fastpath is not supported if preemption is enabled. - */ -#if defined(CONFIG_FAST_CMPXCHG_LOCAL) && !defined(CONFIG_PREEMPT) -#define SLUB_FASTPATH -#endif - #if PAGE_SHIFT <= 12 /* @@ -1514,11 +1507,7 @@ static void *__slab_alloc(struct kmem_cache *s, { void **object; struct page *new; -#ifdef SLUB_FASTPATH - unsigned long flags; - local_irq_save(flags); -#endif if (!c->page) goto new_slab; @@ -1541,9 +1530,6 @@ static void *__slab_alloc(struct kmem_cache *s, unlock_out: slab_unlock(c->page); stat(c, ALLOC_SLOWPATH); -#ifdef SLUB_FASTPATH - local_irq_restore(flags); -#endif return object; another_slab: @@ -1575,9 +1561,7 @@ static void *__slab_alloc(struct kmem_cache *s, c->page = new; goto load_freelist; } -#ifdef SLUB_FASTPATH - local_irq_restore(flags); -#endif + /* * No memory available. * @@ -1619,34 +1603,6 @@ static __always_inline void *slab_alloc(struct kmem_cache *s, { void **object; struct kmem_cache_cpu *c; - -/* - * The SLUB_FASTPATH path is provisional and is currently disabled if the - * kernel is compiled with preemption or if the arch does not support - * fast cmpxchg operations. There are a couple of coming changes that will - * simplify matters and allow preemption. Ultimately we may end up making - * SLUB_FASTPATH the default. - * - * 1. The introduction of the per cpu allocator will avoid array lookups - * through get_cpu_slab(). A special register can be used instead. - * - * 2. The introduction of per cpu atomic operations (cpu_ops) means that - * we can realize the logic here entirely with per cpu atomics. The - * per cpu atomic ops will take care of the preemption issues. - */ - -#ifdef SLUB_FASTPATH - c = get_cpu_slab(s, raw_smp_processor_id()); - do { - object = c->freelist; - if (unlikely(is_end(object) || !node_match(c, node))) { - object = __slab_alloc(s, gfpflags, node, addr, c); - break; - } - stat(c, ALLOC_FASTPATH); - } while (cmpxchg_local(&c->freelist, object, object[c->offset]) - != object); -#else unsigned long flags; local_irq_save(flags); @@ -1661,7 +1617,6 @@ static __always_inline void *slab_alloc(struct kmem_cache *s, stat(c, ALLOC_FASTPATH); } local_irq_restore(flags); -#endif if (unlikely((gfpflags & __GFP_ZERO) && object)) memset(object, 0, c->objsize); @@ -1698,11 +1653,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page, void **object = (void *)x; struct kmem_cache_cpu *c; -#ifdef SLUB_FASTPATH - unsigned long flags; - - local_irq_save(flags); -#endif c = get_cpu_slab(s, raw_smp_processor_id()); stat(c, FREE_SLOWPATH); slab_lock(page); @@ -1734,9 +1684,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page, out_unlock: slab_unlock(page); -#ifdef SLUB_FASTPATH - local_irq_restore(flags); -#endif return; slab_empty: @@ -1749,9 +1696,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page, } slab_unlock(page); stat(c, FREE_SLAB); -#ifdef SLUB_FASTPATH - local_irq_restore(flags); -#endif discard_slab(s, page); return; @@ -1777,34 +1721,6 @@ static __always_inline void slab_free(struct kmem_cache *s, { void **object = (void *)x; struct kmem_cache_cpu *c; - -#ifdef SLUB_FASTPATH - void **freelist; - - c = get_cpu_slab(s, raw_smp_processor_id()); - debug_check_no_locks_freed(object, s->objsize); - do { - freelist = c->freelist; - barrier(); - /* - * If the compiler would reorder the retrieval of c->page to - * come before c->freelist then an interrupt could - * change the cpu slab before we retrieve c->freelist. We - * could be matching on a page no longer active and put the - * object onto the freelist of the wrong slab. - * - * On the other hand: If we already have the freelist pointer - * then any change of cpu_slab will cause the cmpxchg to fail - * since the freelist pointers are unique per slab. - */ - if (unlikely(page != c->page || c->node < 0)) { - __slab_free(s, page, x, addr, c->offset); - break; - } - object[c->offset] = freelist; - stat(c, FREE_FASTPATH); - } while (cmpxchg_local(&c->freelist, freelist, object) != freelist); -#else unsigned long flags; local_irq_save(flags); @@ -1818,7 +1734,6 @@ static __always_inline void slab_free(struct kmem_cache *s, __slab_free(s, page, x, addr, c->offset); local_irq_restore(flags); -#endif } void kmem_cache_free(struct kmem_cache *s, void *x) From ec229e5e81b3cf757e5e8b6a8bd0b4f32fe52f8c Mon Sep 17 00:00:00 2001 From: Pradeep Satyanarayana Date: Tue, 12 Feb 2008 15:00:59 -0800 Subject: [PATCH 414/880] IPoIB/cm: Fix ipoib_cm_dev_stop() cleanup when drain times out Commit efcd9971 ("IPoIB/cm: Factor out ipoib_cm_free_rx_reap_list()") introduced a bug in ipoib_cm_dev_stop() when the receive drain times out. In that case, the function moves all the pending rx stuff into a private list but then calls ipoib_cm_free_rx_reap_list(), which handles a different list. Fix this by moving everything to the rx_reap_list that will actually get freed up. This fixes . Signed-off-by: Pradeep Satyanarayana Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 7dd2ec473d24..52b1bebfa744 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -824,7 +824,6 @@ void ipoib_cm_dev_stop(struct net_device *dev) struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_cm_rx *p; unsigned long begin; - LIST_HEAD(list); int ret; if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id) @@ -857,9 +856,12 @@ void ipoib_cm_dev_stop(struct net_device *dev) /* * assume the HW is wedged and just free up everything. */ - list_splice_init(&priv->cm.rx_flush_list, &list); - list_splice_init(&priv->cm.rx_error_list, &list); - list_splice_init(&priv->cm.rx_drain_list, &list); + list_splice_init(&priv->cm.rx_flush_list, + &priv->cm.rx_reap_list); + list_splice_init(&priv->cm.rx_error_list, + &priv->cm.rx_reap_list); + list_splice_init(&priv->cm.rx_drain_list, + &priv->cm.rx_reap_list); break; } spin_unlock_irq(&priv->lock); From b7f9c112a5e7f68d77a31c79f5942a3272ae9a3b Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 19 Feb 2008 10:42:50 -0800 Subject: [PATCH 415/880] IB/mthca: Free correct MPT on error exit from mthca_fmr_alloc() When mthca_fmr_alloc() returns an error, it should free the MPT at the index key, not mr->ibmr.lkey, since the lkey has been mangled by hw_index_to_key() and no longer is the real index. This bug causes corruption of the MPT table free bitmap when mthca_fmr_alloc() fails. Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index 3b6985557cb2..3538da16e3fe 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c @@ -686,7 +686,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd, mthca_table_put(dev, dev->mr_table.mpt_table, key); err_out_mpt_free: - mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey); + mthca_free(&dev->mr_table.mpt_alloc, key); return err; } From 2e2705bdcb959372d54bf7f79dd9a555ec2adfb4 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 16 Feb 2008 16:37:28 +0100 Subject: [PATCH 416/880] firewire: fw-sbp2: (try to) avoid I/O errors during reconnect While fw-sbp2 takes the necessary time to reconnect to a logical unit after bus reset, the SCSI core keeps sending new commands. They are all immediately completed with host busy status, and application clients or filesystems will break quickly. The SCSI device might even be taken offline: http://bugzilla.kernel.org/show_bug.cgi?id=9734 The only remedy seems to be to block the SCSI device until reconnect. Alas the SCSI core has no useful API to block only one logical unit i.e. the scsi_device, therefore we block the entire Scsi_Host. This currently corresponds to an SBP-2 target. In case of targets with multiple logical units, we need to satisfy the dependencies between logical units by carefully tracking the blocking state of the target and its units. We block all logical units of a target as soon as one of them needs to be blocked, and keep them blocked until all of them are ready to be unblocked. Furthermore, as the history of the old sbp2 driver has shown, the scsi_block_requests() API is a minefield with high potential of deadlocks. We therefore take extra measures to keep logical units unblocked during __scsi_add_device() and during shutdown. This avoids I/O errors during reconnect in many but alas not in all cases. There may still be errors after a re-login had to be performed. Also, some bridges have been seen to cease fetching management ORBs if I/O went on up until a bus reset. In these cases, all management ORBs time out after mgt_orb_timeout. The old sbp2 driver is less vulnerable or maybe not vulnerable to this, for as yet unknown reasons. Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 126 +++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 6d10934c58f1..ea4811c45512 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -139,6 +139,7 @@ struct sbp2_logical_unit { int generation; int retries; struct delayed_work work; + bool blocked; }; /* @@ -157,6 +158,9 @@ struct sbp2_target { int address_high; unsigned int workarounds; unsigned int mgt_orb_timeout; + + int dont_block; /* counter for each logical unit */ + int blocked; /* ditto */ }; /* @@ -646,6 +650,107 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) &z, sizeof(z), complete_agent_reset_write_no_wait, t); } +static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation) +{ + struct fw_card *card = fw_device(lu->tgt->unit->device.parent)->card; + unsigned long flags; + + /* serialize with comparisons of lu->generation and card->generation */ + spin_lock_irqsave(&card->lock, flags); + lu->generation = generation; + spin_unlock_irqrestore(&card->lock, flags); +} + +static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) +{ + /* + * We may access dont_block without taking card->lock here: + * All callers of sbp2_allow_block() and all callers of sbp2_unblock() + * are currently serialized against each other. + * And a wrong result in sbp2_conditionally_block()'s access of + * dont_block is rather harmless, it simply misses its first chance. + */ + --lu->tgt->dont_block; +} + +/* + * Blocks lu->tgt if all of the following conditions are met: + * - Login, INQUIRY, and high-level SCSI setup of all of the target's + * logical units have been finished (indicated by dont_block == 0). + * - lu->generation is stale. + * + * Note, scsi_block_requests() must be called while holding card->lock, + * otherwise it might foil sbp2_[conditionally_]unblock()'s attempt to + * unblock the target. + */ +static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) +{ + struct sbp2_target *tgt = lu->tgt; + struct fw_card *card = fw_device(tgt->unit->device.parent)->card; + struct Scsi_Host *shost = + container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + unsigned long flags; + + spin_lock_irqsave(&card->lock, flags); + if (!tgt->dont_block && !lu->blocked && + lu->generation != card->generation) { + lu->blocked = true; + if (++tgt->blocked == 1) { + scsi_block_requests(shost); + fw_notify("blocked %s\n", lu->tgt->bus_id); + } + } + spin_unlock_irqrestore(&card->lock, flags); +} + +/* + * Unblocks lu->tgt as soon as all its logical units can be unblocked. + * Note, it is harmless to run scsi_unblock_requests() outside the + * card->lock protected section. On the other hand, running it inside + * the section might clash with shost->host_lock. + */ +static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) +{ + struct sbp2_target *tgt = lu->tgt; + struct fw_card *card = fw_device(tgt->unit->device.parent)->card; + struct Scsi_Host *shost = + container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + unsigned long flags; + bool unblock = false; + + spin_lock_irqsave(&card->lock, flags); + if (lu->blocked && lu->generation == card->generation) { + lu->blocked = false; + unblock = --tgt->blocked == 0; + } + spin_unlock_irqrestore(&card->lock, flags); + + if (unblock) { + scsi_unblock_requests(shost); + fw_notify("unblocked %s\n", lu->tgt->bus_id); + } +} + +/* + * Prevents future blocking of tgt and unblocks it. + * Note, it is harmless to run scsi_unblock_requests() outside the + * card->lock protected section. On the other hand, running it inside + * the section might clash with shost->host_lock. + */ +static void sbp2_unblock(struct sbp2_target *tgt) +{ + struct fw_card *card = fw_device(tgt->unit->device.parent)->card; + struct Scsi_Host *shost = + container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + unsigned long flags; + + spin_lock_irqsave(&card->lock, flags); + ++tgt->dont_block; + spin_unlock_irqrestore(&card->lock, flags); + + scsi_unblock_requests(shost); +} + static void sbp2_release_target(struct kref *kref) { struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref); @@ -653,6 +758,9 @@ static void sbp2_release_target(struct kref *kref) struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + /* prevent deadlocks */ + sbp2_unblock(tgt); + list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { if (lu->sdev) scsi_remove_device(lu->sdev); @@ -717,17 +825,20 @@ static void sbp2_login(struct work_struct *work) if (sbp2_send_management_orb(lu, node_id, generation, SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) { - if (lu->retries++ < 5) + if (lu->retries++ < 5) { sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); - else + } else { fw_error("%s: failed to login to LUN %04x\n", tgt->bus_id, lu->lun); + /* Let any waiting I/O fail from now on. */ + sbp2_unblock(lu->tgt); + } goto out; } - lu->generation = generation; tgt->node_id = node_id; tgt->address_high = local_node_id << 16; + sbp2_set_generation(lu, generation); /* Get command block agent offset and login id. */ lu->command_block_agent_address = @@ -749,6 +860,7 @@ static void sbp2_login(struct work_struct *work) /* This was a re-login. */ if (lu->sdev) { sbp2_cancel_orbs(lu); + sbp2_conditionally_unblock(lu); goto out; } @@ -785,6 +897,7 @@ static void sbp2_login(struct work_struct *work) /* No error during __scsi_add_device() */ lu->sdev = sdev; + sbp2_allow_block(lu); goto out; out_logout_login: @@ -825,6 +938,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) lu->sdev = NULL; lu->lun = lun_entry & 0xffff; lu->retries = 0; + lu->blocked = false; + ++tgt->dont_block; INIT_LIST_HEAD(&lu->orb_list); INIT_DELAYED_WORK(&lu->work, sbp2_login); @@ -1041,15 +1156,16 @@ static void sbp2_reconnect(struct work_struct *work) goto out; } - lu->generation = generation; tgt->node_id = node_id; tgt->address_high = local_node_id << 16; + sbp2_set_generation(lu, generation); fw_notify("%s: reconnected to LUN %04x (%d retries)\n", tgt->bus_id, lu->lun, lu->retries); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); + sbp2_conditionally_unblock(lu); out: sbp2_target_put(tgt); } @@ -1066,6 +1182,7 @@ static void sbp2_update(struct fw_unit *unit) * Iteration over tgt->lu_list is therefore safe here. */ list_for_each_entry(lu, &tgt->lu_list, link) { + sbp2_conditionally_block(lu); lu->retries = 0; sbp2_queue_work(lu, 0); } @@ -1169,6 +1286,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) * or when sending the write (less likely). */ result = DID_BUS_BUSY << 16; + sbp2_conditionally_block(orb->lu); } dma_unmap_single(device->card->device, orb->base.request_bus, From 5513c5f6f9bd8c8ad3727130910fa288c62526a7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Feb 2008 14:56:19 +0100 Subject: [PATCH 417/880] firewire: fw-sbp2: fix NULL pointer deref. in slave_alloc Fix a kernel bug when running rescan-scsi-bus while a FireWire disk is connected: http://bugzilla.kernel.org/show_bug.cgi?id=10008 Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index ea4811c45512..60ebcb5fe21a 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -1473,6 +1473,10 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev) { struct sbp2_logical_unit *lu = sdev->hostdata; + /* (Re-)Adding logical units via the SCSI stack is not supported. */ + if (!lu) + return -ENOSYS; + sdev->allow_restart = 1; /* From 33f1c6c3529f5f279e2e98e5cca0c5bac152153b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 19 Feb 2008 09:05:49 +0100 Subject: [PATCH 418/880] firewire: fw-sbp2: fix NULL pointer deref. in scsi_remove_device Fix a kernel bug when unplugging an SBP-2 device after having its scsi_device already removed via the "delete" sysfs attribute. Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 60ebcb5fe21a..5259491580fc 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -762,9 +762,10 @@ static void sbp2_release_target(struct kref *kref) sbp2_unblock(tgt); list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { - if (lu->sdev) + if (lu->sdev) { scsi_remove_device(lu->sdev); - + scsi_device_put(lu->sdev); + } sbp2_send_management_orb(lu, tgt->node_id, lu->generation, SBP2_LOGOUT_REQUEST, lu->login_id, NULL); @@ -886,12 +887,11 @@ static void sbp2_login(struct work_struct *work) if (IS_ERR(sdev)) goto out_logout_login; - scsi_device_put(sdev); - /* Unreported error during __scsi_add_device() */ smp_rmb(); /* get current card generation */ if (generation != device->card->generation) { scsi_remove_device(sdev); + scsi_device_put(sdev); goto out_logout_login; } From ef774c16a744f130f27c654bf9c4806e767fc773 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 17 Feb 2008 14:57:10 +0100 Subject: [PATCH 419/880] ieee1394: sbp2: fix rescan-scsi-bus rescan-scsi-bus used to add SBP-2 targets which weren't there. Signed-off-by: Stefan Richter --- drivers/ieee1394/sbp2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index accb2ad8b561..9e2b1964d71a 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -1974,6 +1974,9 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev) { struct sbp2_lu *lu = (struct sbp2_lu *)sdev->host->hostdata[0]; + if (sdev->lun != 0 || sdev->id != lu->ud->id || sdev->channel != 0) + return -ENODEV; + lu->sdev = sdev; sdev->allow_restart = 1; From 09d7328e62e3b4cefe4bf3eeeeacb54f62a7ae5c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 18 Feb 2008 21:38:35 +0100 Subject: [PATCH 420/880] Documentation: correction to debugging-via-ohci1394 Rectify a factoid about firewire-ohci. Acked-by: Ingo Molnar Also fix a typo spotted by Bernhard Kaindl. Signed-off-by: Stefan Richter --- Documentation/debugging-via-ohci1394.txt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt index de4804e8b396..c360d4e91b48 100644 --- a/Documentation/debugging-via-ohci1394.txt +++ b/Documentation/debugging-via-ohci1394.txt @@ -36,14 +36,15 @@ available (notebooks) or too slow for extensive debug information (like ACPI). Drivers ------- -The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize -the OHCI-1394 controllers to a working state and can be used to enable -physical DMA. By default you only have to load the driver, and physical -DMA access will be granted to all remote nodes, but it can be turned off -when using the ohci1394 driver. - -Because these drivers depend on the PCI enumeration to be completed, an -initialization routine which can runs pretty early (long before console_init(), +The ohci1394 driver in drivers/ieee1394 initializes the OHCI-1394 controllers +to a working state and enables physical DMA by default for all remote nodes. +This can be turned off by ohci1394's module parameter phys_dma=0. + +The alternative firewire-ohci driver in drivers/firewire uses filtered physical +DMA, hence is not yet suitable for remote debugging. + +Because ohci1394 depends on the PCI enumeration to be completed, an +initialization routine which runs pretty early (long before console_init() which makes the printk buffer appear on the console can be called) was written. To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu: From b1d2675a6466090b68d4ef63f9237b4d70a18857 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 Feb 2008 14:12:10 +0100 Subject: [PATCH 421/880] kbuild: fix reversed symbol name order in modpost XXXINIT_TO_INIT and XXXEXIT_TO_EXIT warnings use the reversed symbol name order in the suggestion, e.g.: WARNING: vmlinux.o(.meminit.text+0x36c): Section mismatch in reference from the function free_area_init_core() to the function .init.text:setup_usemap() The function __meminit free_area_init_core() references a function __init setup_usemap(). If free_area_init_core is only used by setup_usemap then annotate free_area_init_core with a matching annotation. Signed-off-by: Geert Uytterhoeven Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 61742771c65d..695b5d657cf5 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1200,7 +1200,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, "annotate %s with a matching annotation.\n", from, sec2annotation(fromsec), fromsym, from_p, to, sec2annotation(tosec), tosym, to_p, - fromsym, tosym, fromsym); + tosym, fromsym, tosym); break; case INIT_TO_EXIT: fprintf(stderr, From 37c514e3dfc8f55145d9c6895e2838ac31859aa4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 19 Feb 2008 21:00:18 +0100 Subject: [PATCH 422/880] Add missing init section definitions When adding __devinitconst etc. the __initconst variant were missed. Add this one and proper definitions for .head.text for use in .S files. The naming .head.text is preferred over .text.head as the latter will conflict for a function named head when introducing -ffunctions-sections. Signed-off-by: Sam Ravnborg --- include/asm-generic/vmlinux.lds.h | 3 +++ include/linux/init.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index f784d2f34149..f054778e916c 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -238,6 +238,9 @@ *(.kprobes.text) \ VMLINUX_SYMBOL(__kprobes_text_end) = .; +/* Section used for early init (in .S files) */ +#define HEAD_TEXT *(.head.text) + /* init and exit section handling */ #define INIT_DATA \ *(.init.data) \ diff --git a/include/linux/init.h b/include/linux/init.h index a404a0055dd7..fb58c0493cf2 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -42,6 +42,7 @@ discard it in modules) */ #define __init __section(.init.text) __cold #define __initdata __section(.init.data) +#define __initconst __section(.init.rodata) #define __exitdata __section(.exit.data) #define __exit_call __used __section(.exitcall.exit) @@ -106,6 +107,7 @@ #define __memexitconst __section(.memexit.rodata) /* For assembly routines */ +#define __HEAD .section ".head.text","ax" #define __INIT .section ".init.text","ax" #define __FINIT .previous From 12aa343add3eced38a44bdb612b35fdf634d918c Mon Sep 17 00:00:00 2001 From: "Jorge Boncompte [DTI2]" Date: Tue, 19 Feb 2008 14:17:04 -0800 Subject: [PATCH 423/880] [NET]: Messed multicast lists after dev_mc_sync/unsync Commit a0a400d79e3dd7843e7e81baa3ef2957bdc292d0 ("[NET]: dev_mcast: add multicast list synchronization helpers") from you introduced a new field "da_synced" to struct dev_addr_list that is not properly initialized to 0. So when any of the current users (8021q, macvlan, mac80211) calls dev_mc_sync/unsync they mess the address list for both devices. The attached patch fixed it for me and avoid future problems. Signed-off-by: Jorge Boncompte [DTI2] Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 6cfc1238c4a6..95161054c4d1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2900,7 +2900,7 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, } } - da = kmalloc(sizeof(*da), GFP_ATOMIC); + da = kzalloc(sizeof(*da), GFP_ATOMIC); if (da == NULL) return -ENOMEM; memcpy(da->da_addr, addr, alen); From 60f92683943c5b7a85963b283d6f8a853aa09203 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Tue, 19 Feb 2008 21:32:45 +1000 Subject: [PATCH 424/880] drm/radeon: add initial rs690 support to drm. This adds support for configuring the RS690 GART. Signed-off-by: Dave Airlie --- drivers/char/drm/drm_pciids.h | 1 + drivers/char/drm/radeon_cp.c | 81 +++++++++++++++++++++++++++++++++++ drivers/char/drm/radeon_drv.h | 38 ++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index f52468843678..5de6f8788b60 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -236,6 +236,7 @@ {0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \ {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ {0, 0, 0} #define r128_PCI_IDS \ diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 5dc799ab86b8..833abc7e55fb 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -825,11 +825,19 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) return ret; } +static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) +{ + RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); + return RADEON_READ(RS690_MC_DATA); +} + u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); else @@ -840,6 +848,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); else @@ -850,6 +860,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); else @@ -1362,6 +1374,70 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) } } +/* Enable or disable RS690 GART on the chip */ +static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on) +{ + u32 temp; + + if (on) { + DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n", + dev_priv->gart_vm_start, + (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL); + RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000); + + RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, + RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID); + RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800); + + RS690_WRITE_MCIND(RS690_MC_GART_BASE, + dev_priv->gart_info.bus_addr); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL); + RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000); + + RS690_WRITE_MCIND(RS690_MC_AGP_BASE, + (unsigned int)dev_priv->gart_vm_start); + + dev_priv->gart_size = 32*1024*1024; + temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & + 0xffff0000) | (dev_priv->gart_vm_start >> 16)); + + RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE); + RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, + RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB); + + do { + temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL); + if ((temp & RS690_MC_GART_CLEAR_STATUS) == + RS690_MC_GART_CLEAR_DONE) + break; + DRM_UDELAY(1); + } while (1); + + RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL, + RS690_MC_GART_CC_CLEAR); + do { + temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL); + if ((temp & RS690_MC_GART_CLEAR_STATUS) == + RS690_MC_GART_CLEAR_DONE) + break; + DRM_UDELAY(1); + } while (1); + + RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL, + RS690_MC_GART_CC_NO_CHANGE); + } else { + RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS); + } +} + static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) { u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); @@ -1396,6 +1472,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { + radeon_set_rs690gart(dev_priv, on); + return; + } + if (dev_priv->flags & RADEON_IS_IGPGART) { radeon_set_igpgart(dev_priv, on); return; diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 4434332c79bc..173ae620223a 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -123,6 +123,7 @@ enum radeon_family { CHIP_R420, CHIP_RV410, CHIP_RS400, + CHIP_RS690, CHIP_RV515, CHIP_R520, CHIP_RV530, @@ -467,6 +468,36 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, #define RADEON_IGPGART_ENABLE 0x38 #define RADEON_IGPGART_UNK_39 0x39 +#define RS690_MC_INDEX 0x78 +# define RS690_MC_INDEX_MASK 0x1ff +# define RS690_MC_INDEX_WR_EN (1 << 9) +# define RS690_MC_INDEX_WR_ACK 0x7f +#define RS690_MC_DATA 0x7c + +#define RS690_MC_MISC_CNTL 0x18 +#define RS690_MC_GART_FEATURE_ID 0x2b +#define RS690_MC_GART_BASE 0x2c +#define RS690_MC_GART_CACHE_CNTL 0x2e +# define RS690_MC_GART_CC_NO_CHANGE 0x0 +# define RS690_MC_GART_CC_CLEAR 0x1 +# define RS690_MC_GART_CLEAR_STATUS (1 << 1) +# define RS690_MC_GART_CLEAR_DONE (0 << 1) +# define RS690_MC_GART_CLEAR_PENDING (1 << 1) +#define RS690_MC_AGP_SIZE 0x38 +# define RS690_MC_GART_DIS 0x0 +# define RS690_MC_GART_EN 0x1 +# define RS690_MC_AGP_SIZE_32MB (0 << 1) +# define RS690_MC_AGP_SIZE_64MB (1 << 1) +# define RS690_MC_AGP_SIZE_128MB (2 << 1) +# define RS690_MC_AGP_SIZE_256MB (3 << 1) +# define RS690_MC_AGP_SIZE_512MB (4 << 1) +# define RS690_MC_AGP_SIZE_1GB (5 << 1) +# define RS690_MC_AGP_SIZE_2GB (6 << 1) +#define RS690_MC_AGP_MODE_CONTROL 0x39 +#define RS690_MC_FB_LOCATION 0x100 +#define RS690_MC_AGP_LOCATION 0x101 +#define RS690_MC_AGP_BASE 0x102 + #define R520_MC_IND_INDEX 0x70 #define R520_MC_IND_WR_EN (1<<24) #define R520_MC_IND_DATA 0x74 @@ -1076,6 +1107,13 @@ do { \ RADEON_WRITE(R520_MC_IND_INDEX, 0); \ } while (0) +#define RS690_WRITE_MCIND( addr, val ) \ +do { \ + RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \ + RADEON_WRITE(RS690_MC_DATA, val); \ + RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ +} while (0) + #define CP_PACKET0( reg, n ) \ (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) #define CP_PACKET0_TABLE( reg, n ) \ From b39d50e53b1bb27f6c29f88a697a4af78427dffd Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 19 Feb 2008 20:59:09 +1000 Subject: [PATCH 425/880] i915: wrap chipset types requiring hw status set ioctl Also applys to recent added new chipset. Signed-off-by: Zhenyu Wang Signed-off-by: Dave Airlie --- drivers/char/drm/i915_dma.c | 5 ++++- drivers/char/drm/i915_drv.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 43986d81ae34..e9d6663bec73 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c @@ -171,7 +171,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) dev_priv->allow_batchbuffer = 1; /* Program Hardware Status Page */ - if (!IS_G33(dev)) { + if (!I915_NEED_GFX_HWS(dev)) { dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); @@ -720,6 +720,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data, drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_hws_addr_t *hws = data; + if (!I915_NEED_GFX_HWS(dev)) + return -EINVAL; + if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index f8308bfb2613..786460d6b1a3 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -1101,6 +1101,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev)) +#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev)) + #define PRIMARY_RINGBUFFER_SIZE (128*1024) #endif From ca0b07d9a969c6561e5d6f69c861fbedf8d09e5d Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Thu, 7 Feb 2008 16:20:50 +1000 Subject: [PATCH 426/880] drm: convert drm from nopage to fault. Remove redundant vma range checks. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/char/drm/drm_vm.c | 125 +++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 70 deletions(-) diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index cea4105374b2..3d65c4dcd0c6 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c @@ -66,7 +66,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) } /** - * \c nopage method for AGP virtual memory. + * \c fault method for AGP virtual memory. * * \param vma virtual memory area. * \param address access address. @@ -76,8 +76,7 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) * map, get the page, increment the use count and return it. */ #if __OS_HAS_AGP -static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, - unsigned long address) +static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_file *priv = vma->vm_file->private_data; struct drm_device *dev = priv->head->dev; @@ -89,19 +88,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, * Find the right map */ if (!drm_core_has_AGP(dev)) - goto vm_nopage_error; + goto vm_fault_error; if (!dev->agp || !dev->agp->cant_use_aperture) - goto vm_nopage_error; + goto vm_fault_error; if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) - goto vm_nopage_error; + goto vm_fault_error; r_list = drm_hash_entry(hash, struct drm_map_list, hash); map = r_list->map; if (map && map->type == _DRM_AGP) { - unsigned long offset = address - vma->vm_start; + /* + * Using vm_pgoff as a selector forces us to use this unusual + * addressing scheme. + */ + unsigned long offset = (unsigned long)vmf->virtual_address - + vma->vm_start; unsigned long baddr = map->offset + offset; struct drm_agp_mem *agpmem; struct page *page; @@ -123,7 +127,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, } if (!agpmem) - goto vm_nopage_error; + goto vm_fault_error; /* * Get the page, inc the use count, and return it @@ -131,22 +135,21 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, offset = (baddr - agpmem->bound) >> PAGE_SHIFT; page = virt_to_page(__va(agpmem->memory->memory[offset])); get_page(page); + vmf->page = page; DRM_DEBUG ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", baddr, __va(agpmem->memory->memory[offset]), offset, page_count(page)); - - return page; + return 0; } - vm_nopage_error: - return NOPAGE_SIGBUS; /* Disallow mremap */ +vm_fault_error: + return VM_FAULT_SIGBUS; /* Disallow mremap */ } #else /* __OS_HAS_AGP */ -static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, - unsigned long address) +static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return NOPAGE_SIGBUS; + return VM_FAULT_SIGBUS; } #endif /* __OS_HAS_AGP */ @@ -160,28 +163,26 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, * Get the mapping, find the real physical page to map, get the page, and * return it. */ -static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, - unsigned long address) +static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_map *map = (struct drm_map *) vma->vm_private_data; unsigned long offset; unsigned long i; struct page *page; - if (address > vma->vm_end) - return NOPAGE_SIGBUS; /* Disallow mremap */ if (!map) - return NOPAGE_SIGBUS; /* Nothing allocated */ + return VM_FAULT_SIGBUS; /* Nothing allocated */ - offset = address - vma->vm_start; + offset = (unsigned long)vmf->virtual_address - vma->vm_start; i = (unsigned long)map->handle + offset; page = vmalloc_to_page((void *)i); if (!page) - return NOPAGE_SIGBUS; + return VM_FAULT_SIGBUS; get_page(page); + vmf->page = page; - DRM_DEBUG("0x%lx\n", address); - return page; + DRM_DEBUG("shm_fault 0x%lx\n", offset); + return 0; } /** @@ -263,7 +264,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) } /** - * \c nopage method for DMA virtual memory. + * \c fault method for DMA virtual memory. * * \param vma virtual memory area. * \param address access address. @@ -271,8 +272,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) * * Determine the page number from the page offset and get it from drm_device_dma::pagelist. */ -static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, - unsigned long address) +static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_file *priv = vma->vm_file->private_data; struct drm_device *dev = priv->head->dev; @@ -282,24 +282,23 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, struct page *page; if (!dma) - return NOPAGE_SIGBUS; /* Error */ - if (address > vma->vm_end) - return NOPAGE_SIGBUS; /* Disallow mremap */ + return VM_FAULT_SIGBUS; /* Error */ if (!dma->pagelist) - return NOPAGE_SIGBUS; /* Nothing allocated */ + return VM_FAULT_SIGBUS; /* Nothing allocated */ - offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ - page_nr = offset >> PAGE_SHIFT; + offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ + page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */ page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK)))); get_page(page); + vmf->page = page; - DRM_DEBUG("0x%lx (page %lu)\n", address, page_nr); - return page; + DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr); + return 0; } /** - * \c nopage method for scatter-gather virtual memory. + * \c fault method for scatter-gather virtual memory. * * \param vma virtual memory area. * \param address access address. @@ -307,8 +306,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, * * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist. */ -static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, - unsigned long address) +static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_map *map = (struct drm_map *) vma->vm_private_data; struct drm_file *priv = vma->vm_file->private_data; @@ -320,77 +318,64 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, struct page *page; if (!entry) - return NOPAGE_SIGBUS; /* Error */ - if (address > vma->vm_end) - return NOPAGE_SIGBUS; /* Disallow mremap */ + return VM_FAULT_SIGBUS; /* Error */ if (!entry->pagelist) - return NOPAGE_SIGBUS; /* Nothing allocated */ + return VM_FAULT_SIGBUS; /* Nothing allocated */ - offset = address - vma->vm_start; + offset = (unsigned long)vmf->virtual_address - vma->vm_start; map_offset = map->offset - (unsigned long)dev->sg->virtual; page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); page = entry->pagelist[page_offset]; get_page(page); + vmf->page = page; - return page; + return 0; } -static struct page *drm_vm_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) +static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - if (type) - *type = VM_FAULT_MINOR; - return drm_do_vm_nopage(vma, address); + return drm_do_vm_fault(vma, vmf); } -static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) +static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - if (type) - *type = VM_FAULT_MINOR; - return drm_do_vm_shm_nopage(vma, address); + return drm_do_vm_shm_fault(vma, vmf); } -static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) +static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - if (type) - *type = VM_FAULT_MINOR; - return drm_do_vm_dma_nopage(vma, address); + return drm_do_vm_dma_fault(vma, vmf); } -static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) +static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - if (type) - *type = VM_FAULT_MINOR; - return drm_do_vm_sg_nopage(vma, address); + return drm_do_vm_sg_fault(vma, vmf); } /** AGP virtual memory operations */ static struct vm_operations_struct drm_vm_ops = { - .nopage = drm_vm_nopage, + .fault = drm_vm_fault, .open = drm_vm_open, .close = drm_vm_close, }; /** Shared virtual memory operations */ static struct vm_operations_struct drm_vm_shm_ops = { - .nopage = drm_vm_shm_nopage, + .fault = drm_vm_shm_fault, .open = drm_vm_open, .close = drm_vm_shm_close, }; /** DMA virtual memory operations */ static struct vm_operations_struct drm_vm_dma_ops = { - .nopage = drm_vm_dma_nopage, + .fault = drm_vm_dma_fault, .open = drm_vm_open, .close = drm_vm_close, }; /** Scatter-gather virtual memory operations */ static struct vm_operations_struct drm_vm_sg_ops = { - .nopage = drm_vm_sg_nopage, + .fault = drm_vm_sg_fault, .open = drm_vm_open, .close = drm_vm_close, }; @@ -604,7 +589,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) /* * On some platforms we can't talk to bus dma address from the CPU, so for * memory of type DRM_AGP, we'll deal with sorting out the real physical - * pages and mappings in nopage() + * pages and mappings in fault() */ #if defined(__powerpc__) pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; @@ -634,7 +619,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) break; case _DRM_CONSISTENT: /* Consistent memory is really like shared memory. But - * it's allocated in a different way, so avoid nopage */ + * it's allocated in a different way, so avoid fault */ if (remap_pfn_range(vma, vma->vm_start, page_to_pfn(virt_to_page(map->handle)), vma->vm_end - vma->vm_start, vma->vm_page_prot)) From 0da3ea12fc2607beb67c2d54d0347807ea615573 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 20 Feb 2008 09:39:58 +1000 Subject: [PATCH 427/880] drm/i915: save/restore interrupt state On resume, if the interrupt state isn't restored correctly, we may end up with a flood of unexpected or ill-timed interrupts, which could cause the kernel to disable the interrupt or vblank events to happen at the wrong time. So save/restore them properly. Signed-off-by: Dave Airlie --- drivers/char/drm/i915_drv.c | 7 +++++++ drivers/char/drm/i915_drv.h | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 52e51033d32c..0f525ad536a4 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -276,6 +276,7 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); } i915_save_palette(dev, PIPE_A); + dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); /* Pipe & plane B info */ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); @@ -303,6 +304,7 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); } i915_save_palette(dev, PIPE_B); + dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); /* CRT state */ dev_priv->saveADPA = I915_READ(ADPA); @@ -329,6 +331,11 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); + /* Interrupt state */ + dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); + dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); + dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); + /* VGA state */ dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 786460d6b1a3..360f6600427b 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -134,6 +134,7 @@ typedef struct drm_i915_private { u32 saveVBLANK_A; u32 saveVSYNC_A; u32 saveBCLRPAT_A; + u32 savePIPEASTAT; u32 saveDSPASTRIDE; u32 saveDSPASIZE; u32 saveDSPAPOS; @@ -154,6 +155,7 @@ typedef struct drm_i915_private { u32 saveVBLANK_B; u32 saveVSYNC_B; u32 saveBCLRPAT_B; + u32 savePIPEBSTAT; u32 saveDSPBSTRIDE; u32 saveDSPBSIZE; u32 saveDSPBPOS; @@ -182,6 +184,9 @@ typedef struct drm_i915_private { u32 saveFBC_LL_BASE; u32 saveFBC_CONTROL; u32 saveFBC_CONTROL2; + u32 saveIER; + u32 saveIIR; + u32 saveIMR; u32 saveSWF0[16]; u32 saveSWF1[16]; u32 saveSWF2[3]; From c0c4261b6fd80f0fc5546ed67058592469a4f5b7 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 7 Feb 2008 17:33:28 -0800 Subject: [PATCH 428/880] drm/i915: restore pipeconf regs unconditionally On many chipsets, the checks for DPLL enable or VGA mode will prevent the pipeconf regs from being restored, which could result in a blank display or X failing to come back after resume. So restore them unconditionally along with actually restoring pipe B's palette correctly. Signed-off-by: Dave Airlie --- drivers/char/drm/i915_drv.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 0f525ad536a4..248e7b1c46a5 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -407,9 +407,7 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); } - if ((dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) && - (dev_priv->saveDPLL_A & DPLL_VGA_MODE_DIS)) - I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); + I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); i915_restore_palette(dev, PIPE_A); /* Enable the plane */ @@ -451,10 +449,9 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); } - if ((dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) && - (dev_priv->saveDPLL_B & DPLL_VGA_MODE_DIS)) - I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); - i915_restore_palette(dev, PIPE_A); + I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); + + i915_restore_palette(dev, PIPE_B); /* Enable the plane */ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); From 1f84e550a870bf5f5f399b611db68f3324ea7883 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Feb 2008 19:19:29 -0800 Subject: [PATCH 429/880] drm/i915 more registers for S3 (DSPCLK_GATE_D, CACHE_MODE_0, MI_ARB_STATE) Failing to preserve the MI_ARB_STATE register was causing FIFO underruns on the VGA output on my HP 2510p after resume. Signed-off-by: Dave Airlie --- drivers/char/drm/i915_drv.c | 18 ++++++++++++++++++ drivers/char/drm/i915_drv.h | 10 ++++++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 248e7b1c46a5..5025f5b02412 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -342,6 +342,15 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + /* Clock gating state */ + dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); + + /* Cache mode state */ + dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); + + /* Memory Arbitration state */ + dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); + /* Scratch space */ for (i = 0; i < 16; i++) { dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); @@ -489,6 +498,15 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); udelay(150); + /* Clock gating state */ + I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); + + /* Cache mode state */ + I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); + + /* Memory arbitration state */ + I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); + for (i = 0; i < 16; i++) { I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 360f6600427b..c10d128e34db 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -187,6 +187,9 @@ typedef struct drm_i915_private { u32 saveIER; u32 saveIIR; u32 saveIMR; + u32 saveCACHE_MODE_0; + u32 saveDSPCLK_GATE_D; + u32 saveMI_ARB_STATE; u32 saveSWF0[16]; u32 saveSWF1[16]; u32 saveSWF2[3]; @@ -455,6 +458,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); */ #define DMA_FADD_S 0x20d4 +/* Memory Interface Arbitration State + */ +#define MI_ARB_STATE 0x20e4 + /* Cache mode 0 reg. * - Manipulating render cache behaviour is central * to the concept of zone rendering, tuning this reg can help avoid @@ -465,6 +472,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. */ #define Cache_Mode_0 0x2120 +#define CACHE_MODE_0 0x2120 #define CM0_MASK_SHIFT 16 #define CM0_IZ_OPT_DISABLE (1<<6) #define CM0_ZR_OPT_DISABLE (1<<5) @@ -660,6 +668,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); /** P1 value is 2 greater than this field */ # define VGA0_PD_P1_MASK (0x1f << 0) +#define DSPCLK_GATE_D 0x6200 + /* I830 CRTC registers */ #define HTOTAL_A 0x60000 #define HBLANK_A 0x60004 From da636ad6a0d72eb5cb99738056af0bcc3db9ef9d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 28 Jan 2008 21:05:22 -0800 Subject: [PATCH 430/880] drm/i915: Fix hibernate save/restore of VGA attribute regs In hibernate, we may end up calling the VGA save regs function twice, so we need to make sure it's idempotent. That means leaving ARX in index mode after the first save operation. Fixes hibernate on 965. Signed-off-by: Dave Airlie --- drivers/char/drm/i915_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 5025f5b02412..35758a6c8b0d 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -160,6 +160,7 @@ static void i915_save_vga(struct drm_device *dev) dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); inb(st01); outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); + inb(st01); /* Graphics controller registers */ for (i = 0; i < 9; i++) @@ -225,6 +226,7 @@ static void i915_restore_vga(struct drm_device *dev) i915_write_ar(st01, i, dev_priv->saveAR[i], 0); inb(st01); /* switch back to index mode */ outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); + inb(st01); /* VGA color palette registers */ outb(dev_priv->saveDACMASK, VGA_DACMASK); From 2b79aac9038ee52fd8d89216b1a3ec9bd8285fac Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 19 Feb 2008 18:58:49 +0000 Subject: [PATCH 431/880] MN10300: Call update_process_times() outside of the xtime_lock Call update_process_times() outside of the xtime_lock. Somewhere somewhere inside one of the functions called by that, xtime_lock is readlocked, which ends up in a deadlock situation. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/mn10300/kernel/time.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c index ff492e3b3457..babb7c2ac377 100644 --- a/arch/mn10300/kernel/time.c +++ b/arch/mn10300/kernel/time.c @@ -84,11 +84,13 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) /* advance the kernel's time tracking system */ profile_tick(CPU_PROFILING); do_timer(1); - update_process_times(user_mode(get_irq_regs())); check_rtc_time(); } write_sequnlock(&xtime_lock); + + update_process_times(user_mode(get_irq_regs())); + return IRQ_HANDLED; } From 5efe92c68045817b97927b748f369d407c1d89ab Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 19 Feb 2008 18:58:54 +0000 Subject: [PATCH 432/880] MN10300: Introduce barriers to replace removed volatiles in gdbstub Introduce into the MN10300 gdbstub a couple of barrier() calls to replace the removed volatility of the input/output index variables for the Rx ring buffer. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/mn10300/kernel/gdb-io-ttysm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c index c5451592d403..e94c25e8ca05 100644 --- a/arch/mn10300/kernel/gdb-io-ttysm.c +++ b/arch/mn10300/kernel/gdb-io-ttysm.c @@ -196,6 +196,7 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock) try_again: /* pull chars out of the buffer */ ix = gdbstub_rx_outp; + barrier(); if (ix == gdbstub_rx_inp) { if (nonblock) return -EAGAIN; @@ -207,6 +208,7 @@ int gdbstub_io_rx_char(unsigned char *_ch, int nonblock) ch = gdbstub_rx_buffer[ix++]; st = gdbstub_rx_buffer[ix++]; + barrier(); gdbstub_rx_outp = ix & (PAGE_SIZE - 1); st &= SC01STR_RXF | SC01STR_RBF | SC01STR_FEF | SC01STR_PEF | From aa409e028c41137a659c02d0081ba57b701e7446 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 19 Feb 2008 18:58:59 +0000 Subject: [PATCH 433/880] MN10300: Make the kernel jump into gdbstub on a BUG Make the kernel jump into gdbstub (if configured) on a BUG with the register set from the BUG rather than interpolating another illegal instruction and leaving gdbstub's idea of the process counter in unsupported_syscall() where the original BUG was detected. With this patch, gdbstub reports a SIGABRT to the compiler and reports the program counter at the original BUG, allowing the execution state at the time of the BUG to be examined with GDB. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/mn10300/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c index 8b9dc6d9dcc6..fcb9a03d46a8 100644 --- a/arch/mn10300/kernel/traps.c +++ b/arch/mn10300/kernel/traps.c @@ -391,7 +391,7 @@ static asmlinkage void unsupported_syscall(struct pt_regs *regs, if (code == EXCEP_SYSCALL15 && !user_mode(regs)) { if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_BUG) { #ifdef CONFIG_GDBSTUB - __gdbstub_bug_trap(); + gdbstub_intercept(regs, code); #endif } } From ae5e1b6cc511b278ad52b2d42afb44780e5d4cb2 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 19 Feb 2008 18:59:04 +0000 Subject: [PATCH 434/880] MN10300: Update asb2303_defconfig Update the ASB2303 default configuration. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/mn10300/configs/asb2303_defconfig | 33 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/arch/mn10300/configs/asb2303_defconfig b/arch/mn10300/configs/asb2303_defconfig index ca9876a111d3..3aa8906b3dea 100644 --- a/arch/mn10300/configs/asb2303_defconfig +++ b/arch/mn10300/configs/asb2303_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc2 -# Fri Nov 16 13:36:38 2007 +# Linux kernel version: 2.6.25-rc2 +# Tue Feb 19 18:52:24 2008 # CONFIG_MN10300=y CONFIG_AM33=y @@ -21,6 +21,7 @@ CONFIG_ARCH_HAS_ILOG2_U32=y # CONFIG_ARCH_SUPPORTS_AOUT is not set CONFIG_GENERIC_HARDIRQS=y # CONFIG_HOTPLUG_CPU is not set +CONFIG_HZ=1000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -38,15 +39,16 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 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 is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_GROUP_SCHED is not set +# CONFIG_USER_SCHED is not set +# CONFIG_CGROUP_SCHED is not set # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -57,22 +59,33 @@ CONFIG_SYSCTL_SYSCALL=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_VM_EVENT_COUNTERS is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_PROFILING=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=y +# CONFIG_HAVE_OPROFILE is not set +# CONFIG_HAVE_KPROBES is not set +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set # CONFIG_BLOCK is not set +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # Matsushita MN10300 system setup @@ -206,6 +219,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -311,6 +325,8 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_PARPORT is not set CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HAVE_IDE is not set # # SCSI device support @@ -345,7 +361,6 @@ CONFIG_SMC91X=y # 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 @@ -405,6 +420,7 @@ CONFIG_RTC=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +# CONFIG_THERMAL is not set # CONFIG_WATCHDOG is not set # @@ -444,6 +460,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_RTC_CLASS is not set @@ -455,10 +472,10 @@ CONFIG_SSB_POSSIBLE=y # # File systems # +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 @@ -554,5 +571,3 @@ CONFIG_HAS_DMA=y # # Profiling support # -CONFIG_PROFILING=y -CONFIG_OPROFILE=y From e03f1a842287480aa03732612148c0d333baca61 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Feb 2008 19:44:19 +0000 Subject: [PATCH 435/880] dm-raid1.c: fix NULL dereferences This patch fixes two NULL dereferences introduced by commit 06386bbfd2441416875d0403d405c56822f6ebac and spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Alasdair G Kergon Signed-off-by: Linus Torvalds --- drivers/md/dm-raid1.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 2928ef228101..51605870f898 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -1695,14 +1695,15 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, * information for a retry or there was no other * mirror in-sync. */ - DMERR_LIMIT("Mirror read failed from %s.", - m->dev->name); + DMERR_LIMIT("Mirror read failed."); return -EIO; } + + m = read_record->m; + DMERR("Mirror read failed from %s. Trying alternative device.", m->dev->name); - m = read_record->m; fail_mirror(m, DM_RAID1_READ_ERROR); /* From b932ccb5674eb649133b5c33950405c37d17aab3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 20 Feb 2008 10:02:20 +1000 Subject: [PATCH 436/880] drm: add support for passing state into the suspend hooks. fix i915 driver to use state for hibernate save avoidance. Signed-off-by: Dave Airlie --- drivers/char/drm/drmP.h | 2 +- drivers/char/drm/drm_sysfs.c | 2 +- drivers/char/drm/i915_drv.c | 13 +++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 19d3be5c4b2d..a6789f25009b 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -568,7 +568,7 @@ struct drm_driver { void (*postclose) (struct drm_device *, struct drm_file *); void (*lastclose) (struct drm_device *); int (*unload) (struct drm_device *); - int (*suspend) (struct drm_device *); + int (*suspend) (struct drm_device *, pm_message_t state); int (*resume) (struct drm_device *); int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv); void (*dma_ready) (struct drm_device *); diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index fa36153619e8..05ed5043254f 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c @@ -36,7 +36,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) printk(KERN_ERR "%s\n", __FUNCTION__); if (drm_dev->driver->suspend) - return drm_dev->driver->suspend(drm_dev); + return drm_dev->driver->suspend(drm_dev, state); return 0; } diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 35758a6c8b0d..4048f39b7eed 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -238,7 +238,7 @@ static void i915_restore_vga(struct drm_device *dev) } -static int i915_suspend(struct drm_device *dev) +static int i915_suspend(struct drm_device *dev, pm_message_t state) { struct drm_i915_private *dev_priv = dev->dev_private; int i; @@ -249,6 +249,9 @@ static int i915_suspend(struct drm_device *dev) return -ENODEV; } + if (state.event == PM_EVENT_PRETHAW) + return 0; + pci_save_state(dev->pdev); pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); @@ -363,9 +366,11 @@ static int i915_suspend(struct drm_device *dev) i915_save_vga(dev); - /* Shut down the device */ - pci_disable_device(dev->pdev); - pci_set_power_state(dev->pdev, PCI_D3hot); + if (state.event == PM_EVENT_SUSPEND) { + /* Shut down the device */ + pci_disable_device(dev->pdev); + pci_set_power_state(dev->pdev, PCI_D3hot); + } return 0; } From f9e9716a67fbea4594749bf1022fdfd0b96099db Mon Sep 17 00:00:00 2001 From: Mirko Date: Wed, 20 Feb 2008 10:07:57 +1000 Subject: [PATCH 437/880] drm: add new rv380 pciid Signed-off-by: Dave Airlie --- drivers/char/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 5de6f8788b60..874af6ff1499 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -83,6 +83,7 @@ {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ + {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ From 76e87306c2de2a581ec939cf9c97cd18d053f90e Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 19 Feb 2008 16:12:08 -0800 Subject: [PATCH 438/880] [RTNL]: Add missing link netlink attribute policy definitions IFLA_LINK is no longer a write-only attribute on the kernel side and must thus be validated. Same goes for the newly introduced IFLA_LINKINFO. Fixes undefined behaviour if either of the attributes are not well formed. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 61ac8d06292c..e170179cc66f 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -689,10 +689,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN }, [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, [IFLA_MTU] = { .type = NLA_U32 }, + [IFLA_LINK] = { .type = NLA_U32 }, [IFLA_TXQLEN] = { .type = NLA_U32 }, [IFLA_WEIGHT] = { .type = NLA_U32 }, [IFLA_OPERSTATE] = { .type = NLA_U8 }, [IFLA_LINKMODE] = { .type = NLA_U8 }, + [IFLA_LINKINFO] = { .type = NLA_NESTED }, [IFLA_NET_NS_PID] = { .type = NLA_U32 }, }; From feac7af508ebdfe1db9920d4e45d0ffd286abe75 Mon Sep 17 00:00:00 2001 From: Chaoyu Chen Date: Wed, 20 Feb 2008 10:12:39 +1000 Subject: [PATCH 439/880] drm/sis: add pciid for SiS 662/671 chipset Signed-off-by: Dave Airlie --- drivers/char/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 874af6ff1499..715b361f0c2b 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -315,6 +315,7 @@ {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ + {0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ From 2e374748c73f34e018a1c13a86a96a15fc55a65a Mon Sep 17 00:00:00 2001 From: Chaoyu Chen Date: Wed, 20 Feb 2008 10:18:46 +1000 Subject: [PATCH 440/880] agp: add support for 662/671 to agp driver Signed-off-by: Dave Airlie --- drivers/char/agp/sis-agp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 6cf54fe60207..b6791846809f 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -14,6 +14,9 @@ #define SIS_TLBCNTRL 0x97 #define SIS_TLBFLUSH 0x98 +#define PCI_DEVICE_ID_SI_662 0x0662 +#define PCI_DEVICE_ID_SI_671 0x0671 + static int __devinitdata agp_sis_force_delay = 0; static int __devinitdata agp_sis_agp_spec = -1; @@ -347,6 +350,22 @@ static struct pci_device_id agp_sis_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_662, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_671, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, From 15e29b8b0542f28fc0feed2d60e0377b39a45c4f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Feb 2008 16:25:30 -0800 Subject: [PATCH 441/880] net/9p/trans_virtio.c: kmalloc() enough memory The Coverity checker spotted that less memory than required was allocated. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller --- net/9p/trans_virtio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 9e3d81cb9f08..de7a9f532edc 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -110,7 +110,7 @@ static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag) } for (count = old_max; count < c->max_tag; count++) { c->reqs[count].status = REQ_STATUS_IDLE; - c->reqs[count].wq = kmalloc(sizeof(wait_queue_t), + c->reqs[count].wq = kmalloc(sizeof(wait_queue_head_t), GFP_ATOMIC); if (!c->reqs[count].wq) { printk(KERN_ERR "Couldn't grow tag array\n"); From 94cb1503c799c0197e7ef5bad606fee5c84b99d8 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Feb 2008 16:28:54 -0800 Subject: [PATCH 442/880] ipv4/fib_hash.c: fix NULL dereference Unless I miss a guaranteed relation between between "f" and "new_fa->fa_info" this patch is required for fixing a NULL dereference introduced by commit a6501e080c318f8d4467679d17807f42b3a33cd5 ("[IPV4] FIB_HASH: Reduce memory needs and speedup lookups") and spotted by the Coverity checker. Eric Dumazet says: Hum, you are right, kmem_cache_free() doesnt allow a NULL object, like kfree() does. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller --- net/ipv4/fib_hash.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 76b9c684cccd..8d58d85dfac6 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -372,7 +372,8 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key) static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) { struct fn_hash *table = (struct fn_hash *) tb->tb_data; - struct fib_node *new_f, *f; + struct fib_node *new_f = NULL; + struct fib_node *f; struct fib_alias *fa, *new_fa; struct fn_zone *fz; struct fib_info *fi; @@ -496,7 +497,6 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) err = -ENOBUFS; - new_f = NULL; if (!f) { new_f = kmem_cache_zalloc(fn_hash_kmem, GFP_KERNEL); if (new_f == NULL) @@ -512,7 +512,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) if (new_fa->fa_info != NULL) { new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); if (new_fa == NULL) - goto out_free_new_f; + goto out; } new_fa->fa_info = fi; new_fa->fa_tos = tos; @@ -540,9 +540,9 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) &cfg->fc_nlinfo, 0); return 0; -out_free_new_f: - kmem_cache_free(fn_hash_kmem, new_f); out: + if (new_f) + kmem_cache_free(fn_hash_kmem, new_f); fib_release_info(fi); return err; } From 44a207fc66c13c82f627178f9f858b8f3e76028f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 20 Feb 2008 10:37:08 +1000 Subject: [PATCH 443/880] agp: fix missing casts that produced a warning. Signed-off-by: Dave Airlie --- drivers/char/agp/amd-k7-agp.c | 4 ++-- drivers/char/agp/ati-agp.c | 4 ++-- drivers/char/agp/sworks-agp.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index fca4d7f30443..d28669992147 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -54,7 +54,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) } global_cache_flush(); #else - set_memory_uc(page_map->real, 1); + set_memory_uc((unsigned long)page_map->real, 1); page_map->remapped = page_map->real; #endif @@ -72,7 +72,7 @@ static void amd_free_page_map(struct amd_page_map *page_map) iounmap(page_map->remapped); ClearPageReserved(virt_to_page(page_map->real)); #else - set_memory_wb(page_map->real, 1); + set_memory_wb((unsigned long)page_map->real, 1); #endif free_page((unsigned long) page_map->real); } diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 9ac3bef3bb7a..55c97f623242 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -60,7 +60,7 @@ static int ati_create_page_map(struct ati_page_map *page_map) if (page_map->real == NULL) return -ENOMEM; - set_memory_uc(page_map->real, 1); + set_memory_uc((unsigned long)page_map->real, 1); err = map_page_into_agp(virt_to_page(page_map->real)); page_map->remapped = page_map->real; @@ -76,7 +76,7 @@ static int ati_create_page_map(struct ati_page_map *page_map) static void ati_free_page_map(struct ati_page_map *page_map) { unmap_page_from_agp(virt_to_page(page_map->real)); - set_memory_wb(page_map->real, 1); + set_memory_wb((unsigned long)page_map->real, 1); free_page((unsigned long) page_map->real); } diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index ae06f8982068..e08934e58f32 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -53,7 +53,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) return -ENOMEM; } - set_memory_uc(page_map->real, 1); + set_memory_uc((unsigned long)page_map->real, 1); page_map->remapped = page_map->real; for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) @@ -65,7 +65,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) static void serverworks_free_page_map(struct serverworks_page_map *page_map) { - set_memory_wb(page_map->real, 1); + set_memory_wb((unsigned long)page_map->real, 1); free_page((unsigned long) page_map->real); } From 6133116849219f4e657ead39c7ac3922583f5a6e Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 19 Feb 2008 11:00:29 +0100 Subject: [PATCH 444/880] ACPI: TSC breaks atkbd suspend TSC is used even on machines when CONFIG_X86_TSC is not set (X86_TSC means _require_ TSC), but it is not properly disabled when it is unusable, because ACPI code understood the config switch as "may use TSC". This actually fixes suspend problems on my x60. Signed-off-by: Pavel Machek Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 980e1c33e6c5..6f3b217699e9 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -364,7 +364,7 @@ int acpi_processor_resume(struct acpi_device * device) return 0; } -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) static int tsc_halts_in_c(int state) { switch (boot_cpu_data.x86_vendor) { @@ -544,7 +544,7 @@ static void acpi_processor_idle(void) /* Get end time (ticks) */ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) /* TSC halts in C2, so notify users */ if (tsc_halts_in_c(ACPI_STATE_C2)) mark_tsc_unstable("possible TSC halt in C2"); @@ -609,7 +609,7 @@ static void acpi_processor_idle(void) acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); } -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) /* TSC halts in C3, so notify users */ if (tsc_halts_in_c(ACPI_STATE_C3)) mark_tsc_unstable("TSC halts in C3"); @@ -1500,7 +1500,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, acpi_idle_do_entry(cx); t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) /* TSC could halt in idle, so notify users */ if (tsc_halts_in_c(cx->type)) mark_tsc_unstable("TSC halts in idle");; @@ -1614,7 +1614,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, spin_unlock(&c3_lock); } -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) /* TSC could halt in idle, so notify users */ if (tsc_halts_in_c(ACPI_STATE_C3)) mark_tsc_unstable("TSC halts in idle"); From e2b58a67b91dec07dfb40ca2056c64011ce8489d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 19 Feb 2008 17:17:52 -0800 Subject: [PATCH 445/880] [NETFILTER]: {ip,ip6,nfnetlink}_queue: fix SKB_LINEAR_ASSERT when mangling packet data As reported by Tomas Simonaitis , inserting new data in skbs queued over {ip,ip6,nfnetlink}_queue triggers a SKB_LINEAR_ASSERT in skb_put(). Going back through the git history, it seems this bug is present since at least 2.6.12-rc2, probably even since the removal of skb_linearize() for netfilter. Linearize non-linear skbs through skb_copy_expand() when enlarging them. Tested by Thomas, fixes bugzilla #9933. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_queue.c | 12 +++++++----- net/ipv6/netfilter/ip6_queue.c | 10 ++++++---- net/netfilter/nfnetlink_queue.c | 10 ++++++---- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 6bda1102851b..fe05da41d6ba 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -283,8 +283,8 @@ static int ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e) { int diff; - int err; struct iphdr *user_iph = (struct iphdr *)v->payload; + struct sk_buff *nskb; if (v->data_len < sizeof(*user_iph)) return 0; @@ -296,14 +296,16 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e) if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "ip_queue: error " - "in mangle, dropping packet: %d\n", -err); - return err; + "in mangle, dropping packet\n"); + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index e869916b05f1..cc2f9afcf808 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -285,8 +285,8 @@ static int ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e) { int diff; - int err; struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload; + struct sk_buff *nskb; if (v->data_len < sizeof(*user_iph)) return 0; @@ -298,14 +298,16 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e) if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "ip6_queue: OOM " "in mangle, dropping packet\n"); - return err; + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a48b20fe9cd6..0043d3a9f87e 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -443,8 +443,8 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) static int nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e) { + struct sk_buff *nskb; int diff; - int err; diff = data_len - e->skb->len; if (diff < 0) { @@ -454,14 +454,16 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e) if (data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "nf_queue: OOM " "in mangle, dropping packet\n"); - return err; + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } From f449b3b54d2263d65a11429050765c325c9809f4 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 19 Feb 2008 17:18:20 -0800 Subject: [PATCH 446/880] [NETFILTER]: xt_u32: drop the actually unused variable from u32_match_it The int ret variable is used only to trigger the BUG_ON() after the skb_copy_bits() call, so check the call failure directly and drop the variable. Signed-off-by: Pavel Emelyanov Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_u32.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c index 9b8ed390a8e0..627e0f336d54 100644 --- a/net/netfilter/xt_u32.c +++ b/net/netfilter/xt_u32.c @@ -26,7 +26,6 @@ static bool u32_match_it(const struct xt_u32 *data, u_int32_t pos; u_int32_t val; u_int32_t at; - int ret; /* * Small example: "0 >> 28 == 4 && 8 & 0xFF0000 >> 16 = 6, 17" @@ -40,8 +39,8 @@ static bool u32_match_it(const struct xt_u32 *data, if (skb->len < 4 || pos > skb->len - 4) return false; - ret = skb_copy_bits(skb, pos, &n, sizeof(n)); - BUG_ON(ret < 0); + if (skb_copy_bits(skb, pos, &n, sizeof(n)) < 0) + BUG(); val = ntohl(n); nnums = ct->nnums; @@ -67,9 +66,9 @@ static bool u32_match_it(const struct xt_u32 *data, pos > skb->len - at - 4) return false; - ret = skb_copy_bits(skb, at + pos, &n, - sizeof(n)); - BUG_ON(ret < 0); + if (skb_copy_bits(skb, at + pos, &n, + sizeof(n)) < 0) + BUG(); val = ntohl(n); break; } From eb1197bc0e20d3ceb450883dbd181460252f0306 Mon Sep 17 00:00:00 2001 From: Joonwoo Park Date: Tue, 19 Feb 2008 17:18:47 -0800 Subject: [PATCH 447/880] [NETFILTER]: Fix incorrect use of skb_make_writable http://bugzilla.kernel.org/show_bug.cgi?id=9920 The function skb_make_writable returns true or false. Signed-off-by: Joonwoo Park Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/netfilter/ebt_dnat.c | 2 +- net/bridge/netfilter/ebt_redirect.c | 2 +- net/bridge/netfilter/ebt_snat.c | 2 +- net/ipv4/netfilter/arpt_mangle.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index e700cbf634c2..1ec671d93dda 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c @@ -20,7 +20,7 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, { const struct ebt_nat_info *info = data; - if (skb_make_writable(skb, 0)) + if (!skb_make_writable(skb, 0)) return NF_DROP; memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN); diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index bfdf2fb60b1f..bfb9f74e2116 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c @@ -21,7 +21,7 @@ static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, { const struct ebt_redirect_info *info = data; - if (skb_make_writable(skb, 0)) + if (!skb_make_writable(skb, 0)) return NF_DROP; if (hooknr != NF_BR_BROUTING) diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c index e252dabbb143..204f9965fb9e 100644 --- a/net/bridge/netfilter/ebt_snat.c +++ b/net/bridge/netfilter/ebt_snat.c @@ -22,7 +22,7 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, { const struct ebt_nat_info *info = data; - if (skb_make_writable(skb, 0)) + if (!skb_make_writable(skb, 0)) return NF_DROP; memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN); diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index 45fa4e20094a..3f4222b0a803 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c @@ -19,7 +19,7 @@ target(struct sk_buff *skb, unsigned char *arpptr; int pln, hln; - if (skb_make_writable(skb, skb->len)) + if (!skb_make_writable(skb, skb->len)) return NF_DROP; arp = arp_hdr(skb); From 651acc9893f2cd036e9485ce782d0c4cffbc27f5 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 19 Feb 2008 17:19:14 -0800 Subject: [PATCH 448/880] [NETFILTER]: Make sure xt_policy.h is unifdef'ed. Since the header file xt_policy.h tests __KERNEL__, it should be unifdef'ed before exporting to userspace. Signed-off-by: Robert P. J. Day Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/Kbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild index 91fef0cae42f..3aff513d12c8 100644 --- a/include/linux/netfilter/Kbuild +++ b/include/linux/netfilter/Kbuild @@ -30,7 +30,6 @@ header-y += xt_mark.h header-y += xt_multiport.h header-y += xt_owner.h header-y += xt_pkttype.h -header-y += xt_policy.h header-y += xt_rateest.h header-y += xt_realm.h header-y += xt_sctp.h @@ -47,3 +46,4 @@ unifdef-y += nfnetlink.h unifdef-y += nfnetlink_compat.h unifdef-y += x_tables.h unifdef-y += xt_physdev.h +unifdef-y += xt_policy.h From 7d9904c2604ce091c97c225b5e2f92f3e7cc2e3a Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 19 Feb 2008 17:19:44 -0800 Subject: [PATCH 449/880] [NETFILTER]: xt_hashlimit: remove unneeded struct member By allocating ->hinfo, we already have the needed indirection to cope with the per-cpu xtables struct match_entry. [Patrick: do this now before the revision 1 struct is used by userspace] Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/xt_hashlimit.h | 1 - net/netfilter/xt_hashlimit.c | 3 --- 2 files changed, 4 deletions(-) diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h index 58b818ee41ca..51b18d83b477 100644 --- a/include/linux/netfilter/xt_hashlimit.h +++ b/include/linux/netfilter/xt_hashlimit.h @@ -61,7 +61,6 @@ struct xt_hashlimit_mtinfo1 { /* Used internally by the kernel */ struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); - struct xt_hashlimit_mtinfo1 *master __attribute__((aligned(8))); }; #endif /*_XT_HASHLIMIT_H*/ diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 744c7f2ab0b1..5418ce59ac3a 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -774,9 +774,6 @@ hashlimit_mt_check(const char *tablename, const void *inf, return false; } mutex_unlock(&hlimit_mutex); - - /* Ugly hack: For SMP, we only want to use one set */ - info->master = info; return true; } From 27ecb1ff0afa2260e6856c05efd6fedcd0cc76b9 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 19 Feb 2008 17:20:06 -0800 Subject: [PATCH 450/880] [NETFILTER]: xt_iprange: fix subtraction-based comparison The host address parts need to be converted to host-endian first before arithmetic makes any sense on them. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_iprange.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c index 4f984dc60319..500528d60cd7 100644 --- a/net/netfilter/xt_iprange.c +++ b/net/netfilter/xt_iprange.c @@ -102,7 +102,7 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b) int r; for (i = 0; i < 4; ++i) { - r = (__force u32)a->s6_addr32[i] - (__force u32)b->s6_addr32[i]; + r = ntohl(a->s6_addr32[i]) - ntohl(b->s6_addr32[i]); if (r != 0) return r; } From 7b33ed22194d8f0dbcf682f5cdf5b9c2ef551e7c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 19 Feb 2008 17:20:33 -0800 Subject: [PATCH 451/880] [NETFILTER]: Use __u32 in struct nf_inet_addr As reported by David Woodhouse , using u_int32_t in struct nf_inet_addr breaks the busybox build. Fix by using __u32. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index d74e79bacd2d..b74b615492e8 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -51,7 +51,7 @@ enum nf_inet_hooks { }; union nf_inet_addr { - u_int32_t all[4]; + __u32 all[4]; __be32 ip; __be32 ip6[4]; struct in_addr in; From 66200ea2228da6aaf317d21e67b1157aae7168e7 Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Fri, 15 Feb 2008 21:59:17 +1100 Subject: [PATCH 452/880] [POWERPC] Kill sparse warnings in kprobes Fix sparse warnings in powerpc kprobes: CHECK arch/powerpc/kernel/kprobes.c arch/powerpc/kernel/kprobes.c:277:6: warning: symbol 'kretprobe_trampoline_holder' was not declared. Should it be static? arch/powerpc/kernel/kprobes.c:287:15: warning: symbol 'trampoline_probe_handler' was not declared. Should it be static? arch/powerpc/kernel/kprobes.c:525:16: warning: symbol 'jprobe_return_end' was not declared. Should it be static? Fix along the same lines as http://lkml.org/lkml/2008/2/13/642 Signed-off-by: Ananth N Mavinakayanahalli Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/kprobes.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 5338e4855712..c176c513566b 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -274,7 +274,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) * - When the probed function returns, this probe * causes the handlers to fire */ -void kretprobe_trampoline_holder(void) +static void __used kretprobe_trampoline_holder(void) { asm volatile(".global kretprobe_trampoline\n" "kretprobe_trampoline:\n" @@ -284,7 +284,8 @@ void kretprobe_trampoline_holder(void) /* * Called when the probe at kretprobe trampoline is hit */ -int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) +static int __kprobes trampoline_probe_handler(struct kprobe *p, + struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; struct hlist_head *head, empty_rp; @@ -517,12 +518,12 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) return 1; } -void __kprobes jprobe_return(void) +void __used __kprobes jprobe_return(void) { asm volatile("trap" ::: "memory"); } -void __kprobes jprobe_return_end(void) +static void __used __kprobes jprobe_return_end(void) { }; From abe768858a54e96f0b2c0585db397107ed1bd213 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Sat, 16 Feb 2008 05:17:14 +1100 Subject: [PATCH 453/880] [POWERPC] Fix dt_mem_next_cell() to read the full address dt_mem_next_cell() currently does of_read_ulong(). This does not allow for the case where #size-cells and/or #address-cells = 2 on a 32-bit system, as it will end up reading 32 bits instead of the expected 64. Change it to use of_read_number instead and always return a u64. Signed-off-by: Becky Bruce Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 8b5efbce8d90..eac97f48b9b8 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -865,12 +865,12 @@ static int __init early_init_dt_scan_root(unsigned long node, return 1; } -static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) +static u64 __init dt_mem_next_cell(int s, cell_t **cellp) { cell_t *p = *cellp; *cellp = p + s; - return of_read_ulong(p, s); + return of_read_number(p, s); } #ifdef CONFIG_PPC_PSERIES @@ -883,8 +883,8 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) static int __init early_init_dt_scan_drconf_memory(unsigned long node) { cell_t *dm, *ls; - unsigned long l, n; - unsigned long base, size, lmb_size, flags; + unsigned long l, n, flags; + u64 base, size, lmb_size; ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l); if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t)) @@ -959,14 +959,15 @@ static int __init early_init_dt_scan_memory(unsigned long node, uname, l, reg[0], reg[1], reg[2], reg[3]); while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { - unsigned long base, size; + u64 base, size; base = dt_mem_next_cell(dt_root_addr_cells, ®); size = dt_mem_next_cell(dt_root_size_cells, ®); if (size == 0) continue; - DBG(" - %lx , %lx\n", base, size); + DBG(" - %llx , %llx\n", (unsigned long long)base, + (unsigned long long)size); #ifdef CONFIG_PPC64 if (iommu_is_off) { if (base >= 0x80000000ul) From bf2e70ac654060bcb2a06bbcb62701ba2451d79d Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 19 Feb 2008 13:52:48 +1100 Subject: [PATCH 454/880] [POWERPC] Fix bootwrapper builds with older gcc versions GCC versions before 3.4 did not support the -mcpu=440 option. Use -mcpu=405 for the 4xx specific bootwrapper files, as that has been around for much longer. Signed-off-by: Josh Boyer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 63d07ccbb9db..e3993a607584 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -35,10 +35,10 @@ endif BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt -$(obj)/4xx.o: BOOTCFLAGS += -mcpu=440 -$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440 -$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440 -$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440 +$(obj)/4xx.o: BOOTCFLAGS += -mcpu=405 +$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405 +$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 +$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 From 3d5d27c40fb38a51eae96a55f51b5a306ed3668d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 20 Feb 2008 11:27:04 +1100 Subject: [PATCH 455/880] [POWERPC] Fix warning in pseries/power.c Introduced by commit 79393fc46ede43451a500a132e5de9856f5a4c83 ("kobject: convert pseries/power.c to kobj_attr interface"). sys_create_file takes a "struct attrbute *" not a "struct kobj_addribute *". arch/powerpc/platforms/pseries/power.c: In function 'apo_pm_init': arch/powerpc/platforms/pseries/power.c:78: warning: passing argument 2 of 'sysfs_create_file' from incompatible pointer type Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c index e95fc1594c84..6d6266236446 100644 --- a/arch/powerpc/platforms/pseries/power.c +++ b/arch/powerpc/platforms/pseries/power.c @@ -75,7 +75,7 @@ core_initcall(pm_init); #else static int __init apo_pm_init(void) { - return (sysfs_create_file(power_kobj, &auto_poweron_attr)); + return (sysfs_create_file(power_kobj, &auto_poweron_attr.attr)); } __initcall(apo_pm_init); #endif From 61b36fc1f7d511132b1dd1422c29c7a8f26d77db Mon Sep 17 00:00:00 2001 From: Andre Detsch Date: Tue, 19 Feb 2008 10:06:15 -0300 Subject: [PATCH 456/880] [POWERPC] cell: fix spurious false return from spu_trap_data_{map,seg} At present, the __spufs_trap_data_map and __spu_trap_data_seq functions exit if spu->flags has the SPU_CONTEXT_SWITCH_ACTIVE set. This was resulting in suprious returns from these functions, as they may be legitimately called when we have this bit set. We only use it in these two sanity checks, so this change removes the flag completely. This fixes hangs in the page-fault path of SPE apps. Signed-off-by: Andre Detsch Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spu_base.c | 12 ------------ arch/powerpc/platforms/cell/spufs/switch.c | 6 +++--- include/asm-powerpc/spu.h | 3 +-- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index e45cfa84911f..87eb07f94c5f 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -160,13 +160,6 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) pr_debug("%s\n", __FUNCTION__); - if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) { - /* SLBs are pre-loaded for context switch, so - * we should never get here! - */ - printk("%s: invalid access during switch!\n", __func__); - return 1; - } slb.esid = (ea & ESID_MASK) | SLB_ESID_V; switch(REGION_ID(ea)) { @@ -226,11 +219,6 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) return 0; } - if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) { - printk("%s: invalid access during switch!\n", __func__); - return 1; - } - spu->class_0_pending = 0; spu->dar = ea; spu->dsisr = dsisr; diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 6063c88c26d2..6f5886c7b1f9 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -720,8 +720,9 @@ static inline void set_switch_active(struct spu_state *csa, struct spu *spu) * Restore, Step 23. * Change the software context switch pending flag * to context switch active. + * + * This implementation does not uses a switch active flag. */ - set_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags); clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); mb(); } @@ -1739,9 +1740,8 @@ static inline void reset_switch_active(struct spu_state *csa, struct spu *spu) { /* Restore, Step 74: * Reset the "context switch active" flag. + * Not performed by this implementation. */ - clear_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags); - mb(); } static inline void reenable_interrupts(struct spu_state *csa, struct spu *spu) diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index f07c99ba5d13..e3c845b0f764 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h @@ -98,9 +98,8 @@ #define MFC_PRIV_ATTN_EVENT 0x00000800 #define MFC_MULTI_SRC_EVENT 0x00001000 -/* Flags indicating progress during context switch. */ +/* Flag indicating progress during context switch. */ #define SPU_CONTEXT_SWITCH_PENDING 0UL -#define SPU_CONTEXT_SWITCH_ACTIVE 1UL struct spu_context; struct spu_runqueue; From c3c25240312d92a088a9981b620e876e960313f8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Feb 2008 20:39:18 -0800 Subject: [PATCH 457/880] [SPARC64]: Fix sparse warnings wrt. machine_alt_power_off(). arch/sparc64/kernel/process.c:123:6: warning: symbol 'machine_alt_power_off' was not declared. Should it be static? Signed-off-by: David S. Miller --- arch/sparc64/kernel/power.c | 3 +-- arch/sparc64/kernel/process.c | 1 + include/asm-sparc64/reboot.h | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 include/asm-sparc64/reboot.h diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 850cdffdd69c..eae8ca2a6ba5 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -39,8 +40,6 @@ static irqreturn_t power_handler(int irq, void *dev_id) return IRQ_HANDLED; } -extern void machine_halt(void); -extern void machine_alt_power_off(void); static void (*poweroff_method)(void) = machine_alt_power_off; void machine_power_off(void) diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 6eceac51ae62..75c1408a664f 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -47,6 +47,7 @@ #include #include #include +#include /* #define VERBOSE_SHOWREGS */ diff --git a/include/asm-sparc64/reboot.h b/include/asm-sparc64/reboot.h new file mode 100644 index 000000000000..3f3f43f5be5e --- /dev/null +++ b/include/asm-sparc64/reboot.h @@ -0,0 +1,6 @@ +#ifndef _SPARC64_REBOOT_H +#define _SPARC64_REBOOT_H + +extern void machine_alt_power_off(void); + +#endif /* _SPARC64_REBOOT_H */ From 5bbdb48d4c90f860861036978618ee1c7cec9d38 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Feb 2008 20:42:11 -0800 Subject: [PATCH 458/880] [SPARC64]: Kill show_stackframe{,32}(). Noticed via sparse: arch/sparc64/kernel/process.c:215:6: warning: symbol 'show_stackframe' was not declared. Should it be static? arch/sparc64/kernel/process.c:243:6: warning: symbol 'show_stackframe32' was not declared. Should it be static? It is totally unused. Signed-off-by: David S. Miller --- arch/sparc64/kernel/process.c | 56 ----------------------------------- 1 file changed, 56 deletions(-) diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 75c1408a664f..548af5d1f2c4 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -212,62 +212,6 @@ static void show_regwindow(struct pt_regs *regs) print_symbol("I7: <%s>\n", rwk->ins[7]); } -void show_stackframe(struct sparc_stackf *sf) -{ - unsigned long size; - unsigned long *stk; - int i; - - printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n" - "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n", - sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3], - sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]); - printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n" - "i4: %016lx i5: %016lx fp: %016lx ret_pc: %016lx\n", - sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3], - sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc); - printk("sp: %016lx x0: %016lx x1: %016lx x2: %016lx\n" - "x3: %016lx x4: %016lx x5: %016lx xx: %016lx\n", - (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1], - sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5], - sf->xxargs[0]); - size = ((unsigned long)sf->fp) - ((unsigned long)sf); - size -= STACKFRAME_SZ; - stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ); - i = 0; - do { - printk("s%d: %016lx\n", i++, *stk++); - } while ((size -= sizeof(unsigned long))); -} - -void show_stackframe32(struct sparc_stackf32 *sf) -{ - unsigned long size; - unsigned *stk; - int i; - - printk("l0: %08x l1: %08x l2: %08x l3: %08x\n", - sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3]); - printk("l4: %08x l5: %08x l6: %08x l7: %08x\n", - sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]); - printk("i0: %08x i1: %08x i2: %08x i3: %08x\n", - sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3]); - printk("i4: %08x i5: %08x fp: %08x ret_pc: %08x\n", - sf->ins[4], sf->ins[5], sf->fp, sf->callers_pc); - printk("sp: %08x x0: %08x x1: %08x x2: %08x\n" - "x3: %08x x4: %08x x5: %08x xx: %08x\n", - sf->structptr, sf->xargs[0], sf->xargs[1], - sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5], - sf->xxargs[0]); - size = ((unsigned long)sf->fp) - ((unsigned long)sf); - size -= STACKFRAME32_SZ; - stk = (unsigned *)((unsigned long)sf + STACKFRAME32_SZ); - i = 0; - do { - printk("s%d: %08x\n", i++, *stk++); - } while ((size -= sizeof(unsigned))); -} - #ifdef CONFIG_SMP static DEFINE_SPINLOCK(regdump_lock); #endif From 3ac1da338bea2f50c24f3c0cc54881e2b432e379 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Feb 2008 20:48:58 -0800 Subject: [PATCH 459/880] [SPARC64]: Fix sparse warnings wrt. __show_regs(). arch/sparc64/kernel/process.c:219:6: warning: symbol '__show_regs' was not declared. Should it be static? Signed-off-by: David S. Miller --- arch/sparc64/kernel/kprobes.c | 2 -- arch/sparc64/kernel/traps.c | 2 -- include/asm-sparc64/ptrace.h | 1 + 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index 34fc3ddd5002..f43b5d755354 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -465,8 +465,6 @@ void __kprobes jprobe_return(void) extern void jprobe_return_trap_instruction(void); -extern void __show_regs(struct pt_regs * regs); - int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) { u32 *addr = (u32 *) regs->tpc; diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 2b6abf633343..007f5317c0de 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1791,8 +1791,6 @@ static const char *sun4v_err_type_to_str(u32 type) }; } -extern void __show_regs(struct pt_regs * regs); - static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) { int cnt; diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h index 67341cff2e6b..6da197803efc 100644 --- a/include/asm-sparc64/ptrace.h +++ b/include/asm-sparc64/ptrace.h @@ -109,6 +109,7 @@ extern unsigned long profile_pc(struct pt_regs *); #define profile_pc(regs) instruction_pointer(regs) #endif extern void show_regs(struct pt_regs *); +extern void __show_regs(struct pt_regs *); #endif #else /* __ASSEMBLY__ */ From 02947ecb0de7a011215568263fd48f3d5b0f8573 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Feb 2008 21:18:08 -0800 Subject: [PATCH 460/880] [SPARC64]: Kill show_regs32(). Unused, noticed via sparse. Signed-off-by: David S. Miller --- arch/sparc64/kernel/process.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 548af5d1f2c4..6c00f1e5c92e 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -299,24 +299,6 @@ void show_regs(struct pt_regs *regs) #endif } -void show_regs32(struct pt_regs32 *regs) -{ - printk("PSR: %08x PC: %08x NPC: %08x Y: %08x %s\n", regs->psr, - regs->pc, regs->npc, regs->y, print_tainted()); - printk("g0: %08x g1: %08x g2: %08x g3: %08x ", - regs->u_regs[0], regs->u_regs[1], regs->u_regs[2], - regs->u_regs[3]); - printk("g4: %08x g5: %08x g6: %08x g7: %08x\n", - regs->u_regs[4], regs->u_regs[5], regs->u_regs[6], - regs->u_regs[7]); - printk("o0: %08x o1: %08x o2: %08x o3: %08x ", - regs->u_regs[8], regs->u_regs[9], regs->u_regs[10], - regs->u_regs[11]); - printk("o4: %08x o5: %08x sp: %08x ret_pc: %08x\n", - regs->u_regs[12], regs->u_regs[13], regs->u_regs[14], - regs->u_regs[15]); -} - unsigned long thread_saved_pc(struct task_struct *tsk) { struct thread_info *ti = task_thread_info(tsk); From 6ca94a13392363d75126029ca7d936825bb16f4e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Feb 2008 21:18:51 -0800 Subject: [PATCH 461/880] [SPARC64]: Fix sparse warning wrt. fault_in_user_windows. arch/sparc64/kernel/process.c:467:6: warning: symbol 'fault_in_user_windows' was not declared. Should it be static? Signed-off-by: David S. Miller --- include/asm-sparc64/system.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index 1faefa6d3708..ed91a5d8d4f0 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -117,6 +117,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ extern void sun_do_break(void); extern int stop_a_enabled; +extern void fault_in_user_windows(void); extern void synchronize_user_stack(void); extern void __flushw_user(void); From b1422401f2491ecb7579c8d241e1f924b35e6b67 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 19 Feb 2008 21:25:50 -0800 Subject: [PATCH 462/880] [SPARC64]: More sparse warning fixes in process.c arch/sparc64/kernel/process.c:504:17: warning: symbol 'sparc_do_fork' was not declared. Should it be static? arch/sparc64/kernel/process.c:655:5: warning: symbol 'dump_fpu' was not declared. Should it be static? arch/sparc64/kernel/process.c:708:16: warning: symbol 'sparc_execve' was not declared. Should it be static? Signed-off-by: David S. Miller --- arch/sparc64/kernel/process.c | 2 ++ include/asm-sparc64/syscalls.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 include/asm-sparc64/syscalls.h diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 6c00f1e5c92e..2aafce7dfc0e 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include /* #define VERBOSE_SHOWREGS */ diff --git a/include/asm-sparc64/syscalls.h b/include/asm-sparc64/syscalls.h new file mode 100644 index 000000000000..45a43f637a14 --- /dev/null +++ b/include/asm-sparc64/syscalls.h @@ -0,0 +1,13 @@ +#ifndef _SPARC64_SYSCALLS_H +#define _SPARC64_SYSCALLS_H + +struct pt_regs; + +extern asmlinkage long sparc_do_fork(unsigned long clone_flags, + unsigned long stack_start, + struct pt_regs *regs, + unsigned long stack_size); + +extern asmlinkage int sparc_execve(struct pt_regs *regs); + +#endif /* _SPARC64_SYSCALLS_H */ From fa907895b7b776208a1406efe5ba7ffe0f49f507 Mon Sep 17 00:00:00 2001 From: Matheos Worku Date: Wed, 20 Feb 2008 00:18:09 -0800 Subject: [PATCH 463/880] [NIU]: More BMAC alt MAC address fixes. From: Matheos Worku 1) niu_enable_alt_mac() needs to be adjusted so that the mask is computed properly for the BMAC case. 2) BMAC has 6 alt MAC addresses available, not 7. Signed-off-by: David S. Miller --- drivers/net/niu.c | 9 +++++---- drivers/net/niu.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index e98ce1e4965b..d11ba61baa4f 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -1616,12 +1616,13 @@ static int niu_enable_alt_mac(struct niu *np, int index, int on) if (index >= niu_num_alt_addr(np)) return -EINVAL; - if (np->flags & NIU_FLAGS_XMAC) + if (np->flags & NIU_FLAGS_XMAC) { reg = XMAC_ADDR_CMPEN; - else + mask = 1 << index; + } else { reg = BMAC_ADDR_CMPEN; - - mask = 1 << index; + mask = 1 << (index + 1); + } val = nr64_mac(reg); if (on) diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 0e8626adc573..59dc05fcd371 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -499,7 +499,7 @@ #define BMAC_ADDR2 0x00110UL #define BMAC_ADDR2_ADDR2 0x000000000000ffffULL -#define BMAC_NUM_ALT_ADDR 7 +#define BMAC_NUM_ALT_ADDR 6 #define BMAC_ALT_ADDR0(NUM) (0x00118UL + (NUM)*0x18UL) #define BMAC_ALT_ADDR0_ADDR0 0x000000000000ffffULL From c15853f2c1c9baaa27bbc494cd183be96f6d9bb9 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 20 Feb 2008 00:21:47 -0800 Subject: [PATCH 464/880] veth: fix dev refcount race When deleting the veth driver, veth_close calls netif_carrier_off for the two extremities of the network device. netif_carrier_off on the peer device will fire an event and hold a reference on the peer device. Just after, the peer is unregistered taking the rtnl_lock while the linkwatch_event is scheduled. If __linkwatch_run_queue does not occurs before the unregistering, unregister_netdevice will wait for the dev refcount to reach zero holding the rtnl_lock and linkwatch_event will wait for the rtnl_lock and hold the dev refcount. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- drivers/net/veth.c | 53 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 3f67a29593bc..e2ad98bee6e7 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -244,18 +244,6 @@ static int veth_open(struct net_device *dev) return 0; } -static int veth_close(struct net_device *dev) -{ - struct veth_priv *priv; - - if (netif_carrier_ok(dev)) { - priv = netdev_priv(dev); - netif_carrier_off(dev); - netif_carrier_off(priv->peer); - } - return 0; -} - static int veth_dev_init(struct net_device *dev) { struct veth_net_stats *stats; @@ -286,13 +274,50 @@ static void veth_setup(struct net_device *dev) dev->hard_start_xmit = veth_xmit; dev->get_stats = veth_get_stats; dev->open = veth_open; - dev->stop = veth_close; dev->ethtool_ops = &veth_ethtool_ops; dev->features |= NETIF_F_LLTX; dev->init = veth_dev_init; dev->destructor = veth_dev_free; } +static void veth_change_state(struct net_device *dev) +{ + struct net_device *peer; + struct veth_priv *priv; + + priv = netdev_priv(dev); + peer = priv->peer; + + if (netif_carrier_ok(peer)) { + if (!netif_carrier_ok(dev)) + netif_carrier_on(dev); + } else { + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); + } +} + +static int veth_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + + if (dev->open != veth_open) + goto out; + + switch (event) { + case NETDEV_CHANGE: + veth_change_state(dev); + break; + } +out: + return NOTIFY_DONE; +} + +static struct notifier_block veth_notifier_block __read_mostly = { + .notifier_call = veth_device_event, +}; + /* * netlink interface */ @@ -454,12 +479,14 @@ static struct rtnl_link_ops veth_link_ops = { static __init int veth_init(void) { + register_netdevice_notifier(&veth_notifier_block); return rtnl_link_register(&veth_link_ops); } static __exit void veth_exit(void) { rtnl_link_unregister(&veth_link_ops); + unregister_netdevice_notifier(&veth_notifier_block); } module_init(veth_init); From 5f31886ff03ef68dc078c585fa3a2af9a011a8fa Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 20 Feb 2008 00:23:01 -0800 Subject: [PATCH 465/880] [SCTP]: Pick up an orphaned sctp_sockets_allocated counter. This counter is currently write-only. Drawing an analogy with the similar tcp counter, I think that this one should be pointed by the sockets_allocated members of sctp_prot and sctpv6_prot. Signed-off-by: Pavel Emelyanov Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/socket.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d47d5787e2e5..44797ad88a05 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -6488,6 +6488,7 @@ struct proto sctp_prot = { .memory_pressure = &sctp_memory_pressure, .enter_memory_pressure = sctp_enter_memory_pressure, .memory_allocated = &sctp_memory_allocated, + .sockets_allocated = &sctp_sockets_allocated, REF_PROTO_INUSE(sctp) }; @@ -6521,6 +6522,7 @@ struct proto sctpv6_prot = { .memory_pressure = &sctp_memory_pressure, .enter_memory_pressure = sctp_enter_memory_pressure, .memory_allocated = &sctp_memory_allocated, + .sockets_allocated = &sctp_sockets_allocated, REF_PROTO_INUSE(sctpv6) }; #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ From da12f7356da1dfb97f1c6c418f828b7ce442fef9 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Wed, 20 Feb 2008 00:26:16 -0800 Subject: [PATCH 466/880] [NETNS]: Namespace leak in pneigh_lookup. release_net is missed on the error path in pneigh_lookup. Signed-off-by: Denis V. Lunev Signed-off-by: David S. Miller --- net/core/neighbour.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index a16cf1ec5e5e..4062b88bfc1b 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -507,6 +507,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, if (tbl->pconstructor && tbl->pconstructor(n)) { if (dev) dev_put(dev); + release_net(net); kfree(n); n = NULL; goto out; From cb616dd5bb6ddadf3e0607696b18055065ce4c3d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 14 Feb 2008 09:36:32 -0800 Subject: [PATCH 467/880] ata: fix sparse warnings in pata_legacy.c Use ld_qdi and ld_winbond to avoid shadowing static int variables qdi and winbond. The ld_ prefix refers to legacy_data. drivers/ata/pata_legacy.c:777:21: warning: symbol 'qdi' shadows an earlier one drivers/ata/pata_legacy.c:128:12: originally declared here drivers/ata/pata_legacy.c:811:21: warning: symbol 'qdi' shadows an earlier one drivers/ata/pata_legacy.c:128:12: originally declared here drivers/ata/pata_legacy.c:848:21: warning: symbol 'qdi' shadows an earlier one drivers/ata/pata_legacy.c:128:12: originally declared here drivers/ata/pata_legacy.c:882:21: warning: symbol 'qdi' shadows an earlier one drivers/ata/pata_legacy.c:128:12: originally declared here drivers/ata/pata_legacy.c:1040:21: warning: symbol 'winbond' shadows an earlier one drivers/ata/pata_legacy.c:129:12: originally declared here Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/ata/pata_legacy.c | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index d2177f75078a..50fe08ebe23c 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -774,14 +774,14 @@ static struct ata_port_operations opti82c46x_port_ops = { static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) { struct ata_timing t; - struct legacy_data *qdi = ap->host->private_data; + struct legacy_data *ld_qdi = ap->host->private_data; int active, recovery; u8 timing; /* Get the timing data in cycles */ ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); - if (qdi->fast) { + if (ld_qdi->fast) { active = 8 - FIT(t.active, 1, 8); recovery = 18 - FIT(t.recover, 3, 18); } else { @@ -790,9 +790,9 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) } timing = (recovery << 4) | active | 0x08; - qdi->clock[adev->devno] = timing; + ld_qdi->clock[adev->devno] = timing; - outb(timing, qdi->timing); + outb(timing, ld_qdi->timing); } /** @@ -808,14 +808,14 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) { struct ata_timing t; - struct legacy_data *qdi = ap->host->private_data; + struct legacy_data *ld_qdi = ap->host->private_data; int active, recovery; u8 timing; /* Get the timing data in cycles */ ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); - if (qdi->fast) { + if (ld_qdi->fast) { active = 8 - FIT(t.active, 1, 8); recovery = 18 - FIT(t.recover, 3, 18); } else { @@ -824,12 +824,12 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) } timing = (recovery << 4) | active | 0x08; - qdi->clock[adev->devno] = timing; + ld_qdi->clock[adev->devno] = timing; - outb(timing, qdi->timing + 2 * ap->port_no); + outb(timing, ld_qdi->timing + 2 * ap->port_no); /* Clear the FIFO */ if (adev->class != ATA_DEV_ATA) - outb(0x5F, qdi->timing + 3); + outb(0x5F, ld_qdi->timing + 3); } /** @@ -845,14 +845,14 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) { struct ata_timing t; - struct legacy_data *qdi = ap->host->private_data; + struct legacy_data *ld_qdi = ap->host->private_data; int active, recovery; u8 timing; /* Get the timing data in cycles */ ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); - if (qdi->fast) { + if (ld_qdi->fast) { active = 8 - FIT(t.active, 1, 8); recovery = 18 - FIT(t.recover, 3, 18); } else { @@ -860,11 +860,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) recovery = 15 - FIT(t.recover, 0, 15); } timing = (recovery << 4) | active | 0x08; - qdi->clock[adev->devno] = timing; - outb(timing, qdi->timing + 2 * adev->devno); + ld_qdi->clock[adev->devno] = timing; + outb(timing, ld_qdi->timing + 2 * adev->devno); /* Clear the FIFO */ if (adev->class != ATA_DEV_ATA) - outb(0x5F, qdi->timing + 3); + outb(0x5F, ld_qdi->timing + 3); } /** @@ -879,12 +879,12 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ata_device *adev = qc->dev; - struct legacy_data *qdi = ap->host->private_data; + struct legacy_data *ld_qdi = ap->host->private_data; - if (qdi->clock[adev->devno] != qdi->last) { + if (ld_qdi->clock[adev->devno] != ld_qdi->last) { if (adev->pio_mode) { - qdi->last = qdi->clock[adev->devno]; - outb(qdi->clock[adev->devno], qdi->timing + + ld_qdi->last = ld_qdi->clock[adev->devno]; + outb(ld_qdi->clock[adev->devno], ld_qdi->timing + 2 * ap->port_no); } } @@ -1037,12 +1037,12 @@ static u8 winbond_readcfg(unsigned long port, u8 reg) static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) { struct ata_timing t; - struct legacy_data *winbond = ap->host->private_data; + struct legacy_data *ld_winbond = ap->host->private_data; int active, recovery; u8 reg; int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2); - reg = winbond_readcfg(winbond->timing, 0x81); + reg = winbond_readcfg(ld_winbond->timing, 0x81); /* Get the timing data in cycles */ if (reg & 0x40) /* Fast VLB bus, assume 50MHz */ @@ -1053,7 +1053,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) active = (FIT(t.active, 3, 17) - 1) & 0x0F; recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; timing = (active << 4) | recovery; - winbond_writecfg(winbond->timing, timing, reg); + winbond_writecfg(ld_winbond->timing, timing, reg); /* Load the setup timing */ @@ -1063,7 +1063,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) if (!ata_pio_need_iordy(adev)) reg |= 0x02; /* IORDY off */ reg |= (FIT(t.setup, 0, 3) << 6); - winbond_writecfg(winbond->timing, timing + 1, reg); + winbond_writecfg(ld_winbond->timing, timing + 1, reg); } static int winbond_port(struct platform_device *dev, From 2e7e1214defe7783c8187962bacdd0a87a7dbeee Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Sat, 16 Feb 2008 18:15:27 +0100 Subject: [PATCH 468/880] sata_mv: Define module alias for platform device The sata_mv driver can be loaded as a platform device, as is done by various Orion (ARM) based devices. The driver needs to define a module alias for the platform driver so udev will load it automatically. Tested with Debian on a QNAP TS-209. Signed-off-by: Martin Michlmayr Acked-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 1c1fbf375d9a..0c0057e76a67 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3194,6 +3194,7 @@ MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, mv_pci_tbl); MODULE_VERSION(DRV_VERSION); +MODULE_ALIAS("platform:sata_mv"); #ifdef CONFIG_PCI module_param(msi, int, 0444); From 0fca0d6f2ce3336022a22bc7fc2e009e599e63a4 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Wed, 13 Feb 2008 10:09:09 -1100 Subject: [PATCH 469/880] sata_mv: use hpriv->base instead of the host->iomap this fixes crash bug as the iomap table is not valid for integrated controllers. Signed-off-by: Saeed Bishara Acked-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 0c0057e76a67..eb97dde28d47 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -870,7 +870,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, struct mv_host_priv *hpriv = ap->host->private_data; int hard_port = mv_hardport_from_port(ap->port_no); void __iomem *hc_mmio = mv_hc_base_from_port( - ap->host->iomap[MV_PRIMARY_BAR], hard_port); + mv_host_base(ap->host), hard_port); u32 hc_irq_cause, ipending; /* clear EDMA event indicators, if any */ From 332673257056d8be8a69d759eda90a799af5472d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 13 Feb 2008 09:15:09 +0900 Subject: [PATCH 470/880] libata: implement libata.force module parameter This patch implements libata.force module parameter which can selectively override ATA port, link and device configurations including cable type, SATA PHY SPD limit, transfer mode and NCQ. For example, you can say "use 1.5Gbps for all fan-out ports attached to the second port but allow 3.0Gbps for the PMP device itself, oh, the device attached to the third fan-out port chokes on NCQ and shouldn't go over UDMA4" by the following. libata.force=2:1.5g,2.15:3.0g,2.03:noncq,udma4 Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- Documentation/kernel-parameters.txt | 35 +++ drivers/ata/libata-core.c | 380 +++++++++++++++++++++++++++- drivers/ata/libata-eh.c | 8 +- drivers/ata/libata.h | 1 + 4 files changed, 420 insertions(+), 4 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 7278295f94d2..9a5b6658c65e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -950,6 +950,41 @@ and is between 256 and 4096 characters. It is defined in the file when set. Format: + libata.force= [LIBATA] Force configurations. The format is comma + separated list of "[ID:]VAL" where ID is + PORT[:DEVICE]. PORT and DEVICE are decimal numbers + matching port, link or device. Basically, it matches + the ATA ID string printed on console by libata. If + the whole ID part is omitted, the last PORT and DEVICE + values are used. If ID hasn't been specified yet, the + configuration applies to all ports, links and devices. + + If only DEVICE is omitted, the parameter applies to + the port and all links and devices behind it. DEVICE + number of 0 either selects the first device or the + first fan-out link behind PMP device. It does not + select the host link. DEVICE number of 15 selects the + host link and device attached to it. + + The VAL specifies the configuration to force. As long + as there's no ambiguity shortcut notation is allowed. + For example, both 1.5 and 1.5G would work for 1.5Gbps. + The following configurations can be forced. + + * Cable type: 40c, 80c, short40c, unk, ign or sata. + Any ID with matching PORT is used. + + * SATA link speed limit: 1.5Gbps or 3.0Gbps. + + * Transfer mode: pio[0-7], mwdma[0-4] and udma[0-7]. + udma[/][16,25,33,44,66,100,133] notation is also + allowed. + + * [no]ncq: Turn on or off NCQ. + + If there are multiple matching configurations changing + the same attribute, the last one is used. + load_ramdisk= [RAM] List of ramdisks to load from floppy See Documentation/ramdisk.txt. diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index def3682f416a..60d1bb556973 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -87,6 +87,28 @@ static struct workqueue_struct *ata_wq; struct workqueue_struct *ata_aux_wq; +struct ata_force_param { + const char *name; + unsigned int cbl; + int spd_limit; + unsigned long xfer_mask; + unsigned int horkage_on; + unsigned int horkage_off; +}; + +struct ata_force_ent { + int port; + int device; + struct ata_force_param param; +}; + +static struct ata_force_ent *ata_force_tbl; +static int ata_force_tbl_size; + +static char ata_force_param_buf[PAGE_SIZE] __initdata; +module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0444); +MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)"); + int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); @@ -129,6 +151,179 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +/** + * ata_force_cbl - force cable type according to libata.force + * @link: ATA link of interest + * + * Force cable type according to libata.force and whine about it. + * The last entry which has matching port number is used, so it + * can be specified as part of device force parameters. For + * example, both "a:40c,1.00:udma4" and "1.00:40c,udma4" have the + * same effect. + * + * LOCKING: + * EH context. + */ +void ata_force_cbl(struct ata_port *ap) +{ + int i; + + for (i = ata_force_tbl_size - 1; i >= 0; i--) { + const struct ata_force_ent *fe = &ata_force_tbl[i]; + + if (fe->port != -1 && fe->port != ap->print_id) + continue; + + if (fe->param.cbl == ATA_CBL_NONE) + continue; + + ap->cbl = fe->param.cbl; + ata_port_printk(ap, KERN_NOTICE, + "FORCE: cable set to %s\n", fe->param.name); + return; + } +} + +/** + * ata_force_spd_limit - force SATA spd limit according to libata.force + * @link: ATA link of interest + * + * Force SATA spd limit according to libata.force and whine about + * it. When only the port part is specified (e.g. 1:), the limit + * applies to all links connected to both the host link and all + * fan-out ports connected via PMP. If the device part is + * specified as 0 (e.g. 1.00:), it specifies the first fan-out + * link not the host link. Device number 15 always points to the + * host link whether PMP is attached or not. + * + * LOCKING: + * EH context. + */ +static void ata_force_spd_limit(struct ata_link *link) +{ + int linkno, i; + + if (ata_is_host_link(link)) + linkno = 15; + else + linkno = link->pmp; + + for (i = ata_force_tbl_size - 1; i >= 0; i--) { + const struct ata_force_ent *fe = &ata_force_tbl[i]; + + if (fe->port != -1 && fe->port != link->ap->print_id) + continue; + + if (fe->device != -1 && fe->device != linkno) + continue; + + if (!fe->param.spd_limit) + continue; + + link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1; + ata_link_printk(link, KERN_NOTICE, + "FORCE: PHY spd limit set to %s\n", fe->param.name); + return; + } +} + +/** + * ata_force_xfermask - force xfermask according to libata.force + * @dev: ATA device of interest + * + * Force xfer_mask according to libata.force and whine about it. + * For consistency with link selection, device number 15 selects + * the first device connected to the host link. + * + * LOCKING: + * EH context. + */ +static void ata_force_xfermask(struct ata_device *dev) +{ + int devno = dev->link->pmp + dev->devno; + int alt_devno = devno; + int i; + + /* allow n.15 for the first device attached to host port */ + if (ata_is_host_link(dev->link) && devno == 0) + alt_devno = 15; + + for (i = ata_force_tbl_size - 1; i >= 0; i--) { + const struct ata_force_ent *fe = &ata_force_tbl[i]; + unsigned long pio_mask, mwdma_mask, udma_mask; + + if (fe->port != -1 && fe->port != dev->link->ap->print_id) + continue; + + if (fe->device != -1 && fe->device != devno && + fe->device != alt_devno) + continue; + + if (!fe->param.xfer_mask) + continue; + + ata_unpack_xfermask(fe->param.xfer_mask, + &pio_mask, &mwdma_mask, &udma_mask); + if (udma_mask) + dev->udma_mask = udma_mask; + else if (mwdma_mask) { + dev->udma_mask = 0; + dev->mwdma_mask = mwdma_mask; + } else { + dev->udma_mask = 0; + dev->mwdma_mask = 0; + dev->pio_mask = pio_mask; + } + + ata_dev_printk(dev, KERN_NOTICE, + "FORCE: xfer_mask set to %s\n", fe->param.name); + return; + } +} + +/** + * ata_force_horkage - force horkage according to libata.force + * @dev: ATA device of interest + * + * Force horkage according to libata.force and whine about it. + * For consistency with link selection, device number 15 selects + * the first device connected to the host link. + * + * LOCKING: + * EH context. + */ +static void ata_force_horkage(struct ata_device *dev) +{ + int devno = dev->link->pmp + dev->devno; + int alt_devno = devno; + int i; + + /* allow n.15 for the first device attached to host port */ + if (ata_is_host_link(dev->link) && devno == 0) + alt_devno = 15; + + for (i = 0; i < ata_force_tbl_size; i++) { + const struct ata_force_ent *fe = &ata_force_tbl[i]; + + if (fe->port != -1 && fe->port != dev->link->ap->print_id) + continue; + + if (fe->device != -1 && fe->device != devno && + fe->device != alt_devno) + continue; + + if (!(~dev->horkage & fe->param.horkage_on) && + !(dev->horkage & fe->param.horkage_off)) + continue; + + dev->horkage |= fe->param.horkage_on; + dev->horkage &= ~fe->param.horkage_off; + + ata_dev_printk(dev, KERN_NOTICE, + "FORCE: horkage modified (%s)\n", fe->param.name); + } +} + /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert @@ -2067,6 +2262,7 @@ int ata_dev_configure(struct ata_device *dev) /* set horkage */ dev->horkage |= ata_dev_blacklisted(dev); + ata_force_horkage(dev); /* let ACPI work its magic */ rc = ata_acpi_on_devcfg(dev); @@ -3150,6 +3346,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) mode_mask = ATA_DMA_MASK_CFA; ata_dev_xfermask(dev); + ata_force_xfermask(dev); pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0); dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); @@ -6497,7 +6694,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp) */ int sata_link_init_spd(struct ata_link *link) { - u32 scontrol, spd; + u32 scontrol; + u8 spd; int rc; rc = sata_scr_read(link, SCR_CONTROL, &scontrol); @@ -6508,6 +6706,8 @@ int sata_link_init_spd(struct ata_link *link) if (spd) link->hw_sata_spd_limit &= (1 << spd) - 1; + ata_force_spd_limit(link); + link->sata_spd_limit = link->hw_sata_spd_limit; return 0; @@ -7218,10 +7418,187 @@ int ata_pci_device_resume(struct pci_dev *pdev) #endif /* CONFIG_PCI */ +static int __init ata_parse_force_one(char **cur, + struct ata_force_ent *force_ent, + const char **reason) +{ + /* FIXME: Currently, there's no way to tag init const data and + * using __initdata causes build failure on some versions of + * gcc. Once __initdataconst is implemented, add const to the + * following structure. + */ + static struct ata_force_param force_tbl[] __initdata = { + { "40c", .cbl = ATA_CBL_PATA40 }, + { "80c", .cbl = ATA_CBL_PATA80 }, + { "short40c", .cbl = ATA_CBL_PATA40_SHORT }, + { "unk", .cbl = ATA_CBL_PATA_UNK }, + { "ign", .cbl = ATA_CBL_PATA_IGN }, + { "sata", .cbl = ATA_CBL_SATA }, + { "1.5Gbps", .spd_limit = 1 }, + { "3.0Gbps", .spd_limit = 2 }, + { "noncq", .horkage_on = ATA_HORKAGE_NONCQ }, + { "ncq", .horkage_off = ATA_HORKAGE_NONCQ }, + { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) }, + { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) }, + { "pio2", .xfer_mask = 1 << (ATA_SHIFT_PIO + 2) }, + { "pio3", .xfer_mask = 1 << (ATA_SHIFT_PIO + 3) }, + { "pio4", .xfer_mask = 1 << (ATA_SHIFT_PIO + 4) }, + { "pio5", .xfer_mask = 1 << (ATA_SHIFT_PIO + 5) }, + { "pio6", .xfer_mask = 1 << (ATA_SHIFT_PIO + 6) }, + { "mwdma0", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 0) }, + { "mwdma1", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 1) }, + { "mwdma2", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 2) }, + { "mwdma3", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 3) }, + { "mwdma4", .xfer_mask = 1 << (ATA_SHIFT_MWDMA + 4) }, + { "udma0", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) }, + { "udma16", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) }, + { "udma/16", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 0) }, + { "udma1", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) }, + { "udma25", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) }, + { "udma/25", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 1) }, + { "udma2", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) }, + { "udma33", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) }, + { "udma/33", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 2) }, + { "udma3", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) }, + { "udma44", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) }, + { "udma/44", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 3) }, + { "udma4", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) }, + { "udma66", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) }, + { "udma/66", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 4) }, + { "udma5", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) }, + { "udma100", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) }, + { "udma/100", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 5) }, + { "udma6", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) }, + { "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) }, + { "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) }, + { "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) }, + }; + char *start = *cur, *p = *cur; + char *id, *val, *endp; + const struct ata_force_param *match_fp = NULL; + int nr_matches = 0, i; + + /* find where this param ends and update *cur */ + while (*p != '\0' && *p != ',') + p++; + + if (*p == '\0') + *cur = p; + else + *cur = p + 1; + + *p = '\0'; + + /* parse */ + p = strchr(start, ':'); + if (!p) { + val = strstrip(start); + goto parse_val; + } + *p = '\0'; + + id = strstrip(start); + val = strstrip(p + 1); + + /* parse id */ + p = strchr(id, '.'); + if (p) { + *p++ = '\0'; + force_ent->device = simple_strtoul(p, &endp, 10); + if (p == endp || *endp != '\0') { + *reason = "invalid device"; + return -EINVAL; + } + } + + force_ent->port = simple_strtoul(id, &endp, 10); + if (p == endp || *endp != '\0') { + *reason = "invalid port/link"; + return -EINVAL; + } + + parse_val: + /* parse val, allow shortcuts so that both 1.5 and 1.5Gbps work */ + for (i = 0; i < ARRAY_SIZE(force_tbl); i++) { + const struct ata_force_param *fp = &force_tbl[i]; + + if (strncasecmp(val, fp->name, strlen(val))) + continue; + + nr_matches++; + match_fp = fp; + + if (strcasecmp(val, fp->name) == 0) { + nr_matches = 1; + break; + } + } + + if (!nr_matches) { + *reason = "unknown value"; + return -EINVAL; + } + if (nr_matches > 1) { + *reason = "ambigious value"; + return -EINVAL; + } + + force_ent->param = *match_fp; + + return 0; +} + +static void __init ata_parse_force_param(void) +{ + int idx = 0, size = 1; + int last_port = -1, last_device = -1; + char *p, *cur, *next; + + /* calculate maximum number of params and allocate force_tbl */ + for (p = ata_force_param_buf; *p; p++) + if (*p == ',') + size++; + + ata_force_tbl = kzalloc(sizeof(ata_force_tbl[0]) * size, GFP_KERNEL); + if (!ata_force_tbl) { + printk(KERN_WARNING "ata: failed to extend force table, " + "libata.force ignored\n"); + return; + } + + /* parse and populate the table */ + for (cur = ata_force_param_buf; *cur != '\0'; cur = next) { + const char *reason = ""; + struct ata_force_ent te = { .port = -1, .device = -1 }; + + next = cur; + if (ata_parse_force_one(&next, &te, &reason)) { + printk(KERN_WARNING "ata: failed to parse force " + "parameter \"%s\" (%s)\n", + cur, reason); + continue; + } + + if (te.port == -1) { + te.port = last_port; + te.device = last_device; + } + + ata_force_tbl[idx++] = te; + + last_port = te.port; + last_device = te.device; + } + + ata_force_tbl_size = idx; +} static int __init ata_init(void) { ata_probe_timeout *= HZ; + + ata_parse_force_param(); + ata_wq = create_workqueue("ata"); if (!ata_wq) return -ENOMEM; @@ -7238,6 +7615,7 @@ static int __init ata_init(void) static void __exit ata_exit(void) { + kfree(ata_force_tbl); destroy_workqueue(ata_wq); destroy_workqueue(ata_aux_wq); } diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 4e31071acc02..698ce2cea52c 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2393,9 +2393,11 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, } /* PDIAG- should have been released, ask cable type if post-reset */ - if (ata_is_host_link(link) && ap->ops->cable_detect && - (ehc->i.flags & ATA_EHI_DID_RESET)) - ap->cbl = ap->ops->cable_detect(ap); + if ((ehc->i.flags & ATA_EHI_DID_RESET) && ata_is_host_link(link)) { + if (ap->ops->cable_detect) + ap->cbl = ap->ops->cable_detect(ap); + ata_force_cbl(ap); + } /* Configure new devices forward such that user doesn't see * device detection messages backwards. diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 409ffb9af163..6036dedfe377 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -61,6 +61,7 @@ extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; extern int libata_allow_tpm; +extern void ata_force_cbl(struct ata_port *ap); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, u64 block, u32 n_block, unsigned int tf_flags, From 5d44b414daa8c1d8551aed6130d86d54175db43f Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 15 Feb 2008 13:41:32 -0800 Subject: [PATCH 471/880] ata: fix sparse warning in libata.h Avoids lots of these, also is more readable. include/linux/libata.h:1210:13: warning: potentially expensive pointer subtraction Change the subtraction to addition on the other side of the comparison. Thanks to Christer Weinigel for the suggestion. Signed-off-by: Harvey Harrison Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/libata.h b/include/linux/libata.h index 2e098f940cec..ce7603a73156 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1197,7 +1197,7 @@ static inline struct ata_link *ata_port_next_link(struct ata_link *link) return ap->pmp_link; } - if (++link - ap->pmp_link < ap->nr_pmp_links) + if (++link < ap->nr_pmp_links + ap->pmp_link) return link; return NULL; } From f1cb0ea12fee23018ad1865bf789cbd463f13747 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Mon, 18 Feb 2008 07:42:28 -1100 Subject: [PATCH 472/880] sata_mv: remove iounmap in mv_platform_remove and use devm_iomap this will fix crash bug when doing rmmod to the driver, this is because the port_stop function get called later and it could access the device's registers. Signed-off-by: Saeed Bishara Acked-by: Mark Lord Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index eb97dde28d47..6ebebde8454a 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2947,7 +2947,8 @@ static int mv_platform_probe(struct platform_device *pdev) hpriv->n_ports = n_ports; host->iomap = NULL; - hpriv->base = ioremap(res->start, res->end - res->start + 1); + hpriv->base = devm_ioremap(&pdev->dev, res->start, + res->end - res->start + 1); hpriv->base -= MV_SATAHC0_REG_BASE; rc = mv_create_dma_pools(hpriv, &pdev->dev); @@ -2979,11 +2980,8 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ata_host *host = dev_get_drvdata(dev); - struct mv_host_priv *hpriv = host->private_data; - void __iomem *base = hpriv->base; ata_host_detach(host); - iounmap(base); return 0; } From 73fd8b6d310196ae878767200786503fcff57bd5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 19 Feb 2008 13:43:21 -0800 Subject: [PATCH 473/880] libata: fix kernel-doc parameter warning Fix libata kernel-doc parameter: Warning(linux-2.6.25-rc2-git3//drivers/ata/libata-scsi.c:845): No description found for parameter 'rq' Signed-off-by: Randy Dunlap Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index dd41b1a1b304..f888babc8283 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -828,7 +828,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) /** * atapi_drain_needed - Check whether data transfer may overflow - * @request: request to be checked + * @rq: request to be checked * * ATAPI commands which transfer variable length data to host * might overflow due to application error or hardare bug. This From 1227a74e2e0217a4ca155d1677bdbf5f69e32bed Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 19 Feb 2008 12:51:35 -0500 Subject: [PATCH 474/880] NFS: flush signals before taking down callback thread Now that the reference counting on the callback thread is working as expected, it uncovers another problem. Peter Staubach noticed while testing that patch on an older kernel that he would occasionally see this printk in rpc_register fire: "RPC: failed to contact portmap (errno -512). The NFSv4 callback thread is signaled by nfs_callback_down(), but never flushes that signal. All of the shutdown processing is done with that signal pending. This makes it fail the call to unregister the port with the portmapper. In actuality, this rpc_register call isn't necessary at all since the port isn't actually registered with the portmapper anymore. Regardless, there doesn't seem to be any reason to leave the signal pending while the thread is being shut down and flushing it should generally silence that printk. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/callback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index ecc06c619494..0d784f6f609f 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -93,6 +93,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp) svc_process(rqstp); } + flush_signals(current); svc_exit_thread(rqstp); nfs_callback_info.pid = 0; complete(&nfs_callback_info.stopped); From 90dc7d2796edf94a9eaa838321a9734c8513e717 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 20 Feb 2008 13:03:05 -0800 Subject: [PATCH 475/880] nfs: fix sparse warnings fs/nfs/nfs4state.c:788:34: warning: Using plain integer as NULL pointer fs/nfs/delegation.c:52:34: warning: Using plain integer as NULL pointer fs/nfs/idmap.c:312:12: warning: Using plain integer as NULL pointer fs/nfs/callback_xdr.c:257:6: warning: Using plain integer as NULL pointer fs/nfs/callback_xdr.c:270:6: warning: Using plain integer as NULL pointer fs/nfs/callback_xdr.c:281:6: warning: Using plain integer as NULL pointer Signed-off-by: Harvey Harrison Signed-off-by: Trond Myklebust --- fs/nfs/callback_xdr.c | 6 +++--- fs/nfs/delegation.c | 2 +- fs/nfs/idmap.c | 2 +- fs/nfs/nfs4state.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index c63eb720b68b..13619d24f023 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -254,7 +254,7 @@ static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) return 0; p = xdr_reserve_space(xdr, 8); - if (unlikely(p == 0)) + if (unlikely(!p)) return htonl(NFS4ERR_RESOURCE); p = xdr_encode_hyper(p, change); return 0; @@ -267,7 +267,7 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u if (!(bitmap[0] & FATTR4_WORD0_SIZE)) return 0; p = xdr_reserve_space(xdr, 8); - if (unlikely(p == 0)) + if (unlikely(!p)) return htonl(NFS4ERR_RESOURCE); p = xdr_encode_hyper(p, size); return 0; @@ -278,7 +278,7 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti __be32 *p; p = xdr_reserve_space(xdr, 12); - if (unlikely(p == 0)) + if (unlikely(!p)) return htonl(NFS4ERR_RESOURCE); p = xdr_encode_hyper(p, time->tv_sec); *p = htonl(time->tv_nsec); diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index b9eadd18ba70..00a5e4405e16 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -49,7 +49,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ struct file_lock *fl; int status; - for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { + for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) continue; if (nfs_file_open_context(fl->fl_file) != ctx) diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 8ae5dba2d4e5..86147b0ab2cf 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -309,7 +309,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, mutex_lock(&idmap->idmap_im_lock); he = idmap_lookup_id(h, id); - if (he != 0) { + if (he) { memcpy(name, he->ih_name, he->ih_namelen); ret = he->ih_namelen; goto out; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6233eb5e98c1..b962397004c1 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -785,7 +785,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s struct file_lock *fl; int status = 0; - for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { + for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) continue; if (nfs_file_open_context(fl->fl_file)->state != state) From 1a17582e64dcc690a7edcd7dcf6fe89f1aa0ef97 Mon Sep 17 00:00:00 2001 From: Ivo Couckuyt Date: Wed, 20 Feb 2008 14:58:00 -0500 Subject: [PATCH 476/880] p54usb: add USB ID for Phillips CPWUA054 Retarget of an old patch against prism54usb in linux-wireless archive: http://marc.info/?l=linux-wireless&m=117449935810254&w=2 Cc: Ivo Couckuyt Signed-off-by: John W. Linville --- drivers/net/wireless/p54usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c index 60d286eb0b8b..f8695665c0ce 100644 --- a/drivers/net/wireless/p54usb.c +++ b/drivers/net/wireless/p54usb.c @@ -35,6 +35,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */ + {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */ {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */ {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ From 387e100ac24a6c8f2b6f4ce572098447d2893008 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 20 Feb 2008 15:06:02 -0500 Subject: [PATCH 477/880] p54usb: add USB ID for Linksys WUSB54G ver 2 Based on report from Cavan Carroll : http://bugzilla.kernel.org/show_bug.cgi?id=9863 Cc: Cavan Carroll Signed-off-by: John W. Linville --- drivers/net/wireless/p54usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c index f8695665c0ce..e7d4aee8799e 100644 --- a/drivers/net/wireless/p54usb.c +++ b/drivers/net/wireless/p54usb.c @@ -63,6 +63,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ + {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ From 65872e6b434ca463123f7d03b530f143aabc6333 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 15 Feb 2008 21:58:51 +0100 Subject: [PATCH 478/880] WDEV: ath5k, fix lock imbalance Omitted lock causes sparse warning drivers/net/wireless/ath5k/base.c:1682:1: warning: context imbalance in 'ath5k_tasklet_rx' - different lock contexts for basic block Add the lock to the guilty fail path. Signed-off-by: Jiri Slaby Acked-by: Nick Kossifidis Cc: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index dfdaec020739..062d004076a2 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1715,6 +1715,7 @@ ath5k_tasklet_rx(unsigned long data) break; else if (unlikely(ret)) { ATH5K_ERR(sc, "error in processing rx descriptor\n"); + spin_unlock(&sc->rxbuflock); return; } From b988763857426020e50a19434c8434a1e08e70eb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 15 Feb 2008 21:58:52 +0100 Subject: [PATCH 479/880] WDEV, ath5k, don't return int from bool function sparse sees int -> bool cast as an error: hw.c:3754:10: warning: cast truncates bits from constant value (ffffffea becomes 0) Fix it by converting the rettype to int and check appropriately. Signed-off-by: Jiri Slaby Cc: Nick Kossifidis Cc: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath5k/base.c | 5 ++++- drivers/net/wireless/ath5k/hw.c | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index c79066b38d3b..69dea3392612 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h @@ -1035,7 +1035,7 @@ struct ath5k_hw { unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); - bool (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, + int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *); diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 062d004076a2..81b45b3e0f02 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -668,7 +668,10 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) * return false w/o doing anything. MAC's that do * support it will return true w/o doing anything. */ - if (ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0)) + ret = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); + if (ret < 0) + goto err; + if (ret > 0) __set_bit(ATH_STAT_MRRETRY, sc->status); /* diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 1ab57aa6e4dc..c2de2d958e8e 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c @@ -45,7 +45,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -static bool ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *, +static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *); @@ -3743,7 +3743,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* * Initialize a 4-word multirate tx descriptor on 5212 */ -static bool +static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) @@ -3783,10 +3783,10 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, #undef _XTX_TRIES - return true; + return 1; } - return false; + return 0; } /* From 04f93a87a2db84e7214a4ec56fccd2289e973ce5 Mon Sep 17 00:00:00 2001 From: David Miller Date: Fri, 15 Feb 2008 16:08:59 -0800 Subject: [PATCH 480/880] ath5k: Fix build warnings on some 64-bit platforms. 'u64' is not necessarily 'unsigned long long' drivers/net/wireless/ath5k/base.c: In function 'ath5k_beacon_update_timers': drivers/net/wireless/ath5k/base.c:2130: warning: format '%llx' expects type 'long long unsigned int', but argument 4 has type 'u64' drivers/net/wireless/ath5k/base.c:2130: warning: format '%llx' expects type 'long long unsigned int', but argument 5 has type 'u64' drivers/net/wireless/ath5k/base.c: In function 'ath5k_intr': drivers/net/wireless/ath5k/base.c:2391: warning: format '%llx' expects type 'long long unsigned int', but argument 6 has type 'u64' Signed-off-by: David S. Miller Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 81b45b3e0f02..bef967ce34a6 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -2130,8 +2130,9 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) "updated timers based on beacon TSF\n"); ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, - "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n", - bc_tsf, hw_tsf, bc_tu, hw_tu, nexttbtt); + "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n", + (unsigned long long) bc_tsf, + (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt); ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n", intval & AR5K_BEACON_PERIOD, intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "", @@ -2389,10 +2390,11 @@ ath5k_intr(int irq, void *dev_id) u64 tsf = ath5k_hw_get_tsf64(ah); sc->nexttbtt += sc->bintval; ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, - "SWBA nexttbtt: %x hw_tu: %x " - "TSF: %llx\n", - sc->nexttbtt, - TSF_TO_TU(tsf), tsf); + "SWBA nexttbtt: %x hw_tu: %x " + "TSF: %llx\n", + sc->nexttbtt, + TSF_TO_TU(tsf), + (unsigned long long) tsf); } else { ath5k_beacon_send(sc); } From 58ff70d4feae29cbb7ace410fa6585ef3afb44b6 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 18 Feb 2008 21:44:39 +0100 Subject: [PATCH 481/880] ssb: Fix serial console on new bcm47xx devices This fixes the baud settings for new devices like the Linksys WRT350n. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 36 +++++++++++++++++++---- include/linux/ssb/ssb_driver_chipcommon.h | 3 ++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 6fbf1c53b6f2..7cc03f2dd5a6 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -376,6 +376,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, unsigned int irq; u32 baud_base, div; u32 i, n; + unsigned int ccrev = cc->dev->id.revision; plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT); irq = ssb_mips_irq(cc->dev); @@ -387,14 +388,39 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, chipco_read32(cc, SSB_CHIPCO_CLOCK_M2)); div = 1; } else { - if (cc->dev->id.revision >= 11) { + if (ccrev == 20) { + /* BCM5354 uses constant 25MHz clock */ + baud_base = 25000000; + div = 48; + /* Set the override bit so we don't divide it */ + chipco_write32(cc, SSB_CHIPCO_CORECTL, + chipco_read32(cc, SSB_CHIPCO_CORECTL) + | SSB_CHIPCO_CORECTL_UARTCLK0); + } else if ((ccrev >= 11) && (ccrev != 15)) { /* Fixed ALP clock */ baud_base = 20000000; + if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { + /* FIXME: baud_base is different for devices with a PMU */ + SSB_WARN_ON(1); + } div = 1; + if (ccrev >= 21) { + /* Turn off UART clock before switching clocksource. */ + chipco_write32(cc, SSB_CHIPCO_CORECTL, + chipco_read32(cc, SSB_CHIPCO_CORECTL) + & ~SSB_CHIPCO_CORECTL_UARTCLKEN); + } /* Set the override bit so we don't divide it */ chipco_write32(cc, SSB_CHIPCO_CORECTL, - SSB_CHIPCO_CORECTL_UARTCLK0); - } else if (cc->dev->id.revision >= 3) { + chipco_read32(cc, SSB_CHIPCO_CORECTL) + | SSB_CHIPCO_CORECTL_UARTCLK0); + if (ccrev >= 21) { + /* Re-enable the UART clock. */ + chipco_write32(cc, SSB_CHIPCO_CORECTL, + chipco_read32(cc, SSB_CHIPCO_CORECTL) + | SSB_CHIPCO_CORECTL_UARTCLKEN); + } + } else if (ccrev >= 3) { /* Internal backplane clock */ baud_base = ssb_clockspeed(bus); div = chipco_read32(cc, SSB_CHIPCO_CLKDIV) @@ -406,7 +432,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, } /* Clock source depends on strapping if UartClkOverride is unset */ - if ((cc->dev->id.revision > 0) && + if ((ccrev > 0) && !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) { if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) == SSB_CHIPCO_CAP_UARTCLK_INT) { @@ -428,7 +454,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE); uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA; /* Offset changed at after rev 0 */ - if (cc->dev->id.revision == 0) + if (ccrev == 0) uart_regs += (i * 8); else uart_regs += (i * 256); diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 4cb995494662..35717b400cef 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h @@ -51,9 +51,12 @@ #define SSB_CHIPCO_CAP_JTAGM 0x00400000 /* JTAG master present */ #define SSB_CHIPCO_CAP_BROM 0x00800000 /* Internal boot ROM active */ #define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */ +#define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */ +#define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */ #define SSB_CHIPCO_CORECTL 0x0008 #define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ #define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ +#define SSB_CHIPCO_CORECTL_UARTCLKEN 0x00000008 /* UART clock enable (rev >= 21) */ #define SSB_CHIPCO_BIST 0x000C #define SSB_CHIPCO_OTPS 0x0010 /* OTP status */ #define SSB_CHIPCO_OTPS_PROGFAIL 0x80000000 From 42bfad4f71637c4eb4791aa8062063c4a8526522 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 12:41:30 +0100 Subject: [PATCH 482/880] ssb: Fix watchdog access for devices without a chipcommon This fixes the SSB watchdog access for devices without a chipcommon. These devices have the watchdog on the extif. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/Kconfig | 6 ++++++ drivers/ssb/Makefile | 1 + drivers/ssb/driver_extif.c | 6 ++++++ drivers/ssb/embedded.c | 26 +++++++++++++++++++++++ include/linux/ssb/ssb_driver_chipcommon.h | 5 +++++ include/linux/ssb/ssb_driver_extif.h | 9 ++++++++ include/linux/ssb/ssb_embedded.h | 10 +++++++++ 7 files changed, 63 insertions(+) create mode 100644 drivers/ssb/embedded.c create mode 100644 include/linux/ssb/ssb_embedded.h diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index d976660cb7f0..78fd33125e02 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig @@ -105,6 +105,12 @@ config SSB_DRIVER_MIPS If unsure, say N +# Assumption: We are on embedded, if we compile the MIPS core. +config SSB_EMBEDDED + bool + depends on SSB_DRIVER_MIPS + default y + config SSB_DRIVER_EXTIF bool "SSB Broadcom EXTIF core driver (EXPERIMENTAL)" depends on SSB_DRIVER_MIPS && EXPERIMENTAL diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile index 7be397595805..e235144add7c 100644 --- a/drivers/ssb/Makefile +++ b/drivers/ssb/Makefile @@ -1,5 +1,6 @@ # core ssb-y += main.o scan.o +ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o # host support ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c index fe55eb8b038a..b1899f422a54 100644 --- a/drivers/ssb/driver_extif.c +++ b/drivers/ssb/driver_extif.c @@ -110,6 +110,12 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif, *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB); } +void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, + u32 ticks) +{ + extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); +} + u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) { return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c new file mode 100644 index 000000000000..751f58ac612c --- /dev/null +++ b/drivers/ssb/embedded.c @@ -0,0 +1,26 @@ +/* + * Sonics Silicon Backplane + * Embedded systems support code + * + * Copyright 2005-2008, Broadcom Corporation + * Copyright 2006-2008, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include + + +int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) +{ + if (ssb_chipco_available(&bus->chipco)) { + ssb_chipco_watchdog_timer_set(&bus->chipco, ticks); + return 0; + } + if (ssb_extif_available(&bus->extif)) { + ssb_extif_watchdog_timer_set(&bus->extif, ticks); + return 0; + } + return -ENODEV; +} diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 35717b400cef..89638153cbe1 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h @@ -360,6 +360,11 @@ struct ssb_chipcommon { u16 fast_pwrup_delay; }; +static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) +{ + return (cc->dev != NULL); +} + extern void ssb_chipcommon_init(struct ssb_chipcommon *cc); #include diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h index a9164357b5ae..0d7c9bfa965d 100644 --- a/include/linux/ssb/ssb_driver_extif.h +++ b/include/linux/ssb/ssb_driver_extif.h @@ -171,6 +171,9 @@ extern void ssb_extif_get_clockcontrol(struct ssb_extif *extif, extern void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns); +extern void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, + u32 ticks); + u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask); void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value); @@ -200,5 +203,11 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif, { } +static inline +void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, + u32 ticks) +{ +} + #endif /* CONFIG_SSB_DRIVER_EXTIF */ #endif /* LINUX_SSB_EXTIFCORE_H_ */ diff --git a/include/linux/ssb/ssb_embedded.h b/include/linux/ssb/ssb_embedded.h new file mode 100644 index 000000000000..80bd58496450 --- /dev/null +++ b/include/linux/ssb/ssb_embedded.h @@ -0,0 +1,10 @@ +#ifndef LINUX_SSB_EMBEDDED_H_ +#define LINUX_SSB_EMBEDDED_H_ + +#include +#include + + +extern int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks); + +#endif /* LINUX_SSB_EMBEDDED_H_ */ From c2bcbe65fc88d61f9a806367ff6eab76c9eabb3a Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 14:53:35 +0100 Subject: [PATCH 483/880] ssb: Fix the GPIO API This fixes the GPIO API to be usable. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 35 +++++++++++++++++++---- drivers/ssb/driver_extif.c | 24 +++++++++++++--- include/linux/ssb/ssb_driver_chipcommon.h | 10 ++++--- include/linux/ssb/ssb_driver_extif.h | 9 +++--- 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 7cc03f2dd5a6..7ea0c0faa9ab 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -39,12 +39,14 @@ static inline void chipco_write32(struct ssb_chipcommon *cc, ssb_write32(cc->dev, offset, value); } -static inline void chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset, - u32 mask, u32 value) +static inline u32 chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset, + u32 mask, u32 value) { value &= mask; value |= chipco_read32(cc, offset) & ~mask; chipco_write32(cc, offset, value); + + return value; } void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, @@ -355,16 +357,37 @@ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) { return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; } +EXPORT_SYMBOL(ssb_chipco_gpio_in); + +u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); +} +EXPORT_SYMBOL(ssb_chipco_gpio_out); + +u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); +} +EXPORT_SYMBOL(ssb_chipco_gpio_outen); + +u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); +} +EXPORT_SYMBOL(ssb_chipco_gpio_control); -void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) +u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) { - chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); } +EXPORT_SYMBOL(ssb_chipco_gpio_intmask); -void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) +u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) { - chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); } +EXPORT_SYMBOL(ssb_chipco_gpio_polarity); #ifdef CONFIG_SSB_SERIAL int ssb_chipco_serial_init(struct ssb_chipcommon *cc, diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c index b1899f422a54..10c6b287f8bb 100644 --- a/drivers/ssb/driver_extif.c +++ b/drivers/ssb/driver_extif.c @@ -27,12 +27,14 @@ static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value) ssb_write32(extif->dev, offset, value); } -static inline void extif_write32_masked(struct ssb_extif *extif, u16 offset, - u32 mask, u32 value) +static inline u32 extif_write32_masked(struct ssb_extif *extif, u16 offset, + u32 mask, u32 value) { value &= mask; value |= extif_read32(extif, offset) & ~mask; extif_write32(extif, offset, value); + + return value; } #ifdef CONFIG_SSB_SERIAL @@ -120,16 +122,30 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) { return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; } +EXPORT_SYMBOL(ssb_extif_gpio_in); -void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) +u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), mask, value); } +EXPORT_SYMBOL(ssb_extif_gpio_out); -void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) +u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), mask, value); } +EXPORT_SYMBOL(ssb_extif_gpio_outen); + +u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) +{ + return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); +} +EXPORT_SYMBOL(ssb_extif_gpio_polarity); +u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) +{ + return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); +} +EXPORT_SYMBOL(ssb_extif_gpio_intmask); diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 89638153cbe1..536851b946f6 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h @@ -390,11 +390,13 @@ extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks); +/* Chipcommon GPIO pin access. */ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask); - -void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value); - -void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value); +u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value); +u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value); +u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value); +u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value); +u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value); #ifdef CONFIG_SSB_SERIAL extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc, diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h index 0d7c9bfa965d..91161f0aa22b 100644 --- a/include/linux/ssb/ssb_driver_extif.h +++ b/include/linux/ssb/ssb_driver_extif.h @@ -174,11 +174,12 @@ extern void ssb_extif_timing_init(struct ssb_extif *extif, extern void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks); +/* Extif GPIO pin access */ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask); - -void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value); - -void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value); +u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value); +u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value); +u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value); +u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value); #ifdef CONFIG_SSB_SERIAL extern int ssb_extif_serial_init(struct ssb_extif *extif, From 53521d8c90d366191b6c134f88a8ebe83de60614 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 16:22:50 +0100 Subject: [PATCH 484/880] ssb: Make the GPIO API reentrancy safe This fixes the GPIO API to be reentrancy safe. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 6 -- drivers/ssb/driver_extif.c | 5 -- drivers/ssb/embedded.c | 106 +++++++++++++++++++++++++++++++ drivers/ssb/main.c | 3 + include/linux/ssb/ssb.h | 5 ++ include/linux/ssb/ssb_embedded.h | 8 +++ 6 files changed, 122 insertions(+), 11 deletions(-) diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 7ea0c0faa9ab..e586321a473a 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -357,37 +357,31 @@ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) { return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; } -EXPORT_SYMBOL(ssb_chipco_gpio_in); u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_out); u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_outen); u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_control); u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_intmask); u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_polarity); #ifdef CONFIG_SSB_SERIAL int ssb_chipco_serial_init(struct ssb_chipcommon *cc, diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c index 10c6b287f8bb..c3e1d3e6d610 100644 --- a/drivers/ssb/driver_extif.c +++ b/drivers/ssb/driver_extif.c @@ -122,30 +122,25 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) { return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; } -EXPORT_SYMBOL(ssb_extif_gpio_in); u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_out); u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_outen); u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_polarity); u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_intmask); diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c index 751f58ac612c..d3ade821555c 100644 --- a/drivers/ssb/embedded.c +++ b/drivers/ssb/embedded.c @@ -11,6 +11,8 @@ #include #include +#include "ssb_private.h" + int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) { @@ -24,3 +26,107 @@ int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) } return -ENODEV; } + +u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_in(&bus->chipco, mask); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_in(&bus->extif, mask); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_in); + +u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_out(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_out(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_out); + +u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_outen(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_outen(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_outen); + +u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_control(&bus->chipco, mask, value); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_control); + +u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_intmask(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_intmask); + +u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_polarity(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_polarity); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 9028ed5715a1..af07ab22708f 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -569,6 +569,9 @@ static int ssb_bus_register(struct ssb_bus *bus, spin_lock_init(&bus->bar_lock); INIT_LIST_HEAD(&bus->list); +#ifdef CONFIG_SSB_EMBEDDED + spin_lock_init(&bus->gpio_lock); +#endif /* Powerup the bus */ err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 9d5da8b2ccf9..d14c03685717 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -283,6 +283,11 @@ struct ssb_bus { /* Contents of the SPROM. */ struct ssb_sprom sprom; +#ifdef CONFIG_SSB_EMBEDDED + /* Lock for GPIO register access. */ + spinlock_t gpio_lock; +#endif /* EMBEDDED */ + /* Internal-only stuff follows. Do not touch. */ struct list_head list; #ifdef CONFIG_SSB_DEBUG diff --git a/include/linux/ssb/ssb_embedded.h b/include/linux/ssb/ssb_embedded.h index 80bd58496450..8d8dedff059d 100644 --- a/include/linux/ssb/ssb_embedded.h +++ b/include/linux/ssb/ssb_embedded.h @@ -7,4 +7,12 @@ extern int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks); +/* Generic GPIO API */ +u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask); +u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value); +u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value); +u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value); +u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value); +u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value); + #endif /* LINUX_SSB_EMBEDDED_H_ */ From 7cb4461520f307a6e3fb2bb32cb8daee45aa1fae Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 17:46:48 +0100 Subject: [PATCH 485/880] ssb: Fix pcicore cardbus mode This fixes the pcicore driver to not die a horrible crash death when inserting a cardbus card. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_pcicore.c | 28 ++++++++++++++++++++++++++-- drivers/ssb/main.c | 1 + include/linux/ssb/ssb.h | 7 +++++++ include/linux/ssb/ssb_driver_pci.h | 5 +++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 2faaa906d5d6..059452fbb168 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "ssb_private.h" @@ -27,6 +28,18 @@ void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value) ssb_write32(pc->dev, offset, value); } +static inline +u16 pcicore_read16(struct ssb_pcicore *pc, u16 offset) +{ + return ssb_read16(pc->dev, offset); +} + +static inline +void pcicore_write16(struct ssb_pcicore *pc, u16 offset, u16 value) +{ + ssb_write16(pc->dev, offset, value); +} + /************************************************** * Code for hostmode operation. **************************************************/ @@ -117,8 +130,10 @@ static u32 get_cfgspace_addr(struct ssb_pcicore *pc, u32 addr = 0; u32 tmp; - if (unlikely(pc->cardbusmode && dev > 1)) + /* We do only have one cardbus device behind the bridge. */ + if (pc->cardbusmode && (dev >= 1)) goto out; + if (bus == 0) { /* Type 0 transaction */ if (unlikely(dev >= SSB_PCI_SLOT_MAX)) @@ -318,7 +333,16 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); udelay(1); /* Assertion time demanded by the PCI standard */ - /*TODO cardbus mode */ + if (pc->dev->bus->has_cardbus_slot) { + ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); + pc->cardbusmode = 1; + /* GPIO 1 resets the bridge */ + ssb_gpio_out(pc->dev->bus, 1, 1); + ssb_gpio_outen(pc->dev->bus, 1, 1); + pcicore_write16(pc, SSB_PCICORE_SPROM(0), + pcicore_read16(pc, SSB_PCICORE_SPROM(0)) + | 0x0400); + } /* 64MB I/O window */ pcicore_write32(pc, SSB_PCICORE_SBTOPCI0, diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index af07ab22708f..bedb2b4ee9d2 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -557,6 +557,7 @@ static int ssb_fetch_invariants(struct ssb_bus *bus, goto out; memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo)); memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom)); + bus->has_cardbus_slot = iv.has_cardbus_slot; out: return err; } diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index d14c03685717..20add65215af 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -282,6 +282,8 @@ struct ssb_bus { struct ssb_boardinfo boardinfo; /* Contents of the SPROM. */ struct ssb_sprom sprom; + /* If the board has a cardbus slot, this is set to true. */ + bool has_cardbus_slot; #ifdef CONFIG_SSB_EMBEDDED /* Lock for GPIO register access. */ @@ -299,8 +301,13 @@ struct ssb_bus { /* The initialization-invariants. */ struct ssb_init_invariants { + /* Versioning information about the PCB. */ struct ssb_boardinfo boardinfo; + /* The SPROM information. That's either stored in an + * EEPROM or NVRAM on the board. */ struct ssb_sprom sprom; + /* If the board has a cardbus slot, this is set to true. */ + bool has_cardbus_slot; }; /* Type of function to fetch the invariants. */ typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus, diff --git a/include/linux/ssb/ssb_driver_pci.h b/include/linux/ssb/ssb_driver_pci.h index 9cfffb7b1a27..5e25bac4ed31 100644 --- a/include/linux/ssb/ssb_driver_pci.h +++ b/include/linux/ssb/ssb_driver_pci.h @@ -51,6 +51,11 @@ #define SSB_PCICORE_SBTOPCI1_MASK 0xFC000000 #define SSB_PCICORE_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */ #define SSB_PCICORE_SBTOPCI2_MASK 0xC0000000 +#define SSB_PCICORE_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */ +#define SSB_PCICORE_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */ +#define SSB_PCICORE_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */ +#define SSB_PCICORE_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */ +#define SSB_PCICORE_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */ /* SBtoPCIx */ #define SSB_PCICORE_SBTOPCI_MEM 0x00000000 From 1955fd0b533d05828bff7ed290213d2a0fc0f04f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Feb 2008 12:05:59 +0100 Subject: [PATCH 486/880] rtl818x: fix sparse warnings This silences a few sparse warnings. There are two more where I can't follow the code. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/rtl8180_dev.c | 4 +++- drivers/net/wireless/rtl8187_dev.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index 27ebd689aa21..5e9a8ace0d81 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c @@ -135,13 +135,15 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) while (skb_queue_len(&ring->queue)) { struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; struct sk_buff *skb; - struct ieee80211_tx_status status = { {0} }; + struct ieee80211_tx_status status; struct ieee80211_tx_control *control; u32 flags = le32_to_cpu(entry->flags); if (flags & RTL8180_TX_DESC_FLAG_OWN) return; + memset(&status, 0, sizeof(status)); + ring->idx = (ring->idx + 1) % ring->entries; skb = __skb_dequeue(&ring->queue); pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 0d71716d750d..f44505994a0e 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -113,10 +113,12 @@ void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) static void rtl8187_tx_cb(struct urb *urb) { - struct ieee80211_tx_status status = { {0} }; + struct ieee80211_tx_status status; struct sk_buff *skb = (struct sk_buff *)urb->context; struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb; + memset(&status, 0, sizeof(status)); + usb_free_urb(info->urb); if (info->control) memcpy(&status.control, info->control, sizeof(status.control)); From 5078ed50712aa3df1099540b524d01075aee653f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Feb 2008 12:09:25 +0100 Subject: [PATCH 487/880] zd1211rw: fix sparse warnings This silences sparse when run on zd1211rw. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 49127e4b42c2..76ef2d83919d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -360,11 +360,14 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) { struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; struct sk_buff *skb; - struct ieee80211_tx_status status = {{0}}; + struct ieee80211_tx_status status; skb = skb_dequeue(q); if (skb == NULL) return; + + memset(&status, 0, sizeof(status)); + tx_status(hw, skb, &status, 0); } @@ -389,7 +392,8 @@ void zd_mac_tx_to_dev(struct sk_buff *skb, int error) if (unlikely(error || (cb->control->flags & IEEE80211_TXCTL_NO_ACK))) { - struct ieee80211_tx_status status = {{0}}; + struct ieee80211_tx_status status; + memset(&status, 0, sizeof(status)); tx_status(hw, skb, &status, !error); } else { struct sk_buff_head *q = @@ -603,7 +607,9 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, tx_hdr = (struct ieee80211_hdr *)skb->data; if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) { - struct ieee80211_tx_status status = {{0}}; + struct ieee80211_tx_status status; + + memset(&status, 0, sizeof(status)); status.flags = IEEE80211_TX_STATUS_ACK; status.ack_signal = stats->ssi; __skb_unlink(skb, q); From fc71acc846c577473ada72a46c5ea9c935eca086 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 16 Feb 2008 18:13:36 +0100 Subject: [PATCH 488/880] ssb: Fix support for PCI devices behind a SSB->PCI bridge We must pin all resources and make sure the PCI subsystem won't relocate us, as the addresses are hardwired into hardware. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_pcicore.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 059452fbb168..6d99a9880055 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -79,6 +79,7 @@ int pcibios_plat_dev_init(struct pci_dev *d) base = &ssb_pcicore_pcibus_iobase; else base = &ssb_pcicore_pcibus_membase; + res->flags |= IORESOURCE_PCI_FIXED; if (res->end) { size = res->end - res->start + 1; if (*base & (size - 1)) @@ -101,10 +102,12 @@ int pcibios_plat_dev_init(struct pci_dev *d) static void __init ssb_fixup_pcibridge(struct pci_dev *dev) { + u8 lat; + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) return; - ssb_printk(KERN_INFO "PCI: fixing up bridge\n"); + ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev)); /* Enable PCI bridge bus mastering and memory space */ pci_set_master(dev); @@ -114,7 +117,10 @@ static void __init ssb_fixup_pcibridge(struct pci_dev *dev) pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3); /* Make sure our latency is high enough to handle the devices behind us */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8); + lat = 168; + ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n", + pci_name(dev), lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge); @@ -294,14 +300,14 @@ static struct resource ssb_pcicore_mem_resource = { .name = "SSB PCIcore external memory", .start = SSB_PCI_DMA, .end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED, }; static struct resource ssb_pcicore_io_resource = { .name = "SSB PCIcore external I/O", .start = 0x100, .end = 0x7FF, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED, }; static struct pci_controller ssb_pcicore_controller = { @@ -368,7 +374,8 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) /* Ok, ready to run, register it to the system. * The following needs change, if we want to port hostmode * to non-MIPS platform. */ - set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000)); + ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000); + set_io_port_base(ssb_pcicore_controller.io_map_base); /* Give some time to the PCI controller to configure itself with the new * values. Not waiting at this point causes crashes of the machine. */ mdelay(10); From 1803f3389b7ac9ed33ea561b3b94e22e2864a95d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 20 Feb 2008 19:55:09 -0800 Subject: [PATCH 489/880] Remove empty file remnants that were left in the tree by mistake Noted by various people (Sam, Jeff, Roland..) Commit 58b7983d15a422d9616bdc4e245d5c31dfaefbe2 intended to remove the xfs "Makefile-linux-2.6" file, but it was mistakenly still left in the tree as a empty file, and would cause git to correctly complain about a tracked file being removed after a "make distclean" (which removes empty files as garbage). And the asm-x86/desc_64.h file was supposed to be removed by commit c81c6ca45a69478c7877b729af1942d2b80ef582, but instead stayed around containing just a single newline. Get rid of them both properly. Signed-off-by: Linus Torvalds --- fs/xfs/Makefile-linux-2.6 | 0 include/asm-x86/desc_64.h | 1 - 2 files changed, 1 deletion(-) delete mode 100644 fs/xfs/Makefile-linux-2.6 delete mode 100644 include/asm-x86/desc_64.h diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h deleted file mode 100644 index 8b137891791f..000000000000 --- a/include/asm-x86/desc_64.h +++ /dev/null @@ -1 +0,0 @@ - From 2d0e2baa25966cff9bcd0a6e8204e676c2bc54e1 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 20 Feb 2008 18:11:39 +0000 Subject: [PATCH 490/880] FRV: Drop the .data.idt section for FRV There is no .data.idt section for FRV, so drop it from the linker script. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/frv/kernel/vmlinux.lds.S | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index 17725a55aed8..b95c4eace62f 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S @@ -76,9 +76,6 @@ SECTIONS *(.data.init_task) } - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - . = ALIGN(L1_CACHE_BYTES); .data.cacheline_aligned : { *(.data.cacheline_aligned) } From e80af3a8dbbbf431b2070cc760699f01c5a6ac69 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 20 Feb 2008 18:11:44 +0000 Subject: [PATCH 491/880] FRV: Change the timerfd syscalls to be the same as i386 Change the FRV timerfd syscalls to be the same as i386 timerfd syscalls. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/frv/kernel/entry.S | 4 +++- include/asm-frv/unistd.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index ca6a345b87e4..f36d7f4a7c25 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1494,9 +1494,11 @@ sys_call_table: .long sys_epoll_pwait .long sys_utimensat /* 320 */ .long sys_signalfd - .long sys_ni_syscall + .long sys_timerfd_create .long sys_eventfd .long sys_fallocate + .long sys_timerfd_settime /* 325 */ + .long sys_timerfd_gettime syscall_table_size = (. - sys_call_table) diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h index e8c986667532..f184eb8c047c 100644 --- a/include/asm-frv/unistd.h +++ b/include/asm-frv/unistd.h @@ -328,9 +328,11 @@ #define __NR_epoll_pwait 319 #define __NR_utimensat 320 #define __NR_signalfd 321 -/* #define __NR_timerfd 322 removed */ +#define __NR_timerfd_create 322 #define __NR_eventfd 323 #define __NR_fallocate 324 +#define __NR_timerfd_settime 325 +#define __NR_timerfd_gettime 326 #ifdef __KERNEL__ From 0f7f22d9a46261e310b32c61eb11977a7cc83f7b Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 20 Feb 2008 22:22:16 -0800 Subject: [PATCH 492/880] [SPARC64]: Fix cpu trampoline et al. mismatch warnings. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc64/kernel/hvtramp.S | 4 +++- arch/sparc64/kernel/smp.c | 2 +- arch/sparc64/kernel/trampoline.S | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/sparc64/kernel/hvtramp.S b/arch/sparc64/kernel/hvtramp.S index b692e044a463..0236c43772fa 100644 --- a/arch/sparc64/kernel/hvtramp.S +++ b/arch/sparc64/kernel/hvtramp.S @@ -3,6 +3,8 @@ * Copyright (C) 2007 David S. Miller */ +#include + #include #include #include @@ -13,7 +15,7 @@ #include #include - .text + __CPUINIT .align 8 .globl hv_cpu_startup, hv_cpu_startup_end diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index a8052b76df41..cc454731d879 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -86,7 +86,7 @@ extern void setup_sparc64_timer(void); static volatile unsigned long callin_flag = 0; -void __devinit smp_callin(void) +void __cpuinit smp_callin(void) { int cpuid = hard_smp_processor_id(); diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 04e81dda13d0..4ae2e525d68b 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -4,6 +4,8 @@ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */ +#include + #include #include #include @@ -36,7 +38,7 @@ dtlb_load: tramp_stack: .skip TRAMP_STACK_SIZE - .text + __CPUINIT .align 8 .globl sparc64_cpu_startup, sparc64_cpu_startup_end sparc64_cpu_startup: From 89c94f2f70d093f59b55d3ea8042d13889169346 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 20 Feb 2008 22:56:42 -0800 Subject: [PATCH 493/880] [SPARC64]: make IOMMU code respect the segment boundary limits Signed-off-by: FUJITA Tomonori Signed-off-by: David S. Miller --- arch/sparc64/kernel/iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c index 0e347ff812a3..fbaab3497bfd 100644 --- a/arch/sparc64/kernel/iommu.c +++ b/arch/sparc64/kernel/iommu.c @@ -134,7 +134,8 @@ unsigned long iommu_range_alloc(struct device *dev, else boundary_size = ALIGN(1UL << 32, 1 << IO_PAGE_SHIFT); - n = iommu_area_alloc(arena->map, limit, start, npages, 0, + n = iommu_area_alloc(arena->map, limit, start, npages, + iommu->page_table_map_base >> IO_PAGE_SHIFT, boundary_size >> IO_PAGE_SHIFT, 0); if (n == -1) { if (likely(pass < 1)) { From 1186974f3ffe3c1796e5efce7afffefcfda9a6f0 Mon Sep 17 00:00:00 2001 From: Ming Lin Date: Thu, 21 Feb 2008 02:01:30 -0500 Subject: [PATCH 494/880] ACPI: fix build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC drivers/acpi/executer/exregion.o drivers/acpi/executer/exregion.c: In function ‘acpi_ex_pci_config_space_handler’: drivers/acpi/executer/exregion.c:369: attention : passing argument 3 of ‘acpi_os_read_pci_configuration’ from incompatible pointer type exposed by 10270d4838bdc493781f5a1cf2e90e9c34c9142f http://bugzilla.kernel.org/show_bug.cgi?id=9989 Signed-off-by: Ming Lin Signed-off-by: Len Brown --- drivers/acpi/executer/exregion.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 2e9ce94798c7..3f51b7e84a17 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c @@ -338,6 +338,7 @@ acpi_ex_pci_config_space_handler(u32 function, acpi_status status = AE_OK; struct acpi_pci_id *pci_id; u16 pci_register; + u32 value32; ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); @@ -364,9 +365,9 @@ acpi_ex_pci_config_space_handler(u32 function, switch (function) { case ACPI_READ: - *value = 0; status = acpi_os_read_pci_configuration(pci_id, pci_register, - value, bit_width); + &value32, bit_width); + *value = value32; break; case ACPI_WRITE: From 8a235efad548abd2ab5ebea45a9ffa750c814375 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 20 Feb 2008 01:47:44 +0100 Subject: [PATCH 495/880] Hibernation: Handle DEBUG_PAGEALLOC on x86 Make hibernation work with CONFIG_DEBUG_PAGEALLOC set on x86, by checking if the pages to be copied are marked as present in the kernel mapping and temporarily marking them as present if that's not the case. No functional modifications are introduced if CONFIG_DEBUG_PAGEALLOC is unset. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- arch/x86/mm/pageattr.c | 19 ++++++++++++++++++- include/linux/mm.h | 6 ++++++ kernel/power/snapshot.c | 42 ++++++++++++++++++++++++++++------------- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index e2a74ea11a53..464d8fc21ce6 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -899,7 +899,24 @@ void kernel_map_pages(struct page *page, int numpages, int enable) */ cpa_fill_pool(); } -#endif + +#ifdef CONFIG_HIBERNATION + +bool kernel_page_present(struct page *page) +{ + unsigned int level; + pte_t *pte; + + if (PageHighMem(page)) + return false; + + pte = lookup_address((unsigned long)page_address(page), &level); + return (pte_val(*pte) & _PAGE_PRESENT); +} + +#endif /* CONFIG_HIBERNATION */ + +#endif /* CONFIG_DEBUG_PAGEALLOC */ /* * The testcases use internal knowledge of the implementation that shouldn't diff --git a/include/linux/mm.h b/include/linux/mm.h index 26c7124b841a..3b3e1341163f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1171,12 +1171,18 @@ static inline void enable_debug_pagealloc(void) { debug_pagealloc_enabled = 1; } +#ifdef CONFIG_HIBERNATION +extern bool kernel_page_present(struct page *page); +#endif /* CONFIG_HIBERNATION */ #else static inline void kernel_map_pages(struct page *page, int numpages, int enable) {} static inline void enable_debug_pagealloc(void) { } +#ifdef CONFIG_HIBERNATION +static inline bool kernel_page_present(struct page *page) { return true; } +#endif /* CONFIG_HIBERNATION */ #endif extern struct vm_area_struct *get_gate_vma(struct task_struct *tsk); diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 95250d7c8d91..72a020cabb4c 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -875,8 +875,8 @@ static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } #endif /* CONFIG_HIGHMEM */ /** - * saveable - Determine whether a non-highmem page should be included in - * the suspend image. + * saveable_page - Determine whether a non-highmem page should be included + * in the suspend image. * * We should save the page if it isn't Nosave, and is not in the range * of pages statically defined as 'unsaveable', and it isn't a part of @@ -897,7 +897,8 @@ static struct page *saveable_page(unsigned long pfn) if (swsusp_page_is_forbidden(page) || swsusp_page_is_free(page)) return NULL; - if (PageReserved(page) && pfn_is_nosave(pfn)) + if (PageReserved(page) + && (!kernel_page_present(page) || pfn_is_nosave(pfn))) return NULL; return page; @@ -938,6 +939,25 @@ static inline void do_copy_page(long *dst, long *src) *dst++ = *src++; } + +/** + * safe_copy_page - check if the page we are going to copy is marked as + * present in the kernel page tables (this always is the case if + * CONFIG_DEBUG_PAGEALLOC is not set and in that case + * kernel_page_present() always returns 'true'). + */ +static void safe_copy_page(void *dst, struct page *s_page) +{ + if (kernel_page_present(s_page)) { + do_copy_page(dst, page_address(s_page)); + } else { + kernel_map_pages(s_page, 1, 1); + do_copy_page(dst, page_address(s_page)); + kernel_map_pages(s_page, 1, 0); + } +} + + #ifdef CONFIG_HIGHMEM static inline struct page * page_is_saveable(struct zone *zone, unsigned long pfn) @@ -946,8 +966,7 @@ page_is_saveable(struct zone *zone, unsigned long pfn) saveable_highmem_page(pfn) : saveable_page(pfn); } -static inline void -copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) +static void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) { struct page *s_page, *d_page; void *src, *dst; @@ -961,29 +980,26 @@ copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) kunmap_atomic(src, KM_USER0); kunmap_atomic(dst, KM_USER1); } else { - src = page_address(s_page); if (PageHighMem(d_page)) { /* Page pointed to by src may contain some kernel * data modified by kmap_atomic() */ - do_copy_page(buffer, src); + safe_copy_page(buffer, s_page); dst = kmap_atomic(pfn_to_page(dst_pfn), KM_USER0); memcpy(dst, buffer, PAGE_SIZE); kunmap_atomic(dst, KM_USER0); } else { - dst = page_address(d_page); - do_copy_page(dst, src); + safe_copy_page(page_address(d_page), s_page); } } } #else #define page_is_saveable(zone, pfn) saveable_page(pfn) -static inline void -copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) +static inline void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn) { - do_copy_page(page_address(pfn_to_page(dst_pfn)), - page_address(pfn_to_page(src_pfn))); + safe_copy_page(page_address(pfn_to_page(dst_pfn)), + pfn_to_page(src_pfn)); } #endif /* CONFIG_HIGHMEM */ From c6868ea00bdebe5762fa59e54b74b4cd4e3b4e6e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Feb 2008 22:53:31 +0100 Subject: [PATCH 496/880] PCI ACPI: Fix comment describing acpi_pci_choose_state The last line of the comment preceding the definition of acpi_pci_choose_state() is incorrect. Remove it. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Len Brown --- drivers/pci/pci-acpi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e569645d59e2..e818e52dc39a 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -241,8 +241,6 @@ EXPORT_SYMBOL(pci_osc_control_set); * choose from highest power _SxD to lowest power _SxW * else // no _PRW at S-state x * choose highest power _SxD or any lower power - * - * currently we simply return _SxD, if present. */ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev, From 19e20c913bae2dd458b9fc42afab0c53f16562d1 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 3 Feb 2008 22:55:18 +0100 Subject: [PATCH 497/880] PM: Make suspend_device() static suspend_device() can become static. Signed-off-by: Adrian Bunk Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Len Brown --- drivers/base/power/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index bdc03f7e8424..a96ca86a7b4a 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -415,7 +415,7 @@ EXPORT_SYMBOL_GPL(device_power_down); * @dev: Device. * @state: Power state device is entering. */ -int suspend_device(struct device *dev, pm_message_t state) +static int suspend_device(struct device *dev, pm_message_t state) { int error = 0; From be2553ffb5773e9a689c94bb85326c5b5f00577f Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Thu, 21 Feb 2008 13:25:54 +1100 Subject: [PATCH 498/880] [POWERPC] pasemi: Register i2c devices at boot Setup i2c_board_info based on device tree contents. This has to be a device_initcall since we need PCI to be probed by the time we run it, but before the actual driver is initialized. Signed-off-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pasemi/Makefile | 2 +- arch/powerpc/platforms/pasemi/misc.c | 97 ++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/pasemi/misc.c diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile index 8f52d7515793..ce6d789e0741 100644 --- a/arch/powerpc/platforms/pasemi/Makefile +++ b/arch/powerpc/platforms/pasemi/Makefile @@ -1,3 +1,3 @@ -obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o +obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o misc.o obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o diff --git a/arch/powerpc/platforms/pasemi/misc.c b/arch/powerpc/platforms/pasemi/misc.c new file mode 100644 index 000000000000..ded7d152d00c --- /dev/null +++ b/arch/powerpc/platforms/pasemi/misc.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2007 PA Semi, Inc + * + * Parts based on arch/powerpc/sysdev/fsl_soc.c: + * + * 2006 (c) MontaVista Software, Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_I2C_BOARDINFO +/* The below is from fsl_soc.c. It's copied because since there are no + * official bus bindings at this time it doesn't make sense to share across + * the platforms, even though they happen to be common. + */ +struct i2c_driver_device { + char *of_device; + char *i2c_driver; + char *i2c_type; +}; + +static struct i2c_driver_device i2c_devices[] __initdata = { + {"dallas,ds1338", "rtc-ds1307", "ds1338"}, +}; + +static int __init find_i2c_driver(struct device_node *node, + struct i2c_board_info *info) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { + if (!of_device_is_compatible(node, i2c_devices[i].of_device)) + continue; + if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver, + KOBJ_NAME_LEN) >= KOBJ_NAME_LEN || + strlcpy(info->type, i2c_devices[i].i2c_type, + I2C_NAME_SIZE) >= I2C_NAME_SIZE) + return -ENOMEM; + return 0; + } + return -ENODEV; +} + +static int __init pasemi_register_i2c_devices(void) +{ + struct pci_dev *pdev; + struct device_node *adap_node; + struct device_node *node; + + pdev = NULL; + while ((pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa003, pdev))) { + adap_node = pci_device_to_OF_node(pdev); + + if (!adap_node) + continue; + + node = NULL; + while ((node = of_get_next_child(adap_node, node))) { + struct i2c_board_info info = {}; + const u32 *addr; + int len; + + addr = of_get_property(node, "reg", &len); + if (!addr || len < sizeof(int) || + *addr > (1 << 10) - 1) { + printk(KERN_WARNING + "pasemi_register_i2c_devices: " + "invalid i2c device entry\n"); + continue; + } + + info.irq = irq_of_parse_and_map(node, 0); + if (info.irq == NO_IRQ) + info.irq = -1; + + if (find_i2c_driver(node, &info) < 0) + continue; + + info.addr = *addr; + + i2c_register_board_info(PCI_FUNC(pdev->devfn), &info, + 1); + } + } + return 0; +} +device_initcall(pasemi_register_i2c_devices); +#endif From 9c0338522896c54b79ad7918638175bf58d7c551 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Thu, 21 Feb 2008 13:34:43 +1100 Subject: [PATCH 499/880] [POWERPC] pasemi: Remove warning in mpic_pasemi_msi.c Remove warning: arch/powerpc/sysdev/mpic_pasemi_msi.c: In function 'pasemi_msi_setup_msi_irqs': arch/powerpc/sysdev/mpic_pasemi_msi.c:135: warning: 'addr' is used uninitialized in this function Turns out addr wasn't even used, it's a leftover from the u3msi code. Signed-off-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic_pasemi_msi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c index d6bfda30ac87..33cbfb22ce3e 100644 --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -95,7 +95,6 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) unsigned int virq; struct msi_desc *entry; struct msi_msg msg; - u64 addr; pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n", pdev, nvec, type); @@ -132,8 +131,8 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) set_irq_chip(virq, &mpic_pasemi_msi_chip); set_irq_type(virq, IRQ_TYPE_EDGE_RISING); - pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n", - virq, hwirq, addr); + pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%x\n", + virq, hwirq, msg.address_lo); /* Likewise, the device writes [0...511] into the target * register to generate MSI [512...1023] From fae603121428ba83b7343c88e68a7144525ab3eb Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 20 Feb 2008 21:10:06 +0100 Subject: [PATCH 500/880] firewire: fix NULL pointer deref. and resource leak By supplying ioctl()s in the wrong order, a userspace client was able to trigger NULL pointer dereferences. Furthermore, by calling ioctl_create_iso_context more than once, new contexts could be created without ever freeing the previously created contexts. Thanks to Anders Blomdell for the report. Signed-off-by: Stefan Richter --- drivers/firewire/fw-cdev.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 44ccee26c368..46bc197a047f 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -646,6 +646,10 @@ static int ioctl_create_iso_context(struct client *client, void *buffer) struct fw_cdev_create_iso_context *request = buffer; struct fw_iso_context *context; + /* We only support one context at this time. */ + if (client->iso_context != NULL) + return -EBUSY; + if (request->channel > 63) return -EINVAL; @@ -792,8 +796,9 @@ static int ioctl_start_iso(struct client *client, void *buffer) { struct fw_cdev_start_iso *request = buffer; - if (request->handle != 0) + if (client->iso_context == NULL || request->handle != 0) return -EINVAL; + if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) { if (request->tags == 0 || request->tags > 15) return -EINVAL; @@ -810,7 +815,7 @@ static int ioctl_stop_iso(struct client *client, void *buffer) { struct fw_cdev_stop_iso *request = buffer; - if (request->handle != 0) + if (client->iso_context == NULL || request->handle != 0) return -EINVAL; return fw_iso_context_stop(client->iso_context); From 717a54ad6cb4b1782a26ae0eaebc8bd49c56c66e Mon Sep 17 00:00:00 2001 From: Leonid Evdokimov Date: Thu, 21 Feb 2008 13:46:59 +0100 Subject: [PATCH 501/880] [ARM] 4835/1: Fix stale comment in struct machine_desc description This patch updates stale comment that pointed to nonexistent file. Signed-off-by: Leonid Evdokimov Signed-off-by: Russell King --- include/asm-arm/mach/arch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index c59fad18e73b..bcc8aed7c9a9 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -17,7 +17,7 @@ struct sys_timer; struct machine_desc { /* * Note! The first four elements are used - * by assembler code in head-armv.S + * by assembler code in head.S, head-common.S */ unsigned int nr; /* architecture number */ unsigned int phys_io; /* start of physical io */ From 599e0f584de8ff16b1428e2e16118757619f1d1b Mon Sep 17 00:00:00 2001 From: David Teigland Date: Thu, 21 Feb 2008 13:39:57 -0600 Subject: [PATCH 502/880] dlm: fix rcom_names message to self The recent patch to validate data lengths in rcom_names messages failed to account for fake messages a node directs to itself before ever sending it. In this case we need to fill in the message length in the header for the validation code to use. Signed-off-by: David Teigland --- fs/dlm/rcom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 035e6f9990b0..67522c268c14 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c @@ -215,6 +215,8 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { + ls->ls_recover_buf->rc_header.h_length = + dlm_config.ci_buffer_size; dlm_copy_master_names(ls, last_name, last_len, ls->ls_recover_buf->rc_buf, max_size, nodeid); From d7c2feaf88df39124e278b9e775b245b057ac99e Mon Sep 17 00:00:00 2001 From: David Teigland Date: Thu, 21 Feb 2008 15:27:09 -0600 Subject: [PATCH 503/880] dlm: update git tree in MAINTAINERS Signed-off-by: David Teigland --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 082d1ee154a9..fd81e0672c0d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1324,8 +1324,7 @@ P: David Teigland M: teigland@redhat.com L: cluster-devel@redhat.com W: http://sources.redhat.com/cluster/ -T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git -T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git +T: git kernel.org:/pub/scm/linux/kernel/git/teigland/dlm.git S: Supported DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER From 82bd3f17f4600fd374524c015826c175819f15ea Mon Sep 17 00:00:00 2001 From: Tsugikazu Shibata Date: Thu, 14 Feb 2008 14:21:34 +0900 Subject: [PATCH 504/880] Fix broken utf-8 encodings in ja_JP translation of stable_kernel_rules.txt Fix the UTF-8 broken encodings in the ja_JP version of stable_kernel_rules.txt From: Tsugikazu Shibata Signed-off-by: Greg Kroah-Hartman --- Documentation/ja_JP/stable_kernel_rules.txt | 106 ++++++++++---------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/Documentation/ja_JP/stable_kernel_rules.txt b/Documentation/ja_JP/stable_kernel_rules.txt index 17d87519e468..b3ffe870de33 100644 --- a/Documentation/ja_JP/stable_kernel_rules.txt +++ b/Documentation/ja_JP/stable_kernel_rules.txt @@ -11,69 +11,69 @@ comment or update of this file, please try to update Original(English) file at first. ================================== -これは、 +これは、 linux-2.6.24/Documentation/stable_kernel_rules.txt -の和訳です。 +の和訳です。 -翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > -翻訳日: 2007/12/30 -翻訳者: Tsugikazu Shibata -校正者: 武井伸光さん、 - かねこさん (Seiji Kaneko) - 小林 雅典さん (Masanori Kobayasi) - 野口さん (Kenji Noguchi) - 神宮信太郎さん +翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > +翻訳日: 2007/12/30 +翻訳者: Tsugikazu Shibata +校正者: 武井伸光さん、 + かねこさん (Seiji Kaneko) + 小林 雅典さん (Masanori Kobayasi) + 野口さん (Kenji Noguchi) + 神宮信太郎さん ================================== -ずっと知りたかった Linux 2.6 -stable リリースの全て +ずっと知りたかった Linux 2.6 -stable リリースの全て -"-stable" ツリーにどのような種類のパッチが受け入れられるか、どのような -ものが受け入れられないか、についての規則- +"-stable" ツリーにどのような種類のパッチが受け入れられるか、どのような +ものが受け入れられないか、についての規則- - - 明らかに正しく、テストされているものでなければならない。 - - 文脈(変更行の前後)を含めて 100 行より大きくてはいけない。 - - ただ一個のことだけを修正しているべき。 - - 皆を悩ませている本物のバグを修正しなければならない。("これはバグで - あるかもしれないが..." のようなものではない) - - ビルドエラー(CONFIG_BROKENになっているものを除く), oops, ハング、デー - タ破壊、現実のセキュリティ問題、その他 "ああ、これはダメだね"という - ようなものを修正しなければならない。短く言えば、重大な問題。 - - どのように競合状態が発生するかの説明も一緒に書かれていない限り、 - "理論的には競合状態になる"ようなものは不可。 - - いかなる些細な修正も含めることはできない。(スペルの修正、空白のクリー - ンアップなど) - - 対応するサブシステムメンテナが受け入れたものでなければならない。 - - Documentation/SubmittingPatches の規則に従ったものでなければならない。 + - 明らかに正しく、テストされているものでなければならない。 + - 文脈(変更行の前後)を含めて 100 行より大きくてはいけない。 + - ただ一個のことだけを修正しているべき。 + - 皆を悩ませている本物のバグを修正しなければならない。("これはバグで + あるかもしれないが..." のようなものではない) + - ビルドエラー(CONFIG_BROKENになっているものを除く), oops, ハング、デー + タ破壊、現実のセキュリティ問題、その他 "ああ、これはダメだね"という + ようなものを修正しなければならない。短く言えば、重大な問題。 + - どのように競合状態が発生するかの説明も一緒に書かれていない限り、 + "理論的には競合状態になる"ようなものは不可。 + - いかなる些細な修正も含めることはできない。(スペルの修正、空白のクリー + ンアップなど) + - 対応するサブシステムメンテナが受け入れたものでなければならない。 + - Documentation/SubmittingPatches の規則に従ったものでなければならない。 --stable ツリーにパッチを送付する手続き- +-stable ツリーにパッチを送付する手続き- - - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ - を送る。 - - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合 - には NAK を受け取る。この反応は開発者たちのスケジュールによって、数 - 日かかる場合がある。 - - もし受け取られたら、パッチは他の開発者たちのレビューのために - -stable キューに追加される。 - - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ - きではなく、代わりに security@kernel.org のアドレスに送られる。 + - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ + を送る。 + - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合 + には NAK を受け取る。この反応は開発者たちのスケジュールによって、数 + 日かかる場合がある。 + - もし受け取られたら、パッチは他の開発者たちのレビューのために + -stable キューに追加される。 + - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ + きではなく、代わりに security@kernel.org のアドレスに送られる。 -レビューサイクル- +レビューサイクル- - - -stable メンテナがレビューサイクルを決めるとき、パッチはレビュー委 - 員会とパッチが影響する領域のメンテナ(提供者がその領域のメンテナで無 - い限り)に送られ、linux-kernel メーリングリストにCCされる。 - - レビュー委員会は 48時間の間に ACK か NAK を出す。 - - もしパッチが委員会のメンバから却下れるか、メンテナ達やメンバが気付 - かなかった問題が持ちあがり、linux-kernel メンバがパッチに異議を唱え - た場合には、パッチはキューから削除される。 - - レビューサイクルの最後に、ACK を受けたパッチは最新の -stable リリー - スに追加され、その後に新しい -stable リリースが行われる。 - - セキュリティパッチは、通常のレビューサイクルを通らず、セキュリティ - カーネルチームから直接 -stable ツリーに受け付けられる。 - この手続きの詳細については kernel security チームに問い合わせること。 + - -stable メンテナがレビューサイクルを決めるとき、パッチはレビュー委 + 員会とパッチが影響する領域のメンテナ(提供者がその領域のメンテナで無 + い限り)に送られ、linux-kernel メーリングリストにCCされる。 + - レビュー委員会は 48時間の間に ACK か NAK を出す。 + - もしパッチが委員会のメンバから却下されるか、メンテナ達やメンバが気付 + かなかった問題が持ちあがり、linux-kernel メンバがパッチに異議を唱え + た場合には、パッチはキューから削除される。 + - レビューサイクルの最後に、ACK を受けたパッチは最新の -stable リリー + スに追加され、その後に新しい -stable リリースが行われる。 + - セキュリティパッチは、通常のレビューサイクルを通らず、セキュリティ + カーネルチームから直接 -stable ツリーに受け付けられる。 + この手続きの詳細については kernel security チームに問い合わせること。 -レビュー委員会- +レビュー委員会- - - この委員会は、このタスクについて活動する多くのボランティアと、少数の - 非ボランティアのカーネル開発者達で構成されている。 + - この委員会は、このタスクについて活動する多くのボランティアと、少数の + 非ボランティアのカーネル開発者達で構成されている。 From b6c24de77cbe9afe4962f0738e6444e709e83c81 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Mon, 4 Feb 2008 23:35:48 -0800 Subject: [PATCH 505/880] slabinfo: fall back from /sys/kernel/slab to /sys/slab I keep running upstream and mm kernels and the location of the slab directory is different since upstream still uses /sys/slab. This patch makes slabinfo check /sys/slab if /sys/kernel/slab is not there. Makes slabinfo work on any kernel. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- Documentation/vm/slabinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c index 7123fee708ca..22d7e3e4d60c 100644 --- a/Documentation/vm/slabinfo.c +++ b/Documentation/vm/slabinfo.c @@ -1123,7 +1123,7 @@ void read_slab_dir(void) char *t; int count; - if (chdir("/sys/kernel/slab")) + if (chdir("/sys/kernel/slab") && chdir("/sys/slab")) fatal("SYSFS support for SLUB not active\n"); dir = opendir("."); From 7ab47050453c10da13940114dea9c7f1c6ad323f Mon Sep 17 00:00:00 2001 From: Balaji Rao Date: Sat, 9 Feb 2008 00:52:40 +0530 Subject: [PATCH 506/880] cpufreq: fix kobject reference count handling The cpufreq core should not take an extra kobject reference count for no reason, and then refuse to release it. This has been reported as keeping machines from properly powering down all the way. Signed-off-by: Balaji Rao Cc: Dave Jones Cc: Yi Yang Cc: Alan Stern Cc: Frans Pop Cc: Yinghai Lu Cc: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/cpufreq.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 64926aa990db..89a29cd93783 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1006,14 +1006,6 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) } #endif - - if (!kobject_get(&data->kobj)) { - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - cpufreq_debug_enable_ratelimit(); - unlock_policy_rwsem_write(cpu); - return -EFAULT; - } - #ifdef CONFIG_SMP #ifdef CONFIG_HOTPLUG_CPU From 7199677d2e919edc75d1fb8856c98cd0c1bbcfc5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 18 Feb 2008 13:09:03 -0800 Subject: [PATCH 507/880] driver-core: fix kernel-doc function parameters Fix drivers/base/ missing kernel-doc parameters: Warning(linux-2.6.24-git12//drivers/base/driver.c:133): No description found for parameter 'drv' Warning(linux-2.6.24-git12//drivers/base/driver.c:133): No description found for parameter 'kobj' Warning(linux-2.6.24-git12//drivers/base/driver.c:133): No description found for parameter 'fmt' Warning(linux-2.6.24-git12//drivers/base/power/main.c:530): No description found for parameter 'state' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 3 +++ drivers/base/power/main.c | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index ba75184c653c..bf31a0170a48 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -120,6 +120,9 @@ EXPORT_SYMBOL_GPL(driver_remove_file); /** * driver_add_kobj - add a kobject below the specified driver + * @drv: requesting device driver + * @kobj: kobject to add below this driver + * @fmt: format string that names the kobject * * You really don't want to do this, this is only here due to one looney * iseries driver, go poke those developers if you are annoyed about diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index bdc03f7e8424..d6095608465a 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -523,6 +523,7 @@ static void lock_all_devices(void) /** * device_suspend - Save state and stop all devices in system. + * @state: new power management state * * Prevent new devices from being registered, then lock all devices * and suspend them. From 0763446429e46fd973f507f79900b95eb8aae2e4 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 18 Feb 2008 17:04:25 +0100 Subject: [PATCH 508/880] Driver core: Fix error handling in bus_add_driver(). - If the allocation of ->priv fails, the reference on the bus must be dropped. - If adding the kobject fails, kobject_put must be called to clean things up. Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 055989e94799..2d207ad30336 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -658,9 +658,10 @@ int bus_add_driver(struct device_driver *drv) pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - + if (!priv) { + error = -ENOMEM; + goto out_put_bus; + } klist_init(&priv->klist_devices, NULL, NULL); priv->driver = drv; drv->p = priv; @@ -668,7 +669,7 @@ int bus_add_driver(struct device_driver *drv) error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, "%s", drv->name); if (error) - goto out_put_bus; + goto out_unregister; if (drv->bus->p->drivers_autoprobe) { error = driver_attach(drv); From 2952755ce364b81f904b49397f6b0004dead2c9f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 13 Feb 2008 23:20:36 +0100 Subject: [PATCH 509/880] ide: mark "ide=reverse" option as obsolete - it is valid only if "Probe IDE PCI devices in the PCI bus order (DEPRECATED)" config option is used - Greg needs to remove pci_get_device_reverse() for PCI core changes Cc: Alan Cox Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Greg Kroah-Hartman --- drivers/ide/ide.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 4a8952a6c3da..477833f0daf5 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1229,7 +1229,7 @@ static int __init ide_setup(char *s) if (!strcmp(s, "ide=reverse")) { ide_scan_direction = 1; printk(" : Enabled support for IDE inverse scan order.\n"); - return 1; + goto obsolete_option; } #endif From 46cdf871d9970b9252469531f9efd4a17243bb0b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 8 Feb 2008 23:26:02 +0100 Subject: [PATCH 510/880] stable_kernel_rules: fix must already be in mainline stable_kernel_rules: fix must already be in mainline Signed-off-by: Stefan Richter Signed-off-by: Greg Kroah-Hartman --- Documentation/stable_kernel_rules.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index c815c5206e84..4cfc78835bc1 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -16,8 +16,9 @@ Rules on what kind of patches are accepted, and which ones are not, into the race can be exploited is also provided. - It cannot contain any "trivial" fixes in it (spelling changes, whitespace cleanups, etc). - - It must be accepted by the relevant subsystem maintainer. - It must follow the Documentation/SubmittingPatches rules. + - It or an equivalent fix must already exist in Linus' tree. Quote the + respective commit ID in Linus' tree in your patch submission to -stable. Procedure for submitting patches to the -stable tree: @@ -28,7 +29,9 @@ Procedure for submitting patches to the -stable tree: queue, or a NAK if the patch is rejected. This response might take a few days, according to the developer's schedules. - If accepted, the patch will be added to the -stable queue, for review by - other developers. + other developers and by the relevant subsystem maintainer. + - If the stable@kernel.org address is added to a patch, when it goes into + Linus's tree it will automatically be emailed to the stable team. - Security patches should not be sent to this alias, but instead to the documented security@kernel.org address. From 4f808bcdf8dcf1f1ecd028f6d5c5347db4cddc54 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 19 Feb 2008 01:55:05 -0800 Subject: [PATCH 511/880] UIO: fix Greg's stupid changes This fixes two bugs with UIO that cropped up recently in -rc1 1) WARNING: at fs/sysfs/file.c:334 sysfs_open_file when trying to open a map addr/size file - complaining about missing sysfs_ops for ktype 2) Permission denied when reading uio/uio0/maps/map0/{addr,size} when files are mode S_IRUGO Also fix a typo: attr_attribute -> addr_attribute Signed-off-by: Brandon Philips Signed-off-by: Hans J. Koch Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio.c | 54 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 2a77e9d42c68..e8a01f264540 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -57,29 +57,29 @@ struct uio_map { }; #define to_map(map) container_of(map, struct uio_map, kobj) - -static ssize_t map_attr_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) +static ssize_t map_addr_show(struct uio_mem *mem, char *buf) { - struct uio_map *map = to_map(kobj); - struct uio_mem *mem = map->mem; - - if (strncmp(attr->attr.name, "addr", 4) == 0) - return sprintf(buf, "0x%lx\n", mem->addr); - - if (strncmp(attr->attr.name, "size", 4) == 0) - return sprintf(buf, "0x%lx\n", mem->size); + return sprintf(buf, "0x%lx\n", mem->addr); +} - return -ENODEV; +static ssize_t map_size_show(struct uio_mem *mem, char *buf) +{ + return sprintf(buf, "0x%lx\n", mem->size); } -static struct kobj_attribute attr_attribute = - __ATTR(addr, S_IRUGO, map_attr_show, NULL); -static struct kobj_attribute size_attribute = - __ATTR(size, S_IRUGO, map_attr_show, NULL); +struct uio_sysfs_entry { + struct attribute attr; + ssize_t (*show)(struct uio_mem *, char *); + ssize_t (*store)(struct uio_mem *, const char *, size_t); +}; + +static struct uio_sysfs_entry addr_attribute = + __ATTR(addr, S_IRUGO, map_addr_show, NULL); +static struct uio_sysfs_entry size_attribute = + __ATTR(size, S_IRUGO, map_size_show, NULL); static struct attribute *attrs[] = { - &attr_attribute.attr, + &addr_attribute.attr, &size_attribute.attr, NULL, /* need to NULL terminate the list of attributes */ }; @@ -90,8 +90,28 @@ static void map_release(struct kobject *kobj) kfree(map); } +static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct uio_map *map = to_map(kobj); + struct uio_mem *mem = map->mem; + struct uio_sysfs_entry *entry; + + entry = container_of(attr, struct uio_sysfs_entry, attr); + + if (!entry->show) + return -EIO; + + return entry->show(mem, buf); +} + +static struct sysfs_ops uio_sysfs_ops = { + .show = map_type_show, +}; + static struct kobj_type map_attr_type = { .release = map_release, + .sysfs_ops = &uio_sysfs_ops, .default_attrs = attrs, }; From ec5a42465abc585a7f8117be5eecc361490e48ce Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 20 Feb 2008 02:01:41 +0100 Subject: [PATCH 512/880] PM: Remove unbalanced mutex_unlock() from dpm_resume() Remove an unnecessary unlocking of dpm_list_mtx in the error path in drivers/base/power/main.c:dpm_suspend() . Signed-off-by: Rafael J. Wysocki Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index d6095608465a..cea5ed3919cd 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -479,7 +479,6 @@ static int dpm_suspend(pm_message_t state) mutex_lock(&dpm_list_mtx); if (list_empty(&dev->power.entry)) list_add(&dev->power.entry, &dpm_locked); - mutex_unlock(&dpm_list_mtx); break; } mutex_lock(&dpm_list_mtx); From 58dc3232ff77158460f79e3c1932b81e8a2a0194 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 20 Feb 2008 11:27:04 +1100 Subject: [PATCH 513/880] POWERPC: fix typo in pseries/power.c Introduced by commit 79393fc46ede43451a500a132e5de9856f5a4c83 ("kobject: convert pseries/power.c to kobj_attr interface"). sys_create_file takes a "struct attrbute *" not a "struct kobj_addribute *". arch/powerpc/platforms/pseries/power.c: In function 'apo_pm_init': arch/powerpc/platforms/pseries/power.c:78: warning: passing argument 2 of 'sysfs_create_file' from incompatible pointer type Signed-off-by: Stephen Rothwell Cc: Paul Mackerras Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/pseries/power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c index e95fc1594c84..6d6266236446 100644 --- a/arch/powerpc/platforms/pseries/power.c +++ b/arch/powerpc/platforms/pseries/power.c @@ -75,7 +75,7 @@ core_initcall(pm_init); #else static int __init apo_pm_init(void) { - return (sysfs_create_file(power_kobj, &auto_poweron_attr)); + return (sysfs_create_file(power_kobj, &auto_poweron_attr.attr)); } __initcall(apo_pm_init); #endif From 120fc3d77acfd91f3521737a440d42839c475982 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 21 Feb 2008 00:33:20 +0100 Subject: [PATCH 514/880] modules: do not try to add sysfs attributes if !CONFIG_SYSFS Thanks to Alexey for the testing and the fix of the fix. Cc: Alexey Dobriyan Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- kernel/module.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 92595bad3812..901cd6ac2f11 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -987,12 +987,11 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, return ret; } - /* * /sys/module/foo/sections stuff * J. Corbet */ -#ifdef CONFIG_KALLSYMS +#if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) static ssize_t module_sect_show(struct module_attribute *mattr, struct module *mod, char *buf) { @@ -1188,7 +1187,7 @@ static inline void add_notes_attrs(struct module *mod, unsigned int nsect, static inline void remove_notes_attrs(struct module *mod) { } -#endif /* CONFIG_KALLSYMS */ +#endif #ifdef CONFIG_SYSFS int module_add_modinfo_attrs(struct module *mod) @@ -1231,9 +1230,7 @@ void module_remove_modinfo_attrs(struct module *mod) } kfree(mod->modinfo_attrs); } -#endif -#ifdef CONFIG_SYSFS int mod_sysfs_init(struct module *mod) { int err; From 498fbb5d411fc8f6207c210796c9308bf54a51a5 Mon Sep 17 00:00:00 2001 From: Gary Hade Date: Wed, 6 Feb 2008 15:43:05 -0800 Subject: [PATCH 515/880] PCI: hotplug: acpiphp_ibm: Remove get device information drivers/pci/hotplug/acpiphp_ibm.c:ibm_find_acpi_device() is not large enough to accommodate data returned by the _CID method executed from acpi_get_object_info(). This patch eliminates the problem by letting ACPI code (instead of driver code) determine and obtain a correctly sized buffer. Signed-off-by: Gary Hade Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_ibm.c | 33 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 750ebd7a4c10..b0a22b92717e 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -395,33 +395,34 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, { acpi_handle *phandle = (acpi_handle *)context; acpi_status status; - struct acpi_device_info info; - struct acpi_buffer info_buffer = { - .length = sizeof(struct acpi_device_info), - .pointer = &info, - }; + struct acpi_device_info *info; + struct acpi_buffer info_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + int retval = 0; status = acpi_get_object_info(handle, &info_buffer); if (ACPI_FAILURE(status)) { - err("%s: Failed to get device information\n", __FUNCTION__); - return 0; + err("%s: Failed to get device information status=0x%x\n", + __FUNCTION__, status); + return retval; } - info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0'; - - if (info.current_status && (info.valid & ACPI_VALID_HID) && - (!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) || - !strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) { - dbg("found hardware: %s, handle: %p\n", info.hardware_id.value, - handle); + info = info_buffer.pointer; + info->hardware_id.value[sizeof(info->hardware_id.value) - 1] = '\0'; + + if (info->current_status && (info->valid & ACPI_VALID_HID) && + (!strcmp(info->hardware_id.value, IBM_HARDWARE_ID1) || + !strcmp(info->hardware_id.value, IBM_HARDWARE_ID2))) { + dbg("found hardware: %s, handle: %p\n", + info->hardware_id.value, handle); *phandle = handle; /* returning non-zero causes the search to stop * and returns this value to the caller of * acpi_walk_namespace, but it also causes some warnings * in the acpi debug code to print... */ - return FOUND_APCI; + retval = FOUND_APCI; } - return 0; + kfree(info); + return retval; } static int __init ibm_acpiphp_init(void) From f96ee7a41ed93ce5962961eb07c2afe8cddb6603 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 4 Feb 2008 23:35:48 -0800 Subject: [PATCH 516/880] PCI: drivers/pcmcia/i82092.c: fix up after pci_bus_region changes drivers/pcmcia/i82092.c: In function 'i82092aa_set_mem_map': drivers/pcmcia/i82092.c:650: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t' drivers/pcmcia/i82092.c:650: warning: format '%lx' expects type 'long unsigned int', but argument 4 has type 'resource_size_t' Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/i82092.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 749515534cc0..e54ecc580d9e 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -647,7 +647,12 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_ if ( (mem->card_start > 0x3ffffff) || (region.start > region.end) || (mem->speed > 1000) ) { leave("i82092aa_set_mem_map: invalid address / speed"); - printk("invalid mem map for socket %i : %lx to %lx with a start of %x \n",sock,region.start, region.end, mem->card_start); + printk("invalid mem map for socket %i: %llx to %llx with a " + "start of %x\n", + sock, + (unsigned long long)region.start, + (unsigned long long)region.end, + mem->card_start); return -EINVAL; } From 05a7d22b9f02e7fe8fb5ff972b46743948139b3c Mon Sep 17 00:00:00 2001 From: Crane Cai Date: Sat, 2 Feb 2008 13:56:56 +0800 Subject: [PATCH 517/880] PCI: AMD SATA IDE mode quirk PCI: modify SATA IDE mode quirk When initialize and resume, SB600/700/800 need to set SATA mode correctly. Signed-off-by: Crane Cai Acked-by: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0a953d43b9a2..f0b3b7166b46 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -867,13 +867,13 @@ static void quirk_disable_pxb(struct pci_dev *pdev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb); - -static void __devinit quirk_sb600_sata(struct pci_dev *pdev) +static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev) { - /* set sb600 sata to ahci mode */ - if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - u8 tmp; + /* set sb600/sb700/sb800 sata to ahci mode */ + u8 tmp; + pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp); + if (tmp == 0x01) { pci_read_config_byte(pdev, 0x40, &tmp); pci_write_config_byte(pdev, 0x40, tmp|1); pci_write_config_byte(pdev, 0x9, 1); @@ -881,10 +881,13 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x40, tmp); pdev->class = PCI_CLASS_STORAGE_SATA_AHCI; + dev_info(&pdev->dev, "set SATA to AHCI mode\n"); } } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); /* * Serverworks CSB5 IDE does not fully support native mode From eb87f65f78bb4fc6dc532e6d7082d90ba0890cb8 Mon Sep 17 00:00:00 2001 From: Jason Gaston Date: Mon, 28 Jan 2008 17:20:36 -0800 Subject: [PATCH 518/880] PCI: pci_ids: patch for Intel ICH10 DeviceID's This patch adds the Intel ICH10 LPC and SMBus Controller DeviceID's. Signed-off-by: Jason Gaston Cc: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0519e53d5eb2..effdb558a588 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2374,6 +2374,12 @@ #define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a #define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e #define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b +#define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14 +#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16 +#define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18 +#define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a +#define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30 +#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff #define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031 From cc09c5bcf130f7c6e17b824a06cbc9f2c1fbb060 Mon Sep 17 00:00:00 2001 From: Jason Gaston Date: Mon, 28 Jan 2008 17:24:37 -0800 Subject: [PATCH 519/880] PCI: irq: patch for Intel ICH10 DeviceID's This patch adds the Intel ICH10 LPC Controller DeviceID's. Signed-off-by: Jason Gaston Signed-off-by: Greg Kroah-Hartman --- arch/x86/pci/irq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index ed07ce6c171b..a8715861877e 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -583,6 +583,10 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH9_4: case PCI_DEVICE_ID_INTEL_ICH9_5: case PCI_DEVICE_ID_INTEL_TOLAPAI_0: + case PCI_DEVICE_ID_INTEL_ICH10_0: + case PCI_DEVICE_ID_INTEL_ICH10_1: + case PCI_DEVICE_ID_INTEL_ICH10_2: + case PCI_DEVICE_ID_INTEL_ICH10_3: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; From 8b3c7622057266d77222a7b54ea7c529270b8901 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 3 Feb 2008 15:06:25 -0800 Subject: [PATCH 520/880] PCI: kernel-doc: fix pci-acpi warning Fix PCI kernel-doc warning: Warning(linux-2.6.24-git12//drivers/pci/pci-acpi.c:166): No description found for parameter 'hid' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e569645d59e2..2f2d308c9aa3 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -158,6 +158,7 @@ acpi_run_osc ( /** * __pci_osc_support_set - register OS support to Firmware * @flags: OS support bits + * @hid: hardware ID * * Update OS support fields and doing a _OSC Query to obtain an update * from Firmware on supported control bits. From 9dc625e72309e1c919ea3e7f51d0ffca96123787 Mon Sep 17 00:00:00 2001 From: Peer Chen Date: Mon, 4 Feb 2008 23:50:13 -0800 Subject: [PATCH 521/880] PCI: quirks: set 'En' bit of MSI Mapping for devices onHT-based nvidia platform According to HT spec, to get message interrupt from devices mapped to HT interrupt message, the 'En' bit of MSI Mapping capability need to be set. The patch do this setting in quirks code for the devices on HT-based nvidia platform. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Andy Currid Signed-off-by: Peer Chen Cc: "Eric W. Biederman" Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f0b3b7166b46..bbad4a9f264f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1778,6 +1778,68 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); +/* + * Force enable MSI mapping capability on HT bridges */ +static inline void ht_enable_msi_mapping(struct pci_dev *dev) +{ + int pos, ttl = 48; + + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); + + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags | HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } +} + +static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) +{ + struct pci_dev *host_bridge; + int pos, ttl = 48; + + /* + * HT MSI mapping should be disabled on devices that are below + * a non-Hypertransport host bridge. Locate the host bridge... + */ + host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + if (host_bridge == NULL) { + dev_warn(&dev->dev, + "nv_msi_ht_cap_quirk didn't locate host bridge\n"); + return; + } + + pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); + if (pos != 0) { + /* Host bridge is to HT */ + ht_enable_msi_mapping(dev); + return; + } + + /* Host bridge is not to HT, disable HT MSI mapping on this device */ + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Quirk disabling HT MSI mapping"); + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags & ~HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); + static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev) { dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; From 6e4be1ff2e767fc3a34c5e8d67c3cba107c02099 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 5 Feb 2008 00:01:48 -0800 Subject: [PATCH 522/880] PCI: don't load acpi_php when acpi is disabled When acpi=off and pci=nomsi, don't load acpiphp. Fixes this: pci_hotplug: PCI Hot Plug PCI Core version: 0.5 acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5 ACPI Exception (utmutex-0263): AE_BAD_PARAMETER, Thread FFFF81103CC54000 could not acquire Mutex [1] [20070126] [akpm@linux-foundation.org: export acpi_pci_disabled for acpiphp.ko] [akpm@linux-foundation.org: fix return statement] Signed-off-by: Yinghai Lu Cc: Kristen Carlson Accardi Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/acpi/boot.c | 3 ++- drivers/pci/hotplug/acpiphp_core.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 680b7300a489..2cdc9de9371d 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -72,7 +72,8 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return #define PREFIX "ACPI: " int acpi_noirq; /* skip ACPI IRQ initialization */ -int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ +int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ +EXPORT_SYMBOL(acpi_pci_disabled); int acpi_ht __initdata = 1; /* enable HT */ int acpi_lapic; diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index c8c263875c21..9279d5ba62e6 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -392,6 +392,9 @@ static int __init acpiphp_init(void) { info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + if (acpi_pci_disabled) + return 0; + acpiphp_debug = debug; /* read all the ACPI info from the system */ @@ -401,6 +404,9 @@ static int __init acpiphp_init(void) static void __exit acpiphp_exit(void) { + if (acpi_pci_disabled) + return; + /* deallocate internal data structures etc. */ acpiphp_glue_exit(); } From 13d36c248379ca09c269f5dbed6dce1e3a326a48 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 4 Feb 2008 23:50:12 -0800 Subject: [PATCH 523/880] PCI: fix up setup-bus.c #ifdef Use upper_32_bits(): no code changes, one less ifdef. Acked-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/setup-bus.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 262b0439abe9..125e7b7f34ff 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -206,10 +206,8 @@ pci_setup_bridge(struct pci_bus *bus) if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { l = (region.start >> 16) & 0xfff0; l |= region.end & 0xfff00000; -#ifdef CONFIG_RESOURCES_64BIT - bu = region.start >> 32; - lu = region.end >> 32; -#endif + bu = upper_32_bits(region.start); + lu = upper_32_bits(region.end); DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n", (unsigned long long)region.start, (unsigned long long)region.end); From 79df4c60c5b24ebc90f591d5991b22782813fcfe Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 21 Feb 2008 15:24:16 +0900 Subject: [PATCH 524/880] PCI: Fix wrong reference counter check for proc_dir_entry Fix wrong counter check for proc_dir_entry in pci_proc_detach_device(). The pci_proc_detach_device() returns with -EBUSY before calling remove_proc_entry() if the reference counter of proc_dir_entry is not 0. But this check is wrong and pci_proc_detach_device() always fails because the reference counter of proc_dir_entry is initialized with 1 at creating time and decremented in remove_proc_entry(). This bug cause strange behaviour as followings: - Accessing /proc/bus/pci/XXXX/YY file after hot-removing pci adapter card causes kernel panic. - Repeating hot-add/hot-remove of pci adapter card increases files with the same name under /proc/bus/pci/XXXX/ directory. For example: # pwd /proc/bus/pci/0002:09 # ls 01.0 # for i in `seq 5` > do > echo 0 > /sys/bus/pci/slots/0009_0032/power > echo 1 > /sys/bus/pci/slots/0009_0032/power > done # ls 01.0 01.0 01.0 01.0 01.0 01.0 The pci_proc_detach_device() should check if the reference counter is not larger than 1 instead. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 68aeeb7206de..ef18fcd641e2 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -422,7 +422,7 @@ int pci_proc_detach_device(struct pci_dev *dev) struct proc_dir_entry *e; if ((e = dev->procent)) { - if (atomic_read(&e->count)) + if (atomic_read(&e->count) > 1) return -EBUSY; remove_proc_entry(e->name, dev->bus->procdir); dev->procent = NULL; From bbc5d276ec1e24d48f794dae1c4bdfc1512f65d5 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Thu, 7 Feb 2008 01:06:07 +0100 Subject: [PATCH 525/880] USB: ftdi_sio.c add missing '|' add missing '|' Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 90dcc625f70d..76db2fef4657 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -393,8 +393,8 @@ static const char *ftdi_chip_name[] = { #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) /* End TIOCMIWAIT */ -#define FTDI_IMPL_ASYNC_FLAGS = ( ASYNC_SPD_HI | ASYNC_SPD_VHI \ - ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP ) +#define FTDI_IMPL_ASYNC_FLAGS = (ASYNC_SPD_HI | ASYNC_SPD_VHI \ + | ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP) /* function prototypes for a FTDI serial converter */ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); From 2129c4e1b4469e1f9711a54e97e8ddf8b26bb62d Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 1 Feb 2008 13:58:52 +0100 Subject: [PATCH 526/880] USB: Sane memory allocation in option driver The option driver - violates DMA coherency rules - allocates ~16500 bytes in one chunk This patch splits out the buffers and uses __get_free_page() to avoid higher order allocations. Signed-off-by: Oliver Neukum Acked-By: Matthias Urlichs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5e8bf1bc1e50..a8126988efe6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -247,10 +247,10 @@ static int debug; struct option_port_private { /* Input endpoints and buffer for this port */ struct urb *in_urbs[N_IN_URB]; - char in_buffer[N_IN_URB][IN_BUFLEN]; + u8 *in_buffer[N_IN_URB]; /* Output endpoints and buffer for this port */ struct urb *out_urbs[N_OUT_URB]; - char out_buffer[N_OUT_URB][OUT_BUFLEN]; + u8 *out_buffer[N_OUT_URB]; unsigned long out_busy; /* Bit vector of URBs in use */ /* Settings for the port */ @@ -737,9 +737,10 @@ static int option_send_setup(struct usb_serial_port *port) static int option_startup(struct usb_serial *serial) { - int i, err; + int i, j, err; struct usb_serial_port *port; struct option_port_private *portdata; + u8 *buffer; dbg("%s", __FUNCTION__); @@ -753,6 +754,20 @@ static int option_startup(struct usb_serial *serial) return (1); } + for (j = 0; j < N_IN_URB; j++) { + buffer = (u8 *)__get_free_page(GFP_KERNEL); + if (!buffer) + goto bail_out_error; + portdata->in_buffer[j] = buffer; + } + + for (j = 0; j < N_OUT_URB; j++) { + buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); + if (!buffer) + goto bail_out_error2; + portdata->out_buffer[j] = buffer; + } + usb_set_serial_port_data(port, portdata); if (! port->interrupt_in_urb) @@ -766,6 +781,16 @@ static int option_startup(struct usb_serial *serial) option_setup_urbs(serial); return (0); + +bail_out_error2: + for (j = 0; j < N_OUT_URB; j++) + kfree(portdata->out_buffer[j]); +bail_out_error: + for (j = 0; j < N_IN_URB; j++) + if (portdata->in_buffer[j]) + free_page((unsigned long)portdata->in_buffer[j]); + kfree(portdata); + return 1; } static void option_shutdown(struct usb_serial *serial) @@ -794,12 +819,14 @@ static void option_shutdown(struct usb_serial *serial) for (j = 0; j < N_IN_URB; j++) { if (portdata->in_urbs[j]) { usb_free_urb(portdata->in_urbs[j]); + free_page((unsigned long)portdata->in_buffer[j]); portdata->in_urbs[j] = NULL; } } for (j = 0; j < N_OUT_URB; j++) { if (portdata->out_urbs[j]) { usb_free_urb(portdata->out_urbs[j]); + kfree(portdata->out_buffer[j]); portdata->out_urbs[j] = NULL; } } From 1902869019918411c148c18cc3a22aade569ac9a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 12 Feb 2008 19:08:30 +0100 Subject: [PATCH 527/880] USB: fix pm counter leak in usblp if you fail in open() you must decrement the pm counter again. Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Pete Zaitcev --- drivers/usb/class/usblp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index ad632f2d6f94..0647164d36db 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -428,6 +428,7 @@ static int usblp_open(struct inode *inode, struct file *file) usblp->rcomplete = 0; if (handle_bidir(usblp) < 0) { + usb_autopm_put_interface(intf); usblp->used = 0; file->private_data = NULL; retval = -EIO; From 59036e94732edc2fb957465008c68bbcfc6736fa Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 4 Feb 2008 23:57:49 -0800 Subject: [PATCH 528/880] USB: usb: yet another Dell wireless CDMA/EVDO modem Add native support of the Dell wireless CDMA/EVDO modem. # modprobe usbserial vendor=0x413c product=0x8129 Following seesion lines describe modem itself at OK ati3 Manufacturer: NOVATEL WIRELESS INCORPORATED Model: EXPEDITE ET620 Revision: M6500C-BBIRD_TLS_MINI_DELL-Q40306.166 [Aug 25 2006 14:00:00] ESN: 0x5B39071D +GCAP: +CIS707-A, CIS-856, +MS, +ES, +DS, +FCLASS OK Signed-off-by: Andy Shevchenko Cc: Matthias Urlichs Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a8126988efe6..e3e71c5f1a70 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -181,6 +181,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, From 94409cc1e507b157f8442dad80ff5e560c3205e5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 11 Feb 2008 15:22:29 +0100 Subject: [PATCH 529/880] USB: fix usb open suspend race in cdc-acm this fixes a race between open and disconnect in the CDC ACM driver. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index bcc42136c93f..0147ea39340e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -496,13 +496,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) otherwise it is scheduled, and with high data rates data can get lost. */ tty->low_latency = 1; - if (usb_autopm_get_interface(acm->control)) { - mutex_unlock(&open_mutex); - return -EIO; - } + if (usb_autopm_get_interface(acm->control) < 0) + goto early_bail; mutex_lock(&acm->mutex); - mutex_unlock(&open_mutex); if (acm->used++) { usb_autopm_put_interface(acm->control); goto done; @@ -536,6 +533,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) done: err_out: mutex_unlock(&acm->mutex); + mutex_unlock(&open_mutex); return rv; full_bailout: @@ -544,6 +542,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) usb_autopm_put_interface(acm->control); acm->used--; mutex_unlock(&acm->mutex); +early_bail: + mutex_unlock(&open_mutex); return -EIO; } From 618b88670573020920a52e8754f4d5f216f74fdb Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Mon, 11 Feb 2008 13:16:26 +0100 Subject: [PATCH 530/880] USB: ehci-fsl: mpc834x config symbol is PPC_MPC834x, not MPC834x The config symbol for mpc834x processors is CONFIG_PPC_MPC834x, not CONFIG_MPC834x. Signed-off-by: Peter Korsgaard Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d97b16b52efa..2dd05441481c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -72,7 +72,7 @@ config USB_EHCI_FSL bool depends on USB_EHCI_HCD select USB_EHCI_ROOT_HUB_TT - default y if MPC834x || PPC_MPC831x + default y if PPC_MPC834x || PPC_MPC831x ---help--- Variation of ARC USB block used in some Freescale chips. From efa66f14e2d1aaad8ad7e1664d768de74ffb665b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 9 Feb 2008 03:16:03 -0800 Subject: [PATCH 531/880] USB: g_printer, fix empty if statement A bug every C programmer makes at some point in time... Signed-off-by: Adrian Bunk Signed-off-by: Craig W. Nadler Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 9fdabc8fcac4..4f6bfa100f2a 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -1299,7 +1299,7 @@ printer_unbind(struct usb_gadget *gadget) printer_req_free(dev->in_ep, req); } - if (dev->current_rx_req != NULL); + if (dev->current_rx_req != NULL) printer_req_free(dev->out_ep, dev->current_rx_req); while (!list_empty(&dev->rx_reqs)) { From 0cc5e2e7c3edd8b45775f50c74738d61b43ac5e8 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 30 Jan 2008 16:06:03 +0100 Subject: [PATCH 532/880] USB: fix error handling in trancevibrator trancevibrator should not pretend success if it returns an error. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/trancevibrator.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 67e2fc20eeeb..03368edf3f22 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -59,13 +59,14 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, { struct usb_interface *intf = to_usb_interface(dev); struct trancevibrator *tv = usb_get_intfdata(intf); - int temp, retval; + int temp, retval, old; temp = simple_strtoul(buf, NULL, 10); if (temp > 255) temp = 255; else if (temp < 0) temp = 0; + old = tv->speed; tv->speed = temp; dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed); @@ -77,6 +78,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, tv->speed, /* speed value */ 0, NULL, 0, USB_CTRL_GET_TIMEOUT); if (retval) { + tv->speed = old; dev_dbg(&tv->udev->dev, "retval = %d\n", retval); return retval; } From e1a491429e7f9b6fb608d9f173e5807fba053d5b Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 2 Feb 2008 02:36:53 -0800 Subject: [PATCH 533/880] USB: fix previous sparse fix which was incorrect The previous fix for a "sparse" warning in ehci_urb_dequeue() was incorrect. After rescheduling interrupt transfers it returned the URB's completion status, not status for the dequeue operation itself. This patch resolves that issue, cleans up the code in the reschedule path, and shrinks the object code by a dozen bytes. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 4caa6a8b9a37..d64887bfa6af 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -862,18 +862,18 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) /* reschedule QH iff another request is queued */ if (!list_empty (&qh->qtd_list) && HC_IS_RUNNING (hcd->state)) { - int schedule_status; - - schedule_status = qh_schedule (ehci, qh); - spin_unlock_irqrestore (&ehci->lock, flags); - - if (schedule_status != 0) { - // shouldn't happen often, but ... - // FIXME kill those tds' urbs - err ("can't reschedule qh %p, err %d", - qh, schedule_status); - } - return status; + rc = qh_schedule(ehci, qh); + + /* An error here likely indicates handshake failure + * or no space left in the schedule. Neither fault + * should happen often ... + * + * FIXME kill the now-dysfunctional queued urbs + */ + if (rc != 0) + ehci_err(ehci, + "can't reschedule qh %p, err %d", + qh, rc); } break; From b68a42b1d98f66c70a536a540f73dba07ddd5d36 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 4 Feb 2008 16:34:11 +0100 Subject: [PATCH 534/880] USB: quirks for known quirky audio devices RESET_RESUME entries for some sound devices that need it. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index d42c561c75f1..dc51790582d6 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -33,6 +33,15 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + /* Creative SB Audigy 2 NX */ + { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, + + /* Roland SC-8820 */ + { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, + + /* Edirol SD-20 */ + { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, + /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, From 564d61d30effcc727f9519538143a6c6aeb92e46 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 19 Feb 2008 13:15:30 -0500 Subject: [PATCH 535/880] USB: option: Add Kyocera KPC680 ids Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e3e71c5f1a70..fbc5aeec35d1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -113,6 +113,9 @@ static int option_send_setup(struct usb_serial_port *port); #define NOVATELWIRELESS_VENDOR_ID 0x1410 #define DELL_VENDOR_ID 0x413C +#define KYOCERA_VENDOR_ID 0x0c88 +#define KYOCERA_PRODUCT_KPC680 0x180a + #define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_PRODUCT_ADU_E100A 0x6501 #define ANYDATA_PRODUCT_ADU_500A 0x6502 @@ -187,6 +190,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); From aa59e053da08336e7def83e83c86369cd9fdaf8b Mon Sep 17 00:00:00 2001 From: Stefan Bader Date: Tue, 5 Feb 2008 15:25:35 -0500 Subject: [PATCH 536/880] USB: option: Added vendor id for Dell 5720 broadband modem this is a small patch to add support for a rebranded Novatel modem (see http://ubuntuforums.org/archive/index.php/t-608388.html for details). Signed-off-by: Stefan Bader Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index fbc5aeec35d1..17ab77869aea 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -183,8 +183,9 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, From a462549b6ad6d4de19a7702c13fbb954d9a10f29 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 13 Feb 2008 10:45:28 -0500 Subject: [PATCH 537/880] USB: usb-storage: don't clear-halt when Get-Max-LUN stalls This patch (as1032) removes the Clear-Halt calls in usb_stor_Bulk_max_lun(). Evidently some devices (such as the Oracom MP3 player) really don't like to receive these requests when their bulk endpoints aren't halted. The only reason for adding them originally was to get an ancient ZIP-100 drive to work. But since this device has only a single LUN, we don't need to send it a Get-Max-LUN request at all. Adding an unusual_devs entry for the ZIP-100 with the SINGLE_LUN flag set will cause this step to be skipped. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/transport.c | 11 ----------- drivers/usb/storage/unusual_devs.h | 12 ++++++++++++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index d9f4912f873d..5780ed15f1ad 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -891,17 +891,6 @@ int usb_stor_Bulk_max_lun(struct us_data *us) if (result > 0) return us->iobuf[0]; - /* - * Some devices (i.e. Iomega Zip100) need this -- apparently - * the bulk pipes get STALLed when the GetMaxLUN request is - * processed. This is, in theory, harmless to all other devices - * (regardless of if they stall or not). - */ - if (result == -EPIPE) { - usb_stor_clear_halt(us, us->recv_bulk_pipe); - usb_stor_clear_halt(us, us->send_bulk_pipe); - } - /* * Some devices don't like GetMaxLUN. They may STALL the control * pipe, they may return a zero-length result, they may do nothing at diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index fe12737e0e2b..a97e7ef252f0 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -759,6 +759,18 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, "Digital Camera EX-20 DSC", US_SC_8070, US_PR_DEVICE, NULL, 0 ), +/* Reported by Andre Welter + * This antique device predates the release of the Bulk-only Transport + * spec, and if it gets a Get-Max-LUN then it requires the host to do a + * Clear-Halt on the bulk endpoints. The SINGLE_LUN flag will prevent + * us from sending the request. + */ +UNUSUAL_DEV( 0x059b, 0x0001, 0x0100, 0x0100, + "Iomega", + "ZIP 100", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + /* Reported by */ UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000, "LaCie", From 9232951ada7ec2f2c1424e4c024dc8540ae97e91 Mon Sep 17 00:00:00 2001 From: Konstantin Kletschke Date: Tue, 19 Feb 2008 02:15:32 -0800 Subject: [PATCH 538/880] USB: storage: Nikon D80 new FW still needs Fixup Add new BCD numbers for Nikon D80 Firmware revision v1.10 to the unusual_devs.h file. Signed-off-by: Konstantin Kletschke Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a97e7ef252f0..6b2b57c32f95 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -357,7 +357,7 @@ UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200, US_FL_FIX_CAPACITY), /* Reported by Emil Larsson */ -UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, +UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0110, "NIKON", "NIKON DSC D80", US_SC_DEVICE, US_PR_DEVICE, NULL, From 7f4a9e8750bb904d94f37778821afd021e875c51 Mon Sep 17 00:00:00 2001 From: Warren Turkal Date: Thu, 14 Feb 2008 14:01:46 -0800 Subject: [PATCH 539/880] USB: Add another Novatel U727 ID to the device table for usbserial Signed-off-by: Warren Turkal Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 17ab77869aea..8c892e54d209 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -177,6 +177,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */ { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ From 41566bcf35a8b23ce4715dadb5acfd1098c1d3e4 Mon Sep 17 00:00:00 2001 From: Jan Altenberg Date: Tue, 19 Feb 2008 01:44:50 +0100 Subject: [PATCH 540/880] USB: gadget: queue usb USB_CDC_GET_ENCAPSULATED_RESPONSE message commit 0cf4f2de0a0f4100795f38ef894d4910678c74f8 introduced a bug, which prevents sending an USB_CDC_GET_ENCAPSULATED_RESPONSE message. This breaks the RNDIS initialization (especially / only Windoze machines dislike this behavior...). Signed-off-by: Benedikt Spranger Signed-off-by: Jan Altenberg Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ether.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index a70e255402b8..e99872308144 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1561,6 +1561,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) memcpy(req->buf, buf, n); req->complete = rndis_response_complete; rndis_free_response(dev->rndis_config, buf); + value = n; } /* else stalls ... spec says to avoid that */ } From 5b0a4d66a11df34b632e48ce80ebe81da94bdb65 Mon Sep 17 00:00:00 2001 From: Stephen Ware Date: Sun, 17 Feb 2008 11:01:58 -0800 Subject: [PATCH 541/880] USB: add new vernier product id to ldusb.c I have a new ldusb device to go into the device table. Jiri has merged the change for hiddev quirks already. From: Stephen Ware Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ldusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 8208496dfc63..c730d20eec66 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -61,6 +61,7 @@ #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 +#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 #define USB_VENDOR_ID_MICROCHIP 0x04d8 #define USB_DEVICE_ID_PICDEM 0x000c @@ -92,6 +93,7 @@ static struct usb_device_id ld_usb_table [] = { { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, { USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) }, + { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ld_usb_table); From d726fb757722a3907356830a0b8d976267596d5c Mon Sep 17 00:00:00 2001 From: Kevin Lloyd Date: Thu, 14 Feb 2008 13:35:16 -0800 Subject: [PATCH 542/880] USB: serial: move zte MF330 from sierra to option Move the Onda H600/ZTE MF33 device from the sierra driver to the option driver. The reason it was moved is because the sierra driver is starting to support more and more sierra proprietary features, so it makes more sense to keep sierra only devices in there. Signed-off-by: Kevin Lloyd Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 +++ drivers/usb/serial/sierra.c | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8c892e54d209..af2674c57414 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -124,6 +124,8 @@ static int option_send_setup(struct usb_serial_port *port); #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 +#define QUALCOMM_VENDOR_ID 0x05C6 + static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -193,6 +195,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 4c925e3e8a63..e3d44ae8d448 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -178,7 +178,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ - { USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */ { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, { } From 4e58407d5c31827de0225ea927420192a71daccd Mon Sep 17 00:00:00 2001 From: Robert Spitzenpfeil Date: Wed, 20 Feb 2008 12:11:22 -0500 Subject: [PATCH 543/880] USB: usb-storage: unusual_devs entry for Oracom MP3 player This patch (as1034) was written by Leonid Petrov, reported by Robert Spitzenpfeil, and updated by me. It adds an unusual_devs entry with the IGNORE_RESIDUE flag for the Oracom MP3 player. Together with the change to the Get-Max-LUN routine in as1032, it makes the player usable. Signed-off-by: Alan Stern Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6b2b57c32f95..6494cc52a11d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1424,6 +1424,17 @@ UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64), +/* Patch by Leonid Petrov mail at lpetrov.net + * Reported by Robert Spitzenpfeil + * http://www.qbik.ch/usb/devices/showdev.php?id=1705 + * Updated to 103 device by MJ Ray mjr at phonecoop.coop + */ +UNUSUAL_DEV( 0x0f19, 0x0103, 0x0100, 0x0100, + "Oracom Co., Ltd", + "ORC-200M", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + /* David Kuehling : * for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI * errors when trying to write. From 274399d14f121d7676ecb75a461cfed6cf9e4cdb Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 20 Feb 2008 12:10:04 -0500 Subject: [PATCH 544/880] USB: quirks and unusual_devs entry for Actions flash drive This patch (as1033) adds a quirks entry and an unusual_devs entry for the Actions Semiconductor flash drive. This device has a 64-byte string descriptor, which it doesn't terminate with a 0-length packet. Oddly enough, the reporter's logs show that when the device was plugged in at boot time, it changes its behavior completely -- it uses a different product ID, product string descriptor, and bDeviceClass. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ drivers/usb/storage/unusual_devs.h | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index dc51790582d6..f90ab5e94c58 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -28,6 +28,9 @@ * devices is broken... */ static const struct usb_device_id usb_quirk_list[] = { + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255}, + /* CBM - Flash disk */ { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, /* HP 5300/5370C scanner */ diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6494cc52a11d..99679a8cfa02 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1500,6 +1500,15 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, 0 ), +/* Reported by Fabio Venturi + * The device reports a vendor-specific bDeviceClass. + */ +UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100, + "Actions Semiconductor", + "Mtp device", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0), + /* Reported by Kevin Lloyd * Entry is needed for the initializer function override, * which instructs the device to load as a modem From 7084191d53b224b953c8e1db525ea6c31aca5fc7 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 20 Feb 2008 14:15:58 -0500 Subject: [PATCH 545/880] USB: usb-storage: don't access beyond the end of the sg buffer This patch (as1035) fixes a bug in usb_stor_access_xfer_buf() (the bug was originally found by Boaz Harrosh): The routine must not attempt to write beyond the end of a scatter-gather list or beyond the number of bytes requested. It also fixes up the formatting of a few comments and similar whitespace issues. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/protocol.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index a41ce21c0697..958f5b17847c 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -150,13 +150,14 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, /* Copy a buffer of length buflen to/from the srb's transfer buffer. * Update the **sgptr and *offset variables so that the next copy will - * pick up from where this one left off. */ - + * pick up from where this one left off. + */ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr, unsigned int *offset, enum xfer_buf_dir dir) { unsigned int cnt; + struct scatterlist *sg = *sgptr; /* We have to go through the list one entry * at a time. Each s-g entry contains some number of pages, and @@ -164,22 +165,23 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, * in kernel-addressable memory then kmap() will return its address. * If the page is not directly accessible -- such as a user buffer * located in high memory -- then kmap() will map it to a temporary - * position in the kernel's virtual address space. */ - struct scatterlist *sg = *sgptr; + * position in the kernel's virtual address space. + */ if (!sg) sg = scsi_sglist(srb); + buflen = min(buflen, scsi_bufflen(srb)); /* This loop handles a single s-g list entry, which may - * include multiple pages. Find the initial page structure - * and the starting offset within the page, and update - * the *offset and **sgptr values for the next loop. */ + * include multiple pages. Find the initial page structure + * and the starting offset within the page, and update + * the *offset and **sgptr values for the next loop. + */ cnt = 0; - while (cnt < buflen) { + while (cnt < buflen && sg) { struct page *page = sg_page(sg) + ((sg->offset + *offset) >> PAGE_SHIFT); - unsigned int poff = - (sg->offset + *offset) & (PAGE_SIZE-1); + unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1); unsigned int sglen = sg->length - *offset; if (sglen > buflen - cnt) { @@ -222,14 +224,15 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, } /* Store the contents of buffer into srb's transfer buffer and set the - * SCSI residue. */ + * SCSI residue. + */ void usb_stor_set_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb) { unsigned int offset = 0; struct scatterlist *sg = NULL; - usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, + buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, TO_XFER_BUF); if (buflen < scsi_bufflen(srb)) scsi_set_resid(srb, scsi_bufflen(srb) - buflen); From c6dd2e61d35e0fbd516c0169decc08e56619f0c6 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 21 Feb 2008 22:49:13 +0300 Subject: [PATCH 546/880] USB: POWERPC: ehci: fix ppc build Currently, this setup: CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PPC_OF=y Will fail to build: CC drivers/usb/host/ehci-hcd.o drivers/usb/host/ehci-hcd.c:1018:2: error: #error "missing bus glue for ehci-hcd" make[3]: *** [drivers/usb/host/ehci-hcd.o] Error 1 ehci-hcd.c actually contains OF_PLATFORM_DRIVER glue, so error is bogus. Signed-off-by: Anton Vorontsov Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d64887bfa6af..b8ad55aff842 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1014,7 +1014,7 @@ MODULE_LICENSE ("GPL"); #endif #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) + !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) #error "missing bus glue for ehci-hcd" #endif From b5937a415fc0387c18c40d618c7e98d1e2f65b42 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 21 Feb 2008 23:30:58 +0300 Subject: [PATCH 547/880] ehci-fsl: add PPC_MPC837x to default y This patch converts USB_EHCI_FSL config option into the verbose bool, so we'll able to select it for other freescale processors with built-in EHCI controller. Signed-off-by: Anton Vorontsov Cc: Kumar Gala Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2dd05441481c..bf8be2a41a4a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -69,10 +69,9 @@ config USB_EHCI_BIG_ENDIAN_DESC default y config USB_EHCI_FSL - bool - depends on USB_EHCI_HCD + bool "Support for Freescale on-chip EHCI USB controller" + depends on USB_EHCI_HCD && FSL_SOC select USB_EHCI_ROOT_HUB_TT - default y if PPC_MPC834x || PPC_MPC831x ---help--- Variation of ARC USB block used in some Freescale chips. From 5216a8e70e25b01cbd2915cd0442fb96deb2c262 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 21 Feb 2008 10:57:45 +0300 Subject: [PATCH 548/880] Wrap buffers used for rpc debug printks into RPC_IFDEBUG Sorry for the noise, but here's the v3 of this compilation fix :) There are some places, which declare the char buf[...] on the stack to push it later into dprintk(). Since the dprintk sometimes (if the CONFIG_SYSCTL=n) becomes an empty do { } while (0) stub, these buffers cause gcc to produce appropriate warnings. Wrap these buffers with RPC_IFDEBUG macro, as Trond proposed, to compile them out when not needed. Signed-off-by: Pavel Emelyanov Acked-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/svc.c | 2 +- fs/nfs/callback.c | 2 +- fs/nfsd/nfsfh.c | 2 +- net/sunrpc/svcsock.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 08226464e563..1ed8bd4de941 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -153,7 +153,7 @@ lockd(struct svc_rqst *rqstp) */ while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { long timeout = MAX_SCHEDULE_TIMEOUT; - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); if (signalled()) { flush_signals(current); diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 0d784f6f609f..66648dd92d97 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -172,7 +172,7 @@ void nfs_callback_down(void) static int nfs_callback_authenticate(struct svc_rqst *rqstp) { struct nfs_client *clp; - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); /* Don't talk to strangers */ clp = nfs_find_client(svc_addr(rqstp), 4); diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 0130b345234d..1eb771d79cca 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -101,7 +101,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, { /* Check if the request originated from a secure port. */ if (!rqstp->rq_secure && EX_SECURE(exp)) { - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk(KERN_WARNING "nfsd: request from insecure port %s!\n", svc_print_addr(rqstp, buf, sizeof(buf))); diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 1d3e5fcc2cc4..c475977de05a 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -175,7 +175,7 @@ static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) size_t base = xdr->page_base; unsigned int pglen = xdr->page_len; unsigned int flags = MSG_MORE; - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); slen = xdr->len; @@ -716,7 +716,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt) struct socket *newsock; struct svc_sock *newsvsk; int err, slen; - char buf[RPC_MAX_ADDRBUFLEN]; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk("svc: tcp_accept %p sock %p\n", svsk, sock); if (!sock) @@ -1206,10 +1206,10 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, struct socket *sock; int error; int type; - char buf[RPC_MAX_ADDRBUFLEN]; struct sockaddr_storage addr; struct sockaddr *newsin = (struct sockaddr *)&addr; int newlen; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk("svc: svc_create_socket(%s, %d, %s)\n", serv->sv_program->pg_name, protocol, From 597592d951cdca8e5edb29f7e8174f633a69685a Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 21 Feb 2008 13:03:45 -0800 Subject: [PATCH 549/880] xen: Implement getgeo for Xen virtual block device. The below implements the getgeo hook for Xen block devices. Extracted from the xen-unstable tree where it has been used for ages. It is useful to have because it allows things like grub2 (used by the Debian installer images) to work in a guest domain without having to sprinkle Xen specific hacks around the place. Signed-off-by: Ian Campbell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Linus Torvalds --- drivers/block/xen-blkfront.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 8afce67c0aa5..9c6f3f99208d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -135,6 +136,22 @@ static void blkif_restart_queue_callback(void *arg) schedule_work(&info->work); } +int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) +{ + /* We don't have real geometry info, but let's at least return + values consistent with the size of the device */ + sector_t nsect = get_capacity(bd->bd_disk); + sector_t cylinders = nsect; + + hg->heads = 0xff; + hg->sectors = 0x3f; + sector_div(cylinders, hg->heads * hg->sectors); + hg->cylinders = cylinders; + if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect) + hg->cylinders = 0xffff; + return 0; +} + /* * blkif_queue_request * @@ -937,6 +954,7 @@ static struct block_device_operations xlvbd_block_fops = .owner = THIS_MODULE, .open = blkif_open, .release = blkif_release, + .getgeo = blkif_getgeo, }; From 5e45bb2ebac937f2eb62138b5d734f3ac7ce8e2f Mon Sep 17 00:00:00 2001 From: Maciej Sosnowski Date: Thu, 21 Feb 2008 13:44:31 +0100 Subject: [PATCH 550/880] MAINTAINERS: ioatdma, dmaengine and async_tx maintainers change Shannon Nelson replaced by Maciej Sosnowski in maintanance of INTEL I/OAT DMA DRIVER, DMA GENERIC ENGINE SUBSYSTEM and ASYNCHRONOUS TRANSFERS/TRANSFORMS API. Signed-off-by: Maciej Sosnowski Signed-off-by: Shannon Nelson Signed-off-by: Linus Torvalds --- MAINTAINERS | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 962babe226c9..f71f66584ed3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -640,8 +640,8 @@ S: Maintained ASYNCHRONOUS TRANSFERS/TRANSFORMS API P: Dan Williams M: dan.j.williams@intel.com -P: Shannon Nelson -M: shannon.nelson@intel.com +P: Maciej Sosnowski +M: maciej.sosnowski@intel.com L: linux-kernel@vger.kernel.org W: http://sourceforge.net/projects/xscaleiop S: Supported @@ -1334,8 +1334,8 @@ L: netdev@vger.kernel.org S: Maintained DMA GENERIC OFFLOAD ENGINE SUBSYSTEM -P: Shannon Nelson -M: shannon.nelson@intel.com +P: Maciej Sosnowski +M: maciej.sosnowski@intel.com P: Dan Williams M: dan.j.williams@intel.com L: linux-kernel@vger.kernel.org @@ -2013,8 +2013,8 @@ M: tigran@aivazian.fsnet.co.uk S: Maintained INTEL I/OAT DMA DRIVER -P: Shannon Nelson -M: shannon.nelson@intel.com +P: Maciej Sosnowski +M: maciej.sosnowski@intel.com L: linux-kernel@vger.kernel.org S: Supported From a62f735cbb1a0937ab6a9196dadf752694ef0b7f Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 21 Feb 2008 16:12:45 +0000 Subject: [PATCH 551/880] MM: Fix macro argument substitution in PageHead() and PageTail() Fix macro argument substitution in PageHead() and PageTail() - 'page' should have brackets surrounding it (commit 6d7779538f765963ced45a3fa4bed7ba8d2c277d). Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- include/linux/page-flags.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index bbad43fb8181..b5b30f1c1e59 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -266,7 +266,7 @@ static inline void SetPageUptodate(struct page *page) #define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim)) -#define PageTail(page) ((page->flags & PG_head_tail_mask) \ +#define PageTail(page) (((page)->flags & PG_head_tail_mask) \ == PG_head_tail_mask) static inline void __SetPageTail(struct page *page) @@ -279,7 +279,7 @@ static inline void __ClearPageTail(struct page *page) page->flags &= ~PG_head_tail_mask; } -#define PageHead(page) ((page->flags & PG_head_tail_mask) \ +#define PageHead(page) (((page)->flags & PG_head_tail_mask) \ == (1L << PG_compound)) #define __SetPageHead(page) __SetPageCompound(page) #define __ClearPageHead(page) __ClearPageCompound(page) From 6e5e93424dc66542c548dfaa3bfebe30d46d50dd Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Fri, 22 Feb 2008 15:36:19 +1100 Subject: [PATCH 552/880] Remove empty file fs/xfs/Makefile-linux-2.6. --- fs/xfs/Makefile-linux-2.6 | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 fs/xfs/Makefile-linux-2.6 diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 deleted file mode 100644 index e69de29bb2d1..000000000000 From 4d9db01ef8f62b03c46f1258fd45a8c8235687ba Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 14 Feb 2008 23:24:02 +0200 Subject: [PATCH 553/880] [SCSI] lpfc: make lpfc_disable_node() static This patch makes the needlessly global lpfc_disable_node() static. Signed-off-by: Adrian Bunk Acked-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_crtn.h | 1 - drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 848d97744b4d..0819f5f39de5 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -55,7 +55,6 @@ void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); -void lpfc_disable_node(struct lpfc_vport *, struct lpfc_nodelist *); struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *, struct lpfc_nodelist *, int); void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index bd572d6b60af..976653440fba 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1694,7 +1694,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) NLP_STE_UNUSED_NODE); } -void +static void lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) From 3b0f208a583f130f1e551a6b8673734f51ab7dcd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 13 Feb 2008 23:30:17 +0200 Subject: [PATCH 554/880] [SCSI] iscsi transport: make 2 functions static This patch makes the following needlessly global functions static: - __iscsi_unblock_session() - iscsi_session_state_name() Signed-off-by: Adrian Bunk Acked-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_iscsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index fac7534f3ec4..9981682d5302 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -231,7 +231,7 @@ static struct { { ISCSI_SESSION_FREE, "FREE" }, }; -const char *iscsi_session_state_name(int state) +static const char *iscsi_session_state_name(int state) { int i; char *name = NULL; @@ -373,7 +373,7 @@ static void session_recovery_timedout(struct work_struct *work) scsi_target_unblock(&session->dev); } -void __iscsi_unblock_session(struct iscsi_cls_session *session) +static void __iscsi_unblock_session(struct iscsi_cls_session *session) { if (!cancel_delayed_work(&session->recovery_work)) flush_workqueue(iscsi_eh_timer_workq); From ad008d42bcec99911b3270a8349f8ec8405a1c4e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 19 Feb 2008 20:03:57 -0600 Subject: [PATCH 555/880] [SCSI] mptbase: fix use-after-free's ioc->name is used in the printk's after ioc has been freed. Free after prinks to fix this. This patch fixes two use-after-free's introduced by commit e78d5b8f1e73ab82f3fd041d05824cfee7d83a2c and spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index bfda731696f7..0c303c84b37b 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1481,15 +1481,15 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); if (pci_enable_device_mem(pdev)) { - kfree(ioc); printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() " "failed\n", ioc->name); + kfree(ioc); return r; } if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) { - kfree(ioc); printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with " "MEM failed\n", ioc->name); + kfree(ioc); return r; } From 69e562c234440fb7410877b5b24f4b29ef8521d1 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Wed, 20 Feb 2008 13:29:05 +0000 Subject: [PATCH 556/880] [SCSI] arcmsr: fix message allocation arcmsr_iop_message_xfer() is called from atomic context under the queuecommand scsi_host_template handler. James Bottomley pointed out that the current GFP_KERNEL|GFP_DMA flags are wrong: firstly we are in atomic context, secondly this memory is not used for DMA. Also removed some unneeded casts. Signed-off-by: Daniel Drake Cc: Nick Cheng Signed-off-by: James Bottomley --- drivers/scsi/arcmsr/arcmsr_hba.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 4f9ff32cfed0..f91f79c8007d 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1387,18 +1387,16 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ switch(controlcode) { case ARCMSR_MESSAGE_READ_RQBUFFER: { - unsigned long *ver_addr; + unsigned char *ver_addr; uint8_t *pQbuffer, *ptmpQbuffer; int32_t allxfer_len = 0; - void *tmp; - tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA); - ver_addr = (unsigned long *)tmp; - if (!tmp) { + ver_addr = kmalloc(1032, GFP_ATOMIC); + if (!ver_addr) { retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; } - ptmpQbuffer = (uint8_t *) ver_addr; + ptmpQbuffer = ver_addr; while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) && (allxfer_len < 1031)) { pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; @@ -1427,26 +1425,24 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ } arcmsr_iop_message_read(acb); } - memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len); + memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len); pcmdmessagefld->cmdmessage.Length = allxfer_len; pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; - kfree(tmp); + kfree(ver_addr); } break; case ARCMSR_MESSAGE_WRITE_WQBUFFER: { - unsigned long *ver_addr; + unsigned char *ver_addr; int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; uint8_t *pQbuffer, *ptmpuserbuffer; - void *tmp; - tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA); - ver_addr = (unsigned long *)tmp; - if (!tmp) { + ver_addr = kmalloc(1032, GFP_ATOMIC); + if (!ver_addr) { retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; } - ptmpuserbuffer = (uint8_t *)ver_addr; + ptmpuserbuffer = ver_addr; user_len = pcmdmessagefld->cmdmessage.Length; memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); wqbuf_lastindex = acb->wqbuf_lastindex; @@ -1492,7 +1488,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ retvalue = ARCMSR_MESSAGE_FAIL; } } - kfree(tmp); + kfree(ver_addr); } break; From f9cb02b0be4de3c51edfdd701754e13d9a2d20d6 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 21 Feb 2008 20:37:24 -0800 Subject: [PATCH 557/880] x86 ptrace: fix compat PTRACE_SETREGS Simple typo fix for regression introduced by the user_regset changes. Signed-off-by: Roland McGrath Signed-off-by: Linus Torvalds --- arch/x86/kernel/ptrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 702c33efea84..d862e396b099 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1160,7 +1160,7 @@ static int genregs32_set(struct task_struct *target, if (kbuf) { const compat_ulong_t *k = kbuf; while (count > 0 && !ret) { - ret = putreg(target, pos, *k++); + ret = putreg32(target, pos, *k++); count -= sizeof(*k); pos += sizeof(*k); } @@ -1171,7 +1171,7 @@ static int genregs32_set(struct task_struct *target, ret = __get_user(word, u++); if (ret) break; - ret = putreg(target, pos, word); + ret = putreg32(target, pos, word); count -= sizeof(*u); pos += sizeof(*u); } From 2c020a99e058cdfc3a073cbfbfcc6ff55d3bfc43 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 22 Feb 2008 08:21:38 -0800 Subject: [PATCH 558/880] Mark CC_STACKPROTECTOR as being BROKEN It's always been broken, but recent fixes actually made it do something, and now the brokenness shows up as the resulting kernel simply not working at all. So it used to be that you could enable this config option, and it just didn't do anything. Now we'd better stop people from enabling it by mistake, since it _does_ do something, but does it so badly as to be unusable. Code to actually make it work is pending, but incomplete and won't be merged into 2.6.25 in any case. Acked-by: Arjan van de Ven Acked-by: Sam Ravnborg Cc: James Morris Cc: Ingo Molnar Signed-off-by: Linus Torvalds --- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3be2305709b7..4a88cf7695b4 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1054,7 +1054,7 @@ config SECCOMP config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - depends on X86_64 && EXPERIMENTAL + depends on X86_64 && EXPERIMENTAL && BROKEN help This option turns on the -fstack-protector GCC feature. This feature puts, at the beginning of critical functions, a canary From 0ee46c9dadcbbd0daa12da30f226391896d90abb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:34:06 +0100 Subject: [PATCH 559/880] [ALSA] opl3 - Fix compilation without sequencer support Add proper ifdef's to the patch loading code moved from the old instr layer so that opl3 driver can be compiled without the sequencer support. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- include/sound/opl3.h | 9 +++++++-- sound/drivers/opl3/opl3_synth.c | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/sound/opl3.h b/include/sound/opl3.h index a0c5febdc4ea..6ba670707831 100644 --- a/include/sound/opl3.h +++ b/include/sound/opl3.h @@ -370,12 +370,13 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3, int device, int seq_device, int snd_opl3_open(struct snd_hwdep * hw, struct file *file); int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg); -long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count, - loff_t *offset); int snd_opl3_release(struct snd_hwdep * hw, struct file *file); void snd_opl3_reset(struct snd_opl3 * opl3); +#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) +long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count, + loff_t *offset); int snd_opl3_load_patch(struct snd_opl3 *opl3, int prog, int bank, int type, const char *name, @@ -384,5 +385,9 @@ int snd_opl3_load_patch(struct snd_opl3 *opl3, struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank, int create_patch); void snd_opl3_clear_patches(struct snd_opl3 *opl3); +#else +#define snd_opl3_write NULL +static inline void snd_opl3_clear_patches(struct snd_opl3 *opl3) {} +#endif #endif /* __SOUND_OPL3_H */ diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c index a7bf7a4b1f85..fb64c890109b 100644 --- a/sound/drivers/opl3/opl3_synth.c +++ b/sound/drivers/opl3/opl3_synth.c @@ -22,6 +22,10 @@ #include #include +#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) +#define OPL3_SUPPORT_SYNTH +#endif + /* * There is 18 possible 2 OP voices * (9 in the left and 9 in the right). @@ -155,9 +159,11 @@ int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file, #endif return snd_opl3_set_connection(opl3, (int) arg); +#ifdef OPL3_SUPPORT_SYNTH case SNDRV_DM_FM_IOCTL_CLEAR_PATCHES: snd_opl3_clear_patches(opl3); return 0; +#endif #ifdef CONFIG_SND_DEBUG default: @@ -178,6 +184,7 @@ int snd_opl3_release(struct snd_hwdep * hw, struct file *file) return 0; } +#ifdef OPL3_SUPPORT_SYNTH /* * write the device - load patches */ @@ -341,6 +348,7 @@ void snd_opl3_clear_patches(struct snd_opl3 *opl3) } memset(opl3->patch_table, 0, sizeof(opl3->patch_table)); } +#endif /* OPL3_SUPPORT_SYNTH */ /* ------------------------------ */ From c0792e00bc2dd1202d48b838b1cf59d13dd2c74a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:34:44 +0100 Subject: [PATCH 560/880] [ALSA] race between disconnect and error handling in usbmidi The driver resubmits URBs from an error handler and schedules the error handler from the URBs' completion handlers. To reliably kill the cycle a flag must be used. Signed-off-by: Oliver Neukum Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/usb/usbmidi.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 750e929d5870..6676a177c99e 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -104,12 +104,14 @@ struct snd_usb_midi { struct usb_protocol_ops* usb_protocol_ops; struct list_head list; struct timer_list error_timer; + spinlock_t disc_lock; struct snd_usb_midi_endpoint { struct snd_usb_midi_out_endpoint *out; struct snd_usb_midi_in_endpoint *in; } endpoints[MIDI_MAX_ENDPOINTS]; unsigned long input_triggered; + unsigned char disconnected; }; struct snd_usb_midi_out_endpoint { @@ -306,6 +308,11 @@ static void snd_usbmidi_error_timer(unsigned long data) struct snd_usb_midi *umidi = (struct snd_usb_midi *)data; int i; + spin_lock(&umidi->disc_lock); + if (umidi->disconnected) { + spin_unlock(&umidi->disc_lock); + return; + } for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { struct snd_usb_midi_in_endpoint *in = umidi->endpoints[i].in; if (in && in->error_resubmit) { @@ -316,6 +323,7 @@ static void snd_usbmidi_error_timer(unsigned long data) if (umidi->endpoints[i].out) snd_usbmidi_do_output(umidi->endpoints[i].out); } + spin_unlock(&umidi->disc_lock); } /* helper function to send static data that may not DMA-able */ @@ -1049,7 +1057,14 @@ void snd_usbmidi_disconnect(struct list_head* p) int i; umidi = list_entry(p, struct snd_usb_midi, list); - del_timer_sync(&umidi->error_timer); + /* + * an URB's completion handler may start the timer and + * a timer may submit an URB. To reliably break the cycle + * a flag under lock must be used + */ + spin_lock_irq(&umidi->disc_lock); + umidi->disconnected = 1; + spin_unlock_irq(&umidi->disc_lock); for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; if (ep->out) @@ -1062,6 +1077,7 @@ void snd_usbmidi_disconnect(struct list_head* p) if (ep->in) usb_kill_urb(ep->in->urb); } + del_timer_sync(&umidi->error_timer); } static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi) @@ -1685,6 +1701,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, umidi->quirk = quirk; umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; init_timer(&umidi->error_timer); + spin_lock_init(&umidi->disc_lock); umidi->error_timer.function = snd_usbmidi_error_timer; umidi->error_timer.data = (unsigned long)umidi; From f007dc045a93aeb7e03fe59b408bc65baa86d991 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:35:22 +0100 Subject: [PATCH 561/880] [ALSA] oxygen - Fix section mismatch Removed invalid __devinit and __devexit that are remaining after split to a helper module. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/oxygen/oxygen_lib.c | 10 +++++----- sound/pci/oxygen/oxygen_pcm.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 6eb36dd11476..78c21155218e 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -204,7 +204,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, mutex_unlock(&chip->mutex); } -static void __devinit oxygen_proc_init(struct oxygen *chip) +static void oxygen_proc_init(struct oxygen *chip) { struct snd_info_entry *entry; @@ -215,7 +215,7 @@ static void __devinit oxygen_proc_init(struct oxygen *chip) #define oxygen_proc_init(chip) #endif -static void __devinit oxygen_init(struct oxygen *chip) +static void oxygen_init(struct oxygen *chip) { unsigned int i; @@ -399,8 +399,8 @@ static void oxygen_card_free(struct snd_card *card) pci_disable_device(chip->pci); } -int __devinit oxygen_pci_probe(struct pci_dev *pci, int index, char *id, - int midi, const struct oxygen_model *model) +int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, + int midi, const struct oxygen_model *model) { struct snd_card *card; struct oxygen *chip; @@ -507,7 +507,7 @@ int __devinit oxygen_pci_probe(struct pci_dev *pci, int index, char *id, } EXPORT_SYMBOL(oxygen_pci_probe); -void __devexit oxygen_pci_remove(struct pci_dev *pci) +void oxygen_pci_remove(struct pci_dev *pci) { snd_card_free(pci_get_drvdata(pci)); pci_set_drvdata(pci, NULL); diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index dfad3db35c82..b70046aca657 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -634,7 +634,7 @@ static void oxygen_pcm_free(struct snd_pcm *pcm) snd_pcm_lib_preallocate_free_for_all(pcm); } -int __devinit oxygen_pcm_init(struct oxygen *chip) +int oxygen_pcm_init(struct oxygen *chip) { struct snd_pcm *pcm; int outs, ins; From 92eed66d5e612216369b27330ac43f6f094d0130 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:35:56 +0100 Subject: [PATCH 562/880] [ALSA] hdsp - Fix section mismatch Removed invalid __devinit from hdsp_request_fw_loader() and snd_hwdep_create_hwdep() that aren't always init functions. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/rme9652/hdsp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index c2bd4384316a..1be84f22d0de 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -745,7 +745,7 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) #ifdef HDSP_FW_LOADER -static int __devinit hdsp_request_fw_loader(struct hdsp *hdsp); +static int hdsp_request_fw_loader(struct hdsp *hdsp); #endif static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand) @@ -4688,8 +4688,7 @@ static struct snd_pcm_ops snd_hdsp_capture_ops = { .copy = snd_hdsp_capture_copy, }; -static int __devinit snd_hdsp_create_hwdep(struct snd_card *card, - struct hdsp *hdsp) +static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp) { struct snd_hwdep *hw; int err; @@ -4857,7 +4856,7 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp #ifdef HDSP_FW_LOADER /* load firmware via hotplug fw loader */ -static int __devinit hdsp_request_fw_loader(struct hdsp *hdsp) +static int hdsp_request_fw_loader(struct hdsp *hdsp) { const char *fwfile; const struct firmware *fw; From 90a5ad52bf2ce54aa7153735dc4488f00c050e54 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:36:22 +0100 Subject: [PATCH 563/880] [ALSA] HDA - enable snoop on SCH This patch enables snoop on Intel SCH chipset, eliminating static during playback. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/hda_intel.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 56f8a3050751..a1098bb875de 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -275,6 +275,11 @@ enum { #define NVIDIA_HDA_TRANSREG_ADDR 0x4e #define NVIDIA_HDA_ENABLE_COHBITS 0x0f +/* Defines for Intel SCH HDA snoop control */ +#define INTEL_SCH_HDA_DEVC 0x78 +#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) + + /* */ @@ -868,6 +873,8 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, static void azx_init_pci(struct azx *chip) { + unsigned short snoop; + /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio @@ -888,6 +895,19 @@ static void azx_init_pci(struct azx *chip) NVIDIA_HDA_TRANSREG_ADDR, 0x0f, NVIDIA_HDA_ENABLE_COHBITS); break; + case AZX_DRIVER_SCH: + pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); + if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { + pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, \ + snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); + pci_read_config_word(chip->pci, + INTEL_SCH_HDA_DEVC, &snoop); + snd_printdd("HDA snoop disabled, enabling ... %s\n",\ + (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) \ + ? "Failed" : "OK"); + } + break; + } } @@ -1040,6 +1060,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) static unsigned int azx_max_codecs[] __devinitdata = { [AZX_DRIVER_ICH] = 3, + [AZX_DRIVER_SCH] = 3, [AZX_DRIVER_ATI] = 4, [AZX_DRIVER_ATIHDMI] = 4, [AZX_DRIVER_VIA] = 3, /* FIXME: correct? */ From cbef97892e0c545575342332d0d84a910ca4c587 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:36:46 +0100 Subject: [PATCH 564/880] [ALSA] hda-codec - Fix SPDIF output on Conexant 5045 codec Fixed the SPDIF output on Conexant Cx5045 codec. Added the missing pin output setting and fixed the wrong NID for digital audio-out widget. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/patch_conexant.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f6dd51cda7b2..f7cd3a804b11 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -488,7 +488,7 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; -#define CXT5045_SPDIF_OUT 0x13 +#define CXT5045_SPDIF_OUT 0x18 static struct hda_channel_mode cxt5045_modes[1] = { { 2, NULL }, @@ -658,6 +658,7 @@ static struct hda_verb cxt5045_init_verbs[] = { {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* SPDIF route: PCM */ + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* EAPD */ {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ @@ -683,6 +684,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = { {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* SPDIF route: PCM */ + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* EAPD */ {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ @@ -781,7 +783,8 @@ static struct hda_verb cxt5045_test_init_verbs[] = { * PCM format, copyright asserted, no pre-emphasis and no validity * control. */ - {0x13, AC_VERB_SET_DIGI_CONVERT_1, 0}, + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0}, /* Start with output sum widgets muted and their output gains at min */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, From 902b05c117c33c50075b21c293bf60958dedb92d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 22 Feb 2008 18:40:56 +0100 Subject: [PATCH 565/880] [ALSA] oxygen: fix line-in recording selection The GPIO pin 0 of the CM9780 must be set when muting the line input even on non-Xonar cards. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/oxygen/oxygen.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index f31a0eb409b0..9a9941bb0460 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -28,7 +28,9 @@ * GPIO 1 -> DFS1 of AK5385 */ +#include #include +#include #include #include #include @@ -37,6 +39,7 @@ #include #include "oxygen.h" #include "ak4396.h" +#include "cm9780.h" MODULE_AUTHOR("Clemens Ladisch "); MODULE_DESCRIPTION("C-Media CMI8788 driver"); @@ -75,6 +78,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); #define GPIO_AK5385_DFS_DOUBLE 0x0001 #define GPIO_AK5385_DFS_QUAD 0x0002 +#define GPIO_LINE_MUTE CM9780_GPO0 + #define WM8785_R0 0 #define WM8785_R1 1 #define WM8785_R2 2 @@ -180,16 +185,23 @@ static void wm8785_init(struct oxygen *chip) snd_component_add(chip->card, "WM8785"); } +static void cmi9780_init(struct oxygen *chip) +{ + oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE); +} + static void generic_init(struct oxygen *chip) { ak4396_init(chip); wm8785_init(chip); + cmi9780_init(chip); } static void meridian_init(struct oxygen *chip) { ak4396_init(chip); ak5385_init(chip); + cmi9780_init(chip); } static void generic_cleanup(struct oxygen *chip) @@ -285,6 +297,27 @@ static void set_ak5385_params(struct oxygen *chip, value, GPIO_AK5385_DFS_MASK); } +static void cmi9780_switch_hook(struct oxygen *chip, unsigned int codec, + unsigned int reg, int mute) +{ + if (codec != 0) + return; + switch (reg) { + case AC97_LINE: + oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, + mute ? GPIO_LINE_MUTE : 0, + GPIO_LINE_MUTE); + break; + case AC97_MIC: + case AC97_CD: + case AC97_AUX: + if (!mute) + oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_STATUS, + GPIO_LINE_MUTE); + break; + } +} + static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); static int ak4396_control_filter(struct snd_kcontrol_new *template) @@ -308,6 +341,7 @@ static const struct oxygen_model model_generic = { .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, + .ac97_switch_hook = cmi9780_switch_hook, .model_data_size = sizeof(struct generic_data), .dac_channels = 8, .used_channels = OXYGEN_CHANNEL_A | @@ -331,6 +365,7 @@ static const struct oxygen_model model_meridian = { .set_adc_params = set_ak5385_params, .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, + .ac97_switch_hook = cmi9780_switch_hook, .model_data_size = sizeof(struct generic_data), .dac_channels = 8, .used_channels = OXYGEN_CHANNEL_B | From e5c21571361d951888c26c6ed1a21047e14b5e71 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Fri, 22 Feb 2008 18:41:41 +0100 Subject: [PATCH 566/880] [ALSA] soc - duplicate strcasecmp test for "rj-master" in mpc8610_hpcd_probe() In linus' git tree I found this problem. Is it also in the alsa tree? please confirm it's the right fix. The patch was not yet tested. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Acked-by: Timur Tabi Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/soc/fsl/mpc8610_hpcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index f26c4b2e8b6e..a00aac7a71f1 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -315,7 +315,7 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev, machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; - } else if (strcasecmp(sprop, "rj-master") == 0) { + } else if (strcasecmp(sprop, "rj-slave") == 0) { machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; From 14c65f98bfea9324cf334793305dd262d0095850 Mon Sep 17 00:00:00 2001 From: "Serge A. Suchkov" Date: Fri, 22 Feb 2008 18:43:16 +0100 Subject: [PATCH 567/880] [ALSA] hda-codec - Fix race condition in generic bound volume/swtich controls Attached patch fix race condition in hd_codec generic bound volume/swtich controls oops on this bug can be easy reproduced by two mixer apps on SMP system with PREEMPT kernel dmesg: ALSA /home/ss/ALSA/alsa-driver-1.0.16/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:596: hda_intel: azx_get_response timeout, switching to polling mode: las t cmd=0x014f0900 BUG: unable to handle kernel paging request at virtual address 00070006 printing eip: f8f43e95 *pde = 00000000 Oops: 0000 [#1] PREEMPT SMP Modules linked in: i915 drm snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss snd_mixer_oss bnep rfcomm hidp l2cap bluetooth w lan_wep acpi_cpufreq coretemp hwmon mmc_block pcspkr psmouse wlan_scan_sta ath_rate_sample snd_hda_intel ath_pci serio_raw wlan tg3 sdhci snd_pcm firewire_o hci mmc_core i2c_i801 snd_timer firewire_core snd_page_alloc ath_hal(P) snd_hwdep snd iTCO_wdt crc_itu_t iTCO_vendor_support shpchp video output acer_acpi b acklight led_class wmi_acer Pid: 3969, comm: gkrellm Tainted: P (2.6.24-jm #4) EIP: 0060:[] EFLAGS: 00010292 CPU: 0 EIP is at snd_hda_mixer_bind_ctls_info+0x20/0x43 [snd_hda_intel] EAX: 00000000 EBX: f7478e00 ECX: f763e000 EDX: f764f788 ESI: 00070002 EDI: edce5e00 EBP: edc3fe64 ESP: edc3fe54 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process gkrellm (pid: 3969, ti=edc3e000 task=f1e4e000 task.ti=edc3e000) Stack: f764f77c f7478e00 edce5e00 f6dd6000 edc3fe84 f8e590e8 edc7a239 f6d14034 f764f34c f6c0f7e0 edc3ff30 f6d14034 edc3fea8 f8e591b7 edc3ff30 edc3ff2c 00000000 f70aa668 f6d14034 f8e59165 bfbfadb0 edc3ff40 f8e587aa edc3ff2c Call Trace: [] show_trace_log_lvl+0x1a/0x2f [] show_stack_log_lvl+0x9d/0xa5 [] show_registers+0xa4/0x1bd [] die+0x122/0x206 [] do_page_fault+0x535/0x623 [] error_code+0x72/0x78 [] snd_mixer_oss_get_volume1_vol+0x74/0xf1 [snd_mixer_oss] [] snd_mixer_oss_get_volume1+0x52/0xa5 [snd_mixer_oss] [] snd_mixer_oss_ioctl1+0x673/0x71e [snd_mixer_oss] [] snd_mixer_oss_ioctl+0xb/0xd [snd_mixer_oss] [] do_ioctl+0x22/0x67 [] vfs_ioctl+0x237/0x24a [] sys_ioctl+0x31/0x4b [] syscall_call+0x7/0xb ======================= Code: 3f 49 c7 89 f8 59 5b 5e 5f 5d c3 55 89 e5 57 89 d7 56 53 89 c3 83 ec 04 8b 70 5c 8b 40 60 05 7c 01 00 00 89 45 f0 e8 c0 3f 49 c7 <8b> 46 04 89 fa 89 4 3 5c 89 d8 8b 0e ff 11 89 73 5c 89 c7 8b 45 EIP: [] snd_hda_mixer_bind_ctls_info+0x20/0x43 [snd_hda_intel] SS:ESP 0068:edc3fe54 ---[ end trace 0a20bc209e9397cc ]--- similar issue report present in ALSA bugtracking system https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3652 Signed-off-by: Serge A. Suchkov Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/hda_codec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 26812dc2b7f2..5c6419ead015 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1197,8 +1197,8 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, struct hda_bind_ctls *c; int err; - c = (struct hda_bind_ctls *)kcontrol->private_value; mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + c = (struct hda_bind_ctls *)kcontrol->private_value; kcontrol->private_value = *c->values; err = c->ops->info(kcontrol, uinfo); kcontrol->private_value = (long)c; @@ -1213,8 +1213,8 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, struct hda_bind_ctls *c; int err; - c = (struct hda_bind_ctls *)kcontrol->private_value; mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + c = (struct hda_bind_ctls *)kcontrol->private_value; kcontrol->private_value = *c->values; err = c->ops->get(kcontrol, ucontrol); kcontrol->private_value = (long)c; @@ -1230,8 +1230,8 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, unsigned long *vals; int err = 0, change = 0; - c = (struct hda_bind_ctls *)kcontrol->private_value; mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + c = (struct hda_bind_ctls *)kcontrol->private_value; for (vals = c->values; *vals; vals++) { kcontrol->private_value = *vals; err = c->ops->put(kcontrol, ucontrol); @@ -1251,8 +1251,8 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, struct hda_bind_ctls *c; int err; - c = (struct hda_bind_ctls *)kcontrol->private_value; mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + c = (struct hda_bind_ctls *)kcontrol->private_value; kcontrol->private_value = *c->values; err = c->ops->tlv(kcontrol, op_flag, size, tlv); kcontrol->private_value = (long)c; From 2f0855497738a56825ee6445574835b4fc1d77d5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:43:50 +0100 Subject: [PATCH 568/880] [ALSA] hda-codec - Don't create vmaster if no slaves found Don't create vmaster controls if no slaves are found in the given list. This prevents the error due to an empty vmaster control. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/hda_codec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 5c6419ead015..37c413923db8 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1055,6 +1055,12 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, const char **s; int err; + for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) + ; + if (!*s) { + snd_printdd("No slave found for %s\n", name); + return 0; + } kctl = snd_ctl_make_virtual_master(name, tlv); if (!kctl) return -ENOMEM; From 614ca92b51b81eb42d6a3dcf125451632ddca0f5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:44:21 +0100 Subject: [PATCH 569/880] [ALSA] hda-codec - Fix wrong capture source selection for ALC883 codec The widget list of capture source selection for ALC883 contains the wrong NIDs. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 586d98f1b63d..2a463c921ae3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6457,7 +6457,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, struct alc_spec *spec = codec->spec; const struct hda_input_mux *imux = spec->input_mux; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; + static hda_nid_t capture_mixers[2] = { 0x23, 0x22 }; hda_nid_t nid = capture_mixers[adc_idx]; unsigned int *cur_val = &spec->cur_mux[adc_idx]; unsigned int i, idx; From cced83b62c61fb39b79e796981065dff474b62aa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:45:30 +0100 Subject: [PATCH 570/880] [ALSA] hda-codec - Fix ALC882 capture source selection The capture source selection for ADC list with two elements is buggy becaues of a wrong capture mux list. This patch fixes the starting index based on spec->num_adc_nids. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/patch_realtek.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2a463c921ae3..777f8c01ca7a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5227,10 +5227,14 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, const struct hda_input_mux *imux = spec->input_mux; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; - hda_nid_t nid = capture_mixers[adc_idx]; + hda_nid_t nid; unsigned int *cur_val = &spec->cur_mux[adc_idx]; unsigned int i, idx; + if (spec->num_adc_nids < 3) + nid = capture_mixers[adc_idx + 1]; + else + nid = capture_mixers[adc_idx]; idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; From 9e03ad7907bc9c9e60a3ea09579a61ad7f9e59c8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:46:00 +0100 Subject: [PATCH 571/880] [ALSA] hda-codec - Fix amp-in values for pin widgets Pin widgets have always one amp-input value regardless of number of connections. The proc file showed values wrongly. Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/hda_proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 35a630d1770f..5633f77f8f3b 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -584,7 +584,8 @@ static void print_codec_info(struct snd_info_entry *entry, print_amp_caps(buffer, codec, nid, HDA_INPUT); snd_iprintf(buffer, " Amp-In vals: "); print_amp_vals(buffer, codec, nid, HDA_INPUT, - wid_caps & AC_WCAP_STEREO, conn_len); + wid_caps & AC_WCAP_STEREO, + wid_type == AC_WID_PIN ? 1 : conn_len); } if (wid_caps & AC_WCAP_OUT_AMP) { snd_iprintf(buffer, " Amp-Out caps: "); From c598195a2d32dc5388c636260c16e07ebee9b051 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 22 Feb 2008 18:46:47 +0100 Subject: [PATCH 572/880] [ALSA] caiaq - fix section mismatch warning Fix following warning: WARNING: vmlinux.o(.text+0x11ec01a): Section mismatch in reference from the function setup_card() to the function .devinit.text:snd_usb_caiaq_control_init() setup_card() are only used by init_card(). init_card() are only used by snd_probe() snd_probe() are used for the .probe parameter in usb_driver.probe Annotate them all __devinit to fix the warning. Signed-off-by: Sam Ravnborg Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/usb/caiaq/caiaq-device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c index 58d25e4e7d6c..7c44a2c7f963 100644 --- a/sound/usb/caiaq/caiaq-device.c +++ b/sound/usb/caiaq/caiaq-device.c @@ -245,7 +245,7 @@ int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, tmp, sizeof(tmp)); } -static void setup_card(struct snd_usb_caiaqdev *dev) +static void __devinit setup_card(struct snd_usb_caiaqdev *dev) { int ret; char val[4]; @@ -359,7 +359,7 @@ static struct snd_card* create_card(struct usb_device* usb_dev) return card; } -static int init_card(struct snd_usb_caiaqdev *dev) +static int __devinit init_card(struct snd_usb_caiaqdev *dev) { char *c; struct usb_device *usb_dev = dev->chip.dev; @@ -428,7 +428,7 @@ static int init_card(struct snd_usb_caiaqdev *dev) return 0; } -static int snd_probe(struct usb_interface *intf, +static int __devinit snd_probe(struct usb_interface *intf, const struct usb_device_id *id) { int ret; From c6cd7d7efe2302697a3cbde718e8e3b0d88ba706 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Feb 2008 18:47:12 +0100 Subject: [PATCH 573/880] [ALSA] hda-intel - Fix Oops with ATI HDMI devices The driver gets Oops with ATI HDMI devices due to the wrong calculation of index for playback streams. This patch fixes it. Reference: https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3746 Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/hda/hda_intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a1098bb875de..4be36c84b36c 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1818,7 +1818,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, */ chip->playback_streams = (gcap & (0xF << 12)) >> 12; chip->capture_streams = (gcap & (0xF << 8)) >> 8; - chip->playback_index_offset = (gcap & (0xF << 12)) >> 12; + chip->playback_index_offset = chip->capture_streams; chip->capture_index_offset = 0; } else { /* gcap didn't give any info, switching to old method */ From 2f93d797ea92113a73c72728c475455cb1409fb3 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 22 Feb 2008 18:47:44 +0100 Subject: [PATCH 574/880] [ALSA] bt87X: fix freeing of shared interrupt Call free_irq() after iounmap() because other devices could trigger our shared interrupt handler. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- sound/pci/bt87x.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index c9a2421cf6f0..4ecdd635ed1d 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -681,15 +681,12 @@ static struct snd_kcontrol_new snd_bt87x_capture_source = { static int snd_bt87x_free(struct snd_bt87x *chip) { - if (chip->mmio) { + if (chip->mmio) snd_bt87x_stop(chip); - if (chip->irq >= 0) - synchronize_irq(chip->irq); - - iounmap(chip->mmio); - } if (chip->irq >= 0) free_irq(chip->irq, chip); + if (chip->mmio) + iounmap(chip->mmio); pci_release_regions(chip->pci); pci_disable_device(chip->pci); kfree(chip); From a8e14fec164cc01d8dfb18760ee9bddd91e127c2 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 19 Feb 2008 21:48:42 -0600 Subject: [PATCH 575/880] [SCSI] libsas: fix error handling The libsas error handler has two fairly fatal bugs 1. scsi_sas_task_done calls scsi_eh_finish_cmd() too early. This happens if the task completes after it has been aborted but before the error handler starts up. Because scsi_eh_finish_cmd() decrements host_failed and adds the task to the done list, the error handler start check (host_failed == host_busy) never passes and the eh never starts. 2. The multiple task completion paths sas_scsi_clear_queue_... all simply delete the task from the error queue. This causes it to disappear into the ether, since a command must be placed on the done queue to be finished off by the error handler. This behaviour causes the HBA to hang on pending commands. Fix 1. by moving the SAS_TASK_STATE_ABORTED check to an exit clause at the top of the routine and calling ->scsi_done() unconditionally (it is a nop if the timer has fired). This keeps the task in the error handling queue until the eh starts. Fix 2. by making sure every task goes through task complete followed by scsi_eh_finish_cmd(). Tested this by firing resets across a disk running a hammer test (now it actually survives without hanging the system) Signed-off-by: James Bottomley --- drivers/scsi/libsas/sas_scsi_host.c | 65 ++++++++++++++++++----------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index f869fba86807..9c96d1bd36e2 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -51,10 +51,14 @@ static void sas_scsi_task_done(struct sas_task *task) { struct task_status_struct *ts = &task->task_status; struct scsi_cmnd *sc = task->uldd_task; - struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(sc->device->host); - unsigned ts_flags = task->task_state_flags; int hs = 0, stat = 0; + if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) { + /* Aborted tasks will be completed by the error handler */ + SAS_DPRINTK("task done but aborted\n"); + return; + } + if (unlikely(!sc)) { SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n"); list_del_init(&task->list); @@ -120,11 +124,7 @@ static void sas_scsi_task_done(struct sas_task *task) sc->result = (hs << 16) | stat; list_del_init(&task->list); sas_free_task(task); - /* This is very ugly but this is how SCSI Core works. */ - if (ts_flags & SAS_TASK_STATE_ABORTED) - scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q); - else - sc->scsi_done(sc); + sc->scsi_done(sc); } static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd) @@ -255,13 +255,33 @@ int sas_queuecommand(struct scsi_cmnd *cmd, return res; } +static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) +{ + struct sas_task *task = TO_SAS_TASK(cmd); + struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host); + + /* remove the aborted task flag to allow the task to be + * completed now. At this point, we only get called following + * an actual abort of the task, so we should be guaranteed not + * to be racing with any completions from the LLD (hence we + * don't need the task state lock to clear the flag) */ + task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; + /* Now call task_done. However, task will be free'd after + * this */ + task->task_done(task); + /* now finish the command and move it on to the error + * handler done list, this also takes it off the + * error handler pending list */ + scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q); +} + static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) { struct scsi_cmnd *cmd, *n; list_for_each_entry_safe(cmd, n, error_q, eh_entry) { if (cmd == my_cmd) - list_del_init(&cmd->eh_entry); + sas_eh_finish_cmd(cmd); } } @@ -274,7 +294,7 @@ static void sas_scsi_clear_queue_I_T(struct list_head *error_q, struct domain_device *x = cmd_to_domain_dev(cmd); if (x == dev) - list_del_init(&cmd->eh_entry); + sas_eh_finish_cmd(cmd); } } @@ -288,7 +308,7 @@ static void sas_scsi_clear_queue_port(struct list_head *error_q, struct asd_sas_port *x = dev->port; if (x == port) - list_del_init(&cmd->eh_entry); + sas_eh_finish_cmd(cmd); } } @@ -528,14 +548,14 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, case TASK_IS_DONE: SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, task); - task->task_done(task); + sas_eh_finish_cmd(cmd); if (need_reset) try_to_reset_cmd_device(shost, cmd); continue; case TASK_IS_ABORTED: SAS_DPRINTK("%s: task 0x%p is aborted\n", __FUNCTION__, task); - task->task_done(task); + sas_eh_finish_cmd(cmd); if (need_reset) try_to_reset_cmd_device(shost, cmd); continue; @@ -547,7 +567,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, "recovered\n", SAS_ADDR(task->dev), cmd->device->lun); - task->task_done(task); + sas_eh_finish_cmd(cmd); if (need_reset) try_to_reset_cmd_device(shost, cmd); sas_scsi_clear_queue_lu(work_q, cmd); @@ -562,7 +582,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { SAS_DPRINTK("I_T %016llx recovered\n", SAS_ADDR(task->dev->sas_addr)); - task->task_done(task); + sas_eh_finish_cmd(cmd); if (need_reset) try_to_reset_cmd_device(shost, cmd); sas_scsi_clear_queue_I_T(work_q, task->dev); @@ -577,7 +597,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, if (res == TMF_RESP_FUNC_COMPLETE) { SAS_DPRINTK("clear nexus port:%d " "succeeded\n", port->id); - task->task_done(task); + sas_eh_finish_cmd(cmd); if (need_reset) try_to_reset_cmd_device(shost, cmd); sas_scsi_clear_queue_port(work_q, @@ -591,10 +611,10 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, if (res == TMF_RESP_FUNC_COMPLETE) { SAS_DPRINTK("clear nexus ha " "succeeded\n"); - task->task_done(task); + sas_eh_finish_cmd(cmd); if (need_reset) try_to_reset_cmd_device(shost, cmd); - goto out; + goto clear_q; } } /* If we are here -- this means that no amount @@ -606,21 +626,18 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost, SAS_ADDR(task->dev->sas_addr), cmd->device->lun); - task->task_done(task); + sas_eh_finish_cmd(cmd); if (need_reset) try_to_reset_cmd_device(shost, cmd); goto clear_q; } } -out: return list_empty(work_q); clear_q: SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); - list_for_each_entry_safe(cmd, n, work_q, eh_entry) { - struct sas_task *task = TO_SAS_TASK(cmd); - list_del_init(&cmd->eh_entry); - task->task_done(task); - } + list_for_each_entry_safe(cmd, n, work_q, eh_entry) + sas_eh_finish_cmd(cmd); + return list_empty(work_q); } From 65fecc77f3c47c5e8758d133b8ec47dcc16ed207 Mon Sep 17 00:00:00 2001 From: David Somayajulu Date: Thu, 21 Feb 2008 03:43:00 -0800 Subject: [PATCH 576/880] [SCSI] qla4xxx: fix up residual handling the check in the residual case has an incorrect test of scsi_status (the logic is reversed, it should be scsi_status != 0 instead of !scsi_status. Since we checked a few lines above that scsi_status was non-zero, just eliminate this test Signed-off-by: David C Somayajulu Signed-off-by: James Bottomley --- drivers/scsi/qla4xxx/ql4_isr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index 0f029d0d7315..fc84db4069f4 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -100,8 +100,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { scsi_set_resid(cmd, residual); - if (!scsi_status && ((scsi_bufflen(cmd) - residual) < - cmd->underflow)) { + if ((scsi_bufflen(cmd) - residual) < cmd->underflow) { cmd->result = DID_ERROR << 16; From eafe1df9e311034cce204e43c0e45c91723b802f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 21 Feb 2008 05:44:33 -0700 Subject: [PATCH 577/880] [SCSI] lpfc: Balance locking Commit 3163f725a5d071eea1830bbbfab78cfe3fc9baaf introduced locking in lpfc_sli_hbqbuf_fill_hbqs, but missed unlocking on one exit. Reported-by: Harvey Harrison Signed-off-by: Matthew Wilcox Acked-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_sli.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f53206411cd8..fc0d9501aba6 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -648,28 +648,24 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) unsigned long flags; struct hbq_dmabuf *hbq_buffer; - if (!phba->hbqs[hbqno].hbq_alloc_buffer) { + if (!phba->hbqs[hbqno].hbq_alloc_buffer) return 0; - } start = phba->hbqs[hbqno].buffer_count; end = count + start; - if (end > lpfc_hbq_defs[hbqno]->entry_count) { + if (end > lpfc_hbq_defs[hbqno]->entry_count) end = lpfc_hbq_defs[hbqno]->entry_count; - } /* Check whether HBQ is still in use */ spin_lock_irqsave(&phba->hbalock, flags); - if (!phba->hbq_in_use) { - spin_unlock_irqrestore(&phba->hbalock, flags); - return 0; - } + if (!phba->hbq_in_use) + goto out; /* Populate HBQ entries */ for (i = start; i < end; i++) { hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); if (!hbq_buffer) - return 1; + goto err; hbq_buffer->tag = (i | (hbqno << 16)); if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) phba->hbqs[hbqno].buffer_count++; @@ -677,8 +673,12 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); } + out: spin_unlock_irqrestore(&phba->hbalock, flags); return 0; + err: + spin_unlock_irqrestore(&phba->hbalock, flags); + return 1; } int From 26106e3ca379e30790c41d8835e79395437152ec Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 22 Feb 2008 23:11:03 +0900 Subject: [PATCH 578/880] [SCSI] stex: stex_direct_copy shouldn't call dma_map_sg stex_direct_copy copies an in-kernel buffer to a sg list in order to spoof some SCSI commands. stex_direct_copy calls dma_map_sg and then stex_internal_copy with the value that dma_map_sg returned. It calls scsi_kmap_atomic_sg to copy data. scsi_kmap_atomic_sg doesn't see sg->dma_length so if dma_map_sg merges sg entries, stex_internal_copy gets the smaller number of sg entries than the acutual number, which means it wrongly think that the data length in the sg list is shorter than the actual length. stex_direct_copy shouldn't call dma_map_sg and it doesn't need since this code path doesn't involve dma transfers. This patch removes stex_direct_copy and simply calls stex_internal_copy with the actual number of sg entries. Signed-off-by: FUJITA Tomonori Acked-by: Ed Lin Signed-off-by: James Bottomley --- drivers/scsi/stex.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 72f6d8015358..4b6861cf0417 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -461,23 +461,6 @@ static void stex_internal_copy(struct scsi_cmnd *cmd, } } -static int stex_direct_copy(struct scsi_cmnd *cmd, - const void *src, size_t count) -{ - size_t cp_len = count; - int n_elem = 0; - - n_elem = scsi_dma_map(cmd); - if (n_elem < 0) - return 0; - - stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD); - - scsi_dma_unmap(cmd); - - return cp_len == count; -} - static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) { struct st_frame *p; @@ -569,8 +552,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) unsigned char page; page = cmd->cmnd[2] & 0x3f; if (page == 0x8 || page == 0x3f) { - stex_direct_copy(cmd, ms10_caching_page, - sizeof(ms10_caching_page)); + size_t cp_len = sizeof(ms10_caching_page); + stex_internal_copy(cmd, ms10_caching_page, + &cp_len, scsi_sg_count(cmd), + ST_TO_CMD); cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; done(cmd); } else @@ -599,8 +584,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) if (id != host->max_id - 1) break; if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { - stex_direct_copy(cmd, console_inq_page, - sizeof(console_inq_page)); + size_t cp_len = sizeof(console_inq_page); + stex_internal_copy(cmd, console_inq_page, + &cp_len, scsi_sg_count(cmd), + ST_TO_CMD); cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; done(cmd); } else @@ -609,6 +596,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) case PASSTHRU_CMD: if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { struct st_drvver ver; + size_t cp_len = sizeof(ver); ver.major = ST_VER_MAJOR; ver.minor = ST_VER_MINOR; ver.oem = ST_OEM; @@ -616,7 +604,9 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) ver.signature[0] = PASSTHRU_SIGNATURE; ver.console_id = host->max_id - 1; ver.host_no = hba->host->host_no; - cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ? + stex_internal_copy(cmd, &ver, &cp_len, + scsi_sg_count(cmd), ST_TO_CMD); + cmd->result = sizeof(ver) == cp_len ? DID_OK << 16 | COMMAND_COMPLETE << 8 : DID_ERROR << 16 | COMMAND_COMPLETE << 8; done(cmd); From c9872fe1add5709fffd42249e6ca1080999aa06a Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 22 Feb 2008 23:11:04 +0900 Subject: [PATCH 579/880] [SCSI] stex: stex_internal_copy should be called with sg_count in struct st_ccb stex_internal_copy copies an in-kernel buffer to a sg list by using scsi_kmap_atomic_sg. Some functions calls stex_internal_copy with sg_count in struct st_ccb, which is the value that dma_map_sg returned. However it might be shorter than the actual number of sg entries (if the IOMMU merged the sg entries). scsi_kmap_atomic_sg doesn't see sg->dma_length so stex_internal_copy should be called with the actual number of sg entries (i.e. scsi_sg_count), because if the sg entries were merged, stex_direct_copy wrongly think that the data length in the sg list is shorter than the actual length. Signed-off-by: FUJITA Tomonori Acked-by: Ed Lin Signed-off-by: James Bottomley --- drivers/scsi/stex.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 4b6861cf0417..654430edf74d 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -467,7 +467,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) size_t count = sizeof(struct st_frame); p = hba->copy_buffer; - stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD); + stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), + ST_FROM_CMD); memset(p->base, 0, sizeof(u32)*6); *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); p->rom_addr = 0; @@ -485,7 +486,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) p->subid = hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; - stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD); + stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), + ST_TO_CMD); } static void @@ -699,7 +701,7 @@ static void stex_copy_data(struct st_ccb *ccb, if (ccb->cmd == NULL) return; stex_internal_copy(ccb->cmd, - resp->variable, &count, ccb->sg_count, ST_TO_CMD); + resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD); } static void stex_ys_commands(struct st_hba *hba, @@ -724,7 +726,7 @@ static void stex_ys_commands(struct st_hba *hba, count = STEX_EXTRA_SIZE; stex_internal_copy(ccb->cmd, hba->copy_buffer, - &count, ccb->sg_count, ST_FROM_CMD); + &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD); inq_data = (ST_INQ *)hba->copy_buffer; if (inq_data->DeviceTypeQualifier != 0) ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; From deee13dfd6dd6c18518ea725f11111ebd9bf4fa8 Mon Sep 17 00:00:00 2001 From: Kai Makisara Date: Fri, 22 Feb 2008 20:11:21 +0200 Subject: [PATCH 580/880] [SCSI] st: compile fix when DEBUG set to one Remove the now useless counting of adjacent pages from the debugging code in to make it compile when DEBUG is set non-zero. Signed-off-by: Kai Makisara Signed-off-by: James Bottomley --- drivers/scsi/st.c | 11 ++++------- drivers/scsi/st.h | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 71952703125a..0a52d9d2da2c 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static const char *verstr = "20080117"; +static const char *verstr = "20080221"; #include @@ -1172,7 +1172,7 @@ static int st_open(struct inode *inode, struct file *filp) STp->try_dio_now = STp->try_dio; STp->recover_count = 0; DEB( STp->nbr_waits = STp->nbr_finished = 0; - STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; ) + STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; ) retval = check_tape(STp, filp); if (retval < 0) @@ -1226,8 +1226,8 @@ static int st_flush(struct file *filp, fl_owner_t id) } DEBC( if (STp->nbr_requests) - printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", - name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable)); + printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n", + name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages)); if (STps->rw == ST_WRITING && !STp->pos_unknown) { struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; @@ -1422,9 +1422,6 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, if (STbp->do_dio) { STp->nbr_dio++; STp->nbr_pages += STbp->do_dio; - for (i=1; i < STbp->do_dio; i++) - if (page_to_pfn(STbp->sg[i].page) == page_to_pfn(STbp->sg[i-1].page) + 1) - STp->nbr_combinable++; } ) } else diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 6c8075712974..5931726fcf93 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -164,7 +164,6 @@ struct scsi_tape { int nbr_requests; int nbr_dio; int nbr_pages; - int nbr_combinable; unsigned char last_cmnd[6]; unsigned char last_sense[16]; #endif From 91b550604480eadcdadc7db8a7d19f496ccad6bd Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 22 Feb 2008 17:01:59 -0600 Subject: [PATCH 581/880] [SCSI] aic94xx: fix sequencer hang on error recovery The clear nexus I_T and clear nexus I_T_L functions in the aic94xx specify the SUSPEND_TX flag which causes the sequencer to be suspended until it receives a RESUME_TX. Unfortunately, nothing ever sends the resume, so the sequencer on the link is stopped forever, leading to eventual timeouts and I/O errors. Since clear nexus commands are only executed as part of error recovery, it's perfectly fine to keep the sequencer running on the link ... as soon as the recovery function is completed, we'll send it the commands to retry. Signed-off-by: James Bottomley --- drivers/scsi/aic94xx/aic94xx_tmf.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index b52124f3d3ac..144f5ad20453 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c @@ -151,8 +151,6 @@ static int asd_clear_nexus_I_T(struct domain_device *dev) CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_I_T; scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ; - if (dev->tproto) - scb->clear_nexus.flags |= SUSPEND_TX; scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) dev->lldd_dev); CLEAR_NEXUS_POST; @@ -169,8 +167,6 @@ static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun) CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_I_T_L; scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ; - if (dev->tproto) - scb->clear_nexus.flags |= SUSPEND_TX; memcpy(scb->clear_nexus.ssp_task.lun, lun, 8); scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) dev->lldd_dev); From 63e4563b9cf77875286312758f61a20f912afbbb Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 22 Feb 2008 17:07:52 -0600 Subject: [PATCH 582/880] [SCSI] libsas: correctly flush the LU queue on error recovery The current sas_scsi_clear_queue_lu() is wrongly checking for commands which match the pointer to the one passed in. It should be checking for commands which are on the same logical unit as the one passed in. Fix this by checking target pointer and LUN for equality. Signed-off-by: James Bottomley --- drivers/scsi/libsas/sas_scsi_host.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 9c96d1bd36e2..704ea06a6e50 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -280,7 +280,8 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd struct scsi_cmnd *cmd, *n; list_for_each_entry_safe(cmd, n, error_q, eh_entry) { - if (cmd == my_cmd) + if (cmd->device->sdev_target == my_cmd->device->sdev_target && + cmd->device->lun == my_cmd->device->lun) sas_eh_finish_cmd(cmd); } } From 39273b58a409cd6d65c9732bdca00bacd1626672 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 21 Feb 2008 17:44:35 -0800 Subject: [PATCH 583/880] i915: fix AR register restore. Make sure the restoration correctly restores the AR registers by flipping the ARX register into index mode before doing anything. Without this, some people have had the text mode restore all green. Signed-off-by: Jesse Barnes Signed-off-by: Linus Torvalds --- drivers/char/drm/i915_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index 4048f39b7eed..b2b451dc4460 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c @@ -222,6 +222,7 @@ static void i915_restore_vga(struct drm_device *dev) dev_priv->saveGR[0x18]); /* Attribute controller registers */ + inb(st01); for (i = 0; i < 20; i++) i915_write_ar(st01, i, dev_priv->saveAR[i], 0); inb(st01); /* switch back to index mode */ From f5ab0d1f8f7df937778c60c3da6f4ef939a54a7b Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Mon, 25 Feb 2008 15:29:55 -0500 Subject: [PATCH 584/880] ext4: Fix BUG when writing to an unitialized extent This patch fixes a bug when writing to preallocated but uninitialized blocks, which resulted in a BUG in fs/buffer.c saying that the buffer is not mapped. When writing to a file, ext4_get_block_wrap() is called with create=1 in order to request that blocks be allocated if necessary. It currently calls ext4_get_blocks() with create=0 in order to do a lookup first. If the inode contains an unitialized data block, the buffer head is left unampped, which ext4_get_blocks_wrap() returns, causing the BUG. We fix this by checking to see if the buffer head is unmapped, and if so, we make sure the the buffer head is mapped by calling ext4_ext_get_blocks with create=1. Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 13 +++++++++++++ fs/ext4/inode.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 8a59f7ba30e6..bcf5d040e328 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2287,9 +2287,22 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, } /* + * Block allocation/map/preallocation routine for extents based files + * + * * Need to be called with * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) + * + * return > 0, number of of blocks already mapped/allocated + * if create == 0 and these are pre-allocated blocks + * buffer head is unmapped + * otherwise blocks are mapped + * + * return = 0, if plain look up failed (blocks have not been allocated) + * buffer head is unmapped + * + * return < 0, error case. */ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 34f3eb615fd5..945cbf6cb1fc 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -908,11 +908,38 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, */ #define DIO_CREDITS 25 + +/* + * + * + * ext4_ext4 get_block() wrapper function + * It will do a look up first, and returns if the blocks already mapped. + * Otherwise it takes the write lock of the i_data_sem and allocate blocks + * and store the allocated blocks in the result buffer head and mark it + * mapped. + * + * If file type is extents based, it will call ext4_ext_get_blocks(), + * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping + * based files + * + * On success, it returns the number of blocks being mapped or allocate. + * if create==0 and the blocks are pre-allocated and uninitialized block, + * the result buffer head is unmapped. If the create ==1, it will make sure + * the buffer head is mapped. + * + * It returns 0 if plain look up failed (blocks have not been allocated), in + * that casem, buffer head is unmapped + * + * It returns the error in case of allocation failure. + */ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, unsigned long max_blocks, struct buffer_head *bh, int create, int extend_disksize) { int retval; + + clear_buffer_mapped(bh); + /* * Try to see if we can get the block without requesting * for new file system block. @@ -926,12 +953,26 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, inode, block, max_blocks, bh, 0, 0); } up_read((&EXT4_I(inode)->i_data_sem)); - if (!create || (retval > 0)) + + /* If it is only a block(s) look up */ + if (!create) + return retval; + + /* + * Returns if the blocks have already allocated + * + * Note that if blocks have been preallocated + * ext4_ext_get_block() returns th create = 0 + * with buffer head unmapped. + */ + if (retval > 0 && buffer_mapped(bh)) return retval; /* - * We need to allocate new blocks which will result - * in i_data update + * New blocks allocate and/or writing to uninitialized extent + * will possibly result in updating i_data, so we take + * the write lock of i_data_sem, and call get_blocks() + * with create == 1 flag. */ down_write((&EXT4_I(inode)->i_data_sem)); /* From 2c98615d3b64ce7888cd46cc668023f456daf287 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 25 Feb 2008 15:41:35 -0500 Subject: [PATCH 585/880] ext4: Don't mark filesystem error if fallocate fails If we fail to allocate blocks don't call ext4_error. Also don't hide errors from ext4_get_blocks_wrap Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bcf5d040e328..9ae6e67090cd 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2661,13 +2661,14 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, EXT4_CREATE_UNINITIALIZED_EXT, 0); - WARN_ON(ret <= 0); if (ret <= 0) { - ext4_error(inode->i_sb, "ext4_fallocate", - "ext4_ext_get_blocks returned error: " - "inode#%lu, block=%u, max_blocks=%lu", +#ifdef EXT4FS_DEBUG + WARN_ON(ret <= 0); + printk(KERN_ERR "%s: ext4_ext_get_blocks " + "returned error inode#%lu, block=%u, " + "max_blocks=%lu", __func__, inode->i_ino, block, max_blocks); - ret = -EIO; +#endif ext4_mark_inode_dirty(handle, inode); ret2 = ext4_journal_stop(handle); break; From 42bf0383d1e09dd1b38f3debb13a76b2f87634b3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 25 Feb 2008 16:38:03 -0500 Subject: [PATCH 586/880] ext4: set EXT4_EXTENTS_FL only for directory and regular files In addition, don't inherit EXT4_EXTENTS_FL from parent directory. If we have a directory with extent flag set and later mount the file system with -o noextents, the files created in that directory will also have extent flag set but we would not have called ext4_ext_tree_init for them. This will cause error later when we are verifying the extent header Signed-off-by: Aneesh Kumar K.V Acked-off-by: Eric Sandeen Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/ialloc.c | 22 +++++++++++++++------- fs/ext4/namei.c | 1 - 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index da18a74b966a..8036b9b5376b 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -702,7 +702,12 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) ei->i_dir_start_lookup = 0; ei->i_disksize = 0; - ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL; + /* + * Don't inherit extent flag from directory. We set extent flag on + * newly created directory and file only if -o extent mount option is + * specified + */ + ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL); if (S_ISLNK(mode)) ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL); /* dirsync only applies to directories */ @@ -745,12 +750,15 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) goto fail_free_drop; } if (test_opt(sb, EXTENTS)) { - EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; - ext4_ext_tree_init(handle, inode); - err = ext4_update_incompat_feature(handle, sb, - EXT4_FEATURE_INCOMPAT_EXTENTS); - if (err) - goto fail; + /* set extent flag only for directory and file */ + if (S_ISDIR(mode) || S_ISREG(mode)) { + EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; + ext4_ext_tree_init(handle, inode); + err = ext4_update_incompat_feature(handle, sb, + EXT4_FEATURE_INCOMPAT_EXTENTS); + if (err) + goto fail; + } } ext4_debug("allocating inode %lu\n", inode->i_ino); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5a79c6b6dc69..28aa2ed4297e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2220,7 +2220,6 @@ static int ext4_symlink (struct inode * dir, inode->i_op = &ext4_fast_symlink_inode_operations; memcpy((char*)&EXT4_I(inode)->i_data,symname,l); inode->i_size = l-1; - EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL; } EXT4_I(inode)->i_disksize = inode->i_size; err = ext4_add_nondir(handle, dentry, inode); From ffad0a44b7216d0f079dcf95a351082099d1e5fb Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 23 Feb 2008 01:38:34 -0500 Subject: [PATCH 587/880] ext4: ext4_find_next_zero_bit needs an aligned address on some arch ext4_find_next_zero_bit and ext4_find_next_bit needs a long aligned address on x8_64. Add mb_find_next_zero_bit and mb_find_next_bit and use them in the mballoc. Fix: https://bugzilla.redhat.com/show_bug.cgi?id=433286 Eric Sandeen debugged the problem and suggested the fix. Signed-off-by: Aneesh Kumar K.V Acked-by: Eric Sandeen Signed-off-by: Mingming Cao Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 62 ++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 6968c53e62ad..ef97f19c2f9d 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -627,21 +627,19 @@ static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, return block; } +static inline void *mb_correct_addr_and_bit(int *bit, void *addr) +{ #if BITS_PER_LONG == 64 -#define mb_correct_addr_and_bit(bit, addr) \ -{ \ - bit += ((unsigned long) addr & 7UL) << 3; \ - addr = (void *) ((unsigned long) addr & ~7UL); \ -} + *bit += ((unsigned long) addr & 7UL) << 3; + addr = (void *) ((unsigned long) addr & ~7UL); #elif BITS_PER_LONG == 32 -#define mb_correct_addr_and_bit(bit, addr) \ -{ \ - bit += ((unsigned long) addr & 3UL) << 3; \ - addr = (void *) ((unsigned long) addr & ~3UL); \ -} + *bit += ((unsigned long) addr & 3UL) << 3; + addr = (void *) ((unsigned long) addr & ~3UL); #else #error "how many bits you are?!" #endif + return addr; +} static inline int mb_test_bit(int bit, void *addr) { @@ -649,34 +647,54 @@ static inline int mb_test_bit(int bit, void *addr) * ext4_test_bit on architecture like powerpc * needs unsigned long aligned address */ - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); return ext4_test_bit(bit, addr); } static inline void mb_set_bit(int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_set_bit(bit, addr); } static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_set_bit_atomic(lock, bit, addr); } static inline void mb_clear_bit(int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_clear_bit(bit, addr); } static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_clear_bit_atomic(lock, bit, addr); } +static inline int mb_find_next_zero_bit(void *addr, int max, int start) +{ + int fix = 0; + addr = mb_correct_addr_and_bit(&fix, addr); + max += fix; + start += fix; + + return ext4_find_next_zero_bit(addr, max, start) - fix; +} + +static inline int mb_find_next_bit(void *addr, int max, int start) +{ + int fix = 0; + addr = mb_correct_addr_and_bit(&fix, addr); + max += fix; + start += fix; + + return ext4_find_next_bit(addr, max, start) - fix; +} + static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) { char *bb; @@ -946,12 +964,12 @@ static void ext4_mb_generate_buddy(struct super_block *sb, /* initialize buddy from bitmap which is aggregation * of on-disk bitmap and preallocations */ - i = ext4_find_next_zero_bit(bitmap, max, 0); + i = mb_find_next_zero_bit(bitmap, max, 0); grp->bb_first_free = i; while (i < max) { fragments++; first = i; - i = ext4_find_next_bit(bitmap, max, i); + i = mb_find_next_bit(bitmap, max, i); len = i - first; free += len; if (len > 1) @@ -959,7 +977,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, else grp->bb_counters[0]++; if (i < max) - i = ext4_find_next_zero_bit(bitmap, max, i); + i = mb_find_next_zero_bit(bitmap, max, i); } grp->bb_fragments = fragments; @@ -1782,7 +1800,7 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, buddy = mb_find_buddy(e4b, i, &max); BUG_ON(buddy == NULL); - k = ext4_find_next_zero_bit(buddy, max, 0); + k = mb_find_next_zero_bit(buddy, max, 0); BUG_ON(k >= max); ac->ac_found++; @@ -1822,7 +1840,7 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, i = e4b->bd_info->bb_first_free; while (free && ac->ac_status == AC_STATUS_CONTINUE) { - i = ext4_find_next_zero_bit(bitmap, + i = mb_find_next_zero_bit(bitmap, EXT4_BLOCKS_PER_GROUP(sb), i); if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { /* @@ -3750,10 +3768,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, } while (bit < end) { - bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit); + bit = mb_find_next_zero_bit(bitmap_bh->b_data, end, bit); if (bit >= end) break; - next = ext4_find_next_bit(bitmap_bh->b_data, end, bit); + next = mb_find_next_bit(bitmap_bh->b_data, end, bit); if (next > end) next = end; start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + From b5762948263dd5e9725a380e7a9626f99e40ae9d Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 25 Oct 2007 20:58:22 -0400 Subject: [PATCH 588/880] [SCSI] mvsas: Add Marvell 6440 SAS/SATA driver Signed-off-by: Jeff Garzik Signed-off-by: James Bottomley --- drivers/scsi/Kconfig | 10 + drivers/scsi/Makefile | 1 + drivers/scsi/mvsas.c | 1825 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1836 insertions(+) create mode 100644 drivers/scsi/mvsas.c diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a7a0813b24cb..c46666a24809 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -992,6 +992,16 @@ config SCSI_IZIP_SLOW_CTR Generally, saying N is fine. +config SCSI_MVSAS + tristate "Marvell 88SE6440 SAS/SATA support" + depends on PCI && SCSI + select SCSI_SAS_LIBSAS + help + This driver supports Marvell SAS/SATA PCI devices. + + To compiler this driver as a module, choose M here: the module + will be called mvsas. + config SCSI_NCR53C406A tristate "NCR53c406a SCSI support" depends on ISA && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 925c26b4fff9..23e6ecbd4778 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -119,6 +119,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o obj-$(CONFIG_SCSI_STEX) += stex.o +obj-$(CONFIG_SCSI_MVSAS) += mvsas.o obj-$(CONFIG_PS3_ROM) += ps3rom.o obj-$(CONFIG_ARM) += arm/ diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c new file mode 100644 index 000000000000..03638b9bb283 --- /dev/null +++ b/drivers/scsi/mvsas.c @@ -0,0 +1,1825 @@ +/* + mvsas.c - Marvell 88SE6440 SAS/SATA support + + Copyright 2007 Red Hat, Inc. + + 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, + 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; see the file COPYING. If not, + write to the Free Software Foundation, 675 Mass Ave, Cambridge, + MA 02139, USA. + + --------------------------------------------------------------- + + Random notes: + * hardware supports controlling the endian-ness of data + structures. this permits elimination of all the le32_to_cpu() + and cpu_to_le32() conversions. + + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "mvsas" +#define DRV_VERSION "0.1" + +#define mr32(reg) readl(regs + MVS_##reg) +#define mw32(reg,val) writel((val), regs + MVS_##reg) +#define mw32_f(reg,val) do { \ + writel((val), regs + MVS_##reg); \ + readl(regs + MVS_##reg); \ + } while (0) + +/* driver compile-time configuration */ +enum driver_configuration { + MVS_TX_RING_SZ = 1024, /* TX ring size (12-bit) */ + MVS_RX_RING_SZ = 1024, /* RX ring size (12-bit) */ + /* software requires power-of-2 + ring size */ + + MVS_SLOTS = 512, /* command slots */ + MVS_SLOT_BUF_SZ = 8192, /* cmd tbl + IU + status + PRD */ + MVS_SSP_CMD_SZ = 64, /* SSP command table buffer size */ + MVS_ATA_CMD_SZ = 128, /* SATA command table buffer size */ + MVS_OAF_SZ = 64, /* Open address frame buffer size */ + + MVS_RX_FIS_COUNT = 17, /* Optional rx'd FISs (max 17) */ +}; + +/* unchangeable hardware details */ +enum hardware_details { + MVS_MAX_PHYS = 8, /* max. possible phys */ + MVS_MAX_PORTS = 8, /* max. possible ports */ + MVS_RX_FISL_SZ = 0x400 + (MVS_RX_FIS_COUNT * 0x100), +}; + +/* peripheral registers (BAR2) */ +enum peripheral_registers { + SPI_CTL = 0x10, /* EEPROM control */ + SPI_CMD = 0x14, /* EEPROM command */ + SPI_DATA = 0x18, /* EEPROM data */ +}; + +enum peripheral_register_bits { + TWSI_RDY = (1U << 7), /* EEPROM interface ready */ + TWSI_RD = (1U << 4), /* EEPROM read access */ + + SPI_ADDR_MASK = 0x3ffff, /* bits 17:0 */ +}; + +/* enhanced mode registers (BAR4) */ +enum hw_registers { + MVS_GBL_CTL = 0x04, /* global control */ + MVS_GBL_INT_STAT = 0x08, /* global irq status */ + MVS_GBL_PI = 0x0C, /* ports implemented bitmask */ + MVS_GBL_PORT_TYPE = 0x00, /* port type */ + + MVS_CTL = 0x100, /* SAS/SATA port configuration */ + MVS_PCS = 0x104, /* SAS/SATA port control/status */ + MVS_CMD_LIST_LO = 0x108, /* cmd list addr */ + MVS_CMD_LIST_HI = 0x10C, + MVS_RX_FIS_LO = 0x110, /* RX FIS list addr */ + MVS_RX_FIS_HI = 0x114, + + MVS_TX_CFG = 0x120, /* TX configuration */ + MVS_TX_LO = 0x124, /* TX (delivery) ring addr */ + MVS_TX_HI = 0x128, + + MVS_RX_PROD_IDX = 0x12C, /* RX producer pointer */ + MVS_RX_CONS_IDX = 0x130, /* RX consumer pointer (RO) */ + MVS_RX_CFG = 0x134, /* RX configuration */ + MVS_RX_LO = 0x138, /* RX (completion) ring addr */ + MVS_RX_HI = 0x13C, + + MVS_INT_COAL = 0x148, /* Int coalescing config */ + MVS_INT_COAL_TMOUT = 0x14C, /* Int coalescing timeout */ + MVS_INT_STAT = 0x150, /* Central int status */ + MVS_INT_MASK = 0x154, /* Central int enable */ + MVS_INT_STAT_SRS = 0x158, /* SATA register set status */ + + /* ports 1-3 follow after this */ + MVS_P0_INT_STAT = 0x160, /* port0 interrupt status */ + MVS_P0_INT_MASK = 0x164, /* port0 interrupt mask */ + + /* ports 1-3 follow after this */ + MVS_P0_SER_CTLSTAT = 0x180, /* port0 serial control/status */ + + MVS_CMD_ADDR = 0x1B8, /* Command register port (addr) */ + MVS_CMD_DATA = 0x1BC, /* Command register port (data) */ + + /* ports 1-3 follow after this */ + MVS_P0_CFG_ADDR = 0x1C0, /* port0 phy register address */ + MVS_P0_CFG_DATA = 0x1C4, /* port0 phy register data */ +}; + +enum hw_register_bits { + /* MVS_GBL_CTL */ + INT_EN = (1U << 1), /* Global int enable */ + HBA_RST = (1U << 0), /* HBA reset */ + + /* MVS_GBL_INT_STAT */ + INT_XOR = (1U << 4), /* XOR engine event */ + INT_SAS_SATA = (1U << 0), /* SAS/SATA event */ + + /* MVS_GBL_PORT_TYPE */ /* shl for ports 1-3 */ + SATA_TARGET = (1U << 16), /* port0 SATA target enable */ + AUTO_DET = (1U << 8), /* port0 SAS/SATA autodetect */ + SAS_MODE = (1U << 0), /* port0 SAS(1), SATA(0) mode */ + /* SAS_MODE value may be + * dictated (in hw) by values + * of SATA_TARGET & AUTO_DET + */ + + /* MVS_TX_CFG */ + TX_EN = (1U << 16), /* Enable TX */ + TX_RING_SZ_MASK = 0xfff, /* TX ring size, bits 11:0 */ + + /* MVS_RX_CFG */ + RX_EN = (1U << 16), /* Enable RX */ + RX_RING_SZ_MASK = 0xfff, /* RX ring size, bits 11:0 */ + + /* MVS_INT_COAL */ + COAL_EN = (1U << 16), /* Enable int coalescing */ + + /* MVS_INT_STAT, MVS_INT_MASK */ + CINT_I2C = (1U << 31), /* I2C event */ + CINT_SW0 = (1U << 30), /* software event 0 */ + CINT_SW1 = (1U << 29), /* software event 1 */ + CINT_PRD_BC = (1U << 28), /* PRD BC err for read cmd */ + CINT_DMA_PCIE = (1U << 27), /* DMA to PCIE timeout */ + CINT_MEM = (1U << 26), /* int mem parity err */ + CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */ + CINT_SRS = (1U << 3), /* SRS event */ + CINT_CI_STOP = (1U << 10), /* cmd issue stopped */ + CINT_DONE = (1U << 0), /* cmd completion */ + + /* shl for ports 1-3 */ + CINT_PORT_STOPPED = (1U << 16), /* port0 stopped */ + CINT_PORT = (1U << 8), /* port0 event */ + + /* TX (delivery) ring bits */ + TXQ_CMD_SHIFT = 29, + TXQ_CMD_SSP = 1, /* SSP protocol */ + TXQ_CMD_SMP = 2, /* SMP protocol */ + TXQ_CMD_STP = 3, /* STP/SATA protocol */ + TXQ_CMD_SSP_FREE_LIST = 4, /* add to SSP targ free list */ + TXQ_CMD_SLOT_RESET = 7, /* reset command slot */ + TXQ_MODE_I = (1U << 28), /* mode: 0=target,1=initiator */ + TXQ_PRIO_HI = (1U << 27), /* priority: 0=normal, 1=high */ + TXQ_SRS_SHIFT = 20, /* SATA register set */ + TXQ_SRS_MASK = 0x7f, + TXQ_PHY_SHIFT = 12, /* PHY bitmap */ + TXQ_PHY_MASK = 0xff, + TXQ_SLOT_MASK = 0xfff, /* slot number */ + + /* RX (completion) ring bits */ + RXQ_GOOD = (1U << 23), /* Response good */ + RXQ_SLOT_RESET = (1U << 21), /* Slot reset complete */ + RXQ_CMD_RX = (1U << 20), /* target cmd received */ + RXQ_ATTN = (1U << 19), /* attention */ + RXQ_RSP = (1U << 18), /* response frame xfer'd */ + RXQ_ERR = (1U << 17), /* err info rec xfer'd */ + RXQ_DONE = (1U << 16), /* cmd complete */ + RXQ_SLOT_MASK = 0xfff, /* slot number */ + + /* mvs_cmd_hdr bits */ + MCH_PRD_LEN_SHIFT = 16, /* 16-bit PRD table len */ + MCH_SSP_FR_TYPE_SHIFT = 13, /* SSP frame type */ + + /* SSP initiator only */ + MCH_SSP_FR_CMD = 0x0, /* COMMAND frame */ + + /* SSP initiator or target */ + MCH_SSP_FR_TASK = 0x1, /* TASK frame */ + + /* SSP target only */ + MCH_SSP_FR_XFER_RDY = 0x4, /* XFER_RDY frame */ + MCH_SSP_FR_RESP = 0x5, /* RESPONSE frame */ + MCH_SSP_FR_READ = 0x6, /* Read DATA frame(s) */ + MCH_SSP_FR_READ_RESP = 0x7, /* ditto, plus RESPONSE */ + + MCH_PASSTHRU = (1U << 12), /* pass-through (SSP) */ + MCH_FBURST = (1U << 11), /* first burst (SSP) */ + MCH_CHK_LEN = (1U << 10), /* chk xfer len (SSP) */ + MCH_RETRY = (1U << 9), /* tport layer retry (SSP) */ + MCH_PROTECTION = (1U << 8), /* protection info rec (SSP) */ + MCH_RESET = (1U << 7), /* Reset (STP/SATA) */ + MCH_FPDMA = (1U << 6), /* First party DMA (STP/SATA) */ + MCH_ATAPI = (1U << 5), /* ATAPI (STP/SATA) */ + MCH_BIST = (1U << 4), /* BIST activate (STP/SATA) */ + MCH_PMP_MASK = 0xf, /* PMP from cmd FIS (STP/SATA)*/ + + CCTL_RST = (1U << 5), /* port logic reset */ + + /* 0(LSB first), 1(MSB first) */ + CCTL_ENDIAN_DATA = (1U << 3), /* PRD data */ + CCTL_ENDIAN_RSP = (1U << 2), /* response frame */ + CCTL_ENDIAN_OPEN = (1U << 1), /* open address frame */ + CCTL_ENDIAN_CMD = (1U << 0), /* command table */ + + /* MVS_Px_SER_CTLSTAT (per-phy control) */ + PHY_SSP_RST = (1U << 3), /* reset SSP link layer */ + PHY_BCAST_CHG = (1U << 2), /* broadcast(change) notif */ + PHY_RST_HARD = (1U << 1), /* hard reset + phy reset */ + PHY_RST = (1U << 0), /* phy reset */ + + /* MVS_Px_INT_STAT, MVS_Px_INT_MASK (per-phy events) */ + PHYEV_UNASSOC_FIS = (1U << 19), /* unassociated FIS rx'd */ + PHYEV_AN = (1U << 18), /* SATA async notification */ + PHYEV_BIST_ACT = (1U << 17), /* BIST activate FIS */ + PHYEV_SIG_FIS = (1U << 16), /* signature FIS */ + PHYEV_POOF = (1U << 12), /* phy ready from 1 -> 0 */ + PHYEV_IU_BIG = (1U << 11), /* IU too long err */ + PHYEV_IU_SMALL = (1U << 10), /* IU too short err */ + PHYEV_UNK_TAG = (1U << 9), /* unknown tag */ + PHYEV_BROAD_CH = (1U << 8), /* broadcast(CHANGE) */ + PHYEV_COMWAKE = (1U << 7), /* COMWAKE rx'd */ + PHYEV_PORT_SEL = (1U << 6), /* port selector present */ + PHYEV_HARD_RST = (1U << 5), /* hard reset rx'd */ + PHYEV_ID_TMOUT = (1U << 4), /* identify timeout */ + PHYEV_ID_FAIL = (1U << 3), /* identify failed */ + PHYEV_ID_DONE = (1U << 2), /* identify done */ + PHYEV_HARD_RST_DONE = (1U << 1), /* hard reset done */ + PHYEV_RDY_CH = (1U << 0), /* phy ready changed state */ + + /* MVS_PCS */ + PCS_SATA_RETRY = (1U << 8), /* retry ctl FIS on R_ERR */ + PCS_RSP_RX_EN = (1U << 7), /* raw response rx */ + PCS_SELF_CLEAR = (1U << 5), /* self-clearing int mode */ + PCS_FIS_RX_EN = (1U << 4), /* FIS rx enable */ + PCS_CMD_STOP_ERR = (1U << 3), /* cmd stop-on-err enable */ + PCS_CMD_RST = (1U << 2), /* reset cmd issue */ + PCS_CMD_EN = (1U << 0), /* enable cmd issue */ +}; + +enum mvs_info_flags { + MVF_MSI = (1U << 0), /* MSI is enabled */ + MVF_PHY_PWR_FIX = (1U << 1), /* bug workaround */ +}; + +enum sas_cmd_port_registers { + CMD_CMRST_OOB_DET = 0x100, /* COMRESET OOB detect register */ + CMD_CMWK_OOB_DET = 0x104, /* COMWAKE OOB detect register */ + CMD_CMSAS_OOB_DET = 0x108, /* COMSAS OOB detect register */ + CMD_BRST_OOB_DET = 0x10c, /* burst OOB detect register */ + CMD_OOB_SPACE = 0x110, /* OOB space control register */ + CMD_OOB_BURST = 0x114, /* OOB burst control register */ + CMD_PHY_TIMER = 0x118, /* PHY timer control register */ + CMD_PHY_CONFIG0 = 0x11c, /* PHY config register 0 */ + CMD_PHY_CONFIG1 = 0x120, /* PHY config register 1 */ + CMD_SAS_CTL0 = 0x124, /* SAS control register 0 */ + CMD_SAS_CTL1 = 0x128, /* SAS control register 1 */ + CMD_SAS_CTL2 = 0x12c, /* SAS control register 2 */ + CMD_SAS_CTL3 = 0x130, /* SAS control register 3 */ + CMD_ID_TEST = 0x134, /* ID test register */ + CMD_PL_TIMER = 0x138, /* PL timer register */ + CMD_WD_TIMER = 0x13c, /* WD timer register */ + CMD_PORT_SEL_COUNT = 0x140, /* port selector count register */ + CMD_APP_MEM_CTL = 0x144, /* Application Memory Control */ + CMD_XOR_MEM_CTL = 0x148, /* XOR Block Memory Control */ + CMD_DMA_MEM_CTL = 0x14c, /* DMA Block Memory Control */ + CMD_PORT_MEM_CTL0 = 0x150, /* Port Memory Control 0 */ + CMD_PORT_MEM_CTL1 = 0x154, /* Port Memory Control 1 */ + CMD_SATA_PORT_MEM_CTL0 = 0x158, /* SATA Port Memory Control 0 */ + CMD_SATA_PORT_MEM_CTL1 = 0x15c, /* SATA Port Memory Control 1 */ + CMD_XOR_MEM_BIST_CTL = 0x160, /* XOR Memory BIST Control */ + CMD_XOR_MEM_BIST_STAT = 0x164, /* XOR Memroy BIST Status */ + CMD_DMA_MEM_BIST_CTL = 0x168, /* DMA Memory BIST Control */ + CMD_DMA_MEM_BIST_STAT = 0x16c, /* DMA Memory BIST Status */ + CMD_PORT_MEM_BIST_CTL = 0x170, /* Port Memory BIST Control */ + CMD_PORT_MEM_BIST_STAT0 = 0x174, /* Port Memory BIST Status 0 */ + CMD_PORT_MEM_BIST_STAT1 = 0x178, /* Port Memory BIST Status 1 */ + CMD_STP_MEM_BIST_CTL = 0x17c, /* STP Memory BIST Control */ + CMD_STP_MEM_BIST_STAT0 = 0x180, /* STP Memory BIST Status 0 */ + CMD_STP_MEM_BIST_STAT1 = 0x184, /* STP Memory BIST Status 1 */ + CMD_RESET_COUNT = 0x188, /* Reset Count */ + CMD_MONTR_DATA_SEL = 0x18C, /* Monitor Data/Select */ + CMD_PLL_PHY_CONFIG = 0x190, /* PLL/PHY Configuration */ + CMD_PHY_CTL = 0x194, /* PHY Control and Status */ + CMD_PHY_TEST_COUNT0 = 0x198, /* Phy Test Count 0 */ + CMD_PHY_TEST_COUNT1 = 0x19C, /* Phy Test Count 1 */ + CMD_PHY_TEST_COUNT2 = 0x1A0, /* Phy Test Count 2 */ + CMD_APP_ERR_CONFIG = 0x1A4, /* Application Error Configuration */ + CMD_PND_FIFO_CTL0 = 0x1A8, /* Pending FIFO Control 0 */ + CMD_HOST_CTL = 0x1AC, /* Host Control Status */ + CMD_HOST_WR_DATA = 0x1B0, /* Host Write Data */ + CMD_HOST_RD_DATA = 0x1B4, /* Host Read Data */ + CMD_PHY_MODE_21 = 0x1B8, /* Phy Mode 21 */ + CMD_SL_MODE0 = 0x1BC, /* SL Mode 0 */ + CMD_SL_MODE1 = 0x1C0, /* SL Mode 1 */ + CMD_PND_FIFO_CTL1 = 0x1C4, /* Pending FIFO Control 1 */ +}; + +/* SAS/SATA configuration port registers, aka phy registers */ +enum sas_sata_config_port_regs { + PHYR_IDENTIFY = 0x0, /* info for IDENTIFY frame */ + PHYR_ADDR_LO = 0x4, /* my SAS address (low) */ + PHYR_ADDR_HI = 0x8, /* my SAS address (high) */ + PHYR_ATT_DEV_INFO = 0xC, /* attached device info */ + PHYR_ATT_ADDR_LO = 0x10, /* attached dev SAS addr (low) */ + PHYR_ATT_ADDR_HI = 0x14, /* attached dev SAS addr (high) */ + PHYR_SATA_CTL = 0x18, /* SATA control */ + PHYR_PHY_STAT = 0x1C, /* PHY status */ + PHYR_WIDE_PORT = 0x38, /* wide port participating */ + PHYR_CURRENT0 = 0x80, /* current connection info 0 */ + PHYR_CURRENT1 = 0x84, /* current connection info 1 */ + PHYR_CURRENT2 = 0x88, /* current connection info 2 */ +}; + +enum pci_cfg_registers { + PCR_PHY_CTL = 0x40, + PCR_PHY_CTL2 = 0x90, +}; + +enum pci_cfg_register_bits { + PCTL_PWR_ON = (0xFU << 24), + PCTL_OFF = (0xFU << 12), +}; + +enum nvram_layout_offsets { + NVR_SIG = 0x00, /* 0xAA, 0x55 */ + NVR_SAS_ADDR = 0x02, /* 8-byte SAS address */ +}; + +enum chip_flavors { + chip_6320, + chip_6440, + chip_6480, +}; + +struct mvs_chip_info { + unsigned int n_phy; + unsigned int srs_sz; + unsigned int slot_width; +}; + +struct mvs_err_info { + __le32 flags; + __le32 flags2; +}; + +struct mvs_prd { + __le64 addr; /* 64-bit buffer address */ + __le32 reserved; + __le32 len; /* 16-bit length */ +}; + +struct mvs_cmd_hdr { + __le32 flags; /* PRD tbl len; SAS, SATA ctl */ + __le32 lens; /* cmd, max resp frame len */ + __le32 tags; /* targ port xfer tag; tag */ + __le32 data_len; /* data xfer len */ + __le64 cmd_tbl; /* command table address */ + __le64 open_frame; /* open addr frame address */ + __le64 status_buf; /* status buffer address */ + __le64 prd_tbl; /* PRD tbl address */ + __le32 reserved[4]; +}; + +struct mvs_slot_info { + struct sas_task *task; + unsigned int n_elem; + + /* DMA buffer for storing cmd tbl, open addr frame, status buffer, + * and PRD table + */ + void *buf; + dma_addr_t buf_dma; + + void *response; +}; + +struct mvs_port { + struct asd_sas_port sas_port; +}; + +struct mvs_phy { + struct mvs_port *port; + struct asd_sas_phy sas_phy; + + u8 frame_rcvd[24 + 1024]; +}; + +struct mvs_info { + unsigned long flags; + + spinlock_t lock; /* host-wide lock */ + struct pci_dev *pdev; /* our device */ + void __iomem *regs; /* enhanced mode registers */ + void __iomem *peri_regs; /* peripheral registers */ + + u8 sas_addr[SAS_ADDR_SIZE]; + struct sas_ha_struct sas; /* SCSI/SAS glue */ + struct Scsi_Host *shost; + + __le32 *tx; /* TX (delivery) DMA ring */ + dma_addr_t tx_dma; + u32 tx_prod; /* cached next-producer idx */ + + __le32 *rx; /* RX (completion) DMA ring */ + dma_addr_t rx_dma; + u32 rx_cons; /* RX consumer idx */ + + __le32 *rx_fis; /* RX'd FIS area */ + dma_addr_t rx_fis_dma; + + struct mvs_cmd_hdr *slot; /* DMA command header slots */ + dma_addr_t slot_dma; + + const struct mvs_chip_info *chip; + + /* further per-slot information */ + struct mvs_slot_info slot_info[MVS_SLOTS]; + unsigned long tags[(MVS_SLOTS / sizeof(unsigned long)) + 1]; + + struct mvs_phy phy[MVS_MAX_PHYS]; + struct mvs_port port[MVS_MAX_PHYS]; +}; + +static struct scsi_transport_template *mvs_stt; + +static const struct mvs_chip_info mvs_chips[] = { + [chip_6320] = { 2, 16, 9 }, + [chip_6440] = { 4, 16, 9 }, + [chip_6480] = { 8, 32, 10 }, +}; + +static struct scsi_host_template mvs_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .queuecommand = sas_queuecommand, + .target_alloc = sas_target_alloc, + .slave_configure = sas_slave_configure, + .slave_destroy = sas_slave_destroy, + .change_queue_depth = sas_change_queue_depth, + .change_queue_type = sas_change_queue_type, + .bios_param = sas_bios_param, + .can_queue = 1, + .cmd_per_lun = 1, + .this_id = -1, + .sg_tablesize = SG_ALL, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler= sas_eh_device_reset_handler, + .eh_bus_reset_handler = sas_eh_bus_reset_handler, + .slave_alloc = sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, +}; + +static void mvs_int_rx(struct mvs_info *mvi, bool self_clear); + +/* move to PCI layer or libata core? */ +static int pci_go_64(struct pci_dev *pdev) +{ + int rc; + + if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { + rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + if (rc) { + rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "64-bit DMA enable failed\n"); + return rc; + } + } + } else { + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "32-bit DMA enable failed\n"); + return rc; + } + rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "32-bit consistent DMA enable failed\n"); + return rc; + } + } + + return rc; +} + +static void mvs_tag_clear(struct mvs_info *mvi, unsigned int tag) +{ + mvi->tags[tag / sizeof(unsigned long)] &= + ~(1UL << (tag % sizeof(unsigned long))); +} + +static void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) +{ + mvi->tags[tag / sizeof(unsigned long)] |= + (1UL << (tag % sizeof(unsigned long))); +} + +static bool mvs_tag_test(struct mvs_info *mvi, unsigned int tag) +{ + return mvi->tags[tag / sizeof(unsigned long)] & + (1UL << (tag % sizeof(unsigned long))); +} + +static int mvs_tag_alloc(struct mvs_info *mvi, unsigned int *tag_out) +{ + unsigned int i; + + for (i = 0; i < MVS_SLOTS; i++) + if (!mvs_tag_test(mvi, i)) { + mvs_tag_set(mvi, i); + *tag_out = i; + return 0; + } + + return -EBUSY; +} + +static int mvs_eep_read(void __iomem *regs, unsigned int addr, u32 *data) +{ + int timeout = 1000; + + if (addr & ~SPI_ADDR_MASK) + return -EINVAL; + + writel(addr, regs + SPI_CMD); + writel(TWSI_RD, regs + SPI_CTL); + + while (timeout-- > 0) { + if (readl(regs + SPI_CTL) & TWSI_RDY) { + *data = readl(regs + SPI_DATA); + return 0; + } + + udelay(10); + } + + return -EBUSY; +} + +static int mvs_eep_read_buf(void __iomem *regs, unsigned int addr, + void *buf, unsigned int buflen) +{ + unsigned int addr_end, tmp_addr, i, j; + u32 tmp = 0; + int rc; + u8 *tmp8, *buf8 = buf; + + addr_end = addr + buflen; + tmp_addr = ALIGN(addr, 4); + if (addr > 0xff) + return -EINVAL; + + j = addr & 0x3; + if (j) { + rc = mvs_eep_read(regs, tmp_addr, &tmp); + if (rc) + return rc; + + tmp8 = (u8 *) &tmp; + for (i = j; i < 4; i++) + *buf8++ = tmp8[i]; + + tmp_addr += 4; + } + + for (j = ALIGN(addr_end, 4); tmp_addr < j; tmp_addr += 4) { + rc = mvs_eep_read(regs, tmp_addr, &tmp); + if (rc) + return rc; + + memcpy(buf8, &tmp, 4); + buf8 += 4; + } + + if (tmp_addr < addr_end) { + rc = mvs_eep_read(regs, tmp_addr, &tmp); + if (rc) + return rc; + + tmp8 = (u8 *) &tmp; + j = addr_end - tmp_addr; + for (i = 0; i < j; i++) + *buf8++ = tmp8[i]; + + tmp_addr += 4; + } + + return 0; +} + +static int mvs_nvram_read(struct mvs_info *mvi, unsigned int addr, + void *buf, unsigned int buflen) +{ + void __iomem *regs = mvi->regs; + int rc, i; + unsigned int sum; + u8 hdr[2], *tmp; + const char *msg; + + rc = mvs_eep_read_buf(regs, addr, &hdr, 2); + if (rc) { + msg = "nvram hdr read failed"; + goto err_out; + } + rc = mvs_eep_read_buf(regs, addr + 2, buf, buflen); + if (rc) { + msg = "nvram read failed"; + goto err_out; + } + + if (hdr[0] != 0x5A) { /* entry id */ + msg = "invalid nvram entry id"; + rc = -ENOENT; + goto err_out; + } + + tmp = buf; + sum = ((unsigned int)hdr[0]) + ((unsigned int)hdr[1]); + for (i = 0; i < buflen; i++) + sum += ((unsigned int)tmp[i]); + + if (sum) { + msg = "nvram checksum failure"; + rc = -EILSEQ; + goto err_out; + } + + return 0; + +err_out: + dev_printk(KERN_ERR, &mvi->pdev->dev, "%s", msg); + return rc; +} + +static void mvs_int_port(struct mvs_info *mvi, int port_no, u32 events) +{ + /* FIXME */ +} + +static void mvs_int_sata(struct mvs_info *mvi) +{ + /* FIXME */ +} + +static void mvs_slot_free(struct mvs_info *mvi, struct sas_task *task, + struct mvs_slot_info *slot, unsigned int slot_idx) +{ + if (slot->n_elem) + pci_unmap_sg(mvi->pdev, task->scatter, + slot->n_elem, task->data_dir); + + switch (task->task_proto) { + case SAS_PROTOCOL_SMP: + pci_unmap_sg(mvi->pdev, &task->smp_task.smp_resp, 1, + PCI_DMA_FROMDEVICE); + pci_unmap_sg(mvi->pdev, &task->smp_task.smp_req, 1, + PCI_DMA_TODEVICE); + break; + + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SSP: + default: + /* do nothing */ + break; + } + + mvs_tag_clear(mvi, slot_idx); +} + +static void mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, + unsigned int slot_idx) +{ + /* FIXME */ +} + +static void mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc) +{ + unsigned int slot_idx = rx_desc & RXQ_SLOT_MASK; + struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; + struct sas_task *task = slot->task; + struct task_status_struct *tstat = &task->task_status; + bool aborted; + + spin_lock(&task->task_state_lock); + aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED; + if (!aborted) { + task->task_state_flags &= + ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); + task->task_state_flags |= SAS_TASK_STATE_DONE; + } + spin_unlock(&task->task_state_lock); + + if (aborted) + return; + + memset(tstat, 0, sizeof(*tstat)); + tstat->resp = SAS_TASK_COMPLETE; + + /* error info record present */ + if (rx_desc & RXQ_ERR) { + tstat->stat = SAM_CHECK_COND; + mvs_slot_err(mvi, task, slot_idx); + goto out; + } + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + /* hw says status == 0, datapres == 0 */ + if (rx_desc & RXQ_GOOD) + tstat->stat = SAM_GOOD; + + /* response frame present */ + else if (rx_desc & RXQ_RSP) { + struct ssp_response_iu *iu = + slot->response + sizeof(struct mvs_err_info); + sas_ssp_task_response(&mvi->pdev->dev, task, iu); + } + + /* should never happen? */ + else + tstat->stat = SAM_CHECK_COND; + break; + + case SAS_PROTOCOL_SMP: + tstat->stat = SAM_GOOD; + break; + + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + if ((rx_desc & (RXQ_DONE | RXQ_ERR | RXQ_ATTN)) == RXQ_DONE) + tstat->stat = SAM_GOOD; + else + tstat->stat = SAM_CHECK_COND; + /* FIXME: read taskfile data from SATA register set + * associated with SATA target + */ + break; + + default: + tstat->stat = SAM_CHECK_COND; + break; + } + +out: + mvs_slot_free(mvi, task, slot, slot_idx); + task->task_done(task); +} + +static void mvs_int_full(struct mvs_info *mvi) +{ + void __iomem *regs = mvi->regs; + u32 tmp, stat; + int i; + + stat = mr32(INT_STAT); + + for (i = 0; i < MVS_MAX_PORTS; i++) { + tmp = (stat >> i) & (CINT_PORT | CINT_PORT_STOPPED); + if (tmp) + mvs_int_port(mvi, i, tmp); + } + + if (stat & CINT_SRS) + mvs_int_sata(mvi); + + if (stat & (CINT_CI_STOP | CINT_DONE)) + mvs_int_rx(mvi, false); + + mw32(INT_STAT, stat); +} + +static void mvs_int_rx(struct mvs_info *mvi, bool self_clear) +{ + u32 rx_prod_idx, rx_desc; + bool attn = false; + + /* the first dword in the RX ring is special: it contains + * a mirror of the hardware's RX producer index, so that + * we don't have to stall the CPU reading that register. + * The actual RX ring is offset by one dword, due to this. + */ + rx_prod_idx = le32_to_cpu(mvi->rx[0]) & 0xfff; + if (rx_prod_idx == 0xfff) { /* h/w hasn't touched RX ring yet */ + mvi->rx_cons = 0xfff; + return; + } + if (mvi->rx_cons == 0xfff) + mvi->rx_cons = MVS_RX_RING_SZ - 1; + + while (mvi->rx_cons != rx_prod_idx) { + /* increment our internal RX consumer pointer */ + mvi->rx_cons = (mvi->rx_cons + 1) & (MVS_RX_RING_SZ - 1); + + /* Read RX descriptor at offset+1, due to above */ + rx_desc = le32_to_cpu(mvi->rx[mvi->rx_cons + 1]); + + if (rx_desc & RXQ_DONE) + /* we had a completion, error or no */ + mvs_slot_complete(mvi, rx_desc); + + if (rx_desc & RXQ_ATTN) + attn = true; + } + + if (attn && self_clear) + mvs_int_full(mvi); + +} + +static irqreturn_t mvs_interrupt(int irq, void *opaque) +{ + struct mvs_info *mvi = opaque; + void __iomem *regs = mvi->regs; + u32 stat; + + stat = mr32(GBL_INT_STAT); + if (stat == 0 || stat == 0xffffffff) + return IRQ_NONE; + + spin_lock(&mvi->lock); + + mvs_int_full(mvi); + + spin_unlock(&mvi->lock); + + return IRQ_HANDLED; +} + +static irqreturn_t mvs_msi_interrupt(int irq, void *opaque) +{ + struct mvs_info *mvi = opaque; + + spin_lock(&mvi->lock); + + mvs_int_rx(mvi, true); + + spin_unlock(&mvi->lock); + + return IRQ_HANDLED; +} + +struct mvs_task_exec_info { + struct sas_task *task; + struct mvs_cmd_hdr *hdr; + unsigned int tag; + int n_elem; +}; + +static int mvs_task_prep_smp(struct mvs_info *mvi, struct mvs_task_exec_info *tei) +{ + int elem, rc; + struct mvs_cmd_hdr *hdr = tei->hdr; + struct scatterlist *sg_req, *sg_resp; + unsigned int req_len, resp_len, tag = tei->tag; + + /* + * DMA-map SMP request, response buffers + */ + + sg_req = &tei->task->smp_task.smp_req; + elem = pci_map_sg(mvi->pdev, sg_req, 1, PCI_DMA_TODEVICE); + if (!elem) + return -ENOMEM; + req_len = sg_dma_len(sg_req); + + sg_resp = &tei->task->smp_task.smp_resp; + elem = pci_map_sg(mvi->pdev, sg_resp, 1, PCI_DMA_FROMDEVICE); + if (!elem) { + rc = -ENOMEM; + goto err_out; + } + resp_len = sg_dma_len(sg_resp); + + /* must be in dwords */ + if ((req_len & 0x3) || (resp_len & 0x3)) { + rc = -EINVAL; + goto err_out_2; + } + + /* + * Fill in TX ring and command slot header + */ + + mvi->tx[tag] = cpu_to_le32( + (TXQ_CMD_SMP << TXQ_CMD_SHIFT) | TXQ_MODE_I | tag); + + hdr->flags = 0; + hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4)); + hdr->tags = cpu_to_le32(tag); + hdr->data_len = 0; + hdr->cmd_tbl = cpu_to_le64(sg_dma_address(sg_req)); + hdr->open_frame = 0; + hdr->status_buf = cpu_to_le64(sg_dma_address(sg_resp)); + hdr->prd_tbl = 0; + + return 0; + +err_out_2: + pci_unmap_sg(mvi->pdev, &tei->task->smp_task.smp_resp, 1, + PCI_DMA_FROMDEVICE); +err_out: + pci_unmap_sg(mvi->pdev, &tei->task->smp_task.smp_req, 1, + PCI_DMA_TODEVICE); + return rc; +} + +static int mvs_task_prep_ata(struct mvs_info *mvi, + struct mvs_task_exec_info *tei) +{ + struct sas_task *task = tei->task; + struct domain_device *dev = task->dev; + struct mvs_cmd_hdr *hdr = tei->hdr; + struct asd_sas_port *sas_port = dev->port; + unsigned int tag = tei->tag; + struct mvs_slot_info *slot = &mvi->slot_info[tag]; + u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); + struct scatterlist *sg; + struct mvs_prd *buf_prd; + void *buf_tmp; + u8 *buf_cmd, *buf_oaf; + dma_addr_t buf_tmp_dma; + unsigned int i, req_len, resp_len; + + /* FIXME: fill in SATA register set */ + mvi->tx[tag] = cpu_to_le32(TXQ_MODE_I | tag | + (TXQ_CMD_STP << TXQ_CMD_SHIFT) | + (sas_port->phy_mask << TXQ_PHY_SHIFT)); + + if (task->ata_task.use_ncq) + flags |= MCH_FPDMA; + if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) + flags |= MCH_ATAPI; + /* FIXME: fill in port multiplier number */ + + hdr->flags = cpu_to_le32(flags); + hdr->tags = cpu_to_le32(tag); + hdr->data_len = cpu_to_le32(task->total_xfer_len); + + /* + * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs + */ + memset(slot->buf, 0, MVS_SLOT_BUF_SZ); + + /* region 1: command table area (MVS_ATA_CMD_SZ bytes) ***************/ + buf_cmd = + buf_tmp = slot->buf; + buf_tmp_dma = slot->buf_dma; + + hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma); + + buf_tmp += MVS_ATA_CMD_SZ; + buf_tmp_dma += MVS_ATA_CMD_SZ; + + /* region 2: open address frame area (MVS_OAF_SZ bytes) **********/ + /* used for STP. unused for SATA? */ + buf_oaf = buf_tmp; + hdr->open_frame = cpu_to_le64(buf_tmp_dma); + + buf_tmp += MVS_OAF_SZ; + buf_tmp_dma += MVS_OAF_SZ; + + /* region 3: PRD table ***********************************************/ + buf_prd = buf_tmp; + hdr->prd_tbl = cpu_to_le64(buf_tmp_dma); + + i = sizeof(struct mvs_prd) * tei->n_elem; + buf_tmp += i; + buf_tmp_dma += i; + + /* region 4: status buffer (larger the PRD, smaller this buf) ********/ + /* FIXME: probably unused, for SATA. kept here just in case + * we get a STP/SATA error information record + */ + slot->response = buf_tmp; + hdr->status_buf = cpu_to_le64(buf_tmp_dma); + + req_len = sizeof(struct ssp_frame_hdr) + 28; + resp_len = MVS_SLOT_BUF_SZ - MVS_ATA_CMD_SZ - + sizeof(struct mvs_err_info) - i; + + /* request, response lengths */ + hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4)); + + /* fill in command FIS and ATAPI CDB */ + memcpy(buf_cmd, &task->ata_task.fis, + sizeof(struct host_to_dev_fis)); + memcpy(buf_cmd + 0x40, task->ata_task.atapi_packet, 16); + + /* fill in PRD (scatter/gather) table, if any */ + sg = task->scatter; + for (i = 0; i < tei->n_elem; i++) { + buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); + buf_prd->len = cpu_to_le32(sg_dma_len(sg)); + + sg++; + buf_prd++; + } + + return 0; +} + +static int mvs_task_prep_ssp(struct mvs_info *mvi, + struct mvs_task_exec_info *tei) +{ + struct sas_task *task = tei->task; + struct asd_sas_port *sas_port = task->dev->port; + struct mvs_cmd_hdr *hdr = tei->hdr; + struct mvs_slot_info *slot; + struct scatterlist *sg; + unsigned int resp_len, req_len, i, tag = tei->tag; + struct mvs_prd *buf_prd; + struct ssp_frame_hdr *ssp_hdr; + void *buf_tmp; + u8 *buf_cmd, *buf_oaf, fburst = 0; + dma_addr_t buf_tmp_dma; + u32 flags; + + slot = &mvi->slot_info[tag]; + + mvi->tx[tag] = cpu_to_le32(TXQ_MODE_I | tag | + (TXQ_CMD_SSP << TXQ_CMD_SHIFT) | + (sas_port->phy_mask << TXQ_PHY_SHIFT)); + + flags = MCH_RETRY; + if (task->ssp_task.enable_first_burst) { + flags |= MCH_FBURST; + fburst = (1 << 7); + } + hdr->flags = cpu_to_le32(flags | + (tei->n_elem << MCH_PRD_LEN_SHIFT) | + (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT)); + + hdr->tags = cpu_to_le32(tag); + hdr->data_len = cpu_to_le32(task->total_xfer_len); + + /* + * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs + */ + memset(slot->buf, 0, MVS_SLOT_BUF_SZ); + + /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ***************/ + buf_cmd = + buf_tmp = slot->buf; + buf_tmp_dma = slot->buf_dma; + + hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma); + + buf_tmp += MVS_SSP_CMD_SZ; + buf_tmp_dma += MVS_SSP_CMD_SZ; + + /* region 2: open address frame area (MVS_OAF_SZ bytes) **********/ + buf_oaf = buf_tmp; + hdr->open_frame = cpu_to_le64(buf_tmp_dma); + + buf_tmp += MVS_OAF_SZ; + buf_tmp_dma += MVS_OAF_SZ; + + /* region 3: PRD table ***********************************************/ + buf_prd = buf_tmp; + hdr->prd_tbl = cpu_to_le64(buf_tmp_dma); + + i = sizeof(struct mvs_prd) * tei->n_elem; + buf_tmp += i; + buf_tmp_dma += i; + + /* region 4: status buffer (larger the PRD, smaller this buf) ********/ + slot->response = buf_tmp; + hdr->status_buf = cpu_to_le64(buf_tmp_dma); + + req_len = sizeof(struct ssp_frame_hdr) + 28; + resp_len = MVS_SLOT_BUF_SZ - MVS_SSP_CMD_SZ - MVS_OAF_SZ - + sizeof(struct mvs_err_info) - i; + + /* request, response lengths */ + hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4)); + + /* generate open address frame hdr (first 12 bytes) */ + buf_oaf[0] = (1 << 7) | (1 << 4) | 0x1; /* initiator, SSP, ftype 1h */ + buf_oaf[1] = task->dev->linkrate & 0xf; + buf_oaf[2] = tag >> 8; + buf_oaf[3] = tag; + memcpy(buf_oaf + 4, task->dev->sas_addr, SAS_ADDR_SIZE); + + /* fill in SSP frame header */ + ssp_hdr = (struct ssp_frame_hdr *) buf_cmd; + ssp_hdr->frame_type = SSP_COMMAND; + memcpy(ssp_hdr->hashed_dest_addr, task->dev->hashed_sas_addr, + HASHED_SAS_ADDR_SIZE); + memcpy(ssp_hdr->hashed_src_addr, + task->dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE); + ssp_hdr->tag = cpu_to_be16(tag); + + /* fill in command frame IU */ + buf_cmd += sizeof(*ssp_hdr); + memcpy(buf_cmd, &task->ssp_task.LUN, 8); + buf_cmd[9] = fburst | + task->ssp_task.task_attr | + (task->ssp_task.task_prio << 3); + memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16); + + /* fill in PRD (scatter/gather) table, if any */ + sg = task->scatter; + for (i = 0; i < tei->n_elem; i++) { + buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); + buf_prd->len = cpu_to_le32(sg_dma_len(sg)); + + sg++; + buf_prd++; + } + + return 0; +} + +static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) +{ + struct mvs_info *mvi = task->dev->port->ha->lldd_ha; + unsigned int tag = 0xdeadbeef, rc, n_elem = 0; + void __iomem *regs = mvi->regs; + unsigned long flags; + struct mvs_task_exec_info tei; + + /* FIXME: STP/SATA support not complete yet */ + if (task->task_proto == SAS_PROTOCOL_SATA || task->task_proto == SAS_PROTOCOL_STP) + return -SAS_DEV_NO_RESPONSE; + + if (task->num_scatter) { + n_elem = pci_map_sg(mvi->pdev, task->scatter, + task->num_scatter, task->data_dir); + if (!n_elem) + return -ENOMEM; + } + + spin_lock_irqsave(&mvi->lock, flags); + + rc = mvs_tag_alloc(mvi, &tag); + if (rc) + goto err_out; + + mvi->slot_info[tag].task = task; + mvi->slot_info[tag].n_elem = n_elem; + tei.task = task; + tei.hdr = &mvi->slot[tag]; + tei.tag = tag; + tei.n_elem = n_elem; + + switch (task->task_proto) { + case SAS_PROTOCOL_SMP: + rc = mvs_task_prep_smp(mvi, &tei); + break; + case SAS_PROTOCOL_SSP: + rc = mvs_task_prep_ssp(mvi, &tei); + break; + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + rc = mvs_task_prep_ata(mvi, &tei); + break; + default: + rc = -EINVAL; + break; + } + + if (rc) + goto err_out_tag; + + /* TODO: select normal or high priority */ + + mw32(RX_PROD_IDX, mvi->tx_prod); + + mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_TX_RING_SZ - 1); + + spin_lock(&task->task_state_lock); + task->task_state_flags |= SAS_TASK_AT_INITIATOR; + spin_unlock(&task->task_state_lock); + + spin_unlock_irqrestore(&mvi->lock, flags); + return 0; + +err_out_tag: + mvs_tag_clear(mvi, tag); +err_out: + if (n_elem) + pci_unmap_sg(mvi->pdev, task->scatter, n_elem, task->data_dir); + spin_unlock_irqrestore(&mvi->lock, flags); + return rc; +} + +static void mvs_free(struct mvs_info *mvi) +{ + int i; + + if (!mvi) + return; + + for (i = 0; i < MVS_SLOTS; i++) { + struct mvs_slot_info *slot = &mvi->slot_info[i]; + + if (slot->buf) + dma_free_coherent(&mvi->pdev->dev, MVS_SLOT_BUF_SZ, + slot->buf, slot->buf_dma); + } + + if (mvi->tx) + dma_free_coherent(&mvi->pdev->dev, + sizeof(*mvi->tx) * MVS_TX_RING_SZ, + mvi->tx, mvi->tx_dma); + if (mvi->rx_fis) + dma_free_coherent(&mvi->pdev->dev, MVS_RX_FISL_SZ, + mvi->rx_fis, mvi->rx_fis_dma); + if (mvi->rx) + dma_free_coherent(&mvi->pdev->dev, + sizeof(*mvi->rx) * MVS_RX_RING_SZ, + mvi->rx, mvi->rx_dma); + if (mvi->slot) + dma_free_coherent(&mvi->pdev->dev, + sizeof(*mvi->slot) * MVS_RX_RING_SZ, + mvi->slot, mvi->slot_dma); + if (mvi->peri_regs) + iounmap(mvi->peri_regs); + if (mvi->regs) + iounmap(mvi->regs); + if (mvi->shost) + scsi_host_put(mvi->shost); + kfree(mvi->sas.sas_port); + kfree(mvi->sas.sas_phy); + kfree(mvi); +} + +/* FIXME: locking? */ +static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + void *funcdata) +{ + struct mvs_info *mvi = sas_phy->ha->lldd_ha; + void __iomem *reg; + int rc = 0, phy_id = sas_phy->id; + u32 tmp; + + reg = mvi->regs + MVS_P0_SER_CTLSTAT + (phy_id * 4); + + switch (func) { + case PHY_FUNC_SET_LINK_RATE: { + struct sas_phy_linkrates *rates = funcdata; + u32 lrmin = 0, lrmax = 0; + + lrmin = (rates->minimum_linkrate << 8); + lrmax = (rates->maximum_linkrate << 12); + + tmp = readl(reg); + if (lrmin) { + tmp &= ~(0xf << 8); + tmp |= lrmin; + } + if (lrmax) { + tmp &= ~(0xf << 12); + tmp |= lrmax; + } + writel(tmp, reg); + break; + } + + case PHY_FUNC_HARD_RESET: + tmp = readl(reg); + if (tmp & PHY_RST_HARD) + break; + writel(tmp | PHY_RST_HARD, reg); + break; + + case PHY_FUNC_LINK_RESET: + writel(readl(reg) | PHY_RST, reg); + break; + + case PHY_FUNC_DISABLE: + case PHY_FUNC_RELEASE_SPINUP_HOLD: + default: + rc = -EOPNOTSUPP; + } + + return rc; +} + +static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id) +{ + struct mvs_phy *phy = &mvi->phy[phy_id]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + + sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0; + sas_phy->class = SAS; + sas_phy->iproto = SAS_PROTOCOL_ALL; + sas_phy->tproto = 0; + sas_phy->type = PHY_TYPE_PHYSICAL; + sas_phy->role = PHY_ROLE_INITIATOR; + sas_phy->oob_mode = OOB_NOT_CONNECTED; + sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN; + + sas_phy->id = phy_id; + sas_phy->sas_addr = &mvi->sas_addr[0]; + sas_phy->frame_rcvd = &phy->frame_rcvd[0]; + sas_phy->ha = &mvi->sas; + sas_phy->lldd_phy = phy; +} + +static struct mvs_info * __devinit mvs_alloc(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct mvs_info *mvi; + unsigned long res_start, res_len; + struct asd_sas_phy **arr_phy; + struct asd_sas_port **arr_port; + const struct mvs_chip_info *chip = &mvs_chips[ent->driver_data]; + int i; + + /* + * alloc and init our per-HBA mvs_info struct + */ + + mvi = kzalloc(sizeof(*mvi), GFP_KERNEL); + if (!mvi) + return NULL; + + spin_lock_init(&mvi->lock); + mvi->pdev = pdev; + mvi->chip = chip; + + if (pdev->device == 0x6440 && pdev->revision == 0) + mvi->flags |= MVF_PHY_PWR_FIX; + + /* + * alloc and init SCSI, SAS glue + */ + + mvi->shost = scsi_host_alloc(&mvs_sht, sizeof(void *)); + if (!mvi->shost) + goto err_out; + + arr_phy = kcalloc(MVS_MAX_PHYS, sizeof(void *), GFP_KERNEL); + arr_port = kcalloc(MVS_MAX_PHYS, sizeof(void *), GFP_KERNEL); + if (!arr_phy || !arr_port) + goto err_out; + + for (i = 0; i < MVS_MAX_PHYS; i++) { + mvs_phy_init(mvi, i); + arr_phy[i] = &mvi->phy[i].sas_phy; + arr_port[i] = &mvi->port[i].sas_port; + } + + SHOST_TO_SAS_HA(mvi->shost) = &mvi->sas; + mvi->shost->transportt = mvs_stt; + mvi->shost->max_id = ~0; + mvi->shost->max_lun = ~0; + mvi->shost->max_cmd_len = ~0; + + mvi->sas.sas_ha_name = DRV_NAME; + mvi->sas.dev = &pdev->dev; + mvi->sas.lldd_module = THIS_MODULE; + mvi->sas.sas_addr = &mvi->sas_addr[0]; + mvi->sas.sas_phy = arr_phy; + mvi->sas.sas_port = arr_port; + mvi->sas.num_phys = chip->n_phy; + mvi->sas.lldd_max_execute_num = MVS_TX_RING_SZ - 1;/* FIXME: correct? */ + mvi->sas.lldd_queue_size = MVS_TX_RING_SZ - 1; /* FIXME: correct? */ + mvi->sas.lldd_ha = mvi; + mvi->sas.core.shost = mvi->shost; + + mvs_tag_set(mvi, MVS_TX_RING_SZ - 1); + + /* + * ioremap main and peripheral registers + */ + + res_start = pci_resource_start(pdev, 2); + res_len = pci_resource_len(pdev, 2); + if (!res_start || !res_len) + goto err_out; + + mvi->peri_regs = ioremap_nocache(res_start, res_len); + if (!mvi->regs) + goto err_out; + + res_start = pci_resource_start(pdev, 4); + res_len = pci_resource_len(pdev, 4); + if (!res_start || !res_len) + goto err_out; + + mvi->regs = ioremap_nocache(res_start, res_len); + if (!mvi->regs) + goto err_out; + + /* + * alloc and init our DMA areas + */ + + mvi->tx = dma_alloc_coherent(&pdev->dev, + sizeof(*mvi->tx) * MVS_TX_RING_SZ, + &mvi->tx_dma, GFP_KERNEL); + if (!mvi->tx) + goto err_out; + memset(mvi->tx, 0, sizeof(*mvi->tx) * MVS_TX_RING_SZ); + + mvi->rx_fis = dma_alloc_coherent(&pdev->dev, MVS_RX_FISL_SZ, + &mvi->rx_fis_dma, GFP_KERNEL); + if (!mvi->rx_fis) + goto err_out; + memset(mvi->rx_fis, 0, MVS_RX_FISL_SZ); + + mvi->rx = dma_alloc_coherent(&pdev->dev, + sizeof(*mvi->rx) * MVS_RX_RING_SZ, + &mvi->rx_dma, GFP_KERNEL); + if (!mvi->rx) + goto err_out; + memset(mvi->rx, 0, sizeof(*mvi->rx) * MVS_RX_RING_SZ); + + mvi->rx[0] = cpu_to_le32(0xfff); + mvi->rx_cons = 0xfff; + + mvi->slot = dma_alloc_coherent(&pdev->dev, + sizeof(*mvi->slot) * MVS_SLOTS, + &mvi->slot_dma, GFP_KERNEL); + if (!mvi->slot) + goto err_out; + memset(mvi->slot, 0, sizeof(*mvi->slot) * MVS_SLOTS); + + for (i = 0; i < MVS_SLOTS; i++) { + struct mvs_slot_info *slot = &mvi->slot_info[i]; + + slot->buf = dma_alloc_coherent(&pdev->dev, MVS_SLOT_BUF_SZ, + &slot->buf_dma, GFP_KERNEL); + if (!slot->buf) + goto err_out; + memset(slot->buf, 0, MVS_SLOT_BUF_SZ); + } + + /* finally, read NVRAM to get our SAS address */ + if (mvs_nvram_read(mvi, NVR_SAS_ADDR, &mvi->sas_addr, 8)) + goto err_out; + + return mvi; + +err_out: + mvs_free(mvi); + return NULL; +} + +static u32 mvs_cr32(void __iomem *regs, u32 addr) +{ + mw32(CMD_ADDR, addr); + return mr32(CMD_DATA); +} + +static void mvs_cw32(void __iomem *regs, u32 addr, u32 val) +{ + mw32(CMD_ADDR, addr); + mw32(CMD_DATA, val); +} + +#if 0 +static u32 mvs_phy_read(struct mvs_info *mvi, unsigned int phy_id, u32 addr) +{ + void __iomem *regs = mvi->regs; + void __iomem *phy_regs = regs + MVS_P0_CFG_ADDR + (phy_id * 8); + + writel(addr, phy_regs); + return readl(phy_regs + 4); +} +#endif + +static void mvs_phy_write(struct mvs_info *mvi, unsigned int phy_id, + u32 addr, u32 val) +{ + void __iomem *regs = mvi->regs; + void __iomem *phy_regs = regs + MVS_P0_CFG_ADDR + (phy_id * 8); + + writel(addr, phy_regs); + writel(val, phy_regs + 4); + readl(phy_regs); /* flush */ +} + +static void __devinit mvs_phy_hacks(struct mvs_info *mvi) +{ + void __iomem *regs = mvi->regs; + u32 tmp; + + /* workaround for SATA R-ERR, to ignore phy glitch */ + tmp = mvs_cr32(regs, CMD_PHY_TIMER); + tmp &= ~(1 << 9); + tmp |= (1 << 10); + mvs_cw32(regs, CMD_PHY_TIMER, tmp); + + /* enable retry 127 times */ + mvs_cw32(regs, CMD_SAS_CTL1, 0x7f7f); + + /* extend open frame timeout to max */ + tmp = mvs_cr32(regs, CMD_SAS_CTL0); + tmp &= ~0xffff; + tmp |= 0x3fff; + mvs_cw32(regs, CMD_SAS_CTL0, tmp); + + /* workaround for WDTIMEOUT , set to 550 ms */ + mvs_cw32(regs, CMD_WD_TIMER, 0xffffff); + + /* not to halt for different port op during wideport link change */ + mvs_cw32(regs, CMD_APP_ERR_CONFIG, 0xffefbf7d); + + /* workaround for Seagate disk not-found OOB sequence, recv + * COMINIT before sending out COMWAKE */ + tmp = mvs_cr32(regs, CMD_PHY_MODE_21); + tmp &= 0x0000ffff; + tmp |= 0x00fa0000; + mvs_cw32(regs, CMD_PHY_MODE_21, tmp); + + tmp = mvs_cr32(regs, CMD_PHY_TIMER); + tmp &= 0x1fffffff; + tmp |= (2U << 29); /* 8 ms retry */ + mvs_cw32(regs, CMD_PHY_TIMER, tmp); +} + +static int __devinit mvs_hw_init(struct mvs_info *mvi) +{ + void __iomem *regs = mvi->regs; + int i; + u32 tmp, cctl; + + /* make sure interrupts are masked immediately (paranoia) */ + mw32(GBL_CTL, 0); + tmp = mr32(GBL_CTL); + + if (!(tmp & HBA_RST)) { + if (mvi->flags & MVF_PHY_PWR_FIX) { + pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp); + tmp &= ~PCTL_PWR_ON; + tmp |= PCTL_OFF; + pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp); + + pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, &tmp); + tmp &= ~PCTL_PWR_ON; + tmp |= PCTL_OFF; + pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, tmp); + } + + /* global reset, incl. COMRESET/H_RESET_N (self-clearing) */ + mw32_f(GBL_CTL, HBA_RST); + } + + + /* wait for reset to finish; timeout is just a guess */ + i = 1000; + while (i-- > 0) { + msleep(10); + + if (!(mr32(GBL_CTL) & HBA_RST)) + break; + } + if (mr32(GBL_CTL) & HBA_RST) { + dev_printk(KERN_ERR, &mvi->pdev->dev, "HBA reset failed\n"); + return -EBUSY; + } + + /* make sure RST is set; HBA_RST /should/ have done that for us */ + cctl = mr32(CTL); + if (cctl & CCTL_RST) + cctl &= ~CCTL_RST; + else + mw32_f(CTL, cctl | CCTL_RST); + + pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp); + tmp |= PCTL_PWR_ON; + tmp &= ~PCTL_OFF; + pci_write_config_dword(mvi->pdev, PCR_PHY_CTL, tmp); + + pci_read_config_dword(mvi->pdev, PCR_PHY_CTL2, &tmp); + tmp |= PCTL_PWR_ON; + tmp &= ~PCTL_OFF; + pci_write_config_dword(mvi->pdev, PCR_PHY_CTL2, tmp); + + mw32_f(CTL, cctl); + + mvs_phy_hacks(mvi); + + mw32(CMD_LIST_LO, mvi->slot_dma); + mw32(CMD_LIST_HI, (mvi->slot_dma >> 16) >> 16); + + mw32(RX_FIS_LO, mvi->rx_fis_dma); + mw32(RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16); + + mw32(TX_CFG, MVS_TX_RING_SZ); + mw32(TX_LO, mvi->tx_dma); + mw32(TX_HI, (mvi->tx_dma >> 16) >> 16); + + mw32(RX_CFG, MVS_RX_RING_SZ); + mw32(RX_LO, mvi->rx_dma); + mw32(RX_HI, (mvi->rx_dma >> 16) >> 16); + + /* init and reset phys */ + for (i = 0; i < mvi->chip->n_phy; i++) { + /* FIXME: is this the correct dword order? */ + u32 lo = *((u32 *) &mvi->sas_addr[0]); + u32 hi = *((u32 *) &mvi->sas_addr[4]); + + /* set phy local SAS address */ + mvs_phy_write(mvi, i, PHYR_ADDR_LO, lo); + mvs_phy_write(mvi, i, PHYR_ADDR_HI, hi); + + /* reset phy */ + tmp = readl(regs + MVS_P0_SER_CTLSTAT + (i * 4)); + tmp |= PHY_RST; + writel(tmp, regs + MVS_P0_SER_CTLSTAT + (i * 4)); + } + + msleep(100); + + for (i = 0; i < mvi->chip->n_phy; i++) { + /* set phy int mask */ + writel(PHYEV_BROAD_CH | PHYEV_RDY_CH, + regs + MVS_P0_INT_MASK + (i * 8)); + + /* clear phy int status */ + tmp = readl(regs + MVS_P0_INT_STAT + (i * 8)); + writel(tmp, regs + MVS_P0_INT_STAT + (i * 8)); + } + + /* FIXME: update wide port bitmaps */ + + /* ladies and gentlemen, start your engines */ + mw32(TX_CFG, MVS_TX_RING_SZ | TX_EN); + mw32(RX_CFG, MVS_RX_RING_SZ | RX_EN); + mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN | + ((mvi->flags & MVF_MSI) ? PCS_SELF_CLEAR : 0)); + + /* re-enable interrupts globally */ + mw32(GBL_CTL, INT_EN); + + return 0; +} + +static void __devinit mvs_print_info(struct mvs_info *mvi) +{ + struct pci_dev *pdev = mvi->pdev; + static int printed_version; + + if (!printed_version++) + dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); + + dev_printk(KERN_INFO, &pdev->dev, "%u phys, addr %llx\n", + mvi->chip->n_phy, SAS_ADDR(mvi->sas_addr)); +} + +static int __devinit mvs_pci_init(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int rc; + struct mvs_info *mvi; + irq_handler_t irq_handler = mvs_interrupt; + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + pci_set_master(pdev); + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_out_disable; + + rc = pci_go_64(pdev); + if (rc) + goto err_out_regions; + + mvi = mvs_alloc(pdev, ent); + if (!mvi) { + rc = -ENOMEM; + goto err_out_regions; + } + + rc = mvs_hw_init(mvi); + if (rc) + goto err_out_mvi; + + if (!pci_enable_msi(pdev)) { + mvi->flags |= MVF_MSI; + irq_handler = mvs_msi_interrupt; + } + + rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME, mvi); + if (rc) + goto err_out_msi; + + rc = scsi_add_host(mvi->shost, &pdev->dev); + if (rc) + goto err_out_irq; + + rc = sas_register_ha(&mvi->sas); + if (rc) + goto err_out_shost; + + pci_set_drvdata(pdev, mvi); + + mvs_print_info(mvi); + + scsi_scan_host(mvi->shost); + return 0; + +err_out_shost: + scsi_remove_host(mvi->shost); +err_out_irq: + free_irq(pdev->irq, mvi); +err_out_msi: + if (mvi->flags |= MVF_MSI) + pci_disable_msi(pdev); +err_out_mvi: + mvs_free(mvi); +err_out_regions: + pci_release_regions(pdev); +err_out_disable: + pci_disable_device(pdev); + return rc; +} + +static void __devexit mvs_pci_remove(struct pci_dev *pdev) +{ + struct mvs_info *mvi = pci_get_drvdata(pdev); + + pci_set_drvdata(pdev, NULL); + + sas_unregister_ha(&mvi->sas); + sas_remove_host(mvi->shost); + scsi_remove_host(mvi->shost); + + free_irq(pdev->irq, mvi); + if (mvi->flags & MVF_MSI) + pci_disable_msi(pdev); + mvs_free(mvi); + pci_release_regions(pdev); + pci_disable_device(pdev); +} + +static struct sas_domain_function_template mvs_transport_ops = { + .lldd_execute_task = mvs_task_exec, + .lldd_control_phy = mvs_phy_control, +}; + +static struct pci_device_id __devinitdata mvs_pci_table[] = { + { PCI_VDEVICE(MARVELL, 0x6320), chip_6320 }, + { PCI_VDEVICE(MARVELL, 0x6340), chip_6440 }, + { PCI_VDEVICE(MARVELL, 0x6440), chip_6440 }, + { PCI_VDEVICE(MARVELL, 0x6480), chip_6480 }, + + { } /* terminate list */ +}; + +static struct pci_driver mvs_pci_driver = { + .name = DRV_NAME, + .id_table = mvs_pci_table, + .probe = mvs_pci_init, + .remove = __devexit_p(mvs_pci_remove), +}; + +static int __init mvs_init(void) +{ + int rc; + + mvs_stt = sas_domain_attach_transport(&mvs_transport_ops); + if (!mvs_stt) + return -ENOMEM; + + rc = pci_register_driver(&mvs_pci_driver); + if (rc) + goto err_out; + + return 0; + +err_out: + sas_release_transport(mvs_stt); + return rc; +} + +static void __exit mvs_exit(void) +{ + pci_unregister_driver(&mvs_pci_driver); + sas_release_transport(mvs_stt); +} + +module_init(mvs_init); +module_exit(mvs_exit); + +MODULE_AUTHOR("Jeff Garzik "); +MODULE_DESCRIPTION("Marvell 88SE6440 SAS/SATA controller driver"); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, mvs_pci_table); + From 8f261aaf9be5c1246013cf6a65b98586d24832a5 Mon Sep 17 00:00:00 2001 From: Ke Wei Date: Sat, 23 Feb 2008 21:15:27 +0800 Subject: [PATCH 589/880] [SCSI] mvsas: convert from rough draft to working driver Convert rough draft Marvell 6440 driver to a working driver. Added support for SAS and SATA devices, hotplug, wide port, and expanders. Signed-off-by: Ke Wei Signed-off-by: James Bottomley --- drivers/scsi/mvsas.c | 1782 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 1469 insertions(+), 313 deletions(-) mode change 100644 => 100755 drivers/scsi/mvsas.c diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c old mode 100644 new mode 100755 index 03638b9bb283..30e20e69715a --- a/drivers/scsi/mvsas.c +++ b/drivers/scsi/mvsas.c @@ -2,6 +2,7 @@ mvsas.c - Marvell 88SE6440 SAS/SATA support Copyright 2007 Red Hat, Inc. + Copyright 2008 Marvell. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -37,16 +38,35 @@ #include #include -#define DRV_NAME "mvsas" -#define DRV_VERSION "0.1" +#define DRV_NAME "mvsas" +#define DRV_VERSION "0.5" +#define _MV_DUMP 0 +#define MVS_DISABLE_NVRAM +#define MVS_DISABLE_MSI #define mr32(reg) readl(regs + MVS_##reg) #define mw32(reg,val) writel((val), regs + MVS_##reg) -#define mw32_f(reg,val) do { \ +#define mw32_f(reg,val) do { \ writel((val), regs + MVS_##reg); \ readl(regs + MVS_##reg); \ } while (0) +#define MVS_ID_NOT_MAPPED 0xff +#define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width) + +/* offset for D2H FIS in the Received FIS List Structure */ +#define SATA_RECEIVED_D2H_FIS(reg_set) \ + ((void *) mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x40) +#define SATA_RECEIVED_PIO_FIS(reg_set) \ + ((void *) mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x20) +#define UNASSOC_D2H_FIS(id) \ + ((void *) mvi->rx_fis + 0x100 * id) + +#define for_each_phy(__lseq_mask, __mc, __lseq, __rest) \ + for ((__mc) = (__lseq_mask), (__lseq) = 0; \ + (__mc) != 0 && __rest; \ + (++__lseq), (__mc) >>= 1) + /* driver compile-time configuration */ enum driver_configuration { MVS_TX_RING_SZ = 1024, /* TX ring size (12-bit) */ @@ -57,10 +77,12 @@ enum driver_configuration { MVS_SLOTS = 512, /* command slots */ MVS_SLOT_BUF_SZ = 8192, /* cmd tbl + IU + status + PRD */ MVS_SSP_CMD_SZ = 64, /* SSP command table buffer size */ - MVS_ATA_CMD_SZ = 128, /* SATA command table buffer size */ + MVS_ATA_CMD_SZ = 96, /* SATA command table buffer size */ MVS_OAF_SZ = 64, /* Open address frame buffer size */ MVS_RX_FIS_COUNT = 17, /* Optional rx'd FISs (max 17) */ + + MVS_QUEUE_SIZE = 30, /* Support Queue depth */ }; /* unchangeable hardware details */ @@ -89,7 +111,7 @@ enum hw_registers { MVS_GBL_CTL = 0x04, /* global control */ MVS_GBL_INT_STAT = 0x08, /* global irq status */ MVS_GBL_PI = 0x0C, /* ports implemented bitmask */ - MVS_GBL_PORT_TYPE = 0x00, /* port type */ + MVS_GBL_PORT_TYPE = 0xa0, /* port type */ MVS_CTL = 0x100, /* SAS/SATA port configuration */ MVS_PCS = 0x104, /* SAS/SATA port control/status */ @@ -102,24 +124,29 @@ enum hw_registers { MVS_TX_LO = 0x124, /* TX (delivery) ring addr */ MVS_TX_HI = 0x128, - MVS_RX_PROD_IDX = 0x12C, /* RX producer pointer */ - MVS_RX_CONS_IDX = 0x130, /* RX consumer pointer (RO) */ + MVS_TX_PROD_IDX = 0x12C, /* TX producer pointer */ + MVS_TX_CONS_IDX = 0x130, /* TX consumer pointer (RO) */ MVS_RX_CFG = 0x134, /* RX configuration */ MVS_RX_LO = 0x138, /* RX (completion) ring addr */ MVS_RX_HI = 0x13C, + MVS_RX_CONS_IDX = 0x140, /* RX consumer pointer (RO) */ MVS_INT_COAL = 0x148, /* Int coalescing config */ MVS_INT_COAL_TMOUT = 0x14C, /* Int coalescing timeout */ MVS_INT_STAT = 0x150, /* Central int status */ MVS_INT_MASK = 0x154, /* Central int enable */ MVS_INT_STAT_SRS = 0x158, /* SATA register set status */ + MVS_INT_MASK_SRS = 0x15C, /* ports 1-3 follow after this */ MVS_P0_INT_STAT = 0x160, /* port0 interrupt status */ MVS_P0_INT_MASK = 0x164, /* port0 interrupt mask */ + MVS_P4_INT_STAT = 0x200, /* Port 4 interrupt status */ + MVS_P4_INT_MASK = 0x204, /* Port 4 interrupt enable mask */ /* ports 1-3 follow after this */ MVS_P0_SER_CTLSTAT = 0x180, /* port0 serial control/status */ + MVS_P4_SER_CTLSTAT = 0x220, /* port4 serial control/status */ MVS_CMD_ADDR = 0x1B8, /* Command register port (addr) */ MVS_CMD_DATA = 0x1BC, /* Command register port (data) */ @@ -127,6 +154,14 @@ enum hw_registers { /* ports 1-3 follow after this */ MVS_P0_CFG_ADDR = 0x1C0, /* port0 phy register address */ MVS_P0_CFG_DATA = 0x1C4, /* port0 phy register data */ + MVS_P4_CFG_ADDR = 0x230, /* Port 4 config address */ + MVS_P4_CFG_DATA = 0x234, /* Port 4 config data */ + + /* ports 1-3 follow after this */ + MVS_P0_VSR_ADDR = 0x1E0, /* port0 VSR address */ + MVS_P0_VSR_DATA = 0x1E4, /* port0 VSR data */ + MVS_P4_VSR_ADDR = 0x250, /* port 4 VSR addr */ + MVS_P4_VSR_DATA = 0x254, /* port 4 VSR data */ }; enum hw_register_bits { @@ -140,12 +175,35 @@ enum hw_register_bits { /* MVS_GBL_PORT_TYPE */ /* shl for ports 1-3 */ SATA_TARGET = (1U << 16), /* port0 SATA target enable */ - AUTO_DET = (1U << 8), /* port0 SAS/SATA autodetect */ - SAS_MODE = (1U << 0), /* port0 SAS(1), SATA(0) mode */ - /* SAS_MODE value may be - * dictated (in hw) by values - * of SATA_TARGET & AUTO_DET - */ + MODE_AUTO_DET_PORT7 = (1U << 15), /* port0 SAS/SATA autodetect */ + MODE_AUTO_DET_PORT6 = (1U << 14), + MODE_AUTO_DET_PORT5 = (1U << 13), + MODE_AUTO_DET_PORT4 = (1U << 12), + MODE_AUTO_DET_PORT3 = (1U << 11), + MODE_AUTO_DET_PORT2 = (1U << 10), + MODE_AUTO_DET_PORT1 = (1U << 9), + MODE_AUTO_DET_PORT0 = (1U << 8), + MODE_AUTO_DET_EN = MODE_AUTO_DET_PORT0 | MODE_AUTO_DET_PORT1 | + MODE_AUTO_DET_PORT2 | MODE_AUTO_DET_PORT3 | + MODE_AUTO_DET_PORT4 | MODE_AUTO_DET_PORT5 | + MODE_AUTO_DET_PORT6 | MODE_AUTO_DET_PORT7, + MODE_SAS_PORT7_MASK = (1U << 7), /* port0 SAS(1), SATA(0) mode */ + MODE_SAS_PORT6_MASK = (1U << 6), + MODE_SAS_PORT5_MASK = (1U << 5), + MODE_SAS_PORT4_MASK = (1U << 4), + MODE_SAS_PORT3_MASK = (1U << 3), + MODE_SAS_PORT2_MASK = (1U << 2), + MODE_SAS_PORT1_MASK = (1U << 1), + MODE_SAS_PORT0_MASK = (1U << 0), + MODE_SAS_SATA = MODE_SAS_PORT0_MASK | MODE_SAS_PORT1_MASK | + MODE_SAS_PORT2_MASK | MODE_SAS_PORT3_MASK | + MODE_SAS_PORT4_MASK | MODE_SAS_PORT5_MASK | + MODE_SAS_PORT6_MASK | MODE_SAS_PORT7_MASK, + + /* SAS_MODE value may be + * dictated (in hw) by values + * of SATA_TARGET & AUTO_DET + */ /* MVS_TX_CFG */ TX_EN = (1U << 16), /* Enable TX */ @@ -167,12 +225,14 @@ enum hw_register_bits { CINT_MEM = (1U << 26), /* int mem parity err */ CINT_I2C_SLAVE = (1U << 25), /* slave I2C event */ CINT_SRS = (1U << 3), /* SRS event */ - CINT_CI_STOP = (1U << 10), /* cmd issue stopped */ + CINT_CI_STOP = (1U << 1), /* cmd issue stopped */ CINT_DONE = (1U << 0), /* cmd completion */ /* shl for ports 1-3 */ CINT_PORT_STOPPED = (1U << 16), /* port0 stopped */ CINT_PORT = (1U << 8), /* port0 event */ + CINT_PORT_MASK_OFFSET = 8, + CINT_PORT_MASK = (0xFF << CINT_PORT_MASK_OFFSET), /* TX (delivery) ring bits */ TXQ_CMD_SHIFT = 29, @@ -239,8 +299,15 @@ enum hw_register_bits { PHY_BCAST_CHG = (1U << 2), /* broadcast(change) notif */ PHY_RST_HARD = (1U << 1), /* hard reset + phy reset */ PHY_RST = (1U << 0), /* phy reset */ + PHY_MIN_SPP_PHYS_LINK_RATE_MASK = (0xF << 8), + PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0xF << 12), + PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (16), + PHY_NEG_SPP_PHYS_LINK_RATE_MASK = + (0xF << PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET), + PHY_READY_MASK = (1U << 20), /* MVS_Px_INT_STAT, MVS_Px_INT_MASK (per-phy events) */ + PHYEV_DEC_ERR = (1U << 24), /* Phy Decoding Error */ PHYEV_UNASSOC_FIS = (1U << 19), /* unassociated FIS rx'd */ PHYEV_AN = (1U << 18), /* SATA async notification */ PHYEV_BIST_ACT = (1U << 17), /* BIST activate FIS */ @@ -260,13 +327,37 @@ enum hw_register_bits { PHYEV_RDY_CH = (1U << 0), /* phy ready changed state */ /* MVS_PCS */ + PCS_EN_SATA_REG_SHIFT = (16), /* Enable SATA Register Set */ + PCS_EN_PORT_XMT_SHIFT = (12), /* Enable Port Transmit */ + PCS_EN_PORT_XMT_SHIFT2 = (8), /* For 6480 */ PCS_SATA_RETRY = (1U << 8), /* retry ctl FIS on R_ERR */ PCS_RSP_RX_EN = (1U << 7), /* raw response rx */ PCS_SELF_CLEAR = (1U << 5), /* self-clearing int mode */ PCS_FIS_RX_EN = (1U << 4), /* FIS rx enable */ PCS_CMD_STOP_ERR = (1U << 3), /* cmd stop-on-err enable */ - PCS_CMD_RST = (1U << 2), /* reset cmd issue */ + PCS_CMD_RST = (1U << 1), /* reset cmd issue */ PCS_CMD_EN = (1U << 0), /* enable cmd issue */ + + /* Port n Attached Device Info */ + PORT_DEV_SSP_TRGT = (1U << 19), + PORT_DEV_SMP_TRGT = (1U << 18), + PORT_DEV_STP_TRGT = (1U << 17), + PORT_DEV_SSP_INIT = (1U << 11), + PORT_DEV_SMP_INIT = (1U << 10), + PORT_DEV_STP_INIT = (1U << 9), + PORT_PHY_ID_MASK = (0xFFU << 24), + PORT_DEV_TRGT_MASK = (0x7U << 17), + PORT_DEV_INIT_MASK = (0x7U << 9), + PORT_DEV_TYPE_MASK = (0x7U << 0), + + /* Port n PHY Status */ + PHY_RDY = (1U << 2), + PHY_DW_SYNC = (1U << 1), + PHY_OOB_DTCTD = (1U << 0), + + /* VSR */ + /* PHYMODE 6 (CDB) */ + PHY_MODE6_DTL_SPEED = (1U << 27), }; enum mvs_info_flags { @@ -329,33 +420,60 @@ enum sas_cmd_port_registers { /* SAS/SATA configuration port registers, aka phy registers */ enum sas_sata_config_port_regs { - PHYR_IDENTIFY = 0x0, /* info for IDENTIFY frame */ - PHYR_ADDR_LO = 0x4, /* my SAS address (low) */ - PHYR_ADDR_HI = 0x8, /* my SAS address (high) */ - PHYR_ATT_DEV_INFO = 0xC, /* attached device info */ + PHYR_IDENTIFY = 0x00, /* info for IDENTIFY frame */ + PHYR_ADDR_LO = 0x04, /* my SAS address (low) */ + PHYR_ADDR_HI = 0x08, /* my SAS address (high) */ + PHYR_ATT_DEV_INFO = 0x0C, /* attached device info */ PHYR_ATT_ADDR_LO = 0x10, /* attached dev SAS addr (low) */ PHYR_ATT_ADDR_HI = 0x14, /* attached dev SAS addr (high) */ PHYR_SATA_CTL = 0x18, /* SATA control */ PHYR_PHY_STAT = 0x1C, /* PHY status */ + PHYR_SATA_SIG0 = 0x20, /*port SATA signature FIS(Byte 0-3) */ + PHYR_SATA_SIG1 = 0x24, /*port SATA signature FIS(Byte 4-7) */ + PHYR_SATA_SIG2 = 0x28, /*port SATA signature FIS(Byte 8-11) */ + PHYR_SATA_SIG3 = 0x2c, /*port SATA signature FIS(Byte 12-15) */ + PHYR_R_ERR_COUNT = 0x30, /* port R_ERR count register */ + PHYR_CRC_ERR_COUNT = 0x34, /* port CRC error count register */ PHYR_WIDE_PORT = 0x38, /* wide port participating */ PHYR_CURRENT0 = 0x80, /* current connection info 0 */ PHYR_CURRENT1 = 0x84, /* current connection info 1 */ PHYR_CURRENT2 = 0x88, /* current connection info 2 */ }; +/* SAS/SATA Vendor Specific Port Registers */ +enum sas_sata_vsp_regs { + VSR_PHY_STAT = 0x00, /* Phy Status */ + VSR_PHY_MODE1 = 0x01, /* phy tx */ + VSR_PHY_MODE2 = 0x02, /* tx scc */ + VSR_PHY_MODE3 = 0x03, /* pll */ + VSR_PHY_MODE4 = 0x04, /* VCO */ + VSR_PHY_MODE5 = 0x05, /* Rx */ + VSR_PHY_MODE6 = 0x06, /* CDR */ + VSR_PHY_MODE7 = 0x07, /* Impedance */ + VSR_PHY_MODE8 = 0x08, /* Voltage */ + VSR_PHY_MODE9 = 0x09, /* Test */ + VSR_PHY_MODE10 = 0x0A, /* Power */ + VSR_PHY_MODE11 = 0x0B, /* Phy Mode */ + VSR_PHY_VS0 = 0x0C, /* Vednor Specific 0 */ + VSR_PHY_VS1 = 0x0D, /* Vednor Specific 1 */ +}; + enum pci_cfg_registers { - PCR_PHY_CTL = 0x40, - PCR_PHY_CTL2 = 0x90, + PCR_PHY_CTL = 0x40, + PCR_PHY_CTL2 = 0x90, + PCR_DEV_CTRL = 0xE8, }; enum pci_cfg_register_bits { - PCTL_PWR_ON = (0xFU << 24), - PCTL_OFF = (0xFU << 12), + PCTL_PWR_ON = (0xFU << 24), + PCTL_OFF = (0xFU << 12), + PRD_REQ_SIZE = (0x4000), + PRD_REQ_MASK = (0x00007000), }; enum nvram_layout_offsets { - NVR_SIG = 0x00, /* 0xAA, 0x55 */ - NVR_SAS_ADDR = 0x02, /* 8-byte SAS address */ + NVR_SIG = 0x00, /* 0xAA, 0x55 */ + NVR_SAS_ADDR = 0x02, /* 8-byte SAS address */ }; enum chip_flavors { @@ -364,10 +482,41 @@ enum chip_flavors { chip_6480, }; +enum port_type { + PORT_TYPE_SAS = (1L << 1), + PORT_TYPE_SATA = (1L << 0), +}; + +/* Command Table Format */ +enum ct_format { + /* SSP */ + SSP_F_H = 0x00, + SSP_F_IU = 0x18, + SSP_F_MAX = 0x4D, + /* STP */ + STP_CMD_FIS = 0x00, + STP_ATAPI_CMD = 0x40, + STP_F_MAX = 0x10, + /* SMP */ + SMP_F_T = 0x00, + SMP_F_DEP = 0x01, + SMP_F_MAX = 0x101, +}; + +enum status_buffer { + SB_EIR_OFF = 0x00, /* Error Information Record */ + SB_RFB_OFF = 0x08, /* Response Frame Buffer */ + SB_RFB_MAX = 0x400, /* RFB size*/ +}; + +enum error_info_rec { + CMD_ISS_STPD = (1U << 31), /* Cmd Issue Stopped */ +}; + struct mvs_chip_info { - unsigned int n_phy; - unsigned int srs_sz; - unsigned int slot_width; + u32 n_phy; + u32 srs_sz; + u32 slot_width; }; struct mvs_err_info { @@ -395,26 +544,43 @@ struct mvs_cmd_hdr { struct mvs_slot_info { struct sas_task *task; - unsigned int n_elem; + u32 n_elem; + u32 tx; /* DMA buffer for storing cmd tbl, open addr frame, status buffer, * and PRD table */ void *buf; dma_addr_t buf_dma; +#if _MV_DUMP + u32 cmd_size; +#endif void *response; }; struct mvs_port { struct asd_sas_port sas_port; + u8 port_attached; + u8 taskfileset; + u8 wide_port_phymap; }; struct mvs_phy { struct mvs_port *port; struct asd_sas_phy sas_phy; - - u8 frame_rcvd[24 + 1024]; + struct sas_identify identify; + struct scsi_device *sdev; + u64 dev_sas_addr; + u64 att_dev_sas_addr; + u32 att_dev_info; + u32 dev_info; + u32 phy_type; + u32 phy_status; + u32 irq_status; + u32 frame_rcvd_size; + u8 frame_rcvd[32]; + u8 phy_attached; }; struct mvs_info { @@ -440,24 +606,62 @@ struct mvs_info { __le32 *rx_fis; /* RX'd FIS area */ dma_addr_t rx_fis_dma; - struct mvs_cmd_hdr *slot; /* DMA command header slots */ + struct mvs_cmd_hdr *slot; /* DMA command header slots */ dma_addr_t slot_dma; const struct mvs_chip_info *chip; - /* further per-slot information */ + unsigned long tags[MVS_SLOTS]; struct mvs_slot_info slot_info[MVS_SLOTS]; - unsigned long tags[(MVS_SLOTS / sizeof(unsigned long)) + 1]; - + /* further per-slot information */ struct mvs_phy phy[MVS_MAX_PHYS]; struct mvs_port port[MVS_MAX_PHYS]; + + u32 can_queue; /* per adapter */ + u32 tag_out; /*Get*/ + u32 tag_in; /*Give*/ }; +struct mvs_queue_task { + struct list_head list; + + void *uldd_task; +}; + +static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, + void *funcdata); +static u32 mvs_read_phy_ctl(struct mvs_info *mvi, u32 port); +static void mvs_write_phy_ctl(struct mvs_info *mvi, u32 port, u32 val); +static u32 mvs_read_port(struct mvs_info *mvi, u32 off, u32 off2, u32 port); +static void mvs_write_port(struct mvs_info *mvi, u32 off, u32 off2, + u32 port, u32 val); +static u32 mvs_read_port_cfg_data(struct mvs_info *mvi, u32 port); +static void mvs_write_port_cfg_data(struct mvs_info *mvi, u32 port, u32 val); +static void mvs_write_port_cfg_addr(struct mvs_info *mvi, u32 port, u32 addr); +static u32 mvs_read_port_vsr_data(struct mvs_info *mvi, u32 port); +static void mvs_write_port_vsr_data(struct mvs_info *mvi, u32 port, u32 val); +static void mvs_write_port_vsr_addr(struct mvs_info *mvi, u32 port, u32 addr); +static u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port); +static void mvs_write_port_irq_stat(struct mvs_info *mvi, u32 port, u32 val); +static void mvs_write_port_irq_mask(struct mvs_info *mvi, u32 port, u32 val); +static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port); + +static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i); +static void mvs_detect_porttype(struct mvs_info *mvi, int i); +static void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); +static void mvs_free_reg_set(struct mvs_info *mvi, struct mvs_port *port); +static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port); +static u32 mvs_is_sig_fis_received(u32 irq_status); + +static int mvs_scan_finished(struct Scsi_Host *, unsigned long); +static void mvs_scan_start(struct Scsi_Host *); +static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev); + static struct scsi_transport_template *mvs_stt; static const struct mvs_chip_info mvs_chips[] = { - [chip_6320] = { 2, 16, 9 }, - [chip_6440] = { 4, 16, 9 }, + [chip_6320] = { 2, 16, 9 }, + [chip_6440] = { 4, 16, 9 }, [chip_6480] = { 8, 32, 10 }, }; @@ -468,6 +672,8 @@ static struct scsi_host_template mvs_sht = { .target_alloc = sas_target_alloc, .slave_configure = sas_slave_configure, .slave_destroy = sas_slave_destroy, + .scan_finished = mvs_scan_finished, + .scan_start = mvs_scan_start, .change_queue_depth = sas_change_queue_depth, .change_queue_type = sas_change_queue_type, .bios_param = sas_bios_param, @@ -477,14 +683,154 @@ static struct scsi_host_template mvs_sht = { .sg_tablesize = SG_ALL, .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .use_clustering = ENABLE_CLUSTERING, - .eh_device_reset_handler= sas_eh_device_reset_handler, + .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_bus_reset_handler = sas_eh_bus_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = mvs_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, }; -static void mvs_int_rx(struct mvs_info *mvi, bool self_clear); +static void mvs_hexdump(u32 size, u8 *data, u32 baseaddr) +{ + u32 i; + u32 run; + u32 offset; + + offset = 0; + while (size) { + printk("%08X : ", baseaddr + offset); + if (size >= 16) + run = 16; + else + run = size; + size -= run; + for (i = 0; i < 16; i++) { + if (i < run) + printk("%02X ", (u32)data[i]); + else + printk(" "); + } + printk(": "); + for (i = 0; i < run; i++) + printk("%c", isalnum(data[i]) ? data[i] : '.'); + printk("\n"); + data = &data[16]; + offset += run; + } + printk("\n"); +} + +static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag, + enum sas_protocol proto) +{ +#if _MV_DUMP + u32 offset; + struct pci_dev *pdev = mvi->pdev; + struct mvs_slot_info *slot = &mvi->slot_info[tag]; + + offset = slot->cmd_size + MVS_OAF_SZ + + sizeof(struct mvs_prd) * slot->n_elem; + dev_printk(KERN_DEBUG, &pdev->dev, "+---->Status buffer[%d] :\n", + tag); + mvs_hexdump(32, (u8 *) slot->response, + (u32) slot->buf_dma + offset); +#endif +} + +static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag, + enum sas_protocol proto) +{ +#if _MV_DUMP + u32 sz, w_ptr, r_ptr; + u64 addr; + void __iomem *regs = mvi->regs; + struct pci_dev *pdev = mvi->pdev; + struct mvs_slot_info *slot = &mvi->slot_info[tag]; + + /*Delivery Queue */ + sz = mr32(TX_CFG) & TX_RING_SZ_MASK; + w_ptr = mr32(TX_PROD_IDX) & TX_RING_SZ_MASK; + r_ptr = mr32(TX_CONS_IDX) & TX_RING_SZ_MASK; + addr = mr32(TX_HI) << 16 << 16 | mr32(TX_LO); + dev_printk(KERN_DEBUG, &pdev->dev, + "Delivery Queue Size=%04d , WRT_PTR=%04X , RD_PTR=%04X\n", + sz, w_ptr, r_ptr); + dev_printk(KERN_DEBUG, &pdev->dev, + "Delivery Queue Base Address=0x%llX (PA)" + "(tx_dma=0x%llX), Entry=%04d\n", + addr, mvi->tx_dma, w_ptr); + mvs_hexdump(sizeof(u32), (u8 *)(&mvi->tx[mvi->tx_prod]), + (u32) mvi->tx_dma + sizeof(u32) * w_ptr); + /*Command List */ + addr = mr32(CMD_LIST_HI) << 16 << 16 | mr32(CMD_LIST_LO); + dev_printk(KERN_DEBUG, &pdev->dev, + "Command List Base Address=0x%llX (PA)" + "(slot_dma=0x%llX), Header=%03d\n", + addr, mvi->slot_dma, tag); + dev_printk(KERN_DEBUG, &pdev->dev, "Command Header[%03d]:\n", tag); + /*mvs_cmd_hdr */ + mvs_hexdump(sizeof(struct mvs_cmd_hdr), (u8 *)(&mvi->slot[tag]), + (u32) mvi->slot_dma + tag * sizeof(struct mvs_cmd_hdr)); + /*1.command table area */ + dev_printk(KERN_DEBUG, &pdev->dev, "+---->Command Table :\n"); + mvs_hexdump(slot->cmd_size, (u8 *) slot->buf, (u32) slot->buf_dma); + /*2.open address frame area */ + dev_printk(KERN_DEBUG, &pdev->dev, "+---->Open Address Frame :\n"); + mvs_hexdump(MVS_OAF_SZ, (u8 *) slot->buf + slot->cmd_size, + (u32) slot->buf_dma + slot->cmd_size); + /*3.status buffer */ + mvs_hba_sb_dump(mvi, tag, proto); + /*4.PRD table */ + dev_printk(KERN_DEBUG, &pdev->dev, "+---->PRD table :\n"); + mvs_hexdump(sizeof(struct mvs_prd) * slot->n_elem, + (u8 *) slot->buf + slot->cmd_size + MVS_OAF_SZ, + (u32) slot->buf_dma + slot->cmd_size + MVS_OAF_SZ); +#endif +} + +static void mvs_hba_cq_dump(struct mvs_info *mvi) +{ +#if _MV_DUMP + u64 addr; + void __iomem *regs = mvi->regs; + struct pci_dev *pdev = mvi->pdev; + u32 entry = mvi->rx_cons + 1; + u32 rx_desc = le32_to_cpu(mvi->rx[entry]); + + /*Completion Queue */ + addr = mr32(RX_HI) << 16 << 16 | mr32(RX_LO); + dev_printk(KERN_DEBUG, &pdev->dev, "Completion Task = 0x%08X\n", + (u32) mvi->slot_info[rx_desc & RXQ_SLOT_MASK].task); + dev_printk(KERN_DEBUG, &pdev->dev, + "Completion List Base Address=0x%llX (PA), " + "CQ_Entry=%04d, CQ_WP=0x%08X\n", + addr, entry - 1, mvi->rx[0]); + mvs_hexdump(sizeof(u32), (u8 *)(&rx_desc), + mvi->rx_dma + sizeof(u32) * entry); +#endif +} + +static void mvs_hba_interrupt_enable(struct mvs_info *mvi) +{ + void __iomem *regs = mvi->regs; + u32 tmp; + + tmp = mr32(GBL_CTL); + + mw32(GBL_CTL, tmp | INT_EN); +} + +static void mvs_hba_interrupt_disable(struct mvs_info *mvi) +{ + void __iomem *regs = mvi->regs; + u32 tmp; + + tmp = mr32(GBL_CTL); + + mw32(GBL_CTL, tmp & ~INT_EN); +} + +static int mvs_int_rx(struct mvs_info *mvi, bool self_clear); /* move to PCI layer or libata core? */ static int pci_go_64(struct pci_dev *pdev) @@ -519,39 +865,38 @@ static int pci_go_64(struct pci_dev *pdev) return rc; } -static void mvs_tag_clear(struct mvs_info *mvi, unsigned int tag) +static void mvs_tag_clear(struct mvs_info *mvi, u32 tag) { - mvi->tags[tag / sizeof(unsigned long)] &= - ~(1UL << (tag % sizeof(unsigned long))); + mvi->tag_in = (mvi->tag_in + 1) & (MVS_SLOTS - 1); + mvi->tags[mvi->tag_in] = tag; } -static void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) +static void mvs_tag_free(struct mvs_info *mvi, u32 tag) { - mvi->tags[tag / sizeof(unsigned long)] |= - (1UL << (tag % sizeof(unsigned long))); + mvi->tag_out = (mvi->tag_out - 1) & (MVS_SLOTS - 1); } -static bool mvs_tag_test(struct mvs_info *mvi, unsigned int tag) +static int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out) { - return mvi->tags[tag / sizeof(unsigned long)] & - (1UL << (tag % sizeof(unsigned long))); + if (mvi->tag_out != mvi->tag_in) { + *tag_out = mvi->tags[mvi->tag_out]; + mvi->tag_out = (mvi->tag_out + 1) & (MVS_SLOTS - 1); + return 0; + } + return -EBUSY; } -static int mvs_tag_alloc(struct mvs_info *mvi, unsigned int *tag_out) +static void mvs_tag_init(struct mvs_info *mvi) { - unsigned int i; - - for (i = 0; i < MVS_SLOTS; i++) - if (!mvs_tag_test(mvi, i)) { - mvs_tag_set(mvi, i); - *tag_out = i; - return 0; - } - - return -EBUSY; + int i; + for (i = 0; i < MVS_SLOTS; ++i) + mvi->tags[i] = i; + mvi->tag_out = 0; + mvi->tag_in = MVS_SLOTS - 1; } -static int mvs_eep_read(void __iomem *regs, unsigned int addr, u32 *data) +#ifndef MVS_DISABLE_NVRAM +static int mvs_eep_read(void __iomem *regs, u32 addr, u32 *data) { int timeout = 1000; @@ -573,10 +918,10 @@ static int mvs_eep_read(void __iomem *regs, unsigned int addr, u32 *data) return -EBUSY; } -static int mvs_eep_read_buf(void __iomem *regs, unsigned int addr, - void *buf, unsigned int buflen) +static int mvs_eep_read_buf(void __iomem *regs, u32 addr, + void *buf, u32 buflen) { - unsigned int addr_end, tmp_addr, i, j; + u32 addr_end, tmp_addr, i, j; u32 tmp = 0; int rc; u8 *tmp8, *buf8 = buf; @@ -592,7 +937,7 @@ static int mvs_eep_read_buf(void __iomem *regs, unsigned int addr, if (rc) return rc; - tmp8 = (u8 *) &tmp; + tmp8 = (u8 *)&tmp; for (i = j; i < 4; i++) *buf8++ = tmp8[i]; @@ -613,7 +958,7 @@ static int mvs_eep_read_buf(void __iomem *regs, unsigned int addr, if (rc) return rc; - tmp8 = (u8 *) &tmp; + tmp8 = (u8 *)&tmp; j = addr_end - tmp_addr; for (i = 0; i < j; i++) *buf8++ = tmp8[i]; @@ -623,13 +968,15 @@ static int mvs_eep_read_buf(void __iomem *regs, unsigned int addr, return 0; } +#endif -static int mvs_nvram_read(struct mvs_info *mvi, unsigned int addr, - void *buf, unsigned int buflen) +static int mvs_nvram_read(struct mvs_info *mvi, u32 addr, + void *buf, u32 buflen) { +#ifndef MVS_DISABLE_NVRAM void __iomem *regs = mvi->regs; int rc, i; - unsigned int sum; + u32 sum; u8 hdr[2], *tmp; const char *msg; @@ -644,16 +991,17 @@ static int mvs_nvram_read(struct mvs_info *mvi, unsigned int addr, goto err_out; } - if (hdr[0] != 0x5A) { /* entry id */ + if (hdr[0] != 0x5A) { + /* entry id */ msg = "invalid nvram entry id"; rc = -ENOENT; goto err_out; } tmp = buf; - sum = ((unsigned int)hdr[0]) + ((unsigned int)hdr[1]); + sum = ((u32)hdr[0]) + ((u32)hdr[1]); for (i = 0; i < buflen; i++) - sum += ((unsigned int)tmp[i]); + sum += ((u32)tmp[i]); if (sum) { msg = "nvram checksum failure"; @@ -665,12 +1013,123 @@ static int mvs_nvram_read(struct mvs_info *mvi, unsigned int addr, err_out: dev_printk(KERN_ERR, &mvi->pdev->dev, "%s", msg); + return rc; +#else + /* FIXME , For SAS target mode */ + memcpy(buf, "\x00\x00\xab\x11\x30\x04\x05\x50", 8); + return 0; +#endif +} + +static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) +{ + struct mvs_phy *phy = &mvi->phy[i]; + + if (!phy->phy_attached) + return; + + if (phy->phy_type & PORT_TYPE_SAS) { + struct sas_identify_frame *id; + + id = (struct sas_identify_frame *)phy->frame_rcvd; + id->dev_type = phy->identify.device_type; + id->initiator_bits = SAS_PROTOCOL_ALL; + id->target_bits = phy->identify.target_port_protocols; + } else if (phy->phy_type & PORT_TYPE_SATA) { + /* TODO */ + } + mvi->sas.sas_phy[i]->frame_rcvd_size = phy->frame_rcvd_size; + mvi->sas.notify_port_event(mvi->sas.sas_phy[i], + PORTE_BYTES_DMAED); +} + +static int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time) +{ + /* give the phy enabling interrupt event time to come in (1s + * is empirically about all it takes) */ + if (time < HZ) + return 0; + /* Wait for discovery to finish */ + scsi_flush_work(shost); + return 1; +} + +static void mvs_scan_start(struct Scsi_Host *shost) +{ + int i; + struct mvs_info *mvi = SHOST_TO_SAS_HA(shost)->lldd_ha; + + for (i = 0; i < mvi->chip->n_phy; ++i) { + mvs_bytes_dmaed(mvi, i); + } +} + +static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev) +{ + int rc; + + rc = sas_slave_alloc(scsi_dev); + return rc; } static void mvs_int_port(struct mvs_info *mvi, int port_no, u32 events) { - /* FIXME */ + struct pci_dev *pdev = mvi->pdev; + struct sas_ha_struct *sas_ha = &mvi->sas; + struct mvs_phy *phy = &mvi->phy[port_no]; + struct asd_sas_phy *sas_phy = &phy->sas_phy; + + phy->irq_status = mvs_read_port_irq_stat(mvi, port_no); + /* + * events is port event now , + * we need check the interrupt status which belongs to per port. + */ + dev_printk(KERN_DEBUG, &pdev->dev, + "Port %d Event = %X\n", + port_no, phy->irq_status); + + if (phy->irq_status & (PHYEV_POOF | PHYEV_DEC_ERR)) { + if (!mvs_is_phy_ready(mvi, port_no)) { + sas_phy_disconnected(sas_phy); + sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); + } else + mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET, NULL); + } + if (!(phy->irq_status & PHYEV_DEC_ERR)) { + if (phy->irq_status & PHYEV_COMWAKE) { + u32 tmp = mvs_read_port_irq_mask(mvi, port_no); + mvs_write_port_irq_mask(mvi, port_no, + tmp | PHYEV_SIG_FIS); + } + if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) { + phy->phy_status = mvs_is_phy_ready(mvi, port_no); + if (phy->phy_status) { + mvs_detect_porttype(mvi, port_no); + + if (phy->phy_type & PORT_TYPE_SATA) { + u32 tmp = mvs_read_port_irq_mask(mvi, + port_no); + tmp &= ~PHYEV_SIG_FIS; + mvs_write_port_irq_mask(mvi, + port_no, tmp); + } + + mvs_update_phyinfo(mvi, port_no, 0); + sas_ha->notify_phy_event(sas_phy, + PHYE_OOB_DONE); + mvs_bytes_dmaed(mvi, port_no); + } else { + dev_printk(KERN_DEBUG, &pdev->dev, + "plugin interrupt but phy is gone\n"); + mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET, + NULL); + } + } else if (phy->irq_status & PHYEV_BROAD_CH) + sas_ha->notify_port_event(sas_phy, + PORTE_BROADCAST_RCVD); + } + mvs_write_port_irq_stat(mvi, port_no, phy->irq_status); } static void mvs_int_sata(struct mvs_info *mvi) @@ -679,11 +1138,12 @@ static void mvs_int_sata(struct mvs_info *mvi) } static void mvs_slot_free(struct mvs_info *mvi, struct sas_task *task, - struct mvs_slot_info *slot, unsigned int slot_idx) + struct mvs_slot_info *slot, u32 slot_idx) { - if (slot->n_elem) - pci_unmap_sg(mvi->pdev, task->scatter, - slot->n_elem, task->data_dir); + if (!sas_protocol_ata(task->task_proto)) + if (slot->n_elem) + pci_unmap_sg(mvi->pdev, task->scatter, + slot->n_elem, task->data_dir); switch (task->task_proto) { case SAS_PROTOCOL_SMP: @@ -701,40 +1161,60 @@ static void mvs_slot_free(struct mvs_info *mvi, struct sas_task *task, break; } + slot->task = NULL; mvs_tag_clear(mvi, slot_idx); } static void mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, - unsigned int slot_idx) + u32 slot_idx) { - /* FIXME */ + struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; + u64 err_dw0 = *(u32 *) slot->response; + void __iomem *regs = mvi->regs; + u32 tmp; + + if (err_dw0 & CMD_ISS_STPD) + if (sas_protocol_ata(task->task_proto)) { + tmp = mr32(INT_STAT_SRS); + mw32(INT_STAT_SRS, tmp & 0xFFFF); + } + + mvs_hba_sb_dump(mvi, slot_idx, task->task_proto); } -static void mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc) +static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc) { - unsigned int slot_idx = rx_desc & RXQ_SLOT_MASK; + u32 slot_idx = rx_desc & RXQ_SLOT_MASK; struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; struct sas_task *task = slot->task; struct task_status_struct *tstat = &task->task_status; + struct mvs_port *port = &mvi->port[task->dev->port->id]; bool aborted; + void *to; spin_lock(&task->task_state_lock); aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED; if (!aborted) { task->task_state_flags &= - ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); + ~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR); task->task_state_flags |= SAS_TASK_STATE_DONE; } spin_unlock(&task->task_state_lock); if (aborted) - return; + return -1; memset(tstat, 0, sizeof(*tstat)); tstat->resp = SAS_TASK_COMPLETE; + + if (unlikely(!port->port_attached)) { + tstat->stat = SAS_PHY_DOWN; + goto out; + } + /* error info record present */ - if (rx_desc & RXQ_ERR) { + if ((rx_desc & RXQ_ERR) && (*(u64 *) slot->response)) { tstat->stat = SAM_CHECK_COND; mvs_slot_err(mvi, task, slot_idx); goto out; @@ -743,13 +1223,14 @@ static void mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc) switch (task->task_proto) { case SAS_PROTOCOL_SSP: /* hw says status == 0, datapres == 0 */ - if (rx_desc & RXQ_GOOD) + if (rx_desc & RXQ_GOOD) { tstat->stat = SAM_GOOD; - + tstat->resp = SAS_TASK_COMPLETE; + } /* response frame present */ else if (rx_desc & RXQ_RSP) { struct ssp_response_iu *iu = - slot->response + sizeof(struct mvs_err_info); + slot->response + sizeof(struct mvs_err_info); sas_ssp_task_response(&mvi->pdev->dev, task, iu); } @@ -758,20 +1239,37 @@ static void mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc) tstat->stat = SAM_CHECK_COND; break; - case SAS_PROTOCOL_SMP: - tstat->stat = SAM_GOOD; - break; + case SAS_PROTOCOL_SMP: { + struct scatterlist *sg_resp = &task->smp_task.smp_resp; + tstat->stat = SAM_GOOD; + to = kmap_atomic(sg_page(sg_resp), KM_IRQ0); + memcpy(to + sg_resp->offset, + slot->response + sizeof(struct mvs_err_info), + sg_dma_len(sg_resp)); + kunmap_atomic(to, KM_IRQ0); + break; + } case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: - if ((rx_desc & (RXQ_DONE | RXQ_ERR | RXQ_ATTN)) == RXQ_DONE) - tstat->stat = SAM_GOOD; - else - tstat->stat = SAM_CHECK_COND; - /* FIXME: read taskfile data from SATA register set - * associated with SATA target - */ - break; + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: { + struct ata_task_resp *resp = + (struct ata_task_resp *)tstat->buf; + + if ((rx_desc & (RXQ_DONE | RXQ_ERR | RXQ_ATTN)) == + RXQ_DONE) + tstat->stat = SAM_GOOD; + else + tstat->stat = SAM_CHECK_COND; + + resp->frame_len = sizeof(struct dev_to_host_fis); + memcpy(&resp->ending_fis[0], + SATA_RECEIVED_D2H_FIS(port->taskfileset), + sizeof(struct dev_to_host_fis)); + if (resp->ending_fis[2] & ATA_ERR) + mvs_hexdump(16, resp->ending_fis, 0); + break; + } default: tstat->stat = SAM_CHECK_COND; @@ -781,6 +1279,7 @@ static void mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc) out: mvs_slot_free(mvi, task, slot, slot_idx); task->task_done(task); + return tstat->stat; } static void mvs_int_full(struct mvs_info *mvi) @@ -791,6 +1290,8 @@ static void mvs_int_full(struct mvs_info *mvi) stat = mr32(INT_STAT); + mvs_int_rx(mvi, false); + for (i = 0; i < MVS_MAX_PORTS; i++) { tmp = (stat >> i) & (CINT_PORT | CINT_PORT_STOPPED); if (tmp) @@ -800,48 +1301,62 @@ static void mvs_int_full(struct mvs_info *mvi) if (stat & CINT_SRS) mvs_int_sata(mvi); - if (stat & (CINT_CI_STOP | CINT_DONE)) - mvs_int_rx(mvi, false); - mw32(INT_STAT, stat); } -static void mvs_int_rx(struct mvs_info *mvi, bool self_clear) +static int mvs_int_rx(struct mvs_info *mvi, bool self_clear) { + void __iomem *regs = mvi->regs; u32 rx_prod_idx, rx_desc; bool attn = false; + struct pci_dev *pdev = mvi->pdev; /* the first dword in the RX ring is special: it contains * a mirror of the hardware's RX producer index, so that * we don't have to stall the CPU reading that register. * The actual RX ring is offset by one dword, due to this. */ - rx_prod_idx = le32_to_cpu(mvi->rx[0]) & 0xfff; + rx_prod_idx = mr32(RX_CONS_IDX) & RX_RING_SZ_MASK; if (rx_prod_idx == 0xfff) { /* h/w hasn't touched RX ring yet */ mvi->rx_cons = 0xfff; - return; + return 0; } + + /* The CMPL_Q may come late, read from register and try again + * note: if coalescing is enabled, + * it will need to read from register every time for sure + */ + if (mvi->rx_cons == rx_prod_idx) + return 0; + if (mvi->rx_cons == 0xfff) mvi->rx_cons = MVS_RX_RING_SZ - 1; while (mvi->rx_cons != rx_prod_idx) { + /* increment our internal RX consumer pointer */ mvi->rx_cons = (mvi->rx_cons + 1) & (MVS_RX_RING_SZ - 1); - /* Read RX descriptor at offset+1, due to above */ rx_desc = le32_to_cpu(mvi->rx[mvi->rx_cons + 1]); - if (rx_desc & RXQ_DONE) - /* we had a completion, error or no */ - mvs_slot_complete(mvi, rx_desc); + mvs_hba_cq_dump(mvi); - if (rx_desc & RXQ_ATTN) + if (unlikely(rx_desc & RXQ_DONE)) + mvs_slot_complete(mvi, rx_desc); + if (rx_desc & RXQ_ATTN) { attn = true; + dev_printk(KERN_DEBUG, &pdev->dev, "ATTN %X\n", + rx_desc); + } else if (rx_desc & RXQ_ERR) { + dev_printk(KERN_DEBUG, &pdev->dev, "RXQ_ERR %X\n", + rx_desc); + } } if (attn && self_clear) mvs_int_full(mvi); + return 0; } static irqreturn_t mvs_interrupt(int irq, void *opaque) @@ -851,6 +1366,10 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque) u32 stat; stat = mr32(GBL_INT_STAT); + + /* clear CMD_CMPLT ASAP */ + mw32_f(INT_STAT, CINT_DONE); + if (stat == 0 || stat == 0xffffffff) return IRQ_NONE; @@ -863,6 +1382,7 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque) return IRQ_HANDLED; } +#ifndef MVS_DISABLE_MSI static irqreturn_t mvs_msi_interrupt(int irq, void *opaque) { struct mvs_info *mvi = opaque; @@ -875,32 +1395,46 @@ static irqreturn_t mvs_msi_interrupt(int irq, void *opaque) return IRQ_HANDLED; } +#endif struct mvs_task_exec_info { - struct sas_task *task; - struct mvs_cmd_hdr *hdr; - unsigned int tag; - int n_elem; + struct sas_task *task; + struct mvs_cmd_hdr *hdr; + struct mvs_port *port; + u32 tag; + int n_elem; }; -static int mvs_task_prep_smp(struct mvs_info *mvi, struct mvs_task_exec_info *tei) +static int mvs_task_prep_smp(struct mvs_info *mvi, + struct mvs_task_exec_info *tei) { - int elem, rc; + int elem, rc, i; + struct sas_task *task = tei->task; struct mvs_cmd_hdr *hdr = tei->hdr; struct scatterlist *sg_req, *sg_resp; - unsigned int req_len, resp_len, tag = tei->tag; - + u32 req_len, resp_len, tag = tei->tag; + void *buf_tmp; + u8 *buf_oaf; + dma_addr_t buf_tmp_dma; + struct mvs_prd *buf_prd; + struct scatterlist *sg; + struct mvs_slot_info *slot = &mvi->slot_info[tag]; + struct asd_sas_port *sas_port = task->dev->port; + u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); +#if _MV_DUMP + u8 *buf_cmd; + void *from; +#endif /* * DMA-map SMP request, response buffers */ - - sg_req = &tei->task->smp_task.smp_req; + sg_req = &task->smp_task.smp_req; elem = pci_map_sg(mvi->pdev, sg_req, 1, PCI_DMA_TODEVICE); if (!elem) return -ENOMEM; req_len = sg_dma_len(sg_req); - sg_resp = &tei->task->smp_task.smp_resp; + sg_resp = &task->smp_task.smp_resp; elem = pci_map_sg(mvi->pdev, sg_resp, 1, PCI_DMA_FROMDEVICE); if (!elem) { rc = -ENOMEM; @@ -915,21 +1449,77 @@ static int mvs_task_prep_smp(struct mvs_info *mvi, struct mvs_task_exec_info *te } /* - * Fill in TX ring and command slot header + * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs */ - mvi->tx[tag] = cpu_to_le32( - (TXQ_CMD_SMP << TXQ_CMD_SHIFT) | TXQ_MODE_I | tag); + /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ************** */ + buf_tmp = slot->buf; + buf_tmp_dma = slot->buf_dma; - hdr->flags = 0; - hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4)); +#if _MV_DUMP + buf_cmd = buf_tmp; + hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma); + buf_tmp += req_len; + buf_tmp_dma += req_len; + slot->cmd_size = req_len; +#else + hdr->cmd_tbl = cpu_to_le64(sg_dma_address(sg_req)); +#endif + + /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ + buf_oaf = buf_tmp; + hdr->open_frame = cpu_to_le64(buf_tmp_dma); + + buf_tmp += MVS_OAF_SZ; + buf_tmp_dma += MVS_OAF_SZ; + + /* region 3: PRD table ********************************************* */ + buf_prd = buf_tmp; + if (tei->n_elem) + hdr->prd_tbl = cpu_to_le64(buf_tmp_dma); + else + hdr->prd_tbl = 0; + + i = sizeof(struct mvs_prd) * tei->n_elem; + buf_tmp += i; + buf_tmp_dma += i; + + /* region 4: status buffer (larger the PRD, smaller this buf) ****** */ + slot->response = buf_tmp; + hdr->status_buf = cpu_to_le64(buf_tmp_dma); + + /* + * Fill in TX ring and command slot header + */ + slot->tx = mvi->tx_prod; + mvi->tx[mvi->tx_prod] = cpu_to_le32((TXQ_CMD_SMP << TXQ_CMD_SHIFT) | + TXQ_MODE_I | tag | + (sas_port->phy_mask << TXQ_PHY_SHIFT)); + + hdr->flags |= flags; + hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | ((req_len - 4) / 4)); hdr->tags = cpu_to_le32(tag); hdr->data_len = 0; - hdr->cmd_tbl = cpu_to_le64(sg_dma_address(sg_req)); - hdr->open_frame = 0; - hdr->status_buf = cpu_to_le64(sg_dma_address(sg_resp)); - hdr->prd_tbl = 0; + /* generate open address frame hdr (first 12 bytes) */ + buf_oaf[0] = (1 << 7) | (0 << 4) | 0x01; /* initiator, SMP, ftype 1h */ + buf_oaf[1] = task->dev->linkrate & 0xf; + *(u16 *)(buf_oaf + 2) = 0xFFFF; /* SAS SPEC */ + memcpy(buf_oaf + 4, task->dev->sas_addr, SAS_ADDR_SIZE); + + /* fill in PRD (scatter/gather) table, if any */ + for_each_sg(task->scatter, sg, tei->n_elem, i) { + buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); + buf_prd->len = cpu_to_le32(sg_dma_len(sg)); + buf_prd++; + } + +#if _MV_DUMP + /* copy cmd table */ + from = kmap_atomic(sg_page(sg_req), KM_IRQ0); + memcpy(buf_cmd, from + sg_req->offset, req_len); + kunmap_atomic(from, KM_IRQ0); +#endif return 0; err_out_2: @@ -941,6 +1531,73 @@ static int mvs_task_prep_smp(struct mvs_info *mvi, struct mvs_task_exec_info *te return rc; } +static void mvs_free_reg_set(struct mvs_info *mvi, struct mvs_port *port) +{ + void __iomem *regs = mvi->regs; + u32 tmp, offs; + u8 *tfs = &port->taskfileset; + + if (*tfs == MVS_ID_NOT_MAPPED) + return; + + offs = 1U << ((*tfs & 0x0f) + PCS_EN_SATA_REG_SHIFT); + if (*tfs < 16) { + tmp = mr32(PCS); + mw32(PCS, tmp & ~offs); + } else { + tmp = mr32(CTL); + mw32(CTL, tmp & ~offs); + } + + tmp = mr32(INT_STAT_SRS) & (1U << *tfs); + if (tmp) + mw32(INT_STAT_SRS, tmp); + + *tfs = MVS_ID_NOT_MAPPED; +} + +static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port) +{ + int i; + u32 tmp, offs; + void __iomem *regs = mvi->regs; + + if (port->taskfileset != MVS_ID_NOT_MAPPED) + return 0; + + tmp = mr32(PCS); + + for (i = 0; i < mvi->chip->srs_sz; i++) { + if (i == 16) + tmp = mr32(CTL); + offs = 1U << ((i & 0x0f) + PCS_EN_SATA_REG_SHIFT); + if (!(tmp & offs)) { + port->taskfileset = i; + + if (i < 16) + mw32(PCS, tmp | offs); + else + mw32(CTL, tmp | offs); + tmp = mr32(INT_STAT_SRS) & (1U << i); + if (tmp) + mw32(INT_STAT_SRS, tmp); + return 0; + } + } + return MVS_ID_NOT_MAPPED; +} + +static u32 mvs_get_ncq_tag(struct sas_task *task) +{ + u32 tag = 0; + struct ata_queued_cmd *qc = task->uldd_task; + + if (qc) + tag = qc->tag; + + return tag; +} + static int mvs_task_prep_ata(struct mvs_info *mvi, struct mvs_task_exec_info *tei) { @@ -948,47 +1605,65 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, struct domain_device *dev = task->dev; struct mvs_cmd_hdr *hdr = tei->hdr; struct asd_sas_port *sas_port = dev->port; - unsigned int tag = tei->tag; - struct mvs_slot_info *slot = &mvi->slot_info[tag]; - u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); + struct mvs_slot_info *slot; struct scatterlist *sg; struct mvs_prd *buf_prd; + struct mvs_port *port = tei->port; + u32 tag = tei->tag; + u32 flags = (tei->n_elem << MCH_PRD_LEN_SHIFT); void *buf_tmp; u8 *buf_cmd, *buf_oaf; dma_addr_t buf_tmp_dma; - unsigned int i, req_len, resp_len; + u32 i, req_len, resp_len; + const u32 max_resp_len = SB_RFB_MAX; + + if (mvs_assign_reg_set(mvi, port) == MVS_ID_NOT_MAPPED) + return -EBUSY; - /* FIXME: fill in SATA register set */ - mvi->tx[tag] = cpu_to_le32(TXQ_MODE_I | tag | - (TXQ_CMD_STP << TXQ_CMD_SHIFT) | - (sas_port->phy_mask << TXQ_PHY_SHIFT)); + slot = &mvi->slot_info[tag]; + slot->tx = mvi->tx_prod; + mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag | + (TXQ_CMD_STP << TXQ_CMD_SHIFT) | + (sas_port->phy_mask << TXQ_PHY_SHIFT) | + (port->taskfileset << TXQ_SRS_SHIFT)); if (task->ata_task.use_ncq) flags |= MCH_FPDMA; - if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) - flags |= MCH_ATAPI; + if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) { + if (task->ata_task.fis.command != ATA_CMD_ID_ATAPI) + flags |= MCH_ATAPI; + } + /* FIXME: fill in port multiplier number */ hdr->flags = cpu_to_le32(flags); - hdr->tags = cpu_to_le32(tag); + + /* FIXME: the low order order 5 bits for the TAG if enable NCQ */ + if (task->ata_task.use_ncq) { + hdr->tags = cpu_to_le32(mvs_get_ncq_tag(task)); + /*Fill in task file */ + task->ata_task.fis.sector_count = hdr->tags << 3; + } else + hdr->tags = cpu_to_le32(tag); hdr->data_len = cpu_to_le32(task->total_xfer_len); /* * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs */ - memset(slot->buf, 0, MVS_SLOT_BUF_SZ); - /* region 1: command table area (MVS_ATA_CMD_SZ bytes) ***************/ - buf_cmd = - buf_tmp = slot->buf; + /* region 1: command table area (MVS_ATA_CMD_SZ bytes) ************** */ + buf_cmd = buf_tmp = slot->buf; buf_tmp_dma = slot->buf_dma; hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma); buf_tmp += MVS_ATA_CMD_SZ; buf_tmp_dma += MVS_ATA_CMD_SZ; +#if _MV_DUMP + slot->cmd_size = MVS_ATA_CMD_SZ; +#endif - /* region 2: open address frame area (MVS_OAF_SZ bytes) **********/ + /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ /* used for STP. unused for SATA? */ buf_oaf = buf_tmp; hdr->open_frame = cpu_to_le64(buf_tmp_dma); @@ -996,40 +1671,49 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, buf_tmp += MVS_OAF_SZ; buf_tmp_dma += MVS_OAF_SZ; - /* region 3: PRD table ***********************************************/ + /* region 3: PRD table ********************************************* */ buf_prd = buf_tmp; - hdr->prd_tbl = cpu_to_le64(buf_tmp_dma); + if (tei->n_elem) + hdr->prd_tbl = cpu_to_le64(buf_tmp_dma); + else + hdr->prd_tbl = 0; i = sizeof(struct mvs_prd) * tei->n_elem; buf_tmp += i; buf_tmp_dma += i; - /* region 4: status buffer (larger the PRD, smaller this buf) ********/ + /* region 4: status buffer (larger the PRD, smaller this buf) ****** */ /* FIXME: probably unused, for SATA. kept here just in case * we get a STP/SATA error information record */ slot->response = buf_tmp; hdr->status_buf = cpu_to_le64(buf_tmp_dma); - req_len = sizeof(struct ssp_frame_hdr) + 28; + req_len = sizeof(struct host_to_dev_fis); resp_len = MVS_SLOT_BUF_SZ - MVS_ATA_CMD_SZ - - sizeof(struct mvs_err_info) - i; + sizeof(struct mvs_err_info) - i; /* request, response lengths */ + resp_len = min(resp_len, max_resp_len); hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4)); + task->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */ /* fill in command FIS and ATAPI CDB */ - memcpy(buf_cmd, &task->ata_task.fis, - sizeof(struct host_to_dev_fis)); - memcpy(buf_cmd + 0x40, task->ata_task.atapi_packet, 16); + memcpy(buf_cmd, &task->ata_task.fis, sizeof(struct host_to_dev_fis)); + if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) + memcpy(buf_cmd + STP_ATAPI_CMD, + task->ata_task.atapi_packet, 16); + + /* generate open address frame hdr (first 12 bytes) */ + buf_oaf[0] = (1 << 7) | (2 << 4) | 0x1; /* initiator, STP, ftype 1h */ + buf_oaf[1] = task->dev->linkrate & 0xf; + *(u16 *)(buf_oaf + 2) = cpu_to_be16(tag); + memcpy(buf_oaf + 4, task->dev->sas_addr, SAS_ADDR_SIZE); /* fill in PRD (scatter/gather) table, if any */ - sg = task->scatter; - for (i = 0; i < tei->n_elem; i++) { + for_each_sg(task->scatter, sg, tei->n_elem, i) { buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); buf_prd->len = cpu_to_le32(sg_dma_len(sg)); - - sg++; buf_prd++; } @@ -1040,23 +1724,25 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, struct mvs_task_exec_info *tei) { struct sas_task *task = tei->task; - struct asd_sas_port *sas_port = task->dev->port; struct mvs_cmd_hdr *hdr = tei->hdr; + struct mvs_port *port = tei->port; struct mvs_slot_info *slot; struct scatterlist *sg; - unsigned int resp_len, req_len, i, tag = tei->tag; struct mvs_prd *buf_prd; struct ssp_frame_hdr *ssp_hdr; void *buf_tmp; u8 *buf_cmd, *buf_oaf, fburst = 0; dma_addr_t buf_tmp_dma; u32 flags; + u32 resp_len, req_len, i, tag = tei->tag; + const u32 max_resp_len = SB_RFB_MAX; slot = &mvi->slot_info[tag]; - mvi->tx[tag] = cpu_to_le32(TXQ_MODE_I | tag | - (TXQ_CMD_SSP << TXQ_CMD_SHIFT) | - (sas_port->phy_mask << TXQ_PHY_SHIFT)); + slot->tx = mvi->tx_prod; + mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag | + (TXQ_CMD_SSP << TXQ_CMD_SHIFT) | + (port->wide_port_phymap << TXQ_PHY_SHIFT)); flags = MCH_RETRY; if (task->ssp_task.enable_first_burst) { @@ -1064,8 +1750,8 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, fburst = (1 << 7); } hdr->flags = cpu_to_le32(flags | - (tei->n_elem << MCH_PRD_LEN_SHIFT) | - (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT)); + (tei->n_elem << MCH_PRD_LEN_SHIFT) | + (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT)); hdr->tags = cpu_to_le32(tag); hdr->data_len = cpu_to_le32(task->total_xfer_len); @@ -1073,40 +1759,46 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, /* * arrange MVS_SLOT_BUF_SZ-sized DMA buffer according to our needs */ - memset(slot->buf, 0, MVS_SLOT_BUF_SZ); - /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ***************/ - buf_cmd = - buf_tmp = slot->buf; + /* region 1: command table area (MVS_SSP_CMD_SZ bytes) ************** */ + buf_cmd = buf_tmp = slot->buf; buf_tmp_dma = slot->buf_dma; hdr->cmd_tbl = cpu_to_le64(buf_tmp_dma); buf_tmp += MVS_SSP_CMD_SZ; buf_tmp_dma += MVS_SSP_CMD_SZ; +#if _MV_DUMP + slot->cmd_size = MVS_SSP_CMD_SZ; +#endif - /* region 2: open address frame area (MVS_OAF_SZ bytes) **********/ + /* region 2: open address frame area (MVS_OAF_SZ bytes) ********* */ buf_oaf = buf_tmp; hdr->open_frame = cpu_to_le64(buf_tmp_dma); buf_tmp += MVS_OAF_SZ; buf_tmp_dma += MVS_OAF_SZ; - /* region 3: PRD table ***********************************************/ + /* region 3: PRD table ********************************************* */ buf_prd = buf_tmp; - hdr->prd_tbl = cpu_to_le64(buf_tmp_dma); + if (tei->n_elem) + hdr->prd_tbl = cpu_to_le64(buf_tmp_dma); + else + hdr->prd_tbl = 0; i = sizeof(struct mvs_prd) * tei->n_elem; buf_tmp += i; buf_tmp_dma += i; - /* region 4: status buffer (larger the PRD, smaller this buf) ********/ + /* region 4: status buffer (larger the PRD, smaller this buf) ****** */ slot->response = buf_tmp; hdr->status_buf = cpu_to_le64(buf_tmp_dma); - req_len = sizeof(struct ssp_frame_hdr) + 28; resp_len = MVS_SLOT_BUF_SZ - MVS_SSP_CMD_SZ - MVS_OAF_SZ - - sizeof(struct mvs_err_info) - i; + sizeof(struct mvs_err_info) - i; + resp_len = min(resp_len, max_resp_len); + + req_len = sizeof(struct ssp_frame_hdr) + 28; /* request, response lengths */ hdr->lens = cpu_to_le32(((resp_len / 4) << 16) | (req_len / 4)); @@ -1114,12 +1806,11 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, /* generate open address frame hdr (first 12 bytes) */ buf_oaf[0] = (1 << 7) | (1 << 4) | 0x1; /* initiator, SSP, ftype 1h */ buf_oaf[1] = task->dev->linkrate & 0xf; - buf_oaf[2] = tag >> 8; - buf_oaf[3] = tag; + *(u16 *)(buf_oaf + 2) = cpu_to_be16(tag); memcpy(buf_oaf + 4, task->dev->sas_addr, SAS_ADDR_SIZE); - /* fill in SSP frame header */ - ssp_hdr = (struct ssp_frame_hdr *) buf_cmd; + /* fill in SSP frame header (Command Table.SSP frame header) */ + ssp_hdr = (struct ssp_frame_hdr *)buf_cmd; ssp_hdr->frame_type = SSP_COMMAND; memcpy(ssp_hdr->hashed_dest_addr, task->dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE); @@ -1130,18 +1821,14 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, /* fill in command frame IU */ buf_cmd += sizeof(*ssp_hdr); memcpy(buf_cmd, &task->ssp_task.LUN, 8); - buf_cmd[9] = fburst | - task->ssp_task.task_attr | - (task->ssp_task.task_prio << 3); + buf_cmd[9] = fburst | task->ssp_task.task_attr | + (task->ssp_task.task_prio << 3); memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16); /* fill in PRD (scatter/gather) table, if any */ - sg = task->scatter; - for (i = 0; i < tei->n_elem; i++) { + for_each_sg(task->scatter, sg, tei->n_elem, i) { buf_prd->addr = cpu_to_le64(sg_dma_address(sg)); buf_prd->len = cpu_to_le32(sg_dma_len(sg)); - - sg++; buf_prd++; } @@ -1150,77 +1837,157 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) { - struct mvs_info *mvi = task->dev->port->ha->lldd_ha; - unsigned int tag = 0xdeadbeef, rc, n_elem = 0; + struct domain_device *dev = task->dev; + struct mvs_info *mvi = dev->port->ha->lldd_ha; + struct pci_dev *pdev = mvi->pdev; void __iomem *regs = mvi->regs; - unsigned long flags; struct mvs_task_exec_info tei; + struct sas_task *t = task; + u32 tag = 0xdeadbeef, rc, n_elem = 0; + unsigned long flags; + u32 n = num, pass = 0; - /* FIXME: STP/SATA support not complete yet */ - if (task->task_proto == SAS_PROTOCOL_SATA || task->task_proto == SAS_PROTOCOL_STP) - return -SAS_DEV_NO_RESPONSE; + spin_lock_irqsave(&mvi->lock, flags); - if (task->num_scatter) { - n_elem = pci_map_sg(mvi->pdev, task->scatter, - task->num_scatter, task->data_dir); - if (!n_elem) - return -ENOMEM; - } + do { + tei.port = &mvi->port[dev->port->id]; - spin_lock_irqsave(&mvi->lock, flags); + if (!tei.port->port_attached) { + struct task_status_struct *ts = &t->task_status; + ts->stat = SAS_PHY_DOWN; + t->task_done(t); + rc = 0; + goto exec_exit; + } + if (!sas_protocol_ata(t->task_proto)) { + if (t->num_scatter) { + n_elem = pci_map_sg(mvi->pdev, t->scatter, + t->num_scatter, + t->data_dir); + if (!n_elem) { + rc = -ENOMEM; + goto err_out; + } + } + } else { + n_elem = t->num_scatter; + } - rc = mvs_tag_alloc(mvi, &tag); - if (rc) - goto err_out; + rc = mvs_tag_alloc(mvi, &tag); + if (rc) + goto err_out; - mvi->slot_info[tag].task = task; - mvi->slot_info[tag].n_elem = n_elem; - tei.task = task; - tei.hdr = &mvi->slot[tag]; - tei.tag = tag; - tei.n_elem = n_elem; + mvi->slot_info[tag].task = t; + mvi->slot_info[tag].n_elem = n_elem; + memset(mvi->slot_info[tag].buf, 0, MVS_SLOT_BUF_SZ); + tei.task = t; + tei.hdr = &mvi->slot[tag]; + tei.tag = tag; + tei.n_elem = n_elem; + + switch (t->task_proto) { + case SAS_PROTOCOL_SMP: + rc = mvs_task_prep_smp(mvi, &tei); + break; + case SAS_PROTOCOL_SSP: + rc = mvs_task_prep_ssp(mvi, &tei); + break; + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: + rc = mvs_task_prep_ata(mvi, &tei); + break; + default: + dev_printk(KERN_ERR, &pdev->dev, + "unknown sas_task proto: 0x%x\n", + t->task_proto); + rc = -EINVAL; + break; + } - switch (task->task_proto) { - case SAS_PROTOCOL_SMP: - rc = mvs_task_prep_smp(mvi, &tei); - break; - case SAS_PROTOCOL_SSP: - rc = mvs_task_prep_ssp(mvi, &tei); - break; - case SAS_PROTOCOL_SATA: - case SAS_PROTOCOL_STP: - rc = mvs_task_prep_ata(mvi, &tei); - break; - default: - rc = -EINVAL; - break; - } + if (rc) + goto err_out_tag; - if (rc) - goto err_out_tag; + /* TODO: select normal or high priority */ - /* TODO: select normal or high priority */ + spin_lock(&t->task_state_lock); + t->task_state_flags |= SAS_TASK_AT_INITIATOR; + spin_unlock(&t->task_state_lock); - mw32(RX_PROD_IDX, mvi->tx_prod); + if (n == 1) { + spin_unlock_irqrestore(&mvi->lock, flags); + mw32(TX_PROD_IDX, mvi->tx_prod); + } + mvs_hba_memory_dump(mvi, tag, t->task_proto); - mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_TX_RING_SZ - 1); + ++pass; + mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1); - spin_lock(&task->task_state_lock); - task->task_state_flags |= SAS_TASK_AT_INITIATOR; - spin_unlock(&task->task_state_lock); + if (n == 1) + break; + + t = list_entry(t->list.next, struct sas_task, list); + } while (--n); - spin_unlock_irqrestore(&mvi->lock, flags); return 0; err_out_tag: - mvs_tag_clear(mvi, tag); + mvs_tag_free(mvi, tag); err_out: - if (n_elem) - pci_unmap_sg(mvi->pdev, task->scatter, n_elem, task->data_dir); + dev_printk(KERN_ERR, &pdev->dev, "mvsas exec failed[%d]!\n", rc); + if (!sas_protocol_ata(t->task_proto)) + if (n_elem) + pci_unmap_sg(mvi->pdev, t->scatter, n_elem, + t->data_dir); +exec_exit: + if (pass) + mw32(TX_PROD_IDX, (mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1)); spin_unlock_irqrestore(&mvi->lock, flags); return rc; } +static int mvs_task_abort(struct sas_task *task) +{ + int rc = 1; + unsigned long flags; + struct mvs_info *mvi = task->dev->port->ha->lldd_ha; + struct pci_dev *pdev = mvi->pdev; + + spin_lock_irqsave(&task->task_state_lock, flags); + if (task->task_state_flags & SAS_TASK_STATE_DONE) { + rc = TMF_RESP_FUNC_COMPLETE; + goto out_done; + } + spin_unlock_irqrestore(&task->task_state_lock, flags); + + /*FIXME*/ + rc = TMF_RESP_FUNC_COMPLETE; + + switch (task->task_proto) { + case SAS_PROTOCOL_SMP: + dev_printk(KERN_DEBUG, &pdev->dev, "SMP Abort! "); + break; + case SAS_PROTOCOL_SSP: + dev_printk(KERN_DEBUG, &pdev->dev, "SSP Abort! "); + break; + case SAS_PROTOCOL_SATA: + case SAS_PROTOCOL_STP: + case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:{ + dev_printk(KERN_DEBUG, &pdev->dev, "STP Abort! " + "Dump D2H FIS: \n"); + mvs_hexdump(sizeof(struct host_to_dev_fis), + (void *)&task->ata_task.fis, 0); + dev_printk(KERN_DEBUG, &pdev->dev, "Dump ATAPI Cmd : \n"); + mvs_hexdump(16, task->ata_task.atapi_packet, 0); + break; + } + default: + break; + } +out_done: + return rc; +} + static void mvs_free(struct mvs_info *mvi) { int i; @@ -1238,7 +2005,7 @@ static void mvs_free(struct mvs_info *mvi) if (mvi->tx) dma_free_coherent(&mvi->pdev->dev, - sizeof(*mvi->tx) * MVS_TX_RING_SZ, + sizeof(*mvi->tx) * MVS_CHIP_SLOT_SZ, mvi->tx, mvi->tx_dma); if (mvi->rx_fis) dma_free_coherent(&mvi->pdev->dev, MVS_RX_FISL_SZ, @@ -1249,10 +2016,12 @@ static void mvs_free(struct mvs_info *mvi) mvi->rx, mvi->rx_dma); if (mvi->slot) dma_free_coherent(&mvi->pdev->dev, - sizeof(*mvi->slot) * MVS_RX_RING_SZ, + sizeof(*mvi->slot) * MVS_SLOTS, mvi->slot, mvi->slot_dma); +#ifdef MVS_ENABLE_PERI if (mvi->peri_regs) iounmap(mvi->peri_regs); +#endif if (mvi->regs) iounmap(mvi->regs); if (mvi->shost) @@ -1267,42 +2036,39 @@ static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, void *funcdata) { struct mvs_info *mvi = sas_phy->ha->lldd_ha; - void __iomem *reg; int rc = 0, phy_id = sas_phy->id; u32 tmp; - reg = mvi->regs + MVS_P0_SER_CTLSTAT + (phy_id * 4); + tmp = mvs_read_phy_ctl(mvi, phy_id); switch (func) { - case PHY_FUNC_SET_LINK_RATE: { - struct sas_phy_linkrates *rates = funcdata; - u32 lrmin = 0, lrmax = 0; + case PHY_FUNC_SET_LINK_RATE:{ + struct sas_phy_linkrates *rates = funcdata; + u32 lrmin = 0, lrmax = 0; - lrmin = (rates->minimum_linkrate << 8); - lrmax = (rates->maximum_linkrate << 12); + lrmin = (rates->minimum_linkrate << 8); + lrmax = (rates->maximum_linkrate << 12); - tmp = readl(reg); - if (lrmin) { - tmp &= ~(0xf << 8); - tmp |= lrmin; - } - if (lrmax) { - tmp &= ~(0xf << 12); - tmp |= lrmax; + if (lrmin) { + tmp &= ~(0xf << 8); + tmp |= lrmin; + } + if (lrmax) { + tmp &= ~(0xf << 12); + tmp |= lrmax; + } + mvs_write_phy_ctl(mvi, phy_id, tmp); + break; } - writel(tmp, reg); - break; - } case PHY_FUNC_HARD_RESET: - tmp = readl(reg); if (tmp & PHY_RST_HARD) break; - writel(tmp | PHY_RST_HARD, reg); + mvs_write_phy_ctl(mvi, phy_id, tmp | PHY_RST_HARD); break; case PHY_FUNC_LINK_RESET: - writel(readl(reg) | PHY_RST, reg); + mvs_write_phy_ctl(mvi, phy_id, tmp | PHY_RST); break; case PHY_FUNC_DISABLE: @@ -1335,11 +2101,11 @@ static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id) sas_phy->lldd_phy = phy; } -static struct mvs_info * __devinit mvs_alloc(struct pci_dev *pdev, - const struct pci_device_id *ent) +static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct mvs_info *mvi; - unsigned long res_start, res_len; + unsigned long res_start, res_len, res_flag; struct asd_sas_phy **arr_phy; struct asd_sas_port **arr_port; const struct mvs_chip_info *chip = &mvs_chips[ent->driver_data]; @@ -1381,9 +2147,10 @@ static struct mvs_info * __devinit mvs_alloc(struct pci_dev *pdev, SHOST_TO_SAS_HA(mvi->shost) = &mvi->sas; mvi->shost->transportt = mvs_stt; - mvi->shost->max_id = ~0; + mvi->shost->max_id = 21; mvi->shost->max_lun = ~0; - mvi->shost->max_cmd_len = ~0; + mvi->shost->max_channel = 0; + mvi->shost->max_cmd_len = 16; mvi->sas.sas_ha_name = DRV_NAME; mvi->sas.dev = &pdev->dev; @@ -1392,32 +2159,40 @@ static struct mvs_info * __devinit mvs_alloc(struct pci_dev *pdev, mvi->sas.sas_phy = arr_phy; mvi->sas.sas_port = arr_port; mvi->sas.num_phys = chip->n_phy; - mvi->sas.lldd_max_execute_num = MVS_TX_RING_SZ - 1;/* FIXME: correct? */ - mvi->sas.lldd_queue_size = MVS_TX_RING_SZ - 1; /* FIXME: correct? */ + mvi->sas.lldd_max_execute_num = MVS_CHIP_SLOT_SZ - 1; + mvi->sas.lldd_queue_size = MVS_QUEUE_SIZE; + mvi->can_queue = (MVS_CHIP_SLOT_SZ >> 1) - 1; mvi->sas.lldd_ha = mvi; mvi->sas.core.shost = mvi->shost; - mvs_tag_set(mvi, MVS_TX_RING_SZ - 1); + mvs_tag_init(mvi); /* * ioremap main and peripheral registers */ +#ifdef MVS_ENABLE_PERI res_start = pci_resource_start(pdev, 2); res_len = pci_resource_len(pdev, 2); if (!res_start || !res_len) goto err_out; mvi->peri_regs = ioremap_nocache(res_start, res_len); - if (!mvi->regs) + if (!mvi->peri_regs) goto err_out; +#endif res_start = pci_resource_start(pdev, 4); res_len = pci_resource_len(pdev, 4); if (!res_start || !res_len) goto err_out; - mvi->regs = ioremap_nocache(res_start, res_len); + res_flag = pci_resource_flags(pdev, 4); + if (res_flag & IORESOURCE_CACHEABLE) + mvi->regs = ioremap(res_start, res_len); + else + mvi->regs = ioremap_nocache(res_start, res_len); + if (!mvi->regs) goto err_out; @@ -1426,14 +2201,14 @@ static struct mvs_info * __devinit mvs_alloc(struct pci_dev *pdev, */ mvi->tx = dma_alloc_coherent(&pdev->dev, - sizeof(*mvi->tx) * MVS_TX_RING_SZ, + sizeof(*mvi->tx) * MVS_CHIP_SLOT_SZ, &mvi->tx_dma, GFP_KERNEL); if (!mvi->tx) goto err_out; - memset(mvi->tx, 0, sizeof(*mvi->tx) * MVS_TX_RING_SZ); + memset(mvi->tx, 0, sizeof(*mvi->tx) * MVS_CHIP_SLOT_SZ); mvi->rx_fis = dma_alloc_coherent(&pdev->dev, MVS_RX_FISL_SZ, - &mvi->rx_fis_dma, GFP_KERNEL); + &mvi->rx_fis_dma, GFP_KERNEL); if (!mvi->rx_fis) goto err_out; memset(mvi->rx_fis, 0, MVS_RX_FISL_SZ); @@ -1459,7 +2234,7 @@ static struct mvs_info * __devinit mvs_alloc(struct pci_dev *pdev, struct mvs_slot_info *slot = &mvi->slot_info[i]; slot->buf = dma_alloc_coherent(&pdev->dev, MVS_SLOT_BUF_SZ, - &slot->buf_dma, GFP_KERNEL); + &slot->buf_dma, GFP_KERNEL); if (!slot->buf) goto err_out; memset(slot->buf, 0, MVS_SLOT_BUF_SZ); @@ -1468,7 +2243,6 @@ static struct mvs_info * __devinit mvs_alloc(struct pci_dev *pdev, /* finally, read NVRAM to get our SAS address */ if (mvs_nvram_read(mvi, NVR_SAS_ADDR, &mvi->sas_addr, 8)) goto err_out; - return mvi; err_out: @@ -1488,26 +2262,89 @@ static void mvs_cw32(void __iomem *regs, u32 addr, u32 val) mw32(CMD_DATA, val); } -#if 0 -static u32 mvs_phy_read(struct mvs_info *mvi, unsigned int phy_id, u32 addr) +static u32 mvs_read_phy_ctl(struct mvs_info *mvi, u32 port) { void __iomem *regs = mvi->regs; - void __iomem *phy_regs = regs + MVS_P0_CFG_ADDR + (phy_id * 8); - - writel(addr, phy_regs); - return readl(phy_regs + 4); + return (port < 4)?mr32(P0_SER_CTLSTAT + port * 4): + mr32(P4_SER_CTLSTAT + (port - 4) * 4); } -#endif -static void mvs_phy_write(struct mvs_info *mvi, unsigned int phy_id, - u32 addr, u32 val) +static void mvs_write_phy_ctl(struct mvs_info *mvi, u32 port, u32 val) { void __iomem *regs = mvi->regs; - void __iomem *phy_regs = regs + MVS_P0_CFG_ADDR + (phy_id * 8); + if (port < 4) + mw32(P0_SER_CTLSTAT + port * 4, val); + else + mw32(P4_SER_CTLSTAT + (port - 4) * 4, val); +} + +static u32 mvs_read_port(struct mvs_info *mvi, u32 off, u32 off2, u32 port) +{ + void __iomem *regs = mvi->regs + off; + void __iomem *regs2 = mvi->regs + off2; + return (port < 4)?readl(regs + port * 8): + readl(regs2 + (port - 4) * 8); +} + +static void mvs_write_port(struct mvs_info *mvi, u32 off, u32 off2, + u32 port, u32 val) +{ + void __iomem *regs = mvi->regs + off; + void __iomem *regs2 = mvi->regs + off2; + if (port < 4) + writel(val, regs + port * 8); + else + writel(val, regs2 + (port - 4) * 8); +} + +static u32 mvs_read_port_cfg_data(struct mvs_info *mvi, u32 port) +{ + return mvs_read_port(mvi, MVS_P0_CFG_DATA, MVS_P4_CFG_DATA, port); +} + +static void mvs_write_port_cfg_data(struct mvs_info *mvi, u32 port, u32 val) +{ + mvs_write_port(mvi, MVS_P0_CFG_DATA, MVS_P4_CFG_DATA, port, val); +} + +static void mvs_write_port_cfg_addr(struct mvs_info *mvi, u32 port, u32 addr) +{ + mvs_write_port(mvi, MVS_P0_CFG_ADDR, MVS_P4_CFG_ADDR, port, addr); +} + +static u32 mvs_read_port_vsr_data(struct mvs_info *mvi, u32 port) +{ + return mvs_read_port(mvi, MVS_P0_VSR_DATA, MVS_P4_VSR_DATA, port); +} + +static void mvs_write_port_vsr_data(struct mvs_info *mvi, u32 port, u32 val) +{ + mvs_write_port(mvi, MVS_P0_VSR_DATA, MVS_P4_VSR_DATA, port, val); +} + +static void mvs_write_port_vsr_addr(struct mvs_info *mvi, u32 port, u32 addr) +{ + mvs_write_port(mvi, MVS_P0_VSR_ADDR, MVS_P4_VSR_ADDR, port, addr); +} + +static u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port) +{ + return mvs_read_port(mvi, MVS_P0_INT_STAT, MVS_P4_INT_STAT, port); +} + +static void mvs_write_port_irq_stat(struct mvs_info *mvi, u32 port, u32 val) +{ + mvs_write_port(mvi, MVS_P0_INT_STAT, MVS_P4_INT_STAT, port, val); +} + +static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port) +{ + return mvs_read_port(mvi, MVS_P0_INT_MASK, MVS_P4_INT_MASK, port); +} - writel(addr, phy_regs); - writel(val, phy_regs + 4); - readl(phy_regs); /* flush */ +static void mvs_write_port_irq_mask(struct mvs_info *mvi, u32 port, u32 val) +{ + mvs_write_port(mvi, MVS_P0_INT_MASK, MVS_P4_INT_MASK, port, val); } static void __devinit mvs_phy_hacks(struct mvs_info *mvi) @@ -1547,6 +2384,260 @@ static void __devinit mvs_phy_hacks(struct mvs_info *mvi) tmp &= 0x1fffffff; tmp |= (2U << 29); /* 8 ms retry */ mvs_cw32(regs, CMD_PHY_TIMER, tmp); + + /* TEST - for phy decoding error, adjust voltage levels */ + mw32(P0_VSR_ADDR + 0, 0x8); + mw32(P0_VSR_DATA + 0, 0x2F0); + + mw32(P0_VSR_ADDR + 8, 0x8); + mw32(P0_VSR_DATA + 8, 0x2F0); + + mw32(P0_VSR_ADDR + 16, 0x8); + mw32(P0_VSR_DATA + 16, 0x2F0); + + mw32(P0_VSR_ADDR + 24, 0x8); + mw32(P0_VSR_DATA + 24, 0x2F0); + +} + +static void mvs_enable_xmt(struct mvs_info *mvi, int PhyId) +{ + void __iomem *regs = mvi->regs; + u32 tmp; + + tmp = mr32(PCS); + if (mvi->chip->n_phy <= 4) + tmp |= 1 << (PhyId + PCS_EN_PORT_XMT_SHIFT); + else + tmp |= 1 << (PhyId + PCS_EN_PORT_XMT_SHIFT2); + mw32(PCS, tmp); +} + +static void mvs_detect_porttype(struct mvs_info *mvi, int i) +{ + void __iomem *regs = mvi->regs; + u32 reg; + struct mvs_phy *phy = &mvi->phy[i]; + + /* TODO check & save device type */ + reg = mr32(GBL_PORT_TYPE); + + if (reg & MODE_SAS_SATA & (1 << i)) + phy->phy_type |= PORT_TYPE_SAS; + else + phy->phy_type |= PORT_TYPE_SATA; +} + +static void *mvs_get_d2h_reg(struct mvs_info *mvi, int i, void *buf) +{ + u32 *s = (u32 *) buf; + + if (!s) + return NULL; + + mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3); + s[3] = mvs_read_port_cfg_data(mvi, i); + + mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2); + s[2] = mvs_read_port_cfg_data(mvi, i); + + mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1); + s[1] = mvs_read_port_cfg_data(mvi, i); + + mvs_write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0); + s[0] = mvs_read_port_cfg_data(mvi, i); + + return (void *)s; +} + +static u32 mvs_is_sig_fis_received(u32 irq_status) +{ + return irq_status & PHYEV_SIG_FIS; +} + +static void mvs_update_wideport(struct mvs_info *mvi, int i) +{ + struct mvs_phy *phy = &mvi->phy[i]; + struct mvs_port *port = phy->port; + int j, no; + + for_each_phy(port->wide_port_phymap, no, j, mvi->chip->n_phy) + if (no & 1) { + mvs_write_port_cfg_addr(mvi, no, PHYR_WIDE_PORT); + mvs_write_port_cfg_data(mvi, no, + port->wide_port_phymap); + } else { + mvs_write_port_cfg_addr(mvi, no, PHYR_WIDE_PORT); + mvs_write_port_cfg_data(mvi, no, 0); + } +} + +static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i) +{ + u32 tmp; + struct mvs_phy *phy = &mvi->phy[i]; + struct mvs_port *port; + + tmp = mvs_read_phy_ctl(mvi, i); + + if ((tmp & PHY_READY_MASK) && !(phy->irq_status & PHYEV_POOF)) { + if (!phy->port) + phy->phy_attached = 1; + return tmp; + } + + port = phy->port; + if (port) { + if (phy->phy_type & PORT_TYPE_SAS) { + port->wide_port_phymap &= ~(1U << i); + if (!port->wide_port_phymap) + port->port_attached = 0; + mvs_update_wideport(mvi, i); + } else if (phy->phy_type & PORT_TYPE_SATA) + port->port_attached = 0; + mvs_free_reg_set(mvi, phy->port); + phy->port = NULL; + phy->phy_attached = 0; + phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA); + } + return 0; +} + +static void mvs_update_phyinfo(struct mvs_info *mvi, int i, + int get_st) +{ + struct mvs_phy *phy = &mvi->phy[i]; + struct pci_dev *pdev = mvi->pdev; + u32 tmp, j; + u64 tmp64; + + mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY); + phy->dev_info = mvs_read_port_cfg_data(mvi, i); + + mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_HI); + phy->dev_sas_addr = (u64) mvs_read_port_cfg_data(mvi, i) << 32; + + mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_LO); + phy->dev_sas_addr |= mvs_read_port_cfg_data(mvi, i); + + if (get_st) { + phy->irq_status = mvs_read_port_irq_stat(mvi, i); + phy->phy_status = mvs_is_phy_ready(mvi, i); + } + + if (phy->phy_status) { + u32 phy_st; + struct asd_sas_phy *sas_phy = mvi->sas.sas_phy[i]; + + mvs_write_port_cfg_addr(mvi, i, PHYR_PHY_STAT); + phy_st = mvs_read_port_cfg_data(mvi, i); + + sas_phy->linkrate = + (phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> + PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET; + + /* Updated attached_sas_addr */ + mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI); + phy->att_dev_sas_addr = + (u64) mvs_read_port_cfg_data(mvi, i) << 32; + + mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO); + phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i); + + dev_printk(KERN_DEBUG, &pdev->dev, + "phy[%d] Get Attached Address 0x%llX ," + " SAS Address 0x%llX\n", + i, phy->att_dev_sas_addr, phy->dev_sas_addr); + dev_printk(KERN_DEBUG, &pdev->dev, + "Rate = %x , type = %d\n", + sas_phy->linkrate, phy->phy_type); + +#if 1 + /* + * If the device is capable of supporting a wide port + * on its phys, it may configure the phys as a wide port. + */ + if (phy->phy_type & PORT_TYPE_SAS) + for (j = 0; j < mvi->chip->n_phy && j != i; ++j) { + if ((mvi->phy[j].phy_attached) && + (mvi->phy[j].phy_type & PORT_TYPE_SAS)) + if (phy->att_dev_sas_addr == + mvi->phy[j].att_dev_sas_addr - 1) { + phy->att_dev_sas_addr = + mvi->phy[j].att_dev_sas_addr; + break; + } + } + +#endif + + tmp64 = cpu_to_be64(phy->att_dev_sas_addr); + memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE); + + if (phy->phy_type & PORT_TYPE_SAS) { + mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_DEV_INFO); + phy->att_dev_info = mvs_read_port_cfg_data(mvi, i); + phy->identify.device_type = + phy->att_dev_info & PORT_DEV_TYPE_MASK; + + if (phy->identify.device_type == SAS_END_DEV) + phy->identify.target_port_protocols = + SAS_PROTOCOL_SSP; + else if (phy->identify.device_type != NO_DEVICE) + phy->identify.target_port_protocols = + SAS_PROTOCOL_SMP; + if (phy_st & PHY_OOB_DTCTD) + sas_phy->oob_mode = SAS_OOB_MODE; + phy->frame_rcvd_size = + sizeof(struct sas_identify_frame); + } else if (phy->phy_type & PORT_TYPE_SATA) { + phy->identify.target_port_protocols = SAS_PROTOCOL_STP; + if (mvs_is_sig_fis_received(phy->irq_status)) { + if (phy_st & PHY_OOB_DTCTD) + sas_phy->oob_mode = SATA_OOB_MODE; + phy->frame_rcvd_size = + sizeof(struct dev_to_host_fis); + mvs_get_d2h_reg(mvi, i, + (void *)sas_phy->frame_rcvd); + } else { + dev_printk(KERN_DEBUG, &pdev->dev, + "No sig fis\n"); + } + } + /* workaround for HW phy decoding error on 1.5g disk drive */ + mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6); + tmp = mvs_read_port_vsr_data(mvi, i); + if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> + PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET) == + SAS_LINK_RATE_1_5_GBPS) + tmp &= ~PHY_MODE6_DTL_SPEED; + else + tmp |= PHY_MODE6_DTL_SPEED; + mvs_write_port_vsr_data(mvi, i, tmp); + + } + if (get_st) + mvs_write_port_irq_stat(mvi, i, phy->irq_status); +} + +static void mvs_port_formed(struct asd_sas_phy *sas_phy) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct mvs_info *mvi = sas_ha->lldd_ha; + struct asd_sas_port *sas_port = sas_phy->port; + struct mvs_phy *phy = sas_phy->lldd_phy; + struct mvs_port *port = &mvi->port[sas_port->id]; + unsigned long flags; + + spin_lock_irqsave(&mvi->lock, flags); + port->port_attached = 1; + phy->port = port; + port->taskfileset = MVS_ID_NOT_MAPPED; + if (phy->phy_type & PORT_TYPE_SAS) { + port->wide_port_phymap = sas_port->phy_mask; + mvs_update_wideport(mvi, sas_phy->id); + } + spin_unlock_irqrestore(&mvi->lock, flags); } static int __devinit mvs_hw_init(struct mvs_info *mvi) @@ -1559,6 +2650,7 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) mw32(GBL_CTL, 0); tmp = mr32(GBL_CTL); + /* Reset Controller */ if (!(tmp & HBA_RST)) { if (mvi->flags & MVF_PHY_PWR_FIX) { pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp); @@ -1576,7 +2668,6 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) mw32_f(GBL_CTL, HBA_RST); } - /* wait for reset to finish; timeout is just a guess */ i = 1000; while (i-- > 0) { @@ -1590,6 +2681,7 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) return -EBUSY; } + /* Init Chip */ /* make sure RST is set; HBA_RST /should/ have done that for us */ cctl = mr32(CTL); if (cctl & CCTL_RST) @@ -1597,6 +2689,12 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) else mw32_f(CTL, cctl | CCTL_RST); + /* write to device control _AND_ device status register? - A.C. */ + pci_read_config_dword(mvi->pdev, PCR_DEV_CTRL, &tmp); + tmp &= ~PRD_REQ_MASK; + tmp |= PRD_REQ_SIZE; + pci_write_config_dword(mvi->pdev, PCR_DEV_CTRL, tmp); + pci_read_config_dword(mvi->pdev, PCR_PHY_CTL, &tmp); tmp |= PCTL_PWR_ON; tmp &= ~PCTL_OFF; @@ -1609,6 +2707,9 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) mw32_f(CTL, cctl); + /* reset control */ + mw32(PCS, 0); /*MVS_PCS */ + mvs_phy_hacks(mvi); mw32(CMD_LIST_LO, mvi->slot_dma); @@ -1617,7 +2718,7 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) mw32(RX_FIS_LO, mvi->rx_fis_dma); mw32(RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16); - mw32(TX_CFG, MVS_TX_RING_SZ); + mw32(TX_CFG, MVS_CHIP_SLOT_SZ); mw32(TX_LO, mvi->tx_dma); mw32(TX_HI, (mvi->tx_dma >> 16) >> 16); @@ -1625,44 +2726,88 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) mw32(RX_LO, mvi->rx_dma); mw32(RX_HI, (mvi->rx_dma >> 16) >> 16); + /* enable auto port detection */ + mw32(GBL_PORT_TYPE, MODE_AUTO_DET_EN); + msleep(100); /* init and reset phys */ for (i = 0; i < mvi->chip->n_phy; i++) { /* FIXME: is this the correct dword order? */ - u32 lo = *((u32 *) &mvi->sas_addr[0]); - u32 hi = *((u32 *) &mvi->sas_addr[4]); + u32 lo = *((u32 *)&mvi->sas_addr[0]); + u32 hi = *((u32 *)&mvi->sas_addr[4]); + + mvs_detect_porttype(mvi, i); /* set phy local SAS address */ - mvs_phy_write(mvi, i, PHYR_ADDR_LO, lo); - mvs_phy_write(mvi, i, PHYR_ADDR_HI, hi); + mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_LO); + mvs_write_port_cfg_data(mvi, i, lo); + mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_HI); + mvs_write_port_cfg_data(mvi, i, hi); /* reset phy */ - tmp = readl(regs + MVS_P0_SER_CTLSTAT + (i * 4)); + tmp = mvs_read_phy_ctl(mvi, i); tmp |= PHY_RST; - writel(tmp, regs + MVS_P0_SER_CTLSTAT + (i * 4)); + mvs_write_phy_ctl(mvi, i, tmp); } msleep(100); for (i = 0; i < mvi->chip->n_phy; i++) { + /* clear phy int status */ + tmp = mvs_read_port_irq_stat(mvi, i); + tmp &= ~PHYEV_SIG_FIS; + mvs_write_port_irq_stat(mvi, i, tmp); + /* set phy int mask */ - writel(PHYEV_BROAD_CH | PHYEV_RDY_CH, - regs + MVS_P0_INT_MASK + (i * 8)); + tmp = PHYEV_RDY_CH | PHYEV_BROAD_CH | PHYEV_UNASSOC_FIS | + PHYEV_ID_DONE | PHYEV_DEC_ERR; + mvs_write_port_irq_mask(mvi, i, tmp); - /* clear phy int status */ - tmp = readl(regs + MVS_P0_INT_STAT + (i * 8)); - writel(tmp, regs + MVS_P0_INT_STAT + (i * 8)); + msleep(100); + mvs_update_phyinfo(mvi, i, 1); + mvs_enable_xmt(mvi, i); } /* FIXME: update wide port bitmaps */ + /* little endian for open address and command table, etc. */ + /* A.C. + * it seems that ( from the spec ) turning on big-endian won't + * do us any good on big-endian machines, need further confirmation + */ + cctl = mr32(CTL); + cctl |= CCTL_ENDIAN_CMD; + cctl |= CCTL_ENDIAN_DATA; + cctl &= ~CCTL_ENDIAN_OPEN; + cctl |= CCTL_ENDIAN_RSP; + mw32_f(CTL, cctl); + + /* reset CMD queue */ + tmp = mr32(PCS); + tmp |= PCS_CMD_RST; + mw32(PCS, tmp); + /* interrupt coalescing may cause missing HW interrput in some case, + * and the max count is 0x1ff, while our max slot is 0x200, + * it will make count 0. + */ + tmp = 0; + mw32(INT_COAL, tmp); + + tmp = 0x100; + mw32(INT_COAL_TMOUT, tmp); + /* ladies and gentlemen, start your engines */ - mw32(TX_CFG, MVS_TX_RING_SZ | TX_EN); + mw32(TX_CFG, 0); + mw32(TX_CFG, MVS_CHIP_SLOT_SZ | TX_EN); mw32(RX_CFG, MVS_RX_RING_SZ | RX_EN); - mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN | - ((mvi->flags & MVF_MSI) ? PCS_SELF_CLEAR : 0)); + /* enable CMD/CMPL_Q/RESP mode */ + mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN); /* re-enable interrupts globally */ - mw32(GBL_CTL, INT_EN); + mvs_hba_interrupt_enable(mvi); + + /* enable completion queue interrupt */ + tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM); + mw32(INT_MASK, tmp); return 0; } @@ -1680,7 +2825,7 @@ static void __devinit mvs_print_info(struct mvs_info *mvi) } static int __devinit mvs_pci_init(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { int rc; struct mvs_info *mvi; @@ -1710,10 +2855,16 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, if (rc) goto err_out_mvi; +#ifndef MVS_DISABLE_MSI if (!pci_enable_msi(pdev)) { + u32 tmp; + void __iomem *regs = mvi->regs; mvi->flags |= MVF_MSI; irq_handler = mvs_msi_interrupt; + tmp = mr32(PCS); + mw32(PCS, tmp | PCS_SELF_CLEAR); } +#endif rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME, mvi); if (rc) @@ -1732,6 +2883,7 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, mvs_print_info(mvi); scsi_scan_host(mvi->shost); + return 0; err_out_shost: @@ -1756,21 +2908,26 @@ static void __devexit mvs_pci_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); - sas_unregister_ha(&mvi->sas); - sas_remove_host(mvi->shost); - scsi_remove_host(mvi->shost); - - free_irq(pdev->irq, mvi); - if (mvi->flags & MVF_MSI) - pci_disable_msi(pdev); - mvs_free(mvi); - pci_release_regions(pdev); + if (mvi) { + sas_unregister_ha(&mvi->sas); + mvs_hba_interrupt_disable(mvi); + sas_remove_host(mvi->shost); + scsi_remove_host(mvi->shost); + + free_irq(pdev->irq, mvi); + if (mvi->flags & MVF_MSI) + pci_disable_msi(pdev); + mvs_free(mvi); + pci_release_regions(pdev); + } pci_disable_device(pdev); } static struct sas_domain_function_template mvs_transport_ops = { .lldd_execute_task = mvs_task_exec, .lldd_control_phy = mvs_phy_control, + .lldd_abort_task = mvs_task_abort, + .lldd_port_formed = mvs_port_formed }; static struct pci_device_id __devinitdata mvs_pci_table[] = { @@ -1822,4 +2979,3 @@ MODULE_DESCRIPTION("Marvell 88SE6440 SAS/SATA controller driver"); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, mvs_pci_table); - From cfb37ae1e9d31fe2c1d21734ab51405e0c3afb7e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 30 Jan 2008 22:03:36 +0200 Subject: [PATCH 590/880] [SCSI] qlogicpt: section fixes In current mainline, __devinit qpti_sbus_probe() still is calling __init qpti_chain_add(). Change occurrences of __init to __devinit to fix. Signed-off-by: Adrian Bunk Signed-off-by: James Bottomley --- drivers/scsi/qlogicpti.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 65455ab1f3b9..4a1cf6377f6c 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -651,7 +651,7 @@ static int qlogicpti_verify_tmon(struct qlogicpti *qpti) static irqreturn_t qpti_intr(int irq, void *dev_id); -static void __init qpti_chain_add(struct qlogicpti *qpti) +static void __devinit qpti_chain_add(struct qlogicpti *qpti) { spin_lock_irq(&qptichain_lock); if (qptichain != NULL) { @@ -667,7 +667,7 @@ static void __init qpti_chain_add(struct qlogicpti *qpti) spin_unlock_irq(&qptichain_lock); } -static void __init qpti_chain_del(struct qlogicpti *qpti) +static void __devexit qpti_chain_del(struct qlogicpti *qpti) { spin_lock_irq(&qptichain_lock); if (qptichain == qpti) { @@ -682,7 +682,7 @@ static void __init qpti_chain_del(struct qlogicpti *qpti) spin_unlock_irq(&qptichain_lock); } -static int __init qpti_map_regs(struct qlogicpti *qpti) +static int __devinit qpti_map_regs(struct qlogicpti *qpti) { struct sbus_dev *sdev = qpti->sdev; @@ -705,7 +705,7 @@ static int __init qpti_map_regs(struct qlogicpti *qpti) return 0; } -static int __init qpti_register_irq(struct qlogicpti *qpti) +static int __devinit qpti_register_irq(struct qlogicpti *qpti) { struct sbus_dev *sdev = qpti->sdev; @@ -730,7 +730,7 @@ static int __init qpti_register_irq(struct qlogicpti *qpti) return -1; } -static void __init qpti_get_scsi_id(struct qlogicpti *qpti) +static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti) { qpti->scsi_id = prom_getintdefault(qpti->prom_node, "initiator-id", @@ -783,7 +783,7 @@ static void qpti_get_clock(struct qlogicpti *qpti) /* The request and response queues must each be aligned * on a page boundary. */ -static int __init qpti_map_queues(struct qlogicpti *qpti) +static int __devinit qpti_map_queues(struct qlogicpti *qpti) { struct sbus_dev *sdev = qpti->sdev; From 3a2d5b700132f35401f1d9e22fe3c2cab02c2549 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 23 Feb 2008 19:13:25 +0100 Subject: [PATCH 591/880] PM: Introduce PM_EVENT_HIBERNATE callback state During the last step of hibernation in the "platform" mode (with the help of ACPI) we use the suspend code, including the devices' ->suspend() methods, to prepare the system for entering the ACPI S4 system sleep state. But at least for some devices the operations performed by the ->suspend() callback in that case must be different from its operations during regular suspend. For this reason, introduce the new PM event type PM_EVENT_HIBERNATE and pass it to the device drivers' ->suspend() methods during the last phase of hibernation, so that they can distinguish this case and handle it as appropriate. Modify the drivers that handle PM_EVENT_SUSPEND in a special way and need to handle PM_EVENT_HIBERNATE in the same way. These changes are necessary to fix a hibernation regression related to the i915 driver (ref. http://lkml.org/lkml/2008/2/22/488). Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Tested-by: Jeff Chua Signed-off-by: Linus Torvalds --- Documentation/power/devices.txt | 13 ++++++++----- drivers/ata/ahci.c | 2 +- drivers/ata/ata_piix.c | 2 +- drivers/ata/libata-core.c | 2 +- drivers/ide/ppc/pmac.c | 4 ++-- drivers/macintosh/mediabay.c | 3 ++- drivers/pci/pci.c | 1 + drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 2 +- drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 2 +- drivers/scsi/mesh.c | 1 + drivers/scsi/sd.c | 3 +-- drivers/usb/host/sl811-hcd.c | 1 + drivers/usb/host/u132-hcd.c | 11 ++++++++--- drivers/video/chipsfb.c | 2 +- drivers/video/nvidia/nvidia.c | 2 +- include/linux/pm.h | 9 ++++++++- kernel/power/disk.c | 4 ++-- net/rfkill/rfkill.c | 2 +- 18 files changed, 42 insertions(+), 24 deletions(-) diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index c53d26361919..461e4f1dbec4 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -310,9 +310,12 @@ used with suspend-to-disk: PM_EVENT_SUSPEND -- quiesce the driver and put hardware into a low-power state. When used with system sleep states like "suspend-to-RAM" or "standby", the upcoming resume() call will often be able to rely on - state kept in hardware, or issue system wakeup events. When used - instead with suspend-to-disk, few devices support this capability; - most are completely powered off. + state kept in hardware, or issue system wakeup events. + + PM_EVENT_HIBERNATE -- Put hardware into a low-power state and enable wakeup + events as appropriate. It is only used with hibernation + (suspend-to-disk) and few devices are able to wake up the system from + this state; most are completely powered off. PM_EVENT_FREEZE -- quiesce the driver, but don't necessarily change into any low power mode. A system snapshot is about to be taken, often @@ -329,8 +332,8 @@ used with suspend-to-disk: wakeup events nor DMA are allowed. To enter "standby" (ACPI S1) or "Suspend to RAM" (STR, ACPI S3) states, or -the similarly named APM states, only PM_EVENT_SUSPEND is used; for "Suspend -to Disk" (STD, hibernate, ACPI S4), all of those event codes are used. +the similarly named APM states, only PM_EVENT_SUSPEND is used; the other event +codes are used for hibernation ("Suspend to Disk", STD, ACPI S4). There's also PM_EVENT_ON, a value which never appears as a suspend event but is sometimes used to record the "not suspended" device state. diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 3c06e457b4dc..6dd12f7019a0 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1932,7 +1932,7 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; u32 ctl; - if (mesg.event == PM_EVENT_SUSPEND) { + if (mesg.event & PM_EVENT_SLEEP) { /* AHCI spec rev1.1 section 8.3.3: * Software must disable interrupts prior to requesting a * transition of the HBA to D3 state. diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 752e7d2f3b2f..fae8404254c0 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1339,7 +1339,7 @@ static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) * cycles and power trying to do something to the sleeping * beauty. */ - if (piix_broken_suspend() && mesg.event == PM_EVENT_SUSPEND) { + if (piix_broken_suspend() && (mesg.event & PM_EVENT_SLEEP)) { pci_save_state(pdev); /* mark its power state as "unknown", since we don't diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 60d1bb556973..4cf8662df99e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -7368,7 +7368,7 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) pci_save_state(pdev); pci_disable_device(pdev); - if (mesg.event == PM_EVENT_SUSPEND) + if (mesg.event & PM_EVENT_SLEEP) pci_set_power_state(pdev, PCI_D3hot); } diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 12ac3bfb4f9a..78c9eeb85634 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1254,7 +1254,7 @@ pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg) int rc = 0; if (mesg.event != mdev->ofdev.dev.power.power_state.event - && mesg.event == PM_EVENT_SUSPEND) { + && (mesg.event & PM_EVENT_SLEEP)) { rc = pmac_ide_do_suspend(hwif); if (rc == 0) mdev->ofdev.dev.power.power_state = mesg; @@ -1364,7 +1364,7 @@ pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) int rc = 0; if (mesg.event != pdev->dev.power.power_state.event - && mesg.event == PM_EVENT_SUSPEND) { + && (mesg.event & PM_EVENT_SLEEP)) { rc = pmac_ide_do_suspend(hwif); if (rc == 0) pdev->dev.power.power_state = mesg; diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 51a112815f46..bd8a1d14b45d 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -698,7 +698,8 @@ static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state) { struct media_bay_info *bay = macio_get_drvdata(mdev); - if (state.event != mdev->ofdev.dev.power.power_state.event && state.event == PM_EVENT_SUSPEND) { + if (state.event != mdev->ofdev.dev.power.power_state.event + && (state.event & PM_EVENT_SLEEP)) { down(&bay->lock); bay->sleeping = 1; set_mb_power(bay, 0); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ae3df46eaabf..183fddaa38b7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -554,6 +554,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) case PM_EVENT_PRETHAW: /* REVISIT both freeze and pre-thaw "should" use D0 */ case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: return PCI_D3hot; default: printk("Unrecognized suspend event %d\n", state.event); diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 4150c8a8fdc2..dfaaae5e73ae 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c @@ -89,7 +89,7 @@ ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) pci_save_state(pdev); pci_disable_device(pdev); - if (mesg.event == PM_EVENT_SUSPEND) + if (mesg.event & PM_EVENT_SLEEP) pci_set_power_state(pdev, PCI_D3hot); return rc; diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index dd6e21d6f1dd..3d3eaef65fb3 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -134,7 +134,7 @@ ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) pci_save_state(pdev); pci_disable_device(pdev); - if (mesg.event == PM_EVENT_SUSPEND) + if (mesg.event & PM_EVENT_SLEEP) pci_set_power_state(pdev, PCI_D3hot); return rc; diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index 651d09b08f2a..fd63b06d9ef1 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1759,6 +1759,7 @@ static int mesh_suspend(struct macio_dev *mdev, pm_message_t mesg) switch (mesg.event) { case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: case PM_EVENT_FREEZE: break; default: diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 37df8bbe7f46..7aee64dbfbeb 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1835,8 +1835,7 @@ static int sd_suspend(struct device *dev, pm_message_t mesg) goto done; } - if (mesg.event == PM_EVENT_SUSPEND && - sdkp->device->manage_start_stop) { + if ((mesg.event & PM_EVENT_SLEEP) && sdkp->device->manage_start_stop) { sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); ret = sd_start_stop_device(sdkp, 0); } diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index ba370c56172c..59be276ccd9d 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1766,6 +1766,7 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state) retval = sl811h_bus_suspend(hcd); break; case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: case PM_EVENT_PRETHAW: /* explicitly discard hw state */ port_power(sl811, 0); break; diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index ac283b09a63f..6fca06961559 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3214,14 +3214,19 @@ static int u132_suspend(struct platform_device *pdev, pm_message_t state) return -ESHUTDOWN; } else { int retval = 0; - if (state.event == PM_EVENT_FREEZE) { + + switch (state.event) { + case PM_EVENT_FREEZE: retval = u132_bus_suspend(hcd); - } else if (state.event == PM_EVENT_SUSPEND) { + break; + case PM_EVENT_SUSPEND: + case PM_EVENT_HIBERNATE: int ports = MAX_U132_PORTS; while (ports-- > 0) { port_power(u132, ports, 0); } - } + break; + } if (retval == 0) pdev->dev.power.power_state = state; return retval; diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index 6796ba62c3c6..777389c40988 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -459,7 +459,7 @@ static int chipsfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) if (state.event == pdev->dev.power.power_state.event) return 0; - if (state.event != PM_EVENT_SUSPEND) + if (!(state.event & PM_EVENT_SLEEP)) goto done; acquire_console_sem(); diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 74517b1b26a6..596652d2831f 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -1066,7 +1066,7 @@ static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg) acquire_console_sem(); par->pm_state = mesg.event; - if (mesg.event == PM_EVENT_SUSPEND) { + if (mesg.event & PM_EVENT_SLEEP) { fb_set_suspend(info, 1); nvidiafb_blank(FB_BLANK_POWERDOWN, info); nvidia_write_regs(par, &par->SavedReg); diff --git a/include/linux/pm.h b/include/linux/pm.h index eccf59ea2a77..015b735811b4 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -143,6 +143,9 @@ typedef struct pm_message { * the upcoming system state (such as PCI_D3hot), and enable * wakeup events as appropriate. * + * HIBERNATE Enter a low power device state appropriate for the hibernation + * state (eg. ACPI S4) and enable wakeup events as appropriate. + * * FREEZE Quiesce operations so that a consistent image can be saved; * but do NOT otherwise enter a low power device state, and do * NOT emit system wakeup events. @@ -166,11 +169,15 @@ typedef struct pm_message { #define PM_EVENT_ON 0 #define PM_EVENT_FREEZE 1 #define PM_EVENT_SUSPEND 2 -#define PM_EVENT_PRETHAW 3 +#define PM_EVENT_HIBERNATE 4 +#define PM_EVENT_PRETHAW 8 + +#define PM_EVENT_SLEEP (PM_EVENT_SUSPEND | PM_EVENT_HIBERNATE) #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) #define PMSG_PRETHAW ((struct pm_message){ .event = PM_EVENT_PRETHAW, }) #define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, }) +#define PMSG_HIBERNATE ((struct pm_message){ .event = PM_EVENT_HIBERNATE, }) #define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) struct dev_pm_info { diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 859a8e59773a..14a656cdc652 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -391,7 +391,7 @@ int hibernation_platform_enter(void) goto Close; suspend_console(); - error = device_suspend(PMSG_SUSPEND); + error = device_suspend(PMSG_HIBERNATE); if (error) goto Resume_console; @@ -404,7 +404,7 @@ int hibernation_platform_enter(void) goto Finish; local_irq_disable(); - error = device_power_down(PMSG_SUSPEND); + error = device_power_down(PMSG_HIBERNATE); if (!error) { hibernation_ops->enter(); /* We should never get here */ diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 1a47f5d1be17..140a0a8c6b02 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -232,7 +232,7 @@ static int rfkill_suspend(struct device *dev, pm_message_t state) struct rfkill *rfkill = to_rfkill(dev); if (dev->power.power_state.event != state.event) { - if (state.event == PM_EVENT_SUSPEND) { + if (state.event & PM_EVENT_SLEEP) { mutex_lock(&rfkill->mutex); if (rfkill->state == RFKILL_STATE_ON) From 1e8352784abaedb424e63fa700e93e6c1307785f Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sat, 23 Feb 2008 19:40:17 +0000 Subject: [PATCH 592/880] percpu: fix DEBUG_PREEMPT per_cpu checking 2.6.25-rc1 percpu changes broke CONFIG_DEBUG_PREEMPT's per_cpu checking on several architectures. On s390, sparc64 and x86 it's been weakened to not checking at all; whereas on powerpc64 it's become too strict, issuing warnings from __raw_get_cpu_var in io_schedule and init_timer for example. Fix this by weakening powerpc's __my_cpu_offset to use the non-checking local_paca instead of get_paca (which itself contains such a check); and strengthening the generic my_cpu_offset to go the old slow way via smp_processor_id when CONFIG_DEBUG_PREEMPT (debug_smp_processor_id is where all the knowledge of what's correct when lives). Signed-off-by: Hugh Dickins Reviewed-by: Mike Travis Signed-off-by: Linus Torvalds --- include/asm-generic/percpu.h | 2 ++ include/asm-powerpc/percpu.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 4b8d31cda1a0..b0e63c672ebd 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -32,6 +32,8 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; */ #ifndef __my_cpu_offset #define __my_cpu_offset per_cpu_offset(raw_smp_processor_id()) +#endif +#ifdef CONFIG_DEBUG_PREEMPT #define my_cpu_offset per_cpu_offset(smp_processor_id()) #else #define my_cpu_offset __my_cpu_offset diff --git a/include/asm-powerpc/percpu.h b/include/asm-powerpc/percpu.h index ccb0523eb3b4..f879252b7ea6 100644 --- a/include/asm-powerpc/percpu.h +++ b/include/asm-powerpc/percpu.h @@ -13,7 +13,7 @@ #include #define __per_cpu_offset(cpu) (paca[cpu].data_offset) -#define __my_cpu_offset get_paca()->data_offset +#define __my_cpu_offset local_paca->data_offset #define per_cpu_offset(x) (__per_cpu_offset(x)) #endif /* CONFIG_SMP */ From 4631a9a1517654748aaf89cbc46503819a29eb30 Mon Sep 17 00:00:00 2001 From: Johann Felix Soden Date: Sat, 23 Feb 2008 15:23:23 -0800 Subject: [PATCH 593/880] uml: fix initrd printk If the initrd file has zero-length, the error message should contain the filepath. Cc: WANG Cong Signed-off-by: Johann Felix Soden Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/initrd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index fa015565001b..d386c75c88eb 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -32,7 +32,7 @@ static int __init read_initrd(void) * ask for no memory. */ if (size == 0) { - printk(KERN_ERR "\"%\" is a zero-size initrd\n"); + printk(KERN_ERR "\"%s\" is a zero-size initrd\n", initrd); return 0; } From 7b59ebcd178b5b1d03760c89b318c7a7fdadd051 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sat, 23 Feb 2008 15:23:24 -0800 Subject: [PATCH 594/880] UML: update defconfig Update defconfig. Cc: Christoph Hellwig Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/defconfig | 280 +++++++++++++++++++++++++++++++--------------- 1 file changed, 187 insertions(+), 93 deletions(-) diff --git a/arch/um/defconfig b/arch/um/defconfig index 59215bc264ef..6bd456f96f90 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -1,13 +1,22 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc3 -# Fri Apr 28 09:31:20 2006 +# Linux kernel version: 2.6.24 +# Thu Feb 7 11:48:55 2008 # +CONFIG_DEFCONFIG_LIST="arch/$ARCH/defconfig" CONFIG_GENERIC_HARDIRQS=y CONFIG_UML=y CONFIG_MMU=y +CONFIG_NO_IOMEM=y +# CONFIG_TRACE_IRQFLAGS_SUPPORT is not set +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_STACKTRACE_SUPPORT is not set CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_IRQ_RELEASE_METHOD=y +CONFIG_HZ=100 # # UML-specific options @@ -40,11 +49,13 @@ CONFIG_M686=y # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set # CONFIG_MVIAC7 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_GENERIC_CPU is not set # CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y CONFIG_X86_L1_CACHE_SHIFT=5 -CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_X86_XADD=y CONFIG_X86_PPRO_FENCE=y CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y @@ -53,7 +64,12 @@ CONFIG_X86_POPAD_OK=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_DEBUGCTLMSR=y CONFIG_UML_X86=y +CONFIG_X86_32=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_64BIT is not set CONFIG_SEMAPHORE_SLEEPERS=y # CONFIG_3_LEVEL_PGTABLES is not set @@ -67,13 +83,18 @@ 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=0 +CONFIG_VIRT_TO_BUS=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_LD_SCRIPT_DYN=y -CONFIG_NET=y CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_MISC=m CONFIG_HOSTFS=y # CONFIG_HPPFS is not set @@ -83,31 +104,38 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_KERNEL_STACK_ORDER=0 # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# +CONFIG_INIT_ENV_ARG_LIMIT=128 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_SYSCTL=y +# 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_INITRAMFS_SOURCE="" -CONFIG_UID16=y +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set CONFIG_KALLSYMS_EXTRA_PASS=y @@ -117,29 +145,36 @@ 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_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=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 is not set +# CONFIG_HAVE_KPROBES is not set +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_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 @@ -153,19 +188,16 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Block devices -# +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set +CONFIG_BLK_DEV=y CONFIG_BLK_DEV_UBD=y # CONFIG_BLK_DEV_UBD_SYNC is not set CONFIG_BLK_DEV_COW_COMMON=y -# CONFIG_MMAPPER is not set CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_CRYPTOLOOP is not set CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_ATA_OVER_ETH is not set # @@ -185,32 +217,43 @@ CONFIG_CON_CHAN="xterm" CONFIG_SSL_CHAN="pts" CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y +# CONFIG_RAW_DRIVER is not set CONFIG_LEGACY_PTY_COUNT=32 # CONFIG_WATCHDOG is not set CONFIG_UML_SOUND=m CONFIG_SOUND=m CONFIG_HOSTAUDIO=m +# CONFIG_HW_RANDOM is not set CONFIG_UML_RANDOM=y +# CONFIG_MMAPPER is not set # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set # # Networking # +CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y 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 @@ -226,28 +269,23 @@ CONFIG_IP_FIB_HASH=y # 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_BIC=y +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_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 @@ -258,13 +296,8 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT 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 # @@ -272,9 +305,20 @@ CONFIG_TCP_CONG_BIC=y # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN 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 # # UML Network Devices @@ -284,31 +328,24 @@ CONFIG_UML_NET_ETHERTAP=y CONFIG_UML_NET_TUNTAP=y CONFIG_UML_NET_SLIP=y CONFIG_UML_NET_DAEMON=y +# CONFIG_UML_NET_VDE is not set CONFIG_UML_NET_MCAST=y # CONFIG_UML_NET_PCAP is not set CONFIG_UML_NET_SLIRP=y - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set CONFIG_DUMMY=m # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=m +# CONFIG_VETH is not set # -# PHY device support -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set @@ -319,18 +356,15 @@ CONFIG_PPP=m # CONFIG_PPP_BSDCOMP is not set # CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set +# CONFIG_PPPOL2TP is not set CONFIG_SLIP=m # CONFIG_SLIP_COMPRESSED is not set +CONFIG_SLHC=m # CONFIG_SLIP_SMART is not set # CONFIG_SLIP_MODE_SLIP6 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 - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set # @@ -341,8 +375,8 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set @@ -350,11 +384,15 @@ CONFIG_REISERFS_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_INOTIFY=y +CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y # CONFIG_QFMT_V1 is not set # CONFIG_QFMT_V2 is not set CONFIG_QUOTACTL=y @@ -383,10 +421,11 @@ CONFIG_JOLIET=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y 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 # @@ -405,10 +444,7 @@ CONFIG_RAMFS=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 is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set @@ -416,17 +452,12 @@ CONFIG_RAMFS=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 # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -467,33 +498,83 @@ 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 +# CONFIG_DLM is not set # # Security options # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_MANAGER is not set +# 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 is not set +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD 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_TWOFISH_586 is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_AES_586 is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SALSA20_586 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_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y # # Library routines # +CONFIG_BITREVERSE=m # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=m +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_DMA=y # -# Multi-device support (RAID and LVM) +# 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_MD is not set # CONFIG_INPUT is not set @@ -501,23 +582,36 @@ CONFIG_CRC32=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SLAB_LEAK is not set -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y +# CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set # CONFIG_GPROF is not set # CONFIG_GCOV is not set # CONFIG_DEBUG_STACK_USAGE is not set From c3be10f75757e681b34766b24264c83b5ba08041 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Sat, 23 Feb 2008 15:23:26 -0800 Subject: [PATCH 595/880] arch/um/kernel/mem.c: fix a shadowed variable Fix a shadowed variable in arch/um/kernel/mem.c, since there is a global variable has the same name. Cc: Jeff Dike Signed-off-by: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/mem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 2627ce82e918..2eea1ff235e6 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -299,7 +299,7 @@ void show_mem(void) { int pfn, total = 0, reserved = 0; int shared = 0, cached = 0; - int highmem = 0; + int high_mem = 0; struct page *page; printk(KERN_INFO "Mem-info:\n"); @@ -311,7 +311,7 @@ void show_mem(void) page = pfn_to_page(pfn); total++; if (PageHighMem(page)) - highmem++; + high_mem++; if (PageReserved(page)) reserved++; else if (PageSwapCache(page)) @@ -320,7 +320,7 @@ void show_mem(void) shared += page_count(page) - 1; } printk(KERN_INFO "%d pages of RAM\n", total); - printk(KERN_INFO "%d pages of HIGHMEM\n", highmem); + 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); From fddd9cf82c9f9617d134ae878a8f6b116ebbd43d Mon Sep 17 00:00:00 2001 From: Chris Snook Date: Sat, 23 Feb 2008 15:23:26 -0800 Subject: [PATCH 596/880] make LKDTM depend on BLOCK Make LKDTM depend on BLOCK to prevent build failures with certain configs. Signed-off-by: Chris Snook Acked-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ab408aa9b6d6..0796c1a090c0 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -527,6 +527,7 @@ config LKDTM tristate "Linux Kernel Dump Test Tool Module" depends on DEBUG_KERNEL depends on KPROBES + depends on BLOCK default n help This module enables testing of the different dumping mechanisms by From 1a823ac9ff09cbdf39201df37b7ede1f9395de83 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Sat, 23 Feb 2008 15:23:27 -0800 Subject: [PATCH 597/880] fuse: fix permission checking I added a nasty local variable shadowing bug to fuse in 2.6.24, with the result, that the 'default_permissions' mount option is basically ignored. How did this happen? - old err declaration in inner scope - new err getting declared in outer scope - 'return err' from inner scope getting removed - old declaration not being noticed -Wshadow would have saved us, but it doesn't seem practical for the kernel :( More testing would have also saved us :(( Signed-off-by: Miklos Szeredi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 7fb514b6d852..c4807b3fc8a3 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -906,7 +906,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) } if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { - int err = generic_permission(inode, mask, NULL); + err = generic_permission(inode, mask, NULL); /* If permission is denied, try to refresh file attributes. This is also needed, because the root From 860f7be283f8b8d7830a741cb72338057a753283 Mon Sep 17 00:00:00 2001 From: David Howells Date: Sat, 23 Feb 2008 15:23:28 -0800 Subject: [PATCH 598/880] MN10300: define HZ as a config option Define HZ as a config option. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mn10300/Kconfig | 4 ++++ include/asm-mn10300/param.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index eedc3a5e0d9b..6a6409adc564 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -63,6 +63,10 @@ config GENERIC_HARDIRQS config HOTPLUG_CPU def_bool n +config HZ + int + default 1000 + mainmenu "Matsushita MN10300/AM33 Kernel Configuration" source "init/Kconfig" diff --git a/include/asm-mn10300/param.h b/include/asm-mn10300/param.h index 54b883ec3906..789b1df41fcb 100644 --- a/include/asm-mn10300/param.h +++ b/include/asm-mn10300/param.h @@ -12,7 +12,7 @@ #define _ASM_PARAM_H #ifdef __KERNEL__ -#define HZ 1000 /* Internal kernel timer frequency */ +#define HZ CONFIG_HZ /* Internal kernel timer frequency */ #define USER_HZ 100 /* .. some user interfaces are in * "ticks" */ #define CLOCKS_PER_SEC (USER_HZ) /* like times() */ From 55a26aeec07f8fdb0f7027a605a430338eb78f4e Mon Sep 17 00:00:00 2001 From: David Howells Date: Sat, 23 Feb 2008 15:23:28 -0800 Subject: [PATCH 599/880] MN10300: define SO_MARK Define SO_MARK for MN10300. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-mn10300/socket.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-mn10300/socket.h b/include/asm-mn10300/socket.h index 99ca648b94c5..80af9c4ccad7 100644 --- a/include/asm-mn10300/socket.h +++ b/include/asm-mn10300/socket.h @@ -52,4 +52,6 @@ #define SO_TIMESTAMPNS 35 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS +#define SO_MARK 36 + #endif /* _ASM_SOCKET_H */ From f81e8a43871f44f98dd14e83a83bf9ca0b3b46c5 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Sat, 23 Feb 2008 15:23:29 -0800 Subject: [PATCH 600/880] ufs: fix parenthesisation in ufs_set_fs_state() This bug snuck in with commit 252e211e90ce56bf005cb533ad5a297c18c19407 Author: Mark Fortescue Date: Tue Oct 16 23:26:31 2007 -0700 Add in SunOS 4.1.x compatible mode for UFS Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Acked-by: Evgeniy Dushistov Cc: Mark Fortescue Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ufs/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ufs/util.h b/fs/ufs/util.h index b26fc4dec1e7..23ceed8c8fb9 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h @@ -58,7 +58,7 @@ ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, { switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { case UFS_ST_SUNOS: - if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) { + if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) { usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value); break; } From 8936b6dba234c994dc4c168818376197abc2faac Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 23 Feb 2008 15:23:30 -0800 Subject: [PATCH 601/880] MAINTAINERS: linux-fbdev is moderated While linux-fbdev is subscribers-only, non-subscribers are not plainly rejected, but moderated, so the casual patch/comment/question comes through. Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f71f66584ed3..25af17830522 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -697,7 +697,7 @@ S: Supported ATMEL LCDFB DRIVER P: Nicolas Ferre M: nicolas.ferre@atmel.com -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained ATMEL MACB ETHERNET DRIVER @@ -1202,7 +1202,7 @@ S: Maintained CYBLAFB FRAMEBUFFER DRIVER P: Knut Petersen M: Knut_Petersen@t-online.de -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained CYCLADES 2X SYNC CARD DRIVER @@ -1579,7 +1579,7 @@ S: Supported FRAMEBUFFER LAYER P: Antonino Daplas M: adaplas@gmail.com -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) W: http://linux-fbdev.sourceforge.net/ S: Maintained @@ -1964,7 +1964,7 @@ L: linux1394-devel@lists.sourceforge.net S: Maintained IMS TWINTURBO FRAMEBUFFER DRIVER -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Orphan INFINIBAND SUBSYSTEM @@ -1998,13 +1998,13 @@ S: Maintained INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) P: Sylvain Meyer M: sylvain.meyer@worldonline.fr -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained INTEL 810/815 FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@gmail.com -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained INTEL IA32 MICROCODE UPDATE SUPPORT @@ -2600,7 +2600,7 @@ S: Odd Fixes for 2.4; Maintained for 2.6. MATROX FRAMEBUFFER DRIVER P: Petr Vandrovec M: vandrove@vc.cvut.cz -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER @@ -2909,7 +2909,7 @@ S: Maintained NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@gmail.com -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained OPENCORES I2C BUS DRIVER @@ -3238,13 +3238,13 @@ S: Maintained RADEON FRAMEBUFFER DISPLAY DRIVER P: Benjamin Herrenschmidt M: benh@kernel.crashing.org -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained RAGE128 FRAMEBUFFER DISPLAY DRIVER P: Paul Mackerras M: paulus@samba.org -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER @@ -3349,7 +3349,7 @@ S: Maintained S3 SAVAGE FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@gmail.com -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained S390 From 745329c4a2a25efbf5ba6cd7842e07840e4e9775 Mon Sep 17 00:00:00 2001 From: Hans Rosenfeld Date: Sat, 23 Feb 2008 15:23:31 -0800 Subject: [PATCH 602/880] /proc/pid/pagemap: fix PM_SPECIAL macro There seems to be a bug in the PM_SPECIAL macro for /proc/pid/pagemap. I think masking out those other bits makes more sense then setting all those mask bits. Signed-off-by: Hans Rosenfeld Acked-by: Matt Mackall Cc: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 49958cffbd8d..6dc0334815f7 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -531,7 +531,7 @@ struct pagemapread { #define PM_RESERVED_BITS 3 #define PM_RESERVED_OFFSET (64 - PM_RESERVED_BITS) #define PM_RESERVED_MASK (((1LL< Date: Sat, 23 Feb 2008 15:23:32 -0800 Subject: [PATCH 603/880] hugetlb: ensure we do not reference a surplus page after handing it to buddy When we free a page via free_huge_page and we detect that we are in surplus the page will be returned to the buddy. After this we no longer own the page. However at the end free_huge_page we clear out our mapping pointer from page private. Even where the page is not a surplus we free the page to the hugepage pool, drop the pool locks and then clear page private. In either case the page may have been reallocated. BAD. Make sure we clear out page private before we free the page. Signed-off-by: Andy Whitcroft Acked-by: Adam Litke Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index cb1b3a7ecdfc..89e6286a7f57 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -120,6 +120,7 @@ static void free_huge_page(struct page *page) struct address_space *mapping; mapping = (struct address_space *) page_private(page); + set_page_private(page, 0); BUG_ON(page_count(page)); INIT_LIST_HEAD(&page->lru); @@ -134,7 +135,6 @@ static void free_huge_page(struct page *page) spin_unlock(&hugetlb_lock); if (mapping) hugetlb_put_quota(mapping, 1); - set_page_private(page, 0); } /* From 094972840f2e7c1c6fc9e1a97d817cc17085378e Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Sat, 23 Feb 2008 15:23:33 -0800 Subject: [PATCH 604/880] file capabilities: simplify signal check Simplify the uid equivalence check in cap_task_kill(). Anyone can kill a process owned by the same uid. Without this patch wireshark is reported to fail. Signed-off-by: Serge E. Hallyn Signed-off-by: Andrew G. Morgan Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/commoncap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/commoncap.c b/security/commoncap.c index 5aba82679a0b..bb0c095f5761 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -552,7 +552,7 @@ int cap_task_kill(struct task_struct *p, struct siginfo *info, * allowed. * We must preserve legacy signal behavior in this case. */ - if (p->euid == 0 && p->uid == current->uid) + if (p->uid == current->uid) return 0; /* sigcont is permitted within same session */ From de4fc64f0f2a4efbaad3e7c1e1e05a28f69b45e5 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 23 Feb 2008 15:23:33 -0800 Subject: [PATCH 605/880] markers: fix sparse warnings in markers.c char can be unsigned kernel/marker.c:64:20: error: dubious one-bit signed bitfield kernel/marker.c:65:14: error: dubious one-bit signed bitfield Signed-off-by: Harvey Harrison Acked-by: Mathieu Desnoyers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/marker.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/marker.c b/kernel/marker.c index c4c2cd8b61f5..50effc01d9a2 100644 --- a/kernel/marker.c +++ b/kernel/marker.c @@ -61,8 +61,8 @@ struct marker_entry { int refcount; /* Number of times armed. 0 if disarmed. */ struct rcu_head rcu; void *oldptr; - char rcu_pending:1; - char ptype:1; + unsigned char rcu_pending:1; + unsigned char ptype:1; char name[0]; /* Contains name'\0'format'\0' */ }; From eaeb16883bd6aa2d6b6b61b825c0d2b0dc793f60 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Sat, 23 Feb 2008 15:23:34 -0800 Subject: [PATCH 606/880] sparc: fix build Fix build failure on sparc: In file included from include/linux/mm.h:39, from include/linux/memcontrol.h:24, from include/linux/swap.h:8, from include/linux/suspend.h:7, from init/do_mounts.c:6: include/asm/pgtable.h:344: warning: parameter names (without types) in function declaration include/asm/pgtable.h:345: warning: parameter names (without types) in function declaration include/asm/pgtable.h:346: error: expected '=', ',', ';', 'asm' or '__attribute__' before '___f___swp_entry' viro sayeth: I've run allmodconfig builds on a bunch of target, FWIW (essentially the same patch). Note that these includes are recent addition caused by added inline function that had since then become a define. So while I agree with your comments in general, in _this_ case it's pretty safe. The commit that had done it is 3062fc67dad01b1d2a15d58c709eff946389eca4 ("memcontrol: move mm_cgroup to header file") and the switch to #define is in commit 60c12b1202a60eabb1c61317e5d2678fcea9893f ("memcontrol: add vm_match_cgroup()") (BTW, that probably warranted mentioning in the changelog of the latter). Cc: Adrian Bunk Cc: Robert Reif Signed-off-by: David Rientjes Cc: "David S. Miller" Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 925d57b236aa..04075628cb9a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -20,9 +20,6 @@ #ifndef _LINUX_MEMCONTROL_H #define _LINUX_MEMCONTROL_H -#include -#include - struct mem_cgroup; struct page_cgroup; struct page; From 98bcef56cadb4da138e2c1a2a0790f372382b236 Mon Sep 17 00:00:00 2001 From: mark gross Date: Sat, 23 Feb 2008 15:23:35 -0800 Subject: [PATCH 607/880] copyright owner and author clean up for intel iommu and related files The following is a clean up and correction of the copyright holding entities for the files associated with the intel iommu code. Signed-off-by: Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pci/dmar.c | 9 +++++---- drivers/pci/intel-iommu.c | 7 ++++--- drivers/pci/intel-iommu.h | 5 +++-- drivers/pci/iova.c | 3 ++- drivers/pci/iova.h | 3 ++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 8ed26480371f..f941f609dbf3 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -14,11 +14,12 @@ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. * - * Copyright (C) Ashok Raj - * Copyright (C) Shaohua Li - * Copyright (C) Anil S Keshavamurthy + * Copyright (C) 2006-2008 Intel Corporation + * Author: Ashok Raj + * Author: Shaohua Li + * Author: Anil S Keshavamurthy * - * This file implements early detection/parsing of DMA Remapping Devices + * This file implements early detection/parsing of DMA Remapping Devices * reported to OS through BIOS via DMA remapping reporting (DMAR) ACPI * tables. */ diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index a4c3089f892a..977d29b32295 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -14,9 +14,10 @@ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. * - * Copyright (C) Ashok Raj - * Copyright (C) Shaohua Li - * Copyright (C) Anil S Keshavamurthy + * Copyright (C) 2006-2008 Intel Corporation + * Author: Ashok Raj + * Author: Shaohua Li + * Author: Anil S Keshavamurthy */ #include diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h index 07f5f6353bda..afc0ad96122e 100644 --- a/drivers/pci/intel-iommu.h +++ b/drivers/pci/intel-iommu.h @@ -14,8 +14,9 @@ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. * - * Copyright (C) Ashok Raj - * Copyright (C) Anil S Keshavamurthy + * Copyright (C) 2006-2008 Intel Corporation + * Author: Ashok Raj + * Author: Anil S Keshavamurthy */ #ifndef _INTEL_IOMMU_H_ diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c index 8de7ab6c6d0c..dbcdd6bfa63a 100644 --- a/drivers/pci/iova.c +++ b/drivers/pci/iova.c @@ -3,7 +3,8 @@ * * This file is released under the GPLv2. * - * Copyright (C) 2006 Anil S Keshavamurthy + * Copyright (C) 2006-2008 Intel Corporation + * Author: Anil S Keshavamurthy */ #include "iova.h" diff --git a/drivers/pci/iova.h b/drivers/pci/iova.h index d521b5b7319c..228f6c94b69c 100644 --- a/drivers/pci/iova.h +++ b/drivers/pci/iova.h @@ -3,7 +3,8 @@ * * This file is released under the GPLv2. * - * Copyright (C) 2006 Anil S Keshavamurthy + * Copyright (C) 2006-2008 Intel Corporation + * Author: Anil S Keshavamurthy * */ From 0400b697ef20247d26427e4beb6a84ca5aa51f45 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Sat, 23 Feb 2008 15:23:36 -0800 Subject: [PATCH 608/880] atmel_serial: fix interrupt handler return value We should only return IRQ_HANDLED when we actually found something to handle. This is important since the USART interrupt handler may be shared with the timer interrupt on some chips. Pointed-out-by: michael Signed-off-by: Haavard Skinnemoen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/atmel_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index fad245b064d6..d57bf3e708d8 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -549,7 +549,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id) atmel_handle_transmit(port, pending); } while (pass_counter++ < ATMEL_ISR_PASS_LIMIT); - return IRQ_HANDLED; + return pass_counter ? IRQ_HANDLED : IRQ_NONE; } /* From 8ca3ed87db062201e1fa15b64a9214e193fc3a8a Mon Sep 17 00:00:00 2001 From: David Howells Date: Sat, 23 Feb 2008 15:23:37 -0800 Subject: [PATCH 609/880] NOMMU: is_vmalloc_addr() won't compile if !MMU Make is_vmalloc_addr() contingent on CONFIG_MMU=y, as it won't compile in !MMU mode. [ Bug introduced in commit 9e2779fa281cfda13ac060753d674bbcaa23367e: "is_vmalloc_addr(): Check if an address is within the vmalloc boundaries" ]. Signed-off-by: David Howells Cc: Greg Ungerer Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 3b3e1341163f..3f3ccfe42de0 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -235,6 +235,7 @@ static inline int get_page_unless_zero(struct page *page) struct page *vmalloc_to_page(const void *addr); unsigned long vmalloc_to_pfn(const void *addr); +#ifdef CONFIG_MMU /* Determine if an address is within the vmalloc range */ static inline int is_vmalloc_addr(const void *x) { @@ -242,6 +243,7 @@ static inline int is_vmalloc_addr(const void *x) return addr >= VMALLOC_START && addr < VMALLOC_END; } +#endif static inline struct page *compound_head(struct page *page) { From 4f9d5f4a353440f2265781bfa641587964901861 Mon Sep 17 00:00:00 2001 From: Hoang-Nam Nguyen Date: Sat, 23 Feb 2008 15:23:37 -0800 Subject: [PATCH 610/880] lib/vsprintf.c: fix bug omitting minus sign of numbers (module_param) lib/vsprintf.c: Fix bug omitting minus sign of numbers (module_param) Signed-off-by: Hoang-Nam Nguyen Cc: Yi Yang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/vsprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index fd987b17bda7..6021757a4496 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -234,7 +234,7 @@ int strict_strto##type(const char *cp, unsigned int base, valtype *res) \ int ret; \ if (*cp == '-') { \ ret = strict_strtou##type(cp+1, base, res); \ - if (ret != 0) \ + if (!ret) \ *res = -(*res); \ } else \ ret = strict_strtou##type(cp, base, res); \ From f6febccd7f86fbe94858a4a32d9384cc014c9f40 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 23 Feb 2008 15:23:39 -0800 Subject: [PATCH 611/880] atmel_spi: fix clock polarity The atmel_spi driver does not initialize clock polarity correctly (except for at91rm9200 CS0 channel) in some case. The atmel_spi driver uses gpio-controlled chipselect. OTOH spi clock signal is controlled by CSRn.CPOL bit, but this register controls clock signal correctly only in 'real transfer' duration. At the time of cs_activate() call, CSRn.CPOL will be initialized correctly, but the controller do not know which channel is to be used next, so clock signal will stay at the inactive state of last transfer. If clock polarity of new transfer and last transfer was differ, new transfer will start with wrong clock signal state. For example, if you started SPI MODE 2 or 3 transfer after SPI MODE 0 or 1 transfer, the clock signal state at the assertion of chipselect will be low. Of course this will violates SPI transfer. This patch is short term solution for this problem. It makes all CSRn.CPOL match for the transfer before activating chipselect. For longer term, the best fix might be to let NPCS0 stay selected permanently in MR and overwrite CSR0 with to the new slave's settings before asserting CS. Signed-off-by: Atsushi Nemoto Acked-by: Haavard Skinnemoen Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/atmel_spi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 293b7cab3e57..85687aaf9cab 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -87,6 +87,16 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) unsigned gpio = (unsigned) spi->controller_data; unsigned active = spi->mode & SPI_CS_HIGH; u32 mr; + int i; + u32 csr; + u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; + + /* Make sure clock polarity is correct */ + for (i = 0; i < spi->master->num_chipselect; i++) { + csr = spi_readl(as, CSR0 + 4 * i); + if ((csr ^ cpol) & SPI_BIT(CPOL)) + spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL)); + } mr = spi_readl(as, MR); mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); From b97c74bddce4e2c6fef6b3b58910b4fd9eb7f3b8 Mon Sep 17 00:00:00 2001 From: Ned Forrester Date: Sat, 23 Feb 2008 15:23:40 -0800 Subject: [PATCH 612/880] spi: pxa2xx_spi clock polarity fix Fixes a sequencing bug in spi driver pxa2xx_spi.c in which the chip select for a transfer may be asserted before the clock polarity is set on the interface. As a result of this bug, the clock signal may have the wrong polarity at transfer start, so it may need to make an extra half transition before the intended clock/data signals begin. (This probably means all transfers are one bit out of sequence.) This only occurs on the first transfer following a change in clock polarity in systems using more than one more than one such polarity. The fix assures that the clock mode is properly set before asserting chip select. This bug was introduced in a patch merged on 2006/12/10, kernel 2.6.20. The patch defines an additional bit in: include/asm-arm/arch-pxa/regs-ssp.h for 2.6.25 and newer kernels but this addition must be made in: include/asm-arm/arch-pxa/pxa-regs.h for kernels between 2.6.20 and 2.6.24, inclusive Signed-off-by: Ned Forrester Signed-off-by: David Brownell Cc: Russell King Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/pxa2xx_spi.c | 41 +++++++++++++++++++---------- include/asm-arm/arch-pxa/regs-ssp.h | 1 + 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 365e0e355aea..59deed79e0ab 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -51,13 +51,19 @@ MODULE_LICENSE("GPL"); #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) -/* for testing SSCR1 changes that require SSP restart, basically - * everything except the service and interrupt enables */ -#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \ +/* + * for testing SSCR1 changes that require SSP restart, basically + * everything except the service and interrupt enables, the pxa270 developer + * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this + * list, but the PXA255 dev man says all bits without really meaning the + * service and interrupt enables + */ +#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \ | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \ - | SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \ - | SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \ - | SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) + | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \ + | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \ + | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ + | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) #define DEFINE_SSP_REG(reg, off) \ static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ @@ -973,9 +979,6 @@ static void pump_transfers(unsigned long data) if (drv_data->ssp_type == PXA25x_SSP) DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN; - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - /* Clear status and start DMA engine */ cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1; write_SSSR(drv_data->clear_sr, reg); @@ -985,9 +988,6 @@ static void pump_transfers(unsigned long data) /* Ensure we have the correct interrupt handler */ drv_data->transfer_handler = interrupt_transfer; - /* Fix me, need to handle cs polarity */ - drv_data->cs_control(PXA2XX_CS_ASSERT); - /* Clear status */ cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; write_SSSR(drv_data->clear_sr, reg); @@ -998,16 +998,29 @@ static void pump_transfers(unsigned long data) || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != (cr1 & SSCR1_CHANGE_MASK)) { + /* stop the SSP, and update the other bits */ write_SSCR0(cr0 & ~SSCR0_SSE, reg); if (drv_data->ssp_type != PXA25x_SSP) write_SSTO(chip->timeout, reg); - write_SSCR1(cr1, reg); + /* first set CR1 without interrupt and service enables */ + write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); + /* restart the SSP */ write_SSCR0(cr0, reg); + } else { if (drv_data->ssp_type != PXA25x_SSP) write_SSTO(chip->timeout, reg); - write_SSCR1(cr1, reg); } + + /* FIXME, need to handle cs polarity, + * this driver uses struct pxa2xx_spi_chip.cs_control to + * specify a CS handling function, and it ignores most + * struct spi_device.mode[s], including SPI_CS_HIGH */ + drv_data->cs_control(PXA2XX_CS_ASSERT); + + /* after chip select, release the data by enabling service + * requests and interrupts, without changing any mode bits */ + write_SSCR1(cr1, reg); } static void pump_messages(struct work_struct *work) diff --git a/include/asm-arm/arch-pxa/regs-ssp.h b/include/asm-arm/arch-pxa/regs-ssp.h index 991cb688db75..0255328c3c18 100644 --- a/include/asm-arm/arch-pxa/regs-ssp.h +++ b/include/asm-arm/arch-pxa/regs-ssp.h @@ -85,6 +85,7 @@ #define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */ #define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */ #define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */ +#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */ #define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */ #define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */ From 0b720378d05d9f5101dd331d16a0957a764583f3 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Sat, 23 Feb 2008 15:23:41 -0800 Subject: [PATCH 613/880] cpuset: trivial documentation fix s/N_MEMORY/N_HIGH_MEMORY/ Current implementation of cpuset track N_HIGH_MEMORY instead N_MEMORY. (N_MEMORY doesn't exist in current implementation) Signed-off-by: KOSAKI Motohiro Acked-by: Paul Jackson Cc: Christoph Lameter Cc: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cpusets.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt index 43db6fe12814..ad2bb3b3acc1 100644 --- a/Documentation/cpusets.txt +++ b/Documentation/cpusets.txt @@ -209,7 +209,7 @@ and name space for cpusets, with a minimum of additional kernel code. The cpus and mems files in the root (top_cpuset) cpuset are read-only. The cpus file automatically tracks the value of cpu_online_map using a CPU hotplug notifier, and the mems file -automatically tracks the value of node_states[N_MEMORY]--i.e., +automatically tracks the value of node_states[N_HIGH_MEMORY]--i.e., nodes with memory--using the cpuset_track_online_nodes() hook. From 4185108c77afee83674101319dc071599846a40b Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 23 Feb 2008 15:23:42 -0800 Subject: [PATCH 614/880] hwrng: remove Michael as HWRNG maintainer It turns out that I rewrote the HWRNG core once to make it pluggable, but I'm not a crypto-expert at all. So I'm certainly the wrong person for being a maintainer of the HWRNG core. Let's orphan it. Signed-off-by: Michael Buesch Cc: Herbert Xu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 25af17830522..36c7bc641dba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1712,9 +1712,7 @@ T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release S: Maintained HARDWARE RANDOM NUMBER GENERATOR CORE -P: Michael Buesch -M: mb@bu3sch.de -S: Maintained +S: Orphaned HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER P: Robert Love From c8626a1d7250c593f148530b559c20f6f6af18e8 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 23 Feb 2008 15:23:44 -0800 Subject: [PATCH 615/880] rtc-cmos: display HPET emulation mode For the "cmos" RTC, have /proc/driver/rtc say whether HPET based IRQ emulation is in effect. Given the problems we've had with this particular hardware maldesign (and the fact that most BIOS code seems not to provide the IRQ routing needed to use the saner HPET modes), this should help troubleshooting. Signed-off-by: David Brownell Cc: Alessandro Zummo Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-cmos.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e059f94c79eb..f3ee2ad566b4 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -388,6 +388,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) return seq_printf(seq, "periodic_IRQ\t: %s\n" "update_IRQ\t: %s\n" + "HPET_emulated\t: %s\n" // "square_wave\t: %s\n" // "BCD\t\t: %s\n" "DST_enable\t: %s\n" @@ -395,6 +396,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) "batt_status\t: %s\n", (rtc_control & RTC_PIE) ? "yes" : "no", (rtc_control & RTC_UIE) ? "yes" : "no", + is_hpet_enabled() ? "yes" : "no", // (rtc_control & RTC_SQWE) ? "yes" : "no", // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", (rtc_control & RTC_DST_EN) ? "yes" : "no", From f3069ae9d76901d021362bb63d9ad6c5900dfc76 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 23 Feb 2008 15:23:46 -0800 Subject: [PATCH 616/880] dmi: don't save the same device twice Now that we gather on-board devices from both DMI types 10 and 41, there is a possibility that we list the same device twice. In order to not confuse drivers, and also to save memory, make sure that we do not add duplicate devices to the dmi_devices list. Signed-off-by: Jean Delvare Cc: Wim Van Sebroeck Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/dmi_scan.c | 74 ++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 653265a40b7f..de3027521bfa 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -10,10 +10,9 @@ static char dmi_empty_string[] = " "; -static char * __init dmi_string(const struct dmi_header *dm, u8 s) +static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s) { const u8 *bp = ((u8 *) dm) + dm->length; - char *str = ""; if (s) { s--; @@ -28,14 +27,29 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s) if (!memcmp(bp, dmi_empty_string, cmp_len)) return dmi_empty_string; - str = dmi_alloc(len); - if (str != NULL) - strcpy(str, bp); - else - printk(KERN_ERR "dmi_string: cannot allocate %Zu bytes.\n", len); + return bp; } } + return ""; +} + +static char * __init dmi_string(const struct dmi_header *dm, u8 s) +{ + const char *bp = dmi_string_nosave(dm, s); + char *str; + size_t len; + + if (bp == dmi_empty_string) + return dmi_empty_string; + + len = strlen(bp) + 1; + str = dmi_alloc(len); + if (str != NULL) + strcpy(str, bp); + else + printk(KERN_ERR "dmi_string: cannot allocate %Zu bytes.\n", len); + return str; } @@ -167,10 +181,30 @@ static void __init dmi_save_type(const struct dmi_header *dm, int slot, int inde dmi_ident[slot] = s; } +static void __init dmi_save_one_device(int type, const char *name) +{ + struct dmi_device *dev; + + /* No duplicate device */ + if (dmi_find_device(type, name, NULL)) + return; + + dev = dmi_alloc(sizeof(*dev) + strlen(name) + 1); + if (!dev) { + printk(KERN_ERR "dmi_save_one_device: out of memory.\n"); + return; + } + + dev->type = type; + strcpy((char *)(dev + 1), name); + dev->name = (char *)(dev + 1); + dev->device_data = NULL; + list_add(&dev->list, &dmi_devices); +} + static void __init dmi_save_devices(const struct dmi_header *dm) { int i, count = (dm->length - sizeof(struct dmi_header)) / 2; - struct dmi_device *dev; for (i = 0; i < count; i++) { const char *d = (char *)(dm + 1) + (i * 2); @@ -179,16 +213,7 @@ static void __init dmi_save_devices(const struct dmi_header *dm) if ((*d & 0x80) == 0) continue; - dev = dmi_alloc(sizeof(*dev)); - if (!dev) { - printk(KERN_ERR "dmi_save_devices: out of memory.\n"); - break; - } - - dev->type = *d++ & 0x7f; - dev->name = dmi_string(dm, *d); - dev->device_data = NULL; - list_add(&dev->list, &dmi_devices); + dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d + 1))); } } @@ -253,23 +278,12 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm) static void __init dmi_save_extended_devices(const struct dmi_header *dm) { const u8 *d = (u8*) dm + 5; - struct dmi_device *dev; /* Skip disabled device */ if ((*d & 0x80) == 0) return; - dev = dmi_alloc(sizeof(*dev)); - if (!dev) { - printk(KERN_ERR "dmi_save_extended_devices: out of memory.\n"); - return; - } - - dev->type = *d-- & 0x7f; - dev->name = dmi_string(dm, *d); - dev->device_data = NULL; - - list_add(&dev->list, &dmi_devices); + dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1))); } /* From b32eb52e4093351bd0debd027575578a599bfb3e Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sat, 23 Feb 2008 15:23:48 -0800 Subject: [PATCH 617/880] uml: remove unused sigcontext accessors The macros which extract registers from a struct sigcontext are no longer needed and can be removed. They are starting not to build anyway, given the removal of the 'e' and 'r' from register names during the x86 merge. Cc: Jiri Olsa Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/user-offsets.c | 27 --------------------------- arch/um/sys-x86_64/user-offsets.c | 28 ---------------------------- 2 files changed, 55 deletions(-) diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index 514241526a1b..39bd32bf84f0 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -17,36 +17,9 @@ void foo(void) { - OFFSET(HOST_SC_IP, sigcontext, eip); - OFFSET(HOST_SC_SP, sigcontext, esp); - OFFSET(HOST_SC_FS, sigcontext, fs); - OFFSET(HOST_SC_GS, sigcontext, gs); - OFFSET(HOST_SC_DS, sigcontext, ds); - OFFSET(HOST_SC_ES, sigcontext, es); - OFFSET(HOST_SC_SS, sigcontext, ss); - OFFSET(HOST_SC_CS, sigcontext, cs); - OFFSET(HOST_SC_EFLAGS, sigcontext, eflags); - OFFSET(HOST_SC_EAX, sigcontext, eax); - OFFSET(HOST_SC_EBX, sigcontext, ebx); - OFFSET(HOST_SC_ECX, sigcontext, ecx); - OFFSET(HOST_SC_EDX, sigcontext, edx); - OFFSET(HOST_SC_EDI, sigcontext, edi); - OFFSET(HOST_SC_ESI, sigcontext, esi); - OFFSET(HOST_SC_EBP, sigcontext, ebp); OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); OFFSET(HOST_SC_ERR, sigcontext, err); OFFSET(HOST_SC_CR2, sigcontext, cr2); - OFFSET(HOST_SC_FPSTATE, sigcontext, fpstate); - OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask); - OFFSET(HOST_SC_FP_CW, _fpstate, cw); - OFFSET(HOST_SC_FP_SW, _fpstate, sw); - OFFSET(HOST_SC_FP_TAG, _fpstate, tag); - OFFSET(HOST_SC_FP_IPOFF, _fpstate, ipoff); - OFFSET(HOST_SC_FP_CSSEL, _fpstate, cssel); - OFFSET(HOST_SC_FP_DATAOFF, _fpstate, dataoff); - OFFSET(HOST_SC_FP_DATASEL, _fpstate, datasel); - OFFSET(HOST_SC_FP_ST, _fpstate, _st); - OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env); DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct)); diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index f1ef2a8dfbc6..2f3443c6e859 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c @@ -19,37 +19,9 @@ void foo(void) { - OFFSET(HOST_SC_RBX, sigcontext, rbx); - OFFSET(HOST_SC_RCX, sigcontext, rcx); - OFFSET(HOST_SC_RDX, sigcontext, rdx); - OFFSET(HOST_SC_RSI, sigcontext, rsi); - OFFSET(HOST_SC_RDI, sigcontext, rdi); - OFFSET(HOST_SC_RBP, sigcontext, rbp); - OFFSET(HOST_SC_RAX, sigcontext, rax); - OFFSET(HOST_SC_R8, sigcontext, r8); - OFFSET(HOST_SC_R9, sigcontext, r9); - OFFSET(HOST_SC_R10, sigcontext, r10); - OFFSET(HOST_SC_R11, sigcontext, r11); - OFFSET(HOST_SC_R12, sigcontext, r12); - OFFSET(HOST_SC_R13, sigcontext, r13); - OFFSET(HOST_SC_R14, sigcontext, r14); - OFFSET(HOST_SC_R15, sigcontext, r15); - OFFSET(HOST_SC_IP, sigcontext, rip); - OFFSET(HOST_SC_SP, sigcontext, rsp); OFFSET(HOST_SC_CR2, sigcontext, cr2); OFFSET(HOST_SC_ERR, sigcontext, err); OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - OFFSET(HOST_SC_CS, sigcontext, cs); - OFFSET(HOST_SC_FS, sigcontext, fs); - OFFSET(HOST_SC_GS, sigcontext, gs); - OFFSET(HOST_SC_EFLAGS, sigcontext, eflags); - OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask); -#if 0 - OFFSET(HOST_SC_ORIG_RAX, sigcontext, orig_rax); - OFFSET(HOST_SC_DS, sigcontext, ds); - OFFSET(HOST_SC_ES, sigcontext, es); - OFFSET(HOST_SC_SS, sigcontext, ss); -#endif DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); DEFINE(HOST_XFP_SIZE, 0); From e4d06b3f904ddfab4531a1e23f1f5e1bd284b605 Mon Sep 17 00:00:00 2001 From: Johann Felix Soden Date: Sat, 23 Feb 2008 15:23:49 -0800 Subject: [PATCH 618/880] uml: fix helper_wait calls in watchdog In commit 1aa351a308d2c3ddb92b6cc45083fc54271d0010 ("uml: tidy helper code") the arguments of helper_wait() were changed. The adaptation of harddog_user.c was forgotten, so this errors occur: /arch/um/drivers/harddog_user.c: In function 'start_watchdog': /arch/um/drivers/harddog_user.c:82: error: too many arguments to function 'helper_wait' /arch/um/drivers/harddog_user.c:89: error: too many arguments to function 'helper_wait' Signed-off-by: Johann Felix Soden Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/harddog_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 448ba59207a1..b56f8e0196a9 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -79,14 +79,14 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) n = read(in_fds[0], &c, sizeof(c)); if (n == 0) { printk("harddog_open - EOF on watchdog pipe\n"); - helper_wait(pid, 1, NULL); + helper_wait(pid); err = -EIO; goto out_close_out; } else if (n < 0) { printk("harddog_open - read of watchdog pipe failed, " "err = %d\n", errno); - helper_wait(pid, 1, NULL); + helper_wait(pid); err = n; goto out_close_out; } From 2f56debd77a8f52f1ac1d3c3d89cc7ce5e083230 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sat, 23 Feb 2008 15:23:49 -0800 Subject: [PATCH 619/880] uml: fix FP register corruption Commit ee3d9bd4de1ed93d2a7ee41c331ed30a1c7b8acd ("uml: simplify SIGSEGV handling"), while greatly simplifying the kernel SIGSEGV handler that runs in the process address space, introduced a bug which corrupts FP state in the process. Previously, the SIGSEGV handler called the sigreturn system call by hand - it couldn't return through the restorer provided to it because that could try to call the libc restorer which likely wouldn't exist in the process address space. So, it blocked off some signals, including SIGUSR1, on entry to the SIGSEGV handler, queued a SIGUSR1 to itself, and invoked sigreturn. The SIGUSR1 was delivered, and was visible to the UML kernel after sigreturn finished. The commit eliminated the signal masking and the call to sigreturn. The handler simply hits itself with a SIGTRAP to let the UML kernel know that it is finished. UML then restores the process registers, which effectively longjmps the process out of the signal handler, skipping sigreturn's restoring of register state and the signal mask. The bug is that the host apparently sets used_fp to 0 when it saves the process FP state in the sigcontext on the process signal stack. Thus, when the process is longjmped out of the handler, its FP state is corrupt because it wasn't saved on the context switch to the UML kernel. This manifested itself as sleep hanging. For some reason, sleep uses floating point in order to calculate the sleep interval. When a page fault corrupts its FP state, it is faked into essentially sleeping forever. This patch saves the FP state before entering the SIGSEGV handler and restores it afterwards. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/registers.h | 2 ++ arch/um/include/sysdep-i386/ptrace_user.h | 3 +++ arch/um/include/sysdep-x86_64/ptrace_user.h | 3 +++ arch/um/os-Linux/skas/process.c | 15 +++++++++++++++ arch/um/os-Linux/sys-i386/registers.c | 16 ++++++++++++++++ arch/um/os-Linux/sys-x86_64/registers.c | 10 ++++++++++ 6 files changed, 49 insertions(+) diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h index 9ea1ae3c8f46..b0b4589e0ebc 100644 --- a/arch/um/include/registers.h +++ b/arch/um/include/registers.h @@ -18,5 +18,7 @@ extern int restore_registers(int pid, struct uml_pt_regs *regs); extern int init_registers(int pid); extern void get_safe_registers(unsigned long *regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); +extern int get_fp_registers(int pid, unsigned long *regs); +extern int put_fp_registers(int pid, unsigned long *regs); #endif diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h index 899aa4b2a78d..75650723c38f 100644 --- a/arch/um/include/sysdep-i386/ptrace_user.h +++ b/arch/um/include/sysdep-i386/ptrace_user.h @@ -9,6 +9,7 @@ #include #include #include +#include "user_constants.h" #define PT_OFFSET(r) ((r) * sizeof(long)) @@ -40,6 +41,8 @@ #define PT_SP_OFFSET PT_OFFSET(UESP) #define PT_SP(regs) ((regs)[UESP]) +#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE) + #ifndef FRAME_SIZE #define FRAME_SIZE (17) #endif diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h index 4cd61a852fab..45c0bd881cb3 100644 --- a/arch/um/include/sysdep-x86_64/ptrace_user.h +++ b/arch/um/include/sysdep-x86_64/ptrace_user.h @@ -12,6 +12,7 @@ #include #include #undef __FRAME_OFFSETS +#include "user_constants.h" #define PT_INDEX(off) ((off) / sizeof(unsigned long)) @@ -69,6 +70,8 @@ #define REGS_IP_INDEX PT_INDEX(RIP) #define REGS_SP_INDEX PT_INDEX(RSP) +#define FP_SIZE (HOST_FP_SIZE) + #endif /* diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index b14829469fae..1e8cba6550a9 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -115,6 +115,14 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) sizeof(struct ptrace_faultinfo)); } else { + unsigned long fpregs[FP_SIZE]; + + err = get_fp_registers(pid, fpregs); + if (err < 0) { + printk(UM_KERN_ERR "save_fp_registers returned %d\n", + err); + fatal_sigsegv(); + } err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); if (err) { printk(UM_KERN_ERR "Failed to continue stub, pid = %d, " @@ -128,6 +136,13 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) * the stub stack page. We just have to copy it. */ memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); + + err = put_fp_registers(pid, fpregs); + if (err < 0) { + printk(UM_KERN_ERR "put_fp_registers returned %d\n", + err); + fatal_sigsegv(); + } } } diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index f74d853a0ee0..b613473b3ec1 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -56,6 +56,22 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf) int have_fpx_regs = 1; +int get_fp_registers(int pid, unsigned long *regs) +{ + if (have_fpx_regs) + return save_fpx_registers(pid, regs); + else + return save_fp_registers(pid, regs); +} + +int put_fp_registers(int pid, unsigned long *regs) +{ + if (have_fpx_regs) + return restore_fpx_registers(pid, regs); + else + return restore_fp_registers(pid, regs); +} + void arch_init_registers(int pid) { unsigned long fpx_regs[HOST_XFP_SIZE]; diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index a375853337a7..594d97ad02b3 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -40,3 +40,13 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf) return 0; } } + +int get_fp_registers(int pid, unsigned long *regs) +{ + return save_fp_registers(pid, regs); +} + +int put_fp_registers(int pid, unsigned long *regs) +{ + return restore_fp_registers(pid, regs); +} From 48f15b93b2c9f4ec9b8af08ab78f7a27db7c8378 Mon Sep 17 00:00:00 2001 From: Paul Clements Date: Sat, 23 Feb 2008 15:23:50 -0800 Subject: [PATCH 620/880] NBD: make nbd default to deadline I/O scheduler NBD doesn't work well with CFQ (or AS) schedulers, so let's default to something else. The two problems I have experienced with nbd and cfq are: 1) nbd hangs with cfq on RHEL 5 (2.6.18) -- this may well have been fixed There's a similar debian bug that has been filed as well: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=447638 There have been posts to nbd-general mailing list about problems with cfq and nbd also. 2) nbd performs about 10% better (the last time I tested) with deadline vs. cfq (the overhead of cfq doesn't provide much advantage to nbd [not being a real disk], and you end up going through the I/O scheduler on the nbd server anyway, so it makes sense that deadline is better with nbd) Signed-off-by: Paul Clements Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/nbd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 018753c59b8e..b53fdb0a282c 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -655,6 +655,7 @@ static int __init nbd_init(void) for (i = 0; i < nbds_max; i++) { struct gendisk *disk = alloc_disk(1); + elevator_t *old_e; if (!disk) goto out; nbd_dev[i].disk = disk; @@ -668,6 +669,11 @@ static int __init nbd_init(void) put_disk(disk); goto out; } + old_e = disk->queue->elevator; + if (elevator_init(disk->queue, "deadline") == 0 || + elevator_init(disk->queue, "noop") == 0) { + elevator_exit(old_e); + } } if (register_blkdev(NBD_MAJOR, "nbd")) { From 45254b4fb2aef51c94a7397df1e481c4137b4b97 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 23 Feb 2008 15:23:51 -0800 Subject: [PATCH 621/880] efs: move headers out of include/linux/ Merge include/linux/efs_fs{_i,_dir}.h into fs/efs/efs.h. efs_vh.h remains there because this is the IRIX volume header and shouldn't really be handled by efs but by the partitioning code. efs_sb.h remains there for now because it's exported to userspace. Of course this wrong and aboot should have a copy of it's own, but I'll leave that to a separate patch to avoid any contention. Signed-off-by: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/efs/dir.c | 2 +- fs/efs/efs.h | 140 +++++++++++++++++++++++++++++++++++++++ fs/efs/file.c | 2 +- fs/efs/inode.c | 4 +- fs/efs/namei.c | 2 +- fs/efs/super.c | 7 +- fs/efs/symlink.c | 2 +- include/linux/efs_dir.h | 42 ------------ include/linux/efs_fs.h | 56 ---------------- include/linux/efs_fs_i.h | 68 ------------------- 10 files changed, 150 insertions(+), 175 deletions(-) create mode 100644 fs/efs/efs.h delete mode 100644 include/linux/efs_dir.h delete mode 100644 include/linux/efs_fs.h delete mode 100644 include/linux/efs_fs_i.h diff --git a/fs/efs/dir.c b/fs/efs/dir.c index dfb5cb400217..49308a29798a 100644 --- a/fs/efs/dir.c +++ b/fs/efs/dir.c @@ -5,8 +5,8 @@ */ #include -#include #include +#include "efs.h" static int efs_readdir(struct file *, void *, filldir_t); diff --git a/fs/efs/efs.h b/fs/efs/efs.h new file mode 100644 index 000000000000..d8305b582ab0 --- /dev/null +++ b/fs/efs/efs.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1999 Al Smith + * + * Portions derived from work (c) 1995,1996 Christian Vogelgsang. + * Portions derived from IRIX header files (c) 1988 Silicon Graphics + */ +#ifndef _EFS_EFS_H_ +#define _EFS_EFS_H_ + +#include +#include + +#define EFS_VERSION "1.0a" + +static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith "; + + +/* 1 block is 512 bytes */ +#define EFS_BLOCKSIZE_BITS 9 +#define EFS_BLOCKSIZE (1 << EFS_BLOCKSIZE_BITS) + +typedef int32_t efs_block_t; +typedef uint32_t efs_ino_t; + +#define EFS_DIRECTEXTENTS 12 + +/* + * layout of an extent, in memory and on disk. 8 bytes exactly. + */ +typedef union extent_u { + unsigned char raw[8]; + struct extent_s { + unsigned int ex_magic:8; /* magic # (zero) */ + unsigned int ex_bn:24; /* basic block */ + unsigned int ex_length:8; /* numblocks in this extent */ + unsigned int ex_offset:24; /* logical offset into file */ + } cooked; +} efs_extent; + +typedef struct edevs { + __be16 odev; + __be32 ndev; +} efs_devs; + +/* + * extent based filesystem inode as it appears on disk. The efs inode + * is exactly 128 bytes long. + */ +struct efs_dinode { + __be16 di_mode; /* mode and type of file */ + __be16 di_nlink; /* number of links to file */ + __be16 di_uid; /* owner's user id */ + __be16 di_gid; /* owner's group id */ + __be32 di_size; /* number of bytes in file */ + __be32 di_atime; /* time last accessed */ + __be32 di_mtime; /* time last modified */ + __be32 di_ctime; /* time created */ + __be32 di_gen; /* generation number */ + __be16 di_numextents; /* # of extents */ + u_char di_version; /* version of inode */ + u_char di_spare; /* spare - used by AFS */ + union di_addr { + efs_extent di_extents[EFS_DIRECTEXTENTS]; + efs_devs di_dev; /* device for IFCHR/IFBLK */ + } di_u; +}; + +/* efs inode storage in memory */ +struct efs_inode_info { + int numextents; + int lastextent; + + efs_extent extents[EFS_DIRECTEXTENTS]; + struct inode vfs_inode; +}; + +#include + +#define EFS_DIRBSIZE_BITS EFS_BLOCKSIZE_BITS +#define EFS_DIRBSIZE (1 << EFS_DIRBSIZE_BITS) + +struct efs_dentry { + __be32 inode; + unsigned char namelen; + char name[3]; +}; + +#define EFS_DENTSIZE (sizeof(struct efs_dentry) - 3 + 1) +#define EFS_MAXNAMELEN ((1 << (sizeof(char) * 8)) - 1) + +#define EFS_DIRBLK_HEADERSIZE 4 +#define EFS_DIRBLK_MAGIC 0xbeef /* moo */ + +struct efs_dir { + __be16 magic; + unsigned char firstused; + unsigned char slots; + + unsigned char space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE]; +}; + +#define EFS_MAXENTS \ + ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \ + (EFS_DENTSIZE + sizeof(char))) + +#define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot]) + +#define EFS_REALOFF(offset) ((offset << 1)) + + +static inline struct efs_inode_info *INODE_INFO(struct inode *inode) +{ + return container_of(inode, struct efs_inode_info, vfs_inode); +} + +static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb) +{ + return sb->s_fs_info; +} + +struct statfs; +struct fid; + +extern const struct inode_operations efs_dir_inode_operations; +extern const struct file_operations efs_dir_operations; +extern const struct address_space_operations efs_symlink_aops; + +extern struct inode *efs_iget(struct super_block *, unsigned long); +extern efs_block_t efs_map_block(struct inode *, efs_block_t); +extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int); + +extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *); +extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type); +extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type); +extern struct dentry *efs_get_parent(struct dentry *); +extern int efs_bmap(struct inode *, int); + +#endif /* _EFS_EFS_H_ */ diff --git a/fs/efs/file.c b/fs/efs/file.c index 5db20129681e..1ccb364ffa63 100644 --- a/fs/efs/file.c +++ b/fs/efs/file.c @@ -7,7 +7,7 @@ */ #include -#include +#include "efs.h" int efs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) diff --git a/fs/efs/inode.c b/fs/efs/inode.c index 627c3026946d..79e19e5958e1 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c @@ -7,11 +7,11 @@ * and from work (c) 1998 Mike Shaver. */ -#include -#include #include #include #include +#include "efs.h" +#include static int efs_readpage(struct file *file, struct page *page) { diff --git a/fs/efs/namei.c b/fs/efs/namei.c index e26704742d41..3a404e7fad53 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c @@ -8,9 +8,9 @@ #include #include -#include #include #include +#include "efs.h" static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { diff --git a/fs/efs/super.c b/fs/efs/super.c index 14082405cdd1..d733531b55e2 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -8,14 +8,15 @@ #include #include -#include -#include -#include #include #include #include #include +#include "efs.h" +#include +#include + static int efs_statfs(struct dentry *dentry, struct kstatfs *buf); static int efs_fill_super(struct super_block *s, void *d, int silent); diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 1d30d2ff440f..41911ec83aaf 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c @@ -7,10 +7,10 @@ */ #include -#include #include #include #include +#include "efs.h" static int efs_symlink_readpage(struct file *file, struct page *page) { diff --git a/include/linux/efs_dir.h b/include/linux/efs_dir.h deleted file mode 100644 index a09ec010569c..000000000000 --- a/include/linux/efs_dir.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * efs_dir.h - * - * Copyright (c) 1999 Al Smith - */ - -#ifndef __EFS_DIR_H__ -#define __EFS_DIR_H__ - -#define EFS_DIRBSIZE_BITS EFS_BLOCKSIZE_BITS -#define EFS_DIRBSIZE (1 << EFS_DIRBSIZE_BITS) - -struct efs_dentry { - __be32 inode; - unsigned char namelen; - char name[3]; -}; - -#define EFS_DENTSIZE (sizeof(struct efs_dentry) - 3 + 1) -#define EFS_MAXNAMELEN ((1 << (sizeof(char) * 8)) - 1) - -#define EFS_DIRBLK_HEADERSIZE 4 -#define EFS_DIRBLK_MAGIC 0xbeef /* moo */ - -struct efs_dir { - __be16 magic; - unsigned char firstused; - unsigned char slots; - - unsigned char space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE]; -}; - -#define EFS_MAXENTS \ - ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \ - (EFS_DENTSIZE + sizeof(char))) - -#define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot]) - -#define EFS_REALOFF(offset) ((offset << 1)) - -#endif /* __EFS_DIR_H__ */ - diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h deleted file mode 100644 index a695d63a07af..000000000000 --- a/include/linux/efs_fs.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * efs_fs.h - * - * Copyright (c) 1999 Al Smith - * - * Portions derived from work (c) 1995,1996 Christian Vogelgsang. - */ - -#ifndef __EFS_FS_H__ -#define __EFS_FS_H__ - -#define EFS_VERSION "1.0a" - -static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith "; - -#include - -/* 1 block is 512 bytes */ -#define EFS_BLOCKSIZE_BITS 9 -#define EFS_BLOCKSIZE (1 << EFS_BLOCKSIZE_BITS) - -#include -#include -#include -#include - -static inline struct efs_inode_info *INODE_INFO(struct inode *inode) -{ - return container_of(inode, struct efs_inode_info, vfs_inode); -} - -static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb) -{ - return sb->s_fs_info; -} - -struct statfs; -struct fid; - -extern const struct inode_operations efs_dir_inode_operations; -extern const struct file_operations efs_dir_operations; -extern const struct address_space_operations efs_symlink_aops; - -extern struct inode *efs_iget(struct super_block *, unsigned long); -extern efs_block_t efs_map_block(struct inode *, efs_block_t); -extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int); - -extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *); -extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid, - int fh_len, int fh_type); -extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid, - int fh_len, int fh_type); -extern struct dentry *efs_get_parent(struct dentry *); -extern int efs_bmap(struct inode *, int); - -#endif /* __EFS_FS_H__ */ diff --git a/include/linux/efs_fs_i.h b/include/linux/efs_fs_i.h deleted file mode 100644 index 617c474ca659..000000000000 --- a/include/linux/efs_fs_i.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * efs_fs_i.h - * - * Copyright (c) 1999 Al Smith - * - * Portions derived from IRIX header files (c) 1988 Silicon Graphics - */ - -#ifndef __EFS_FS_I_H__ -#define __EFS_FS_I_H__ - -typedef int32_t efs_block_t; -typedef uint32_t efs_ino_t; - -#define EFS_DIRECTEXTENTS 12 - -/* - * layout of an extent, in memory and on disk. 8 bytes exactly. - */ -typedef union extent_u { - unsigned char raw[8]; - struct extent_s { - unsigned int ex_magic:8; /* magic # (zero) */ - unsigned int ex_bn:24; /* basic block */ - unsigned int ex_length:8; /* numblocks in this extent */ - unsigned int ex_offset:24; /* logical offset into file */ - } cooked; -} efs_extent; - -typedef struct edevs { - __be16 odev; - __be32 ndev; -} efs_devs; - -/* - * extent based filesystem inode as it appears on disk. The efs inode - * is exactly 128 bytes long. - */ -struct efs_dinode { - __be16 di_mode; /* mode and type of file */ - __be16 di_nlink; /* number of links to file */ - __be16 di_uid; /* owner's user id */ - __be16 di_gid; /* owner's group id */ - __be32 di_size; /* number of bytes in file */ - __be32 di_atime; /* time last accessed */ - __be32 di_mtime; /* time last modified */ - __be32 di_ctime; /* time created */ - __be32 di_gen; /* generation number */ - __be16 di_numextents; /* # of extents */ - u_char di_version; /* version of inode */ - u_char di_spare; /* spare - used by AFS */ - union di_addr { - efs_extent di_extents[EFS_DIRECTEXTENTS]; - efs_devs di_dev; /* device for IFCHR/IFBLK */ - } di_u; -}; - -/* efs inode storage in memory */ -struct efs_inode_info { - int numextents; - int lastextent; - - efs_extent extents[EFS_DIRECTEXTENTS]; - struct inode vfs_inode; -}; - -#endif /* __EFS_FS_I_H__ */ - From 8808117ca571fd63e188a2306baae86cca9fce7a Mon Sep 17 00:00:00 2001 From: Eugene Teo Date: Sat, 23 Feb 2008 15:23:52 -0800 Subject: [PATCH 622/880] proc: add RLIMIT_RTTIME to /proc//limits RLIMIT_RTTIME was introduced to allow the user to set a runtime timeout on real-time tasks: http://lkml.org/lkml/2007/12/18/218. This patch updates /proc//limits with the new rlimit. Signed-off-by: Eugene Teo Acked-by: Peter Zijlstra Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/proc/base.c b/fs/proc/base.c index 88f8edf18258..96ee899d6502 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -416,6 +416,7 @@ static const struct limit_names lnames[RLIM_NLIMITS] = { [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"}, [RLIMIT_NICE] = {"Max nice priority", NULL}, [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, + [RLIMIT_RTTIME] = {"Max realtime timeout", "us"}, }; /* Display limits for a process */ From 79306a340c23e40c94ce16e504d172ae15b24187 Mon Sep 17 00:00:00 2001 From: Sergio Luis Date: Sat, 23 Feb 2008 15:23:53 -0800 Subject: [PATCH 623/880] drivers/video/uvesafb.c: fix section mismatch warning in param_set_scroll() Fix following warnings: WARNING: drivers/video/built-in.o(.text+0x7c64a): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/video/built-in.o(.text+0x7c65d): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/video/built-in.o(.text+0x7c679): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/video/built-in.o(.text+0x7c699): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/video/built-in.o(.text+0x7c69f): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/built-in.o(.text+0xa3676): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/built-in.o(.text+0xa3689): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/built-in.o(.text+0xa36a5): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/built-in.o(.text+0xa36c5): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: drivers/built-in.o(.text+0xa36cb): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: vmlinux.o(.text+0x4a079a): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: vmlinux.o(.text+0x4a07ad): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: vmlinux.o(.text+0x4a07c9): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: vmlinux.o(.text+0x4a07e9): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan WARNING: vmlinux.o(.text+0x4a07ef): Section mismatch in reference from the function param_set_scroll() to the variable .devinit.data:ypan Remove __devinitdata annotation from the variable ypan. Signed-off-by: Sergio Luis Cc: Michal Januszewski Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/uvesafb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index be27b9c1ed72..93361656316c 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -44,7 +44,7 @@ static struct fb_fix_screeninfo uvesafb_fix __devinitdata = { static int mtrr __devinitdata = 3; /* enable mtrr by default */ static int blank = 1; /* enable blanking by default */ -static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */ +static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */ static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */ static int nocrtc __devinitdata; /* ignore CRTC settings */ static int noedid __devinitdata; /* don't try DDC transfers */ From 43fe105a5c91b2f00ea7f900ed307fe980410612 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 23 Feb 2008 15:23:55 -0800 Subject: [PATCH 624/880] dmi: prevent linked list corruption Adding the same item to a given linked list more than once is guaranteed to break and corrupt the list. This is however what we do in dmi_scan since commit 79da4721117fcf188b4b007b775738a530f574da ("x86: fix DMI out of memory problems"). Given that there is absolutely no interest in saving empty OEM strings anyway, I propose the simple and efficient fix below: we discard the empty OEM strings altogether. Signed-off-by: Jean Delvare Acked-by: Parag Warudkar Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Matt Domsch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/dmi_scan.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index de3027521bfa..4072449ad1cd 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -217,10 +217,6 @@ static void __init dmi_save_devices(const struct dmi_header *dm) } } -static struct dmi_device empty_oem_string_dev = { - .name = dmi_empty_string, -}; - static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm) { int i, count = *(u8 *)(dm + 1); @@ -229,10 +225,8 @@ static void __init dmi_save_oem_strings_devices(const struct dmi_header *dm) for (i = 1; i <= count; i++) { char *devname = dmi_string(dm, i); - if (!strcmp(devname, dmi_empty_string)) { - list_add(&empty_oem_string_dev.list, &dmi_devices); + if (devname == dmi_empty_string) continue; - } dev = dmi_alloc(sizeof(*dev)); if (!dev) { From 3e4ab747efa8e78562ec6782b08bbf21a00aba1b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Feb 2008 15:23:55 -0800 Subject: [PATCH 625/880] futex: fix init order When the futex init code fails to initialize the futex pseudo file system it returns early without initializing the hash queues. Should the boot succeed then a futex syscall which tries to enqueue a waiter on the hashqueue will crash due to the unitilialized plist heads. Initialize the hash queues before the filesystem. Signed-off-by: Thomas Gleixner Acked-by: Ingo Molnar Cc: Lennert Buytenhek Cc: Riku Voipio Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/futex.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 221f2128a437..c21f667c63f6 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -2145,8 +2145,14 @@ static struct file_system_type futex_fs_type = { static int __init init(void) { - int i = register_filesystem(&futex_fs_type); + int i; + for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { + plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock); + spin_lock_init(&futex_queues[i].lock); + } + + i = register_filesystem(&futex_fs_type); if (i) return i; @@ -2156,10 +2162,6 @@ static int __init init(void) return PTR_ERR(futex_mnt); } - for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { - plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock); - spin_lock_init(&futex_queues[i].lock); - } return 0; } __initcall(init); From a0c1e9073ef7428a14309cba010633a6cd6719ea Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Feb 2008 15:23:57 -0800 Subject: [PATCH 626/880] futex: runtime enable pi and robust functionality Not all architectures implement futex_atomic_cmpxchg_inatomic(). The default implementation returns -ENOSYS, which is currently not handled inside of the futex guts. Futex PI calls and robust list exits with a held futex result in an endless loop in the futex code on architectures which have no support. Fixing up every place where futex_atomic_cmpxchg_inatomic() is called would add a fair amount of extra if/else constructs to the already complex code. It is also not possible to disable the robust feature before user space tries to register robust lists. Compile time disabling is not a good idea either, as there are already architectures with runtime detection of futex_atomic_cmpxchg_inatomic support. Detect the functionality at runtime instead by calling cmpxchg_futex_value_locked() with a NULL pointer from the futex initialization code. This is guaranteed to fail, but the call of futex_atomic_cmpxchg_inatomic() happens with pagefaults disabled. On architectures, which use the asm-generic implementation or have a runtime CPU feature detection, a -ENOSYS return value disables the PI/robust features. On architectures with a working implementation the call returns -EFAULT and the PI/robust features are enabled. The relevant syscalls return -ENOSYS and the robust list exit code is blocked, when the detection fails. Fixes http://lkml.org/lkml/2008/2/11/149 Originally reported by: Lennart Buytenhek Signed-off-by: Thomas Gleixner Acked-by: Ingo Molnar Cc: Lennert Buytenhek Cc: Riku Voipio Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/futex.h | 1 + kernel/futex.c | 38 ++++++++++++++++++++++++++++++++++---- kernel/futex_compat.c | 9 +++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/include/linux/futex.h b/include/linux/futex.h index 90048fb28a38..586ab56a3ec3 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -167,6 +167,7 @@ union futex_key { #ifdef CONFIG_FUTEX extern void exit_robust_list(struct task_struct *curr); extern void exit_pi_state_list(struct task_struct *curr); +extern int futex_cmpxchg_enabled; #else static inline void exit_robust_list(struct task_struct *curr) { diff --git a/kernel/futex.c b/kernel/futex.c index c21f667c63f6..06968cd79200 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -60,6 +60,8 @@ #include "rtmutex_common.h" +int __read_mostly futex_cmpxchg_enabled; + #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8) /* @@ -469,6 +471,8 @@ void exit_pi_state_list(struct task_struct *curr) struct futex_hash_bucket *hb; union futex_key key; + if (!futex_cmpxchg_enabled) + return; /* * We are a ZOMBIE and nobody can enqueue itself on * pi_state_list anymore, but we have to be careful @@ -1870,6 +1874,8 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, size_t len) { + if (!futex_cmpxchg_enabled) + return -ENOSYS; /* * The kernel knows only one size for now: */ @@ -1894,6 +1900,9 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr, struct robust_list_head __user *head; unsigned long ret; + if (!futex_cmpxchg_enabled) + return -ENOSYS; + if (!pid) head = current->robust_list; else { @@ -1997,6 +2006,9 @@ void exit_robust_list(struct task_struct *curr) unsigned long futex_offset; int rc; + if (!futex_cmpxchg_enabled) + return; + /* * Fetch the list head (which was registered earlier, via * sys_set_robust_list()): @@ -2051,7 +2063,7 @@ void exit_robust_list(struct task_struct *curr) long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3) { - int ret; + int ret = -ENOSYS; int cmd = op & FUTEX_CMD_MASK; struct rw_semaphore *fshared = NULL; @@ -2083,13 +2095,16 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3); break; case FUTEX_LOCK_PI: - ret = futex_lock_pi(uaddr, fshared, val, timeout, 0); + if (futex_cmpxchg_enabled) + ret = futex_lock_pi(uaddr, fshared, val, timeout, 0); break; case FUTEX_UNLOCK_PI: - ret = futex_unlock_pi(uaddr, fshared); + if (futex_cmpxchg_enabled) + ret = futex_unlock_pi(uaddr, fshared); break; case FUTEX_TRYLOCK_PI: - ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1); + if (futex_cmpxchg_enabled) + ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1); break; default: ret = -ENOSYS; @@ -2145,8 +2160,23 @@ static struct file_system_type futex_fs_type = { static int __init init(void) { + u32 curval; int i; + /* + * This will fail and we want it. Some arch implementations do + * runtime detection of the futex_atomic_cmpxchg_inatomic() + * functionality. We want to know that before we call in any + * of the complex code paths. Also we want to prevent + * registration of robust lists in that case. NULL is + * guaranteed to fault and we get -EFAULT on functional + * implementation, the non functional ones will return + * -ENOSYS. + */ + curval = cmpxchg_futex_value_locked(NULL, 0, 0); + if (curval == -EFAULT) + futex_cmpxchg_enabled = 1; + for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock); spin_lock_init(&futex_queues[i].lock); diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c index 7d5e4b016f39..ff90f049f8f6 100644 --- a/kernel/futex_compat.c +++ b/kernel/futex_compat.c @@ -54,6 +54,9 @@ void compat_exit_robust_list(struct task_struct *curr) compat_long_t futex_offset; int rc; + if (!futex_cmpxchg_enabled) + return; + /* * Fetch the list head (which was registered earlier, via * sys_set_robust_list()): @@ -115,6 +118,9 @@ asmlinkage long compat_sys_set_robust_list(struct compat_robust_list_head __user *head, compat_size_t len) { + if (!futex_cmpxchg_enabled) + return -ENOSYS; + if (unlikely(len != sizeof(*head))) return -EINVAL; @@ -130,6 +136,9 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, struct compat_robust_list_head __user *head; unsigned long ret; + if (!futex_cmpxchg_enabled) + return -ENOSYS; + if (!pid) head = current->compat_robust_list; else { From 45d464eb67a1ad03e909ae1868e7ecfcb696c57f Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sat, 23 Feb 2008 15:23:58 -0800 Subject: [PATCH 627/880] h8300: signal.c typo fix typo fix. Signed-off-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/kernel/signal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index 62ea12d339b9..cf3472f7389b 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c @@ -352,7 +352,7 @@ static void setup_frame (int sig, struct k_sigaction *ka, ret = (unsigned char *)(ka->sa.sa_restorer); else { /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ - err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), + err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), (unsigned long *)(frame->retcode + 0)); err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); } @@ -428,7 +428,7 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, ret = (unsigned char *)(ka->sa.sa_restorer); else { /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */ - err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), + err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff), (unsigned long *)(frame->retcode + 0)); err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4)); } From 4223cc34365e46f5e50d5496623367c552cd8a51 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sat, 23 Feb 2008 15:23:59 -0800 Subject: [PATCH 628/880] h8300: uaccess.h update get_user const *ptr access fix. Signed-off-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-h8300/uaccess.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-h8300/uaccess.h b/include/asm-h8300/uaccess.h index ebe58c6c8387..a22350ec271a 100644 --- a/include/asm-h8300/uaccess.h +++ b/include/asm-h8300/uaccess.h @@ -91,7 +91,7 @@ extern int __put_user_bad(void); #define get_user(x, ptr) \ ({ \ int __gu_err = 0; \ - typeof(*(ptr)) __gu_val = 0; \ + uint32_t __gu_val = 0; \ switch (sizeof(*(ptr))) { \ case 1: \ case 2: \ @@ -106,7 +106,7 @@ extern int __put_user_bad(void); __gu_err = __get_user_bad(); \ break; \ } \ - (x) = __gu_val; \ + (x) = (typeof(*(ptr)))__gu_val; \ __gu_err; \ }) #define __get_user(x, ptr) get_user(x, ptr) From 5cc265a5de169d8e61ad5ba009610467e158fcec Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sat, 23 Feb 2008 15:23:59 -0800 Subject: [PATCH 629/880] h8300: IRQ handling update - add missing file and declare. - remove unused file and macros. - some cleanup. Signed-off-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/kernel/irq.c | 4 +- arch/h8300/platform/h8300h/Makefile | 2 +- arch/h8300/platform/h8300h/irq.c | 82 +++++ arch/h8300/platform/h8s/ints.c | 304 ------------------ arch/h8300/platform/h8s/{ints_h8s.c => irq.c} | 8 +- include/asm-h8300/hardirq.h | 2 + include/asm-h8300/irq.h | 19 +- 7 files changed, 94 insertions(+), 327 deletions(-) create mode 100644 arch/h8300/platform/h8300h/irq.c delete mode 100644 arch/h8300/platform/h8s/ints.c rename arch/h8300/platform/h8s/{ints_h8s.c => irq.c} (95%) diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c index 5a1b4cfea05b..ef4f0047067d 100644 --- a/arch/h8300/kernel/irq.c +++ b/arch/h8300/kernel/irq.c @@ -26,7 +26,7 @@ extern unsigned long *interrupt_redirect_table; extern const int h8300_saved_vectors[]; -extern const unsigned long h8300_trap_table[]; +extern const h8300_vector h8300_trap_table[]; int h8300_enable_irq_pin(unsigned int irq); void h8300_disable_irq_pin(unsigned int irq); @@ -116,7 +116,7 @@ static void __init setup_vector(void) { int i; unsigned long *ramvec,*ramvec_p; - const unsigned long *trap_entry; + const h8300_vector *trap_entry; const int *saved_vector; ramvec = get_vector_address(); diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile index c5096369ea50..420f73b0d962 100644 --- a/arch/h8300/platform/h8300h/Makefile +++ b/arch/h8300/platform/h8300h/Makefile @@ -4,4 +4,4 @@ # Reuse any files we can from the H8/300H # -obj-y := irq_pin.o ptrace_h8300h.o +obj-y := irq.o ptrace_h8300h.o diff --git a/arch/h8300/platform/h8300h/irq.c b/arch/h8300/platform/h8300h/irq.c new file mode 100644 index 000000000000..e977345105d7 --- /dev/null +++ b/arch/h8300/platform/h8300h/irq.c @@ -0,0 +1,82 @@ +/* + * Interrupt handling H8/300H depend. + * Yoshinori Sato + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +const int __initdata h8300_saved_vectors[] = { +#if defined(CONFIG_GDB_DEBUG) + TRAP3_VEC, /* TRAPA #3 is GDB breakpoint */ +#endif + -1, +}; + +const h8300_vector __initdata h8300_trap_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + system_call, + 0, + 0, + trace_break, +}; + +int h8300_enable_irq_pin(unsigned int irq) +{ + int bitmask; + if (irq < EXT_IRQ0 || irq > EXT_IRQ5) + return 0; + + /* initialize IRQ pin */ + bitmask = 1 << (irq - EXT_IRQ0); + switch(irq) { + case EXT_IRQ0: + case EXT_IRQ1: + case EXT_IRQ2: + case EXT_IRQ3: + if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0) + return -EBUSY; + H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT); + break; + case EXT_IRQ4: + case EXT_IRQ5: + if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0) + return -EBUSY; + H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT); + break; + } + + return 0; +} + +void h8300_disable_irq_pin(unsigned int irq) +{ + int bitmask; + if (irq < EXT_IRQ0 || irq > EXT_IRQ5) + return; + + /* disable interrupt & release IRQ pin */ + bitmask = 1 << (irq - EXT_IRQ0); + switch(irq) { + case EXT_IRQ0: + case EXT_IRQ1: + case EXT_IRQ2: + case EXT_IRQ3: + *(volatile unsigned char *)IER &= ~bitmask; + H8300_GPIO_FREE(H8300_GPIO_P8, bitmask); + break ; + case EXT_IRQ4: + case EXT_IRQ5: + *(volatile unsigned char *)IER &= ~bitmask; + H8300_GPIO_FREE(H8300_GPIO_P9, bitmask); + break; + } +} diff --git a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c deleted file mode 100644 index ac10b9783850..000000000000 --- a/arch/h8300/platform/h8s/ints.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * linux/arch/h8300/platform/h8s/ints.c - * - * Yoshinori Sato - * - * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * - * Copyright 1996 Roman Zippel - * Copyright 1999 D. Jeff Dionne - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This structure has only 4 elements for speed reasons - */ -typedef struct irq_handler { - irqreturn_t (*handler)(int, void *, struct pt_regs *); - int flags; - int count; - void *dev_id; - const char *devname; -} irq_handler_t; - -static irq_handler_t *irq_list[NR_IRQS]; - -/* IRQ pin assignment */ -struct irq_pins { - unsigned char port_no; - unsigned char bit_no; -}; -/* ISTR = 0 */ -static const struct irq_pins irq_assign_table0[16]={ - {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1}, - {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3}, - {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5}, - {H8300_GPIO_P5,H8300_GPIO_B6},{H8300_GPIO_P5,H8300_GPIO_B7}, - {H8300_GPIO_P6,H8300_GPIO_B0},{H8300_GPIO_P6,H8300_GPIO_B1}, - {H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3}, - {H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5}, - {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2}, -}; -/* ISTR = 1 */ -static const struct irq_pins irq_assign_table1[16]={ - {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1}, - {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3}, - {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5}, - {H8300_GPIO_PH,H8300_GPIO_B2},{H8300_GPIO_PH,H8300_GPIO_B3}, - {H8300_GPIO_P2,H8300_GPIO_B0},{H8300_GPIO_P2,H8300_GPIO_B1}, - {H8300_GPIO_P2,H8300_GPIO_B2},{H8300_GPIO_P2,H8300_GPIO_B3}, - {H8300_GPIO_P2,H8300_GPIO_B4},{H8300_GPIO_P2,H8300_GPIO_B5}, - {H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7}, -}; - -static short use_kmalloc = 0; - -extern unsigned long *interrupt_redirect_table; - -#define CPU_VECTOR ((unsigned long *)0x000000) -#define ADDR_MASK (0xffffff) - -static inline unsigned long *get_vector_address(void) -{ - volatile unsigned long *rom_vector = CPU_VECTOR; - unsigned long base,tmp; - int vec_no; - - base = rom_vector[EXT_IRQ0] & ADDR_MASK; - - /* check romvector format */ - for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ15; vec_no++) { - if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK)) - return NULL; - } - - /* ramvector base address */ - base -= EXT_IRQ0*4; - - /* writerble check */ - tmp = ~(*(unsigned long *)base); - (*(unsigned long *)base) = tmp; - if ((*(unsigned long *)base) != tmp) - return NULL; - return (unsigned long *)base; -} - -void __init init_IRQ(void) -{ -#if defined(CONFIG_RAMKERNEL) - int i; - unsigned long *ramvec,*ramvec_p; - unsigned long break_vec; - - ramvec = get_vector_address(); - if (ramvec == NULL) - panic("interrupt vector serup failed."); - else - printk("virtual vector at 0x%08lx\n",(unsigned long)ramvec); - -#if defined(CONFIG_GDB_DEBUG) - /* save original break vector */ - break_vec = ramvec[TRAP3_VEC]; -#else - break_vec = VECTOR(trace_break); -#endif - - /* create redirect table */ - for (ramvec_p = ramvec, i = 0; i < NR_IRQS; i++) - *ramvec_p++ = REDIRECT(interrupt_entry); - - /* set special vector */ - ramvec[TRAP0_VEC] = VECTOR(system_call); - ramvec[TRAP3_VEC] = break_vec; - interrupt_redirect_table = ramvec; -#ifdef DUMP_VECTOR - ramvec_p = ramvec; - for (i = 0; i < NR_IRQS; i++) { - if ((i % 8) == 0) - printk("\n%p: ",ramvec_p); - printk("%p ",*ramvec_p); - ramvec_p++; - } - printk("\n"); -#endif -#endif -} - -int request_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long flags, const char *devname, void *dev_id) -{ - unsigned short ptn = 1 << (irq - EXT_IRQ0); - irq_handler_t *irq_handle; - if (irq < 0 || irq >= NR_IRQS) { - printk("Incorrect IRQ %d from %s\n", irq, devname); - return -EINVAL; - } - if (irq_list[irq]) - return -EBUSY; /* already used */ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) { - /* initialize IRQ pin */ - unsigned int port_no,bit_no; - if (*(volatile unsigned short *)ITSR & ptn) { - port_no = irq_assign_table1[irq - EXT_IRQ0].port_no; - bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no; - } else { - port_no = irq_assign_table0[irq - EXT_IRQ0].port_no; - bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no; - } - if (H8300_GPIO_RESERVE(port_no, bit_no) == 0) - return -EBUSY; /* pin already use */ - H8300_GPIO_DDR(port_no, bit_no, H8300_GPIO_INPUT); - *(volatile unsigned short *)ISR &= ~ptn; /* ISR clear */ - } - - if (use_kmalloc) - irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC); - else { - /* use bootmem allocator */ - irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t)); - irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000); - } - - if (irq_handle == NULL) - return -ENOMEM; - - irq_handle->handler = handler; - irq_handle->flags = flags; - irq_handle->count = 0; - irq_handle->dev_id = dev_id; - irq_handle->devname = devname; - irq_list[irq] = irq_handle; - if (irq_handle->flags & IRQF_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - /* enable interrupt */ - /* compatible i386 */ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) - *(volatile unsigned short *)IER |= ptn; - return 0; -} - -EXPORT_SYMBOL(request_irq); - -void free_irq(unsigned int irq, void *dev_id) -{ - if (irq >= NR_IRQS) - return; - if (irq_list[irq]->dev_id != dev_id) - printk("%s: Removing probably wrong IRQ %d from %s\n", - __FUNCTION__, irq, irq_list[irq]->devname); - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) { - /* disable interrupt & release IRQ pin */ - unsigned short port_no,bit_no; - *(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0)); - *(volatile unsigned short *)IER |= 1 << (irq - EXT_IRQ0); - if (*(volatile unsigned short *)ITSR & (1 << (irq - EXT_IRQ0))) { - port_no = irq_assign_table1[irq - EXT_IRQ0].port_no; - bit_no = irq_assign_table1[irq - EXT_IRQ0].bit_no; - } else { - port_no = irq_assign_table0[irq - EXT_IRQ0].port_no; - bit_no = irq_assign_table0[irq - EXT_IRQ0].bit_no; - } - H8300_GPIO_FREE(port_no, bit_no); - } - if (((unsigned long)irq_list[irq] & 0x80000000) == 0) { - kfree(irq_list[irq]); - irq_list[irq] = NULL; - } -} - -EXPORT_SYMBOL(free_irq); - -unsigned long probe_irq_on (void) -{ - return 0; -} - -EXPORT_SYMBOL(probe_irq_on); - -int probe_irq_off (unsigned long irqs) -{ - return 0; -} - -EXPORT_SYMBOL(probe_irq_off); - -void enable_irq(unsigned int irq) -{ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) - *(volatile unsigned short *)IER |= 1 << (irq - EXT_IRQ0); -} - -void disable_irq(unsigned int irq) -{ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) - *(volatile unsigned short *)IER &= ~(1 << (irq - EXT_IRQ0)); -} - -asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) -{ - irq_enter(); - /* ISR clear */ - /* compatible i386 */ - if (vec >= EXT_IRQ0 && vec <= EXT_IRQ15) - *(volatile unsigned short *)ISR &= ~(1 << (vec - EXT_IRQ0)); - if (vec < NR_IRQS) { - if (irq_list[vec]) { - irq_list[vec]->handler(vec, irq_list[vec]->dev_id, fp); - irq_list[vec]->count++; - if (irq_list[vec]->flags & IRQF_SAMPLE_RANDOM) - add_interrupt_randomness(vec); - } - } else { - BUG(); - } - irq_exit(); -} - -int show_interrupts(struct seq_file *p, void *v) -{ - int i = *(loff_t *) v; - - if ((i < NR_IRQS) && (irq_list[i] !=NULL)) { - seq_printf(p, "%3d: %10u ",i,irq_list[i]->count); - seq_printf(p, "%s\n", irq_list[i]->devname); - } - - return 0; -} - -void init_irq_proc(void) -{ -} - -static int __init enable_kmalloc(void) -{ - use_kmalloc = 1; - return 0; -} -core_initcall(enable_kmalloc); diff --git a/arch/h8300/platform/h8s/ints_h8s.c b/arch/h8300/platform/h8s/irq.c similarity index 95% rename from arch/h8300/platform/h8s/ints_h8s.c rename to arch/h8300/platform/h8s/irq.c index faa8a459d952..8182f041f829 100644 --- a/arch/h8300/platform/h8s/ints_h8s.c +++ b/arch/h8300/platform/h8s/irq.c @@ -27,11 +27,11 @@ const int __initdata h8300_saved_vectors[]={ }; /* trap entry table */ -const unsigned long __initdata h8300_trap_table[NR_TRAPS]={ +const H8300_VECTOR __initdata h8300_trap_table[] = { 0,0,0,0,0, - (unsigned long)trace_break, /* TRACE */ + trace_break, /* TRACE */ 0,0, - (unsigned long)system_call, /* TRAPA #0 */ + system_call, /* TRAPA #0 */ 0,0,0,0,0,0,0 }; @@ -50,7 +50,7 @@ static const struct irq_pins irq_assign_table0[16]={ {H8300_GPIO_P6,H8300_GPIO_B2},{H8300_GPIO_P6,H8300_GPIO_B3}, {H8300_GPIO_P6,H8300_GPIO_B4},{H8300_GPIO_P6,H8300_GPIO_B5}, {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2}, -}; +}; /* ISTR = 1 */ static const struct irq_pins irq_assign_table1[16]={ {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1}, diff --git a/include/asm-h8300/hardirq.h b/include/asm-h8300/hardirq.h index 18fa7931e09f..9d7f7a7462b2 100644 --- a/include/asm-h8300/hardirq.h +++ b/include/asm-h8300/hardirq.h @@ -12,6 +12,8 @@ typedef struct { #include /* Standard mappings for irq_cpustat_t above */ +extern void ack_bad_irq(unsigned int irq); + #define HARDIRQ_BITS 8 /* diff --git a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h index 56eec28cc2c4..13d7c601cd0a 100644 --- a/include/asm-h8300/irq.h +++ b/include/asm-h8300/irq.h @@ -3,7 +3,7 @@ #include -#if defined(__H8300H__) +#if defined(CONFIG_CPU_H8300H) #define NR_IRQS 64 #define EXT_IRQ0 12 #define EXT_IRQ1 13 @@ -14,14 +14,6 @@ #define EXT_IRQ6 18 #define EXT_IRQ7 19 #define EXT_IRQS 5 - -#include -#define h8300_clear_isr(irq) \ -do { \ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ5) \ - *(volatile unsigned char *)ISR &= ~(1 << (irq - EXT_IRQ0)); \ -} while(0) - #define IER_REGS *(volatile unsigned char *)IER #endif #if defined(CONFIG_CPU_H8S) @@ -44,13 +36,6 @@ do { \ #define EXT_IRQ15 31 #define EXT_IRQS 15 -#include -#define h8300_clear_isr(irq) \ -do { \ - if (irq >= EXT_IRQ0 && irq <= EXT_IRQ15) \ - *(volatile unsigned short *)ISR &= ~(1 << (irq - EXT_IRQ0)); \ -} while(0) - #define IER_REGS *(volatile unsigned short *)IER #endif @@ -59,4 +44,6 @@ static __inline__ int irq_canonicalize(int irq) return irq; } +typedef void (*h8300_vector)(void); + #endif /* _H8300_IRQ_H_ */ From ff10e5dc1781cd0121f8ee936234c222ff15c105 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sat, 23 Feb 2008 15:24:00 -0800 Subject: [PATCH 630/880] h8300: defconfig update defconfig update. Signed-off-by: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/defconfig | 263 +++++++++++++++++++++++-------------------- 1 file changed, 140 insertions(+), 123 deletions(-) diff --git a/arch/h8300/defconfig b/arch/h8300/defconfig index 8f1ec3297150..8901cdb5e75b 100644 --- a/arch/h8300/defconfig +++ b/arch/h8300/defconfig @@ -1,51 +1,98 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc1 -# Sun Jan 16 17:24:38 2005 +# Linux kernel version: 2.6.25-rc1 +# Fri Feb 15 17:13:14 2008 # CONFIG_H8300=y # CONFIG_MMU is not set # CONFIG_SWAP is not set +CONFIG_ZONE_DMA=y # CONFIG_FPU is not set -CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_TIME_LOW_RES=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_NO_IOPORT=y +CONFIG_NO_DMA=y CONFIG_ISA=y # CONFIG_PCI is not set +CONFIG_HZ=100 +CONFIG_C_SYMBOL_PREFIX=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# +CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SYSVIPC is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set -# CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_HOTPLUG is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y CONFIG_EMBEDDED=y +# CONFIG_UID16 is not set +# CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_BASE_FULL is not set # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLAB is not set +# CONFIG_SLUB is not set +CONFIG_SLOB=y +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +# CONFIG_HAVE_OPROFILE is not set +# CONFIG_HAVE_KPROBES is not set CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=1 +# CONFIG_MODULES is not set +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 # -# Loadable module support +# IO Schedulers # -# CONFIG_MODULES is not set +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # Processor type and features @@ -62,14 +109,26 @@ CONFIG_H8300H_GENERIC=y # Detail Selection # # CONFIG_H83002 is not set -# CONFIG_H83007 is not set +CONFIG_H83007=y # CONFIG_H83048 is not set -CONFIG_H83068=y +# CONFIG_H83068 is not set CONFIG_CPU_CLOCK=20000 -# CONFIG_RAMKERNEL is not set -CONFIG_ROMKERNEL=y +CONFIG_RAMKERNEL=y +# CONFIG_ROMKERNEL is not set CONFIG_CPU_H8300H=y # CONFIG_PREEMPT 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 # # Executable file formats @@ -77,34 +136,42 @@ CONFIG_CPU_H8300H=y CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_ZFLAT=y # CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_MISC=y # -# Generic Driver Options +# Networking # -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set +# CONFIG_NET is not set # -# Memory Technology Devices (MTD) +# Generic Driver Options # +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_SYS_HYPERVISOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CONCAT=y -# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set # CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers # CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y +# 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 @@ -129,7 +196,9 @@ CONFIG_MTD_ROM=y # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set CONFIG_MTD_UCLINUX=y +# CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers @@ -137,7 +206,6 @@ CONFIG_MTD_UCLINUX=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -146,63 +214,27 @@ CONFIG_MTD_UCLINUX=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 is not set +# CONFIG_MTD_ONENAND is not set # -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set - -# -# ATA/ATAPI/MFM/RLL support +# UBI - Unsorted block images # +# CONFIG_MTD_UBI is not set +# CONFIG_BLK_DEV is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set -# -# Networking support -# -# CONFIG_NET is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - # # Input device support # # CONFIG_INPUT is not set # -# Userland interfaces -# - -# -# Input I/O drivers +# Hardware I/O ports # -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set - -# -# Input Device Drivers -# +# CONFIG_GAMEPORT is not set # # Character devices @@ -223,45 +255,31 @@ CONFIG_SOUND_GAMEPORT=y # Non-8250 serial port support # CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y - -# -# I2C support -# # CONFIG_I2C is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set # # File systems # # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set -# CONFIG_JBD 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_MINIX_FS is not set -CONFIG_ROMFS_FS=y -# CONFIG_QUOTA is not set +# CONFIG_GFS2_FS is not set # CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA 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 @@ -280,11 +298,11 @@ CONFIG_ROMFS_FS=y # Pseudo filesystems # CONFIG_PROC_FS=y -# CONFIG_SYSFS is not set -# CONFIG_DEVFS_FS is not set +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 # # Miscellaneous filesystems @@ -296,12 +314,13 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS 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_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set @@ -310,22 +329,23 @@ CONFIG_RAMFS=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set # # Kernel hacking # -CONFIG_DEBUG_KERNEL=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set -CONFIG_FULLDEBUG=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SAMPLES is not set +# CONFIG_FULLDEBUG is not set # CONFIG_HIGHPROFILE is not set -CONFIG_NO_KERNEL_MSG=y +# CONFIG_NO_KERNEL_MSG is not set # CONFIG_SYSCALL_PRINT is not set # CONFIG_GDB_DEBUG is not set # CONFIG_SH_STANDARD_BIOS is not set @@ -337,20 +357,17 @@ CONFIG_NO_KERNEL_MSG=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# +# CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set -# -# Hardware crypto devices -# - # # Library routines # # CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y +CONFIG_HAS_IOMEM=y From 00d6296145c6b671a9886e380efc24f2731d856a Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Sat, 23 Feb 2008 15:24:01 -0800 Subject: [PATCH 631/880] kernel-doc: fix function-pointer-parameter parsing When running "make htmldocs" I'm seeing some non-fatal perl errors caused by trying to parse the callback function definitions in blk-core.c. The errors are "Use of uninitialized value in concatenation (.)..." in combination with: Warning(linux-2.6.25-rc2/block/blk-core.c:1877): No description found for parameter '' The function pointers are defined without a * i.e. int (drv_callback)(struct request *) The compiler is happy with them, but kernel-doc isn't. This patch teaches create_parameterlist in kernel-doc to parse this type of function pointer definition, but is it the right way to fix the problem ? The problem only seems to occur in blk-core.c. However with the patch applied, kernel-doc finds the correct parameter description for the callback in blk_end_request_callback, which is doesn't normally. I thought it would be a bit odd to change to code to use the more normal form of function pointers just to get the documentation to work, so I fixed kernel-doc instead - even though this is teaching it to understand code that might go away (The comment for blk_end_request_callback says that it should not be used and will removed at some point). Signed-off-by: Richard Kennedy Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/kernel-doc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 26146cbaa504..74c2f9db2aac 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1512,13 +1512,13 @@ sub create_parameterlist($$$) { # corresponding data structures "correctly". Catch it later in # output_* subs. push_parameter($arg, "", $file); - } elsif ($arg =~ m/\(.*\*/) { + } elsif ($arg =~ m/\(.+\)\s*\(/) { # pointer-to-function $arg =~ tr/#/,/; - $arg =~ m/[^\(]+\(\*\s*([^\)]+)\)/; + $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/; $param = $1; $type = $arg; - $type =~ s/([^\(]+\(\*)$param/$1/; + $type =~ s/([^\(]+\(\*?)\s*$param/$1/; push_parameter($param, $type, $file); } elsif ($arg) { $arg =~ s/\s*:\s*/:/g; From 0835ab53eab5bbeebe1c135e92fb0c4d483dde17 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 23 Feb 2008 15:24:02 -0800 Subject: [PATCH 632/880] cgroup memory controller: document huge memory/cache overhead in Kconfig Document huge memory/cache overhead of memory controller in Kconfig I was a little surprised that 2.6.25-rc* increased struct page for the memory controller. At least on many x86-64 machines it will not fit into a single cache line now anymore and also costs considerable amounts of RAM. At earlier review I remembered asking for a external data structure for this. It's also quite unobvious that a innocent looking Kconfig option with a single line Kconfig description has such a negative effect. This patch attempts to document these disadvantages at least so that users configuring their kernel can make a informed decision. Signed-off-by: Andi Kleen Cc: Balbir Singh Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/init/Kconfig b/init/Kconfig index dcef8b55011a..f698a5af5007 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -394,6 +394,14 @@ config CGROUP_MEM_CONT Provides a memory controller that manages both page cache and RSS memory. + Note that setting this option increases fixed memory overhead + associated with each page of memory in the system by 4/8 bytes + and also increases cache misses because struct page on many 64bit + systems will not fit into a single cache line anymore. + + Only enable when you're ok with these trade offs and really + sure you need the memory controller. + config PROC_PID_CPUSET bool "Include legacy /proc//cpuset file" depends on CPUSETS From 43627582799db317e966ecb0002c2c3c9805ec0f Mon Sep 17 00:00:00 2001 From: Srinivasa Ds Date: Sat, 23 Feb 2008 15:24:04 -0800 Subject: [PATCH 633/880] kprobes: refuse kprobe insertion on add/sub_preempt_counter() Kprobes makes use of preempt_disable(),preempt_enable_noresched() and these functions inturn call add/sub_preempt_count(). So we need to refuse user from inserting probe in to these functions. This patch disallows user from probing add/sub_preempt_count(). Signed-off-by: Srinivasa DS Acked-by: Ananth N Mavinakayanahalli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index f28f19e65b59..c4bc8c210958 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3766,7 +3766,7 @@ void scheduler_tick(void) #if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT) -void add_preempt_count(int val) +void __kprobes add_preempt_count(int val) { /* * Underflow? @@ -3782,7 +3782,7 @@ void add_preempt_count(int val) } EXPORT_SYMBOL(add_preempt_count); -void sub_preempt_count(int val) +void __kprobes sub_preempt_count(int val) { /* * Underflow? From bcdca225bfa016100985e5fc7e51cdc1d68beaa6 Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Sat, 23 Feb 2008 15:24:04 -0800 Subject: [PATCH 634/880] Smack: update for file capabilities Update the Smack LSM to allow the registration of the capability "module" as a secondary LSM. Integrate the new hooks required for file based capabilities. Signed-off-by: Casey Schaufler Cc: Serge Hallyn Cc: Stephen Smalley Cc: Paul Moore Cc: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/smack/smack_lsm.c | 87 ++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 25cbfa3f71f4..770eb067e165 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -584,14 +584,20 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) static int smack_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) { - if (!capable(CAP_MAC_ADMIN)) { - if (strcmp(name, XATTR_NAME_SMACK) == 0 || - strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || - strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) - return -EPERM; - } + int rc = 0; - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + if (strcmp(name, XATTR_NAME_SMACK) == 0 || + strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + if (!capable(CAP_MAC_ADMIN)) + rc = -EPERM; + } else + rc = cap_inode_setxattr(dentry, name, value, size, flags); + + if (rc == 0) + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + + return rc; } /** @@ -658,10 +664,20 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name) */ static int smack_inode_removexattr(struct dentry *dentry, char *name) { - if (strcmp(name, XATTR_NAME_SMACK) == 0 && !capable(CAP_MAC_ADMIN)) - return -EPERM; + int rc = 0; - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + if (strcmp(name, XATTR_NAME_SMACK) == 0 || + strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + if (!capable(CAP_MAC_ADMIN)) + rc = -EPERM; + } else + rc = cap_inode_removexattr(dentry, name); + + if (rc == 0) + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + + return rc; } /** @@ -1016,7 +1032,12 @@ static void smack_task_getsecid(struct task_struct *p, u32 *secid) */ static int smack_task_setnice(struct task_struct *p, int nice) { - return smk_curacc(p->security, MAY_WRITE); + int rc; + + rc = cap_task_setnice(p, nice); + if (rc == 0) + rc = smk_curacc(p->security, MAY_WRITE); + return rc; } /** @@ -1028,7 +1049,12 @@ static int smack_task_setnice(struct task_struct *p, int nice) */ static int smack_task_setioprio(struct task_struct *p, int ioprio) { - return smk_curacc(p->security, MAY_WRITE); + int rc; + + rc = cap_task_setioprio(p, ioprio); + if (rc == 0) + rc = smk_curacc(p->security, MAY_WRITE); + return rc; } /** @@ -1053,7 +1079,12 @@ static int smack_task_getioprio(struct task_struct *p) static int smack_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) { - return smk_curacc(p->security, MAY_WRITE); + int rc; + + rc = cap_task_setscheduler(p, policy, lp); + if (rc == 0) + rc = smk_curacc(p->security, MAY_WRITE); + return rc; } /** @@ -1093,6 +1124,11 @@ static int smack_task_movememory(struct task_struct *p) static int smack_task_kill(struct task_struct *p, struct siginfo *info, int sig, u32 secid) { + int rc; + + rc = cap_task_kill(p, info, sig, secid); + if (rc != 0) + return rc; /* * Special cases where signals really ought to go through * in spite of policy. Stephen Smalley suggests it may @@ -1778,6 +1814,27 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) return smk_curacc(isp, may); } +/* module stacking operations */ + +/** + * smack_register_security - stack capability module + * @name: module name + * @ops: module operations - ignored + * + * Allow the capability module to register. + */ +static int smack_register_security(const char *name, + struct security_operations *ops) +{ + if (strcmp(name, "capability") != 0) + return -EINVAL; + + printk(KERN_INFO "%s: Registering secondary module %s\n", + __func__, name); + + return 0; +} + /** * smack_d_instantiate - Make sure the blob is correct on an inode * @opt_dentry: unused @@ -2412,6 +2469,8 @@ static struct security_operations smack_ops = { .inode_post_setxattr = smack_inode_post_setxattr, .inode_getxattr = smack_inode_getxattr, .inode_removexattr = smack_inode_removexattr, + .inode_need_killpriv = cap_inode_need_killpriv, + .inode_killpriv = cap_inode_killpriv, .inode_getsecurity = smack_inode_getsecurity, .inode_setsecurity = smack_inode_setsecurity, .inode_listsecurity = smack_inode_listsecurity, @@ -2471,6 +2530,8 @@ static struct security_operations smack_ops = { .netlink_send = cap_netlink_send, .netlink_recv = cap_netlink_recv, + .register_security = smack_register_security, + .d_instantiate = smack_d_instantiate, .getprocattr = smack_getprocattr, From b5a0e011329431b90d315eaf6ca5fdb41df7a117 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Sat, 23 Feb 2008 15:24:06 -0800 Subject: [PATCH 635/880] Solve section mismatch for free_area_init_core. WARNING: vmlinux.o(.meminit.text+0x649): Section mismatch in reference from the function free_area_init_core() to the function .init.text:setup_usemap() The function __meminit free_area_init_core() references a function __init setup_usemap(). If free_area_init_core is only used by setup_usemap then annotate free_area_init_core with a matching annotation. The warning is covers this stack of functions in mm/page_alloc.c: alloc_bootmem_node must be marked __init. alloc_bootmem_node is used by setup_usemap, if !SPARSEMEM. (usemap_size is only used by setup_usemap, if !SPARSEMEM.) setup_usemap is only used by free_area_init_core. free_area_init_core is only used by free_area_init_node. free_area_init_node is used by: arch/alpha/mm/numa.c: __init paging_init() arch/arm/mm/init.c: __init bootmem_init_node() arch/avr32/mm/init.c: __init paging_init() arch/cris/arch-v10/mm/init.c: __init paging_init() arch/cris/arch-v32/mm/init.c: __init paging_init() arch/m32r/mm/discontig.c: __init zone_sizes_init() arch/m32r/mm/init.c: __init zone_sizes_init() arch/m68k/mm/motorola.c: __init paging_init() arch/m68k/mm/sun3mmu.c: __init paging_init() arch/mips/sgi-ip27/ip27-memory.c: __init paging_init() arch/parisc/mm/init.c: __init paging_init() arch/sparc/mm/srmmu.c: __init srmmu_paging_init() arch/sparc/mm/sun4c.c: __init sun4c_paging_init() arch/sparc64/mm/init.c: __init paging_init() mm/page_alloc.c: __init free_area_init_nodes() mm/page_alloc.c: __init free_area_init() and mm/memory_hotplug.c: hotadd_new_pgdat() hotadd_new_pgdat can not be an __init function, but: It is compiled for MEMORY_HOTPLUG configurations only MEMORY_HOTPLUG depends on SPARSEMEM || X86_64_ACPI_NUMA X86_64_ACPI_NUMA depends on X86_64 ARCH_FLATMEM_ENABLE depends on X86_32 ARCH_DISCONTIGMEM_ENABLE depends on X86_32 So X86_64_ACPI_NUMA implies SPARSEMEM, right? So we can mark the stack of functions __init for !SPARSEMEM, but we must mark them __meminit for SPARSEMEM configurations. This is ok, because then the calls to alloc_bootmem_node are also avoided. Compile-tested on: silly minimal config defconfig x86_32 defconfig x86_64 defconfig x86_64 -HIBERNATION +MEMORY_HOTPLUG Signed-off-by: Alexander van Heukelum Reviewed-by: Sam Ravnborg Acked-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/internal.h | 13 +++++++++++++ mm/page_alloc.c | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index 5a9a6200e034..789727309f4d 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -47,4 +47,17 @@ static inline unsigned long page_order(struct page *page) VM_BUG_ON(!PageBuddy(page)); return page_private(page); } + +/* + * FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node, + * so all functions starting at paging_init should be marked __init + * in those cases. SPARSEMEM, however, allows for memory hotplug, + * and alloc_bootmem_node is not used. + */ +#ifdef CONFIG_SPARSEMEM +#define __paginginit __meminit +#else +#define __paginginit __init +#endif + #endif diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 75b979313346..8896e874a67d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3314,7 +3314,7 @@ static inline int pageblock_default_order(unsigned int order) * - mark all memory queues empty * - clear the memory bitmaps */ -static void __meminit free_area_init_core(struct pglist_data *pgdat, +static void __paginginit free_area_init_core(struct pglist_data *pgdat, unsigned long *zones_size, unsigned long *zholes_size) { enum zone_type j; @@ -3438,7 +3438,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) #endif /* CONFIG_FLAT_NODE_MEM_MAP */ } -void __meminit free_area_init_node(int nid, struct pglist_data *pgdat, +void __paginginit free_area_init_node(int nid, struct pglist_data *pgdat, unsigned long *zones_size, unsigned long node_start_pfn, unsigned long *zholes_size) { From d19e0583300da82a6e27cd2116f558048502edaa Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:08 -0800 Subject: [PATCH 636/880] cgroup: fix and update documentation Misc fixes and updates, make the doc consistent with current cgroup implementation. Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups.txt | 66 +++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt index 42d7c4cb39cd..31d12e21ff8a 100644 --- a/Documentation/cgroups.txt +++ b/Documentation/cgroups.txt @@ -28,7 +28,7 @@ CONTENTS: 4. Questions 1. Control Groups -========== +================= 1.1 What are cgroups ? ---------------------- @@ -143,10 +143,10 @@ proliferation of such cgroups. Also lets say that the administrator would like to give enhanced network access temporarily to a student's browser (since it is night and the user -wants to do online gaming :) OR give one of the students simulation +wants to do online gaming :)) OR give one of the students simulation apps enhanced CPU power, -With ability to write pids directly to resource classes, its just a +With ability to write pids directly to resource classes, it's just a matter of : # echo pid > /mnt/network//tasks @@ -227,10 +227,13 @@ Each cgroup is represented by a directory in the cgroup file system containing the following files describing that cgroup: - tasks: list of tasks (by pid) attached to that cgroup - - notify_on_release flag: run /sbin/cgroup_release_agent on exit? + - releasable flag: cgroup currently removeable? + - notify_on_release flag: run the release agent on exit? + - release_agent: the path to use for release notifications (this file + exists in the top cgroup only) Other subsystems such as cpusets may add additional files in each -cgroup dir +cgroup dir. New cgroups are created using the mkdir system call or shell command. The properties of a cgroup, such as its flags, are @@ -257,7 +260,7 @@ performance. To allow access from a cgroup to the css_sets (and hence tasks) that comprise it, a set of cg_cgroup_link objects form a lattice; each cg_cgroup_link is linked into a list of cg_cgroup_links for -a single cgroup on its cont_link_list field, and a list of +a single cgroup on its cgrp_link_list field, and a list of cg_cgroup_links for a single css_set on its cg_link_list. Thus the set of tasks in a cgroup can be listed by iterating over @@ -271,9 +274,6 @@ for cgroups, with a minimum of additional kernel code. 1.4 What does notify_on_release do ? ------------------------------------ -*** notify_on_release is disabled in the current patch set. It will be -*** reactivated in a future patch in a less-intrusive manner - If the notify_on_release flag is enabled (1) in a cgroup, then whenever the last task in the cgroup leaves (exits or attaches to some other cgroup) and the last child cgroup of that cgroup @@ -360,8 +360,8 @@ Now you want to do something with this cgroup. In this directory you can find several files: # ls -notify_on_release release_agent tasks -(plus whatever files are added by the attached subsystems) +notify_on_release releasable tasks +(plus whatever files added by the attached subsystems) Now attach your shell to this cgroup: # /bin/echo $$ > tasks @@ -404,19 +404,13 @@ with a subsystem id which will be assigned by the cgroup system. Other fields in the cgroup_subsys object include: - subsys_id: a unique array index for the subsystem, indicating which - entry in cgroup->subsys[] this subsystem should be - managing. Initialized by cgroup_register_subsys(); prior to this - it should be initialized to -1 + entry in cgroup->subsys[] this subsystem should be managing. -- hierarchy: an index indicating which hierarchy, if any, this - subsystem is currently attached to. If this is -1, then the - subsystem is not attached to any hierarchy, and all tasks should be - considered to be members of the subsystem's top_cgroup. It should - be initialized to -1. +- name: should be initialized to a unique subsystem name. Should be + no longer than MAX_CGROUP_TYPE_NAMELEN. -- name: should be initialized to a unique subsystem name prior to - calling cgroup_register_subsystem. Should be no longer than - MAX_CGROUP_TYPE_NAMELEN +- early_init: indicate if the subsystem needs early initialization + at system boot. Each cgroup object created by the system has an array of pointers, indexed by subsystem id; this pointer is entirely managed by the @@ -434,8 +428,6 @@ situation. See kernel/cgroup.c for more details. Subsystems can take/release the cgroup_mutex via the functions -cgroup_lock()/cgroup_unlock(), and can -take/release the callback_mutex via the functions cgroup_lock()/cgroup_unlock(). Accessing a task's cgroup pointer may be done in the following ways: @@ -444,7 +436,7 @@ Accessing a task's cgroup pointer may be done in the following ways: - inside an rcu_read_lock() section via rcu_dereference() 3.3 Subsystem API --------------------------- +----------------- Each subsystem should: @@ -455,7 +447,8 @@ Each subsystem may export the following methods. The only mandatory methods are create/destroy. Any others that are null are presumed to be successful no-ops. -struct cgroup_subsys_state *create(struct cgroup *cont) +struct cgroup_subsys_state *create(struct cgroup_subsys *ss, + struct cgroup *cgrp) (cgroup_mutex held by caller) Called to create a subsystem state object for a cgroup. The @@ -470,7 +463,7 @@ identified by the passed cgroup object having a NULL parent (since it's the root of the hierarchy) and may be an appropriate place for initialization code. -void destroy(struct cgroup *cont) +void destroy(struct cgroup_subsys *ss, struct cgroup *cgrp) (cgroup_mutex held by caller) The cgroup system is about to destroy the passed cgroup; the subsystem @@ -481,7 +474,14 @@ cgroup->parent is still valid. (Note - can also be called for a newly-created cgroup if an error occurs after this subsystem's create() method has been called for the new cgroup). -int can_attach(struct cgroup_subsys *ss, struct cgroup *cont, +void pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); +(cgroup_mutex held by caller) + +Called before checking the reference count on each subsystem. This may +be useful for subsystems which have some extra references even if +there are not tasks in the cgroup. + +int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, struct task_struct *task) (cgroup_mutex held by caller) @@ -492,8 +492,8 @@ unspecified task can be moved into the cgroup. Note that this isn't called on a fork. If this method returns 0 (success) then this should remain valid while the caller holds cgroup_mutex. -void attach(struct cgroup_subsys *ss, struct cgroup *cont, - struct cgroup *old_cont, struct task_struct *task) +void attach(struct cgroup_subsys *ss, struct cgroup *cgrp, + struct cgroup *old_cgrp, struct task_struct *task) Called after the task has been attached to the cgroup, to allow any post-attachment activity that requires memory allocations or blocking. @@ -505,9 +505,9 @@ registration for all existing tasks. void exit(struct cgroup_subsys *ss, struct task_struct *task) -Called during task exit +Called during task exit. -int populate(struct cgroup_subsys *ss, struct cgroup *cont) +int populate(struct cgroup_subsys *ss, struct cgroup *cgrp) Called after creation of a cgroup to allow a subsystem to populate the cgroup directory with file entries. The subsystem should make @@ -516,7 +516,7 @@ include/linux/cgroup.h for details). Note that although this method can return an error code, the error code is currently not always handled well. -void post_clone(struct cgroup_subsys *ss, struct cgroup *cont) +void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp) Called at the end of cgroup_clone() to do any paramater initialization which might be required before a task could attach. For From a043e3b2c63445512c5592cbe3c8694f3c655e81 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:09 -0800 Subject: [PATCH 637/880] cgroup: fix comments fix: - comments about need_forkexit_callback - comments about release agent - typo and comment style, etc. Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup.h | 2 +- kernel/cgroup.c | 142 +++++++++++++++++++++++------------------ 2 files changed, 80 insertions(+), 64 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index ff9055fc3d2a..2ebf7afedd9f 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -175,7 +175,7 @@ struct css_set { * * * When reading/writing to a file: - * - the cgroup to use in file->f_dentry->d_parent->d_fsdata + * - the cgroup to use is file->f_dentry->d_parent->d_fsdata * - the 'cftype' of the file is file->f_dentry->d_fsdata */ diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 4766bb65e4d9..36066d8a4911 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -113,9 +113,9 @@ static int root_count; #define dummytop (&rootnode.top_cgroup) /* This flag indicates whether tasks in the fork and exit paths should - * take callback_mutex and check for fork/exit handlers to call. This - * avoids us having to do extra work in the fork/exit path if none of the - * subsystems need to be called. + * check for fork/exit handlers to call. This avoids us having to do + * extra work in the fork/exit path if none of the subsystems need to + * be called. */ static int need_forkexit_callback; @@ -307,7 +307,6 @@ static inline void put_css_set_taskexit(struct css_set *cg) * template: location in which to build the desired set of subsystem * state objects for the new cgroup group */ - static struct css_set *find_existing_css_set( struct css_set *oldcg, struct cgroup *cgrp, @@ -354,7 +353,6 @@ static struct css_set *find_existing_css_set( * and chains them on tmp through their cgrp_link_list fields. Returns 0 on * success or a negative error */ - static int allocate_cg_links(int count, struct list_head *tmp) { struct cg_cgroup_link *link; @@ -396,7 +394,6 @@ static void free_cg_links(struct list_head *tmp) * substituted into the appropriate hierarchy. Must be called with * cgroup_mutex held */ - static struct css_set *find_css_set( struct css_set *oldcg, struct cgroup *cgrp) { @@ -507,8 +504,8 @@ static struct css_set *find_css_set( * critical pieces of code here. The exception occurs on cgroup_exit(), * when a task in a notify_on_release cgroup exits. Then cgroup_mutex * is taken, and if the cgroup count is zero, a usermode call made - * to /sbin/cgroup_release_agent with the name of the cgroup (path - * relative to the root of cgroup file system) as the argument. + * to the release agent with the name of the cgroup (path relative to + * the root of cgroup file system) as the argument. * * A cgroup can only be deleted if both its 'count' of using tasks * is zero, and its list of 'children' cgroups is empty. Since all @@ -521,7 +518,7 @@ static struct css_set *find_css_set( * * The need for this exception arises from the action of * cgroup_attach_task(), which overwrites one tasks cgroup pointer with - * another. It does so using cgroup_mutexe, however there are + * another. It does so using cgroup_mutex, however there are * several performance critical places that need to reference * task->cgroup without the expense of grabbing a system global * mutex. Therefore except as noted below, when dereferencing or, as @@ -537,7 +534,6 @@ static struct css_set *find_css_set( * cgroup_lock - lock out any changes to cgroup structures * */ - void cgroup_lock(void) { mutex_lock(&cgroup_mutex); @@ -548,7 +544,6 @@ void cgroup_lock(void) * * Undo the lock taken in a previous cgroup_lock() call. */ - void cgroup_unlock(void) { mutex_unlock(&cgroup_mutex); @@ -590,7 +585,6 @@ static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb) * Call subsys's pre_destroy handler. * This is called before css refcnt check. */ - static void cgroup_call_pre_destroy(struct cgroup *cgrp) { struct cgroup_subsys *ss; @@ -600,7 +594,6 @@ static void cgroup_call_pre_destroy(struct cgroup *cgrp) return; } - static void cgroup_diput(struct dentry *dentry, struct inode *inode) { /* is dentry a directory ? if so, kfree() associated cgroup */ @@ -1129,8 +1122,13 @@ static inline struct cftype *__d_cft(struct dentry *dentry) return dentry->d_fsdata; } -/* - * Called with cgroup_mutex held. Writes path of cgroup into buf. +/** + * cgroup_path - generate the path of a cgroup + * @cgrp: the cgroup in question + * @buf: the buffer to write the path into + * @buflen: the length of the buffer + * + * Called with cgroup_mutex held. Writes path of cgroup into buf. * Returns 0 on success, -errno on error. */ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) @@ -1188,11 +1186,13 @@ static void get_first_subsys(const struct cgroup *cgrp, *subsys_id = test_ss->subsys_id; } -/* - * Attach task 'tsk' to cgroup 'cgrp' +/** + * cgroup_attach_task - attach task 'tsk' to cgroup 'cgrp' + * @cgrp: the cgroup the task is attaching to + * @tsk: the task to be attached * - * Call holding cgroup_mutex. May take task_lock of - * the task 'pid' during call. + * Call holding cgroup_mutex. May take task_lock of + * the task 'tsk' during call. */ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) { @@ -1293,7 +1293,6 @@ static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf) } /* The various types of files and directories in a cgroup file system */ - enum cgroup_filetype { FILE_ROOT, FILE_DIR, @@ -1584,12 +1583,11 @@ static int cgroup_create_file(struct dentry *dentry, int mode, } /* - * cgroup_create_dir - create a directory for an object. - * cgrp: the cgroup we create the directory for. - * It must have a valid ->parent field - * And we are going to fill its ->dentry field. - * dentry: dentry of the new cgroup - * mode: mode to set on new directory. + * cgroup_create_dir - create a directory for an object. + * @cgrp: the cgroup we create the directory for. It must have a valid + * ->parent field. And we are going to fill its ->dentry field. + * @dentry: dentry of the new cgroup + * @mode: mode to set on new directory. */ static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry, int mode) @@ -1651,8 +1649,12 @@ int cgroup_add_files(struct cgroup *cgrp, return 0; } -/* Count the number of tasks in a cgroup. */ - +/** + * cgroup_task_count - count the number of tasks in a cgroup. + * @cgrp: the cgroup in question + * + * Return the number of tasks in the cgroup. + */ int cgroup_task_count(const struct cgroup *cgrp) { int count = 0; @@ -1962,12 +1964,13 @@ static int pid_array_load(pid_t *pidarray, int npids, struct cgroup *cgrp) } /** - * Build and fill cgroupstats so that taskstats can export it to user - * space. - * + * cgroupstats_build - build and fill cgroupstats * @stats: cgroupstats to fill information into * @dentry: A dentry entry belonging to the cgroup for which stats have * been requested. + * + * Build and fill cgroupstats so that taskstats can export it to user + * space. */ int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry) { @@ -2199,14 +2202,13 @@ static void init_cgroup_css(struct cgroup_subsys_state *css, } /* - * cgroup_create - create a cgroup - * parent: cgroup that will be parent of the new cgroup. - * name: name of the new cgroup. Will be strcpy'ed. - * mode: mode to set on new inode + * cgroup_create - create a cgroup + * @parent: cgroup that will be parent of the new cgroup + * @dentry: dentry of the new cgroup + * @mode: mode to set on new inode * - * Must be called with the mutex on the parent inode held + * Must be called with the mutex on the parent inode held */ - static long cgroup_create(struct cgroup *parent, struct dentry *dentry, int mode) { @@ -2349,13 +2351,12 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) parent = cgrp->parent; root = cgrp->root; sb = root->sb; + /* - * Call pre_destroy handlers of subsys + * Call pre_destroy handlers of subsys. Notify subsystems + * that rmdir() request comes. */ cgroup_call_pre_destroy(cgrp); - /* - * Notify subsyses that rmdir() request comes. - */ if (cgroup_has_css_refs(cgrp)) { mutex_unlock(&cgroup_mutex); @@ -2431,8 +2432,10 @@ static void cgroup_init_subsys(struct cgroup_subsys *ss) } /** - * cgroup_init_early - initialize cgroups at system boot, and - * initialize any subsystems that request early init. + * cgroup_init_early - cgroup initialization at system boot + * + * Initialize cgroups at system boot, and initialize any + * subsystems that request early init. */ int __init cgroup_init_early(void) { @@ -2474,8 +2477,10 @@ int __init cgroup_init_early(void) } /** - * cgroup_init - register cgroup filesystem and /proc file, and - * initialize any subsystems that didn't request early init. + * cgroup_init - cgroup initialization + * + * Register cgroup filesystem and /proc file, and initialize + * any subsystems that didn't request early init. */ int __init cgroup_init(void) { @@ -2618,7 +2623,7 @@ static struct file_operations proc_cgroupstats_operations = { /** * cgroup_fork - attach newly forked task to its parents cgroup. - * @tsk: pointer to task_struct of forking parent process. + * @child: pointer to task_struct of forking parent process. * * Description: A task inherits its parent's cgroup at fork(). * @@ -2642,9 +2647,12 @@ void cgroup_fork(struct task_struct *child) } /** - * cgroup_fork_callbacks - called on a new task very soon before - * adding it to the tasklist. No need to take any locks since no-one - * can be operating on this task + * cgroup_fork_callbacks - run fork callbacks + * @child: the new task + * + * Called on a new task very soon before adding it to the + * tasklist. No need to take any locks since no-one can + * be operating on this task. */ void cgroup_fork_callbacks(struct task_struct *child) { @@ -2659,11 +2667,14 @@ void cgroup_fork_callbacks(struct task_struct *child) } /** - * cgroup_post_fork - called on a new task after adding it to the - * task list. Adds the task to the list running through its css_set - * if necessary. Has to be after the task is visible on the task list - * in case we race with the first call to cgroup_iter_start() - to - * guarantee that the new task ends up on its list. */ + * cgroup_post_fork - called on a new task after adding it to the task list + * @child: the task in question + * + * Adds the task to the list running through its css_set if necessary. + * Has to be after the task is visible on the task list in case we race + * with the first call to cgroup_iter_start() - to guarantee that the + * new task ends up on its list. + */ void cgroup_post_fork(struct task_struct *child) { if (use_task_css_set_links) { @@ -2676,6 +2687,7 @@ void cgroup_post_fork(struct task_struct *child) /** * cgroup_exit - detach cgroup from exiting task * @tsk: pointer to task_struct of exiting process + * @run_callback: run exit callbacks? * * Description: Detach cgroup from @tsk and release it. * @@ -2706,7 +2718,6 @@ void cgroup_post_fork(struct task_struct *child) * top_cgroup isn't going away, and either task has PF_EXITING set, * which wards off any cgroup_attach_task() attempts, or task is a failed * fork, never visible to cgroup_attach_task. - * */ void cgroup_exit(struct task_struct *tsk, int run_callbacks) { @@ -2743,9 +2754,13 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) } /** - * cgroup_clone - duplicate the current cgroup in the hierarchy - * that the given subsystem is attached to, and move this task into - * the new child + * cgroup_clone - clone the cgroup the given subsystem is attached to + * @tsk: the task to be moved + * @subsys: the given subsystem + * + * Duplicate the current cgroup in the hierarchy that the given + * subsystem is attached to, and move this task into the new + * child. */ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys) { @@ -2858,9 +2873,12 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys) return ret; } -/* - * See if "cgrp" is a descendant of the current task's cgroup in - * the appropriate hierarchy +/** + * cgroup_is_descendant - see if @cgrp is a descendant of current task's cgrp + * @cgrp: the cgroup in question + * + * See if @cgrp is a descendant of the current task's cgroup in + * the appropriate hierarchy. * * If we are sending in dummytop, then presumably we are creating * the top cgroup in the subsystem. @@ -2939,9 +2957,7 @@ void __css_put(struct cgroup_subsys_state *css) * release agent task. We don't bother to wait because the caller of * this routine has no use for the exit status of the release agent * task, so no sense holding our caller up for that. - * */ - static void cgroup_release_agent(struct work_struct *work) { BUG_ON(work != &release_agent_work); From ffd2d883399cbbb641e55730676ce1ec4845d99d Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:09 -0800 Subject: [PATCH 638/880] cgroup: clean up cgroup.h - replace old name 'cont' with 'cgrp' (Paul Menage did this cleanup for cgroup.c in commit bd89aabc6761de1c35b154fe6f914a445d301510) - remove a duplicate declaration of cgroup_path() Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup.h | 48 ++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 2ebf7afedd9f..028ba3b523b1 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -186,15 +186,15 @@ struct cftype { char name[MAX_CFTYPE_NAME]; int private; int (*open) (struct inode *inode, struct file *file); - ssize_t (*read) (struct cgroup *cont, struct cftype *cft, + ssize_t (*read) (struct cgroup *cgrp, struct cftype *cft, struct file *file, char __user *buf, size_t nbytes, loff_t *ppos); /* * read_uint() is a shortcut for the common case of returning a * single integer. Use it in place of read() */ - u64 (*read_uint) (struct cgroup *cont, struct cftype *cft); - ssize_t (*write) (struct cgroup *cont, struct cftype *cft, + u64 (*read_uint) (struct cgroup *cgrp, struct cftype *cft); + ssize_t (*write) (struct cgroup *cgrp, struct cftype *cft, struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos); @@ -203,7 +203,7 @@ struct cftype { * a single integer (as parsed by simple_strtoull) from * userspace. Use in place of write(); return 0 or error. */ - int (*write_uint) (struct cgroup *cont, struct cftype *cft, u64 val); + int (*write_uint) (struct cgroup *cgrp, struct cftype *cft, u64 val); int (*release) (struct inode *inode, struct file *file); }; @@ -218,41 +218,41 @@ struct cgroup_scanner { /* Add a new file to the given cgroup directory. Should only be * called by subsystems from within a populate() method */ -int cgroup_add_file(struct cgroup *cont, struct cgroup_subsys *subsys, +int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys, const struct cftype *cft); /* Add a set of new files to the given cgroup directory. Should * only be called by subsystems from within a populate() method */ -int cgroup_add_files(struct cgroup *cont, +int cgroup_add_files(struct cgroup *cgrp, struct cgroup_subsys *subsys, const struct cftype cft[], int count); -int cgroup_is_removed(const struct cgroup *cont); +int cgroup_is_removed(const struct cgroup *cgrp); -int cgroup_path(const struct cgroup *cont, char *buf, int buflen); +int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen); -int cgroup_task_count(const struct cgroup *cont); +int cgroup_task_count(const struct cgroup *cgrp); /* Return true if the cgroup is a descendant of the current cgroup */ -int cgroup_is_descendant(const struct cgroup *cont); +int cgroup_is_descendant(const struct cgroup *cgrp); /* Control Group subsystem type. See Documentation/cgroups.txt for details */ struct cgroup_subsys { struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss, - struct cgroup *cont); - void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cont); - void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont); + struct cgroup *cgrp); + void (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp); + void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp); int (*can_attach)(struct cgroup_subsys *ss, - struct cgroup *cont, struct task_struct *tsk); - void (*attach)(struct cgroup_subsys *ss, struct cgroup *cont, - struct cgroup *old_cont, struct task_struct *tsk); + struct cgroup *cgrp, struct task_struct *tsk); + void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, + struct cgroup *old_cgrp, struct task_struct *tsk); void (*fork)(struct cgroup_subsys *ss, struct task_struct *task); void (*exit)(struct cgroup_subsys *ss, struct task_struct *task); int (*populate)(struct cgroup_subsys *ss, - struct cgroup *cont); - void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cont); + struct cgroup *cgrp); + void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp); void (*bind)(struct cgroup_subsys *ss, struct cgroup *root); int subsys_id; int active; @@ -273,9 +273,9 @@ struct cgroup_subsys { #undef SUBSYS static inline struct cgroup_subsys_state *cgroup_subsys_state( - struct cgroup *cont, int subsys_id) + struct cgroup *cgrp, int subsys_id) { - return cont->subsys[subsys_id]; + return cgrp->subsys[subsys_id]; } static inline struct cgroup_subsys_state *task_subsys_state( @@ -290,8 +290,6 @@ static inline struct cgroup* task_cgroup(struct task_struct *task, return task_subsys_state(task, subsys_id)->cgroup; } -int cgroup_path(const struct cgroup *cont, char *buf, int buflen); - int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss); /* A cgroup_iter should be treated as an opaque object */ @@ -313,10 +311,10 @@ struct cgroup_iter { * - cgroup_scan_tasks() holds the css_set_lock when calling the test_task() * callback, but not while calling the process_task() callback. */ -void cgroup_iter_start(struct cgroup *cont, struct cgroup_iter *it); -struct task_struct *cgroup_iter_next(struct cgroup *cont, +void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it); +struct task_struct *cgroup_iter_next(struct cgroup *cgrp, struct cgroup_iter *it); -void cgroup_iter_end(struct cgroup *cont, struct cgroup_iter *it); +void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); int cgroup_scan_tasks(struct cgroup_scanner *scan); int cgroup_attach_task(struct cgroup *, struct task_struct *); From f777073848ba3708d68d87e43f104f83316187d7 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:10 -0800 Subject: [PATCH 639/880] cgroup: fix memory leak in cgroup_get_sb() opts.release_agent is not kfree()ed in all necessary places. Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/cgroup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 36066d8a4911..947fe3b22182 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -954,8 +954,11 @@ static int cgroup_get_sb(struct file_system_type *fs_type, } root = kzalloc(sizeof(*root), GFP_KERNEL); - if (!root) + if (!root) { + if (opts.release_agent) + kfree(opts.release_agent); return -ENOMEM; + } init_cgroup_root(root); root->subsys_bits = opts.subsys_bits; From 8d53d55d27754508e58e9ac18a4a445b110434bf Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:11 -0800 Subject: [PATCH 640/880] cgroup: fix subsys bitops Cgroup uses unsigned long for subsys bitops, not unsigned long long. Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/cgroup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 947fe3b22182..841259361724 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -319,7 +319,7 @@ static struct css_set *find_existing_css_set( /* Built the set of subsystem state objects that we want to * see in the new css_set */ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - if (root->subsys_bits & (1ull << i)) { + if (root->subsys_bits & (1UL << i)) { /* Subsystem is in this hierarchy. So we want * the subsystem state from the new * cgroup */ @@ -689,7 +689,7 @@ static int rebind_subsystems(struct cgroupfs_root *root, added_bits = final_bits & ~root->actual_subsys_bits; /* Check that any added subsystems are currently free */ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - unsigned long long bit = 1ull << i; + unsigned long bit = 1UL << i; struct cgroup_subsys *ss = subsys[i]; if (!(bit & added_bits)) continue; From 68db38f1537a44097e264f28bda751d6b919cd53 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:11 -0800 Subject: [PATCH 641/880] cgroup: remove duplicate code in find_css_set() The list head res->tasks gets initialized twice in find_css_set(). Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/cgroup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 841259361724..2aa408201aa5 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -470,7 +470,6 @@ static struct css_set *find_css_set( /* Link this cgroup group into the list */ list_add(&res->list, &init_css_set.list); css_set_count++; - INIT_LIST_HEAD(&res->tasks); write_unlock(&css_set_lock); return res; From bc231d2a048010d5e0b49ac7fddbfa822fc41109 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:12 -0800 Subject: [PATCH 642/880] cgroup: remove dead code in cgroup_get_rootdir() Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/cgroup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 2aa408201aa5..d8abe996e009 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -919,7 +919,6 @@ static int cgroup_get_rootdir(struct super_block *sb) if (!inode) return -ENOMEM; - inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; inode->i_op = &cgroup_dir_inode_operations; /* directories start off with i_nlink == 2 (for "." entry) */ From 2324c5dd47233859cd7ba6272d0601f26ce60dcd Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:12 -0800 Subject: [PATCH 643/880] memcgroup: fix and update documentation - remove trailing " Bytes"s in the demonstration - remove section 4.4 (feature control_type has been removed) - fix reference section Signed-off-by: Li Zefan Acked-by: KAMEZAWA Hiroyuki Acked-by: Balbir Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/controllers/memory.txt | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/Documentation/controllers/memory.txt b/Documentation/controllers/memory.txt index b5bbea92a61a..6015347b41e2 100644 --- a/Documentation/controllers/memory.txt +++ b/Documentation/controllers/memory.txt @@ -170,14 +170,14 @@ NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo, mega or gigabytes. # cat /cgroups/0/memory.limit_in_bytes -4194304 Bytes +4194304 NOTE: The interface has now changed to display the usage in bytes instead of pages We can check the usage: # cat /cgroups/0/memory.usage_in_bytes -1216512 Bytes +1216512 A successful write to this file does not guarantee a successful set of this limit to the value written into the file. This can be due to a @@ -187,7 +187,7 @@ this file after a write to guarantee the value committed by the kernel. # echo -n 1 > memory.limit_in_bytes # cat memory.limit_in_bytes -4096 Bytes +4096 The memory.failcnt field gives the number of times that the cgroup limit was exceeded. @@ -233,13 +233,6 @@ cgroup might have some charge associated with it, even though all tasks have migrated away from it. Such charges are automatically dropped at rmdir() if there are no tasks. -4.4 Choosing what to account -- Page Cache (unmapped) vs RSS (mapped)? - -The type of memory accounted by the cgroup can be limited to just -mapped pages by writing "1" to memory.control_type field - -echo -n 1 > memory.control_type - 5. TODO 1. Add support for accounting huge pages (as a separate controller) @@ -262,18 +255,19 @@ References 3. Emelianov, Pavel. Resource controllers based on process cgroups http://lkml.org/lkml/2007/3/6/198 4. Emelianov, Pavel. RSS controller based on process cgroups (v2) - http://lkml.org/lkml/2007/4/9/74 + http://lkml.org/lkml/2007/4/9/78 5. Emelianov, Pavel. RSS controller based on process cgroups (v3) http://lkml.org/lkml/2007/5/30/244 6. Menage, Paul. Control Groups v10, http://lwn.net/Articles/236032/ 7. Vaidyanathan, Srinivasan, Control Groups: Pagecache accounting and control subsystem (v3), http://lwn.net/Articles/235534/ -8. Singh, Balbir. RSS controller V2 test results (lmbench), +8. Singh, Balbir. RSS controller v2 test results (lmbench), http://lkml.org/lkml/2007/5/17/232 -9. Singh, Balbir. RSS controller V2 AIM9 results +9. Singh, Balbir. RSS controller v2 AIM9 results http://lkml.org/lkml/2007/5/18/1 -10. Singh, Balbir. Memory controller v6 results, +10. Singh, Balbir. Memory controller v6 test results, http://lkml.org/lkml/2007/8/19/36 -11. Singh, Balbir. Memory controller v6, http://lkml.org/lkml/2007/8/17/69 +11. Singh, Balbir. Memory controller introduction (v6), + http://lkml.org/lkml/2007/8/17/69 12. Corbet, Jonathan, Controlling memory use in cgroups, http://lwn.net/Articles/243795/ From 7fde4c3eb7ee68828d76a2148ed6d70b6a794add Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:13 -0800 Subject: [PATCH 644/880] memcgroup: remove a useless VM_BUG_ON() Remove this VM_BUG_ON(), as Balbir stated: We used to have a for loop with !list_empty() as a termination condition and VM_BUG_ON(!pc) is a spill over. With the new loop, VM_BUG_ON(!pc) does not make sense. Signed-off-by: Li Zefan Acked-by: Balbir Singh Acked-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 6bded84c20c8..bb4d7acfbca3 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -534,7 +534,6 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, if (scan >= nr_to_scan) break; page = pc->page; - VM_BUG_ON(!pc); if (unlikely(!PageLRU(page))) continue; From 2dda81ca31dc73e695ff8b83351f7aaefbef192a Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Sat, 23 Feb 2008 15:24:14 -0800 Subject: [PATCH 645/880] memcgroup: return negative error code in mem_cgroup_create() Cgroup requires the subsystem to return negative error code on error in the create method. Signed-off-by: Li Zefan Acked-by: KAMEZAWA Hiroyuki Acked-by: Balbir Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index bb4d7acfbca3..631002d085d1 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1100,7 +1100,7 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) mem = kzalloc(sizeof(struct mem_cgroup), GFP_KERNEL); if (mem == NULL) - return NULL; + return ERR_PTR(-ENOMEM); res_counter_init(&mem->res); @@ -1116,7 +1116,7 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) free_mem_cgroup_per_zone_info(mem, node); if (cont->parent != NULL) kfree(mem); - return NULL; + return ERR_PTR(-ENOMEM); } static void mem_cgroup_pre_destroy(struct cgroup_subsys *ss, From 02c608c1fefe821a4c6fc34c45a0dea3cebf4764 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 24 Feb 2008 00:03:29 +0300 Subject: [PATCH 646/880] documentation: atomic_add_unless() doesn't imply mb() on failure (sorry for being offtpoic, but while experts are here...) A "typical" implementation of atomic_add_unless() can return 0 immediately after the first atomic_read() (before doing cmpxchg). In that case it doesn't provide any barrier semantics. See include/asm-ia64/atomic.h as an example. We should either change the implementation, or fix the docs. Signed-off-by: Oleg Nesterov Acked-by: Nick Piggin Signed-off-by: Linus Torvalds --- Documentation/atomic_ops.txt | 3 ++- Documentation/memory-barriers.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt index f20c10c2858f..4ef245010457 100644 --- a/Documentation/atomic_ops.txt +++ b/Documentation/atomic_ops.txt @@ -186,7 +186,8 @@ If the atomic value v is not equal to u, this function adds a to v, and returns non zero. If v is equal to u then it returns zero. This is done as an atomic operation. -atomic_add_unless requires explicit memory barriers around the operation. +atomic_add_unless requires explicit memory barriers around the operation +unless it fails (returns 0). atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0) diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 4e17beba2379..1f506f7830ec 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -1493,7 +1493,7 @@ explicit lock operations, described later). These include: atomic_dec_and_test(); atomic_sub_and_test(); atomic_add_negative(); - atomic_add_unless(); + atomic_add_unless(); /* when succeeds (returns 1) */ test_and_set_bit(); test_and_clear_bit(); test_and_change_bit(); From 0a3716eb04ccfdbef6e872a343ba7ce309237e79 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 23 Feb 2008 16:53:44 -0500 Subject: [PATCH 647/880] mvsas: fix build warning, clean prototypes - Fix build 'make randconfig' build warning spotted by Toralf Foerster: drivers/scsi/mvsas.c: In function 'mvs_hexdump': drivers/scsi/mvsas.c:715: error: implicit declaration of function 'isalnum' - Remove unneeded prototypes (spotted by hch) Signed-off-by: Jeff Garzik Signed-off-by: Linus Torvalds --- drivers/scsi/mvsas.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c index 30e20e69715a..d4a6ac3c9c47 100755 --- a/drivers/scsi/mvsas.c +++ b/drivers/scsi/mvsas.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -632,15 +633,6 @@ static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, void *funcdata); static u32 mvs_read_phy_ctl(struct mvs_info *mvi, u32 port); static void mvs_write_phy_ctl(struct mvs_info *mvi, u32 port, u32 val); -static u32 mvs_read_port(struct mvs_info *mvi, u32 off, u32 off2, u32 port); -static void mvs_write_port(struct mvs_info *mvi, u32 off, u32 off2, - u32 port, u32 val); -static u32 mvs_read_port_cfg_data(struct mvs_info *mvi, u32 port); -static void mvs_write_port_cfg_data(struct mvs_info *mvi, u32 port, u32 val); -static void mvs_write_port_cfg_addr(struct mvs_info *mvi, u32 port, u32 addr); -static u32 mvs_read_port_vsr_data(struct mvs_info *mvi, u32 port); -static void mvs_write_port_vsr_data(struct mvs_info *mvi, u32 port, u32 val); -static void mvs_write_port_vsr_addr(struct mvs_info *mvi, u32 port, u32 addr); static u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port); static void mvs_write_port_irq_stat(struct mvs_info *mvi, u32 port, u32 val); static void mvs_write_port_irq_mask(struct mvs_info *mvi, u32 port, u32 val); @@ -649,9 +641,6 @@ static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port); static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i); static void mvs_detect_porttype(struct mvs_info *mvi, int i); static void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); -static void mvs_free_reg_set(struct mvs_info *mvi, struct mvs_port *port); -static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port); -static u32 mvs_is_sig_fis_received(u32 irq_status); static int mvs_scan_finished(struct Scsi_Host *, unsigned long); static void mvs_scan_start(struct Scsi_Host *); From 04e2f1741d235ba599037734878d72e57cb302b5 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 23 Feb 2008 18:05:03 -0800 Subject: [PATCH 648/880] Add memory barrier semantics to wake_up() & co Oleg Nesterov and others have pointed out that on some architectures, the traditional sequence of set_current_state(TASK_INTERRUPTIBLE); if (CONDITION) return; schedule(); is racy wrt another CPU doing CONDITION = 1; wake_up_process(p); because while set_current_state() has a memory barrier separating setting of the TASK_INTERRUPTIBLE state from reading of the CONDITION variable, there is no such memory barrier on the wakeup side. Now, wake_up_process() does actually take a spinlock before it reads and sets the task state on the waking side, and on x86 (and many other architectures) that spinlock is in fact equivalent to a memory barrier, but that is not generally guaranteed. The write that sets CONDITION could move into the critical region protected by the runqueue spinlock. However, adding a smp_wmb() to before the spinlock should now order the writing of CONDITION wrt the lock itself, which in turn is ordered wrt the accesses within the spinlock (which includes the reading of the old state). This should thus close the race (which probably has never been seen in practice, but since smp_wmb() is a no-op on x86, it's not like this will make anything worse either on the most common architecture where the spinlock already gave the required protection). Acked-by: Oleg Nesterov Acked-by: Dmitry Adamushko Cc: Andrew Morton Cc: Nick Piggin Signed-off-by: Linus Torvalds --- kernel/sched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sched.c b/kernel/sched.c index c4bc8c210958..b387a8de26a5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1831,6 +1831,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) long old_state; struct rq *rq; + smp_wmb(); rq = task_rq_lock(p, &flags); old_state = p->state; if (!(old_state & state)) From a2724e2559a3c41ac6182da6e2446d3abf0720a5 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 23 Feb 2008 19:47:44 -0800 Subject: [PATCH 649/880] [BNX2]: More 5706S link down workaround. The previous patches to workaround the 5706S on an HP blade were not sufficient. The link state still does not change properly in some cases. This patch adds polling to make it completely reliable. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 471c7f3e8a4a..2fa258050968 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1273,14 +1273,20 @@ bnx2_set_link(struct bnx2 *bp) if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) && (CHIP_NUM(bp) == CHIP_NUM_5706)) { - u32 val; + u32 val, an_dbg; if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) { bnx2_5706s_force_link_dn(bp, 0); bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN; } val = REG_RD(bp, BNX2_EMAC_STATUS); - if (val & BNX2_EMAC_STATUS_LINK) + + bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG); + bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg); + bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg); + + if ((val & BNX2_EMAC_STATUS_LINK) && + !(an_dbg & MISC_SHDW_AN_DBG_NOSYNC)) bmsr |= BMSR_LSTATUS; else bmsr &= ~BMSR_LSTATUS; @@ -5390,13 +5396,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) int check_link = 1; spin_lock(&bp->phy_lock); - if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) { - bnx2_5706s_force_link_dn(bp, 0); - bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN; - spin_unlock(&bp->phy_lock); - return; - } - if (bp->serdes_an_pending) { bp->serdes_an_pending--; check_link = 0; @@ -5420,7 +5419,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) (bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) { u32 phy2; - check_link = 0; bnx2_write_phy(bp, 0x17, 0x0f01); bnx2_read_phy(bp, 0x15, &phy2); if (phy2 & 0x20) { @@ -5435,17 +5433,21 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) } else bp->current_interval = bp->timer_interval; - if (bp->link_up && (bp->autoneg & AUTONEG_SPEED) && check_link) { + if (check_link) { u32 val; bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG); bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val); bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val); - if (val & MISC_SHDW_AN_DBG_NOSYNC) { - bnx2_5706s_force_link_dn(bp, 1); - bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN; - } + if (bp->link_up && (val & MISC_SHDW_AN_DBG_NOSYNC)) { + if (!(bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN)) { + bnx2_5706s_force_link_dn(bp, 1); + bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN; + } else + bnx2_set_link(bp); + } else if (!bp->link_up && !(val & MISC_SHDW_AN_DBG_NOSYNC)) + bnx2_set_link(bp); } spin_unlock(&bp->phy_lock); } From 38ea3686f6d1110a3787dfd7c5cf7bad1926818b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 23 Feb 2008 19:48:57 -0800 Subject: [PATCH 650/880] [BNX2]: Disable parallel detect on an HP blade. Because of some board issues, we need to disable parallel detect on an HP blade. Without this patch, the link state can become stuck when it goes into parallel detect mode. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 14 +++++++++++++- drivers/net/bnx2.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 2fa258050968..35356fba5a71 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -5362,11 +5362,15 @@ bnx2_test_intr(struct bnx2 *bp) return -ENODEV; } +/* Determining link for parallel detection. */ static int bnx2_5706_serdes_has_link(struct bnx2 *bp) { u32 mode_ctl, an_dbg, exp; + if (bp->phy_flags & BNX2_PHY_FLAG_NO_PARALLEL) + return 0; + bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_MODE_CTL); bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &mode_ctl); @@ -7328,7 +7332,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->flags |= BNX2_FLAG_NO_WOL; bp->wol = 0; } - if (CHIP_NUM(bp) != CHIP_NUM_5706) { + if (CHIP_NUM(bp) == CHIP_NUM_5706) { + /* Don't do parallel detect on this board because of + * some board problems. The link will not go down + * if we do parallel detect. + */ + if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP && + pdev->subsystem_device == 0x310c) + bp->phy_flags |= BNX2_PHY_FLAG_NO_PARALLEL; + } else { bp->phy_addr = 2; if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) bp->phy_flags |= BNX2_PHY_FLAG_2_5G_CAPABLE; diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 3aa0364942e2..1eaf5bb3d9c2 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6673,6 +6673,7 @@ struct bnx2 { #define BNX2_PHY_FLAG_DIS_EARLY_DAC 0x00000400 #define BNX2_PHY_FLAG_REMOTE_PHY_CAP 0x00000800 #define BNX2_PHY_FLAG_FORCED_DOWN 0x00001000 +#define BNX2_PHY_FLAG_NO_PARALLEL 0x00002000 u32 mii_bmcr; u32 mii_bmsr; From 42e6de0e6079f4a7ce6bd62340b1b14a1af314dc Mon Sep 17 00:00:00 2001 From: Oliver Pinter Date: Sun, 24 Feb 2008 04:33:21 +0100 Subject: [PATCH 651/880] fix vmsas.c file permissions Signed-off-by: Oliver Pinter Signed-off-by: Linus Torvalds --- drivers/scsi/mvsas.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 drivers/scsi/mvsas.c diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c old mode 100755 new mode 100644 From c73b1d1f26d4c9d54b49526edf9ee958ee5b80c1 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 23 Feb 2008 19:49:48 -0800 Subject: [PATCH 652/880] [BNX2]: Update version to 1.7.4. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 35356fba5a71..15853be4680a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.7.3" -#define DRV_MODULE_RELDATE "January 29, 2008" +#define DRV_MODULE_VERSION "1.7.4" +#define DRV_MODULE_RELDATE "February 18, 2008" #define RUN_AT(x) (jiffies + (x)) From 759afc31332aed66bde20743e7e2d1e47b08aaeb Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sat, 23 Feb 2008 19:51:59 -0800 Subject: [PATCH 653/880] tg3: ethtool phys_id default When asked to blink LEDs the tg3 driver behaves when using: ethtool -p ethX The default value for data is zero, and other drivers interpret this as blink forever (or at least a really long time). The tg3 driver interprets this as blink once. All drivers should have the same behaviour. Signed-off-by: Stephen Hemminger Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index db606b603884..26ffb67f1da2 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8781,7 +8781,7 @@ static int tg3_phys_id(struct net_device *dev, u32 data) return -EAGAIN; if (data == 0) - data = 2; + data = UINT_MAX / 2; for (i = 0; i < (data * 2); i++) { if ((i % 2) == 0) From 1840bb13c22f5b8fd2e242e36c8d6ea3f312be67 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Sat, 23 Feb 2008 19:54:36 -0800 Subject: [PATCH 654/880] [RTNL]: Validate hardware and broadcast address attribute for RTM_NEWLINK RTM_NEWLINK allows for already existing links to be modified. For this purpose do_setlink() is called which expects address attributes with a payload length of at least dev->addr_len. This patch adds the necessary validation for the RTM_NEWLINK case. The address length for links to be created is not checked for now as the actual attribute length is used when copying the address to the netdevice structure. It might make sense to report an error if less than addr_len bytes are provided but enforcing this might break drivers trying to be smart with not transmitting all zero addresses. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e170179cc66f..2bd9c5f7627d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -722,6 +722,21 @@ static struct net *get_net_ns_by_pid(pid_t pid) return net; } +static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) +{ + if (dev) { + if (tb[IFLA_ADDRESS] && + nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) + return -EINVAL; + + if (tb[IFLA_BROADCAST] && + nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) + return -EINVAL; + } + + return 0; +} + static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, struct nlattr **tb, char *ifname, int modified) { @@ -894,12 +909,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) goto errout; } - if (tb[IFLA_ADDRESS] && - nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) - goto errout_dev; - - if (tb[IFLA_BROADCAST] && - nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) + if ((err = validate_linkmsg(dev, tb)) < 0) goto errout_dev; err = do_setlink(dev, ifm, tb, ifname, 0); @@ -1020,6 +1030,9 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) else dev = NULL; + if ((err = validate_linkmsg(dev, tb)) < 0) + return err; + if (tb[IFLA_LINKINFO]) { err = nla_parse_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO], ifla_info_policy); From bc4bf5f38cf0a623e6a29f52ec80bfcc56a373c6 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Sat, 23 Feb 2008 19:57:02 -0800 Subject: [PATCH 655/880] [NEIGH]: Fix race between neighbor lookup and table's hash_rnd update. The neigh_hash_grow() may update the tbl->hash_rnd value, which is used in all tbl->hash callbacks to calculate the hashval. Two lookup routines may race with this, since they call the ->hash callback without the tbl->lock held. Since the hash_rnd is changed with this lock write-locked moving the calls to ->hash under this lock read-locked closes this gap. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/core/neighbour.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 4062b88bfc1b..2328acbd16cd 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -358,11 +358,12 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, { struct neighbour *n; int key_len = tbl->key_len; - u32 hash_val = tbl->hash(pkey, dev); + u32 hash_val; NEIGH_CACHE_STAT_INC(tbl, lookups); read_lock_bh(&tbl->lock); + hash_val = tbl->hash(pkey, dev); for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) { neigh_hold(n); @@ -379,11 +380,12 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, { struct neighbour *n; int key_len = tbl->key_len; - u32 hash_val = tbl->hash(pkey, NULL); + u32 hash_val; NEIGH_CACHE_STAT_INC(tbl, lookups); read_lock_bh(&tbl->lock); + hash_val = tbl->hash(pkey, NULL); for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { if (!memcmp(n->primary_key, pkey, key_len) && (net == n->dev->nd_net)) { From 55b01e8681cba392ccda4ff6184054d38968115d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 23 Feb 2008 20:09:11 -0800 Subject: [PATCH 656/880] [NET]: Restore sanity wrt. print_mac(). MAC_FMT had only one user and we tried to get rid of that, but this created more problems than it solved. As a result, this reverts three commits: 235365f3aaaa10b7056293877c0ead50425f25c7 ("net/8021q/vlan_dev.c: Use print_mac."), fea5fa875eb235dc186b1f5184eb36abc63e26cc ("[NET]: Remove MAC_FMT"), and 8f789c48448aed74fe1c07af76de8f04adacec7d ("[NET]: Elminate spurious print_mac() calls.") Signed-off-by: David S. Miller --- include/linux/if_ether.h | 3 ++- net/8021q/vlan_dev.c | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 42dc6a3571ec..e157c1399b61 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -129,7 +129,8 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); /* * Display a 6 byte device address (MAC) in a readable format. */ -extern __pure char *print_mac(char *buf, const unsigned char *addr); +extern char *print_mac(char *buf, const unsigned char *addr); +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" #define MAC_BUF_SIZE 18 #define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index fc60c6d096b9..77f04e49a1a0 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -366,8 +366,7 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = &dev->stats; struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); - DECLARE_MAC_BUF(mac); - DECLARE_MAC_BUF(mac2); + /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING @@ -405,8 +404,11 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) pr_debug("%s: about to send skb: %p to dev: %s\n", __FUNCTION__, skb, skb->dev->name); - pr_debug(" %s %s %4hx %4hx %4hx\n", - print_mac(mac, veth->h_dest), print_mac(mac2, veth->h_source), + pr_debug(" " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n", + veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], + veth->h_dest[3], veth->h_dest[4], veth->h_dest[5], + veth->h_source[0], veth->h_source[1], veth->h_source[2], + veth->h_source[3], veth->h_source[4], veth->h_source[5], veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto); From 34cc7ba6398203aab4056917fa1e2aa5988487aa Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Sat, 23 Feb 2008 20:19:20 -0800 Subject: [PATCH 657/880] [IP_TUNNEL]: Don't limit the number of tunnels with generic name explicitly. Use the added dev_alloc_name() call to create tunnel device name, rather than iterate in a hand-made loop with an artificial limit. Thanks Patrick for noticing this. [ The way this works is, when the device is actually registered, the generic code noticed the '%' in the name and invokes dev_alloc_name() to fully resolve the name. -DaveM ] Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- include/net/ip6_tunnel.h | 2 -- net/ipv4/ip_gre.c | 12 ++---------- net/ipv4/ipip.c | 12 ++---------- net/ipv6/ip6_tunnel.c | 15 ++++----------- net/ipv6/sit.c | 12 ++---------- 5 files changed, 10 insertions(+), 43 deletions(-) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index c17fa1fdc356..6512d85f11b3 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -14,8 +14,6 @@ /* capable of receiving packets */ #define IP6_TNL_F_CAP_RCV 0x20000 -#define IP6_TNL_MAX 128 - /* IPv6 tunnel */ struct ip6_tnl { diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 63f691719353..906cb1ada4c3 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -259,16 +259,8 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); - else { - int i; - for (i=1; i<100; i++) { - sprintf(name, "gre%d", i); - if (__dev_get_by_name(&init_net, name) == NULL) - break; - } - if (i==100) - goto failed; - } + else + sprintf(name, "gre%%d"); dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); if (!dev) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index da281581692c..e77e3b855834 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -221,16 +221,8 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); - else { - int i; - for (i=1; i<100; i++) { - sprintf(name, "tunl%d", i); - if (__dev_get_by_name(&init_net, name) == NULL) - break; - } - if (i==100) - goto failed; - } + else + sprintf(name, "tunl%%d"); dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup); if (dev == NULL) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index cd940647bd12..2a124e9a1b2d 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -229,18 +229,11 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p) char name[IFNAMSIZ]; int err; - if (p->name[0]) { + if (p->name[0]) strlcpy(name, p->name, IFNAMSIZ); - } else { - int i; - for (i = 1; i < IP6_TNL_MAX; i++) { - sprintf(name, "ip6tnl%d", i); - if (__dev_get_by_name(&init_net, name) == NULL) - break; - } - if (i == IP6_TNL_MAX) - goto failed; - } + else + sprintf(name, "ip6tnl%%d"); + dev = alloc_netdev(sizeof (*t), name, ip6_tnl_dev_setup); if (dev == NULL) goto failed; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e77239d02bf5..dde7801abeff 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -164,16 +164,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); - else { - int i; - for (i=1; i<100; i++) { - sprintf(name, "sit%d", i); - if (__dev_get_by_name(&init_net, name) == NULL) - break; - } - if (i==100) - goto failed; - } + else + sprintf(name, "sit%%d"); dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); if (dev == NULL) From 1b04ab4597725f75f94942da9aa40daa7b9a4bd9 Mon Sep 17 00:00:00 2001 From: Joonwoo Park Date: Sat, 23 Feb 2008 20:22:27 -0800 Subject: [PATCH 658/880] [NETFILTER]: fix ebtable targets return The function ebt_do_table doesn't take NF_DROP as a verdict from the targets. Signed-off-by: Joonwoo Park Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/netfilter/ebt_dnat.c | 2 +- net/bridge/netfilter/ebt_redirect.c | 2 +- net/bridge/netfilter/ebt_snat.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index 1ec671d93dda..ca64c1cc1b47 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c @@ -21,7 +21,7 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, const struct ebt_nat_info *info = data; if (!skb_make_writable(skb, 0)) - return NF_DROP; + return EBT_DROP; memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN); return info->target; diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index bfb9f74e2116..b8afe850cf1e 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c @@ -22,7 +22,7 @@ static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, const struct ebt_redirect_info *info = data; if (!skb_make_writable(skb, 0)) - return NF_DROP; + return EBT_DROP; if (hooknr != NF_BR_BROUTING) memcpy(eth_hdr(skb)->h_dest, diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c index 204f9965fb9e..5425333dda03 100644 --- a/net/bridge/netfilter/ebt_snat.c +++ b/net/bridge/netfilter/ebt_snat.c @@ -23,7 +23,7 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, const struct ebt_nat_info *info = data; if (!skb_make_writable(skb, 0)) - return NF_DROP; + return EBT_DROP; memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN); if (!(info->target & NAT_ARP_BIT) && From 038eb0ea04b245351be34b0ae76b55eee4603989 Mon Sep 17 00:00:00 2001 From: Mirco Tischler Date: Sun, 24 Feb 2008 05:16:39 +0100 Subject: [PATCH 659/880] Fix u132-hcd.c compile error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following compile error caused by commit 3a2d5b700132f35401f1d9e22fe3c2cab02c2549 ("PM: Introduce PM_EVENT_HIBERNATE callback state") CC [M] drivers/usb/host/u132-hcd.o drivers/usb/host/u132-hcd.c: In function ‘u132_suspend’: drivers/usb/host/u132-hcd.c:3224: error: expected expression before ‘int’ drivers/usb/host/u132-hcd.c:3225: error: ‘ports’ undeclared (first use in this function) ... Signed-off-by: Mirco Tischler Signed-off-by: Linus Torvalds --- drivers/usb/host/u132-hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 6fca06961559..3033d6945202 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3213,7 +3213,7 @@ static int u132_suspend(struct platform_device *pdev, pm_message_t state) dev_err(&u132->platform_dev->dev, "device is being removed\n"); return -ESHUTDOWN; } else { - int retval = 0; + int retval = 0, ports; switch (state.event) { case PM_EVENT_FREEZE: @@ -3221,7 +3221,7 @@ static int u132_suspend(struct platform_device *pdev, pm_message_t state) break; case PM_EVENT_SUSPEND: case PM_EVENT_HIBERNATE: - int ports = MAX_U132_PORTS; + ports = MAX_U132_PORTS; while (ports-- > 0) { port_power(u132, ports, 0); } From 21eee2dd1b5702f15924f18f923b2a281f0e72e8 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Wed, 13 Feb 2008 16:18:33 +0100 Subject: [PATCH 660/880] ehea: add kdump support This patch adds kdump support to the ehea driver. As the firmware doesn't free resource handles automatically, the driver has to run an as simple as possible free resource function in case of a crash shutdown. The function iterates over two arrays freeing all resource handles which are stored there. The arrays are kept up-to-date during normal runtime. The crash handler fn is triggered by the recently introduced PPC crash shutdown reg/unreg functions. Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea.h | 34 ++++- drivers/net/ehea/ehea_main.c | 281 ++++++++++++++++++++++++++++++++--- 2 files changed, 290 insertions(+), 25 deletions(-) diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 88fb53eba715..7c4ead35cfa2 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0083" +#define DRV_VERSION "EHEA_0087" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 @@ -386,6 +386,13 @@ struct ehea_port_res { #define EHEA_MAX_PORTS 16 + +#define EHEA_NUM_PORTRES_FW_HANDLES 6 /* QP handle, SendCQ handle, + RecvCQ handle, EQ handle, + SendMR handle, RecvMR handle */ +#define EHEA_NUM_PORT_FW_HANDLES 1 /* EQ handle */ +#define EHEA_NUM_ADAPTER_FW_HANDLES 2 /* MR handle, NEQ handle */ + struct ehea_adapter { u64 handle; struct of_device *ofdev; @@ -405,6 +412,31 @@ struct ehea_mc_list { u64 macaddr; }; +/* kdump support */ +struct ehea_fw_handle_entry { + u64 adh; /* Adapter Handle */ + u64 fwh; /* Firmware Handle */ +}; + +struct ehea_fw_handle_array { + struct ehea_fw_handle_entry *arr; + int num_entries; + struct semaphore lock; +}; + +struct ehea_bcmc_reg_entry { + u64 adh; /* Adapter Handle */ + u32 port_id; /* Logical Port Id */ + u8 reg_type; /* Registration Type */ + u64 macaddr; +}; + +struct ehea_bcmc_reg_array { + struct ehea_bcmc_reg_entry *arr; + int num_entries; + struct semaphore lock; +}; + #define EHEA_PORT_UP 1 #define EHEA_PORT_DOWN 0 #define EHEA_PHY_LINK_UP 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index c051c7e09b9a..21af674b764e 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -98,8 +99,10 @@ static int port_name_cnt; static LIST_HEAD(adapter_list); u64 ehea_driver_flags; struct work_struct ehea_rereg_mr_task; - struct semaphore dlpar_mem_lock; +struct ehea_fw_handle_array ehea_fw_handles; +struct ehea_bcmc_reg_array ehea_bcmc_regs; + static int __devinit ehea_probe_adapter(struct of_device *dev, const struct of_device_id *id); @@ -132,6 +135,160 @@ void ehea_dump(void *adr, int len, char *msg) } } +static void ehea_update_firmware_handles(void) +{ + struct ehea_fw_handle_entry *arr = NULL; + struct ehea_adapter *adapter; + int num_adapters = 0; + int num_ports = 0; + int num_portres = 0; + int i = 0; + int num_fw_handles, k, l; + + /* Determine number of handles */ + list_for_each_entry(adapter, &adapter_list, list) { + num_adapters++; + + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + num_ports++; + num_portres += port->num_def_qps + port->num_add_tx_qps; + } + } + + num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES + + num_ports * EHEA_NUM_PORT_FW_HANDLES + + num_portres * EHEA_NUM_PORTRES_FW_HANDLES; + + if (num_fw_handles) { + arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL); + if (!arr) + return; /* Keep the existing array */ + } else + goto out_update; + + list_for_each_entry(adapter, &adapter_list, list) { + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + for (l = 0; + l < port->num_def_qps + port->num_add_tx_qps; + l++) { + struct ehea_port_res *pr = &port->port_res[l]; + + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->qp->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->send_cq->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->recv_cq->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->eq->fw_handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->send_mr.handle; + arr[i].adh = adapter->handle; + arr[i++].fwh = pr->recv_mr.handle; + } + arr[i].adh = adapter->handle; + arr[i++].fwh = port->qp_eq->fw_handle; + } + + arr[i].adh = adapter->handle; + arr[i++].fwh = adapter->neq->fw_handle; + + if (adapter->mr.handle) { + arr[i].adh = adapter->handle; + arr[i++].fwh = adapter->mr.handle; + } + } + +out_update: + kfree(ehea_fw_handles.arr); + ehea_fw_handles.arr = arr; + ehea_fw_handles.num_entries = i; +} + +static void ehea_update_bcmc_registrations(void) +{ + struct ehea_bcmc_reg_entry *arr = NULL; + struct ehea_adapter *adapter; + struct ehea_mc_list *mc_entry; + int num_registrations = 0; + int i = 0; + int k; + + /* Determine number of registrations */ + list_for_each_entry(adapter, &adapter_list, list) + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + num_registrations += 2; /* Broadcast registrations */ + + list_for_each_entry(mc_entry, &port->mc_list->list,list) + num_registrations += 2; + } + + if (num_registrations) { + arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL); + if (!arr) + return; /* Keep the existing array */ + } else + goto out_update; + + list_for_each_entry(adapter, &adapter_list, list) { + for (k = 0; k < EHEA_MAX_PORTS; k++) { + struct ehea_port *port = adapter->port[k]; + + if (!port || (port->state != EHEA_PORT_UP)) + continue; + + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_BROADCAST | + EHEA_BCMC_UNTAGGED; + arr[i++].macaddr = port->mac_addr; + + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_BROADCAST | + EHEA_BCMC_VLANID_ALL; + arr[i++].macaddr = port->mac_addr; + + list_for_each_entry(mc_entry, + &port->mc_list->list, list) { + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | + EHEA_BCMC_UNTAGGED; + arr[i++].macaddr = mc_entry->macaddr; + + arr[i].adh = adapter->handle; + arr[i].port_id = port->logical_port_id; + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | + EHEA_BCMC_VLANID_ALL; + arr[i++].macaddr = mc_entry->macaddr; + } + } + } + +out_update: + kfree(ehea_bcmc_regs.arr); + ehea_bcmc_regs.arr = arr; + ehea_bcmc_regs.num_entries = i; +} + static struct net_device_stats *ehea_get_stats(struct net_device *dev) { struct ehea_port *port = netdev_priv(dev); @@ -1601,19 +1758,25 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); + down(&ehea_bcmc_regs.lock); + /* Deregister old MAC in pHYP */ ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); if (ret) - goto out_free; + goto out_upregs; port->mac_addr = cb0->port_mac_addr << 16; /* Register new MAC in pHYP */ ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); if (ret) - goto out_free; + goto out_upregs; ret = 0; + +out_upregs: + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); out_free: kfree(cb0); out: @@ -1775,9 +1938,11 @@ static void ehea_set_multicast_list(struct net_device *dev) } ehea_promiscuous(dev, 0); + down(&ehea_bcmc_regs.lock); + if (dev->flags & IFF_ALLMULTI) { ehea_allmulti(dev, 1); - return; + goto out; } ehea_allmulti(dev, 0); @@ -1803,6 +1968,8 @@ static void ehea_set_multicast_list(struct net_device *dev) } out: + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); return; } @@ -2285,6 +2452,8 @@ static int ehea_up(struct net_device *dev) if (port->state == EHEA_PORT_UP) return 0; + down(&ehea_fw_handles.lock); + ret = ehea_port_res_setup(port, port->num_def_qps, port->num_add_tx_qps); if (ret) { @@ -2321,8 +2490,17 @@ static int ehea_up(struct net_device *dev) } } - ret = 0; + down(&ehea_bcmc_regs.lock); + + ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); + if (ret) { + ret = -EIO; + goto out_free_irqs; + } + port->state = EHEA_PORT_UP; + + ret = 0; goto out; out_free_irqs: @@ -2334,6 +2512,12 @@ static int ehea_up(struct net_device *dev) if (ret) ehea_info("Failed starting %s. ret=%i", dev->name, ret); + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); + + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); + return ret; } @@ -2382,16 +2566,27 @@ static int ehea_down(struct net_device *dev) if (port->state == EHEA_PORT_DOWN) return 0; + down(&ehea_bcmc_regs.lock); ehea_drop_multicast_list(dev); + ehea_broadcast_reg_helper(port, H_DEREG_BCMC); + ehea_free_interrupts(dev); + down(&ehea_fw_handles.lock); + port->state = EHEA_PORT_DOWN; + ehea_update_bcmc_registrations(); + up(&ehea_bcmc_regs.lock); + ret = ehea_clean_all_portres(port); if (ret) ehea_info("Failed freeing resources for %s. ret=%i", dev->name, ret); + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); + return ret; } @@ -2920,19 +3115,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; INIT_WORK(&port->reset_task, ehea_reset_port); - - ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); - if (ret) { - ret = -EIO; - goto out_unreg_port; - } - ehea_set_ethtool_ops(dev); ret = register_netdev(dev); if (ret) { ehea_error("register_netdev failed. ret=%d", ret); - goto out_dereg_bc; + goto out_unreg_port; } port->lro_max_aggr = lro_max_aggr; @@ -2949,9 +3137,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, return port; -out_dereg_bc: - ehea_broadcast_reg_helper(port, H_DEREG_BCMC); - out_unreg_port: ehea_unregister_port(port); @@ -2971,7 +3156,6 @@ static void ehea_shutdown_single_port(struct ehea_port *port) { unregister_netdev(port->netdev); ehea_unregister_port(port); - ehea_broadcast_reg_helper(port, H_DEREG_BCMC); kfree(port->mc_list); free_netdev(port->netdev); port->adapter->active_ports--; @@ -3014,7 +3198,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) i++; }; - return 0; } @@ -3159,6 +3342,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, ehea_error("Invalid ibmebus device probed"); return -EINVAL; } + down(&ehea_fw_handles.lock); adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); if (!adapter) { @@ -3239,7 +3423,10 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, out_free_ad: kfree(adapter); + out: + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); return ret; } @@ -3258,18 +3445,41 @@ static int __devexit ehea_remove(struct of_device *dev) flush_scheduled_work(); + down(&ehea_fw_handles.lock); + ibmebus_free_irq(adapter->neq->attr.ist1, adapter); tasklet_kill(&adapter->neq_tasklet); ehea_destroy_eq(adapter->neq); ehea_remove_adapter_mr(adapter); list_del(&adapter->list); - kfree(adapter); + ehea_update_firmware_handles(); + up(&ehea_fw_handles.lock); + return 0; } +void ehea_crash_handler(void) +{ + int i; + + if (ehea_fw_handles.arr) + for (i = 0; i < ehea_fw_handles.num_entries; i++) + ehea_h_free_resource(ehea_fw_handles.arr[i].adh, + ehea_fw_handles.arr[i].fwh, + FORCE_FREE); + + if (ehea_bcmc_regs.arr) + for (i = 0; i < ehea_bcmc_regs.num_entries; i++) + ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh, + ehea_bcmc_regs.arr[i].port_id, + ehea_bcmc_regs.arr[i].reg_type, + ehea_bcmc_regs.arr[i].macaddr, + 0, H_DEREG_BCMC); +} + static int ehea_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused) { @@ -3330,7 +3540,12 @@ int __init ehea_module_init(void) INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs); + memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles)); + memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); + sema_init(&dlpar_mem_lock, 1); + sema_init(&ehea_fw_handles.lock, 1); + sema_init(&ehea_bcmc_regs.lock, 1); ret = check_module_parm(); if (ret) @@ -3340,12 +3555,18 @@ int __init ehea_module_init(void) if (ret) goto out; - register_reboot_notifier(&ehea_reboot_nb); + ret = register_reboot_notifier(&ehea_reboot_nb); + if (ret) + ehea_info("failed registering reboot notifier"); + + ret = crash_shutdown_register(&ehea_crash_handler); + if (ret) + ehea_info("failed registering crash handler"); ret = ibmebus_register_driver(&ehea_driver); if (ret) { ehea_error("failed registering eHEA device driver on ebus"); - goto out; + goto out2; } ret = driver_create_file(&ehea_driver.driver, @@ -3353,21 +3574,33 @@ int __init ehea_module_init(void) if (ret) { ehea_error("failed to register capabilities attribute, ret=%d", ret); - unregister_reboot_notifier(&ehea_reboot_nb); - ibmebus_unregister_driver(&ehea_driver); - goto out; + goto out3; } + return ret; + +out3: + ibmebus_unregister_driver(&ehea_driver); +out2: + unregister_reboot_notifier(&ehea_reboot_nb); + crash_shutdown_unregister(&ehea_crash_handler); out: return ret; } static void __exit ehea_module_exit(void) { + int ret; + flush_scheduled_work(); driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); unregister_reboot_notifier(&ehea_reboot_nb); + ret = crash_shutdown_unregister(&ehea_crash_handler); + if (ret) + ehea_info("failed unregistering crash handler"); + kfree(ehea_fw_handles.arr); + kfree(ehea_bcmc_regs.arr); ehea_destroy_busmap(); } From 5bd3670f31f1c58f500e55c4cdbc243fb4b2e3df Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 15 Feb 2008 15:08:04 -0600 Subject: [PATCH 661/880] fs_enet: Don't call phy_mii_ioctl() in atomic context. The lock acquisition in fs_ioctl() does not appear to actually be necessary, and thus is simply removed. Signed-off-by: Scott Wood Signed-off-by: Jeff Garzik --- drivers/net/fs_enet/fs_enet-main.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 42d94edeee26..af869cf9ae7d 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -946,16 +946,11 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct fs_enet_private *fep = netdev_priv(dev); struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data; - unsigned long flags; - int rc; if (!netif_running(dev)) return -EINVAL; - spin_lock_irqsave(&fep->lock, flags); - rc = phy_mii_ioctl(fep->phydev, mii, cmd); - spin_unlock_irqrestore(&fep->lock, flags); - return rc; + return phy_mii_ioctl(fep->phydev, mii, cmd); } extern int fs_mii_connect(struct net_device *dev); From 6cb5e57701d355737f0bc9f94c0f80ed69a95b62 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Fri, 15 Feb 2008 14:05:25 -0800 Subject: [PATCH 662/880] igb: fix legacy mode irq issue I booted an igb kernel with the option pci=nomsi and instantly noticed that interrupts no longer worked on my igb device. I took a look at the interrupt initialization and quickly discovered a comment stating: "DO NOT USE EIAME or IAME in legacy mode" It seemed a bit odd that bits to enable IAM were being set in legacy interrupt mode, so I dropped out the following parts and interrupts began working fine again. [Updated code flow and a nitpick spelling error --Auke] Signed-off-by: Andy Gospodarek Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/igb/igb_main.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index bff280eff5e3..3480cc72467a 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -439,7 +439,7 @@ static int igb_request_irq(struct igb_adapter *adapter) err = igb_request_msix(adapter); if (!err) { /* enable IAM, auto-mask, - * DO NOT USE EIAME or IAME in legacy mode */ + * DO NOT USE EIAM or IAM in legacy mode */ wr32(E1000_IAM, IMS_ENABLE_MASK); goto request_done; } @@ -465,14 +465,9 @@ static int igb_request_irq(struct igb_adapter *adapter) err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED, netdev->name, netdev); - if (err) { + if (err) dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n", err); - goto request_done; - } - - /* enable IAM, auto-mask */ - wr32(E1000_IAM, IMS_ENABLE_MASK); request_done: return err; From 740db6d7f5bf194abf327613a5a500e3729fc19a Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Sun, 17 Feb 2008 11:53:49 -0700 Subject: [PATCH 663/880] update TULIP MAINTAINERS Kyle and I are co-maintaining tulip driver. Normally kyle will review my patchs and submit them. I'll deal with bugzilla.kernel.org bugs and try to resolve those bugs. Signed-off-by: Grant Grundler Signed-off-by: Jeff Garzik --- MAINTAINERS | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 36c7bc641dba..2333255417f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3884,10 +3884,13 @@ M: trivial@kernel.org L: linux-kernel@vger.kernel.org S: Maintained -TULIP NETWORK DRIVER -L: tulip-users@lists.sourceforge.net -W: http://sourceforge.net/projects/tulip/ -S: Orphan +TULIP NETWORK DRIVERS +P: Grant Grundler +M: grundler@parisc-linux.org +P: Kyle McMartin +M: kyle@parisc-linux.org +L: netdev@vger.kernel.org +S: Maintained TUN/TAP driver P: Maxim Krasnyansky From 7a7d23dac29825a75e375800573d53e49d864a42 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Sun, 17 Feb 2008 11:30:23 -0700 Subject: [PATCH 664/880] uli526x partially recognizing interface Patch fixes: http://bugzilla.kernel.org/show_bug.cgi?id=5839 Init sequence needs to poll phy until phy reset is complete. This is the same problem that I fixed in 2002 in tulip driver. Thanks to manty@manty.net for testing this patch. Thanks to Pozsar Balazs for posting/testing a similar patch before: http://lkml.org/lkml/2006/8/21/45 Signed-off-by: Grant Grundler Signed-off-by: Jeff Garzik --- drivers/net/tulip/uli526x.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index a7afeea156bd..a59c1f224aa8 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -482,9 +482,11 @@ static void uli526x_init(struct net_device *dev) struct uli526x_board_info *db = netdev_priv(dev); unsigned long ioaddr = db->ioaddr; u8 phy_tmp; + u8 timeout; u16 phy_value; u16 phy_reg_reset; + ULI526X_DBUG(0, "uli526x_init()", 0); /* Reset M526x MAC controller */ @@ -509,11 +511,19 @@ static void uli526x_init(struct net_device *dev) /* Parser SROM and media mode */ db->media_mode = uli526x_media_mode; - /* Phyxcer capability setting */ + /* phyxcer capability setting */ phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id); phy_reg_reset = (phy_reg_reset | 0x8000); phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id); + + /* See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management + * functions") or phy data sheet for details on phy reset + */ udelay(500); + timeout = 10; + while (timeout-- && + phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id) & 0x8000) + udelay(100); /* Process Phyxcer Media Mode */ uli526x_set_phyxcer(db); From d9d5dcc88ca5c72237e2d09d23a13a9b9d1e7445 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 18 Feb 2008 10:02:51 +0100 Subject: [PATCH 665/880] virtio_net: Fix oops on early interrupts - introduced by virtio reset code Signed-off-by: Jeff Garzik --- drivers/net/virtio_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index fdc23678117b..19fd4cb0ddf8 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -361,6 +361,7 @@ static int virtnet_probe(struct virtio_device *vdev) netif_napi_add(dev, &vi->napi, virtnet_poll, napi_weight); vi->dev = dev; vi->vdev = vdev; + vdev->priv = vi; /* We expect two virtqueues, receive then send. */ vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); @@ -395,7 +396,6 @@ static int virtnet_probe(struct virtio_device *vdev) } pr_debug("virtnet: registered device %s\n", dev->name); - vdev->priv = vi; return 0; unregister: From a80763c9090fe03a1af98f0106b2aaa4ad6502f9 Mon Sep 17 00:00:00 2001 From: Leonardo Potenza Date: Sun, 17 Feb 2008 18:23:15 +0100 Subject: [PATCH 666/880] drivers/net/cs89x0.c: compilation warning fix Suppress the warning message about the 'netcard_portlist' defined but not used. Signed-off-by: Leonardo Potenza Signed-off-by: Jeff Garzik --- drivers/net/cs89x0.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 571750975137..348371fda597 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -172,30 +172,30 @@ static char version[] __initdata = them to system IRQ numbers. This mapping is card specific and is set to the configuration of the Cirrus Eval board for this chip. */ #ifdef CONFIG_ARCH_CLPS7500 -static unsigned int netcard_portlist[] __initdata = +static unsigned int netcard_portlist[] __used __initdata = { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int cs8900_irq_map[] = {12,0,0,0}; #elif defined(CONFIG_SH_HICOSH4) -static unsigned int netcard_portlist[] __initdata = +static unsigned int netcard_portlist[] __used __initdata = { 0x0300, 0}; static unsigned int cs8900_irq_map[] = {1,0,0,0}; #elif defined(CONFIG_MACH_IXDP2351) -static unsigned int netcard_portlist[] __initdata = {IXDP2351_VIRT_CS8900_BASE, 0}; +static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; #include #elif defined(CONFIG_ARCH_IXDP2X01) #include -static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; +static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; #elif defined(CONFIG_ARCH_PNX010X) #include #include #define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */ #define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */ -static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0}; +static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0}; static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0}; #else -static unsigned int netcard_portlist[] __initdata = +static unsigned int netcard_portlist[] __used __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int cs8900_irq_map[] = {10,11,12,5}; #endif From 61da96be07ec860e260ca4af0199b9d48d000b80 Mon Sep 17 00:00:00 2001 From: Komuro Date: Mon, 18 Feb 2008 22:06:19 +0900 Subject: [PATCH 667/880] pcnet_cs: if AX88190-based card, printk "use axnet_cs instead" message. * If ConfigBase is 0x03c0 && manfid is (0x0149,0xc1ab), printk "use axnet_cs instead" message. Actually, most of the card with manfid(0x0149, 0xc1ab) use pcnet_cs driver. * remove entry (0x021b, 0x0202) Signed-off-by: Komuro Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/pcnet_cs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 6323988dfa1d..fd8158a86f64 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -590,6 +590,13 @@ static int pcnet_config(struct pcmcia_device *link) dev->if_port = 0; } + if ((link->conf.ConfigBase == 0x03c0) + && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) { + printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n"); + printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n"); + goto failed; + } + local_hw_info = get_hwinfo(link); if (local_hw_info == NULL) local_hw_info = get_prom(link); @@ -1567,12 +1574,11 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145), PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230), PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), -/* PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), conflict with axnet_cs */ + PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), -/* PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), conflict with axnet_cs */ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a), From f5154fbf4902744cdd2bb7548487ceaac9840fd2 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 18 Feb 2008 14:41:55 +0100 Subject: [PATCH 668/880] claw: make use of DIV_ROUND_UP The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. Signed-off-by: Ursula Braun Signed-off-by: Jeff Garzik --- drivers/s390/net/claw.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index c3076217871e..d8a5c229c5a7 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -1851,8 +1851,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid) } } /* See how many write buffers are required to hold this data */ - numBuffers= ( skb->len + privptr->p_env->write_size - 1) / - ( privptr->p_env->write_size); + numBuffers = DIV_ROUND_UP(skb->len, privptr->p_env->write_size); /* If that number of buffers isn't available, give up for now */ if (privptr->write_free_count < numBuffers || @@ -2114,8 +2113,7 @@ init_ccw_bk(struct net_device *dev) */ ccw_blocks_perpage= PAGE_SIZE / CCWBK_SIZE; ccw_pages_required= - (ccw_blocks_required+ccw_blocks_perpage -1) / - ccw_blocks_perpage; + DIV_ROUND_UP(ccw_blocks_required, ccw_blocks_perpage); #ifdef DEBUGMSG printk(KERN_INFO "%s: %s() > ccw_blocks_perpage=%d\n", @@ -2131,30 +2129,29 @@ init_ccw_bk(struct net_device *dev) * provide good performance. With packing buffers support 32k * buffers are used. */ - if (privptr->p_env->read_size < PAGE_SIZE) { - claw_reads_perpage= PAGE_SIZE / privptr->p_env->read_size; - claw_read_pages= (privptr->p_env->read_buffers + - claw_reads_perpage -1) / claw_reads_perpage; + if (privptr->p_env->read_size < PAGE_SIZE) { + claw_reads_perpage = PAGE_SIZE / privptr->p_env->read_size; + claw_read_pages = DIV_ROUND_UP(privptr->p_env->read_buffers, + claw_reads_perpage); } else { /* > or equal */ - privptr->p_buff_pages_perread= - (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE; - claw_read_pages= - privptr->p_env->read_buffers * privptr->p_buff_pages_perread; + privptr->p_buff_pages_perread = + DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE); + claw_read_pages = privptr->p_env->read_buffers * + privptr->p_buff_pages_perread; } if (privptr->p_env->write_size < PAGE_SIZE) { - claw_writes_perpage= - PAGE_SIZE / privptr->p_env->write_size; - claw_write_pages= - (privptr->p_env->write_buffers + claw_writes_perpage -1) / - claw_writes_perpage; + claw_writes_perpage = + PAGE_SIZE / privptr->p_env->write_size; + claw_write_pages = DIV_ROUND_UP(privptr->p_env->write_buffers, + claw_writes_perpage); } else { /* > or equal */ - privptr->p_buff_pages_perwrite= - (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE; - claw_write_pages= - privptr->p_env->write_buffers * privptr->p_buff_pages_perwrite; + privptr->p_buff_pages_perwrite = + DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE); + claw_write_pages = privptr->p_env->write_buffers * + privptr->p_buff_pages_perwrite; } #ifdef DEBUGMSG if (privptr->p_env->read_size < PAGE_SIZE) { From 98e0f521456943801aacc7a4c0efb5b3bb6f89e0 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Mon, 18 Feb 2008 10:04:38 -0800 Subject: [PATCH 669/880] tlan: add static to function definitions The forward declarations were already marked static, make the definitions be static as well. Fixes the sparse warnings as well. drivers/net/tlan.c:1403:5: warning: symbol 'TLan_HandleInvalid' was not declared. Should it be static? drivers/net/tlan.c:1435:5: warning: symbol 'TLan_HandleTxEOF' was not declared. Should it be static? drivers/net/tlan.c:1521:5: warning: symbol 'TLan_HandleStatOverflow' was not declared. Should it be static? drivers/net/tlan.c:1557:5: warning: symbol 'TLan_HandleRxEOF' was not declared. Should it be static? drivers/net/tlan.c:1692:5: warning: symbol 'TLan_HandleDummy' was not declared. Should it be static? drivers/net/tlan.c:1722:5: warning: symbol 'TLan_HandleTxEOC' was not declared. Should it be static? drivers/net/tlan.c:1770:5: warning: symbol 'TLan_HandleStatusCheck' was not declared. Should it be static? drivers/net/tlan.c:1845:5: warning: symbol 'TLan_HandleRxEOC' was not declared. Should it be static? drivers/net/tlan.c:1905:6: warning: symbol 'TLan_Timer' was not declared. Should it be static? drivers/net/tlan.c:1986:6: warning: symbol 'TLan_ResetLists' was not declared. Should it be static? drivers/net/tlan.c:2046:6: warning: symbol 'TLan_FreeLists' was not declared. Should it be static? drivers/net/tlan.c:2095:6: warning: symbol 'TLan_PrintDio' was not declared. Should it be static? drivers/net/tlan.c:2130:6: warning: symbol 'TLan_PrintList' was not declared. Should it be static? drivers/net/tlan.c:2166:6: warning: symbol 'TLan_ReadAndClearStats' was not declared. Should it be static? drivers/net/tlan.c:2242:1: warning: symbol 'TLan_ResetAdapter' was not declared. Should it be static? drivers/net/tlan.c:2328:1: warning: symbol 'TLan_FinishReset' was not declared. Should it be static? drivers/net/tlan.c:2451:6: warning: symbol 'TLan_SetMac' was not declared. Should it be static? drivers/net/tlan.c:2493:6: warning: symbol 'TLan_PhyPrint' was not declared. Should it be static? drivers/net/tlan.c:2542:6: warning: symbol 'TLan_PhyDetect' was not declared. Should it be static? drivers/net/tlan.c:2589:6: warning: symbol 'TLan_PhyPowerDown' was not declared. Should it be static? drivers/net/tlan.c:2614:6: warning: symbol 'TLan_PhyPowerUp' was not declared. Should it be static? drivers/net/tlan.c:2635:6: warning: symbol 'TLan_PhyReset' was not declared. Should it be static? drivers/net/tlan.c:2663:6: warning: symbol 'TLan_PhyStartLink' was not declared. Should it be static? drivers/net/tlan.c:2750:6: warning: symbol 'TLan_PhyFinishAutoNeg' was not declared. Should it be static? drivers/net/tlan.c:2906:5: warning: symbol 'TLan_MiiReadReg' was not declared. Should it be static? drivers/net/tlan.c:2996:6: warning: symbol 'TLan_MiiSendData' was not declared. Should it be static? drivers/net/tlan.c:3038:6: warning: symbol 'TLan_MiiSync' was not declared. Should it be static? drivers/net/tlan.c:3077:6: warning: symbol 'TLan_MiiWriteReg' was not declared. Should it be static? drivers/net/tlan.c:3147:6: warning: symbol 'TLan_EeSendStart' was not declared. Should it be static? drivers/net/tlan.c:3187:5: warning: symbol 'TLan_EeSendByte' was not declared. Should it be static? drivers/net/tlan.c:3248:6: warning: symbol 'TLan_EeReceiveByte' was not declared. Should it be static? drivers/net/tlan.c:3306:5: warning: symbol 'TLan_EeReadByte' was not declared. Should it be static? Signed-off-by: Harvey Harrison Signed-off-by: Jeff Garzik --- drivers/net/tlan.c | 64 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 3af5b92b48c8..0166407d7061 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -1400,7 +1400,7 @@ static void TLan_SetMulticastList( struct net_device *dev ) * **************************************************************/ -u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) { /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */ return 0; @@ -1432,7 +1432,7 @@ u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); int eoc = 0; @@ -1518,7 +1518,7 @@ u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) { TLan_ReadAndClearStats( dev, TLAN_RECORD ); @@ -1554,7 +1554,7 @@ u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); u32 ack = 0; @@ -1689,7 +1689,7 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) { printk( "TLAN: Test interrupt on %s.\n", dev->name ); return 1; @@ -1719,7 +1719,7 @@ u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); TLanList *head_list; @@ -1767,7 +1767,7 @@ u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); u32 ack; @@ -1842,7 +1842,7 @@ u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) * **************************************************************/ -u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) +static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = netdev_priv(dev); dma_addr_t head_list_phys; @@ -1902,7 +1902,7 @@ u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) * **************************************************************/ -void TLan_Timer( unsigned long data ) +static void TLan_Timer( unsigned long data ) { struct net_device *dev = (struct net_device *) data; TLanPrivateInfo *priv = netdev_priv(dev); @@ -1983,7 +1983,7 @@ void TLan_Timer( unsigned long data ) * **************************************************************/ -void TLan_ResetLists( struct net_device *dev ) +static void TLan_ResetLists( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); int i; @@ -2043,7 +2043,7 @@ void TLan_ResetLists( struct net_device *dev ) } /* TLan_ResetLists */ -void TLan_FreeLists( struct net_device *dev ) +static void TLan_FreeLists( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); int i; @@ -2092,7 +2092,7 @@ void TLan_FreeLists( struct net_device *dev ) * **************************************************************/ -void TLan_PrintDio( u16 io_base ) +static void TLan_PrintDio( u16 io_base ) { u32 data0, data1; int i; @@ -2127,7 +2127,7 @@ void TLan_PrintDio( u16 io_base ) * **************************************************************/ -void TLan_PrintList( TLanList *list, char *type, int num) +static void TLan_PrintList( TLanList *list, char *type, int num) { int i; @@ -2163,7 +2163,7 @@ void TLan_PrintList( TLanList *list, char *type, int num) * **************************************************************/ -void TLan_ReadAndClearStats( struct net_device *dev, int record ) +static void TLan_ReadAndClearStats( struct net_device *dev, int record ) { TLanPrivateInfo *priv = netdev_priv(dev); u32 tx_good, tx_under; @@ -2238,7 +2238,7 @@ void TLan_ReadAndClearStats( struct net_device *dev, int record ) * **************************************************************/ -void +static void TLan_ResetAdapter( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); @@ -2324,7 +2324,7 @@ TLan_ResetAdapter( struct net_device *dev ) -void +static void TLan_FinishReset( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); @@ -2448,7 +2448,7 @@ TLan_FinishReset( struct net_device *dev ) * **************************************************************/ -void TLan_SetMac( struct net_device *dev, int areg, char *mac ) +static void TLan_SetMac( struct net_device *dev, int areg, char *mac ) { int i; @@ -2490,7 +2490,7 @@ void TLan_SetMac( struct net_device *dev, int areg, char *mac ) * ********************************************************************/ -void TLan_PhyPrint( struct net_device *dev ) +static void TLan_PhyPrint( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 i, data0, data1, data2, data3, phy; @@ -2539,7 +2539,7 @@ void TLan_PhyPrint( struct net_device *dev ) * ********************************************************************/ -void TLan_PhyDetect( struct net_device *dev ) +static void TLan_PhyDetect( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 control; @@ -2586,7 +2586,7 @@ void TLan_PhyDetect( struct net_device *dev ) -void TLan_PhyPowerDown( struct net_device *dev ) +static void TLan_PhyPowerDown( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 value; @@ -2611,7 +2611,7 @@ void TLan_PhyPowerDown( struct net_device *dev ) -void TLan_PhyPowerUp( struct net_device *dev ) +static void TLan_PhyPowerUp( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 value; @@ -2632,7 +2632,7 @@ void TLan_PhyPowerUp( struct net_device *dev ) -void TLan_PhyReset( struct net_device *dev ) +static void TLan_PhyReset( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 phy; @@ -2660,7 +2660,7 @@ void TLan_PhyReset( struct net_device *dev ) -void TLan_PhyStartLink( struct net_device *dev ) +static void TLan_PhyStartLink( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 ability; @@ -2747,7 +2747,7 @@ void TLan_PhyStartLink( struct net_device *dev ) -void TLan_PhyFinishAutoNeg( struct net_device *dev ) +static void TLan_PhyFinishAutoNeg( struct net_device *dev ) { TLanPrivateInfo *priv = netdev_priv(dev); u16 an_adv; @@ -2903,7 +2903,7 @@ void TLan_PhyMonitor( struct net_device *dev ) * **************************************************************/ -int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) +static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) { u8 nack; u16 sio, tmp; @@ -2993,7 +2993,7 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) * **************************************************************/ -void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) +static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) { u16 sio; u32 i; @@ -3035,7 +3035,7 @@ void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) * **************************************************************/ -void TLan_MiiSync( u16 base_port ) +static void TLan_MiiSync( u16 base_port ) { int i; u16 sio; @@ -3074,7 +3074,7 @@ void TLan_MiiSync( u16 base_port ) * **************************************************************/ -void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) +static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) { u16 sio; int minten; @@ -3144,7 +3144,7 @@ void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) * **************************************************************/ -void TLan_EeSendStart( u16 io_base ) +static void TLan_EeSendStart( u16 io_base ) { u16 sio; @@ -3184,7 +3184,7 @@ void TLan_EeSendStart( u16 io_base ) * **************************************************************/ -int TLan_EeSendByte( u16 io_base, u8 data, int stop ) +static int TLan_EeSendByte( u16 io_base, u8 data, int stop ) { int err; u8 place; @@ -3245,7 +3245,7 @@ int TLan_EeSendByte( u16 io_base, u8 data, int stop ) * **************************************************************/ -void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) +static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) { u8 place; u16 sio; @@ -3303,7 +3303,7 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) * **************************************************************/ -int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) +static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) { int err; TLanPrivateInfo *priv = netdev_priv(dev); From 563e0ae06ff18f0b280f11cf706ba0172255ce52 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 18 Feb 2008 21:20:32 +0100 Subject: [PATCH 670/880] sis190: read the mac address from the eeprom first Reading a serie of zero from the cmos sram area do not work well with is_valid_ether_addr(). Let's read the mac address from the eeprom first as it seems more reliable. Fix for http://bugzilla.kernel.org/show_bug.cgi?id=9831 Signed-off-by: Francois Romieu Signed-off-by: Jeff Garzik --- drivers/net/sis190.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 202fdf356621..20745fd4e973 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1633,13 +1633,18 @@ static inline void sis190_init_rxfilter(struct net_device *dev) static int __devinit sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev) { - u8 from; + int rc; + + rc = sis190_get_mac_addr_from_eeprom(pdev, dev); + if (rc < 0) { + u8 reg; - pci_read_config_byte(pdev, 0x73, &from); + pci_read_config_byte(pdev, 0x73, ®); - return (from & 0x00000001) ? - sis190_get_mac_addr_from_apc(pdev, dev) : - sis190_get_mac_addr_from_eeprom(pdev, dev); + if (reg & 0x00000001) + rc = sis190_get_mac_addr_from_apc(pdev, dev); + } + return rc; } static void sis190_set_speed_auto(struct net_device *dev) From cf7822983f21617b805712eec46eb31058508d6a Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Mon, 18 Feb 2008 17:24:30 -0600 Subject: [PATCH 671/880] gianfar: don't pass NULL dev ptr to DMA ops Change all dma op invocations in gianfar.c to actually pass in the device pointer. Currently, the value is ignored, but it will be used going forward as we implement archdata for 32-bit powerpc. Signed-off-by: Becky Bruce Acked-by: Andy Fleming Signed-off-by: Jeff Garzik --- drivers/net/gianfar.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 4244fc282f21..718cf77e345a 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -605,7 +605,7 @@ void stop_gfar(struct net_device *dev) free_skb_resources(priv); - dma_free_coherent(NULL, + dma_free_coherent(&dev->dev, sizeof(struct txbd8)*priv->tx_ring_size + sizeof(struct rxbd8)*priv->rx_ring_size, priv->tx_bd_base, @@ -626,7 +626,7 @@ static void free_skb_resources(struct gfar_private *priv) for (i = 0; i < priv->tx_ring_size; i++) { if (priv->tx_skbuff[i]) { - dma_unmap_single(NULL, txbdp->bufPtr, + dma_unmap_single(&priv->dev->dev, txbdp->bufPtr, txbdp->length, DMA_TO_DEVICE); dev_kfree_skb_any(priv->tx_skbuff[i]); @@ -643,7 +643,7 @@ static void free_skb_resources(struct gfar_private *priv) if(priv->rx_skbuff != NULL) { for (i = 0; i < priv->rx_ring_size; i++) { if (priv->rx_skbuff[i]) { - dma_unmap_single(NULL, rxbdp->bufPtr, + dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr, priv->rx_buffer_size, DMA_FROM_DEVICE); @@ -708,7 +708,7 @@ int startup_gfar(struct net_device *dev) gfar_write(®s->imask, IMASK_INIT_CLEAR); /* Allocate memory for the buffer descriptors */ - vaddr = (unsigned long) dma_alloc_coherent(NULL, + vaddr = (unsigned long) dma_alloc_coherent(&dev->dev, sizeof (struct txbd8) * priv->tx_ring_size + sizeof (struct rxbd8) * priv->rx_ring_size, &addr, GFP_KERNEL); @@ -919,7 +919,7 @@ int startup_gfar(struct net_device *dev) rx_skb_fail: free_skb_resources(priv); tx_skb_fail: - dma_free_coherent(NULL, + dma_free_coherent(&dev->dev, sizeof(struct txbd8)*priv->tx_ring_size + sizeof(struct rxbd8)*priv->rx_ring_size, priv->tx_bd_base, @@ -1053,7 +1053,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Set buffer length and pointer */ txbdp->length = skb->len; - txbdp->bufPtr = dma_map_single(NULL, skb->data, + txbdp->bufPtr = dma_map_single(&dev->dev, skb->data, skb->len, DMA_TO_DEVICE); /* Save the skb pointer so we can free it later */ @@ -1332,7 +1332,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp) */ skb_reserve(skb, alignamount); - bdp->bufPtr = dma_map_single(NULL, skb->data, + bdp->bufPtr = dma_map_single(&dev->dev, skb->data, priv->rx_buffer_size, DMA_FROM_DEVICE); bdp->length = 0; From 68707acb5b5d4e2b7583cbff0883516afed54d4f Mon Sep 17 00:00:00 2001 From: Bill Hayes Date: Tue, 19 Feb 2008 10:24:41 -0800 Subject: [PATCH 672/880] igb: Fix panic with NICs with 1000BASE-SX PHY This patch eliminates a kernel panic with the igb driver in 2.6.25-rc2 when running on a Intel 82575 Ethernet controller with a 1000BASE-SX PHY. The panic does not happen with the 1000BASE-T PHY, only with a SX connection. Signed-off-by: Bill Hayes Signed-off-by: Andy Gospodarek Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/igb/igb_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 3480cc72467a..6a1f23092099 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -816,7 +816,8 @@ void igb_reset(struct igb_adapter *adapter) wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE); igb_reset_adaptive(&adapter->hw); - adapter->hw.phy.ops.get_phy_info(&adapter->hw); + if (adapter->hw.phy.ops.get_phy_info) + adapter->hw.phy.ops.get_phy_info(&adapter->hw); } /** @@ -2052,7 +2053,8 @@ static void igb_set_multi(struct net_device *netdev) static void igb_update_phy_info(unsigned long data) { struct igb_adapter *adapter = (struct igb_adapter *) data; - adapter->hw.phy.ops.get_phy_info(&adapter->hw); + if (adapter->hw.phy.ops.get_phy_info) + adapter->hw.phy.ops.get_phy_info(&adapter->hw); } /** From d1e7fe4d92742dd1aa28ca11512628adc79a904b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 20 Feb 2008 02:13:53 +0200 Subject: [PATCH 673/880] net/phy/mdio_bus.c: fix a check-after-use This patch fixes a check-after-use spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/phy/mdio_bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 6e9f619c491f..963630c65ca9 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -49,13 +49,13 @@ int mdiobus_register(struct mii_bus *bus) int i; int err = 0; - mutex_init(&bus->mdio_lock); - if (NULL == bus || NULL == bus->name || NULL == bus->read || NULL == bus->write) return -EINVAL; + mutex_init(&bus->mdio_lock); + if (bus->reset) bus->reset(bus); From f11cf25ef345a320b152aa68a014c8a65cf4ed44 Mon Sep 17 00:00:00 2001 From: Laura Garcia Date: Sat, 23 Feb 2008 18:56:35 +0100 Subject: [PATCH 674/880] [netdrvr] via-rhine: Use register offset definition for WOLcgClr Use register offset definition for WOLcgClr, rather than a magic number. This patch does not change the driver behaviour. Signed-off-by: Laura Garcia Liebana Signed-off-by: Jeff Garzik --- drivers/net/via-rhine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 7c851b1e6daa..8c9d6ae2bb31 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -1893,7 +1893,7 @@ static void rhine_shutdown (struct pci_dev *pdev) /* Make sure we use pattern 0, 1 and not 4, 5 */ if (rp->quirks & rq6patterns) - iowrite8(0x04, ioaddr + 0xA7); + iowrite8(0x04, ioaddr + WOLcgClr); if (rp->wolopts & WAKE_MAGIC) { iowrite8(WOLmagic, ioaddr + WOLcrSet); From a84d0a3d6909c871bfa617a45a7517ce9292d4fb Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 22 Feb 2008 16:00:33 -0800 Subject: [PATCH 675/880] sky2: fix LED management Fix problems in LED management, so ethtool -p works correctly on Yukon-EC and other chips. The driver was incorrectly setting the PHY LED overide bits. Moral: read the spec sheet, not the vendor driver. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 123 ++++++++++++++++++++++----------------------- drivers/net/sky2.h | 27 +++++----- 2 files changed, 76 insertions(+), 74 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 9a6295909e43..54c662690f65 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -572,8 +572,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) default: /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; + /* turn off the Rx LED (LED_RX) */ - ledover &= ~PHY_M_LED_MO_RX; + ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); } if (hw->chip_id == CHIP_ID_YUKON_EC_U && @@ -602,7 +603,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { /* turn on 100 Mbps LED (LED_LINK100) */ - ledover |= PHY_M_LED_MO_100; + ledover |= PHY_M_LED_MO_100(MO_LED_ON); } if (ledover) @@ -3322,82 +3323,80 @@ static void sky2_set_multicast(struct net_device *dev) /* Can have one global because blinking is controlled by * ethtool and that is always under RTNL mutex */ -static void sky2_led(struct sky2_hw *hw, unsigned port, int on) +static void sky2_led(struct sky2_port *sky2, enum led_mode mode) { - u16 pg; + struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; - switch (hw->chip_id) { - case CHIP_ID_YUKON_XL: + spin_lock_bh(&sky2->phy_lock); + if (hw->chip_id == CHIP_ID_YUKON_EC_U || + hw->chip_id == CHIP_ID_YUKON_EX || + hw->chip_id == CHIP_ID_YUKON_SUPR) { + u16 pg; pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, - on ? (PHY_M_LEDC_LOS_CTRL(1) | - PHY_M_LEDC_INIT_CTRL(7) | - PHY_M_LEDC_STA1_CTRL(7) | - PHY_M_LEDC_STA0_CTRL(7)) - : 0); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - break; + switch (mode) { + case MO_LED_OFF: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(8) | + PHY_M_LEDC_INIT_CTRL(8) | + PHY_M_LEDC_STA1_CTRL(8) | + PHY_M_LEDC_STA0_CTRL(8)); + break; + case MO_LED_ON: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(9) | + PHY_M_LEDC_INIT_CTRL(9) | + PHY_M_LEDC_STA1_CTRL(9) | + PHY_M_LEDC_STA0_CTRL(9)); + break; + case MO_LED_BLINK: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(0xa) | + PHY_M_LEDC_INIT_CTRL(0xa) | + PHY_M_LEDC_STA1_CTRL(0xa) | + PHY_M_LEDC_STA0_CTRL(0xa)); + break; + case MO_LED_NORM: + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, + PHY_M_LEDC_LOS_CTRL(1) | + PHY_M_LEDC_INIT_CTRL(8) | + PHY_M_LEDC_STA1_CTRL(7) | + PHY_M_LEDC_STA0_CTRL(7)); + } - default: - gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); + } else gm_phy_write(hw, port, PHY_MARV_LED_OVER, - on ? PHY_M_LED_ALL : 0); - } + PHY_M_LED_MO_DUP(mode) | + PHY_M_LED_MO_10(mode) | + PHY_M_LED_MO_100(mode) | + PHY_M_LED_MO_1000(mode) | + PHY_M_LED_MO_RX(mode) | + PHY_M_LED_MO_TX(mode)); + + spin_unlock_bh(&sky2->phy_lock); } /* blink LED's for finding board */ static int sky2_phys_id(struct net_device *dev, u32 data) { struct sky2_port *sky2 = netdev_priv(dev); - struct sky2_hw *hw = sky2->hw; - unsigned port = sky2->port; - u16 ledctrl, ledover = 0; - long ms; - int interrupted; - int onoff = 1; + unsigned int i; - if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)) - ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT); - else - ms = data * 1000; - - /* save initial values */ - spin_lock_bh(&sky2->phy_lock); - if (hw->chip_id == CHIP_ID_YUKON_XL) { - u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - } else { - ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL); - ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER); - } - - interrupted = 0; - while (!interrupted && ms > 0) { - sky2_led(hw, port, onoff); - onoff = !onoff; - - spin_unlock_bh(&sky2->phy_lock); - interrupted = msleep_interruptible(250); - spin_lock_bh(&sky2->phy_lock); - - ms -= 250; - } + if (data == 0) + data = UINT_MAX; - /* resume regularly scheduled programming */ - if (hw->chip_id == CHIP_ID_YUKON_XL) { - u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl); - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); - } else { - gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); - gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); + for (i = 0; i < data; i++) { + sky2_led(sky2, MO_LED_ON); + if (msleep_interruptible(500)) + break; + sky2_led(sky2, MO_LED_OFF); + if (msleep_interruptible(500)) + break; } - spin_unlock_bh(&sky2->phy_lock); + sky2_led(sky2, MO_LED_NORM); return 0; } diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 5ab5c1c7c5aa..7bb3ba9bcbd8 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1318,18 +1318,21 @@ enum { BLINK_670MS = 4,/* 670 ms */ }; -/**** PHY_MARV_LED_OVER 16 bit r/w LED control */ -enum { - PHY_M_LED_MO_DUP = 3<<10,/* Bit 11..10: Duplex */ - PHY_M_LED_MO_10 = 3<<8, /* Bit 9.. 8: Link 10 */ - PHY_M_LED_MO_100 = 3<<6, /* Bit 7.. 6: Link 100 */ - PHY_M_LED_MO_1000 = 3<<4, /* Bit 5.. 4: Link 1000 */ - PHY_M_LED_MO_RX = 3<<2, /* Bit 3.. 2: Rx */ - PHY_M_LED_MO_TX = 3<<0, /* Bit 1.. 0: Tx */ - - PHY_M_LED_ALL = PHY_M_LED_MO_DUP | PHY_M_LED_MO_10 - | PHY_M_LED_MO_100 | PHY_M_LED_MO_1000 - | PHY_M_LED_MO_RX, +/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ +#define PHY_M_LED_MO_SGMII(x) ((x)<<14) /* Bit 15..14: SGMII AN Timer */ + +#define PHY_M_LED_MO_DUP(x) ((x)<<10) /* Bit 11..10: Duplex */ +#define PHY_M_LED_MO_10(x) ((x)<<8) /* Bit 9.. 8: Link 10 */ +#define PHY_M_LED_MO_100(x) ((x)<<6) /* Bit 7.. 6: Link 100 */ +#define PHY_M_LED_MO_1000(x) ((x)<<4) /* Bit 5.. 4: Link 1000 */ +#define PHY_M_LED_MO_RX(x) ((x)<<2) /* Bit 3.. 2: Rx */ +#define PHY_M_LED_MO_TX(x) ((x)<<0) /* Bit 1.. 0: Tx */ + +enum led_mode { + MO_LED_NORM = 0, + MO_LED_BLINK = 1, + MO_LED_OFF = 2, + MO_LED_ON = 3, }; /***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/ From 179956f498bd8cc55fb803c4ee0cf18be59c8b01 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 21 Feb 2008 22:50:54 +0900 Subject: [PATCH 676/880] macb: Fix speed setting Fix NCFGR.SPD setting on 10Mbps. This bug was introduced by conversion to generic PHY layer in kernel 2.6.23. Signed-off-by: Atsushi Nemoto Signed-off-by: Jeff Garzik --- drivers/net/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 81bf005ff280..1d210ed46130 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -148,7 +148,7 @@ static void macb_handle_link_change(struct net_device *dev) if (phydev->duplex) reg |= MACB_BIT(FD); - if (phydev->speed) + if (phydev->speed == SPEED_100) reg |= MACB_BIT(SPD); macb_writel(bp, NCFGR, reg); From ac0b3509f048b34ba1b60f164fd811b7cbdbc27a Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 21 Feb 2008 15:10:41 -0800 Subject: [PATCH 677/880] ixgb: add RNBC counter - no buffer count - to ethtool stats This counter is valuable to determine if the system is unable to timely return buffers to the hardware and this counter starts to increase well before the hardware starts to drop packets. If users experience rx_no_buffer_count increasing, they should increase the amount of descriptors. That will provide more buffers for the hardware and will decrease the chance of hard drops. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/ixgb/ixgb_ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index 53a9fd086f96..75f3a68ee354 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -67,6 +67,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = { {"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)}, {"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)}, {"rx_frame_errors", IXGB_STAT(net_stats.rx_frame_errors)}, + {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)}, {"rx_fifo_errors", IXGB_STAT(net_stats.rx_fifo_errors)}, {"rx_missed_errors", IXGB_STAT(net_stats.rx_missed_errors)}, {"tx_aborted_errors", IXGB_STAT(net_stats.tx_aborted_errors)}, From 31f8c4fe5d24376c15e18e2936cfa18cd7e5d917 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 21 Feb 2008 15:10:47 -0800 Subject: [PATCH 678/880] e1000e: 82573 can use eerd method to read eeprom This simplifies the 82571/2/3 family initialization a bit and removes an initialization table no longer needed. Signed-off-by: Auke Kok Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/e1000e/82571.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 3beace55b58d..f7ffd35c8a43 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1280,16 +1280,6 @@ static struct e1000_phy_operations e82_phy_ops_m88 = { }; static struct e1000_nvm_operations e82571_nvm_ops = { - .acquire_nvm = e1000_acquire_nvm_82571, - .read_nvm = e1000e_read_nvm_spi, - .release_nvm = e1000_release_nvm_82571, - .update_nvm = e1000_update_nvm_checksum_82571, - .valid_led_default = e1000_valid_led_default_82571, - .validate_nvm = e1000_validate_nvm_checksum_82571, - .write_nvm = e1000_write_nvm_82571, -}; - -static struct e1000_nvm_operations e82573_nvm_ops = { .acquire_nvm = e1000_acquire_nvm_82571, .read_nvm = e1000e_read_nvm_eerd, .release_nvm = e1000_release_nvm_82571, @@ -1355,6 +1345,6 @@ struct e1000_info e1000_82573_info = { .get_invariants = e1000_get_invariants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_m88, - .nvm_ops = &e82573_nvm_ops, + .nvm_ops = &e82571_nvm_ops, }; From 03ae221fe9987e22679642b5b687aebbb67bbb47 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Thu, 21 Feb 2008 15:10:52 -0800 Subject: [PATCH 679/880] e1000e: fix link up message to show ethX: Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/e1000.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 8b88c226e858..327c0620da31 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -42,8 +42,7 @@ struct e1000_info; #define ndev_printk(level, netdev, format, arg...) \ - printk(level "%s: %s: " format, (netdev)->dev.parent->bus_id, \ - (netdev)->name, ## arg) + printk(level "%s: " format, (netdev)->name, ## arg) #ifdef DEBUG #define ndev_dbg(netdev, format, arg...) \ From 4a5694e66428607585c9f4dd14bcf4158d2de191 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Thu, 21 Feb 2008 15:10:57 -0800 Subject: [PATCH 680/880] e1000e: fix flow control when using ethtool overrides Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/lib.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 16f35fadb74b..0860b5fb3471 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -589,9 +589,6 @@ static s32 e1000_set_default_fc_generic(struct e1000_hw *hw) s32 ret_val; u16 nvm_data; - if (mac->fc != e1000_fc_default) - return 0; - /* Read and store word 0x0F of the EEPROM. This word contains bits * that determine the hardware's default PAUSE (flow control) mode, * a bit that determines whether the HW defaults to enabling or From de92d84ec2305c490aa1db33f6e40680f8c236a8 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Thu, 21 Feb 2008 15:11:02 -0800 Subject: [PATCH 681/880] e1000e: fix flow control denial of service possibility this patch avoids a denial of service from an evildoer sending a continuous stream of flow control at our adapter that is plugged into a non-flow control enabled switch. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/lib.c | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 0860b5fb3471..341d74e81fb0 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -1104,34 +1104,13 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { mac->fc = e1000_fc_rx_pause; hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n"); - } - /* Per the IEEE spec, at this point flow control should be - * disabled. However, we want to consider that we could - * be connected to a legacy switch that doesn't advertise - * desired flow control, but can be forced on the link - * partner. So if we advertised no flow control, that is - * what we will resolve to. If we advertised some kind of - * receive capability (Rx Pause Only or Full Flow Control) - * and the link partner advertised none, we will configure - * ourselves to enable Rx Flow Control only. We can do - * this safely for two reasons: If the link partner really - * didn't want flow control enabled, and we enable Rx, no - * harm done since we won't be receiving any PAUSE frames - * anyway. If the intent on the link partner was to have - * flow control enabled, then by us enabling RX only, we - * can at least receive pause frames and process them. - * This is a good idea because in most cases, since we are - * predominantly a server NIC, more times than not we will - * be asked to delay transmission of packets than asking - * our link partner to pause transmission of frames. - */ - else if ((mac->original_fc == e1000_fc_none) || - (mac->original_fc == e1000_fc_tx_pause)) { + } else { + /* + * Per the IEEE spec, at this point flow control + * should be disabled. + */ mac->fc = e1000_fc_none; hw_dbg(hw, "Flow Control = NONE.\r\n"); - } else { - mac->fc = e1000_fc_rx_pause; - hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n"); } /* Now we need to do one last check... If we auto- From 489815ce224e75c2fcd5ebdfaa740d7f9a4f20d3 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 21 Feb 2008 15:11:07 -0800 Subject: [PATCH 682/880] e1000e: fix spelling errors in comments Fix some spelling errors and inconsistencies in comment blocks. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/82571.c | 10 +++++----- drivers/net/e1000e/defines.h | 10 +++++----- drivers/net/e1000e/hw.h | 4 ++-- drivers/net/e1000e/ich8lan.c | 24 ++++++++++++------------ drivers/net/e1000e/lib.c | 16 ++++++++-------- drivers/net/e1000e/netdev.c | 16 +++++++++------- drivers/net/e1000e/phy.c | 10 +++++----- 7 files changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index f7ffd35c8a43..7fe20310eb5f 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -438,7 +438,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw) * For non-82573 silicon, write data to EEPROM at offset using SPI interface. * * If e1000e_update_nvm_checksum is not called after this function, the - * EEPROM will most likley contain an invalid checksum. + * EEPROM will most likely contain an invalid checksum. **/ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) @@ -547,7 +547,7 @@ static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) * poll for completion. * * If e1000e_update_nvm_checksum is not called after this function, the - * EEPROM will most likley contain an invalid checksum. + * EEPROM will most likely contain an invalid checksum. **/ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) @@ -1053,7 +1053,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) /* If SerDes loopback mode is entered, there is no form * of reset to take the adapter out of that mode. So we * have to explicitly take the adapter out of loopback - * mode. This prevents drivers from twidling their thumbs + * mode. This prevents drivers from twiddling their thumbs * if another tool failed to take it out of loopback mode. */ ew32(SCTL, @@ -1098,7 +1098,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) * e1000e_get_laa_state_82571 - Get locally administered address state * @hw: pointer to the HW structure * - * Retrieve and return the current locally administed address state. + * Retrieve and return the current locally administered address state. **/ bool e1000e_get_laa_state_82571(struct e1000_hw *hw) { @@ -1113,7 +1113,7 @@ bool e1000e_get_laa_state_82571(struct e1000_hw *hw) * @hw: pointer to the HW structure * @state: enable/disable locally administered address * - * Enable/Disable the current locally administed address state. + * Enable/Disable the current locally administers address state. **/ void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state) { diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 6232c3e96689..a4f511f549f7 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -66,7 +66,7 @@ #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ /* Extended Device Control */ -#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */ +#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ #define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 @@ -75,12 +75,12 @@ #define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ -/* Receive Decriptor bit definitions */ +/* Receive Descriptor bit definitions */ #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ #define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ #define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ #define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ -#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ +#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */ #define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ #define E1000_RXD_ERR_CE 0x01 /* CRC Error */ #define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ @@ -223,7 +223,7 @@ #define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */ #define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ -/* Constants used to intrepret the masked PCI-X bus speed. */ +/* Constants used to interpret the masked PCI-X bus speed. */ #define HALF_DUPLEX 1 #define FULL_DUPLEX 2 @@ -517,7 +517,7 @@ /* PHY 1000 MII Register/Bit Definitions */ /* PHY Registers defined by IEEE */ #define PHY_CONTROL 0x00 /* Control Register */ -#define PHY_STATUS 0x01 /* Status Regiser */ +#define PHY_STATUS 0x01 /* Status Register */ #define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ #define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ #define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 3c5862f97dbf..916025b30fc3 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -184,7 +184,7 @@ enum e1e_registers { E1000_ICRXDMTC = 0x04120, /* Irq Cause Rx Desc MinThreshold Count */ E1000_ICRXOC = 0x04124, /* Irq Cause Receiver Overrun Count */ E1000_RXCSUM = 0x05000, /* RX Checksum Control - RW */ - E1000_RFCTL = 0x05008, /* Receive Filter Control*/ + E1000_RFCTL = 0x05008, /* Receive Filter Control */ E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */ E1000_RA = 0x05400, /* Receive Address - RW Array */ E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */ @@ -202,7 +202,7 @@ enum e1e_registers { E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ E1000_SWSM = 0x05B50, /* SW Semaphore */ E1000_FWSM = 0x05B54, /* FW Semaphore */ - E1000_HICR = 0x08F00, /* Host Inteface Control */ + E1000_HICR = 0x08F00, /* Host Interface Control */ }; /* RSS registers */ diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 8f8139de1f48..0ae39550768d 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -671,7 +671,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) * e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY * @hw: pointer to the HW structure * - * Polarity is determined on the polarity reveral feature being enabled. + * Polarity is determined on the polarity reversal feature being enabled. * This function is only called by other family-specific * routines. **/ @@ -947,7 +947,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) /* Either we should have a hardware SPI cycle in progress * bit to check against, in order to start a new cycle or * FDONE bit should be changed in the hardware so that it - * is 1 after harware reset, which can then be used as an + * is 1 after hardware reset, which can then be used as an * indication whether a cycle is in progress or has been * completed. */ @@ -1155,7 +1155,7 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, * which writes the checksum to the shadow ram. The changes in the shadow * ram are then committed to the EEPROM by processing each bank at a time * checking for the modified bit and writing only the pending changes. - * After a succesful commit, the shadow ram is cleared and is ready for + * After a successful commit, the shadow ram is cleared and is ready for * future writes. **/ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) @@ -1680,7 +1680,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) * - initialize LED identification * - setup receive address registers * - setup flow control - * - setup transmit discriptors + * - setup transmit descriptors * - clear statistics **/ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) @@ -1961,7 +1961,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_NOND0A_GBE_DISABLE); ew32(PHY_CTRL, phy_ctrl); - /* Call gig speed drop workaround on Giga disable before accessing + /* Call gig speed drop workaround on Gig disable before accessing * any PHY registers */ e1000e_gig_downshift_workaround_ich8lan(hw); @@ -1972,7 +1972,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) /** * e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state * @hw: pointer to the HW structure - * @state: boolean value used to set the current Kumaran workaround state + * @state: boolean value used to set the current Kumeran workaround state * * If ICH8, set the current Kumeran workaround state (enabled - TRUE * /disabled - FALSE). @@ -2017,7 +2017,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_NOND0A_GBE_DISABLE); ew32(PHY_CTRL, reg); - /* Call gig speed drop workaround on Giga disable before + /* Call gig speed drop workaround on Gig disable before * accessing any PHY registers */ if (hw->mac.type == e1000_ich8lan) e1000e_gig_downshift_workaround_ich8lan(hw); @@ -2045,7 +2045,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) * @hw: pointer to the HW structure * * Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC), - * LPLU, Giga disable, MDIC PHY reset): + * LPLU, Gig disable, MDIC PHY reset): * 1) Set Kumeran Near-end loopback * 2) Clear Kumeran Near-end loopback * Should only be called for ICH8[m] devices with IGP_3 Phy. @@ -2089,10 +2089,10 @@ static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) } /** - * e1000_led_on_ich8lan - Turn LED's on + * e1000_led_on_ich8lan - Turn LEDs on * @hw: pointer to the HW structure * - * Turn on the LED's. + * Turn on the LEDs. **/ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) { @@ -2105,10 +2105,10 @@ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) } /** - * e1000_led_off_ich8lan - Turn LED's off + * e1000_led_off_ich8lan - Turn LEDs off * @hw: pointer to the HW structure * - * Turn off the LED's. + * Turn off the LEDs. **/ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) { diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 341d74e81fb0..95f75a43c9f9 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -1140,7 +1140,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) } /** - * e1000e_get_speed_and_duplex_copper - Retreive current speed/duplex + * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex * @hw: pointer to the HW structure * @speed: stores the current speed * @duplex: stores the current duplex @@ -1176,7 +1176,7 @@ s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *dup } /** - * e1000e_get_speed_and_duplex_fiber_serdes - Retreive current speed/duplex + * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex * @hw: pointer to the HW structure * @speed: stores the current speed * @duplex: stores the current duplex @@ -1386,7 +1386,7 @@ s32 e1000e_cleanup_led_generic(struct e1000_hw *hw) * e1000e_blink_led - Blink LED * @hw: pointer to the HW structure * - * Blink the led's which are set to be on. + * Blink the LEDs which are set to be on. **/ s32 e1000e_blink_led(struct e1000_hw *hw) { @@ -1491,7 +1491,7 @@ void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop) * @hw: pointer to the HW structure * * Returns 0 if successful, else returns -10 - * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued + * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused * the master requests to be disabled. * * Disables PCI-Express master access and verifies there are no pending @@ -1852,7 +1852,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) } /** - * e1000e_read_nvm_spi - Read EEPROM's using SPI + * e1000e_read_nvm_spi - Reads EEPROM using SPI * @hw: pointer to the HW structure * @offset: offset of word in the EEPROM to read * @words: number of words to read @@ -1956,7 +1956,7 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * Writes data to EEPROM at offset using SPI interface. * * If e1000e_update_nvm_checksum is not called after this function , the - * EEPROM will most likley contain an invalid checksum. + * EEPROM will most likely contain an invalid checksum. **/ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { @@ -2198,7 +2198,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length) * * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND * - * This function checks whether the HOST IF is enabled for command operaton + * This function checks whether the HOST IF is enabled for command operation * and also checks whether the previous command is completed. It busy waits * in case of previous command is not completed. **/ @@ -2230,7 +2230,7 @@ static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) } /** - * e1000e_check_mng_mode - check managament mode + * e1000e_check_mng_mode - check management mode * @hw: pointer to the HW structure * * Reads the firmware semaphore register and returns true (>0) if diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3031d6d16247..7824bc2993a7 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1006,7 +1006,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) * e1000_get_hw_control - get control of the h/w from f/w * @adapter: address of board private structure * - * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit. + * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit. * For ASF and Pass Through versions of f/w this means that * the driver is loaded. For AMT version (only with 82573) * of the f/w this means that the network i/f is open. @@ -1032,7 +1032,7 @@ static void e1000_get_hw_control(struct e1000_adapter *adapter) * e1000_release_hw_control - release control of the h/w to f/w * @adapter: address of board private structure * - * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit. + * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit. * For ASF and Pass Through versions of f/w this means that the * driver is no longer loaded. For AMT version (only with 82573) i * of the f/w this means that the network i/f is closed. @@ -1241,6 +1241,11 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter) /** * e1000_update_itr - update the dynamic ITR value based on statistics + * @adapter: pointer to adapter + * @itr_setting: current adapter->itr + * @packets: the number of packets during this measurement interval + * @bytes: the number of bytes during this measurement interval + * * Stores a new ITR value based on packets and byte * counts during the last interrupt. The advantage of per interrupt * computation is faster updates and more accurate ITR for the current @@ -1250,10 +1255,6 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter) * while increasing bulk throughput. * this functionality is controlled by the InterruptThrottleRate module * parameter (see e1000_param.c) - * @adapter: pointer to adapter - * @itr_setting: current adapter->itr - * @packets: the number of packets during this measurement interval - * @bytes: the number of bytes during this measurement interval **/ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, u16 itr_setting, int packets, @@ -1366,6 +1367,7 @@ static void e1000_set_itr(struct e1000_adapter *adapter) /** * e1000_clean - NAPI Rx polling callback * @adapter: board private structure + * @budget: amount of packets driver is allowed to process this poll **/ static int e1000_clean(struct napi_struct *napi, int budget) { @@ -2000,7 +2002,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter) e1000_check_reset_block(hw)) return; - /* managebility (AMT) is enabled */ + /* manageability (AMT) is enabled */ if (er32(MANC) & E1000_MANC_SMBUS_EN) return; diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index fc6fee112f1c..dab3c468a768 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -121,7 +121,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw) * @offset: register offset to be read * @data: pointer to the read data * - * Reads the MDI control regsiter in the PHY at offset and stores the + * Reads the MDI control register in the PHY at offset and stores the * information read to data. **/ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) @@ -1172,7 +1172,7 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active) } /** - * e1000e_check_downshift - Checks whether a downshift in speed occured + * e1000e_check_downshift - Checks whether a downshift in speed occurred * @hw: pointer to the HW structure * * Success returns 0, Failure returns 1 @@ -1388,8 +1388,8 @@ s32 e1000e_get_cable_length_m88(struct e1000_hw *hw) * * The automatic gain control (agc) normalizes the amplitude of the * received signal, adjusting for the attenuation produced by the - * cable. By reading the AGC registers, which reperesent the - * cobination of course and fine gain value, the value can be put + * cable. By reading the AGC registers, which represent the + * combination of course and fine gain value, the value can be put * into a lookup table to obtain the approximate cable length * for each channel. **/ @@ -1619,7 +1619,7 @@ s32 e1000e_phy_sw_reset(struct e1000_hw *hw) * Verify the reset block is not blocking us from resetting. Acquire * semaphore (if necessary) and read/set/write the device control reset * bit in the PHY. Wait the appropriate delay time for the device to - * reset and relase the semaphore (if necessary). + * reset and release the semaphore (if necessary). **/ s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw) { From 3bf319a787a881aa6ad8213b98b93b8de2b6f0e0 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 21 Feb 2008 15:11:13 -0800 Subject: [PATCH 683/880] e1000e: remove unused read value in ASPM disable code. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e1000e/netdev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 7824bc2993a7..fc5c63f4f578 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3490,7 +3490,6 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) static void e1000e_disable_l1aspm(struct pci_dev *pdev) { int pos; - u32 cap; u16 val; /* @@ -3505,7 +3504,6 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev) * active. */ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); - pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap); pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val); if (val & 0x2) { dev_warn(&pdev->dev, "Disabling L1 ASPM\n"); From 635adc28087ced0c843d2ecb6d4ae474d0e611cd Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 20 Feb 2008 20:09:23 +0000 Subject: [PATCH 684/880] pata_atiixp: Use 255 sector limit AHCI needs sorting too but this deals with the old interface Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_atiixp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 9623f5295530..408bdc1a9776 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -227,7 +227,7 @@ static struct scsi_host_template atiixp_sht = { .queuecommand = ata_scsi_queuecmd, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, + .sg_tablesize = LIBATA_DUMB_MAX_PRD, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, @@ -259,7 +259,7 @@ static struct ata_port_operations atiixp_port_ops = { .bmdma_stop = atiixp_bmdma_stop, .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, + .qc_prep = ata_dumb_qc_prep, .qc_issue = ata_qc_issue_prot, .data_xfer = ata_data_xfer, From 559bbe6cbd0d8c68d40076a5f7dc98e3bf5864b2 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 21 Feb 2008 13:56:55 +0100 Subject: [PATCH 685/880] power_state: get rid of write-only variable in SATA power_state is scheduled for removal, and libata uses it in write-only mode. Remove it. Signed-off-by: Pavel Machek Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4cf8662df99e..9812bbf05e62 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6560,8 +6560,6 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) ata_lpm_enable(host); rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); - if (rc == 0) - host->dev->power.power_state = mesg; return rc; } @@ -6580,7 +6578,6 @@ void ata_host_resume(struct ata_host *host) { ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET, ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); - host->dev->power.power_state = PMSG_ON; /* reenable link pm */ ata_lpm_disable(host); From 9116300634c5c76cfcd0d2af689846e04d172256 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 21 Feb 2008 13:25:50 +0900 Subject: [PATCH 686/880] libata: automatically use DMADIR if drive/bridge requires it Back in 2.6.17-rc2, a libata module parameter was added for atapi_dmadir. That's nice, but most SATA devices which need it will tell us about it in their IDENTIFY PACKET response, as bit-15 of word-62 of the returned data (as per ATA7, ATA8 specifications). So for those which specify it, we should automatically use the DMADIR bit. Otherwise, disc writing will fail by default on many SATA-ATAPI drives. This patch adds ATA_DFLAG_DMADIR and make ata_dev_configure() set it if atapi_dmadir is set or identify data indicates DMADIR is necessary. atapi_xlat() is converted to check ATA_DFLAG_DMADIR before setting DMADIR. Original patch is from Mark Lord. Signed-off-by: Tejun Heo Cc: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 11 +++++++++-- drivers/ata/libata-scsi.c | 3 ++- include/linux/ata.h | 5 +++++ include/linux/libata.h | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 9812bbf05e62..1845119cc7f0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2396,6 +2396,7 @@ int ata_dev_configure(struct ata_device *dev) else if (dev->class == ATA_DEV_ATAPI) { const char *cdb_intr_string = ""; const char *atapi_an_string = ""; + const char *dma_dir_string = ""; u32 sntf; rc = atapi_cdb_len(id); @@ -2436,13 +2437,19 @@ int ata_dev_configure(struct ata_device *dev) cdb_intr_string = ", CDB intr"; } + if (atapi_dmadir || atapi_id_dmadir(dev->id)) { + dev->flags |= ATA_DFLAG_DMADIR; + dma_dir_string = ", DMADIR"; + } + /* print device info to dmesg */ if (ata_msg_drv(ap) && print_info) ata_dev_printk(dev, KERN_INFO, - "ATAPI: %s, %s, max %s%s%s\n", + "ATAPI: %s, %s, max %s%s%s%s\n", modelbuf, fwrevbuf, ata_mode_string(xfer_mask), - cdb_intr_string, atapi_an_string); + cdb_intr_string, atapi_an_string, + dma_dir_string); } /* determine max_sectors */ diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index f888babc8283..0562b0a49f3b 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2582,7 +2582,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) qc->tf.protocol = ATAPI_PROT_DMA; qc->tf.feature |= ATAPI_PKT_DMA; - if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE)) + if ((dev->flags & ATA_DFLAG_DMADIR) && + (scmd->sc_data_direction != DMA_TO_DEVICE)) /* some SATA bridges need us to indicate data xfer direction */ qc->tf.feature |= ATAPI_DMADIR; } diff --git a/include/linux/ata.h b/include/linux/ata.h index 78bbacaed8c4..1c622e2b0504 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -659,6 +659,11 @@ static inline int atapi_command_packet_set(const u16 *dev_id) return (dev_id[0] >> 8) & 0x1f; } +static inline int atapi_id_dmadir(const u16 *dev_id) +{ + return ata_id_major_version(dev_id) >= 7 && (dev_id[62] & 0x8000); +} + static inline int is_multi_taskfile(struct ata_taskfile *tf) { return (tf->command == ATA_CMD_READ_MULTI) || diff --git a/include/linux/libata.h b/include/linux/libata.h index ce7603a73156..a05f60013642 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -138,6 +138,7 @@ enum { ATA_DFLAG_AN = (1 << 7), /* AN configured */ ATA_DFLAG_HIPM = (1 << 8), /* device supports HIPM */ ATA_DFLAG_DIPM = (1 << 9), /* device supports DIPM */ + ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */ ATA_DFLAG_CFG_MASK = (1 << 12) - 1, ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */ From 39f25e70ca37b8a719e8274e6f3ec2ce2ea8df04 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Thu, 21 Feb 2008 15:52:25 -0500 Subject: [PATCH 687/880] libata-pmp: clear hob for pmp register accesses >> Mark Lord wrote: >>> Tejun, I've added PMP to sata_mv, and am now trying to get it >>> to work with a Marvell PM attached. >>> >>> And the behaviour I see is very bizarre. >>> >>> After hard+soft resets, the PM signature is found, >>> and libata interrogates the PM registers. >>> >>> It successfully reads register 0, and then register 1. >>> But all subsequent registers read out (incorrectly) as zeros. ... This behavior has been confirmed by Marvell with a SATA analyzer. The Marvell port-multiplier apparently likes to see clean HOB information when accessing PMP registers. Since sata_mv uses PIO shadow register access, this doesn't happen automatically, as it might in a more purely FIS-based driver (eg. ahci). One way to fix this is to flag these commands with ATA_TFLAG_LBA48, forcing libata to write out the HOB fields with known (zero) values. Signed-off-by: Saeed Bishara Acked-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/libata-pmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index caef2bbd4a8a..d91f5090ba9d 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -35,7 +35,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) ata_tf_init(pmp_dev, &tf); tf.command = ATA_CMD_PMP_READ; tf.protocol = ATA_PROT_NODATA; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; tf.feature = reg; tf.device = link->pmp; @@ -71,7 +71,7 @@ static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val) ata_tf_init(pmp_dev, &tf); tf.command = ATA_CMD_PMP_WRITE; tf.protocol = ATA_PROT_NODATA; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; tf.feature = reg; tf.device = link->pmp; tf.nsect = val & 0xff; From e39fc8c9fd0bb6f4018186801e4a53a5eccaaf70 Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Fri, 22 Feb 2008 05:00:31 -0800 Subject: [PATCH 688/880] [libata] ahci: AMD SB700/SB800 SATA support 64bit DMA SB700 SATA controller can support 64 bit DMA, the previous commit badc2341579511a247f5993865aa68379e283c5c was added with careless reference to SB600, which should be modified by this patch. Signed-off-by: Shane Huang Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6dd12f7019a0..1db93b619074 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -85,6 +85,7 @@ enum { board_ahci_ign_iferr = 2, board_ahci_sb600 = 3, board_ahci_mv = 4, + board_ahci_sb700 = 5, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -442,6 +443,16 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, + /* board_ahci_sb700 */ + { + AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | + AHCI_HFLAG_NO_PMP), + .flags = AHCI_FLAG_COMMON, + .link_flags = AHCI_LFLAG_COMMON, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, }; static const struct pci_device_id ahci_pci_tbl[] = { @@ -484,12 +495,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* ATI */ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ - { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb600 }, /* ATI SB700/800 */ - { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb600 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700 }, /* ATI SB700/800 */ + { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */ /* VIA */ { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ From b1f5dc48e2dcfcacb37d0bc2c5658f0f3307da52 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 22 Feb 2008 19:54:25 +0300 Subject: [PATCH 689/880] sata_fsl: fix build with ATA_VERBOSE_DEBUG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes build and few warnings when ATA_VERBOSE_DEBUG is defined: CC drivers/ata/sata_fsl.o drivers/ata/sata_fsl.c: In function ‘sata_fsl_fill_sg’: drivers/ata/sata_fsl.c:338: warning: format ‘%x’ expects type ‘unsigned int’, but argument 3 has type ‘void *’ drivers/ata/sata_fsl.c:338: warning: format ‘%x’ expects type ‘unsigned int’, but argument 4 has type ‘struct prde *’ drivers/ata/sata_fsl.c: In function ‘sata_fsl_qc_issue’: drivers/ata/sata_fsl.c:459: error: ‘csr_base’ undeclared (first use in this function) drivers/ata/sata_fsl.c:459: error: (Each undeclared identifier is reported only once drivers/ata/sata_fsl.c:459: error: for each function it appears in.) drivers/ata/sata_fsl.c: In function ‘sata_fsl_freeze’: drivers/ata/sata_fsl.c:525: error: ‘csr_base’ undeclared (first use in this function) make[2]: *** [drivers/ata/sata_fsl.o] Error 1 Signed-off-by: Anton Vorontsov Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 9323dd0c7d8d..07791a7a48a5 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -335,7 +335,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, dma_addr_t indirect_ext_segment_paddr; unsigned int si; - VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd); + VPRINTK("SATA FSL : cd = 0x%p, prd = 0x%p\n", cmd_desc, prd); indirect_ext_segment_paddr = cmd_desc_paddr + SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16; @@ -459,7 +459,8 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n", ioread32(CE + hcr_base), ioread32(DE + hcr_base), - ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base)); + ioread32(CC + hcr_base), + ioread32(COMMANDSTAT + host_priv->csr_base)); return 0; } @@ -522,7 +523,8 @@ static void sata_fsl_freeze(struct ata_port *ap) ioread32(CQ + hcr_base), ioread32(CA + hcr_base), ioread32(CE + hcr_base), ioread32(DE + hcr_base)); - VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT)); + VPRINTK("CmdStat = 0x%x\n", + ioread32(host_priv->csr_base + COMMANDSTAT)); /* disable interrupts on the controller/port */ temp = ioread32(hcr_base + HCONTROL); From 4cdfa1b3ce4731dd538ac3ed010bcf127ed6e836 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 22 Feb 2008 12:21:37 -0800 Subject: [PATCH 690/880] libata-core: fix kernel-doc warning Fix libata-core kernel-doc warning: Warning(linux-2.6.25-rc2-git6//drivers/ata/libata-core.c:168): No description found for parameter 'ap' Signed-off-by: Randy Dunlap Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 1845119cc7f0..fbc24358ada0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -153,7 +153,7 @@ MODULE_VERSION(DRV_VERSION); /** * ata_force_cbl - force cable type according to libata.force - * @link: ATA link of interest + * @ap: ATA port of interest * * Force cable type according to libata.force and whine about it. * The last entry which has matching port number is used, so it From c9a2c46d7f32a884510b20f0cfa79a2c6a2f1413 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 24 Feb 2008 20:03:41 +0100 Subject: [PATCH 691/880] ARM: OMAP: Release i2c_adapter after use (Siemens SX1) Each call to i2c_get_adapter() must be followed by a call to i2c_put_adapter() to release the grabbed reference. Otherwise the reference count grows forever and the adapter can never be unregistered. Signed-off-by: Jean Delvare Acked-by: Vladimir Ananiev Acked-by: Tony Lindgren --- arch/arm/mach-omap1/board-sx1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 1c7f09aedf07..e473fa6d4a5f 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -61,6 +61,7 @@ int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value) data[0] = regoffset; /* register num */ data[1] = value; /* register data */ err = i2c_transfer(adap, msg, 1); + i2c_put_adapter(adap); if (err >= 0) return 0; return err; @@ -91,6 +92,7 @@ int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value) msg->buf = data; err = i2c_transfer(adap, msg, 1); *value = data[0]; + i2c_put_adapter(adap); if (err >= 0) return 0; From a92b36ed33800435a2356a78489e129aaf30f673 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 24 Feb 2008 20:03:42 +0100 Subject: [PATCH 692/880] i2c-pxa: Misc fixes While working on the PCA9564-platform driver, I sometimes had a glimpse at the pxa-driver. I found some suspicious places, and this patch contains my suggestions. Note: They are not tested, due to no hardware. [JD: Some more fixes.] Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare Tested-by: Mike Rapoport Tested-by: Eric Miao --- drivers/i2c/busses/i2c-pxa.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 2b557bfd7f70..2d2087ad708f 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -999,7 +999,14 @@ static int i2c_pxa_probe(struct platform_device *dev) spin_lock_init(&i2c->lock); init_waitqueue_head(&i2c->wait); - sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id); + /* + * If "dev->id" is negative we consider it as zero. + * The reason to do so is to avoid sysfs names that only make + * sense when there are multiple adapters. + */ + i2c->adap.nr = dev->id != -1 ? dev->id : 0; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", + i2c->adap.nr); i2c->clk = clk_get(&dev->dev, "I2CCLK"); if (IS_ERR(i2c->clk)) { @@ -1050,13 +1057,6 @@ static int i2c_pxa_probe(struct platform_device *dev) i2c->adap.algo_data = i2c; i2c->adap.dev.parent = &dev->dev; - /* - * If "dev->id" is negative we consider it as zero. - * The reason to do so is to avoid sysfs names that only make - * sense when there are multiple adapters. - */ - i2c->adap.nr = dev->id != -1 ? dev->id : 0; - ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) { printk(KERN_INFO "I2C: Failed to add bus\n"); @@ -1080,6 +1080,7 @@ static int i2c_pxa_probe(struct platform_device *dev) ereqirq: clk_disable(i2c->clk); i2c_pxa_disable(dev); + iounmap(i2c->reg_base); eremap: clk_put(i2c->clk); eclk: @@ -1089,7 +1090,7 @@ static int i2c_pxa_probe(struct platform_device *dev) return ret; } -static int i2c_pxa_remove(struct platform_device *dev) +static int __exit i2c_pxa_remove(struct platform_device *dev) { struct pxa_i2c *i2c = platform_get_drvdata(dev); @@ -1103,6 +1104,7 @@ static int i2c_pxa_remove(struct platform_device *dev) clk_put(i2c->clk); i2c_pxa_disable(dev); + iounmap(i2c->reg_base); release_mem_region(i2c->iobase, i2c->iosize); kfree(i2c); @@ -1111,9 +1113,10 @@ static int i2c_pxa_remove(struct platform_device *dev) static struct platform_driver i2c_pxa_driver = { .probe = i2c_pxa_probe, - .remove = i2c_pxa_remove, + .remove = __exit_p(i2c_pxa_remove), .driver = { .name = "pxa2xx-i2c", + .owner = THIS_MODULE, }, }; @@ -1122,7 +1125,7 @@ static int __init i2c_adap_pxa_init(void) return platform_driver_register(&i2c_pxa_driver); } -static void i2c_adap_pxa_exit(void) +static void __exit i2c_adap_pxa_exit(void) { platform_driver_unregister(&i2c_pxa_driver); } From 305183fc3ec8aac55179ef0fcb65dab9b97a9145 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 24 Feb 2008 20:03:42 +0100 Subject: [PATCH 693/880] i2c: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-pmcmsp.c | 4 ++-- include/linux/i2c.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index be99c02ecac5..b03af5653c65 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -122,7 +122,7 @@ struct pmcmsptwi_data { }; /* The default settings */ -const static struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = { +static const struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = { .standard = { .filter = 0x3, .clock = 0x1f, @@ -133,7 +133,7 @@ const static struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = { }, }; -const static struct pmcmsptwi_cfg pmcmsptwi_defcfg = { +static const struct pmcmsptwi_cfg pmcmsptwi_defcfg = { .arbf = 0x03, .nak = 0x03, .add10 = 0x00, diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 76014f8f3c60..2d1c608eb5db 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -598,7 +598,7 @@ I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \ "additionally"); \ I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \ "scan"); \ -const static struct i2c_client_address_data addr_data = { \ +static const struct i2c_client_address_data addr_data = { \ .normal_i2c = normal_i2c, \ .probe = probe, \ .ignore = ignore, \ From 9e39ffeff6e54ef65832e4eb58059133f1a8aadf Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Sun, 24 Feb 2008 20:03:42 +0100 Subject: [PATCH 694/880] Alchemy: compile fix Commit 8b798c4d16b762d15f4055597ff8d87f73b35552 broke alchemy build, fix it. Pointed out by Adrian Bunk. Signed-off-by: Manuel Lauss Signed-off-by: Jean Delvare --- include/asm-mips/mach-db1x00/db1200.h | 1 + include/asm-mips/mach-db1x00/db1x00.h | 1 + include/asm-mips/mach-pb1x00/pb1200.h | 1 + include/asm-mips/mach-pb1x00/pb1550.h | 1 + 4 files changed, 4 insertions(+) diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h index 050eae87ff01..a6bdac61ab49 100644 --- a/include/asm-mips/mach-db1x00/db1200.h +++ b/include/asm-mips/mach-db1x00/db1200.h @@ -25,6 +25,7 @@ #define __ASM_DB1200_H #include +#include // This is defined in au1000.h with bogus value #undef AU1X00_EXTERNAL_INT diff --git a/include/asm-mips/mach-db1x00/db1x00.h b/include/asm-mips/mach-db1x00/db1x00.h index 0f5f4c29f4e8..e7a88ba35833 100644 --- a/include/asm-mips/mach-db1x00/db1x00.h +++ b/include/asm-mips/mach-db1x00/db1x00.h @@ -28,6 +28,7 @@ #ifndef __ASM_DB1X00_H #define __ASM_DB1X00_H +#include #ifdef CONFIG_MIPS_DB1550 diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h index d9f384acfea9..ed5fd7390678 100644 --- a/include/asm-mips/mach-pb1x00/pb1200.h +++ b/include/asm-mips/mach-pb1x00/pb1200.h @@ -25,6 +25,7 @@ #define __ASM_PB1200_H #include +#include // This is defined in au1000.h with bogus value #undef AU1X00_EXTERNAL_INT diff --git a/include/asm-mips/mach-pb1x00/pb1550.h b/include/asm-mips/mach-pb1x00/pb1550.h index 9a4955ce3b4a..c2ab0e2df4ae 100644 --- a/include/asm-mips/mach-pb1x00/pb1550.h +++ b/include/asm-mips/mach-pb1x00/pb1550.h @@ -28,6 +28,7 @@ #define __ASM_PB1550_H #include +#include #define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX #define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX From 104cb574feb3033299568483a3f68031f47e0d43 Mon Sep 17 00:00:00 2001 From: Christian Krafft Date: Sun, 24 Feb 2008 20:03:42 +0100 Subject: [PATCH 695/880] i2c-pca-isa: Add access check to legacy ioports When probing i2c-pca-isa writes to legacy ioports, which crashes the kernel if there is no device at that port. This patch adds a check_legacy_ioport call, so probe fails gracefully and thus prevents the oops. Signed-off-by: Christian Krafft Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-pca-isa.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index 5161aaf9341b..496ee875eb4f 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -125,6 +125,13 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id) dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq); +#ifdef CONFIG_PPC_MERGE + if (check_legacy_ioport(base)) { + dev_err(dev, "I/O address %#08lx is not available\n", base); + goto out; + } +#endif + if (!request_region(base, IO_SIZE, "i2c-pca-isa")) { dev_err(dev, "I/O address %#08lx is in use\n", base); goto out; From 263867631ea02741baf878ca9faaf94b1563b9d7 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 24 Feb 2008 20:03:42 +0100 Subject: [PATCH 696/880] i2c: Make i2c_register_board_info() a NOP when CONFIG_I2C_BOARDINFO=n Don't require platform code to be #ifdeffed according to whether I2C is enabled or not ... if it's not enabled, let GCC compile out all I2C device declarations. (Issue noted on an NSLU2 build that didn't configure I2C.) Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- include/linux/i2c.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 2d1c608eb5db..365e0df3646b 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -271,9 +271,16 @@ extern void i2c_unregister_device(struct i2c_client *); * This is done at arch_initcall time, before declaring any i2c adapters. * Modules for add-on boards must use other calls. */ +#ifdef CONFIG_I2C_BOARDINFO extern int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n); - +#else +static inline int +i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n) +{ + return 0; +} +#endif /* * The following structs are for those who like to implement new bus drivers: From d28dc711217a2d5cafb64ec4e33a469b01376d91 Mon Sep 17 00:00:00 2001 From: "Gaston, Jason D" Date: Sun, 24 Feb 2008 20:03:42 +0100 Subject: [PATCH 697/880] i2c-i801: Add support for the ICH10 Add the Intel ICH10 SMBus Controller DeviceID's and updates Tolapai support. Signed-off-by: Jason Gaston Signed-off-by: Jean Delvare --- Documentation/i2c/busses/i2c-i801 | 3 ++- drivers/i2c/busses/Kconfig | 2 ++ drivers/i2c/busses/i2c-i801.c | 10 ++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 3bd958360159..c31e0291e167 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 @@ -12,8 +12,9 @@ Supported adapters: * Intel 82801G (ICH7) * Intel 631xESB/632xESB (ESB2) * Intel 82801H (ICH8) - * Intel ICH9 + * Intel 82801I (ICH9) * Intel Tolapai + * Intel ICH10 Datasheets: Publicly available at the Intel website Authors: diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b61f56b6f311..476b0bb72d6c 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -177,6 +177,8 @@ config I2C_I801 ESB2 ICH8 ICH9 + Tolapai + ICH10 This driver can also be built as a module. If so, the module will be called i2c-i801. diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index aa9157913b9a..b0f771fe4326 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -40,7 +40,9 @@ 82801G (ICH7) 0x27da 32 hard yes yes yes 82801H (ICH8) 0x283e 32 hard yes yes yes 82801I (ICH9) 0x2930 32 hard yes yes yes - Tolapai 0x5032 32 hard yes ? ? + Tolapai 0x5032 32 hard yes yes yes + ICH10 0x3a30 32 hard yes yes yes + ICH10 0x3a60 32 hard yes yes yes Features supported by this driver: Software PEC no @@ -588,6 +590,8 @@ static struct pci_device_id i801_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) }, { 0, } }; @@ -608,10 +612,12 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id case PCI_DEVICE_ID_INTEL_ESB2_17: case PCI_DEVICE_ID_INTEL_ICH8_5: case PCI_DEVICE_ID_INTEL_ICH9_6: + case PCI_DEVICE_ID_INTEL_TOLAPAI_1: + case PCI_DEVICE_ID_INTEL_ICH10_4: + case PCI_DEVICE_ID_INTEL_ICH10_5: i801_features |= FEATURE_I2C_BLOCK_READ; /* fall through */ case PCI_DEVICE_ID_INTEL_82801DB_3: - case PCI_DEVICE_ID_INTEL_TOLAPAI_1: i801_features |= FEATURE_SMBUS_PEC; i801_features |= FEATURE_BLOCK_BUFFER; break; From bfa274e2436fc7ef72ef51c878083647f1cfd429 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 24 Feb 2008 13:25:54 -0800 Subject: [PATCH 698/880] Linux 2.6.25-rc3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 99300dc680e9..a22978413b65 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 25 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Funky Weasel is Jiggy wit it # *DOCUMENTATION* From 5f2f40a92e007ec5b503db20f3f70cb331c64f65 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sun, 24 Feb 2008 18:38:31 -0800 Subject: [PATCH 699/880] tipc: fix integer as NULL pointer sparse warnings in tipc net/tipc/cluster.c:145:2: warning: Using plain integer as NULL pointer net/tipc/link.c:3254:36: warning: Using plain integer as NULL pointer net/tipc/ref.c:151:15: warning: Using plain integer as NULL pointer net/tipc/zone.c:85:2: warning: Using plain integer as NULL pointer Signed-off-by: Harvey Harrison Signed-off-by: David S. Miller --- net/tipc/cluster.c | 2 +- net/tipc/link.c | 2 +- net/tipc/ref.c | 2 +- net/tipc/zone.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index 95b373913aa0..4bb3404f610b 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -142,7 +142,7 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr) max_n_num = tipc_highest_allowed_slave; assert(n_num > 0); assert(n_num <= max_n_num); - assert(c_ptr->nodes[n_num] == 0); + assert(c_ptr->nodes[n_num] == NULL); c_ptr->nodes[n_num] = n_ptr; if (n_num > c_ptr->highest_node) c_ptr->highest_node = n_num; diff --git a/net/tipc/link.c b/net/tipc/link.c index 1b17fecee747..cefa99824c58 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -3251,7 +3251,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, if ((mod(msg_seqno(buf_msg(l_ptr->last_out)) - msg_seqno(buf_msg(l_ptr->first_out))) != (l_ptr->out_queue_size - 1)) - || (l_ptr->last_out->next != 0)) { + || (l_ptr->last_out->next != NULL)) { tipc_printf(buf, "\nSend queue inconsistency\n"); tipc_printf(buf, "first_out= %x ", l_ptr->first_out); tipc_printf(buf, "next_out= %x ", l_ptr->next_out); diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 6704a58c7851..c38744c96ed1 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -148,7 +148,7 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) reference = (next_plus_upper & ~index_mask) + index; entry->data.reference = reference; entry->object = object; - if (lock != 0) + if (lock != NULL) *lock = &entry->lock; spin_unlock_bh(&entry->lock); } diff --git a/net/tipc/zone.c b/net/tipc/zone.c index 114e173f11a5..3506f8563441 100644 --- a/net/tipc/zone.c +++ b/net/tipc/zone.c @@ -82,7 +82,7 @@ void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr) assert(c_ptr->addr); assert(c_num <= tipc_max_clusters); - assert(z_ptr->clusters[c_num] == 0); + assert(z_ptr->clusters[c_num] == NULL); z_ptr->clusters[c_num] = c_ptr; } From b80a71860d0cfaaa9aa0722238cf3b69bb859eee Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 24 Feb 2008 18:45:09 -0800 Subject: [PATCH 700/880] [SPARC]: Fix build in arch/sparc/kernel/led.c CC [M] arch/sparc/kernel/led.o arch/sparc/kernel/led.c: In function 'led_blink': arch/sparc/kernel/led.c:35: error: invalid use of undefined type 'struct timer_list' arch/sparc/kernel/led.c:35: error: 'jiffies' undeclared (first use in this function) arch/sparc/kernel/led.c:35: error: (Each undeclared identifier is reported only once arch/sparc/kernel/led.c:35: error: for each function it appears in.) arch/sparc/kernel/led.c:36: error: 'avenrun' undeclared (first use in this function) arch/sparc/kernel/led.c:36: error: 'FSHIFT' undeclared (first use in this function) arch/sparc/kernel/led.c:36: error: 'HZ' undeclared (first use in this function) arch/sparc/kernel/led.c:37: error: invalid use of undefined type 'struct timer_list' arch/sparc/kernel/led.c:39: error: invalid use of undefined type 'struct timer_list' arch/sparc/kernel/led.c:40: error: invalid use of undefined type 'struct timer_list' arch/sparc/kernel/led.c:42: error: implicit declaration of function 'add_timer' arch/sparc/kernel/led.c: In function 'led_write_proc': arch/sparc/kernel/led.c:70: error: implicit declaration of function 'copy_from_user' arch/sparc/kernel/led.c:84: error: implicit declaration of function 'del_timer_sync' arch/sparc/kernel/led.c: In function 'led_init': arch/sparc/kernel/led.c:109: error: implicit declaration of function 'init_timer' arch/sparc/kernel/led.c:110: error: invalid use of undefined type 'struct timer_list' make[1]: *** [arch/sparc/kernel/led.o] Error 1 Based upon original patch by Robert Reif. Signed-off-by: David S. Miller --- arch/sparc/kernel/led.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index 313d1620ae8e..59e9344e7a0d 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include From 7769bd1c65e3dc22391d60420fea0c859e39b716 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 24 Feb 2008 19:47:51 -0800 Subject: [PATCH 701/880] [SPARC64]: Fix section mismatchs from dr_cpu_data Fix following warnings: WARNING: vmlinux.o(.text+0x4b258): Section mismatch in reference from the function dr_cpu_data() to the function .devinit.text:mdesc_fill_in_cpu_data() WARNING: vmlinux.o(.text+0x4b290): Section mismatch in reference from the function dr_cpu_data() to the function .cpuinit.text:cpu_up() mdesc_fill_in_cpu_data() is only used during early init and for cpu hotplug so the __cpuinit annotation is the correct choice. We have the call chain: dr_cpu_data() => dr_cpu_configure() => mdesc_fill_in_cpu_data() dr_cpu_data() is used only during early init and for cpu hotplug. So annotating them all __cpuinit solves the section mismatch and should be correct. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc64/kernel/ds.c | 14 +++++++------- arch/sparc64/kernel/mdesc.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c index eeb5a2fc788d..bd76482077be 100644 --- a/arch/sparc64/kernel/ds.c +++ b/arch/sparc64/kernel/ds.c @@ -525,10 +525,10 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus, } } -static int dr_cpu_configure(struct ds_info *dp, - struct ds_cap_state *cp, - u64 req_num, - cpumask_t *mask) +static int __cpuinit dr_cpu_configure(struct ds_info *dp, + struct ds_cap_state *cp, + u64 req_num, + cpumask_t *mask) { struct ds_data *resp; int resp_len, ncpus, cpu; @@ -623,9 +623,9 @@ static int dr_cpu_unconfigure(struct ds_info *dp, return 0; } -static void dr_cpu_data(struct ds_info *dp, - struct ds_cap_state *cp, - void *buf, int len) +static void __cpuinit dr_cpu_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) { struct ds_data *data = buf; struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 856659bb1311..910083589569 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c @@ -758,7 +758,7 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp, get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } -void __devinit mdesc_fill_in_cpu_data(cpumask_t mask) +void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask) { struct mdesc_handle *hp = mdesc_grab(); u64 mp; From 896aef430e5afb56b5f7b1d959226b8a6a08108a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 24 Feb 2008 19:49:52 -0800 Subject: [PATCH 702/880] [SPARC64]: Fix section mismatch from kernel_map_range Fix following warnings: WARNING: vmlinux.o(.text+0x4f980): Section mismatch in reference from the function kernel_map_range() to the function .init.text:__alloc_bootmem() WARNING: vmlinux.o(.text+0x4f9cc): Section mismatch in reference from the function kernel_map_range() to the function .init.text:__alloc_bootmem() alloc_bootmem() is only used during early init and for any subsequent call to kernel_map_range() the program logic avoid the call. So annotate kernel_map_range() with __ref to tell modpost to ignore the reference to a __init function. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc64/mm/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 9e6bca266d88..b5c30416fdac 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1010,7 +1010,8 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata; static int pall_ents __initdata; #ifdef CONFIG_DEBUG_PAGEALLOC -static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot) +static unsigned long __ref kernel_map_range(unsigned long pstart, + unsigned long pend, pgprot_t prot) { unsigned long vstart = PAGE_OFFSET + pstart; unsigned long vend = PAGE_OFFSET + pend; From 0711d857605ba598cd6d4254462d1419b233321b Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 25 Feb 2008 15:16:50 +0800 Subject: [PATCH 703/880] Blackfin Serial Driver: Fix bug - Increase buffer tail immediately before starting tx dma. http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=2920 Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 69ac7007682e..2fb3081c5022 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -64,15 +64,20 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); static void bfin_serial_stop_tx(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; + struct circ_buf *xmit = &uart->port.info->xmit; #if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA) unsigned short ier; #endif while (!(UART_GET_LSR(uart) & TEMT)) - continue; + cpu_relax(); #ifdef CONFIG_SERIAL_BFIN_DMA disable_dma(uart->tx_dma_channel); + xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx += uart->tx_count; + uart->tx_count = 0; + uart->tx_done = 1; #else #ifdef CONFIG_BF54x /* Clear TFI bit */ @@ -94,7 +99,8 @@ static void bfin_serial_start_tx(struct uart_port *port) struct bfin_serial_port *uart = (struct bfin_serial_port *)port; #ifdef CONFIG_SERIAL_BFIN_DMA - bfin_serial_dma_tx_chars(uart); + if (uart->tx_done) + bfin_serial_dma_tx_chars(uart); #else #ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); @@ -389,12 +395,10 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) unsigned short ier; int flags = 0; - if (!uart->tx_done) - return; uart->tx_done = 0; if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { - bfin_serial_stop_tx(&uart->port); + uart->tx_count = 0; uart->tx_done = 1; return; } @@ -428,9 +432,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) set_dma_x_modify(uart->tx_dma_channel, 1); enable_dma(uart->tx_dma_channel); - xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); - uart->port.icount.tx += uart->tx_count; - #ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); #else @@ -515,8 +516,8 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) spin_lock(&uart->port.lock); if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { - clear_dma_irqstat(uart->tx_dma_channel); disable_dma(uart->tx_dma_channel); + clear_dma_irqstat(uart->tx_dma_channel); #ifdef CONFIG_BF54x UART_CLEAR_IER(uart, ETBEI); #else @@ -527,7 +528,8 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); - uart->tx_done = 1; + xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx += uart->tx_count; bfin_serial_dma_tx_chars(uart); } @@ -542,12 +544,14 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) unsigned short irqstat; uart->rx_dma_nrows++; - if (uart->rx_dma_nrows == DMA_RX_YCOUNT) { + uart->rx_dma_buf.tail = DMA_RX_XCOUNT * uart->rx_dma_nrows; + bfin_serial_dma_rx_chars(uart); + if (uart->rx_dma_nrows >= DMA_RX_YCOUNT) { uart->rx_dma_nrows = 0; - uart->rx_dma_buf.tail = DMA_RX_XCOUNT*DMA_RX_YCOUNT; - bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail = 0; + uart->rx_dma_buf.tail = 0; } + uart->rx_dma_buf.head = uart->rx_dma_buf.tail; + spin_lock(&uart->port.lock); irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); clear_dma_irqstat(uart->rx_dma_channel); From 56f5de8fe7c127f6fb94b7a061d53090fd4a1c49 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 25 Feb 2008 15:19:09 +0800 Subject: [PATCH 704/880] Blackfin Serial Driver: Fix bug - update tx dma buffer tail before wake up processes. Also make rx dma buffer work as a loop. Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 51 ++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 2fb3081c5022..2a4117485799 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -415,7 +415,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) */ bfin_serial_mctrl_check(uart); - spin_lock_irqsave(&uart->port.lock, flags); uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail)) uart->tx_count = UART_XMIT_SIZE - xmit->tail; @@ -439,7 +438,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) ier |= ETBEI; UART_PUT_IER(uart, ier); #endif - spin_unlock_irqrestore(&uart->port.lock, flags); } static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) @@ -450,7 +448,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) status = UART_GET_LSR(uart); UART_CLEAR_LSR(uart); - uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);; + uart->port.icount.rx += + CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, + UART_XMIT_SIZE); if (status & BI) { uart->port.icount.brk++; @@ -476,10 +476,12 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) else flg = TTY_NORMAL; - for (i = uart->rx_dma_buf.head; i < uart->rx_dma_buf.tail; i++) { - if (uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) - goto dma_ignore_char; - uart_insert_char(&uart->port, status, OE, uart->rx_dma_buf.buf[i], flg); + for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) { + if (i >= UART_XMIT_SIZE) + i = 0; + if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) + uart_insert_char(&uart->port, status, OE, + uart->rx_dma_buf.buf[i], flg); } dma_ignore_char: @@ -492,16 +494,20 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) int flags = 0; spin_lock_irqsave(&uart->port.lock, flags); - x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel); + uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel); + x_pos = get_dma_curr_xcount(uart->rx_dma_channel); + uart->rx_dma_nrows = DMA_RX_YCOUNT - uart->rx_dma_nrows; + if (uart->rx_dma_nrows == DMA_RX_YCOUNT) + uart->rx_dma_nrows = 0; + x_pos = DMA_RX_XCOUNT - x_pos; if (x_pos == DMA_RX_XCOUNT) x_pos = 0; pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos; - - if (pos>uart->rx_dma_buf.tail) { - uart->rx_dma_buf.tail = pos; + if (pos != uart->rx_dma_buf.tail) { + uart->rx_dma_buf.head = pos; bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail; + uart->rx_dma_buf.tail = uart->rx_dma_buf.head; } spin_unlock_irqrestore(&uart->port.lock, flags); uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; @@ -525,12 +531,12 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) ier &= ~ETBEI; UART_PUT_IER(uart, ier); #endif - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uart->port); - xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); uart->port.icount.tx += uart->tx_count; + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&uart->port); + bfin_serial_dma_tx_chars(uart); } @@ -542,15 +548,16 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; unsigned short irqstat; + int pos; - uart->rx_dma_nrows++; - uart->rx_dma_buf.tail = DMA_RX_XCOUNT * uart->rx_dma_nrows; - bfin_serial_dma_rx_chars(uart); - if (uart->rx_dma_nrows >= DMA_RX_YCOUNT) { - uart->rx_dma_nrows = 0; - uart->rx_dma_buf.tail = 0; + uart->rx_dma_nrows = DMA_RX_YCOUNT - + get_dma_curr_ycount(uart->rx_dma_channel); + pos = DMA_RX_XCOUNT * uart->rx_dma_nrows; + if (pos != uart->rx_dma_buf.tail) { + uart->rx_dma_buf.head = pos; + bfin_serial_dma_rx_chars(uart); + uart->rx_dma_buf.tail = uart->rx_dma_buf.head; } - uart->rx_dma_buf.head = uart->rx_dma_buf.tail; spin_lock(&uart->port.lock); irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); From cc645a020510cf68332a71394a32c1eacb92c6ed Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Feb 2008 15:09:27 +0900 Subject: [PATCH 705/880] sh: Rename SH-3 CCR3 reg to avoid synclink_cs clash. drivers/char/pcmcia/synclink_cs.c:284:1: warning: "CCR3" redefined In file included from include/asm/cache.h:13, from include/asm/processor_32.h:15, from include/asm/processor.h:60, from include/linux/prefetch.h:14, from include/linux/list.h:8, from include/linux/module.h:9, from drivers/char/pcmcia/synclink_cs.c:38: include/asm/cpu/cache.h:38:1: warning: this is the location of the previous definition Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/probe.c | 4 ++-- include/asm-sh/cpu-sh3/cache.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index fcc80bb7bee7..10f2a760c5ee 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void) boot_cpu_data.dcache.way_incr = (1 << 13); boot_cpu_data.dcache.entry_mask = 0x1ff0; boot_cpu_data.dcache.sets = 512; - ctrl_outl(CCR_CACHE_32KB, CCR3); + ctrl_outl(CCR_CACHE_32KB, CCR3_REG); #else - ctrl_outl(CCR_CACHE_16KB, CCR3); + ctrl_outl(CCR_CACHE_16KB, CCR3_REG); #endif #endif } diff --git a/include/asm-sh/cpu-sh3/cache.h b/include/asm-sh/cpu-sh3/cache.h index 56bd838b7db4..bee2d81c56bf 100644 --- a/include/asm-sh/cpu-sh3/cache.h +++ b/include/asm-sh/cpu-sh3/cache.h @@ -35,7 +35,7 @@ defined(CONFIG_CPU_SUBTYPE_SH7710) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) -#define CCR3 0xa40000b4 +#define CCR3_REG 0xa40000b4 #define CCR_CACHE_16KB 0x00010000 #define CCR_CACHE_32KB 0x00020000 #endif From 8ef97dd7a8721882732ea8041fc07c80be3882ba Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Feb 2008 15:30:54 +0900 Subject: [PATCH 706/880] sh: SH5-103 needs to select CPU_SH5. Without this, it's possible to have CONFIG_SUPERH32=y set on SH5-103 parts, which leads to much build badness. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b3400b5ad5c6..783cfbbf87ca 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -330,6 +330,7 @@ config CPU_SUBTYPE_SH5_101 config CPU_SUBTYPE_SH5_103 bool "Support SH5-103 processor" + select CPU_SH5 endchoice From 6892b75e60557a48c01d57ba320419a9e2ce9846 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 13 Feb 2008 14:02:36 +0100 Subject: [PATCH 707/880] sched: make early bootup sched_clock() use safer do not call sched_clock() too early. Not only might rq->idle not be set up - but pure per-cpu data might not be accessible either. this solves an ia64 early bootup hang with CONFIG_PRINTK_TIME=y. Tested-by: Tony Luck Acked-by: Tony Luck Acked-by: David S. Miller Signed-off-by: Ingo Molnar --- kernel/sched.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index b387a8de26a5..7286ccb01082 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -668,6 +668,8 @@ const_debug unsigned int sysctl_sched_nr_migrate = 32; */ unsigned int sysctl_sched_rt_period = 1000000; +static __read_mostly int scheduler_running; + /* * part of the period that we allow rt tasks to run in us. * default: 0.95s @@ -689,14 +691,16 @@ unsigned long long cpu_clock(int cpu) unsigned long flags; struct rq *rq; - local_irq_save(flags); - rq = cpu_rq(cpu); /* * Only call sched_clock() if the scheduler has already been * initialized (some code might call cpu_clock() very early): */ - if (rq->idle) - update_rq_clock(rq); + if (unlikely(!scheduler_running)) + return 0; + + local_irq_save(flags); + rq = cpu_rq(cpu); + update_rq_clock(rq); now = rq->clock; local_irq_restore(flags); @@ -7284,6 +7288,8 @@ void __init sched_init(void) * During early bootup we pretend to be a normal task: */ current->sched_class = &fair_sched_class; + + scheduler_running = 1; } #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP From 70eee74b70c1a8485ec5f2bafa13dbc66fab6e02 Mon Sep 17 00:00:00 2001 From: Balbir Singh Date: Fri, 22 Feb 2008 13:25:53 +0530 Subject: [PATCH 708/880] sched: remove duplicate code from sched_fair.c pick_task_entity() duplicates existing code. This functionality can be easily obtained using rb_last(). Avoid code duplication by using rb_last(). Signed-off-by: Balbir Singh Signed-off-by: Ingo Molnar --- kernel/sched_fair.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 6c091d6e159d..7abad50d935f 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -202,16 +202,13 @@ static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) { - struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; - struct sched_entity *se = NULL; - struct rb_node *parent; - - while (*link) { - parent = *link; - se = rb_entry(parent, struct sched_entity, run_node); - link = &parent->rb_right; - } + struct rb_node *last; + struct sched_entity *se; + last = rb_last(&cfs_rq->tasks_timeline); + if (!last) + return NULL; + se = rb_entry(last, struct sched_entity, run_node); return se; } From 7eee3e677d6e2e9007afcd7d79b0715525aa552e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 22 Feb 2008 10:32:21 +0100 Subject: [PATCH 709/880] sched: clean up __pick_last_entity() a bit Signed-off-by: Ingo Molnar --- kernel/sched_fair.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 7abad50d935f..c8e6492c5925 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -202,14 +202,12 @@ static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) { - struct rb_node *last; - struct sched_entity *se; + struct rb_node *last = rb_last(&cfs_rq->tasks_timeline); - last = rb_last(&cfs_rq->tasks_timeline); if (!last) return NULL; - se = rb_entry(last, struct sched_entity, run_node); - return se; + + return rb_entry(last, struct sched_entity, run_node); } /************************************************************** From 67ca7bde2e9d3516b5ae0188330ad1059ac03f38 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 15 Feb 2008 09:56:36 -0800 Subject: [PATCH 710/880] sched: fix signedness warnings in sched.c Unsigned long values are always assigned to switch_count, make it unsigned long. kernel/sched.c:3897:15: warning: incorrect type in assignment (different signedness) kernel/sched.c:3897:15: expected long *switch_count kernel/sched.c:3897:15: got unsigned long * kernel/sched.c:3921:16: warning: incorrect type in assignment (different signedness) kernel/sched.c:3921:16: expected long *switch_count kernel/sched.c:3921:16: got unsigned long * Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar --- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index 7286ccb01082..f06950c8a6ce 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3889,7 +3889,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev) asmlinkage void __sched schedule(void) { struct task_struct *prev, *next; - long *switch_count; + unsigned long *switch_count; struct rq *rq; int cpu; From 2d07b255c7b8a9723010e5c74778e058dc05162e Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 15 Feb 2008 09:56:34 -0800 Subject: [PATCH 711/880] sched: add declaration of sched_tail to sched.h Avoids sparse warnings: kernel/sched.c:2170:17: warning: symbol 'schedule_tail' was not declared. Should it be static? Avoids the need for an external declaration in arch/um/process.c Signed-off-by: Harvey Harrison Signed-off-by: Ingo Molnar --- arch/um/kernel/process.c | 2 -- include/linux/sched.h | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index fc50d2f959d1..e8cb9ff183e9 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -128,8 +128,6 @@ void *get_current(void) return current; } -extern void schedule_tail(struct task_struct *prev); - /* * This is called magically, by its address being stuffed in a jmp_buf * and being longjmp-d to. diff --git a/include/linux/sched.h b/include/linux/sched.h index e217d188a102..9c17e828d6d4 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -242,6 +242,7 @@ struct task_struct; extern void sched_init(void); extern void sched_init_smp(void); +extern asmlinkage void schedule_tail(struct task_struct *prev); extern void init_idle(struct task_struct *idle, int cpu); extern void init_idle_bootup_task(struct task_struct *idle); From ae0027869db7d28563cd783865fab04ffd18419c Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 14 Feb 2008 10:26:24 -0800 Subject: [PATCH 712/880] latencytop: fix kernel panic while reading latency proc file Reading /proc//latency or /proc//task//latency could cause NULL pointer dereference. In lstats_open(), get_proc_task() can return NULL, in which case the kernel will oops at lstats_show_proc() because m->private is NULL. When get_proc_task() returns NULL, the kernel should return -ENOENT. This can be reproduced by the following script. while : do date bash -c 'ls > ls.$$' & pid=$! cat /proc/$pid/latency & cat /proc/$pid/latency & cat /proc/$pid/latency & cat /proc/$pid/latency done Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/proc/base.c b/fs/proc/base.c index 96ee899d6502..989e3078d7af 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -350,6 +350,8 @@ static int lstats_open(struct inode *inode, struct file *file) struct seq_file *m; struct task_struct *task = get_proc_task(inode); + if (!task) + return -ENOENT; ret = single_open(file, lstats_show_proc, NULL); if (!ret) { m = file->private_data; From d6643d12cb0885d06a1491b16c1476abcbd53d40 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Thu, 14 Feb 2008 10:27:00 -0800 Subject: [PATCH 713/880] latencytop: fix memory leak on latency proc file At lstats_open(), calling get_proc_task() gets task struct, but it never put. put_task_struct() should be called when releasing. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 989e3078d7af..85e06e498078 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -360,6 +360,15 @@ static int lstats_open(struct inode *inode, struct file *file) return ret; } +static int lstats_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = file->private_data; + struct task_struct *task = m->private; + + put_task_struct(task); + return single_release(inode, file); +} + static ssize_t lstats_write(struct file *file, const char __user *buf, size_t count, loff_t *offs) { @@ -378,7 +387,7 @@ static const struct file_operations proc_lstats_operations = { .read = seq_read, .write = lstats_write, .llseek = seq_lseek, - .release = single_release, + .release = lstats_release, }; #endif From 13d77c37cab2bb906022309e1e7182c327e49916 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Wed, 20 Feb 2008 16:53:29 -0800 Subject: [PATCH 714/880] latencytop: change /proc task_struct access method Change getting task_struct by get_proc_task() at read or write time, and returns -ESRCH if get_proc_task() returns NULL. This is same behavior as other /proc files. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- fs/proc/base.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 85e06e498078..91a1bd67ac1d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -314,9 +314,12 @@ static int proc_pid_schedstat(struct task_struct *task, char *buffer) static int lstats_show_proc(struct seq_file *m, void *v) { int i; - struct task_struct *task = m->private; - seq_puts(m, "Latency Top version : v0.1\n"); + struct inode *inode = m->private; + struct task_struct *task = get_proc_task(inode); + if (!task) + return -ESRCH; + seq_puts(m, "Latency Top version : v0.1\n"); for (i = 0; i < 32; i++) { if (task->latency_record[i].backtrace[0]) { int q; @@ -341,43 +344,24 @@ static int lstats_show_proc(struct seq_file *m, void *v) } } + put_task_struct(task); return 0; } static int lstats_open(struct inode *inode, struct file *file) { - int ret; - struct seq_file *m; - struct task_struct *task = get_proc_task(inode); - - if (!task) - return -ENOENT; - ret = single_open(file, lstats_show_proc, NULL); - if (!ret) { - m = file->private_data; - m->private = task; - } - return ret; -} - -static int lstats_release(struct inode *inode, struct file *file) -{ - struct seq_file *m = file->private_data; - struct task_struct *task = m->private; - - put_task_struct(task); - return single_release(inode, file); + return single_open(file, lstats_show_proc, inode); } static ssize_t lstats_write(struct file *file, const char __user *buf, size_t count, loff_t *offs) { - struct seq_file *m; - struct task_struct *task; + struct task_struct *task = get_proc_task(file->f_dentry->d_inode); - m = file->private_data; - task = m->private; + if (!task) + return -ESRCH; clear_all_latency_tracing(task); + put_task_struct(task); return count; } @@ -387,7 +371,7 @@ static const struct file_operations proc_lstats_operations = { .read = seq_read, .write = lstats_write, .llseek = seq_lseek, - .release = lstats_release, + .release = single_release, }; #endif From 5606bf5d0cbfbc3dfa78793a3793c43dd045fb1b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 25 Feb 2008 15:37:42 -0500 Subject: [PATCH 715/880] ext4: add missing ext4_journal_stop() Add missing ext4_journal_stop() in error handling. Signed-off-by: Akinobu Mita Signed-off-by: "Theodore Ts'o" Cc: Stephen Tweedie Cc: adilger@clusterfs.com Cc: Andrew Morton Cc: Mingming Cao --- fs/ext4/resize.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9477a2bd6ff2..e29efa0f9d62 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1037,6 +1037,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, ext4_warning(sb, __FUNCTION__, "multiple resizers run on filesystem!"); unlock_super(sb); + ext4_journal_stop(handle); err = -EBUSY; goto exit_put; } From bdb9441e9c325d50b5ae17f7d3205d65b8ed2e5f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 25 Feb 2008 23:02:48 +0100 Subject: [PATCH 716/880] lockdep: increase MAX_LOCK_DEPTH Some code paths exceed the current max lock depth (XFS), so increase this limit a bit. I looked at making this a dynamic allocated array, but we should not advocate insane lock depths, so stay with this as long as it works... Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index e217d188a102..e3ea12437547 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1189,7 +1189,7 @@ struct task_struct { int softirq_context; #endif #ifdef CONFIG_LOCKDEP -# define MAX_LOCK_DEPTH 30UL +# define MAX_LOCK_DEPTH 48UL u64 curr_chain_key; int lockdep_depth; struct held_lock held_locks[MAX_LOCK_DEPTH]; From 1481197b50114d7212d659d41cb97f31a8934883 Mon Sep 17 00:00:00 2001 From: Dale Farnsworth Date: Mon, 25 Feb 2008 23:03:02 +0100 Subject: [PATCH 717/880] Subject: lockdep: include all lock classes in all_lock_classes Add each lock class to the all_lock_classes list when it is first registered. Previously, lock classes were added to all_lock_classes when the lock class was first used. Since one of the uses of the list is to find unused locks, this didn't work well. Signed-off-by: Dale Farnsworth Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/lockdep.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 3574379f4d62..81a4e4a3f087 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -779,6 +779,10 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) * parallel walking of the hash-list safe: */ list_add_tail_rcu(&class->hash_entry, hash_head); + /* + * Add it to the global list of classes: + */ + list_add_tail_rcu(&class->lock_entry, &all_lock_classes); if (verbose(class)) { graph_unlock(); @@ -2282,10 +2286,6 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, return 0; break; case LOCK_USED: - /* - * Add it to the global list of classes: - */ - list_add_tail_rcu(&this->class->lock_entry, &all_lock_classes); debug_atomic_dec(&nr_unused_locks); break; default: From c5c61bda5ecceaa0f16d326cd2c2147468a4c443 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 25 Feb 2008 02:07:25 +0200 Subject: [PATCH 718/880] make atapi_dmadir static atapi_dmadir can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 +- drivers/ata/libata.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fbc24358ada0..b57fad3eb24c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -113,7 +113,7 @@ int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); -int atapi_dmadir = 0; +static int atapi_dmadir = 0; module_param(atapi_dmadir, int, 0444); MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)"); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 6036dedfe377..aa884f71a12a 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -56,7 +56,6 @@ enum { extern unsigned int ata_print_id; extern struct workqueue_struct *ata_aux_wq; extern int atapi_enabled; -extern int atapi_dmadir; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; From 72ad6ec48989d4b5477128e739b960be11155036 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 25 Feb 2008 17:31:10 -0500 Subject: [PATCH 719/880] Revert "power_state: get rid of write-only variable in SATA" This reverts commit 559bbe6cbd0d8c68d40076a5f7dc98e3bf5864b2. Michael S. Tsirkin reports that this changes breaks suspend/resume. Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b57fad3eb24c..4fbcce758b04 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6567,6 +6567,8 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) ata_lpm_enable(host); rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); + if (rc == 0) + host->dev->power.power_state = mesg; return rc; } @@ -6585,6 +6587,7 @@ void ata_host_resume(struct ata_host *host) { ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET, ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); + host->dev->power.power_state = PMSG_ON; /* reenable link pm */ ata_lpm_disable(host); From 82d416fffb5e8e39e899be7075dbeeac5fb8f0c2 Mon Sep 17 00:00:00 2001 From: Bryan Rosenburg Date: Wed, 20 Feb 2008 17:31:48 -0600 Subject: [PATCH 720/880] RDMA/cxgb3: Fix shift calc in build_phys_page_list() for 1-entry page lists A single entry (addr 0x10001000, size 0x2000) will get converted to page address 0x10000000 with a page size of 0x4000. The code as it stands doesn't address the single buffer case, but in fact it allows the subsequent single-buffer special case to be eliminated entirely. Because the mask now includes the (page adjusted) starting and ending addresses, the general case works for the single buffer case as well. Signed-off-by: Bryan Rosenburg Acked-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb3/iwch_mem.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c index 73bfd1656f86..b8797c66676d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_mem.c +++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c @@ -136,14 +136,8 @@ int build_phys_page_list(struct ib_phys_buf *buffer_list, /* Find largest page shift we can use to cover buffers */ for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift)) - if (num_phys_buf > 1) { - if ((1ULL << *shift) & mask) - break; - } else - if (1ULL << *shift >= - buffer_list[0].size + - (buffer_list[0].addr & ((1ULL << *shift) - 1))) - break; + if ((1ULL << *shift) & mask) + break; buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1); buffer_list[0].addr &= ~0ull << *shift; From 9300c0c06788a409a97d54bbe3360d2f385fc621 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Thu, 21 Feb 2008 07:51:17 -0600 Subject: [PATCH 721/880] RDMA/nes: Resurrect error path dead code Adrian Bunk pointed out that a Coverity scan found some apparently dead code in nes_verbs.c that really shouldn't have been dead. The function nes_create_cq() was missing the assignment err = 1; just prior to an iteration that conditionally set err = 0 if a PBL was found for a given virtual CQ. I also noticed we should have been returning -EFAULT on a couple related error paths. Signed-off-by: Chien Tung Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_verbs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 4dafbe16e82a..201b95ee23cb 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1327,7 +1327,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, (long long unsigned int)req.user_wqe_buffers); nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); kfree(nesqp->allocated_buffer); - return ERR_PTR(-ENOMEM); + return ERR_PTR(-EFAULT); } } @@ -1674,6 +1674,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, } nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n", (unsigned long)req.user_cq_buffer, entries); + err = 1; list_for_each_entry(nespbl, &nes_ucontext->cq_reg_mem_list, list) { if (nespbl->user_base == (unsigned long )req.user_cq_buffer) { list_del(&nespbl->list); @@ -1686,7 +1687,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, if (err) { nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); kfree(nescq); - return ERR_PTR(err); + return ERR_PTR(-EFAULT); } pbl_entries = nespbl->pbl_size >> 3; From 65b07ec29354b345ff93914d064c2467aef4c862 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 21 Feb 2008 08:01:18 -0600 Subject: [PATCH 722/880] RDMA/nes: Fix off-by-one Fix an off-by-one spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 201b95ee23cb..692f0d821301 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -929,7 +929,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, NES_MAX_USER_DB_REGIONS, nesucontext->first_free_db); nes_debug(NES_DBG_PD, "find_first_zero_biton doorbells returned %u, mapping pd_id %u.\n", nespd->mmap_db_index, nespd->pd_id); - if (nespd->mmap_db_index > NES_MAX_USER_DB_REGIONS) { + if (nespd->mmap_db_index >= NES_MAX_USER_DB_REGIONS) { nes_debug(NES_DBG_PD, "mmap_db_index > MAX\n"); nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num); kfree(nespd); From 24d10f0c37d301e88f6965e3dc0aa684311544e5 Mon Sep 17 00:00:00 2001 From: Adrian McMenamin Date: Sat, 16 Feb 2008 23:37:33 +0000 Subject: [PATCH 723/880] maple: remove unused variable Remove an unused variable from the definition of struct maple_device Signed-off-by: Adrian McMenamin Signed-off-by: Paul Mundt --- include/linux/maple.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/maple.h b/include/linux/maple.h index 3f01e2bae1a1..d31e36ebb436 100644 --- a/include/linux/maple.h +++ b/include/linux/maple.h @@ -64,7 +64,6 @@ struct maple_driver { int (*connect) (struct maple_device * dev); void (*disconnect) (struct maple_device * dev); struct device_driver drv; - int registered; }; void maple_getcond_callback(struct maple_device *dev, From 4377e605e0b004a8d2049eac6cc89fbe1fdcdbb2 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 17 Feb 2008 15:38:35 +0100 Subject: [PATCH 724/880] sh: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2a/clock-sh7203.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c index 3feb95a4fcbc..fb781329848a 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c @@ -21,8 +21,8 @@ #include #include -const static int pll1rate[]={8,12,16,0}; -const static int pfc_divisors[]={1,2,3,4,6,8,12}; +static const int pll1rate[]={8,12,16,0}; +static const int pfc_divisors[]={1,2,3,4,6,8,12}; #define ifc_divisors pfc_divisors #if (CONFIG_SH_CLK_MD == 0) From 1de83e94e6d4af22614c100b0c69716ab6eaa870 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Mon, 18 Feb 2008 14:09:10 +0100 Subject: [PATCH 725/880] sh: heartbeat: ioremap is expected to succeed ioremap is expected to succeed Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Paul Mundt --- arch/sh/drivers/heartbeat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index b76a14f12ce2..ab77b0e0fa0e 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -93,7 +93,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev) } hd->base = ioremap_nocache(res->start, res->end - res->start + 1); - if (!unlikely(hd->base)) { + if (unlikely(!hd->base)) { dev_err(&pdev->dev, "ioremap failed\n"); if (!pdev->dev.platform_data) From b7fd095602468ee501c5bcc3f9ca788cb3834096 Mon Sep 17 00:00:00 2001 From: Rafael Ignacio Zurita Date: Mon, 18 Feb 2008 22:32:58 -0300 Subject: [PATCH 726/880] sh: fix rtc_resources setup for sh770x Fix the RTC resources setup for sh770x. Whit these proper start values RTC driver (drivers/rtc/rtc-sh.c) works. Signed-off-by: Rafael Ignacio Zurita Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 969804bb523b..9066ed78e283 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -123,15 +123,15 @@ static struct resource rtc_resources[] = { .flags = IORESOURCE_IO, }, [1] = { - .start = 20, + .start = 21, .flags = IORESOURCE_IRQ, }, [2] = { - .start = 21, + .start = 22, .flags = IORESOURCE_IRQ, }, [3] = { - .start = 22, + .start = 20, .flags = IORESOURCE_IRQ, }, }; From bd49666974a12f39eb9c74044e0b1753efcd94c4 Mon Sep 17 00:00:00 2001 From: Adrian McMenamin Date: Sun, 24 Feb 2008 14:30:23 +0000 Subject: [PATCH 727/880] maple: fix device detection The maple bus driver that went into the kernel mainline in September 2007 contained some bugs which were revealed by the update of the kobj code for the current release series. Unfortunately those bugs also helped ensure maple devices were properly detected. This patch (against the current git) now ensures that devices are properly detected again. (A previous attempt to fix this by delaying initialisation only partially fixed this - as became apparent when the bus was fully loaded) Signed-off-by: Adrian McMenamin Signed-off-by: Paul Mundt --- drivers/sh/maple/maple.c | 66 ++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index 9cfcfd8dad5e..617efb1640b1 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -1,7 +1,7 @@ /* * Core maple bus functionality * - * Copyright (C) 2007 Adrian McMenamin + * Copyright (C) 2007, 2008 Adrian McMenamin * * Based on 2.4 code by: * @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -54,7 +53,7 @@ static struct device maple_bus; static int subdevice_map[MAPLE_PORTS]; static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; static unsigned long maple_pnp_time; -static int started, scanning, liststatus, realscan; +static int started, scanning, liststatus, fullscan; static struct kmem_cache *maple_queue_cache; struct maple_device_specify { @@ -62,6 +61,9 @@ struct maple_device_specify { int unit; }; +static bool checked[4]; +static struct maple_device *baseunits[4]; + /** * maple_driver_register - register a device driver * automatically makes the driver bus a maple bus @@ -309,11 +311,9 @@ static void maple_attach_driver(struct maple_device *mdev) else break; - if (realscan) { - printk(KERN_INFO "Maple device detected: %s\n", - mdev->product_name); - printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); - } + printk(KERN_INFO "Maple device detected: %s\n", + mdev->product_name); + printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); function = be32_to_cpu(mdev->devinfo.function); @@ -323,10 +323,9 @@ static void maple_attach_driver(struct maple_device *mdev) mdev->driver = &maple_dummy_driver; sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port); } else { - if (realscan) - printk(KERN_INFO - "Maple bus at (%d, %d): Function 0x%lX\n", - mdev->port, mdev->unit, function); + printk(KERN_INFO + "Maple bus at (%d, %d): Function 0x%lX\n", + mdev->port, mdev->unit, function); matched = bus_for_each_drv(&maple_bus_type, NULL, mdev, @@ -334,9 +333,8 @@ static void maple_attach_driver(struct maple_device *mdev) if (matched == 0) { /* Driver does not exist yet */ - if (realscan) - printk(KERN_INFO - "No maple driver found.\n"); + printk(KERN_INFO + "No maple driver found.\n"); mdev->driver = &maple_dummy_driver; } sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port, @@ -472,9 +470,12 @@ static void maple_response_none(struct maple_device *mdev, maple_detach_driver(mdev); return; } - if (!started) { - printk(KERN_INFO "No maple devices attached to port %d\n", - mdev->port); + if (!started || !fullscan) { + if (checked[mdev->port] == false) { + checked[mdev->port] = true; + printk(KERN_INFO "No maple devices attached" + " to port %d\n", mdev->port); + } return; } maple_clean_submap(mdev); @@ -485,8 +486,14 @@ static void maple_response_devinfo(struct maple_device *mdev, char *recvbuf) { char submask; - if ((!started) || (scanning == 2)) { - maple_attach_driver(mdev); + if (!started || (scanning == 2) || !fullscan) { + if ((mdev->unit == 0) && (checked[mdev->port] == false)) { + checked[mdev->port] = true; + maple_attach_driver(mdev); + } else { + if (mdev->unit != 0) + maple_attach_driver(mdev); + } return; } if (mdev->unit == 0) { @@ -505,6 +512,7 @@ static void maple_dma_handler(struct work_struct *work) struct maple_device *dev; char *recvbuf; enum maple_code code; + int i; if (!maple_dma_done()) return; @@ -557,6 +565,19 @@ static void maple_dma_handler(struct work_struct *work) } else scanning = 0; + if (!fullscan) { + fullscan = 1; + for (i = 0; i < MAPLE_PORTS; i++) { + if (checked[i] == false) { + fullscan = 0; + dev = baseunits[i]; + dev->mq->command = + MAPLE_COMMAND_DEVINFO; + dev->mq->length = 0; + maple_add_packet(dev->mq); + } + } + } if (started == 0) started = 1; } @@ -694,7 +715,9 @@ static int __init maple_bus_init(void) /* setup maple ports */ for (i = 0; i < MAPLE_PORTS; i++) { + checked[i] = false; mdev[i] = maple_alloc_dev(i, 0); + baseunits[i] = mdev[i]; if (!mdev[i]) { while (i-- > 0) maple_free_dev(mdev[i]); @@ -703,12 +726,9 @@ static int __init maple_bus_init(void) mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; mdev[i]->mq->length = 0; maple_add_packet(mdev[i]->mq); - /* delay aids hardware detection */ - mdelay(5); subdevice_map[i] = 0; } - realscan = 1; /* setup maplebus hardware */ maplebus_dma_reset(); /* initial detection */ From 763a495a022ac26afb2940e768e86725c1c7e8c9 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 26 Feb 2008 14:14:56 +0900 Subject: [PATCH 728/880] sh: revert dreamcast pci change Commit e036eaa681a17f71b64f6d9040fe605555623919 broke dreamcast pci, this patch fixes that by reverting the dreamcast specific bits. Signed-off-by: Magnus Damm Acked-by: Adrian McMenamin Signed-off-by: Andrew Morton Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-dreamcast.c | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index 0dac87b19624..e1284fc69361 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c @@ -83,9 +83,9 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: *val = ctrl_inb(GAPSPCI_BBA_CONFIG+where); break; - case 2: *val = ctrl_inw(GAPSPCI_BBA_CONFIG+where); break; - case 4: *val = ctrl_inl(GAPSPCI_BBA_CONFIG+where); break; + case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; + case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; + case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -97,9 +97,9 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: ctrl_outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; - case 2: ctrl_outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; - case 4: ctrl_outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; + case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; + case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; + case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -127,36 +127,36 @@ int __init gapspci_init(void) */ for (i=0; i<16; i++) - idbuf[i] = ctrl_inb(GAPSPCI_REGS+i); + idbuf[i] = inb(GAPSPCI_REGS+i); if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) return -ENODEV; - ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18); + outl(0x5a14a501, GAPSPCI_REGS+0x18); for (i=0; i<1000000; i++) ; - if (ctrl_inl(GAPSPCI_REGS+0x18) != 1) + if (inl(GAPSPCI_REGS+0x18) != 1) return -EINVAL; - ctrl_outl(0x01000000, GAPSPCI_REGS+0x20); - ctrl_outl(0x01000000, GAPSPCI_REGS+0x24); + outl(0x01000000, GAPSPCI_REGS+0x20); + outl(0x01000000, GAPSPCI_REGS+0x24); - ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); - ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); + outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); + outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); - ctrl_outl(1, GAPSPCI_REGS+0x14); - ctrl_outl(1, GAPSPCI_REGS+0x34); + outl(1, GAPSPCI_REGS+0x14); + outl(1, GAPSPCI_REGS+0x34); /* Setting Broadband Adapter */ - ctrl_outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); - ctrl_outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); - ctrl_outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); - ctrl_outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); - ctrl_outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); - ctrl_outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); - ctrl_outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); + outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); + outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); + outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); + outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); + outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); + outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); + outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); return 0; } From 8b1d16540c6ae4e62fcff56bd47794951b3ca87a Mon Sep 17 00:00:00 2001 From: Hideo Saito Date: Tue, 26 Feb 2008 14:28:48 +0900 Subject: [PATCH 729/880] sh: Fix up HAS_SR_RB typo in entry-macros. Signed-off-by: Hideo Saito Signed-off-by: Paul Mundt --- include/asm-sh/entry-macros.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-sh/entry-macros.S b/include/asm-sh/entry-macros.S index 500030eae7aa..2dab0b8d9454 100644 --- a/include/asm-sh/entry-macros.S +++ b/include/asm-sh/entry-macros.S @@ -12,7 +12,7 @@ not r11, r11 stc sr, r10 and r11, r10 -#ifdef CONFIG_HAS_SR_RB +#ifdef CONFIG_CPU_HAS_SR_RB stc k_g_imask, r11 or r11, r10 #endif @@ -20,7 +20,7 @@ .endm .macro get_current_thread_info, ti, tmp -#ifdef CONFIG_HAS_SR_RB +#ifdef CONFIG_CPU_HAS_SR_RB stc r7_bank, \ti #else mov #((THREAD_SIZE - 1) >> 10) ^ 0xff, \tmp From 96de1a8f0275bd67f243833e7088baced518f873 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 26 Feb 2008 14:52:45 +0900 Subject: [PATCH 730/880] serial: Move asm-sh/sci.h to linux/serial_sci.h. This header is needed on other architectures as well (namely h8300), which currently fails to build without this in place. Rather than duplicating the port definition completely there, just move this to a common location instead. This should get h8300 working again for 2.6.25, in addition to the changes already pushed by Sato-san in -rc2. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 2 +- arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 2 +- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-shx3.c | 2 +- drivers/serial/sh-sci.c | 2 +- include/{asm-sh/sci.h => linux/serial_sci.h} | 10 ++++------ 20 files changed, 23 insertions(+), 25 deletions(-) rename include/{asm-sh/sci.h => linux/serial_sci.h} (73%) diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index b230eb278cef..cc530f4d84d6 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index db6ef5cecde1..e98dc4450352 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index a564425b905f..e6d4ec445dd8 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index dd0a20a685f7..f581534cb732 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include enum { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 9066ed78e283..d3733b13ea52 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 0cc0e2bf135d..7406c9ad9259 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include enum { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 3855ea4c21c8..8028082527c5 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #define INTC_ICR1 0xA4140010UL diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index dab193293f20..7371abf64f80 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index ae3603aca615..ec884039b914 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 85f81579b97e..254c5c55ab91 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index c0a3f079dfdc..6d4f50cd4aaf 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 967e8b69a2f8..f26b5cdad0d1 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 73c778d40d13..b98b4bc93ec9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -10,9 +10,9 @@ #include #include #include +#include #include #include -#include static struct resource usbf_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index eabd5386812d..07c988dc9de6 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 32f4f59a837b..b9cec48b1808 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 293004b526ff..18dbbe23fea1 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 74b60e96cdf4..621e7329ec63 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -10,10 +10,10 @@ #include #include #include +#include #include #include #include -#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 4dc958b6b314..bd35f32534b9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -10,9 +10,9 @@ #include #include #include +#include #include #include -#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 9ce12cb2cebc..a8c116b80bff 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef CONFIG_CPU_FREQ #include @@ -54,7 +55,6 @@ #include #endif -#include #include "sh-sci.h" struct sci_port { diff --git a/include/asm-sh/sci.h b/include/linux/serial_sci.h similarity index 73% rename from include/asm-sh/sci.h rename to include/linux/serial_sci.h index 52e73660c129..893cc53486bc 100644 --- a/include/asm-sh/sci.h +++ b/include/linux/serial_sci.h @@ -1,12 +1,10 @@ -#ifndef __ASM_SH_SCI_H -#define __ASM_SH_SCI_H +#ifndef __LINUX_SERIAL_SCI_H +#define __LINUX_SERIAL_SCI_H #include /* - * Generic header for SuperH SCI(F) - * - * Do not place SH-specific parts in here, sh64 and h8300 depend on this too. + * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) */ /* Offsets into the sci_port->irqs array */ @@ -31,4 +29,4 @@ struct plat_sci_port { int early_sci_setup(struct uart_port *port); -#endif /* __ASM_SH_SCI_H */ +#endif /* __LINUX_SERIAL_SCI_H */ From db69c915e67705daac25cad06d816c09be634de0 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Tue, 26 Feb 2008 17:00:14 +1100 Subject: [PATCH 731/880] [XFS] Undo bit ops cleanup mod due to regression on 32-bit powermac platform. SGI-PV: 974005 SGI-Modid: xfs-linux-melb:xfs-kern:30558a Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_bit.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 325a007dec91..0f9fc9a3c415 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h @@ -61,15 +61,15 @@ static inline int xfs_highbit64(__uint64_t v) /* Get low bit set out of 32-bit argument, -1 if none set */ static inline int xfs_lowbit32(__uint32_t v) { - __uint32_t t = v; - return (t) ? find_first_bit((unsigned long *)&t, 32) : -1; + unsigned long t = v; + return (v) ? find_first_bit(&t, 32) : -1; } /* Get low bit set out of 64-bit argument, -1 if none set */ static inline int xfs_lowbit64(__uint64_t v) { - __uint64_t t = v; - return (t) ? find_first_bit((unsigned long *)&t, 64) : -1; + unsigned long t = v; + return (v) ? find_first_bit(&t, 64) : -1; } /* Return whether bitmap is empty (1 == empty) */ From ef8ece55d9b6825c28a5c1a4bd89b94040cb7b32 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Tue, 26 Feb 2008 17:00:22 +1100 Subject: [PATCH 732/880] [XFS] Undo bit ops cleanup mod due to regression on 32-bit powermac platform. SGI-PV: 971186 SGI-Modid: xfs-linux-melb:xfs-kern:30559a Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_bit.c | 103 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_bit.h | 27 +++--------- fs/xfs/xfs_rtalloc.c | 19 +++++--- 3 files changed, 120 insertions(+), 29 deletions(-) diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index 48228848f5ae..fab0b6d5a41b 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c @@ -25,6 +25,109 @@ * XFS bit manipulation routines, used in non-realtime code. */ +#ifndef HAVE_ARCH_HIGHBIT +/* + * Index of high bit number in byte, -1 for none set, 0..7 otherwise. + */ +static const char xfs_highbit[256] = { + -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ + 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ + 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ + 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ + 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ + 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ +}; +#endif + +/* + * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. + */ +inline int +xfs_highbit32( + __uint32_t v) +{ +#ifdef HAVE_ARCH_HIGHBIT + return highbit32(v); +#else + int i; + + if (v & 0xffff0000) + if (v & 0xff000000) + i = 24; + else + i = 16; + else if (v & 0x0000ffff) + if (v & 0x0000ff00) + i = 8; + else + i = 0; + else + return -1; + return i + xfs_highbit[(v >> i) & 0xff]; +#endif +} + +/* + * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. + */ +int +xfs_lowbit64( + __uint64_t v) +{ + __uint32_t w = (__uint32_t)v; + int n = 0; + + if (w) { /* lower bits */ + n = ffs(w); + } else { /* upper bits */ + w = (__uint32_t)(v >> 32); + if (w && (n = ffs(w))) + n += 32; + } + return n - 1; +} + +/* + * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. + */ +int +xfs_highbit64( + __uint64_t v) +{ + __uint32_t h = (__uint32_t)(v >> 32); + + if (h) + return xfs_highbit32(h) + 32; + return xfs_highbit32((__uint32_t)v); +} + + /* * Return whether bitmap is empty. * Size is number of words in the bitmap, which is padded to word boundary diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 0f9fc9a3c415..082641a9782c 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h @@ -47,30 +47,13 @@ static inline __uint64_t xfs_mask64lo(int n) } /* Get high bit set out of 32-bit argument, -1 if none set */ -static inline int xfs_highbit32(__uint32_t v) -{ - return fls(v) - 1; -} - -/* Get high bit set out of 64-bit argument, -1 if none set */ -static inline int xfs_highbit64(__uint64_t v) -{ - return fls64(v) - 1; -} - -/* Get low bit set out of 32-bit argument, -1 if none set */ -static inline int xfs_lowbit32(__uint32_t v) -{ - unsigned long t = v; - return (v) ? find_first_bit(&t, 32) : -1; -} +extern int xfs_highbit32(__uint32_t v); /* Get low bit set out of 64-bit argument, -1 if none set */ -static inline int xfs_lowbit64(__uint64_t v) -{ - unsigned long t = v; - return (v) ? find_first_bit(&t, 64) : -1; -} +extern int xfs_lowbit64(__uint64_t v); + +/* Get high bit set out of 64-bit argument, -1 if none set */ +extern int xfs_highbit64(__uint64_t); /* Return whether bitmap is empty (1 == empty) */ extern int xfs_bitmap_empty(uint *map, uint size); diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index ca83ddf72af4..47082c01872d 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -72,6 +72,18 @@ STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, * Internal functions. */ +/* + * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set. + */ +STATIC int +xfs_lowbit32( + __uint32_t v) +{ + if (v) + return ffs(v) - 1; + return -1; +} + /* * Allocate space to the bitmap or summary file, and zero it, for growfs. */ @@ -432,7 +444,6 @@ xfs_rtallocate_extent_near( } bbno = XFS_BITTOBLOCK(mp, bno); i = 0; - ASSERT(minlen != 0); log2len = xfs_highbit32(minlen); /* * Loop over all bitmap blocks (bbno + i is current block). @@ -601,8 +612,6 @@ xfs_rtallocate_extent_size( xfs_suminfo_t sum; /* summary information for extents */ ASSERT(minlen % prod == 0 && maxlen % prod == 0); - ASSERT(maxlen != 0); - /* * Loop over all the levels starting with maxlen. * At each level, look at all the bitmap blocks, to see if there @@ -660,9 +669,6 @@ xfs_rtallocate_extent_size( *rtblock = NULLRTBLOCK; return 0; } - ASSERT(minlen != 0); - ASSERT(maxlen != 0); - /* * Loop over sizes, from maxlen down to minlen. * This time, when we do the allocations, allow smaller ones @@ -1948,7 +1954,6 @@ xfs_growfs_rt( nsbp->sb_blocksize * nsbp->sb_rextsize); nsbp->sb_rextents = nsbp->sb_rblocks; do_div(nsbp->sb_rextents, nsbp->sb_rextsize); - ASSERT(nsbp->sb_rextents != 0); nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; nrsumsize = From cbc34973709eb41b369c304c075cf2069f847012 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 13:14:35 -0800 Subject: [PATCH 733/880] lguest: include function prototypes Added a declaration to asm-x86/lguest.h and moved the extern arrays there as well. As an alternative to including asm/lguest.h directly, an include could be put in linux/lguest.h Signed-off-by: Harvey Harrison Cc: "rusty@rustcorp.com.au" Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/lguest/boot.c | 10 +--------- include/asm-x86/lguest.h | 11 +++++++++++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 5afdde4895dc..1e613fb03e32 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -75,15 +76,6 @@ * behaving in simplified but equivalent ways. In particular, the Guest is the * same kernel as the Host (or at least, built from the same source code). :*/ -/* Declarations for definitions in lguest_guest.S */ -extern char lguest_noirq_start[], lguest_noirq_end[]; -extern const char lgstart_cli[], lgend_cli[]; -extern const char lgstart_sti[], lgend_sti[]; -extern const char lgstart_popf[], lgend_popf[]; -extern const char lgstart_pushf[], lgend_pushf[]; -extern const char lgstart_iret[], lgend_iret[]; -extern void lguest_iret(void); - struct lguest_data lguest_data = { .hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF }, .noirq_start = (u32)lguest_noirq_start, diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h index 4d9367b72976..9b17571e9bc3 100644 --- a/include/asm-x86/lguest.h +++ b/include/asm-x86/lguest.h @@ -23,6 +23,17 @@ /* Found in switcher.S */ extern unsigned long default_idt_entries[]; +/* Declarations for definitions in lguest_guest.S */ +extern char lguest_noirq_start[], lguest_noirq_end[]; +extern const char lgstart_cli[], lgend_cli[]; +extern const char lgstart_sti[], lgend_sti[]; +extern const char lgstart_popf[], lgend_popf[]; +extern const char lgstart_pushf[], lgend_pushf[]; +extern const char lgstart_iret[], lgend_iret[]; + +extern void lguest_iret(void); +extern void lguest_init(void); + struct lguest_regs { /* Manually saved part. */ From db342d216ba9e060d8c5501eefc1d0a789c9e711 Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Tue, 19 Feb 2008 08:16:03 +0100 Subject: [PATCH 734/880] lguest: fix build breakage [ mingo@elte.hu: merged to Rusty's patch ] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/asm-offsets_32.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index a33d53017997..8ea040124f7d 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -128,13 +128,11 @@ void foo(void) OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending); #endif -#ifdef CONFIG_LGUEST_GUEST +#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE) BLANK(); OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled); OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir); -#endif -#ifdef CONFIG_LGUEST BLANK(); OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc); OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc); From 1ce70c4fac3c3954bd48c035f448793867592bc0 Mon Sep 17 00:00:00 2001 From: "Ahmed S. Darwish" Date: Sun, 24 Feb 2008 17:55:15 +0200 Subject: [PATCH 735/880] x86/lguest: fix pgdir pmd index calculation Hi all, Beginning from commits close to v2.6.25-rc2, running lguest always oopses the host kernel. Oops is at [1]. Bisection led to the following commit: commit 37cc8d7f963ba2deec29c9b68716944516a3244f x86/early_ioremap: don't assume we're using swapper_pg_dir At the early stages of boot, before the kernel pagetable has been fully initialized, a Xen kernel will still be running off the Xen-provided pagetables rather than swapper_pg_dir[]. Therefore, readback cr3 to determine the base of the pagetable rather than assuming swapper_pg_dir[]. static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) { - pgd_t *pgd = &swapper_pg_dir[pgd_index(addr)]; + /* Don't assume we're using swapper_pg_dir at this point */ + pgd_t *base = __va(read_cr3()); + pgd_t *pgd = &base[pgd_index(addr)]; pud_t *pud = pud_offset(pgd, addr); pmd_t *pmd = pmd_offset(pud, addr); Trying to analyze the problem, it seems on the guest side of lguest, %cr3 has a different value from &swapper_pg-dir (which is AFAIK fine on a pravirt guest): Putting some debugging messages in early_ioremap_pmd: /* Appears 3 times */ [ 0.000000] *************************** [ 0.000000] __va(%cr3) = c0000000, &swapper_pg_dir = c02cc000 [ 0.000000] *************************** After 8 hours of debugging and staring on lguest code, I noticed something strange in paravirt_ops->set_pmd hypercall invocation: static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) { *pmdp = pmdval; lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK, (__pa(pmdp)&(PAGE_SIZE-1))/4, 0); } The first hcall parameter is global pgdir which looks fine. The second parameter is the pmd index in the pgdir which is suspectful. AFAIK, calculating the index of pmd does not need a divisoin over four. Removing the division made lguest work fine again . Patch is at [2]. I am not sure why the division over four existed in the first place. It seems bogus, maybe the Xen patch just made the problem appear ? [2]: The patch: [PATCH] lguest: fix pgdir pmd index cacluation Remove an error in index calculation which leads to removing a not existing shadow page table (leading to a Null dereference). Signed-off-by: Ahmed S. Darwish Signed-off-by: Ingo Molnar --- arch/x86/lguest/boot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 1e613fb03e32..cccb38a59653 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -481,7 +481,7 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) { *pmdp = pmdval; lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK, - (__pa(pmdp)&(PAGE_SIZE-1))/4, 0); + (__pa(pmdp)&(PAGE_SIZE-1)), 0); } /* There are a couple of legacy places where the kernel sets a PTE, but we From 92cb54a37a42a41cfb2ef7f1478bfa4395198258 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 13 Feb 2008 14:37:52 +0100 Subject: [PATCH 736/880] x86: make DEBUG_PAGEALLOC and CPA more robust Use PF_MEMALLOC to prevent recursive calls in the DBEUG_PAGEALLOC case. This makes the code simpler and more robust against allocation failures. This fixes the following fallback to non-mmconfig: http://lkml.org/lkml/2008/2/20/551 http://bugzilla.kernel.org/show_bug.cgi?id=10083 Also, for DEBUG_PAGEALLOC=n reduce the pool size to one page. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/mm/pageattr.c | 84 +++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 464d8fc21ce6..14e48b5a94ba 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -44,6 +44,12 @@ static inline unsigned long highmap_end_pfn(void) #endif +#ifdef CONFIG_DEBUG_PAGEALLOC +# define debug_pagealloc 1 +#else +# define debug_pagealloc 0 +#endif + static inline int within(unsigned long addr, unsigned long start, unsigned long end) { @@ -355,45 +361,48 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, static LIST_HEAD(page_pool); static unsigned long pool_size, pool_pages, pool_low; -static unsigned long pool_used, pool_failed, pool_refill; +static unsigned long pool_used, pool_failed; -static void cpa_fill_pool(void) +static void cpa_fill_pool(struct page **ret) { - struct page *p; gfp_t gfp = GFP_KERNEL; + unsigned long flags; + struct page *p; - /* Do not allocate from interrupt context */ - if (in_irq() || irqs_disabled()) - return; /* - * Check unlocked. I does not matter when we have one more - * page in the pool. The bit lock avoids recursive pool - * allocations: + * Avoid recursion (on debug-pagealloc) and also signal + * our priority to get to these pagetables: */ - if (pool_pages >= pool_size || test_and_set_bit_lock(0, &pool_refill)) + if (current->flags & PF_MEMALLOC) return; + current->flags |= PF_MEMALLOC; -#ifdef CONFIG_DEBUG_PAGEALLOC /* - * We could do: - * gfp = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - * but this fails on !PREEMPT kernels + * Allocate atomically from atomic contexts: */ - gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; -#endif + if (in_atomic() || irqs_disabled() || debug_pagealloc) + gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; - while (pool_pages < pool_size) { + while (pool_pages < pool_size || (ret && !*ret)) { p = alloc_pages(gfp, 0); if (!p) { pool_failed++; break; } - spin_lock_irq(&pgd_lock); + /* + * If the call site needs a page right now, provide it: + */ + if (ret && !*ret) { + *ret = p; + continue; + } + spin_lock_irqsave(&pgd_lock, flags); list_add(&p->lru, &page_pool); pool_pages++; - spin_unlock_irq(&pgd_lock); + spin_unlock_irqrestore(&pgd_lock, flags); } - clear_bit_unlock(0, &pool_refill); + + current->flags &= ~PF_MEMALLOC; } #define SHIFT_MB (20 - PAGE_SHIFT) @@ -414,11 +423,15 @@ void __init cpa_init(void) * GiB. Shift MiB to Gib and multiply the result by * POOL_PAGES_PER_GB: */ - gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB; - pool_size = POOL_PAGES_PER_GB * gb; + if (debug_pagealloc) { + gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB; + pool_size = POOL_PAGES_PER_GB * gb; + } else { + pool_size = 1; + } pool_low = pool_size; - cpa_fill_pool(); + cpa_fill_pool(NULL); printk(KERN_DEBUG "CPA: page pool initialized %lu of %lu pages preallocated\n", pool_pages, pool_size); @@ -440,16 +453,20 @@ static int split_large_page(pte_t *kpte, unsigned long address) spin_lock_irqsave(&pgd_lock, flags); if (list_empty(&page_pool)) { spin_unlock_irqrestore(&pgd_lock, flags); - return -ENOMEM; + base = NULL; + cpa_fill_pool(&base); + if (!base) + return -ENOMEM; + spin_lock_irqsave(&pgd_lock, flags); + } else { + base = list_first_entry(&page_pool, struct page, lru); + list_del(&base->lru); + pool_pages--; + + if (pool_pages < pool_low) + pool_low = pool_pages; } - base = list_first_entry(&page_pool, struct page, lru); - list_del(&base->lru); - pool_pages--; - - if (pool_pages < pool_low) - pool_low = pool_pages; - /* * Check for races, another CPU might have split this page * up for us already: @@ -734,7 +751,8 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, cpa_flush_all(cache); out: - cpa_fill_pool(); + cpa_fill_pool(NULL); + return ret; } @@ -897,7 +915,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable) * Try to refill the page pool here. We can do this only after * the tlb flush. */ - cpa_fill_pool(); + cpa_fill_pool(NULL); } #ifdef CONFIG_HIBERNATION From b02a7f22f39f02fdf5a1380ff700293639db4490 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 5 Feb 2008 00:48:13 +0100 Subject: [PATCH 737/880] x86: hpet fix docbook comment Signed-off-by: Pavel Machek Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/hpet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 429d084e014d..235fd6c77504 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -368,8 +368,8 @@ static int hpet_clocksource_register(void) return 0; } -/* - * Try to setup the HPET timer +/** + * hpet_enable - Try to setup the HPET timer. Returns 1 on success. */ int __init hpet_enable(void) { From a7ef94e6889186848573a10c5bdb8271405f44de Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 14 Feb 2008 14:51:00 -0800 Subject: [PATCH 738/880] x86: do not promote TM3x00/TM5x00 to i686-class We have been promoting Transmeta TM3x00/TM5x00 chips to i686-class based on the notion that they contain all the user-space visible features of an i686-class chip. However, this is not actually true: they lack the EA-taking long NOPs (0F 1F /0). Since this is a userspace-visible incompatibility, downgrade these CPUs to the manufacturer-defined i586 level. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/transmeta.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c index 200fb3f9ebfb..e8b422c1c512 100644 --- a/arch/x86/kernel/cpu/transmeta.c +++ b/arch/x86/kernel/cpu/transmeta.c @@ -76,13 +76,6 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) /* All Transmeta CPUs have a constant TSC */ set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); - /* If we can run i686 user-space code, call us an i686 */ -#define USER686 ((1 << X86_FEATURE_TSC)|\ - (1 << X86_FEATURE_CX8)|\ - (1 << X86_FEATURE_CMOV)) - if (c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686) - c->x86 = 6; - #ifdef CONFIG_SYSCTL /* randomize_va_space slows us down enormously; it probably triggers retranslation of x86->native bytecode */ From 7343b3b3a627eb30e24e921f004f659c8ebb91c5 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 14 Feb 2008 14:52:05 -0800 Subject: [PATCH 739/880] x86: require family >= 6 if we are using P6 NOPs The P6 family of NOPs are only available on family >= 6 or above, so enforce that in the boot code. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig.cpu | 5 +++++ include/asm-x86/nops.h | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index e09a6b73a1aa..86fd2a0e4597 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -377,6 +377,10 @@ config X86_OOSTORE def_bool y depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR +config X86_P6_NOP + def_bool y + depends on (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || PENTIUM4) + config X86_TSC def_bool y depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 @@ -390,6 +394,7 @@ config X86_CMOV config X86_MINIMUM_CPU_FAMILY int default "64" if X86_64 + default "6" if X86_32 && X86_P6_NOP default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) default "3" diff --git a/include/asm-x86/nops.h b/include/asm-x86/nops.h index fec025c7f58c..c52b334b8166 100644 --- a/include/asm-x86/nops.h +++ b/include/asm-x86/nops.h @@ -63,9 +63,7 @@ #define ASM_NOP6 K7_NOP6 #define ASM_NOP7 K7_NOP7 #define ASM_NOP8 K7_NOP8 -#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \ - defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \ - defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4) +#elif defined(CONFIG_X86_P6_NOP) #define ASM_NOP1 P6_NOP1 #define ASM_NOP2 P6_NOP2 #define ASM_NOP3 P6_NOP3 From 959b3be64cab9160cd74532a49b89cdd918d38e9 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 14 Feb 2008 14:56:45 -0800 Subject: [PATCH 740/880] x86: don't use P6_NOPs if compiling with CONFIG_X86_GENERIC P6_NOPs are definitely not supported on some VIA CPUs, and possibly (unverified) on AMD K7s. It is also the only thing that prevents a 686 kernel from running on Transmeta TM3x00/5x00 (Crusoe) series. The performance benefit over generic NOPs is very small, so when building for generic consumption, avoid using them. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig.cpu | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 86fd2a0e4597..6d50064db182 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -377,9 +377,18 @@ config X86_OOSTORE def_bool y depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR +# +# P6_NOPs are a relatively minor optimization that require a family >= +# 6 processor, except that it is broken on certain VIA chips. +# Furthermore, AMD chips prefer a totally different sequence of NOPs +# (which work on all CPUs). As a result, disallow these if we're +# compiling X86_GENERIC but not X86_64 (these NOPs do work on all +# x86-64 capable chips); the list of processors in the right-hand clause +# are the cores that benefit from this optimization. +# config X86_P6_NOP def_bool y - depends on (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || PENTIUM4) + depends on (X86_64 || !X86_GENERIC) && (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || PENTIUM4) config X86_TSC def_bool y From 4cd20952d74323df06e438c0c3273b5be89d6bfd Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 18 Feb 2008 23:24:33 -0800 Subject: [PATCH 741/880] x86: add comments for NOPs Add comments describing the various NOP sequences. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/nops.h | 62 ++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/include/asm-x86/nops.h b/include/asm-x86/nops.h index c52b334b8166..e3b2bce0aff8 100644 --- a/include/asm-x86/nops.h +++ b/include/asm-x86/nops.h @@ -3,17 +3,29 @@ /* Define nops for use with alternative() */ -/* generic versions from gas */ -#define GENERIC_NOP1 ".byte 0x90\n" -#define GENERIC_NOP2 ".byte 0x89,0xf6\n" -#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" -#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" -#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 -#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 +/* generic versions from gas + 1: nop + 2: movl %esi,%esi + 3: leal 0x00(%esi),%esi + 4: leal 0x00(,%esi,1),%esi + 6: leal 0x00000000(%esi),%esi + 7: leal 0x00000000(,%esi,1),%esi +*/ +#define GENERIC_NOP1 ".byte 0x90\n" +#define GENERIC_NOP2 ".byte 0x89,0xf6\n" +#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" +#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" +#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 +#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 -/* Opteron 64bit nops */ +/* Opteron 64bit nops + 1: nop + 2: osp nop + 3: osp osp nop + 4: osp osp osp nop +*/ #define K8_NOP1 GENERIC_NOP1 #define K8_NOP2 ".byte 0x66,0x90\n" #define K8_NOP3 ".byte 0x66,0x66,0x90\n" @@ -23,19 +35,35 @@ #define K8_NOP7 K8_NOP4 K8_NOP3 #define K8_NOP8 K8_NOP4 K8_NOP4 -/* K7 nops */ -/* uses eax dependencies (arbitary choice) */ -#define K7_NOP1 GENERIC_NOP1 +/* K7 nops + uses eax dependencies (arbitary choice) + 1: nop + 2: movl %eax,%eax + 3: leal (,%eax,1),%eax + 4: leal 0x00(,%eax,1),%eax + 6: leal 0x00000000(%eax),%eax + 7: leal 0x00000000(,%eax,1),%eax +*/ +#define K7_NOP1 GENERIC_NOP1 #define K7_NOP2 ".byte 0x8b,0xc0\n" #define K7_NOP3 ".byte 0x8d,0x04,0x20\n" #define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" #define K7_NOP5 K7_NOP4 ASM_NOP1 #define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" -#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" -#define K7_NOP8 K7_NOP7 ASM_NOP1 +#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" +#define K7_NOP8 K7_NOP7 ASM_NOP1 -/* P6 nops */ -/* uses eax dependencies (Intel-recommended choice) */ +/* P6 nops + uses eax dependencies (Intel-recommended choice) + 1: nop + 2: osp nop + 3: nopl (%eax) + 4: nopl 0x00(%eax) + 5: nopl 0x00(%eax,%eax,1) + 6: osp nopl 0x00(%eax,%eax,1) + 7: nopl 0x00000000(%eax) + 8: nopl 0x00000000(%eax,%eax,1) +*/ #define P6_NOP1 GENERIC_NOP1 #define P6_NOP2 ".byte 0x66,0x90\n" #define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" From 829157be590af1c2555fb74c3c4db3327e3201fc Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 13 Feb 2008 11:16:46 -0800 Subject: [PATCH 742/880] x86: handle BIOSes which terminate e820 with CF=1 and no SMAP The proper way to terminate the e820 chain is with %ebx == 0 on the last legitimate memory block. However, several BIOSes don't do that and instead return error (CF = 1) when trying to read off the end of the list. For this error return, %eax doesn't necessarily return the SMAP signature -- correctly so, since %ah should contain an error code in this case. To deal with some particularly broken BIOSes, we clear the entire e820 chain if the SMAP signature is missing in the middle, indicating a plain insane e820 implementation. However, we need to make the test for CF = 1 before the SMAP check. This fixes at least one HP laptop (nc6400) for which none of the memory-probing methods (e820, e801, 88) functioned fully according to spec. Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/boot/memory.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c index 378353956b5d..e77d89f9e8aa 100644 --- a/arch/x86/boot/memory.c +++ b/arch/x86/boot/memory.c @@ -37,6 +37,12 @@ static int detect_memory_e820(void) "=m" (*desc) : "D" (desc), "d" (SMAP), "a" (0xe820)); + /* BIOSes which terminate the chain with CF = 1 as opposed + to %ebx = 0 don't always report the SMAP signature on + the final, failing, probe. */ + if (err) + break; + /* Some BIOSes stop returning SMAP in the middle of the search loop. We don't know exactly how the BIOS screwed up the map at that point, we might have a @@ -47,9 +53,6 @@ static int detect_memory_e820(void) break; } - if (err) - break; - count++; desc++; } while (next && count < E820MAX); From f5106d91f2bf9153d6420f9ebb8114f73f9ce66a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 18 Feb 2008 13:10:44 -0800 Subject: [PATCH 743/880] x86/mtrr: fix kernel-doc missing notation Fix mtrr kernel-doc warning: Warning(linux-2.6.24-git12//arch/x86/kernel/cpu/mtrr/main.c:677): No description found for parameter 'end_pfn' Signed-off-by: Randy Dunlap Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/mtrr/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index b6e136f23d3d..c8fda3eb3d7e 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -649,6 +649,7 @@ static __init int amd_special_default_mtrr(void) /** * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs + * @end_pfn: ending page frame number * * Some buggy BIOSes don't setup the MTRRs properly for systems with certain * memory configurations. This routine checks that the highest MTRR matches From 7265b6f10deba1cbe071cee646b063bda07ecd68 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 19 Feb 2008 11:02:30 +0100 Subject: [PATCH 744/880] x86: notsc is ignored on common configurations notsc is ignored in 32-bit kernels if CONFIG_X86_TSC is on.. which is bad, fix it. Signed-off-by: Pavel Machek Signed-off-by: Ingo Molnar --- arch/x86/kernel/tsc_32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index 43517e324be8..f14cfd9d1f94 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c @@ -28,7 +28,8 @@ EXPORT_SYMBOL_GPL(tsc_khz); static int __init tsc_setup(char *str) { printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " - "cannot disable TSC.\n"); + "cannot disable TSC completely.\n"); + mark_tsc_unstable("user disabled TSC"); return 1; } #else From 3b57bc461fd5019aef4cfc77d4faf56ebe95449c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 20 Feb 2008 18:53:17 -0800 Subject: [PATCH 745/880] x86: remove double-checking empty zero pages debug so far no one complained about that. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/mm/init_64.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index bb652f5a93fb..6dbb0035c57a 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -515,14 +515,6 @@ void __init mem_init(void) /* clear_bss() already clear the empty_zero_page */ - /* temporary debugging - double check it's true: */ - { - int i; - - for (i = 0; i < 1024; i++) - WARN_ON_ONCE(empty_zero_page[i]); - } - reservedpages = 0; /* this will put all low memory onto the freelists */ From 88f3aec7afd9ae3e6f6d221801996b69aad1e3a4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 21 Feb 2008 11:04:11 +0100 Subject: [PATCH 746/880] x86: fix spontaneous reboot with allyesconfig bzImage recently the 64-bit allyesconfig bzImage kernel started spontaneously rebooting during early bootup. after a few fun hours spent with early init debugging, it turns out that we've got this rather annoying limit on the size of the kernel image: #define KERNEL_TEXT_SIZE (40*1024*1024) which limit my vmlinux just happened to pass: text data bss dec hex filename 29703744 4222751 8646224 42572719 2899baf vmlinux 40 MB is 42572719 bytes, so my vmlinux was just 1.5% above this limit :-/ So it happily crashed right in head_64.S, which - as we all know - is the most debuggable code in the whole architecture ;-) So increase the limit to allow an up to 128MB kernel image to be mapped. (should anyone be that crazy or lazy) We have a full 4K of pagetable (level2_kernel_pgt) allocated for these mappings already, so there's no RAM overhead and the limit was rather pointless and arbitrary. Signed-off-by: Ingo Molnar --- arch/x86/kernel/head_64.S | 22 ++++++++++++++-------- arch/x86/mm/init_64.c | 5 +++-- include/asm-x86/page_64.h | 8 ++++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index eb415043a929..b037b15be7f8 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -379,18 +379,24 @@ NEXT_PAGE(level2_ident_pgt) /* Since I easily can, map the first 1G. * Don't set NX because code runs from these pages. */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) + PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) NEXT_PAGE(level2_kernel_pgt) - /* 40MB kernel mapping. The kernel code cannot be bigger than that. - When you change this change KERNEL_TEXT_SIZE in page.h too. */ - /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE) - /* Module mapping starts here */ - .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0 + /* + * 128 MB kernel mapping. We spend a full page on this pagetable + * anyway. + * + * The kernel code+data+bss must not be bigger than that. + * + * (NOTE: at +128MB starts the module area, see MODULES_VADDR. + * If you want to increase this then increase MODULES_VADDR + * too.) + */ + PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, + KERNEL_TEXT_SIZE/PMD_SIZE) NEXT_PAGE(level2_spare_pgt) - .fill 512,8,0 + .fill 512, 8, 0 #undef PMDS #undef NEXT_PAGE diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 6dbb0035c57a..a02a14f0f324 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -172,8 +172,9 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) } /* - * The head.S code sets up the kernel high mapping from: - * __START_KERNEL_map to __START_KERNEL_map + KERNEL_TEXT_SIZE + * The head.S code sets up the kernel high mapping: + * + * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text) * * phys_addr holds the negative offset to the kernel, which is added * to the compile time generated pmds. This results in invalid pmds up diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index f7393bc516ef..3e2e3ca63048 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -47,8 +47,12 @@ #define __PHYSICAL_MASK_SHIFT 46 #define __VIRTUAL_MASK_SHIFT 48 -#define KERNEL_TEXT_SIZE (40*1024*1024) -#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) +/* + * Kernel image size is limited to 128 MB (see level2_kernel_pgt in + * arch/x86/kernel/head_64.S), and it is mapped here: + */ +#define KERNEL_TEXT_SIZE (128*1024*1024) +#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) #ifndef __ASSEMBLY__ void clear_page(void *page); From d4afe414189b098d56bcd24280c018aa2ac9a990 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 21 Feb 2008 13:39:30 +0100 Subject: [PATCH 747/880] x86: rename KERNEL_TEXT_SIZE => KERNEL_IMAGE_SIZE The KERNEL_TEXT_SIZE constant was mis-named, as we not only map the kernel text but data, bss and init sections as well. That name led me on the wrong path with the KERNEL_TEXT_SIZE regression, because i knew how big of _text_ my images have and i knew about the 40 MB "text" limit so i wrongly thought to be on the safe side of the 40 MB limit with my 29 MB of text, while the total image size was slightly above 40 MB. Signed-off-by: Ingo Molnar --- arch/x86/kernel/head_64.S | 2 +- include/asm-x86/page_64.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index b037b15be7f8..a007454133a3 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -393,7 +393,7 @@ NEXT_PAGE(level2_kernel_pgt) * too.) */ PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, - KERNEL_TEXT_SIZE/PMD_SIZE) + KERNEL_IMAGE_SIZE/PMD_SIZE) NEXT_PAGE(level2_spare_pgt) .fill 512, 8, 0 diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index 3e2e3ca63048..143546073b95 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -51,8 +51,8 @@ * Kernel image size is limited to 128 MB (see level2_kernel_pgt in * arch/x86/kernel/head_64.S), and it is mapped here: */ -#define KERNEL_TEXT_SIZE (128*1024*1024) -#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) +#define KERNEL_IMAGE_SIZE (128*1024*1024) +#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) #ifndef __ASSEMBLY__ void clear_page(void *page); From ce28b9864b853803320c3f1d8de1b81aa4120b14 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 20 Feb 2008 23:57:30 +0100 Subject: [PATCH 748/880] x86: fix vsyscall wreckage based on a report from Arne Georg Gleditsch about user-space apps misbehaving after toggling /proc/sys/kernel/vsyscall64, a review of the code revealed that the "NOP patching" done there is fundamentally unsafe for a number of reasons: 1) the patching code runs without synchronizing other CPUs 2) it inserts NOPs even if there is no clock source which provides vread 3) when the clock source changes to one without vread we run in exactly the same problem as in #2 4) if nobody toggles the proc entry from 1 to 0 and to 1 again, then the syscall is not patched out as a result it is possible to break user-space via this patching. The only safe thing for now is to remove the patching. This code was broken since v2.6.21. Reported-by: Arne Georg Gleditsch Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/kernel/vsyscall_64.c | 52 ++--------------------------------- 1 file changed, 3 insertions(+), 49 deletions(-) diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 3f8242774580..b6be812fac05 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -44,11 +44,6 @@ #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) #define __syscall_clobber "r11","cx","memory" -#define __pa_vsymbol(x) \ - ({unsigned long v; \ - extern char __vsyscall_0; \ - asm("" : "=r" (v) : "0" (x)); \ - ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); }) /* * vsyscall_gtod_data contains data that is : @@ -102,7 +97,7 @@ static __always_inline void do_get_tz(struct timezone * tz) static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz) { int ret; - asm volatile("vsysc2: syscall" + asm volatile("syscall" : "=a" (ret) : "0" (__NR_gettimeofday),"D" (tv),"S" (tz) : __syscall_clobber ); @@ -112,7 +107,7 @@ static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz) static __always_inline long time_syscall(long *t) { long secs; - asm volatile("vsysc1: syscall" + asm volatile("syscall" : "=a" (secs) : "0" (__NR_time),"D" (t) : __syscall_clobber); return secs; @@ -227,50 +222,10 @@ long __vsyscall(3) venosys_1(void) } #ifdef CONFIG_SYSCTL - -#define SYSCALL 0x050f -#define NOP2 0x9090 - -/* - * NOP out syscall in vsyscall page when not needed. - */ -static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - extern u16 vsysc1, vsysc2; - u16 __iomem *map1; - u16 __iomem *map2; - int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); - if (!write) - return ret; - /* gcc has some trouble with __va(__pa()), so just do it this - way. */ - map1 = ioremap(__pa_vsymbol(&vsysc1), 2); - if (!map1) - return -ENOMEM; - map2 = ioremap(__pa_vsymbol(&vsysc2), 2); - if (!map2) { - ret = -ENOMEM; - goto out; - } - if (!vsyscall_gtod_data.sysctl_enabled) { - writew(SYSCALL, map1); - writew(SYSCALL, map2); - } else { - writew(NOP2, map1); - writew(NOP2, map2); - } - iounmap(map2); -out: - iounmap(map1); - return ret; -} - static ctl_table kernel_table2[] = { { .procname = "vsyscall64", .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = vsyscall_sysctl_change }, + .mode = 0644 }, {} }; @@ -279,7 +234,6 @@ static ctl_table kernel_root_table2[] = { .child = kernel_table2 }, {} }; - #endif /* Assume __initcall executes before all user space. Hopefully kmod From 5d119b2c9a490e2d647eae134211b32a18a04c7d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 26 Feb 2008 12:55:57 +0100 Subject: [PATCH 749/880] x86: fix execve with -fstack-protect pointed out by pageexec@freemail.hu: > what happens here is that gcc treats the argument area as owned by the > callee, not the caller and is allowed to do certain tricks. for ssp it > will make a copy of the struct passed by value into the local variable > area and pass *its* address down, and it won't copy it back into the > original instance stored in the argument area. > > so once sys_execve returns, the pt_regs passed by value hasn't at all > changed and its default content will cause a nice double fault (FWIW, > this part took me the longest to debug, being down with cold didn't > help it either ;). To fix this we pass in pt_regs by pointer. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/entry_64.S | 6 ++++-- arch/x86/kernel/process_64.c | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 2ad9a1bc6a73..c20c9e7e08dd 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -453,6 +453,7 @@ ENTRY(stub_execve) CFI_REGISTER rip, r11 SAVE_REST FIXUP_TOP_OF_STACK %r11 + movq %rsp, %rcx call sys_execve RESTORE_TOP_OF_STACK %r11 movq %rax,RAX(%rsp) @@ -1036,15 +1037,16 @@ ENDPROC(child_rip) * rdi: name, rsi: argv, rdx: envp * * We want to fallback into: - * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs) + * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs) * * do_sys_execve asm fallback arguments: - * rdi: name, rsi: argv, rdx: envp, fake frame on the stack + * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack */ ENTRY(kernel_execve) CFI_STARTPROC FAKE_STACK_FRAME $0 SAVE_ALL + movq %rsp,%rcx call sys_execve movq %rax, RAX(%rsp) RESTORE_REST diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index b0cc8f0136d8..43f287744f9f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -730,16 +730,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ asmlinkage long sys_execve(char __user *name, char __user * __user *argv, - char __user * __user *envp, struct pt_regs regs) + char __user * __user *envp, struct pt_regs *regs) { long error; char * filename; filename = getname(name); error = PTR_ERR(filename); - if (IS_ERR(filename)) + if (IS_ERR(filename)) return error; - error = do_execve(filename, argv, envp, ®s); + error = do_execve(filename, argv, envp, regs); putname(filename); return error; } From 4147c8747eace9058c606b35e700060297edaf91 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Thu, 21 Feb 2008 15:50:14 +0100 Subject: [PATCH 750/880] x86: don't print a warning when MTRR are blank and running in KVM Inside a KVM virtual machine the MTRRs are usually blank. This confuses Linux and causes a warning message at boot. This patch removes that warning message when running Linux as a KVM guest. Signed-off-by: Joerg Roedel Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/mtrr/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index c8fda3eb3d7e..be83336fddba 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "mtrr.h" u32 num_var_ranges = 0; @@ -689,8 +690,11 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) /* kvm/qemu doesn't have mtrr set right, don't trim them all */ if (!highest_pfn) { - printk(KERN_WARNING "WARNING: strange, CPU MTRRs all blank?\n"); - WARN_ON(1); + if (!kvm_para_available()) { + printk(KERN_WARNING + "WARNING: strange, CPU MTRRs all blank?\n"); + WARN_ON(1); + } return 0; } From ed2b7e2b1d1ae201afe8fbd111632074b7b53ed4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 22 Feb 2008 21:58:37 +0200 Subject: [PATCH 751/880] x86: don't make swapper_pg_pmd global There doesn't seem to be any reason for swapper_pg_pmd being global. Signed-off-by: Adrian Bunk Signed-off-by: Ingo Molnar --- arch/x86/kernel/head_32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 25eb98540a41..fd8ca53943a8 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -606,7 +606,7 @@ ENTRY(_stext) .section ".bss.page_aligned","wa" .align PAGE_SIZE_asm #ifdef CONFIG_X86_PAE -ENTRY(swapper_pg_pmd) +swapper_pg_pmd: .fill 1024*KPMDS,4,0 #else ENTRY(swapper_pg_dir) From 1650743cdc0db73478f72c57544ce79ea8f3dda6 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 22 Feb 2008 19:23:58 +0100 Subject: [PATCH 752/880] x86: don't save unreliable stack trace entries Currently, there is no way for print_stack_trace() to determine whether a given stack trace entry was deemed reliable or not, simply because save_stack_trace() does not record this information. (Perhaps needless to say, this makes the saved stack traces A LOT harder to read, and probably with no other benefits, since debugging features that use save_stack_trace() most likely also require frame pointers, etc.) This patch reverts to the old behaviour of only recording the reliable trace entries for saved stack traces. Signed-off-by: Vegard Nossum Acked-by: Arjan van de Ven Signed-off-by: Ingo Molnar --- arch/x86/kernel/stacktrace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index 02f0f61f5b11..c28c342c162f 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -25,6 +25,8 @@ static int save_stack_stack(void *data, char *name) static void save_stack_address(void *data, unsigned long addr, int reliable) { struct stack_trace *trace = data; + if (!reliable) + return; if (trace->skip > 0) { trace->skip--; return; @@ -37,6 +39,8 @@ static void save_stack_address_nosched(void *data, unsigned long addr, int reliable) { struct stack_trace *trace = (struct stack_trace *)data; + if (!reliable) + return; if (in_sched_functions(addr)) return; if (trace->skip > 0) { From 2b775a27c0d9fdf8078d5b31e1e27411e5bf2a91 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Fri, 22 Feb 2008 12:09:29 -0300 Subject: [PATCH 753/880] x86: make c_idle.work have a static address. Currently, c_idle is declared in the stack, and thus, have no static address. Peter Zijlstra points out this simple solution, in which c_idle.work is initializated separatedly. Note that the INIT_WORK macro has a static declaration of a key inside. Signed-off-by: Glauber Costa Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/x86/kernel/smpboot_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index d53bd6fcb428..0880f2c388a9 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -554,10 +554,10 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) int timeout; unsigned long start_rip; struct create_idle c_idle = { - .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), }; + INIT_WORK(&c_idle.work, do_fork_idle); /* allocate memory for gdts of secondary cpus. Hotplug is considered */ if (!cpu_gdt_descr[cpu].address && From 03994f01e8b72b3d01fd3d09d1cc7c9f421a727c Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sun, 24 Feb 2008 18:36:05 +0200 Subject: [PATCH 754/880] x86: fix build on non-C locales. For some locales regex range [a-zA-Z] does not work as it is supposed to. so we have to use [:alnum:] and [:xdigit:] to make it work as intended. [1] http://en.wikipedia.org/wiki/Estonian_alphabet Signed-off-by: Ingo Molnar --- arch/x86/vdso/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index f385a4b4a484..b8bd0c4aa02e 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -48,7 +48,7 @@ obj-$(VDSO64-y) += vdso-syms.lds # Match symbols in the DSO that look like VDSO*; produce a file of constants. # sed-vdsosym := -e 's/^00*/0/' \ - -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' + -e 's/^\([[:xdigit:]]*\) . \(VDSO[[:alnum:]_]*\)$$/\2 = 0x\1;/p' quiet_cmd_vdsosym = VDSOSYM $@ cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ From 12c247a6719987aad65f83158d2bb3e73c75c1f5 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sun, 24 Feb 2008 18:27:03 +0100 Subject: [PATCH 755/880] x86: fix boot failure on 486 due to TSC breakage > Diffing dmesg between git7 and git8 doesn't sched any light since > git8 also removed the printouts of the x86 caps as they were being > initialised and updated. I'm currently adding those printouts back > in the hope of seeing where and when the caps get broken. That turned out to be very illuminating: --- dmesg-2.6.24-git7 2008-02-24 18:01:25.295851000 +0100 +++ dmesg-2.6.24-git8 2008-02-24 18:01:25.530358000 +0100 ... CPU: After generic identify, caps: 00000003 00000000 00000000 00000000 00000000 00000000 00000000 00000000 CPU: After all inits, caps: 00000003 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +CPU: After applying cleared_cpu_caps, caps: 00000013 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Notice how the TSC cap bit goes from Off to On. (The first two lines are printout loops from -git7 forward-ported to -git8, the third line is the same printout loop added just after the xor-with-cleared_cpu_caps[] loop.) Here's how the breakage occurs: 1. arch/x86/kernel/tsc_32.c:tsc_init() sees !cpu_has_tsc, so bails and calls setup_clear_cpu_cap(X86_FEATURE_TSC). 2. include/asm-x86/cpufeature.h:setup_clear_cpu_cap(bit) clears the bit in boot_cpu_data and sets it in cleared_cpu_caps 3. arch/x86/kernel/cpu/common.c:identify_cpu() XORs all caps in with cleared_cpu_caps HOWEVER, at this point c->x86_capability correctly has TSC Off, cleared_cpu_caps has TSC On, so the XOR incorrectly sets TSC to On in c->x86_capability, with disastrous results. The real bug is that clearing bits with XOR only works if the bits are known to be 1 prior to the XOR, and that's not true here. A simple fix is to convert the XOR to AND-NOT instead. The following patch does that, and allows my 486 to boot 2.6.25-rc kernels again. [ mingo@elte.hu: fixed a similar bug in setup_64.c as well. ] The breakage was introduced via commit 7d851c8d3db0. Signed-off-by: Mikael Pettersson Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/setup_64.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f86a3c4a2669..a38aafaefc23 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -504,7 +504,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) /* Clear all flags overriden by options */ for (i = 0; i < NCAPINTS; i++) - c->x86_capability[i] ^= cleared_cpu_caps[i]; + c->x86_capability[i] &= ~cleared_cpu_caps[i]; /* Init Machine Check Exception if available. */ mcheck_init(c); diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 6fd804f07821..7637dc91c79b 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -1021,7 +1021,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) /* Clear all flags overriden by options */ for (i = 0; i < NCAPINTS; i++) - c->x86_capability[i] ^= cleared_cpu_caps[i]; + c->x86_capability[i] &= ~cleared_cpu_caps[i]; #ifdef CONFIG_X86_MCE mcheck_init(c); From f18edc95a37a901ffcbe91f5e05105f916a04fae Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 16 Feb 2008 14:05:01 +0100 Subject: [PATCH 756/880] x86: no robust/pi futex for real i386 CPUs Real i386 CPUs do not have cmpxchg instructions. Catch it before crashing on an invalid opcode. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/futex.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h index cd9f894dd2d7..c9952ea9f698 100644 --- a/include/asm-x86/futex.h +++ b/include/asm-x86/futex.h @@ -102,6 +102,13 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) { + +#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP) + /* Real i386 machines have no cmpxchg instruction */ + if (boot_cpu_data.x86 == 3) + return -ENOSYS; +#endif + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; From cf3680b90c7842cf91ed857ac4528f4e057da366 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 14 Feb 2008 10:32:07 +0900 Subject: [PATCH 757/880] printk: fix possible printk overrun printk recursion detection prepends message to printk_buf and offsets printk_buf when actual message is printed but it forgets to trim buffer length accordingly. This can result in overrun in extreme cases. Fix it. [ mingo@elte.hu: bug was introduced by me via: commit 32a76006683f7b28ae3cc491da37716e002f198e Author: Ingo Molnar Date: Fri Jan 25 21:07:58 2008 +0100 printk: make printk more robust by not allowing recursion ] Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk.c b/kernel/printk.c index bee36100f110..9adc2a473e6e 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -666,7 +666,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) } /* Emit the output into the temporary buffer */ printed_len += vscnprintf(printk_buf + printed_len, - sizeof(printk_buf), fmt, args); + sizeof(printk_buf) - printed_len, fmt, args); /* * Copy the output into log_buf. If the caller didn't provide From acbe44e6274e88a14a68df511d87890846a9bc99 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 26 Feb 2008 21:50:32 +0100 Subject: [PATCH 758/880] ide-cd: Enable audio play quirk for Optiarc DVD RW AD-5200A drive Reported-by: Stefan Bader Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 310e497b5838..022a029f81c2 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1931,6 +1931,7 @@ static const struct cd_list_entry ide_cd_quirks_list[] = { { "MATSHITADVD-ROM SR-8186", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { "MATSHITADVD-ROM SR-8176", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { "MATSHITADVD-ROM SR-8174", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, + { "Optiarc DVD RW AD-5200A", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { NULL, NULL, 0 } }; From b66cae7672996c1ed0c4c4a4df04ce7b275c61f6 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 26 Feb 2008 21:50:33 +0100 Subject: [PATCH 759/880] hpt366: fix section mismatch warnings hpt366: fix section mismatch warnings Fix following warnings: WARNING: o-sparc64/vmlinux.o(.data+0x195a38): Section mismatch in reference from the variable hpt37x_info.0 to the variable .devinit.data:hpt370 WARNING: o-sparc64/vmlinux.o(.data+0x195a40): Section mismatch in reference from the variable hpt37x_info.0 to the variable .devinit.data:hpt370a WARNING: o-sparc64/vmlinux.o(.data+0x195a48): Section mismatch in reference from the variable hpt37x_info.0 to the variable .devinit.data:hpt372 WARNING: o-sparc64/vmlinux.o(.data+0x195a50): Section mismatch in reference from the variable hpt37x_info.0 to the variable .devinit.data:hpt372n Replace a static array with a small switch resulting in more readable code. Mark the pci table __devinitconst. A lot of variables are const but annotated __devinitdata. Annotating them __devinitconst would cause a section type conflict error when build for 64 bit powerpc. Signed-off-by: Sam Ravnborg Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/hpt366.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index d0f7bb8b8adf..6357bb6269ab 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1570,10 +1570,12 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic if (rev < 3) info = &hpt36x; else { - static const struct hpt_info *hpt37x_info[] = - { &hpt370, &hpt370a, &hpt372, &hpt372n }; - - info = hpt37x_info[min_t(u8, rev, 6) - 3]; + switch (min_t(u8, rev, 6)) { + case 3: info = &hpt370; break; + case 4: info = &hpt370a; break; + case 5: info = &hpt372; break; + case 6: info = &hpt372n; break; + } idx++; } break; @@ -1626,7 +1628,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic return ide_setup_pci_device(dev, &d); } -static const struct pci_device_id hpt366_pci_tbl[] = { +static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), 0 }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), 1 }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), 2 }, From cbd34d00af2960097ebd46a31dabc8bb9f16ea4e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:33 +0100 Subject: [PATCH 760/880] ide: remove redundant comment from ide_unregister() Identical comment is present in ide_hwif_release_regions() documentation. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 477833f0daf5..784d60e376ee 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -590,11 +590,6 @@ void ide_unregister(unsigned int index, int init_default, int restore) hwif->extra_ports = 0; } - /* - * Note that we only release the standard ports, - * and do not even try to handle any extra ports - * allocated for weird IDE interface chipsets. - */ ide_hwif_release_regions(hwif); /* copy original settings */ From c53ea18dc29a1ac075119f651d6ac4386a549a34 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:34 +0100 Subject: [PATCH 761/880] ide: skip probing port if "hdx=noprobe" was used for both devices on it * Skip probing port if "hdx=noprobe" parameter was used for both devices on it. * Obsolete "idex=noprobe" parameter - it only works for ide_generic, cmd640 and PCI hosts in Compatibility mode (on alpha/x86/ia64/m32r/mips/ppc32). Signed-off-by: Bartlomiej Zolnierkiewicz --- Documentation/ide.txt | 2 -- drivers/ide/ide-probe.c | 3 ++- drivers/ide/ide.c | 2 +- drivers/ide/pci/cmd640.c | 3 ++- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/ide.txt b/Documentation/ide.txt index 94e2e3b9e77f..7b782e84001f 100644 --- a/Documentation/ide.txt +++ b/Documentation/ide.txt @@ -258,8 +258,6 @@ Summary of ide driver parameters for kernel command line As for VLB, it is safest to not specify it. Bigger values are safer than smaller ones. - "idex=noprobe" : do not attempt to access/use this interface - "idex=base" : probe for an interface at the addr specified, where "base" is usually 0x1f0 or 0x170 and "ctl" is assumed to be "base"+0x206 diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 4a2cb2868226..194ecb0049eb 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -756,7 +756,8 @@ static int ide_probe_port(ide_hwif_t *hwif) BUG_ON(hwif->present); - if (hwif->noprobe) + if (hwif->noprobe || + (hwif->drives[0].noprobe && hwif->drives[1].noprobe)) return -EACCES; /* diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 784d60e376ee..300536697622 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1444,7 +1444,7 @@ static int __init ide_setup(char *s) case -1: /* "noprobe" */ hwif->noprobe = 1; - goto done; + goto obsolete_option; case 1: /* base */ vals[1] = vals[0] + 0x206; /* default ctl */ diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index bd24dad3cfc6..ec667982809c 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -787,7 +787,8 @@ static int __init cmd640x_init(void) /* * Try to enable the secondary interface, if not already enabled */ - if (cmd_hwif1->noprobe) { + if (cmd_hwif1->noprobe || + (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe)) { port2 = "not probed"; } else { b = get_cmd640_reg(CNTRL); From 788d669736dd3d15195fea07bf97ec5a2e9f15e7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:35 +0100 Subject: [PATCH 762/880] qd65xx: fix setup of QD6580 Control register Control register of QD6580 should be setup before probing for devices. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/qd65xx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index bba29df5f21d..1ec0e970f577 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -444,6 +444,8 @@ static int __init qd_probe(int base) printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n", config, control, QD_ID3); + outb(QD_DEF_CONTR, QD_CONTROL_PORT); + if (control & QD_CONTR_SEC_DISABLED) { /* secondary disabled */ @@ -460,8 +462,6 @@ static int __init qd_probe(int base) ide_device_add(idx, &qd65xx_port_info); - outb(QD_DEF_CONTR, QD_CONTROL_PORT); - return 1; } else { ide_hwif_t *mate; @@ -487,8 +487,6 @@ static int __init qd_probe(int base) ide_device_add(idx, &qd65xx_port_info); - outb(QD_DEF_CONTR, QD_CONTROL_PORT); - return 0; /* no other qd65xx possible */ } } From 9f10d9ee0ac6d79d7bc8b9a158bf4a29322d84d3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:35 +0100 Subject: [PATCH 763/880] ide-cd: fix 'ireason' handling for REQ_TYPE_ATA_PC requests Pass 'struct request *rq' to ide_cd_check_ireason() from cdrom_newpc_intr() and use ide_cd_check_ireason() also for REQ_TYPE_ATA_PC requests. This fixes some hangs caused by not finishing the transfer before ending the request and also makes use of 'ireason == 1' quirk for spurious IRQs. Tested-by: Brad Rosser Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 022a029f81c2..1495fe7a6ecf 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -670,8 +670,8 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector, * and attempt to recover if there are problems. Returns 0 if everything's * ok; nonzero if the request has been terminated. */ -static -int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) +static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, + int len, int ireason, int rw) { /* * ireason == 0: the drive wants to receive data from us @@ -701,6 +701,9 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) drive->name, __FUNCTION__, ireason); } + if (rq->cmd_type == REQ_TYPE_ATA_PC) + rq->cmd_flags |= REQ_FAILED; + cdrom_end_request(drive, 0); return -1; } @@ -1071,11 +1074,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) /* * check which way to transfer data */ - if (blk_fs_request(rq) || blk_pc_request(rq)) { - if (ide_cd_check_ireason(drive, len, ireason, write)) - return ide_stopped; + if (ide_cd_check_ireason(drive, rq, len, ireason, write)) + return ide_stopped; - if (blk_fs_request(rq) && write == 0) { + if (blk_fs_request(rq)) { + if (write == 0) { int nskip; if (ide_cd_check_transfer_size(drive, len)) { @@ -1101,16 +1104,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (ireason == 0) { write = 1; xferfunc = HWIF(drive)->atapi_output_bytes; - } else if (ireason == 2 || (ireason == 1 && - (blk_fs_request(rq) || blk_pc_request(rq)))) { + } else { write = 0; xferfunc = HWIF(drive)->atapi_input_bytes; - } else { - printk(KERN_ERR "%s: %s: The drive " - "appears confused (ireason = 0x%02x). " - "Trying to recover by ending request.\n", - drive->name, __FUNCTION__, ireason); - goto end_request; } /* From bcd88ac3b2ff2eae3d0fa57a6b02d4fce5392f32 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 26 Feb 2008 21:50:35 +0100 Subject: [PATCH 764/880] ide-cd: fix CD/DVD burning Move counting of sense bytes into the transfer loop. Signed-off-by: Andreas Schwab Acked-by: Borislav Petkov Cc: Kiyoshi Ueda Cc: Jens Axboe Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 1495fe7a6ecf..c8d0e8715997 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1178,11 +1178,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) else rq->data += blen; } + if (!write && blk_sense_request(rq)) + rq->sense_len += blen; } - if (write && blk_sense_request(rq)) - rq->sense_len += thislen; - /* * pad, if necessary */ From dbecebca1914f414008553b57aefde95b70f9142 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:35 +0100 Subject: [PATCH 765/880] ide: fix sparse warning about shadowing 'flags' symbol drivers/ide/ide.c:801:18: warning: symbol 'flags' shadows an earlier one drivers/ide/ide.c:732:16: originally declared here Also fix some whitespace damage while at it. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 300536697622..fa16bc30bbc9 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1031,10 +1031,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device drive->nice1 = (arg >> IDE_NICE_1) & 1; return 0; case HDIO_DRIVE_RESET: - { - unsigned long flags; - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + /* * Abort the current command on the * group if there is one, taking @@ -1053,17 +1052,15 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device ide_abort(drive, "drive reset"); BUG_ON(HWGROUP(drive)->handler); - + /* Ensure nothing gets queued after we drop the lock. Reset will clear the busy */ - + HWGROUP(drive)->busy = 1; spin_unlock_irqrestore(&ide_lock, flags); (void) ide_do_reset(drive); return 0; - } - case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; From d12faa2736ebdee025a9aa07b2683c5fa8c86553 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:36 +0100 Subject: [PATCH 766/880] ide-disk: add missing printk() KERN_* levels Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-disk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 8f5bed471050..39501d130256 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -867,7 +867,7 @@ static void idedisk_setup (ide_drive_t *drive) /* Only print cache size when it was specified */ if (id->buf_size) - printk (" w/%dKiB Cache", id->buf_size/2); + printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2); printk(KERN_CONT ", CHS=%d/%d/%d\n", drive->bios_cyl, drive->bios_head, drive->bios_sect); @@ -949,7 +949,8 @@ static void ide_device_shutdown(ide_drive_t *drive) return; } - printk("Shutdown: %s\n", drive->name); + printk(KERN_INFO "Shutdown: %s\n", drive->name); + drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); } From d48567dd43868b3d2e1fcc33ee76dc2d38a1ddeb Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 26 Feb 2008 21:50:36 +0100 Subject: [PATCH 767/880] ide-tape: schedule driver for removal after 6 months Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- Documentation/feature-removal-schedule.txt | 10 ++++++++++ drivers/ide/ide-tape.c | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 4d3aa519eadf..ba899ff2a8f9 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -172,6 +172,16 @@ Who: Len Brown --------------------------- +What: ide-tape driver +When: July 2008 +Files: drivers/ide/ide-tape.c +Why: This driver might not have any users anymore and maintaining it for no + reason is an effort no one wants to make. +Who: Bartlomiej Zolnierkiewicz , Borislav Petkov + + +--------------------------- + What: libata spindown skipping and warning When: Dec 2008 Why: Some halt(8) implementations synchronize caches for and spin diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0598ecfd5f37..43e0e0557776 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -3765,6 +3765,11 @@ static int ide_tape_probe(ide_drive_t *drive) g->fops = &idetape_block_ops; ide_register_region(g); + printk(KERN_WARNING "It is possible that this driver does not have any" + " users anymore and, as a result, it will be REMOVED soon." + " Please notify Bart or Boris" + " in case you still need it.\n"); + return 0; out_free_tape: From fcac6f87a5642ab16fe3deab11e57252dacf4d55 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:36 +0100 Subject: [PATCH 768/880] qd65xx: remove commented out code Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/qd65xx.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 1ec0e970f577..2f4f47ad602f 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -334,43 +334,6 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif) hwif->drives[1].drive_data = t2; } -/* - * qd_unsetup: - * - * called to unsetup an ata channel : back to default values, unlinks tuning - */ -/* -static void __exit qd_unsetup(ide_hwif_t *hwif) -{ - u8 config = hwif->config_data; - int base = hwif->select_data; - void *set_pio_mode = (void *)hwif->set_pio_mode; - - if (hwif->chipset != ide_qd65xx) - return; - - printk(KERN_NOTICE "%s: back to defaults\n", hwif->name); - - hwif->selectproc = NULL; - hwif->set_pio_mode = NULL; - - if (set_pio_mode == (void *)qd6500_set_pio_mode) { - // will do it for both - outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - } else if (set_pio_mode == (void *)qd6580_set_pio_mode) { - if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) { - outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1])); - } else { - outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - } - } else { - printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n"); - printk(KERN_WARNING "keeping settings !\n"); - } -} -*/ - static const struct ide_port_info qd65xx_port_info __initdata = { .chipset = ide_qd65xx, .host_flags = IDE_HFLAG_IO_32BIT | From 56467d17d205368f857e194858ea69368a1cfec2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:36 +0100 Subject: [PATCH 769/880] ide: remove ide-tape documentation from Documentation/ide.txt More complete documentation is available in Documentation/ide/ide-tape.txt. Signed-off-by: Bartlomiej Zolnierkiewicz --- Documentation/ide.txt | 47 ------------------------------------------- 1 file changed, 47 deletions(-) diff --git a/Documentation/ide.txt b/Documentation/ide.txt index 7b782e84001f..bcd7cd1278ef 100644 --- a/Documentation/ide.txt +++ b/Documentation/ide.txt @@ -305,53 +305,6 @@ Also for legacy CMD640 host driver (cmd640) you need to use "probe_vlb" kernel paremeter to enable probing for VLB version of the chipset (PCI ones are detected automatically). -================================================================================ - -IDE ATAPI streaming tape driver -------------------------------- - -This driver is a part of the Linux ide driver and works in co-operation -with linux/drivers/block/ide.c. - -The driver, in co-operation with ide.c, basically traverses the -request-list for the block device interface. The character device -interface, on the other hand, creates new requests, adds them -to the request-list of the block device, and waits for their completion. - -Pipelined operation mode is now supported on both reads and writes. - -The block device major and minor numbers are determined from the -tape's relative position in the ide interfaces, as explained in ide.c. - -The character device interface consists of the following devices: - - ht0 major 37, minor 0 first IDE tape, rewind on close. - ht1 major 37, minor 1 second IDE tape, rewind on close. - ... - nht0 major 37, minor 128 first IDE tape, no rewind on close. - nht1 major 37, minor 129 second IDE tape, no rewind on close. - ... - -Run /dev/MAKEDEV to create the above entries. - -The general magnetic tape commands compatible interface, as defined by -include/linux/mtio.h, is accessible through the character device. - -General ide driver configuration options, such as the interrupt-unmask -flag, can be configured by issuing an ioctl to the block device interface, -as any other ide device. - -Our own ide-tape ioctl's can be issued to either the block device or -the character device interface. - -Maximal throughput with minimal bus load will usually be achieved in the -following scenario: - - 1. ide-tape is operating in the pipelined operation mode. - 2. No buffering is performed by the user backup program. - - - ================================================================================ Some Terminology From 204f47c5a581630369d425b5a4afa48448c30359 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 26 Feb 2008 21:50:36 +0100 Subject: [PATCH 770/880] ide: remove stale comments from ide-dma.c (take 2) - ide-dma.c is not a separate module - ide-dma.c is not PCI specific anymore - DMA is enabled by default nowadays - link for Intel Zappa BIOS is dead etc. v2: * Some comments should be preserved. (Noticed by Mark Lord) Cc: Mark Lord Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 52 ++++--------------------------------------- 1 file changed, 4 insertions(+), 48 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index d0e7b537353e..2de99e4be5c9 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -1,9 +1,13 @@ /* + * IDE DMA support (including IDE PCI BM-DMA). + * * Copyright (C) 1995-1998 Mark Lord * Copyright (C) 1999-2000 Andre Hedrick * Copyright (C) 2004, 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public License + * + * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). */ /* @@ -11,49 +15,6 @@ */ /* - * This module provides support for the bus-master IDE DMA functions - * of various PCI chipsets, including the Intel PIIX (i82371FB for - * the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and - * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset) - * ("PIIX" stands for "PCI ISA IDE Xcellerator"). - * - * Pretty much the same code works for other IDE PCI bus-mastering chipsets. - * - * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). - * - * By default, DMA support is prepared for use, but is currently enabled only - * for drives which already have DMA enabled (UltraDMA or mode 2 multi/single), - * or which are recognized as "good" (see table below). Drives with only mode0 - * or mode1 (multi/single) DMA should also work with this chipset/driver - * (eg. MC2112A) but are not enabled by default. - * - * Use "hdparm -i" to view modes supported by a given drive. - * - * The hdparm-3.5 (or later) utility can be used for manually enabling/disabling - * DMA support, but must be (re-)compiled against this kernel version or later. - * - * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting. - * If problems arise, ide.c will disable DMA operation after a few retries. - * This error recovery mechanism works and has been extremely well exercised. - * - * IDE drives, depending on their vintage, may support several different modes - * of DMA operation. The boot-time modes are indicated with a "*" in - * the "hdparm -i" listing, and can be changed with *knowledgeable* use of - * the "hdparm -X" feature. There is seldom a need to do this, as drives - * normally power-up with their "best" PIO/DMA modes enabled. - * - * Testing has been done with a rather extensive number of drives, - * with Quantum & Western Digital models generally outperforming the pack, - * and Fujitsu & Conner (and some Seagate which are really Conner) drives - * showing more lackluster throughput. - * - * Keep an eye on /var/adm/messages for "DMA disabled" messages. - * - * Some people have reported trouble with Intel Zappa motherboards. - * This can be fixed by upgrading the AMI BIOS to version 1.00.04.BS0, - * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe - * (thanks to Glen Morrell for researching this). - * * Thanks to "Christopher J. Reimer" for * fixing the problem with the BIOS on some Acer motherboards. * @@ -65,11 +26,6 @@ * * Most importantly, thanks to Robert Bringman * for supplying a Promise UDMA board & WD UDMA drive for this work! - * - * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports. - * - * ATA-66/100 and recovery functions, I forgot the rest...... - * */ #include From ed0ba33d64fb933f5fd985aa8f641984efd9d658 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 21 Feb 2008 08:12:06 -0600 Subject: [PATCH 771/880] RDMA/nes: Fix a memory leak in schedule_nes_timer() Fix a memory leak spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_cm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index bd5cfeaac203..78e845c94576 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -370,11 +370,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, int ret = 0; u32 was_timer_set; + if (!cm_node) + return -EINVAL; new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); if (!new_send) return -1; - if (!cm_node) - return -EINVAL; /* new_send->timetosend = currenttime */ new_send->retrycount = NES_DEFAULT_RETRYS; From a4435febd4c0f14b25159dca249ecf91301c7c76 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 21 Feb 2008 08:13:47 -0600 Subject: [PATCH 772/880] RDMA/nes: Fix a check-after-use in nes_probe() Fix a check-after-use spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 7f8853b44ee1..b2112f5a422f 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -567,12 +567,12 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i /* Init the adapter */ nesdev->nesadapter = nes_init_adapter(nesdev, hw_rev); - nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; if (!nesdev->nesadapter) { printk(KERN_ERR PFX "Unable to initialize adapter.\n"); ret = -ENOMEM; goto bail5; } + nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; /* nesdev->base_doorbell_index = nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */ From f84fba6f969065c6622669bbaa955c26fc1461ae Mon Sep 17 00:00:00 2001 From: Glenn Streiff Date: Thu, 21 Feb 2008 08:17:54 -0600 Subject: [PATCH 773/880] RDMA/nes: Fix use-after-free in nes_create_cq() Just delete the debugging statement so we don't use cqp_request after freeing it. Adrian Bunk flagged this use-after-free issue spotted by the Coverity checker. Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_verbs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 692f0d821301..a651e9d9f0ef 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1832,9 +1832,6 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, spin_unlock_irqrestore(&nesdev->cqp.lock, flags); } } - nes_debug(NES_DBG_CQ, "iWARP CQ%u create timeout expired, major code = 0x%04X," - " minor code = 0x%04X\n", - nescq->hw_cq.cq_number, cqp_request->major_code, cqp_request->minor_code); if (!context) pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, nescq->hw_cq.cq_pbase); From a2e9c384ce76993cd68d6de57eaa81985b4618e3 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Thu, 21 Feb 2008 08:27:32 -0600 Subject: [PATCH 774/880] RDMA/nes: Fix use-after-free in mini_cm_dec_refcnt_listen() Fix use-after-free spotted by Coverity checker flagged by Adrian Bunk. Signed-off-by: Faisal Latif Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_cm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 78e845c94576..6c298aa9ab05 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -947,6 +947,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener); kfree(listener); + listener = NULL; ret = 0; cm_listens_destroyed++; } else { From 30da7cff87f0ffa169fe07b766c3d6a5f6d1f6ab Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Thu, 21 Feb 2008 08:31:22 -0600 Subject: [PATCH 775/880] RDMA/nes: Fix CRC endianness for RDMA connection establishment on big-endian With commit ef19454b ("[LIB] crc32c: Keep intermediate crc state in cpu order"), the behavior of crc32c changes on big-endian platforms. Our algorithm expects the previous behavior; otherwise we have RDMA connection establishment failure on big-endian platforms like powerpc. Apply cpu_to_le32() to value returned by crc32c() to get the previous behavior. Signed-off-by: Faisal Latif Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes.h | 15 +++++++++++++++ drivers/infiniband/hw/nes/nes_cm.c | 10 ++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index fd57e8a1582f..a48b288618ec 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -285,6 +285,21 @@ struct nes_device { }; +static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad) +{ + u32 crc_value; + crc_value = crc32c(~0, (void *)nes_quad, sizeof (struct nes_v4_quad)); + + /* + * With commit ef19454b ("[LIB] crc32c: Keep intermediate crc + * state in cpu order"), behavior of crc32c changes on + * big-endian platforms. Our algorithm expects the previous + * behavior; otherwise we have RDMA connection establishment + * issue on big-endian. + */ + return cpu_to_le32(crc_value); +} + static inline void set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value) { diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 6c298aa9ab05..39adb267fb15 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -2320,6 +2320,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct iw_cm_event cm_event; struct nes_hw_qp_wqe *wqe; struct nes_v4_quad nes_quad; + u32 crc_value; int ret; ibqp = nes_get_qp(cm_id->device, conn_param->qpn); @@ -2436,8 +2437,8 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; /* Produce hash key */ - nesqp->hte_index = cpu_to_be32( - crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); + crc_value = get_crc_value(&nes_quad); + nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n", nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask); @@ -2751,6 +2752,7 @@ void cm_event_connected(struct nes_cm_event *event) struct iw_cm_event cm_event; struct nes_hw_qp_wqe *wqe; struct nes_v4_quad nes_quad; + u32 crc_value; int ret; /* get all our handles */ @@ -2828,8 +2830,8 @@ void cm_event_connected(struct nes_cm_event *event) nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; /* Produce hash key */ - nesqp->hte_index = cpu_to_be32( - crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); + crc_value = get_crc_value(&nes_quad); + nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n", nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask); From 4b1cc7e7ca5715907d17619dcb49144db6efe1c9 Mon Sep 17 00:00:00 2001 From: John Lacombe Date: Thu, 21 Feb 2008 08:34:58 -0600 Subject: [PATCH 776/880] RDMA/nes: Fix interrupt moderation low threshold Interrupt moderation low threshold value was incorrectly triggering, indicating that the threshold should be lowered. The impact was the timer was likely to become 40usecs and get stuck there. The biggest side effect was too many interrupts and nonoptimal performance. Signed-off-by: John Lacombe Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_hw.c | 13 +++++-------- drivers/infiniband/hw/nes/nes_hw.h | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 7c4c0fbf0abd..49e53e4c1ebe 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -156,15 +156,14 @@ static void nes_nic_tune_timer(struct nes_device *nesdev) spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); - if (shared_timer->cq_count_old < cq_count) { - if (cq_count > shared_timer->threshold_low) - shared_timer->cq_direction_downward=0; - } - if (shared_timer->cq_count_old >= cq_count) + if (shared_timer->cq_count_old <= cq_count) + shared_timer->cq_direction_downward = 0; + else shared_timer->cq_direction_downward++; shared_timer->cq_count_old = cq_count; if (shared_timer->cq_direction_downward > NES_NIC_CQ_DOWNWARD_TREND) { - if (cq_count <= shared_timer->threshold_low) { + if (cq_count <= shared_timer->threshold_low && + shared_timer->threshold_low > 4) { shared_timer->threshold_low = shared_timer->threshold_low/2; shared_timer->cq_direction_downward=0; nesdev->currcq_count = 0; @@ -1728,7 +1727,6 @@ int nes_napi_isr(struct nes_device *nesdev) nesdev->int_req &= ~NES_INT_TIMER; nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); - nesadapter->tune_timer.timer_in_use_old = 0; } nesdev->deepcq_count = 0; return 1; @@ -1867,7 +1865,6 @@ void nes_dpc(unsigned long param) nesdev->int_req &= ~NES_INT_TIMER; nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); - nesdev->nesadapter->tune_timer.timer_in_use_old = 0; } else { nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); } diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 1e10df550c9e..b7e2844f096b 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -962,7 +962,7 @@ struct nes_arp_entry { #define DEFAULT_JUMBO_NES_QL_LOW 12 #define DEFAULT_JUMBO_NES_QL_TARGET 40 #define DEFAULT_JUMBO_NES_QL_HIGH 128 -#define NES_NIC_CQ_DOWNWARD_TREND 8 +#define NES_NIC_CQ_DOWNWARD_TREND 16 struct nes_hw_tune_timer { //u16 cq_count; From 030f1b2f5d880c1ad3d7e0b71fc383f00f38f8f7 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 21 Feb 2008 09:02:41 -0600 Subject: [PATCH 777/880] MAINTAINERS: neteffect update Adding Nishi to the maintainers list. Signed-off-by: Glenn Streiff Signed-off-by: Roland Dreier --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 36c7bc641dba..4fc5f0aee6a6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2744,6 +2744,8 @@ S: Maintained NETEFFECT IWARP RNIC DRIVER (IW_NES) P: Faisal Latif M: flatif@neteffect.com +P: Nishi Gupta +M: ngupta@neteffect.com P: Glenn Streiff M: gstreiff@neteffect.com L: general@lists.openfabrics.org From b2d7c7f7a69fd953626c3e507bac70e18b21f70e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 26 Feb 2008 21:42:11 +0100 Subject: [PATCH 778/880] arch/sh/drivers/dma/dma-sh.c: Correct use of ! and & In commit e6bafba5b4765a5a252f1b8d31cbf6d2459da337, a bug was fixed that involved converting !x & y to !(x & y). The code below shows the same pattern, and thus should perhaps be fixed in the same way. This is not tested and clearly changes the semantics, so it is only something to consider. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ expression E1,E2; @@ ( !E1 & !E2 | - !E1 & E2 + !(E1 & E2) ) // Signed-off-by: Julia Lawall Signed-off-by: Paul Mundt --- arch/sh/drivers/dma/dma-sh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 5c3359756a92..71ff3d6f26e2 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -90,7 +90,7 @@ static irqreturn_t dma_tei(int irq, void *dev_id) static int sh_dmac_request_dma(struct dma_channel *chan) { - if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) + if (unlikely(!(chan->flags & DMA_TEI_CAPABLE))) return 0; return request_irq(get_dmte_irq(chan->chan), dma_tei, From 622eaec613130e6ea78f2a5d5070e3278b21cd8f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Feb 2008 17:30:02 -0800 Subject: [PATCH 779/880] [SPARC64]: Loosen checks in exception table handling. Some parts of the kernel now do things like do *_user() accesses while set_fs(KERNEL_DS) that fault on purpose. See, for example, the code added by changeset a0c1e9073ef7428a14309cba010633a6cd6719ea ("futex: runtime enable pi and robust functionality"). That trips up the ASI sanity checking we make in do_kernel_fault(). Just remove it for now. Maybe we can add it back later with an added conditional which looks at the current get_fs() value. Signed-off-by: David S. Miller --- arch/sparc64/mm/fault.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index e2027f27c0fe..918363360280 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, if (regs->tstate & TSTATE_PRIV) { const struct exception_table_entry *entry; - if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) { - if (insn & 0x2000) - asi = (regs->tstate >> 24); - else - asi = (insn >> 5); - } - - /* Look in asi.h: All _S asis have LS bit set */ - if ((asi & 0x1) && - (entry = search_exception_tables(regs->tpc))) { + entry = search_exception_tables(regs->tpc); + if (entry) { regs->tpc = entry->fixup; regs->tnpc = regs->tpc + 4; return; From 3ab2273175bd59616b6e85c0f88b154e8bd97413 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 26 Feb 2008 17:42:56 -0800 Subject: [PATCH 780/880] bluetooth: delete timer in l2cap_conn_del() Delete a possibly armed timer before kfree'ing the connection object. Solves: http://lkml.org/lkml/2008/2/15/514 Reported-by:Quel Qun Signed-off-by: Thomas Gleixner Signed-off-by: David S. Miller --- net/bluetooth/l2cap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index a8811c0a0cea..7c5459c8e8ef 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -417,6 +417,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) l2cap_sock_kill(sk); } + del_timer_sync(&conn->info_timer); + hcon->l2cap_data = NULL; kfree(conn); } From 3dbf8d56a2b7e0d738950daa16682e1e6dafb28b Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 26 Feb 2008 17:52:05 -0800 Subject: [PATCH 781/880] [MACVLAN]: Update Kconfig to refer to iproute Since the macvlan release I had at least 5 users asking how to configure it since the old userspace tool doesn't work with the version in the kernel. Add a pointer to the Kconfig help. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- drivers/net/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f337800076c0..a20e72f5ad28 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -90,6 +90,11 @@ config MACVLAN This allows one to create virtual interfaces that map packets to or from specific MAC addresses to a particular interface. + Macvlan devices can be added using the "ip" command from the + iproute2 package starting with the iproute2-2.6.23 release: + + "ip link add link [ address MAC ] [ NAME ] type macvlan" + To compile this driver as a module, choose M here: the module will be called macvlan. From f1243c2db6e3b8e5a602b1be2d256b582fc78ce4 Mon Sep 17 00:00:00 2001 From: Benjamin Thery Date: Tue, 26 Feb 2008 18:10:03 -0800 Subject: [PATCH 782/880] [IPV6]: Add missing initializations of the new nl_info.nl_net field Add some more missing initializations of the new nl_info.nl_net field in IPv6 stack. This field will be used when network namespaces are fully supported. Signed-off-by: Benjamin Thery Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 3 +++ net/ipv6/route.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e40213db9e4c..101e0e70ba27 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1557,6 +1557,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, .fc_expires = expires, .fc_dst_len = plen, .fc_flags = RTF_UP | flags, + .fc_nlinfo.nl_net = &init_net, }; ipv6_addr_copy(&cfg.fc_dst, pfx); @@ -1583,6 +1584,7 @@ static void addrconf_add_mroute(struct net_device *dev) .fc_ifindex = dev->ifindex, .fc_dst_len = 8, .fc_flags = RTF_UP, + .fc_nlinfo.nl_net = &init_net, }; ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0); @@ -1599,6 +1601,7 @@ static void sit_route_add(struct net_device *dev) .fc_ifindex = dev->ifindex, .fc_dst_len = 96, .fc_flags = RTF_UP | RTF_NONEXTHOP, + .fc_nlinfo.nl_net = &init_net, }; /* prefix length - 96 bits "::d.d.d.d" */ diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 6e7b56ef4449..e8b241cb60bc 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1719,6 +1719,8 @@ static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg, cfg->fc_src_len = rtmsg->rtmsg_src_len; cfg->fc_flags = rtmsg->rtmsg_flags; + cfg->fc_nlinfo.nl_net = &init_net; + ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst); ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src); ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway); From 148f97292e8fa2c35fcef60a7725cf1b073d6818 Mon Sep 17 00:00:00 2001 From: Bjorn Mork Date: Tue, 26 Feb 2008 18:17:53 -0800 Subject: [PATCH 783/880] [IPV4]: Reset scope when changing address This bug did bite at least one user, who did have to resort to rebooting the system after an "ifconfig eth0 127.0.0.1" typo. Deleting the address and adding a new is a less intrusive workaround. But I still beleive this is a bug that should be fixed. Some way or another. Another possibility would be to remove the scope mangling based on address. This will always be incomplete (are 127/8 the only address space with host scope requirements?) We set the scope to RT_SCOPE_HOST if an IPv4 interface is configured with a loopback address (127/8). The scope is never reset, and will remain set to RT_SCOPE_HOST after changing the address. This patch resets the scope if the address is changed again, to restore normal functionality. Signed-off-by: Bjorn Mork Signed-off-by: David S. Miller --- net/ipv4/devinet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index f282b26f63eb..87490f7bb0f7 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -752,6 +752,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) inet_del_ifa(in_dev, ifap, 0); ifa->ifa_broadcast = 0; ifa->ifa_anycast = 0; + ifa->ifa_scope = 0; } ifa->ifa_address = ifa->ifa_local = sin->sin_addr.s_addr; From 78374676efae525094aee45c0aab4bcab95ea9d1 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 26 Feb 2008 18:25:53 -0800 Subject: [PATCH 784/880] CONNECTOR: make cn_already_initialized static It is used in connector.c only, so make it static. Signed-off-by: Li Zefan Signed-off-by: David S. Miller --- drivers/connector/connector.c | 2 +- include/linux/connector.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index fea2d3ed9cbd..85e2ba7fcfba 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -47,7 +47,7 @@ static LIST_HEAD(notify_list); static struct cn_dev cdev; -int cn_already_initialized = 0; +static int cn_already_initialized; /* * msg->seq and msg->ack are used to determine message genealogy. diff --git a/include/linux/connector.h b/include/linux/connector.h index da6dd957f908..96a89d3d6727 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -170,7 +170,5 @@ int cn_cb_equal(struct cb_id *, struct cb_id *); void cn_queue_wrapper(struct work_struct *work); -extern int cn_already_initialized; - #endif /* __KERNEL__ */ #endif /* __CONNECTOR_H */ From d9595a7b9c777d45a74774f1428c263a0a47f4c0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Feb 2008 22:20:44 -0800 Subject: [PATCH 785/880] [AF_KEY]: Fix oops by converting to proc_net_*(). To make sure the procfs visibility occurs after the ->proc_fs ops are setup, use proc_net_fops_create() and proc_net_remove(). This also fixes an OOPS after module unload in that the name string for remove was wrong, so it wouldn't actually be removed. That bug was introduced by commit 61145aa1a12401ac71bcc450a58c773dd6e2bfb9 ("[KEY]: Clean up proc files creation a bit.") Signed-off-by: David S. Miller --- net/key/af_key.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/key/af_key.c b/net/key/af_key.c index 1c853927810a..8b5f486ac80f 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -3807,17 +3807,16 @@ static int pfkey_init_proc(void) { struct proc_dir_entry *e; - e = create_proc_entry("pfkey", 0, init_net.proc_net); + e = proc_net_fops_create(&init_net, "pfkey", 0, &pfkey_proc_ops); if (e == NULL) return -ENOMEM; - e->proc_fops = &pfkey_proc_ops; return 0; } static void pfkey_exit_proc(void) { - remove_proc_entry("net/pfkey", NULL); + proc_net_remove(&init_net, "pfkey"); } #else static inline int pfkey_init_proc(void) From b37d428b24ad38034f56b614de05686ba151b614 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 26 Feb 2008 23:51:04 -0800 Subject: [PATCH 786/880] [INET]: Don't create tunnels with '%' in name. Four tunnel drivers (ip_gre, ipip, ip6_tunnel and sit) can receive a pre-defined name for a device from the userspace. Since these drivers call the register_netdevice() (rtnl_lock, is held), which does _not_ generate the device's name, this name may contain a '%' character. Not sure how bad is this to have a device with a '%' in its name, but all the other places either use the register_netdev(), which call the dev_alloc_name(), or explicitly call the dev_alloc_name() before registering, i.e. do not allow for such names. This had to be prior to the commit 34cc7b, but I forgot to number the patches and this one got lost, sorry. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 14 +++++++++----- net/ipv4/ipip.c | 14 +++++++++----- net/ipv6/ip6_tunnel.c | 15 +++++++++++---- net/ipv6/sit.c | 13 +++++++++---- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 906cb1ada4c3..e7821ba7a9a0 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -266,20 +266,24 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int if (!dev) return NULL; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + dev->init = ipgre_tunnel_init; nt = netdev_priv(dev); nt->parms = *parms; - if (register_netdevice(dev) < 0) { - free_netdev(dev); - goto failed; - } + if (register_netdevice(dev) < 0) + goto failed_free; dev_hold(dev); ipgre_tunnel_link(nt); return nt; -failed: +failed_free: + free_netdev(dev); return NULL; } diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e77e3b855834..dbaed69de06a 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -228,20 +228,24 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c if (dev == NULL) return NULL; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + nt = netdev_priv(dev); dev->init = ipip_tunnel_init; nt->parms = *parms; - if (register_netdevice(dev) < 0) { - free_netdev(dev); - goto failed; - } + if (register_netdevice(dev) < 0) + goto failed_free; dev_hold(dev); ipip_tunnel_link(nt); return nt; -failed: +failed_free: + free_netdev(dev); return NULL; } diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 2a124e9a1b2d..78f438880923 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -238,17 +238,24 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p) if (dev == NULL) goto failed; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + t = netdev_priv(dev); dev->init = ip6_tnl_dev_init; t->parms = *p; - if ((err = register_netdevice(dev)) < 0) { - free_netdev(dev); - goto failed; - } + if ((err = register_netdevice(dev)) < 0) + goto failed_free; + dev_hold(dev); ip6_tnl_link(t); return t; + +failed_free: + free_netdev(dev); failed: return NULL; } diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index dde7801abeff..1656c003b989 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -171,6 +171,11 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int if (dev == NULL) return NULL; + if (strchr(name, '%')) { + if (dev_alloc_name(dev, name) < 0) + goto failed_free; + } + nt = netdev_priv(dev); dev->init = ipip6_tunnel_init; nt->parms = *parms; @@ -178,16 +183,16 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int if (parms->i_flags & SIT_ISATAP) dev->priv_flags |= IFF_ISATAP; - if (register_netdevice(dev) < 0) { - free_netdev(dev); - goto failed; - } + if (register_netdevice(dev) < 0) + goto failed_free; dev_hold(dev); ipip6_tunnel_link(nt); return nt; +failed_free: + free_netdev(dev); failed: return NULL; } From 325d6f5593b40b5a48cf4ade74c01681f2ff6044 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 27 Feb 2008 14:04:29 +0100 Subject: [PATCH 787/880] avr32: Fix OCD refcounting bug Iff the parent has TIF_DEBUG set, _and_ clone_flags includes CLONE_PTRACE we should set the TIF_DEBUG flag for the child and increment the ocd refcount. Otherwise, the TIF_DEBUG flag must be unset. Currently, the child inherits TIF_DEBUG from the parent before copy_thread is called, so TIF_DEBUG may be already be set before we determine whether the child is supposed to inherit debugging capabilities from the parent or not. This means that ocd_enable() won't increment the refcount, because TIF_DEBUG is already set, and that TIF_DEBUG will be set for processes that aren't being debugged. This leads to a refcounting asymmetry, which may show up as ------------[ cut here ]------------ Badness at arch/avr32/kernel/ocd.c:73 PC is at ocd_disable+0x34/0x60 LR is at put_lock_stats+0xa/0x20 as reported by David Brownell. Happens when strace'ing a process that forks a new child process, e.g. "strace mount -tjffs2 mtd1 /mnt", and subsequently killing the child process (e.g. "umount /mnt".) Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/process.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index faf8d0e76801..7f4af0b1e111 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -348,6 +348,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, p->thread.cpu_context.ksp = (unsigned long)childregs; p->thread.cpu_context.pc = (unsigned long)ret_from_fork; + clear_tsk_thread_flag(p, TIF_DEBUG); if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) ocd_enable(p); From 3bdfe7ec08b4256121a8894cd978e74fcf7031d7 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Wed, 27 Feb 2008 12:06:38 -0800 Subject: [PATCH 788/880] [IPV6] SYSCTL: Fix possible memory leakage in error path. In error path, we do need to free memory just allocated. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/sysctl_net_ipv6.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 408691b777c2..d6d3e68086f8 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -101,9 +101,6 @@ static int ipv6_sysctl_net_init(struct net *net) net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, ipv6_table); - if (!net->ipv6.sysctl.table) - return -ENOMEM; - if (!net->ipv6.sysctl.table) goto out_ipv6_icmp_table; From 4e29e9ec7e0707d3925f5dcc29af0d3f04e49833 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 27 Feb 2008 12:07:47 -0800 Subject: [PATCH 789/880] [NETFILTER]: nf_conntrack: fix smp_processor_id() in preemptible code warning Since we're using RCU for the conntrack hash now, we need to avoid getting preempted or interrupted by BHs while changing the stats. Fixes warning reported by Tilman Schmidt when using preemptible RCU: [ 48.180297] BUG: using smp_processor_id() in preemptible [00000000] code: ntpdate/3562 [ 48.180297] caller is __nf_conntrack_find+0x9b/0xeb [nf_conntrack] [ 48.180297] Pid: 3562, comm: ntpdate Not tainted 2.6.25-rc2-mm1-testing #1 [ 48.180297] [] debug_smp_processor_id+0x99/0xb0 [ 48.180297] [] __nf_conntrack_find+0x9b/0xeb [nf_conntrack] Tested-by: Tilman Schmidt Tested-by: Christian Casteyde [Bugzilla #10097] Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_core.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 327e847d2702..b77eb56a87e3 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -256,13 +256,19 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple) struct hlist_node *n; unsigned int hash = hash_conntrack(tuple); + /* Disable BHs the entire time since we normally need to disable them + * at least once for the stats anyway. + */ + local_bh_disable(); hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { if (nf_ct_tuple_equal(tuple, &h->tuple)) { NF_CT_STAT_INC(found); + local_bh_enable(); return h; } NF_CT_STAT_INC(searched); } + local_bh_enable(); return NULL; } @@ -400,17 +406,20 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, struct hlist_node *n; unsigned int hash = hash_conntrack(tuple); - rcu_read_lock(); + /* Disable BHs the entire time since we need to disable them at + * least once for the stats anyway. + */ + rcu_read_lock_bh(); hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && nf_ct_tuple_equal(tuple, &h->tuple)) { NF_CT_STAT_INC(found); - rcu_read_unlock(); + rcu_read_unlock_bh(); return 1; } NF_CT_STAT_INC(searched); } - rcu_read_unlock(); + rcu_read_unlock_bh(); return 0; } From d61f89e9417e68caf9ca801606694c1c960ad179 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 27 Feb 2008 12:09:05 -0800 Subject: [PATCH 790/880] [NETFILTER]: xt_conntrack: fix missing boolean clamping Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_conntrack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 85330856a29c..dd192ac74b4a 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c @@ -231,7 +231,7 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in, if (test_bit(IPS_DST_NAT_BIT, &ct->status)) statebit |= XT_CONNTRACK_STATE_DNAT; } - if ((info->state_mask & statebit) ^ + if (!!(info->state_mask & statebit) ^ !(info->invert_flags & XT_CONNTRACK_STATE)) return false; } From 6556874dc3770aefae89907b3cf9be8e23d66137 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 27 Feb 2008 12:20:41 -0800 Subject: [PATCH 791/880] [NETFILTER]: xt_conntrack: fix IPv4 address comparison Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_conntrack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index dd192ac74b4a..0c50b2894055 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c @@ -122,7 +122,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr, const union nf_inet_addr *umask, unsigned int l3proto) { if (l3proto == AF_INET) - return (kaddr->ip & umask->ip) == uaddr->ip; + return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0; else if (l3proto == AF_INET6) return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6, &uaddr->in6) == 0; From fbabbed8284d1526ed01754ecd4fabdb941a1ff2 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 27 Feb 2008 12:21:18 -0800 Subject: [PATCH 792/880] [NETFILTER]: Fix NF_QUEUE_NR() parenthesis Properly add parens around the macro argument. This is not needed by the kernel but the macro is exported to userspace, so it shouldn't make any assumptions. Also use NF_VERDICT_BITS instead of NF_VERDICT_QBTIS for the left-shift since thats whats logically correct. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index b74b615492e8..f0680c2bee73 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -31,7 +31,7 @@ #define NF_VERDICT_QMASK 0xffff0000 #define NF_VERDICT_QBITS 16 -#define NF_QUEUE_NR(x) (((x << NF_VERDICT_QBITS) & NF_VERDICT_QMASK) | NF_QUEUE) +#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE) /* only for userspace compatibility */ #ifndef __KERNEL__ From b90a137d30a6322d76023d879d40fc31f3edf0a6 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 14 Feb 2008 10:18:20 -0500 Subject: [PATCH 793/880] [SCTP]: Correctly set the length of sctp_assoc_change notification sctp_assoc_change notification may contain the data from a received ABORT chunk. Set the length correctly to account for that. Signed-off-by: Vlad Yasevich --- net/sctp/ulpevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index e27b11f18b7f..b43f1f110f87 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -206,7 +206,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( * This field is the total length of the notification data, including * the notification header. */ - sac->sac_length = sizeof(struct sctp_assoc_change); + sac->sac_length = skb->len; /* Socket Extensions for SCTP * 5.3.1.1 SCTP_ASSOC_CHANGE From 5b0acc64a3750f8f017b973f1059bb25b791c2a3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Feb 2008 11:47:45 +0100 Subject: [PATCH 794/880] rndis_wlan: fix sparse warnings It is obviously wrong to use an enum in a little endian struct, and those other enums should be declared differently. Signed-off-by: Johannes Berg Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 8ce2ddf8024f..d9460aed1f22 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -228,9 +228,9 @@ struct NDIS_WLAN_BSSID_EX { struct NDIS_802_11_SSID Ssid; __le32 Privacy; __le32 Rssi; - enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + __le32 NetworkTypeInUse; struct NDIS_802_11_CONFIGURATION Configuration; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + __le32 InfrastructureMode; u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX]; __le32 IELength; u8 IEs[0]; @@ -279,11 +279,11 @@ struct RNDIS_CONFIG_PARAMETER_INFOBUFFER { } __attribute__((packed)); /* these have to match what is in wpa_supplicant */ -enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg; -enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 } - wpa_cipher; -enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA, - KEY_MGMT_WPA_NONE } wpa_key_mgmt; +enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; +enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, + CIPHER_WEP104 }; +enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, + KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE }; /* * private data From 4b74850dc3fb8a0941dde0f1bf7686803d1250cd Mon Sep 17 00:00:00 2001 From: Masakazu Mokuno Date: Fri, 22 Feb 2008 16:45:26 +0900 Subject: [PATCH 795/880] PS3: gelic: Link the wireless net_device structure to the corresponding device structure Link the net_device structure of the wireless part to the corresponding device structure. Without this, the sysfs node for this net_device would not have 'device' link. Signed-off-by: Masakazu Mokuno Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/ps3_gelic_wireless.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 750d2a99cb4f..daf5abab9534 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -2690,6 +2690,7 @@ int gelic_wl_driver_probe(struct gelic_card *card) return -ENOMEM; /* setup net_device structure */ + SET_NETDEV_DEV(netdev, &card->dev->core); gelic_wl_setup_netdev_ops(netdev); /* setup some of net_device and register it */ From 8bfb04756a698e38825656eab3bc339a321551b3 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Sat, 23 Feb 2008 21:46:31 +0100 Subject: [PATCH 796/880] gelic wireless driver needs WIRELESS_EXT support | CC drivers/net/ps3_gelic_wireless.o | /home/bigeasy/git/linux-2.6/drivers/net/ps3_gelic_wireless.c: In function 'gelic_wl_setup_netdev_ops': | /home/bigeasy/git/linux-2.6/drivers/net/ps3_gelic_wireless.c:2660: error: 'struct net_device' has no member named 'wireless_data' | /home/bigeasy/git/linux-2.6/drivers/net/ps3_gelic_wireless.c:2661: error: 'struct net_device' has no member named 'wireless_handlers' | make[3]: *** [drivers/net/ps3_gelic_wireless.o] Error 1 | make[2]: *** [drivers/net] Error 2 | make[1]: *** [drivers] Error 2 | make[1]: *** Waiting for unfinished jobs.... | make: *** [sub-make] Error 2 Signed-off-by: Sebastian Siewior Acked-by: Masakazu Mokuno Signed-off-by: John W. Linville --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a20e72f5ad28..a0f0e605d630 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2368,6 +2368,7 @@ config GELIC_NET config GELIC_WIRELESS bool "PS3 Wireless support" depends on GELIC_NET + select WIRELESS_EXT help This option adds the support for the wireless feature of PS3. If you have the wireless-less model of PS3 or have no plan to From b290d433618aa7122f6e6c4a62ddc79412a48d4d Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 25 Feb 2008 23:15:01 +0100 Subject: [PATCH 797/880] rt2x00: Fix antenna diversity Fix 2 issues in antenna diversity selection. 1) the following statement will always return true. if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5) It is cleaner to check if the absolute value is smaller then 5. 2) Only enable software diversity when default antenna setup indicates support for it. Don't select it when the hardware does not indicate support for it... Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c4be2ac4d7a4..00f5f0d49e1d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -293,7 +293,7 @@ static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev) * sample the rssi from the other antenna to make a valid * comparison between the 2 antennas. */ - if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5) + if (abs(rssi_curr - rssi_old) < 5) return; rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE; @@ -319,10 +319,10 @@ static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev) rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY; if (rt2x00dev->hw->conf.antenna_sel_rx == 0 && - rt2x00dev->default_ant.rx != ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY; if (rt2x00dev->hw->conf.antenna_sel_tx == 0 && - rt2x00dev->default_ant.tx != ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY; if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) && From 61667d8d5bf3c3ee09474069eaf4b93a4755ff8b Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 25 Feb 2008 23:15:05 +0100 Subject: [PATCH 798/880] rt2x00: Add link tuner safe RX toggle states This adds 2 new states which both are used to toggle the RX. These new states are required for usage inside the link tuner thread, because the normal RX toggling will stop the link tuner thread. While it is possible that the link tuner thread itself is the caller of the RX toggle (when using software antenna diversity). Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt2500pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt2500usb.c | 6 +++++- drivers/net/wireless/rt2x00/rt2x00config.c | 4 ++-- drivers/net/wireless/rt2x00/rt2x00reg.h | 2 ++ drivers/net/wireless/rt2x00/rt61pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt73usb.c | 6 +++++- 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index d6cba138c7ab..c69f85ed7669 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -960,8 +960,12 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2400pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt2400pci_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index e874fdcae204..91e87b53374f 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1112,8 +1112,12 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt2500pci_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 4ca9730e5e92..638c3d243108 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1001,8 +1001,12 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt2500usb_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 72cfe00c1ed7..0d57d7f67837 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -102,7 +102,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); /* * Write new antenna setup to device and reset the link tuner. @@ -116,7 +116,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, rt2x00dev->link.ant.active.tx = libconf.ant.tx; if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); } void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index 838421216da0..b1915dc7dda1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -85,6 +85,8 @@ enum dev_state { STATE_RADIO_OFF, STATE_RADIO_RX_ON, STATE_RADIO_RX_OFF, + STATE_RADIO_RX_ON_LINK, + STATE_RADIO_RX_OFF_LINK, STATE_RADIO_IRQ_ON, STATE_RADIO_IRQ_OFF, }; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index b31f0c26c32b..e808db98f2f5 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1482,8 +1482,12 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt61pci_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt61pci_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 4d576ab3e7f9..4fac2d414d84 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1208,8 +1208,12 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt73usb_disable_radio(rt2x00dev); break; case STATE_RADIO_RX_ON: + case STATE_RADIO_RX_ON_LINK: + rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: - rt73usb_toggle_rx(rt2x00dev, state); + case STATE_RADIO_RX_OFF_LINK: + rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: From 05253c93feb40901d80a0d6f239a0bc78860c679 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 25 Feb 2008 23:15:08 +0100 Subject: [PATCH 799/880] rt2x00: Don't switch to antenna with low rssi When rssi_a > rssi_b is true and the current antenna was already antenna A, then rt2x00 incorrectly jumped to antenna B. Also don't configure the antenna when there has been no change in the antenna setup. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00config.c | 4 ++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 18 +++++------------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 0d57d7f67837..07adc576db49 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -97,6 +97,10 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, libconf.ant.rx = rx; libconf.ant.tx = tx; + if (rx == rt2x00dev->link.ant.active.rx && + tx == rt2x00dev->link.ant.active.tx) + return; + /* * Antenna setup changes require the RX to be disabled, * else the changes will be ignored by the device. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 00f5f0d49e1d..7294c75272d0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -260,19 +260,11 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev) if (sample_a == sample_b) return; - if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) { - if (sample_a > sample_b && rx == ANTENNA_B) - rx = ANTENNA_A; - else if (rx == ANTENNA_A) - rx = ANTENNA_B; - } + if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) + rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; - if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) { - if (sample_a > sample_b && tx == ANTENNA_B) - tx = ANTENNA_A; - else if (tx == ANTENNA_A) - tx = ANTENNA_B; - } + if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) + tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; rt2x00lib_config_antenna(rt2x00dev, rx, tx); } @@ -327,7 +319,7 @@ static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev) if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) && !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) { - rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE; + rt2x00dev->link.ant.flags = 0; return; } From 53b3f8e47a38f39836da1c9f9d2ea9a9c164c8f4 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 25 Feb 2008 23:15:13 +0100 Subject: [PATCH 800/880] rt2x00: Fix rt2x00lib_reset_link_tuner() rt2x00lib_reset_link_tuner() can be called from within the link tuner itself. This means that it should _not_ call rt2x00lib_stop_link_tuner() since that will cause the thread to hang. Reorder the things that should be done during a link tuner reset and during a link tuner start. Also make antenna tuning the last step of the link tuner since it could possibly reset some statistical information which we need for average calculation. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 49 +++++++++++++++---------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 7294c75272d0..0d51f478bcdf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -61,11 +61,33 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); /* * Link tuning handlers */ -static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) +void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) { + if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) + return; + + /* + * Reset link information. + * Both the currently active vgc level as well as + * the link tuner counter should be reset. Resetting + * the counter is important for devices where the + * device should only perform link tuning during the + * first minute after being enabled. + */ rt2x00dev->link.count = 0; rt2x00dev->link.vgc_level = 0; + /* + * Reset the link tuner. + */ + rt2x00dev->ops->lib->reset_tuner(rt2x00dev); +} + +static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) +{ + /* + * Clear all (possibly) pre-existing quality statistics. + */ memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual)); /* @@ -79,10 +101,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) rt2x00dev->link.qual.rx_percentage = 50; rt2x00dev->link.qual.tx_percentage = 50; - /* - * Reset the link tuner. - */ - rt2x00dev->ops->lib->reset_tuner(rt2x00dev); + rt2x00lib_reset_link_tuner(rt2x00dev); queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, LINK_TUNE_INTERVAL); @@ -93,15 +112,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) cancel_delayed_work_sync(&rt2x00dev->link.work); } -void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) -{ - if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - return; - - rt2x00lib_stop_link_tuner(rt2x00dev); - rt2x00lib_start_link_tuner(rt2x00dev); -} - /* * Ring initialization */ @@ -432,17 +442,18 @@ static void rt2x00lib_link_tuner(struct work_struct *work) if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags)) rt2x00dev->ops->lib->link_tuner(rt2x00dev); - /* - * Evaluate antenna setup. - */ - rt2x00lib_evaluate_antenna(rt2x00dev); - /* * Precalculate a portion of the link signal which is * in based on the tx/rx success/failure counters. */ rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); + /* + * Evaluate antenna setup, make this the last step since this could + * possibly reset some statistics. + */ + rt2x00lib_evaluate_antenna(rt2x00dev); + /* * Increase tuner counter, and reschedule the next link tuner run. */ From 03147dfc8a3756439f0cc54aa181f30067f1b21b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Feb 2008 00:39:28 +0100 Subject: [PATCH 801/880] mac80211: fix kmalloc vs. net_ratelimit The "goto end;" part definitely must not be rate limited. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_sta.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 2019b4f0528d..9aeed5320228 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -1116,9 +1116,10 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, /* prepare reordering buffer */ tid_agg_rx->reorder_buf = kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); - if ((!tid_agg_rx->reorder_buf) && net_ratelimit()) { - printk(KERN_ERR "can not allocate reordering buffer " - "to tid %d\n", tid); + if (!tid_agg_rx->reorder_buf) { + if (net_ratelimit()) + printk(KERN_ERR "can not allocate reordering buffer " + "to tid %d\n", tid); goto end; } memset(tid_agg_rx->reorder_buf, 0, From 4b7524a42e14a7f86fa12611f3419650e99e2526 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 26 Feb 2008 15:26:56 +0100 Subject: [PATCH 802/880] libertas: Remove unused exports The libertas driver exports a number of symbols with no in-tree users; remove these unused exports. lbs_reset_device() is completely unused, with no callers at all, so remove the function completely. A couple of these unused exported symbols are static, which causes the following build error on ia64 with gcc 4.2.3: drivers/net/wireless/libertas/main.c:1375: error: __ksymtab_lbs_remove_mesh causes a section type conflict drivers/net/wireless/libertas/main.c:1354: error: __ksymtab_lbs_add_mesh causes a section type conflict Signed-off-by: Roland Dreier Acked-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 2 -- drivers/net/wireless/libertas/decl.h | 1 - drivers/net/wireless/libertas/main.c | 17 ----------------- 3 files changed, 20 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index eab020338fde..b3c1acbcc655 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1040,7 +1040,6 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, lbs_deb_leave(LBS_DEB_CMD); return ret; } -EXPORT_SYMBOL_GPL(lbs_mesh_access); int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan) { @@ -1576,7 +1575,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command); /** * @brief This function allocates the command buffer and link diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index aaacd9bd6bd2..4e22341b4f3d 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -69,7 +69,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev); int lbs_remove_card(struct lbs_private *priv); int lbs_start_card(struct lbs_private *priv); int lbs_stop_card(struct lbs_private *priv); -int lbs_reset_device(struct lbs_private *priv); void lbs_host_to_card_done(struct lbs_private *priv); int lbs_update_channel(struct lbs_private *priv); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 84fb49ca0fae..4d4e2f3b66ac 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1351,8 +1351,6 @@ static int lbs_add_mesh(struct lbs_private *priv) lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(lbs_add_mesh); - static void lbs_remove_mesh(struct lbs_private *priv) { @@ -1372,7 +1370,6 @@ static void lbs_remove_mesh(struct lbs_private *priv) free_netdev(mesh_dev); lbs_deb_leave(LBS_DEB_MESH); } -EXPORT_SYMBOL_GPL(lbs_remove_mesh); /** * @brief This function finds the CFP in @@ -1458,20 +1455,6 @@ void lbs_interrupt(struct lbs_private *priv) } EXPORT_SYMBOL_GPL(lbs_interrupt); -int lbs_reset_device(struct lbs_private *priv) -{ - int ret; - - lbs_deb_enter(LBS_DEB_MAIN); - ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET, - CMD_ACT_HALT, 0, 0, NULL); - msleep_interruptible(10); - - lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); - return ret; -} -EXPORT_SYMBOL_GPL(lbs_reset_device); - static int __init lbs_init_module(void) { lbs_deb_enter(LBS_DEB_MAIN); From c7084535c9d2b8bcfc19f1ad9452eabde742ae22 Mon Sep 17 00:00:00 2001 From: Alexey Zaytsev Date: Sat, 23 Feb 2008 12:59:26 +0300 Subject: [PATCH 803/880] Use a separate config option for the b43 pci to ssb bridge. The bridge code was unnecessary enabled by the b44 driver, but it prevents the bcm43xx driver from being loaded, as the bridge claims the same pci ids. Now we enable the birdge only if the b43{legacy} drivers are selected. Signed-off-by: Alexey Zaytsev Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 1 + drivers/net/wireless/b43legacy/Kconfig | 1 + drivers/ssb/Kconfig | 5 +++++ drivers/ssb/Makefile | 2 +- drivers/ssb/ssb_private.h | 4 ++-- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 1a2141dabdc7..8bc4bc4c330e 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -32,6 +32,7 @@ config B43_PCI_AUTOSELECT bool depends on B43 && SSB_PCIHOST_POSSIBLE select SSB_PCIHOST + select SSB_B43_PCI_BRIDGE default y # Auto-select SSB PCICORE driver, if possible diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 6745579ba96d..13c65faf0247 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig @@ -25,6 +25,7 @@ config B43LEGACY_PCI_AUTOSELECT bool depends on B43LEGACY && SSB_PCIHOST_POSSIBLE select SSB_PCIHOST + select SSB_B43_PCI_BRIDGE default y # Auto-select SSB PCICORE driver, if possible diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 78fd33125e02..adea792fb675 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig @@ -35,6 +35,11 @@ config SSB_PCIHOST If unsure, say Y +config SSB_B43_PCI_BRIDGE + bool + depends on SSB_PCIHOST + default n + config SSB_PCMCIAHOST_POSSIBLE bool depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile index e235144add7c..de94c2eb7a37 100644 --- a/drivers/ssb/Makefile +++ b/drivers/ssb/Makefile @@ -14,6 +14,6 @@ ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o # b43 pci-ssb-bridge driver # Not strictly a part of SSB, but kept here for convenience -ssb-$(CONFIG_SSB_PCIHOST) += b43_pci_bridge.o +ssb-$(CONFIG_SSB_B43_PCI_BRIDGE) += b43_pci_bridge.o obj-$(CONFIG_SSB) += ssb.o diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index a789364264a6..21eca2b5118b 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h @@ -120,10 +120,10 @@ extern int ssb_devices_thaw(struct ssb_bus *bus); extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev); /* b43_pci_bridge.c */ -#ifdef CONFIG_SSB_PCIHOST +#ifdef CONFIG_SSB_B43_PCI_BRIDGE extern int __init b43_pci_ssb_bridge_init(void); extern void __exit b43_pci_ssb_bridge_exit(void); -#else /* CONFIG_SSB_PCIHOST */ +#else /* CONFIG_SSB_B43_PCI_BRIDGR */ static inline int b43_pci_ssb_bridge_init(void) { return 0; From f9d8f88952c263a4eeaaa0fc6ff726d2315b6a57 Mon Sep 17 00:00:00 2001 From: Alexey Zaytsev Date: Sat, 23 Feb 2008 13:33:07 +0300 Subject: [PATCH 804/880] Don't build bcm43xx if SSB is static and b43 PCI-SSB bridge is enabled. This may happen e.g. when the ssb is statically enables by the b44 driver, and the b43 pci-ssb bridge is enbled by the b43/b43legacy drivers, or the b43/b43legacy drivers are built statically. Signed-off-by: Alexey Zaytsev Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/bcm43xx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig index 0159701e8456..afb8f4305c24 100644 --- a/drivers/net/wireless/bcm43xx/Kconfig +++ b/drivers/net/wireless/bcm43xx/Kconfig @@ -1,6 +1,6 @@ config BCM43XX tristate "Broadcom BCM43xx wireless support (DEPRECATED)" - depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL + depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && (!SSB_B43_PCI_BRIDGE || SSB != y) && EXPERIMENTAL select WIRELESS_EXT select FW_LOADER select HW_RANDOM From 2d8d4fdf78488f3362dccfd2a6bfdb4bc65c0858 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Thu, 28 Feb 2008 15:11:26 +0100 Subject: [PATCH 805/880] SSB PCI core driver: use new SPROM data structure Switch the SSB PCI core driver to the new SPROM data structure now that the old one has been removed. Signed-off-by: Aurelien Jarno Acked-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_pcicore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 6d99a9880055..07ab48d9ceab 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -393,7 +393,7 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) chipid_top != 0x5300) return 0; - if (bus->sprom.r1.boardflags_lo & SSB_PCICORE_BFL_NOPCI) + if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI) return 0; /* The 200-pin BCM4712 package does not bond out PCI. Even when From 21e43188f272c7fd9efc84b8244c0b1dfccaa105 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 28 Feb 2008 11:23:17 -0800 Subject: [PATCH 806/880] [IPCOMP]: Disable BH on output when using shared tfm Because we use shared tfm objects in order to conserve memory, (each tfm requires 128K of vmalloc memory), BH needs to be turned off on output as that can occur in process context. Previously this was done implicitly by the xfrm output code. That was lost when it became lockless. So we need to add the BH disabling to IPComp directly. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/ipcomp.c | 5 ++++- net/ipv6/ipcomp6.c | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index ae1f45fc23b9..58b60b2fb011 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -108,8 +108,11 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) const int cpu = get_cpu(); u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); - int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + int err; + local_bh_disable(); + err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + local_bh_enable(); if (err) goto out; diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index b90039593a7f..e3dcfa2f436b 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -146,7 +146,9 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); tfm = *per_cpu_ptr(ipcd->tfms, cpu); + local_bh_disable(); err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + local_bh_enable(); if (err || (dlen + sizeof(*ipch)) >= plen) { put_cpu(); goto out_ok; From c14423fe585a5937db6e2eece4b79486521103be Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:49:42 -0800 Subject: [PATCH 807/880] [BNX2X]: Spelling fixes Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 119 ++++++++++++++++++++------------------------ drivers/net/bnx2x.h | 2 +- 2 files changed, 56 insertions(+), 65 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index afc7f34b1dcf..7b2d7898f06d 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -10,13 +10,13 @@ * Based on code from Michael Chan's bnx2 driver * UDP CSUM errata workaround by Arik Gendelman * Slowpath rework by Vladislav Zolotarov - * Statistics and Link managment by Yitchak Gertner + * Statistics and Link management by Yitchak Gertner * */ /* define this to make the driver freeze on error * to allow getting debug info - * (you will need to reboot afterwords) + * (you will need to reboot afterwards) */ /*#define BNX2X_STOP_ON_ERROR*/ @@ -71,7 +71,7 @@ #define TX_TIMEOUT (5*HZ) static char version[] __devinitdata = - "Broadcom NetXtreme II 577xx 10Gigabit Ethernet Driver " + "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir "); @@ -94,8 +94,8 @@ module_param(debug, int, 0); MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X"); MODULE_PARM_DESC(poll, "use polling (for debug)"); MODULE_PARM_DESC(onefunc, "enable only first function"); -MODULE_PARM_DESC(nomcp, "ignore managment CPU (Implies onefunc)"); -MODULE_PARM_DESC(debug, "defualt debug msglevel"); +MODULE_PARM_DESC(nomcp, "ignore management CPU (Implies onefunc)"); +MODULE_PARM_DESC(debug, "default debug msglevel"); #ifdef BNX2X_MULTI module_param(use_multi, int, 0); @@ -341,6 +341,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp) } return rc; } + static void bnx2x_fw_dump(struct bnx2x *bp) { u32 mark, offset; @@ -491,7 +492,7 @@ static void bnx2x_disable_int_sync(struct bnx2x *bp) int i; atomic_inc(&bp->intr_sem); - /* prevent the HW from sending interrupts*/ + /* prevent the HW from sending interrupts */ bnx2x_disable_int(bp); /* make sure all ISRs are done */ @@ -775,6 +776,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp, mb(); /* force bnx2x_wait_ramrod to see the change */ return; } + switch (command | bp->state) { case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT): DP(NETIF_MSG_IFUP, "got setup ramrod\n"); @@ -1471,7 +1473,7 @@ static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val) } /* - * link managment + * link management */ static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status) @@ -1482,7 +1484,7 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status) bp->flow_ctrl = 0; - /* reolve from gp_status in case of AN complete and not sgmii */ + /* resolve from gp_status in case of AN complete and not sgmii */ if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) && (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && (!(bp->phy_flags & PHY_SGMII_FLAG)) && @@ -1680,7 +1682,7 @@ static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g) int port = bp->port; /* first reset all status - * we asume only one line will be change at a time */ + * we assume only one line will be change at a time */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, (NIG_XGXS0_LINK_STATUS | NIG_SERDES0_LINK_STATUS | @@ -1819,7 +1821,7 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb) u32 wb_write[2]; u32 val; - DP(NETIF_MSG_LINK, "enableing BigMAC\n"); + DP(NETIF_MSG_LINK, "enabling BigMAC\n"); /* reset and unreset the BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); @@ -1940,7 +1942,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp) u32 val; int timeout; - DP(NETIF_MSG_LINK, "enableing EMAC\n"); + DP(NETIF_MSG_LINK, "enabling EMAC\n"); /* reset and unreset the emac core */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); @@ -2033,7 +2035,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp) EMAC_TX_MODE_EXT_PAUSE_EN); } - /* KEEP_VLAN_TAG, promiscous */ + /* KEEP_VLAN_TAG, promiscuous */ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; EMAC_WR(EMAC_REG_EMAC_RX_MODE, val); @@ -2161,7 +2163,6 @@ static void bnx2x_pbf_update(struct bnx2x *bp) u32 count = 1000; u32 pause = 0; - /* disable port */ REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); @@ -2803,7 +2804,7 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); + DP(NETIF_MSG_LINK, "enabled external phy int\n"); bp->phy_addr = ext_phy_type; bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, @@ -2824,7 +2825,7 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); + DP(NETIF_MSG_LINK, "enabled external phy int\n"); bp->phy_addr = ext_phy_type; bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, @@ -2857,7 +2858,7 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); + DP(NETIF_MSG_LINK, "enabled external phy int\n"); break; default: @@ -2994,13 +2995,13 @@ static void bnx2x_link_initialize(struct bnx2x *bp) /* AN enabled */ bnx2x_set_brcm_cl37_advertisment(bp); - /* program duplex & pause advertisment (for aneg) */ + /* program duplex & pause advertisement (for aneg) */ bnx2x_set_ieee_aneg_advertisment(bp); /* enable autoneg */ bnx2x_set_autoneg(bp); - /* enalbe and restart AN */ + /* enable and restart AN */ bnx2x_restart_autoneg(bp); } @@ -3158,7 +3159,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, int port = bp->port; DP(NETIF_MSG_TIMER, - "spe (%x:%x) command %x hw_cid %x data (%x:%x) left %x\n", + "spe (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) + (void *)bp->spq_prod_bd - (void *)bp->spq), command, HW_CID(bp, cid), data_hi, data_lo, bp->spq_left); @@ -3464,7 +3465,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) HW_PRTY_ASSERT_SET_1) || (attn.sig[2] & group_mask.sig[2] & HW_PRTY_ASSERT_SET_2)) - BNX2X_ERR("FATAL HW block parity atention\n"); + BNX2X_ERR("FATAL HW block parity attention\n"); } } @@ -3906,7 +3907,7 @@ static void bnx2x_stop_stats(struct bnx2x *bp) while (bp->stats_state != STATS_STATE_DISABLE) { if (!timeout) { - BNX2X_ERR("timeout wating for stats stop\n"); + BNX2X_ERR("timeout waiting for stats stop\n"); break; } timeout--; @@ -4626,7 +4627,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp) fp->rx_bd_prod = fp->rx_comp_prod = ring_prod; fp->rx_pkt = fp->rx_calls = 0; - /* Warning! this will genrate an interrupt (to the TSTORM) */ + /* Warning! this will generate an interrupt (to the TSTORM) */ /* must only be done when chip is initialized */ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod); @@ -4850,7 +4851,7 @@ static void bnx2x_init_internal(struct bnx2x *bp) /* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n", (*(u32 *)&tstorm_config)); */ - bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx untill link is up */ + bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ bnx2x_set_storm_rx_mode(bp); for_each_queue(bp, i) @@ -5359,7 +5360,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8); #endif bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END); - /* softrest pulse */ + /* soft reset pulse */ REG_WR(bp, QM_REG_SOFT_RESET, 1); REG_WR(bp, QM_REG_SOFT_RESET, 0); @@ -5413,7 +5414,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) { REG_WR(bp, i, 0xc0cac01a); - /* TODO: repleace with something meaningfull */ + /* TODO: replace with something meaningful */ } /* SRCH COMMON comes here */ REG_WR(bp, SRC_REG_SOFT_RST, 0); @@ -5647,7 +5648,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) bnx2x_link_reset(bp); - /* Reset pciex errors for debug */ + /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); REG_WR(bp, 0x2120, 0xffffffff); REG_WR(bp, 0x2814, 0xffffffff); @@ -5681,8 +5682,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) return 0; } - -/* send the MCP a request, block untill there is a reply */ +/* send the MCP a request, block until there is a reply */ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) { u32 rc = 0; @@ -5869,7 +5869,7 @@ static int bnx2x_alloc_mem(struct bnx2x *bp) for (i = 0; i < 16*1024; i += 64) * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; - /* now sixup the last line in the block to point to the next block */ + /* now fixup the last line in the block to point to the next block */ *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping; /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */ @@ -5950,11 +5950,11 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) int i; free_irq(bp->msix_table[0].vector, bp->dev); - DP(NETIF_MSG_IFDOWN, "rleased sp irq (%d)\n", + DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", bp->msix_table[0].vector); for_each_queue(bp, i) { - DP(NETIF_MSG_IFDOWN, "about to rlease fp #%d->%d irq " + DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " "state(%x)\n", i, bp->msix_table[i + 1].vector, bnx2x_fp(bp, i, state)); @@ -6010,7 +6010,6 @@ static int bnx2x_enable_msix(struct bnx2x *bp) static int bnx2x_req_msix_irqs(struct bnx2x *bp) { - int i, rc; DP(NETIF_MSG_IFUP, "about to request sp irq\n"); @@ -6109,8 +6108,8 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, /* can take a while if any port is running */ int timeout = 500; - /* DP("waiting for state to become %d on IDX [%d]\n", - state, sb_idx); */ + DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", + poll ? "polling" : "waiting", state, idx); might_sleep(); @@ -6136,7 +6135,6 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, } - /* timeout! */ BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx); return -EBUSY; @@ -6146,7 +6144,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, static int bnx2x_setup_leading(struct bnx2x *bp) { - /* reset IGU staae */ + /* reset IGU state */ bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, 0, IGU_INT_ENABLE, 0); /* SETUP ramrod */ @@ -6196,18 +6194,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) rc = FW_MSG_CODE_DRV_LOAD_COMMON; } - DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues); - /* if we can't use msix we only need one fp, * so try to enable msix with the requested number of fp's * and fallback to inta with one fp */ if (req_irq) { - if (use_inta) { bp->num_queues = 1; } else { - if (use_multi > 1 && use_multi <= 16) + if ((use_multi > 1) && (use_multi <= 16)) /* user requested number */ bp->num_queues = use_multi; else if (use_multi == 1) @@ -6216,15 +6211,17 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) bp->num_queues = 1; if (bnx2x_enable_msix(bp)) { - /* faild to enable msix */ + /* failed to enable msix */ bp->num_queues = 1; if (use_multi) - BNX2X_ERR("Muti requested but failed" + BNX2X_ERR("Multi requested but failed" " to enable MSI-X\n"); } } } + DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues); + if (bnx2x_alloc_mem(bp)) return -ENOMEM; @@ -6257,12 +6254,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) atomic_set(&bp->intr_sem, 0); - /* Reenable SP tasklet */ - /*if (bp->sp_task_en) { */ - /* tasklet_enable(&bp->sp_task);*/ - /*} else { */ - /* bp->sp_task_en = 1; */ - /*} */ /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp); @@ -6401,14 +6392,14 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index) int rc; - /* halt the connnection */ + /* halt the connection */ bp->fp[index].state = BNX2X_FP_STATE_HALTING; bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0); rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, &(bp->fp[index].state), 1); - if (rc) /* timout */ + if (rc) /* timeout */ return rc; /* delete cfc entry */ @@ -6423,7 +6414,7 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index) static void bnx2x_stop_leading(struct bnx2x *bp) { - /* if the other port is hadling traffic, + /* if the other port is handling traffic, this can take a lot of time */ int timeout = 500; @@ -6471,7 +6462,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) msleep(1); /* Delete the timer: do it before disabling interrupts, as it - may be stil STAT_QUERY ramrod pending after stopping the timer */ + may be still STAT_QUERY ramrod pending after stopping the timer */ del_timer_sync(&bp->timer); /* Wait until stat ramrod returns and all SP tasks complete */ @@ -6932,7 +6923,7 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, validity_map[port]); if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) BNX2X_ERR("MCP validity signature bad\n"); bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) & @@ -7452,13 +7443,13 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf, if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { DP(NETIF_MSG_NVM, - "Invalid paramter: offset 0x%x buf_size 0x%x\n", + "Invalid parameter: offset 0x%x buf_size 0x%x\n", offset, buf_size); return -EINVAL; } if (offset + buf_size > bp->flash_size) { - DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +" " buf_size (0x%x) > flash_size (0x%x)\n", offset, buf_size, bp->flash_size); return -EINVAL; @@ -7568,7 +7559,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf, u32 val; if (offset + buf_size > bp->flash_size) { - DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +" " buf_size (0x%x) > flash_size (0x%x)\n", offset, buf_size, bp->flash_size); return -EINVAL; @@ -7621,13 +7612,13 @@ static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf, if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { DP(NETIF_MSG_NVM, - "Invalid paramter: offset 0x%x buf_size 0x%x\n", + "Invalid parameter: offset 0x%x buf_size 0x%x\n", offset, buf_size); return -EINVAL; } if (offset + buf_size > bp->flash_size) { - DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +" " buf_size (0x%x) > flash_size (0x%x)\n", offset, buf_size, bp->flash_size); return -EINVAL; @@ -8314,7 +8305,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) ETH_TX_BD_ETH_ADDR_TYPE_SHIFT); tx_bd->general_data |= 1; /* header nbd */ - /* remeber the first bd of the packet */ + /* remember the first bd of the packet */ tx_buf->first_bd = bd_prod; DP(NETIF_MSG_TX_QUEUED, @@ -8427,7 +8418,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_bd->vlan = cpu_to_le16(pkt_prod); /* this marks the bd * as one that has no individual mapping - * the FW ignors this flag in a bd not maked start + * the FW ignores this flag in a bd not marked start */ tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO; DP(NETIF_MSG_TX_QUEUED, @@ -8584,7 +8575,7 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIPHY: data->phy_id = bp->phy_addr; - /* fallthru */ + /* fallthrough */ case SIOCGMIIREG: { u32 mii_regval; @@ -8633,7 +8624,7 @@ static int bnx2x_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; /* This does not race with packet allocation - * because the actuall alloc size is + * because the actual alloc size is * only updated as part of load */ dev->mtu = new_mtu; @@ -8813,7 +8804,7 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev, bnx2x_get_hwinfo(bp); if (CHIP_REV(bp) == CHIP_REV_FPGA) { - printk(KERN_ERR PFX "FPGA detacted. MCP disabled," + printk(KERN_ERR PFX "FPGA detected. MCP disabled," " will only init first device\n"); onefunc = 1; nomcp = 1; @@ -8944,7 +8935,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, rc = register_netdev(dev); if (rc) { - printk(KERN_ERR PFX "Cannot register net device\n"); + dev_err(&pdev->dev, "Cannot register net device\n"); if (bp->regview) iounmap(bp->regview); if (bp->doorbells) diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 4f7ae6f77452..7a01668e3978 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -517,7 +517,7 @@ struct bnx2x { */ u8 stat_pending; - /* End of fileds used in the performance code paths */ + /* End of fields used in the performance code paths */ int panic; int msglevel; From 250479504ff7d7e8c7d5cf85bedd40fb8d725429 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:50:16 -0800 Subject: [PATCH 808/880] [BNX2X]: Correct init_one() Correct PCI-E info printed by init_one() In one case it failed to free the netdev. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 41 ++++++++++++++++++++++++++--------------- drivers/net/bnx2x.h | 5 +++++ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 7b2d7898f06d..77867161968b 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -8873,14 +8873,32 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev, return rc; } +static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL); + + val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT; + return val; +} + +/* return value of 1=2.5GHz 2=5GHz */ +static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL); + + val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; + return val; +} + static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int version_printed; struct net_device *dev = NULL; struct bnx2x *bp; - int rc, i; + int rc; int port = PCI_FUNC(pdev->devfn); + DECLARE_MAC_BUF(mac); if (version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -8897,6 +8915,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, if (port && onefunc) { printk(KERN_ERR PFX "second function disabled. exiting\n"); + free_netdev(dev); return 0; } @@ -8950,22 +8969,14 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); bp->name = board_info[ent->driver_data].name; - printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz " - "found at mem %lx, IRQ %d, ", - dev->name, bp->name, + printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx," + " IRQ %d, ", dev->name, bp->name, ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', ((CHIP_ID(bp) & 0x0ff0) >> 4), - ((bp->flags & PCIX_FLAG) ? "-X" : ""), - ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), - bp->bus_speed_mhz, - dev->base_addr, - bp->pdev->irq); - - printk("node addr "); - for (i = 0; i < 6; i++) - printk("%2.2x", dev->dev_addr[i]); - printk("\n"); - + bnx2x_get_pcie_width(bp), + (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz", + dev->base_addr, bp->pdev->irq); + printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr)); return 0; } diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 7a01668e3978..ea9100855c5c 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -867,6 +867,11 @@ struct bnx2x { DPM_TRIGER_TYPE); \ } while (0) +/* PCIE link and speed */ +#define PCICFG_LINK_WIDTH 0x1f00000 +#define PCICFG_LINK_WIDTH_SHIFT 20 +#define PCICFG_LINK_SPEED 0xf0000 +#define PCICFG_LINK_SPEED_SHIFT 16 /* stuff added to make the code fit 80Col */ From f14106478e372e64be54a3cdab1e2fa83a5c8a35 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:51:50 -0800 Subject: [PATCH 809/880] [BNX2X]: Correct Link management Properly protect PHY access between two devices on the same board with a HW lock. Use GPIO to clear all previous configurations before changing link parameters. Shut down the external PHY in case of fan failure. Reducing the MDC/MDIO clock to 2.5MHz due to problems with some devices. Resolve the flow control response according to autoneg with external PHY. Unmasking all PHY interrupts in single write to prevent a race in the interrupts order. LASI indication fixes to work with peculiarities of PHYs. Disable MAC RX to avoid a HW bug when closing the MAC under traffic. Disable parallel detection on HiGig due to HW limitation. Updating the shared memory structure to work with the current bootcode. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 1711 ++++++++++++++++++++++++++--------- drivers/net/bnx2x.h | 34 +- drivers/net/bnx2x_fw_defs.h | 2 +- drivers/net/bnx2x_hsi.h | 428 +++++---- drivers/net/bnx2x_reg.h | 212 ++++- 5 files changed, 1736 insertions(+), 651 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 77867161968b..5cd785064ba3 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -1,6 +1,6 @@ /* bnx2x.c: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * 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 @@ -65,7 +65,7 @@ #define DRV_MODULE_VERSION "0.40.15" #define DRV_MODULE_RELDATE "$DateTime: 2007/11/15 07:28:37 $" -#define BNX2X_BC_VER 0x040009 +#define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (5*HZ) @@ -78,7 +78,7 @@ MODULE_AUTHOR("Eliezer Tamir "); MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); -MODULE_INFO(cvs_version, "$Revision: #356 $"); +MODULE_INFO(cvs_version, "$Revision: #404 $"); static int use_inta; static int poll; @@ -1181,12 +1181,175 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) return val; } +static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource) +{ + u32 cnt; + u32 lock_status; + u32 resource_bit = (1 << resource); + u8 func = bp->port; + + /* Validating that the resource is within range */ + if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { + DP(NETIF_MSG_HW, + "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", + resource, HW_LOCK_MAX_RESOURCE_VALUE); + return -EINVAL; + } + + /* Validating that the resource is not already taken */ + lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8); + if (lock_status & resource_bit) { + DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", + lock_status, resource_bit); + return -EEXIST; + } + + /* Try for 1 second every 5ms */ + for (cnt = 0; cnt < 200; cnt++) { + /* Try to acquire the lock */ + REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8 + 4, + resource_bit); + lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8); + if (lock_status & resource_bit) + return 0; + + msleep(5); + } + DP(NETIF_MSG_HW, "Timeout\n"); + return -EAGAIN; +} + +static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource) +{ + u32 lock_status; + u32 resource_bit = (1 << resource); + u8 func = bp->port; + + /* Validating that the resource is within range */ + if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { + DP(NETIF_MSG_HW, + "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", + resource, HW_LOCK_MAX_RESOURCE_VALUE); + return -EINVAL; + } + + /* Validating that the resource is currently taken */ + lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8); + if (!(lock_status & resource_bit)) { + DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", + lock_status, resource_bit); + return -EFAULT; + } + + REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8, resource_bit); + return 0; +} + +static int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode) +{ + /* The GPIO should be swapped if swap register is set and active */ + int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && + REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port; + int gpio_shift = gpio_num + + (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); + u32 gpio_mask = (1 << gpio_shift); + u32 gpio_reg; + + if (gpio_num > MISC_REGISTERS_GPIO_3) { + BNX2X_ERR("Invalid GPIO %d\n", gpio_num); + return -EINVAL; + } + + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); + /* read GPIO and mask except the float bits */ + gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT); + + switch (mode) { + case MISC_REGISTERS_GPIO_OUTPUT_LOW: + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n", + gpio_num, gpio_shift); + /* clear FLOAT and set CLR */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS); + break; + + case MISC_REGISTERS_GPIO_OUTPUT_HIGH: + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n", + gpio_num, gpio_shift); + /* clear FLOAT and set SET */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS); + break; + + case MISC_REGISTERS_GPIO_INPUT_HI_Z : + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n", + gpio_num, gpio_shift); + /* set FLOAT */ + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + break; + + default: + break; + } + + REG_WR(bp, MISC_REG_GPIO, gpio_reg); + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO); + + return 0; +} + +static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) +{ + u32 spio_mask = (1 << spio_num); + u32 spio_reg; + + if ((spio_num < MISC_REGISTERS_SPIO_4) || + (spio_num > MISC_REGISTERS_SPIO_7)) { + BNX2X_ERR("Invalid SPIO %d\n", spio_num); + return -EINVAL; + } + + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); + /* read SPIO and mask except the float bits */ + spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT); + + switch (mode) { + case MISC_REGISTERS_SPIO_OUTPUT_LOW : + DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num); + /* clear FLOAT and set CLR */ + spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS); + break; + + case MISC_REGISTERS_SPIO_OUTPUT_HIGH : + DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num); + /* clear FLOAT and set SET */ + spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS); + break; + + case MISC_REGISTERS_SPIO_INPUT_HI_Z: + DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num); + /* set FLOAT */ + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + break; + + default: + break; + } + + REG_WR(bp, MISC_REG_SPIO, spio_reg); + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO); + + return 0; +} + static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val) { - int rc; - u32 tmp, i; int port = bp->port; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 tmp; + int i, rc; /* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x val 0x%08x\n", bp->phy_addr, reg, val); */ @@ -1238,8 +1401,8 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val) { int port = bp->port; u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 val, i; - int rc; + u32 val; + int i, rc; if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { @@ -1288,58 +1451,54 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val) return rc; } -static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val) +static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl, + u32 phy_addr, u32 reg, u32 addr, u32 val) { - int rc = 0; - u32 tmp, i; - int port = bp->port; - u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { - - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - tmp &= ~EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); - REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - udelay(40); - } + u32 tmp; + int i, rc = 0; - /* set clause 45 mode */ - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - tmp |= EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + /* set clause 45 mode, slow down the MDIO clock to 2.5MHz + * (a value of 49==0x31) and make sure that the AUTO poll is off + */ + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + tmp &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT); + tmp |= (EMAC_MDIO_MODE_CLAUSE_45 | + (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); + REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); /* address */ - tmp = ((bp->phy_addr << 21) | (reg << 16) | addr | + tmp = ((phy_addr << 21) | (reg << 16) | addr | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; } } - if (tmp & EMAC_MDIO_COMM_START_BUSY) { BNX2X_ERR("write phy register failed\n"); rc = -EBUSY; + } else { /* data */ - tmp = ((bp->phy_addr << 21) | (reg << 16) | val | + tmp = ((phy_addr << 21) | (reg << 16) | val | EMAC_MDIO_COMM_COMMAND_WRITE_45 | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -1353,75 +1512,78 @@ static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val) } } - /* unset clause 45 mode */ - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - tmp &= ~EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); - - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { - - tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + /* unset clause 45 mode, set the MDIO clock to a faster value + * (0x13 => 6.25Mhz) and restore the AUTO poll if needed + */ + tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + tmp &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT); + tmp |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) tmp |= EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); - } + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); return rc; } -static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr, - u32 *ret_val) +static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg, + u32 addr, u32 val) { - int port = bp->port; - u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 val, i; - int rc = 0; + u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr, + reg, addr, val); +} - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - val &= ~EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); - REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - udelay(40); - } +static int bnx2x_mdio45_ctrl_read(struct bnx2x *bp, u32 mdio_ctrl, + u32 phy_addr, u32 reg, u32 addr, + u32 *ret_val) +{ + u32 val; + int i, rc = 0; - /* set clause 45 mode */ - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - val |= EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + /* set clause 45 mode, slow down the MDIO clock to 2.5MHz + * (a value of 49==0x31) and make sure that the AUTO poll is off + */ + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + val &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT); + val |= (EMAC_MDIO_MODE_CLAUSE_45 | + (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); + REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); /* address */ - val = ((bp->phy_addr << 21) | (reg << 16) | addr | + val = ((phy_addr << 21) | (reg << 16) | addr | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; } } - if (val & EMAC_MDIO_COMM_START_BUSY) { BNX2X_ERR("read phy register failed\n"); *ret_val = 0; rc = -EBUSY; + } else { /* data */ - val = ((bp->phy_addr << 21) | (reg << 16) | + val = ((phy_addr << 21) | (reg << 16) | EMAC_MDIO_COMM_COMMAND_READ_45 | EMAC_MDIO_COMM_START_BUSY); - EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { val &= EMAC_MDIO_COMM_DATA; break; @@ -1438,31 +1600,39 @@ static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr, *ret_val = val; } - /* unset clause 45 mode */ - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); - val &= ~EMAC_MDIO_MODE_CLAUSE_45; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); - - if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { - - val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + /* unset clause 45 mode, set the MDIO clock to a faster value + * (0x13 => 6.25Mhz) and restore the AUTO poll if needed + */ + val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + val &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT); + val |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) val |= EMAC_MDIO_MODE_AUTO_POLL; - EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); - } + REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); return rc; } -static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val) +static int bnx2x_mdio45_read(struct bnx2x *bp, u32 phy_addr, u32 reg, + u32 addr, u32 *ret_val) +{ + u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + + return bnx2x_mdio45_ctrl_read(bp, emac_base, phy_addr, + reg, addr, ret_val); +} + +static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 phy_addr, u32 reg, + u32 addr, u32 val) { int i; u32 rd_val; might_sleep(); for (i = 0; i < 10; i++) { - bnx2x_mdio45_write(bp, reg, addr, val); + bnx2x_mdio45_write(bp, phy_addr, reg, addr, val); msleep(5); - bnx2x_mdio45_read(bp, reg, addr, &rd_val); + bnx2x_mdio45_read(bp, phy_addr, reg, addr, &rd_val); /* if the read value is not the same as the value we wrote, we should write it again */ if (rd_val == val) @@ -1476,10 +1646,73 @@ static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val) * link management */ +static void bnx2x_pause_resolve(struct bnx2x *bp, u32 pause_result) +{ + switch (pause_result) { /* ASYM P ASYM P */ + case 0xb: /* 1 0 1 1 */ + bp->flow_ctrl = FLOW_CTRL_TX; + break; + + case 0xe: /* 1 1 1 0 */ + bp->flow_ctrl = FLOW_CTRL_RX; + break; + + case 0x5: /* 0 1 0 1 */ + case 0x7: /* 0 1 1 1 */ + case 0xd: /* 1 1 0 1 */ + case 0xf: /* 1 1 1 1 */ + bp->flow_ctrl = FLOW_CTRL_BOTH; + break; + + default: + break; + } +} + +static u8 bnx2x_ext_phy_resove_fc(struct bnx2x *bp) +{ + u32 ext_phy_addr; + u32 ld_pause; /* local */ + u32 lp_pause; /* link partner */ + u32 an_complete; /* AN complete */ + u32 pause_result; + u8 ret = 0; + + ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + + /* read twice */ + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_STATUS, &an_complete); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_STATUS, &an_complete); + + if (an_complete & EXT_PHY_KR_AUTO_NEG_COMPLETE) { + ret = 1; + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_AUTO_NEG_ADVERT, &ld_pause); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_LP_AUTO_NEG, &lp_pause); + pause_result = (ld_pause & + EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 8; + pause_result |= (lp_pause & + EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 10; + DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n", + pause_result); + bnx2x_pause_resolve(bp, pause_result); + } + return ret; +} + static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status) { - u32 ld_pause; /* local driver */ - u32 lp_pause; /* link partner */ + u32 ld_pause; /* local driver */ + u32 lp_pause; /* link partner */ u32 pause_result; bp->flow_ctrl = 0; @@ -1501,45 +1734,57 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status) pause_result |= (lp_pause & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result); + bnx2x_pause_resolve(bp, pause_result); + } else if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) || + !(bnx2x_ext_phy_resove_fc(bp))) { + /* forced speed */ + if (bp->req_autoneg & AUTONEG_FLOW_CTRL) { + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + if (bp->dev->mtu <= 4500) + bp->flow_ctrl = FLOW_CTRL_BOTH; + else + bp->flow_ctrl = FLOW_CTRL_TX; + break; - switch (pause_result) { /* ASYM P ASYM P */ - case 0xb: /* 1 0 1 1 */ - bp->flow_ctrl = FLOW_CTRL_TX; - break; - - case 0xe: /* 1 1 1 0 */ - bp->flow_ctrl = FLOW_CTRL_RX; - break; + case FLOW_CTRL_TX: + bp->flow_ctrl = FLOW_CTRL_TX; + break; - case 0x5: /* 0 1 0 1 */ - case 0x7: /* 0 1 1 1 */ - case 0xd: /* 1 1 0 1 */ - case 0xf: /* 1 1 1 1 */ - bp->flow_ctrl = FLOW_CTRL_BOTH; - break; + case FLOW_CTRL_RX: + if (bp->dev->mtu <= 4500) + bp->flow_ctrl = FLOW_CTRL_RX; + break; - default: - break; - } + case FLOW_CTRL_BOTH: + if (bp->dev->mtu <= 4500) + bp->flow_ctrl = FLOW_CTRL_BOTH; + else + bp->flow_ctrl = FLOW_CTRL_TX; + break; - } else { /* forced mode */ - switch (bp->req_flow_ctrl) { - case FLOW_CTRL_AUTO: - if (bp->dev->mtu <= 4500) - bp->flow_ctrl = FLOW_CTRL_BOTH; - else - bp->flow_ctrl = FLOW_CTRL_TX; - break; + case FLOW_CTRL_NONE: + default: + break; + } + } else { /* forced mode */ + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while" + " req_autoneg 0x%x\n", + bp->req_flow_ctrl, bp->req_autoneg); + break; - case FLOW_CTRL_TX: - case FLOW_CTRL_RX: - case FLOW_CTRL_BOTH: - bp->flow_ctrl = bp->req_flow_ctrl; - break; + case FLOW_CTRL_TX: + case FLOW_CTRL_RX: + case FLOW_CTRL_BOTH: + bp->flow_ctrl = bp->req_flow_ctrl; + break; - case FLOW_CTRL_NONE: - default: - break; + case FLOW_CTRL_NONE: + default: + break; + } } } DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl); @@ -1550,9 +1795,9 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status) bp->link_status = 0; if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { - DP(NETIF_MSG_LINK, "link up\n"); + DP(NETIF_MSG_LINK, "phy link up\n"); - bp->link_up = 1; + bp->phy_link_up = 1; bp->link_status |= LINK_STATUS_LINK_UP; if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) @@ -1661,20 +1906,20 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status) bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED; } else { /* link_down */ - DP(NETIF_MSG_LINK, "link down\n"); + DP(NETIF_MSG_LINK, "phy link down\n"); - bp->link_up = 0; + bp->phy_link_up = 0; bp->line_speed = 0; bp->duplex = DUPLEX_FULL; bp->flow_ctrl = 0; } - DP(NETIF_MSG_LINK, "gp_status 0x%x link_up %d\n" + DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %d\n" DP_LEVEL " line_speed %d duplex %d flow_ctrl 0x%x" " link_status 0x%x\n", - gp_status, bp->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl, - bp->link_status); + gp_status, bp->phy_link_up, bp->line_speed, bp->duplex, + bp->flow_ctrl, bp->link_status); } static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g) @@ -1684,38 +1929,38 @@ static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g) /* first reset all status * we assume only one line will be change at a time */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_XGXS0_LINK_STATUS | - NIG_SERDES0_LINK_STATUS | - NIG_STATUS_INTERRUPT_XGXS0_LINK10G)); - if (bp->link_up) { + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS)); + if (bp->phy_link_up) { if (is_10g) { /* Disable the 10G link interrupt * by writing 1 to the status register */ - DP(NETIF_MSG_LINK, "10G XGXS link up\n"); + DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); bnx2x_bits_en(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_INTERRUPT_XGXS0_LINK10G); + NIG_STATUS_XGXS0_LINK10G); } else if (bp->phy_flags & PHY_XGXS_FLAG) { /* Disable the link interrupt * by writing 1 to the relevant lane * in the status register */ - DP(NETIF_MSG_LINK, "1G XGXS link up\n"); + DP(NETIF_MSG_LINK, "1G XGXS phy link up\n"); bnx2x_bits_en(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, ((1 << bp->ser_lane) << - NIG_XGXS0_LINK_STATUS_SIZE)); + NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); } else { /* SerDes */ - DP(NETIF_MSG_LINK, "SerDes link up\n"); + DP(NETIF_MSG_LINK, "SerDes phy link up\n"); /* Disable the link interrupt * by writing 1 to the status register */ bnx2x_bits_en(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_SERDES0_LINK_STATUS); + NIG_STATUS_SERDES0_LINK_STATUS); } } else { /* link_down */ @@ -1726,91 +1971,182 @@ static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp) { u32 ext_phy_type; u32 ext_phy_addr; - u32 local_phy; - u32 val = 0; + u32 val1 = 0, val2; u32 rx_sd, pcs_status; if (bp->phy_flags & PHY_XGXS_FLAG) { - local_phy = bp->phy_addr; ext_phy_addr = ((bp->ext_phy_config & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); - bp->phy_addr = (u8)ext_phy_addr; ext_phy_type = XGXS_EXT_PHY_TYPE(bp); switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "XGXS Direct\n"); - val = 1; + val1 = 1; break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_WIS_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_WIS_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PMD_RX_SD, &rx_sd); - val = (rx_sd & 0x1); + DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd); + val1 = (rx_sd & 0x1); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: DP(NETIF_MSG_LINK, "XGXS 8706\n"); - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, - EXT_PHY_OPT_LASI_STATUS, &val); - DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val); - - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1); + + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PMD_RX_SD, &rx_sd); - bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD, - EXT_PHY_OPT_PCS_STATUS, &pcs_status); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PCS_DEVAD, + EXT_PHY_OPT_PCS_STATUS, &pcs_status); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_LINK_STATUS, &val2); + DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x" - " pcs_status 0x%x\n", rx_sd, pcs_status); - /* link is up if both bit 0 of pmd_rx and - * bit 0 of pcs_status are set + " pcs_status 0x%x 1Gbps link_status 0x%x 0x%x\n", + rx_sd, pcs_status, val2, (val2 & (1<<1))); + /* link is up if both bit 0 of pmd_rx_sd and + * bit 0 of pcs_status are set, or if the autoneg bit + 1 is set + */ + val1 = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO); + + /* clear the interrupt LASI status register */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PCS_DEVAD, + EXT_PHY_KR_LASI_STATUS, &val2); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PCS_DEVAD, + EXT_PHY_KR_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "KR LASI status 0x%x->0x%x\n", + val2, val1); + /* Check the LASI */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0x9003, &val2); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0x9003, &val1); + DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n", + val2, val1); + /* Check the link status */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PCS_DEVAD, + EXT_PHY_KR_PCS_STATUS, &val2); + DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); + /* Check the link status on 1.1.2 */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val2); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val1); + DP(NETIF_MSG_LINK, + "KR PMA status 0x%x->0x%x\n", val2, val1); + val1 = ((val1 & 4) == 4); + /* If 1G was requested assume the link is up */ + if (!(bp->req_autoneg & AUTONEG_SPEED) && + (bp->req_line_speed == SPEED_1000)) + val1 = 1; + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val2); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, + "10G-base-T LASI status 0x%x->0x%x\n", val2, val1); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val2); + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_KR_STATUS, &val1); + DP(NETIF_MSG_LINK, + "10G-base-T PMA status 0x%x->0x%x\n", val2, val1); + val1 = ((val1 & 4) == 4); + /* if link is up + * print the AN outcome of the SFX7101 PHY */ - val = (rx_sd & pcs_status); + if (val1) { + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0x21, &val2); + DP(NETIF_MSG_LINK, + "SFX7101 AN status 0x%x->%s\n", val2, + (val2 & (1<<14)) ? "Master" : "Slave"); + } break; default: DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", bp->ext_phy_config); - val = 0; + val1 = 0; break; } - bp->phy_addr = local_phy; } else { /* SerDes */ ext_phy_type = SERDES_EXT_PHY_TYPE(bp); switch (ext_phy_type) { case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "SerDes Direct\n"); - val = 1; + val1 = 1; break; case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: DP(NETIF_MSG_LINK, "SerDes 5482\n"); - val = 1; + val1 = 1; break; default: DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", bp->ext_phy_config); - val = 0; + val1 = 0; break; } } - return val; + return val1; } static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb) @@ -1935,6 +2271,35 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb) bp->stats_state = STATS_STATE_ENABLE; } +static void bnx2x_bmac_rx_disable(struct bnx2x *bp) +{ + int port = bp->port; + u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 wb_write[2]; + + /* Only if the bmac is out of reset */ + if (REG_RD(bp, MISC_REG_RESET_REG_2) & + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)) { + /* Clear Rx Enable bit in BMAC_CONTROL register */ +#ifdef BNX2X_DMAE_RD + bnx2x_read_dmae(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, 2); + wb_write[0] = *bnx2x_sp(bp, wb_data[0]); + wb_write[1] = *bnx2x_sp(bp, wb_data[1]); +#else + wb_write[0] = REG_RD(bp, + bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL); + wb_write[1] = REG_RD(bp, + bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL + 4); +#endif + wb_write[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, + wb_write, 2); + msleep(1); + } +} + static void bnx2x_emac_enable(struct bnx2x *bp) { int port = bp->port; @@ -2233,7 +2598,7 @@ static void bnx2x_pbf_update(struct bnx2x *bp) static void bnx2x_update_mng(struct bnx2x *bp) { if (!nomcp) - SHMEM_WR(bp, drv_fw_mb[bp->port].link_status, + SHMEM_WR(bp, port_mb[bp->port].link_status, bp->link_status); } @@ -2295,19 +2660,19 @@ static void bnx2x_link_down(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - STOP\n"); } - /* indicate link down */ + /* indicate no mac active */ bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG); - /* reset BigMac */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + /* update shared memory */ + bnx2x_update_mng(bp); - /* ignore drain flag interrupt */ /* activate nig drain */ NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - /* update shared memory */ - bnx2x_update_mng(bp); + /* reset BigMac */ + bnx2x_bmac_rx_disable(bp); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); /* indicate link down */ bnx2x_link_report(bp); @@ -2318,14 +2683,15 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp); /* This function is called upon link interrupt */ static void bnx2x_link_update(struct bnx2x *bp) { - u32 gp_status; int port = bp->port; int i; + u32 gp_status; int link_10g; - DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x," + DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x," " int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x," - " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG), + " 10G %x, XGXS_LINK %x\n", port, + (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes", REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4), REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask, REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), @@ -2337,7 +2703,7 @@ static void bnx2x_link_update(struct bnx2x *bp) might_sleep(); MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS); /* avoid fast toggling */ - for (i = 0 ; i < 10 ; i++) { + for (i = 0; i < 10; i++) { msleep(10); bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); @@ -2352,7 +2718,8 @@ static void bnx2x_link_update(struct bnx2x *bp) bnx2x_link_int_ack(bp, link_10g); /* link is up only if both local phy and external phy are up */ - if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) { + bp->link_up = (bp->phy_link_up && bnx2x_ext_phy_is_link_up(bp)); + if (bp->link_up) { if (link_10g) { bnx2x_bmac_enable(bp, 0); bnx2x_leds_set(bp, SPEED_10000); @@ -2428,7 +2795,9 @@ static void bnx2x_reset_unicore(struct bnx2x *bp) } } - BNX2X_ERR("BUG! unicore is still in reset!\n"); + BNX2X_ERR("BUG! %s (0x%x) is still in reset!\n", + (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes", + bp->phy_addr); } static void bnx2x_set_swap_lanes(struct bnx2x *bp) @@ -2476,12 +2845,12 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp) MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT); bnx2x_mdio22_write(bp, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); bnx2x_mdio22_read(bp, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, - &control2); + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + &control2); if (bp->autoneg & AUTONEG_PARALLEL) { control2 |= @@ -2491,8 +2860,14 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp) ~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; } bnx2x_mdio22_write(bp, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, - control2); + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + control2); + + /* Disable parallel detection of HiG */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2); + bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, + MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | + MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS); } } @@ -2626,7 +3001,7 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp) MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G); /* set extended capabilities */ - if (bp->advertising & ADVERTISED_2500baseT_Full) + if (bp->advertising & ADVERTISED_2500baseX_Full) val |= MDIO_OVER_1G_UP1_2_5G; if (bp->advertising & ADVERTISED_10000baseT_Full) val |= MDIO_OVER_1G_UP1_10G; @@ -2639,23 +3014,94 @@ static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp) { u32 an_adv; - /* for AN, we are always publishing full duplex */ - an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; + /* for AN, we are always publishing full duplex */ + an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; + + /* resolve pause mode and advertisement + * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ + if (bp->req_autoneg & AUTONEG_FLOW_CTRL) { + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + if (bp->dev->mtu <= 4500) { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + } + break; + + case FLOW_CTRL_TX: + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + break; + + case FLOW_CTRL_RX: + if (bp->dev->mtu <= 4500) { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } + break; + + case FLOW_CTRL_BOTH: + if (bp->dev->mtu <= 4500) { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + } + break; + + case FLOW_CTRL_NONE: + default: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + } + } else { /* forced mode */ + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while" + " req_autoneg 0x%x\n", + bp->req_flow_ctrl, bp->req_autoneg); + break; + + case FLOW_CTRL_TX: + an_adv |= + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + break; + + case FLOW_CTRL_RX: + case FLOW_CTRL_BOTH: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; - /* set pause */ - switch (bp->pause_mode) { - case PAUSE_SYMMETRIC: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; - break; - case PAUSE_ASYMMETRIC: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; - break; - case PAUSE_BOTH: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; - break; - case PAUSE_NONE: - an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; - break; + case FLOW_CTRL_NONE: + default: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + } } MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); @@ -2753,47 +3199,162 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x *bp) static void bnx2x_link_int_enable(struct bnx2x *bp) { int port = bp->port; + u32 ext_phy_type; + u32 mask; /* setting the status to report on link up for either XGXS or SerDes */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_XGXS0_LINK_STATUS | - NIG_STATUS_INTERRUPT_XGXS0_LINK10G | - NIG_SERDES0_LINK_STATUS)); + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS)); if (bp->phy_flags & PHY_XGXS_FLAG) { - /* TBD - - * in force mode (not AN) we can enable just the relevant - * interrupt - * Even in AN we might enable only one according to the AN - * speed mask - */ - bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G)); - DP(NETIF_MSG_LINK, "enable XGXS interrupt\n"); + mask = (NIG_MASK_XGXS0_LINK10G | + NIG_MASK_XGXS0_LINK_STATUS); + DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); + ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && + (ext_phy_type != + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); + } } else { /* SerDes */ - bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_SERDES0_LINK_STATUS); - DP(NETIF_MSG_LINK, "enable SerDes interrupt\n"); + mask = NIG_MASK_SERDES0_LINK_STATUS; + DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); + ext_phy_type = SERDES_EXT_PHY_TYPE(bp); + if ((ext_phy_type != + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && + (ext_phy_type != + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); + } } + bnx2x_bits_en(bp, + NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + mask); + DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x," + " int_mask 0x%x, MI_INT %x, SERDES_LINK %x," + " 10G %x, XGXS_LINK %x\n", port, + (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes", + REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4), + REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), + REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), + REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68) + ); +} + +static void bnx2x_bcm8072_external_rom_boot(struct bnx2x *bp) +{ + u32 ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + u32 fw_ver1, fw_ver2; + + /* Need to wait 200ms after reset */ + msleep(200); + /* Boot port from external ROM + * Set ser_boot_ctl bit in the MISC_CTRL1 register + */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + EXT_PHY_KR_MISC_CTRL1, 0x0001); + + /* Reset internal microprocessor */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL, + EXT_PHY_KR_ROM_RESET_INTERNAL_MP); + /* set micro reset = 0 */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL, + EXT_PHY_KR_ROM_MICRO_RESET); + /* Reset internal microprocessor */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL, + EXT_PHY_KR_ROM_RESET_INTERNAL_MP); + /* wait for 100ms for code download via SPI port */ + msleep(100); + + /* Clear ser_boot_ctl bit */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + EXT_PHY_KR_MISC_CTRL1, 0x0000); + /* Wait 100ms */ + msleep(100); + + /* Print the PHY FW version */ + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0xca19, &fw_ver1); + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0xca1a, &fw_ver2); + DP(NETIF_MSG_LINK, + "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2); +} + +static void bnx2x_bcm8072_force_10G(struct bnx2x *bp) +{ + u32 ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + + /* Force KR or KX */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL, + 0x2040); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL2, + 0x000b); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_PMD_CTRL, + 0x0000); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, EXT_PHY_KR_CTRL, + 0x0000); } static void bnx2x_ext_phy_init(struct bnx2x *bp) { - int port = bp->port; u32 ext_phy_type; u32 ext_phy_addr; - u32 local_phy; + u32 cnt; + u32 ctrl; + u32 val = 0; if (bp->phy_flags & PHY_XGXS_FLAG) { - local_phy = bp->phy_addr; ext_phy_addr = ((bp->ext_phy_config & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + /* Make sure that the soft reset is off (expect for the 8072: + * due to the lock, it will be done inside the specific + * handling) + */ + if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)) { + /* Wait for soft reset to get cleared upto 1 sec */ + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL, &ctrl); + if (!(ctrl & (1<<15))) + break; + msleep(1); + } + DP(NETIF_MSG_LINK, + "control reg 0x%x (after %d ms)\n", ctrl, cnt); + } + switch (ext_phy_type) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: DP(NETIF_MSG_LINK, "XGXS Direct\n"); @@ -2801,49 +3362,235 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled external phy int\n"); - bp->phy_addr = ext_phy_type; - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PMD_MISC_CNTL, 0x8288); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_PHY_IDENTIFIER, 0x7fbf); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_CMU_PLL_BYPASS, 0x0100); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD, + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_WIS_DEVAD, EXT_PHY_OPT_LASI_CNTL, 0x1); break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: DP(NETIF_MSG_LINK, "XGXS 8706\n"); - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled external phy int\n"); - bp->phy_addr = ext_phy_type; - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, - EXT_PHY_OPT_PMD_DIGITAL_CNT, - 0x400); - bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + if (!(bp->req_autoneg & AUTONEG_SPEED)) { + /* Force speed */ + if (bp->req_line_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, + "XGXS 8706 force 10Gbps\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_PMD_DIGITAL_CNT, + 0x400); + } else { + /* Force 1Gbps */ + DP(NETIF_MSG_LINK, + "XGXS 8706 force 1Gbps\n"); + + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL, + 0x0040); + + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL2, + 0x000D); + } + + /* Enable LASI */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_CNTL, + 0x1); + } else { + /* AUTONEG */ + /* Allow CL37 through CL73 */ + DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_CL37_CL73, + 0x040c); + + /* Enable Full-Duplex advertisment on CL37 */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_CL37_FD, + 0x0020); + /* Enable CL37 AN */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_CL37_AN, + 0x1000); + /* Advertise 10G/1G support */ + if (bp->advertising & + ADVERTISED_1000baseT_Full) + val = (1<<5); + if (bp->advertising & + ADVERTISED_10000baseT_Full) + val |= (1<<7); + + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_AN_ADV, val); + /* Enable LASI */ + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_CNTL, + 0x1); + + /* Enable clause 73 AN */ + bnx2x_mdio45_write(bp, ext_phy_addr, + EXT_PHY_AUTO_NEG_DEVAD, + EXT_PHY_OPT_CNTL, + 0x1200); + } + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO); + /* Wait for soft reset to get cleared upto 1 sec */ + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL, &ctrl); + if (!(ctrl & (1<<15))) + break; + msleep(1); + } + DP(NETIF_MSG_LINK, + "8072 control reg 0x%x (after %d ms)\n", + ctrl, cnt); + + bnx2x_bcm8072_external_rom_boot(bp); + DP(NETIF_MSG_LINK, "Finshed loading 8072 KR ROM\n"); + + /* enable LASI */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0x9000, 0x0400); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + EXT_PHY_KR_LASI_CNTL, 0x0004); + + /* If this is forced speed, set to KR or KX + * (all other are not supported) + */ + if (!(bp->req_autoneg & AUTONEG_SPEED)) { + if (bp->req_line_speed == SPEED_10000) { + bnx2x_bcm8072_force_10G(bp); + DP(NETIF_MSG_LINK, + "Forced speed 10G on 8072\n"); + /* unlock */ + bnx2x_hw_unlock(bp, + HW_LOCK_RESOURCE_8072_MDIO); + break; + } else + val = (1<<5); + } else { + + /* Advertise 10G/1G support */ + if (bp->advertising & + ADVERTISED_1000baseT_Full) + val = (1<<5); + if (bp->advertising & + ADVERTISED_10000baseT_Full) + val |= (1<<7); + } + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0x11, val); + /* Add support for CL37 ( passive mode ) I */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0x8370, 0x040c); + /* Add support for CL37 ( passive mode ) II */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0xffe4, 0x20); + /* Add support for CL37 ( passive mode ) III */ + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + 0xffe0, 0x1000); + /* Restart autoneg */ + msleep(500); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_CTRL, 0x1200); + DP(NETIF_MSG_LINK, "8072 Autoneg Restart: " + "1G %ssupported 10G %ssupported\n", + (val & (1<<5)) ? "" : "not ", + (val & (1<<7)) ? "" : "not "); + + /* unlock */ + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + DP(NETIF_MSG_LINK, + "Setting the SFX7101 LASI indication\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_LASI_CNTL, 0x1); + DP(NETIF_MSG_LINK, + "Setting the SFX7101 LED to blink on traffic\n"); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, + 0xC007, (1<<3)); + + /* read modify write pause advertizing */ + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_AUTO_NEG_ADVERT, &val); + val &= ~EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH; + /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ + if (bp->advertising & ADVERTISED_Pause) + val |= EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE; + + if (bp->advertising & ADVERTISED_Asym_Pause) { + val |= + EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC; + } + DP(NETIF_MSG_LINK, "SFX7101 AN advertize 0x%x\n", val); + bnx2x_mdio45_vwrite(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_AUTO_NEG_ADVERT, val); + /* Restart autoneg */ + bnx2x_mdio45_read(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_CTRL, &val); + val |= 0x200; + bnx2x_mdio45_write(bp, ext_phy_addr, + EXT_PHY_KR_AUTO_NEG_DEVAD, + EXT_PHY_KR_CTRL, val); break; default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - bp->ext_phy_config); + BNX2X_ERR("BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); break; } - bp->phy_addr = local_phy; } else { /* SerDes */ -/* ext_phy_addr = ((bp->ext_phy_config & +/* ext_phy_addr = ((bp->ext_phy_config & PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT); */ @@ -2855,10 +3602,6 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: DP(NETIF_MSG_LINK, "SerDes 5482\n"); - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - NIG_MASK_MI_INT); - DP(NETIF_MSG_LINK, "enabled external phy int\n"); break; default: @@ -2872,8 +3615,22 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp) static void bnx2x_ext_phy_reset(struct bnx2x *bp) { u32 ext_phy_type; - u32 ext_phy_addr; - u32 local_phy; + u32 ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK); + + /* The PHY reset is controled by GPIO 1 + * Give it 1ms of reset pulse + */ + if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) && + (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) { + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH); + } if (bp->phy_flags & PHY_XGXS_FLAG) { ext_phy_type = XGXS_EXT_PHY_TYPE(bp); @@ -2884,15 +3641,24 @@ static void bnx2x_ext_phy_reset(struct bnx2x *bp) case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - DP(NETIF_MSG_LINK, "XGXS 8705/6\n"); - local_phy = bp->phy_addr; - ext_phy_addr = ((bp->ext_phy_config & - PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> - PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); - bp->phy_addr = (u8)ext_phy_addr; - bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + DP(NETIF_MSG_LINK, "XGXS 8705/8706\n"); + bnx2x_mdio45_write(bp, ext_phy_addr, + EXT_PHY_OPT_PMA_PMD_DEVAD, EXT_PHY_OPT_CNTL, 0xa040); - bp->phy_addr = local_phy; + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + DP(NETIF_MSG_LINK, "XGXS 8072\n"); + bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO); + bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, + ext_phy_addr, + EXT_PHY_KR_PMA_PMD_DEVAD, + 0, 1<<15); + bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + DP(NETIF_MSG_LINK, "XGXS SFX7101\n"); break; default: @@ -2931,6 +3697,7 @@ static void bnx2x_link_initialize(struct bnx2x *bp) NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); + /* Activate the external PHY */ bnx2x_ext_phy_reset(bp); bnx2x_set_aer_mmd(bp); @@ -3011,11 +3778,11 @@ static void bnx2x_link_initialize(struct bnx2x *bp) bnx2x_initialize_sgmii_process(bp); } - /* enable the interrupt */ - bnx2x_link_int_enable(bp); - /* init ext phy and enable link state int */ bnx2x_ext_phy_init(bp); + + /* enable the interrupt */ + bnx2x_link_int_enable(bp); } static void bnx2x_phy_deassert(struct bnx2x *bp) @@ -3074,6 +3841,11 @@ static int bnx2x_phy_init(struct bnx2x *bp) static void bnx2x_link_reset(struct bnx2x *bp) { int port = bp->port; + u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK); + + /* update shared memory */ + bp->link_status = 0; + bnx2x_update_mng(bp); /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, @@ -3082,21 +3854,45 @@ static void bnx2x_link_reset(struct bnx2x *bp) NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); - bnx2x_ext_phy_reset(bp); + /* activate nig drain */ + NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + + /* disable nig egress interface */ + NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0); + NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + + /* Stop BigMac rx */ + bnx2x_bmac_rx_disable(bp); + + /* disable emac */ + NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0); + + msleep(10); + + /* The PHY reset is controled by GPIO 1 + * Hold it as output low + */ + if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) && + (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) { + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + DP(NETIF_MSG_LINK, "reset external PHY\n"); + } /* reset the SerDes/XGXS */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, (0x1ff << (port*16))); - /* reset EMAC / BMAC and disable NIG interfaces */ - NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0); - NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0); + /* reset BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0); + /* disable nig ingress interface */ + NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0); NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0); - NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); - NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + /* set link down */ + bp->link_up = 0; } #ifdef BNX2X_XGXS_LB @@ -3177,6 +3973,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, bnx2x_panic(); return -EBUSY; } + /* CID needs port number to be encoded int it */ bp->spq_prod_bd->hdr.conn_and_cmd_data = cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) | @@ -4335,7 +5132,7 @@ static void bnx2x_timer(unsigned long data) return; if (atomic_read(&bp->intr_sem) != 0) - goto bnx2x_restart_timer; + goto timer_restart; if (poll) { struct bnx2x_fastpath *fp = &bp->fp[0]; @@ -4345,7 +5142,7 @@ static void bnx2x_timer(unsigned long data) rc = bnx2x_rx_int(fp, 1000); } - if (!nomcp && (bp->bc_ver >= 0x040003)) { + if (!nomcp) { int port = bp->port; u32 drv_pulse; u32 mcp_pulse; @@ -4354,9 +5151,9 @@ static void bnx2x_timer(unsigned long data) bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; /* TBD - add SYSTEM_TIME */ drv_pulse = bp->fw_drv_pulse_wr_seq; - SHMEM_WR(bp, drv_fw_mb[port].drv_pulse_mb, drv_pulse); + SHMEM_WR(bp, func_mb[port].drv_pulse_mb, drv_pulse); - mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].mcp_pulse_mb) & + mcp_pulse = (SHMEM_RD(bp, func_mb[port].mcp_pulse_mb) & MCP_PULSE_SEQ_MASK); /* The delta between driver pulse and mcp response * should be 1 (before mcp response) or 0 (after mcp response) @@ -4370,11 +5167,11 @@ static void bnx2x_timer(unsigned long data) } if (bp->stats_state == STATS_STATE_DISABLE) - goto bnx2x_restart_timer; + goto timer_restart; bnx2x_update_stats(bp); -bnx2x_restart_timer: +timer_restart: mod_timer(&bp->timer, jiffies + bp->current_interval); } @@ -5266,8 +6063,10 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) if (mode & 0x1) { /* init common */ DP(BNX2X_MSG_MCP, "starting common init func %d mode %x\n", func, mode); - REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff); - REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + 0xffffffff); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + 0xfffc); bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END); REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); @@ -5487,6 +6286,28 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) enable_blocks_attention(bp); /* enable_blocks_parity(bp); */ + switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) { + case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G: + /* Fan failure is indicated by SPIO 5 */ + bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5, + MISC_REGISTERS_SPIO_INPUT_HI_Z); + + /* set to active low mode */ + val = REG_RD(bp, MISC_REG_SPIO_INT); + val |= ((1 << MISC_REGISTERS_SPIO_5) << + MISC_REGISTERS_SPIO_INT_OLD_SET_POS); + REG_WR(bp, MISC_REG_SPIO_INT, val); + + /* enable interrupt to signal the IGU */ + val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN); + val |= (1 << MISC_REGISTERS_SPIO_5); + REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); + break; + + default: + break; + } + } /* end of common init */ /* per port init */ @@ -5646,6 +6467,18 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) /* Port MCP comes here */ /* Port DMAE comes here */ + switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) { + case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G: + /* add SPIO 5 to group 0 */ + val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + val |= AEU_INPUTS_ATTN_BITS_SPIO5; + REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val); + break; + + default: + break; + } + bnx2x_link_reset(bp); /* Reset PCIE errors for debug */ @@ -5670,9 +6503,9 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) port = bp->port; bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) & + (SHMEM_RD(bp, func_mb[port].drv_pulse_mb) & DRV_PULSE_SEQ_MASK); - bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param); + bp->fw_mb = SHMEM_RD(bp, func_mb[port].fw_mb_param); DP(BNX2X_MSG_MCP, "drv_pulse 0x%x fw_mb 0x%x\n", bp->fw_drv_pulse_wr_seq, bp->fw_mb); } else { @@ -5685,12 +6518,12 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode) /* send the MCP a request, block until there is a reply */ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) { - u32 rc = 0; - u32 seq = ++bp->fw_seq; int port = bp->port; + u32 seq = ++bp->fw_seq; + u32 rc = 0; - SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq); - DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq); + SHMEM_WR(bp, func_mb[port].drv_mb_header, (command | seq)); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); /* let the FW do it's magic ... */ msleep(100); /* TBD */ @@ -5698,19 +6531,20 @@ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) if (CHIP_REV_IS_SLOW(bp)) msleep(900); - rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header); - + rc = SHMEM_RD(bp, func_mb[port].fw_mb_header); DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq); /* is this a reply to our command? */ if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) { rc &= FW_MSG_CODE_MASK; + } else { /* FW BUG! */ BNX2X_ERR("FW failed to respond!\n"); bnx2x_fw_dump(bp); rc = 0; } + return rc; } @@ -6559,7 +7393,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseT_Full | + SUPPORTED_2500baseX_Full | SUPPORTED_TP | SUPPORTED_FIBRE | SUPPORTED_Autoneg | SUPPORTED_Pause | @@ -6572,10 +7406,10 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) bp->phy_flags |= PHY_SGMII_FLAG; - bp->supported |= (/* SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full |*/ + bp->supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_TP | SUPPORTED_FIBRE | SUPPORTED_Autoneg | @@ -6611,7 +7445,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseT_Full | + SUPPORTED_2500baseX_Full | SUPPORTED_10000baseT_Full | SUPPORTED_TP | SUPPORTED_FIBRE | SUPPORTED_Autoneg | @@ -6620,12 +7454,46 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", + ext_phy_type); + + bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n", + BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", + ext_phy_type); + + bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", ext_phy_type); bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n", + ext_phy_type); + + bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | SUPPORTED_Pause | SUPPORTED_Asym_Pause); break; @@ -6682,7 +7550,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) SUPPORTED_1000baseT_Full); if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - bp->supported &= ~SUPPORTED_2500baseT_Full; + bp->supported &= ~SUPPORTED_2500baseX_Full; if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) bp->supported &= ~SUPPORTED_10000baseT_Full; @@ -6702,13 +7570,8 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) bp->req_line_speed = 0; bp->advertising = bp->supported; } else { - u32 ext_phy_type; - - ext_phy_type = XGXS_EXT_PHY_TYPE(bp); - if ((ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) { + if (XGXS_EXT_PHY_TYPE(bp) == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) { /* force 10G, no AN */ bp->req_line_speed = SPEED_10000; bp->advertising = @@ -6725,8 +7588,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_10M_FULL: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) { + if (bp->supported & SUPPORTED_10baseT_Full) { bp->req_line_speed = SPEED_10; bp->advertising = (ADVERTISED_10baseT_Full | ADVERTISED_TP); @@ -6740,8 +7602,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_10M_HALF: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) { + if (bp->supported & SUPPORTED_10baseT_Half) { bp->req_line_speed = SPEED_10; bp->req_duplex = DUPLEX_HALF; bp->advertising = (ADVERTISED_10baseT_Half | @@ -6756,8 +7617,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) { + if (bp->supported & SUPPORTED_100baseT_Full) { bp->req_line_speed = SPEED_100; bp->advertising = (ADVERTISED_100baseT_Full | ADVERTISED_TP); @@ -6771,8 +7631,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) { + if (bp->supported & SUPPORTED_100baseT_Half) { bp->req_line_speed = SPEED_100; bp->req_duplex = DUPLEX_HALF; bp->advertising = (ADVERTISED_100baseT_Half | @@ -6787,8 +7646,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_1G: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) { + if (bp->supported & SUPPORTED_1000baseT_Full) { bp->req_line_speed = SPEED_1000; bp->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_TP); @@ -6802,10 +7660,9 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) break; case PORT_FEATURE_LINK_SPEED_2_5G: - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) { + if (bp->supported & SUPPORTED_2500baseX_Full) { bp->req_line_speed = SPEED_2500; - bp->advertising = (ADVERTISED_2500baseT_Full | + bp->advertising = (ADVERTISED_2500baseX_Full | ADVERTISED_TP); } else { BNX2X_ERR("NVRAM config error. " @@ -6819,15 +7676,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) case PORT_FEATURE_LINK_SPEED_10G_CX4: case PORT_FEATURE_LINK_SPEED_10G_KX4: case PORT_FEATURE_LINK_SPEED_10G_KR: - if (!(bp->phy_flags & PHY_XGXS_FLAG)) { - BNX2X_ERR("NVRAM config error. " - "Invalid link_config 0x%x" - " phy_flags 0x%x\n", - bp->link_config, bp->phy_flags); - return; - } - if (bp->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { + if (bp->supported & SUPPORTED_10000baseT_Full) { bp->req_line_speed = SPEED_10000; bp->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); @@ -6854,43 +7703,13 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) bp->req_flow_ctrl = (bp->link_config & PORT_FEATURE_FLOW_CONTROL_MASK); - /* Please refer to Table 28B-3 of the 802.3ab-1999 spec */ - switch (bp->req_flow_ctrl) { - case FLOW_CTRL_AUTO: + if ((bp->req_flow_ctrl == FLOW_CTRL_AUTO) && + (bp->supported & SUPPORTED_Autoneg)) bp->req_autoneg |= AUTONEG_FLOW_CTRL; - if (bp->dev->mtu <= 4500) { - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - } else { - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; - } - break; - - case FLOW_CTRL_TX: - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; - break; - - case FLOW_CTRL_RX: - case FLOW_CTRL_BOTH: - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; - case FLOW_CTRL_NONE: - default: - bp->pause_mode = PAUSE_NONE; - bp->advertising &= ~(ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; - } - BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x\n" - KERN_INFO " pause_mode %d advertising 0x%x\n", - bp->req_autoneg, bp->req_flow_ctrl, - bp->pause_mode, bp->advertising); + BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x" + " advertising 0x%x\n", + bp->req_autoneg, bp->req_flow_ctrl, bp->advertising); } static void bnx2x_get_hwinfo(struct bnx2x *bp) @@ -6923,16 +7742,16 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, validity_map[port]); if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - BNX2X_ERR("MCP validity signature bad\n"); + != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + BNX2X_ERR("BAD MCP validity signature\n"); - bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) & + bp->fw_seq = (SHMEM_RD(bp, func_mb[port].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); - + bp->board = SHMEM_RD(bp, dev_info.shared_hw_config.board); bp->serdes_config = - SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config); + SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config); bp->lane_config = SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); bp->ext_phy_config = @@ -6945,13 +7764,13 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp) bp->link_config = SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); - BNX2X_DEV_INFO("hw_config (%08x) serdes_config (%08x)\n" + BNX2X_DEV_INFO("hw_config (%08x) board (%08x) serdes_config (%08x)\n" KERN_INFO " lane_config (%08x) ext_phy_config (%08x)\n" KERN_INFO " speed_cap_mask (%08x) link_config (%08x)" " fw_seq (%08x)\n", - bp->hw_config, bp->serdes_config, bp->lane_config, - bp->ext_phy_config, bp->speed_cap_mask, - bp->link_config, bp->fw_seq); + bp->hw_config, bp->board, bp->serdes_config, + bp->lane_config, bp->ext_phy_config, + bp->speed_cap_mask, bp->link_config, bp->fw_seq); switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK); bnx2x_link_settings_supported(bp, switch_cfg); @@ -7005,14 +7824,8 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp) return; set_mac: /* only supposed to happen on emulation/FPGA */ - BNX2X_ERR("warning constant MAC workaround active\n"); - bp->dev->dev_addr[0] = 0; - bp->dev->dev_addr[1] = 0x50; - bp->dev->dev_addr[2] = 0xc2; - bp->dev->dev_addr[3] = 0x2c; - bp->dev->dev_addr[4] = 0x71; - bp->dev->dev_addr[5] = port ? 0x0d : 0x0e; - + BNX2X_ERR("warning rendom MAC workaround active\n"); + random_ether_addr(bp->dev->dev_addr); memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6); } @@ -7039,19 +7852,34 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) } if (bp->phy_flags & PHY_XGXS_FLAG) { - cmd->port = PORT_FIBRE; - } else { + u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + + switch (ext_phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + cmd->port = PORT_FIBRE; + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + cmd->port = PORT_TP; + break; + + default: + DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); + } + } else cmd->port = PORT_TP; - } cmd->phy_address = bp->phy_addr; cmd->transceiver = XCVR_INTERNAL; - if (bp->req_autoneg & AUTONEG_SPEED) { + if (bp->req_autoneg & AUTONEG_SPEED) cmd->autoneg = AUTONEG_ENABLE; - } else { + else cmd->autoneg = AUTONEG_DISABLE; - } cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; @@ -7082,8 +7910,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) switch (cmd->port) { case PORT_TP: - if (!(bp->supported & SUPPORTED_TP)) + if (!(bp->supported & SUPPORTED_TP)) { + DP(NETIF_MSG_LINK, "TP not supported\n"); return -EINVAL; + } if (bp->phy_flags & PHY_XGXS_FLAG) { bnx2x_link_reset(bp); @@ -7093,8 +7923,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; case PORT_FIBRE: - if (!(bp->supported & SUPPORTED_FIBRE)) + if (!(bp->supported & SUPPORTED_FIBRE)) { + DP(NETIF_MSG_LINK, "FIBRE not supported\n"); return -EINVAL; + } if (!(bp->phy_flags & PHY_XGXS_FLAG)) { bnx2x_link_reset(bp); @@ -7104,12 +7936,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; default: + DP(NETIF_MSG_LINK, "Unknown port type\n"); return -EINVAL; } if (cmd->autoneg == AUTONEG_ENABLE) { - if (!(bp->supported & SUPPORTED_Autoneg)) + if (!(bp->supported & SUPPORTED_Autoneg)) { + DP(NETIF_MSG_LINK, "Aotoneg not supported\n"); return -EINVAL; + } /* advertise the requested speed and duplex if supported */ cmd->advertising &= bp->supported; @@ -7124,14 +7959,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) switch (cmd->speed) { case SPEED_10: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->supported & SUPPORTED_10baseT_Full)) + if (!(bp->supported & + SUPPORTED_10baseT_Full)) { + DP(NETIF_MSG_LINK, + "10M full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { - if (!(bp->supported & SUPPORTED_10baseT_Half)) + if (!(bp->supported & + SUPPORTED_10baseT_Half)) { + DP(NETIF_MSG_LINK, + "10M half not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_10baseT_Half | ADVERTISED_TP); @@ -7141,15 +7984,21 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) case SPEED_100: if (cmd->duplex == DUPLEX_FULL) { if (!(bp->supported & - SUPPORTED_100baseT_Full)) + SUPPORTED_100baseT_Full)) { + DP(NETIF_MSG_LINK, + "100M full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { if (!(bp->supported & - SUPPORTED_100baseT_Half)) + SUPPORTED_100baseT_Half)) { + DP(NETIF_MSG_LINK, + "100M half not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_100baseT_Half | ADVERTISED_TP); @@ -7157,39 +8006,54 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; case SPEED_1000: - if (cmd->duplex != DUPLEX_FULL) + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, "1G half not supported\n"); return -EINVAL; + } - if (!(bp->supported & SUPPORTED_1000baseT_Full)) + if (!(bp->supported & SUPPORTED_1000baseT_Full)) { + DP(NETIF_MSG_LINK, "1G full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_TP); break; case SPEED_2500: - if (cmd->duplex != DUPLEX_FULL) + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, + "2.5G half not supported\n"); return -EINVAL; + } - if (!(bp->supported & SUPPORTED_2500baseT_Full)) + if (!(bp->supported & SUPPORTED_2500baseX_Full)) { + DP(NETIF_MSG_LINK, + "2.5G full not supported\n"); return -EINVAL; + } - advertising = (ADVERTISED_2500baseT_Full | + advertising = (ADVERTISED_2500baseX_Full | ADVERTISED_TP); break; case SPEED_10000: - if (cmd->duplex != DUPLEX_FULL) + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, "10G half not supported\n"); return -EINVAL; + } - if (!(bp->supported & SUPPORTED_10000baseT_Full)) + if (!(bp->supported & SUPPORTED_10000baseT_Full)) { + DP(NETIF_MSG_LINK, "10G full not supported\n"); return -EINVAL; + } advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); break; default: + DP(NETIF_MSG_LINK, "Unsupported speed\n"); return -EINVAL; } @@ -7389,8 +8253,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp) static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val, u32 cmd_flags) { - int rc; - int count, i; + int count, i, rc; u32 val; /* build the command word */ @@ -7510,8 +8373,7 @@ static int bnx2x_get_eeprom(struct net_device *dev, static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, u32 cmd_flags) { - int rc; - int count, i; + int count, i, rc; /* build the command word */ cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR; @@ -7548,7 +8410,7 @@ static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, return rc; } -#define BYTE_OFFSET(offset) (8 * (offset & 0x03)) +#define BYTE_OFFSET(offset) (8 * (offset & 0x03)) static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf, int buf_size) @@ -7779,52 +8641,29 @@ static int bnx2x_set_pauseparam(struct net_device *dev, DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); - bp->req_flow_ctrl = FLOW_CTRL_AUTO; if (epause->autoneg) { - bp->req_autoneg |= AUTONEG_FLOW_CTRL; - if (bp->dev->mtu <= 4500) { - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - } else { - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; + if (!(bp->supported & SUPPORTED_Autoneg)) { + DP(NETIF_MSG_LINK, "Aotoneg not supported\n"); + return -EINVAL; } - } else { + bp->req_autoneg |= AUTONEG_FLOW_CTRL; + } else bp->req_autoneg &= ~AUTONEG_FLOW_CTRL; - if (epause->rx_pause) - bp->req_flow_ctrl |= FLOW_CTRL_RX; - if (epause->tx_pause) - bp->req_flow_ctrl |= FLOW_CTRL_TX; - - switch (bp->req_flow_ctrl) { - case FLOW_CTRL_AUTO: - bp->req_flow_ctrl = FLOW_CTRL_NONE; - bp->pause_mode = PAUSE_NONE; - bp->advertising &= ~(ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; + bp->req_flow_ctrl = FLOW_CTRL_AUTO; - case FLOW_CTRL_TX: - bp->pause_mode = PAUSE_ASYMMETRIC; - bp->advertising |= ADVERTISED_Asym_Pause; - break; + if (epause->rx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_RX; + if (epause->tx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_TX; - case FLOW_CTRL_RX: - case FLOW_CTRL_BOTH: - bp->pause_mode = PAUSE_BOTH; - bp->advertising |= (ADVERTISED_Pause | - ADVERTISED_Asym_Pause); - break; - } - } + if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) && + (bp->req_flow_ctrl == FLOW_CTRL_AUTO)) + bp->req_flow_ctrl = FLOW_CTRL_NONE; - DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n" - DP_LEVEL " pause_mode %d advertising 0x%x\n", - bp->req_autoneg, bp->req_flow_ctrl, bp->pause_mode, - bp->advertising); + DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n", + bp->req_autoneg, bp->req_flow_ctrl); bnx2x_stop_stats(bp); bnx2x_link_initialize(bp); diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index ea9100855c5c..dc423e58dad8 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -24,6 +24,8 @@ #define BNX2X_MSG_STATS 0x20000 /* was: NETIF_MSG_TIMER */ #define NETIF_MSG_NVM 0x40000 /* was: NETIF_MSG_HW */ #define NETIF_MSG_DMAE 0x80000 /* was: NETIF_MSG_HW */ +#define BNX2X_MSG_SP 0x100000 /* was: NETIF_MSG_INTR */ +#define BNX2X_MSG_FP 0x200000 /* was: NETIF_MSG_INTR */ #define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */ @@ -40,6 +42,12 @@ __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \ } while (0) +/* for logging (never masked) */ +#define BNX2X_LOG(__fmt, __args...) do { \ + printk(KERN_NOTICE "[%s:%d(%s)]" __fmt, __FUNCTION__, \ + __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \ + } while (0) + /* before we have a dev->name use dev_info() */ #define BNX2X_DEV_INFO(__fmt, __args...) do { \ if (bp->msglevel & NETIF_MSG_PROBE) \ @@ -574,7 +582,8 @@ struct bnx2x { u32 fw_mb; u32 hw_config; - u32 serdes_config; + u32 board; + u32 serdes_config; u32 lane_config; u32 ext_phy_config; #define XGXS_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \ @@ -595,11 +604,11 @@ struct bnx2x { u8 tx_lane_swap; u8 link_up; + u8 phy_link_up; u32 supported; /* link settings - missing defines */ #define SUPPORTED_2500baseT_Full (1 << 15) -#define SUPPORTED_CX4 (1 << 16) u32 phy_flags; /*#define PHY_SERDES_FLAG 0x1*/ @@ -644,16 +653,9 @@ struct bnx2x { #define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH #define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE - u32 pause_mode; -#define PAUSE_NONE 0 -#define PAUSE_SYMMETRIC 1 -#define PAUSE_ASYMMETRIC 2 -#define PAUSE_BOTH 3 - u32 advertising; /* link settings - missing defines */ #define ADVERTISED_2500baseT_Full (1 << 15) -#define ADVERTISED_CX4 (1 << 16) u32 link_status; u32 line_speed; @@ -667,6 +669,8 @@ struct bnx2x { #define NVRAM_TIMEOUT_COUNT 30000 #define NVRAM_PAGE_SIZE 256 + u8 wol; + int rx_ring_size; u16 tx_quick_cons_trip_int; @@ -718,9 +722,6 @@ struct bnx2x { #endif char *name; - u16 bus_speed_mhz; - u8 wol; - u8 pad; /* used to synchronize stats collecting */ int stats_state; @@ -873,6 +874,7 @@ struct bnx2x { #define PCICFG_LINK_SPEED 0xf0000 #define PCICFG_LINK_SPEED_SHIFT 16 +#define BMAC_CONTROL_RX_ENABLE 2 /* stuff added to make the code fit 80Col */ #define TPA_TYPE_START ETH_FAST_PATH_RX_CQE_START_FLG @@ -944,13 +946,13 @@ struct bnx2x { #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD -#define NIG_STATUS_INTERRUPT_XGXS0_LINK10G \ +#define NIG_STATUS_XGXS0_LINK10G \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G -#define NIG_XGXS0_LINK_STATUS \ +#define NIG_STATUS_XGXS0_LINK_STATUS \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS -#define NIG_XGXS0_LINK_STATUS_SIZE \ +#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE -#define NIG_SERDES0_LINK_STATUS \ +#define NIG_STATUS_SERDES0_LINK_STATUS \ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS #define NIG_MASK_MI_INT \ NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h index 62a6eb81025a..3b968904ca65 100644 --- a/drivers/net/bnx2x_fw_defs.h +++ b/drivers/net/bnx2x_fw_defs.h @@ -1,6 +1,6 @@ /* bnx2x_fw_defs.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * 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 diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h index 6fd959c34d1f..b21075ccb52e 100644 --- a/drivers/net/bnx2x_hsi.h +++ b/drivers/net/bnx2x_hsi.h @@ -1,6 +1,6 @@ /* bnx2x_hsi.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * 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 @@ -8,169 +8,9 @@ */ -#define FUNC_0 0 -#define FUNC_1 1 -#define FUNC_MAX 2 - - -/* This value (in milliseconds) determines the frequency of the driver - * issuing the PULSE message code. The firmware monitors this periodic - * pulse to determine when to switch to an OS-absent mode. */ -#define DRV_PULSE_PERIOD_MS 250 - -/* This value (in milliseconds) determines how long the driver should - * wait for an acknowledgement from the firmware before timing out. Once - * the firmware has timed out, the driver will assume there is no firmware - * running and there won't be any firmware-driver synchronization during a - * driver reset. */ -#define FW_ACK_TIME_OUT_MS 5000 - -#define FW_ACK_POLL_TIME_MS 1 - -#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS) - -/* LED Blink rate that will achieve ~15.9Hz */ -#define LED_BLINK_RATE_VAL 480 - -/**************************************************************************** - * Driver <-> FW Mailbox * - ****************************************************************************/ -struct drv_fw_mb { - u32 drv_mb_header; -#define DRV_MSG_CODE_MASK 0xffff0000 -#define DRV_MSG_CODE_LOAD_REQ 0x10000000 -#define DRV_MSG_CODE_LOAD_DONE 0x11000000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000 -#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000 -#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000 -#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000 -#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000 -#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000 -#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000 -#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000 -#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 -#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 - -#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff - - u32 drv_mb_param; - - u32 fw_mb_header; -#define FW_MSG_CODE_MASK 0xffff0000 -#define FW_MSG_CODE_DRV_LOAD_COMMON 0x11000000 -#define FW_MSG_CODE_DRV_LOAD_PORT 0x12000000 -#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x13000000 -#define FW_MSG_CODE_DRV_LOAD_DONE 0x14000000 -#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x21000000 -#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x22000000 -#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x23000000 -#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50000000 -#define FW_MSG_CODE_DIAG_REFUSE 0x51000000 -#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70000000 -#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x71000000 -#define FW_MSG_CODE_GET_KEY_DONE 0x80000000 -#define FW_MSG_CODE_NO_KEY 0x8f000000 -#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x8f800000 -#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90000000 -#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x91000000 -#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x92000000 -#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x93000000 -#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x94000000 - -#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff - - u32 fw_mb_param; - - u32 link_status; - /* Driver should update this field on any link change event */ - -#define LINK_STATUS_LINK_FLAG_MASK 0x00000001 -#define LINK_STATUS_LINK_UP 0x00000001 -#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E -#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1) -#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1) - -#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020 -#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 - -#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 -#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080 -#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 - -#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 -#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 -#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800 -#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000 -#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000 -#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000 -#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000 - -#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000 -#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000 - -#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000 -#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000 - -#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 -#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18) -#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18) -#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18) -#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18) - -#define LINK_STATUS_SERDES_LINK 0x00100000 - -#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000 -#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000 -#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 -#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000 -#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000 -#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000 -#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000 -#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000 - - u32 drv_pulse_mb; -#define DRV_PULSE_SEQ_MASK 0x00007fff -#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 - /* The system time is in the format of - * (year-2001)*12*32 + month*32 + day. */ -#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 - /* Indicate to the firmware not to go into the - * OS-absent when it is not getting driver pulse. - * This is used for debugging as well for PXE(MBA). */ - - u32 mcp_pulse_mb; -#define MCP_PULSE_SEQ_MASK 0x00007fff -#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 - /* Indicates to the driver not to assert due to lack - * of MCP response */ -#define MCP_EVENT_MASK 0xffff0000 -#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 - -}; - +#define PORT_0 0 +#define PORT_1 1 +#define PORT_MAX 2 /**************************************************************************** * Shared HW configuration * @@ -249,7 +89,7 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_SMBUS_TIMING_100KHZ 0x00000000 #define SHARED_HW_CFG_SMBUS_TIMING_400KHZ 0x00001000 -#define SHARED_HW_CFG_HIDE_FUNC1 0x00002000 +#define SHARED_HW_CFG_HIDE_PORT1 0x00002000 u32 power_dissipated; /* 0x11c */ #define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000 @@ -290,6 +130,8 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006 #define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007 #define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a #define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000 #define SHARED_HW_CFG_BOARD_VER_SHIFT 16 @@ -304,13 +146,12 @@ struct shared_hw_cfg { /* NVRAM Offset */ }; + /**************************************************************************** * Port HW configuration * ****************************************************************************/ -struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */ +struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ - /* Fields below are port specific (in anticipation of dual port - devices */ u32 pci_id; #define PORT_HW_CFG_PCI_VENDOR_ID_MASK 0xffff0000 #define PORT_HW_CFG_PCI_DEVICE_ID_MASK 0x0000ffff @@ -420,6 +261,8 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */ #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00 #define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK 0x000000ff @@ -462,11 +305,13 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */ }; + /**************************************************************************** * Shared Feature configuration * ****************************************************************************/ struct shared_feat_cfg { /* NVRAM Offset */ - u32 bmc_common; /* 0x450 */ + + u32 config; /* 0x450 */ #define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001 }; @@ -475,7 +320,8 @@ struct shared_feat_cfg { /* NVRAM Offset */ /**************************************************************************** * Port Feature configuration * ****************************************************************************/ -struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */ +struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ + u32 config; #define PORT_FEATURE_BAR1_SIZE_MASK 0x0000000f #define PORT_FEATURE_BAR1_SIZE_SHIFT 0 @@ -609,8 +455,7 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */ #define PORT_FEATURE_SMBUS_ADDR_MASK 0x000000fe #define PORT_FEATURE_SMBUS_ADDR_SHIFT 1 - u32 iscsib_boot_cfg; -#define PORT_FEATURE_ISCSIB_SKIP_TARGET_BOOT 0x00000001 + u32 reserved1; u32 link_config; /* Used as HW defaults for the driver */ #define PORT_FEATURE_CONNECTED_SWITCH_MASK 0x03000000 @@ -657,20 +502,201 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */ }; +/***************************************************************************** + * Device Information * + *****************************************************************************/ +struct dev_info { /* size */ + + u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */ + + struct shared_hw_cfg shared_hw_config; /* 40 */ + + struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */ + + struct shared_feat_cfg shared_feature_config; /* 4 */ + + struct port_feat_cfg port_feature_config[PORT_MAX]; /* 116*2=232 */ + +}; + + +#define FUNC_0 0 +#define FUNC_1 1 +#define E1_FUNC_MAX 2 +#define FUNC_MAX E1_FUNC_MAX + + +/* This value (in milliseconds) determines the frequency of the driver + * issuing the PULSE message code. The firmware monitors this periodic + * pulse to determine when to switch to an OS-absent mode. */ +#define DRV_PULSE_PERIOD_MS 250 + +/* This value (in milliseconds) determines how long the driver should + * wait for an acknowledgement from the firmware before timing out. Once + * the firmware has timed out, the driver will assume there is no firmware + * running and there won't be any firmware-driver synchronization during a + * driver reset. */ +#define FW_ACK_TIME_OUT_MS 5000 + +#define FW_ACK_POLL_TIME_MS 1 + +#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS) + +/* LED Blink rate that will achieve ~15.9Hz */ +#define LED_BLINK_RATE_VAL 480 + /**************************************************************************** - * Device Information * + * Driver <-> FW Mailbox * ****************************************************************************/ -struct dev_info { /* size */ +struct drv_port_mb { + + u32 link_status; + /* Driver should update this field on any link change event */ + +#define LINK_STATUS_LINK_FLAG_MASK 0x00000001 +#define LINK_STATUS_LINK_UP 0x00000001 +#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E +#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1) + +#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020 +#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 + +#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 +#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080 +#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 + +#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 +#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 +#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800 +#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000 +#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000 +#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000 +#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000 + +#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000 +#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000 + +#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000 +#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000 + +#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 +#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18) +#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18) +#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18) +#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18) + +#define LINK_STATUS_SERDES_LINK 0x00100000 + +#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000 +#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000 +#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 +#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000 +#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000 +#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000 +#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000 +#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000 - u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */ + u32 reserved[3]; - struct shared_hw_cfg shared_hw_config; /* 40 */ +}; + + +struct drv_func_mb { + + u32 drv_mb_header; +#define DRV_MSG_CODE_MASK 0xffff0000 +#define DRV_MSG_CODE_LOAD_REQ 0x10000000 +#define DRV_MSG_CODE_LOAD_DONE 0x11000000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000 +#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000 +#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000 +#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000 +#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000 +#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000 +#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000 +#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 +#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 + +#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff + + u32 drv_mb_param; + + u32 fw_mb_header; +#define FW_MSG_CODE_MASK 0xffff0000 +#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000 +#define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000 +#define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000 +#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000 +#define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000 +#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000 +#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x20110000 +#define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 0x20120000 +#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x21100000 +#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50100000 +#define FW_MSG_CODE_DIAG_REFUSE 0x50200000 +#define FW_MSG_CODE_DIAG_EXIT_DONE 0x60100000 +#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70100000 +#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x70200000 +#define FW_MSG_CODE_GET_KEY_DONE 0x80100000 +#define FW_MSG_CODE_NO_KEY 0x80f00000 +#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x80f80000 +#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90100000 +#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x90210000 +#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000 +#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000 +#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000 + +#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff + + u32 fw_mb_param; + + u32 drv_pulse_mb; +#define DRV_PULSE_SEQ_MASK 0x00007fff +#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 + /* The system time is in the format of + * (year-2001)*12*32 + month*32 + day. */ +#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 + /* Indicate to the firmware not to go into the + * OS-absent when it is not getting driver pulse. + * This is used for debugging as well for PXE(MBA). */ - struct port_hw_cfg port_hw_config[FUNC_MAX]; /* 400*2=800 */ + u32 mcp_pulse_mb; +#define MCP_PULSE_SEQ_MASK 0x00007fff +#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 + /* Indicates to the driver not to assert due to lack + * of MCP response */ +#define MCP_EVENT_MASK 0xffff0000 +#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 - struct shared_feat_cfg shared_feature_config; /* 4 */ + u32 iscsi_boot_signature; + u32 iscsi_boot_block_offset; - struct port_feat_cfg port_feature_config[FUNC_MAX];/* 116*2=232 */ + u32 reserved[3]; }; @@ -678,9 +704,8 @@ struct dev_info { /* size */ /**************************************************************************** * Management firmware state * ****************************************************************************/ -/* Allocate 320 bytes for management firmware: still not known exactly - * how much IMD needs. */ -#define MGMTFW_STATE_WORD_SIZE 80 +/* Allocate 440 bytes for management firmware */ +#define MGMTFW_STATE_WORD_SIZE 110 struct mgmtfw_state { u32 opaque[MGMTFW_STATE_WORD_SIZE]; @@ -691,31 +716,40 @@ struct mgmtfw_state { * Shared Memory Region * ****************************************************************************/ struct shmem_region { /* SharedMem Offset (size) */ - u32 validity_map[FUNC_MAX]; /* 0x0 (4 * 2 = 0x8) */ -#define SHR_MEM_VALIDITY_PCI_CFG 0x00000001 -#define SHR_MEM_VALIDITY_MB 0x00000002 -#define SHR_MEM_VALIDITY_DEV_INFO 0x00000004 + + u32 validity_map[PORT_MAX]; /* 0x0 (4*2 = 0x8) */ +#define SHR_MEM_FORMAT_REV_ID ('A'<<24) +#define SHR_MEM_FORMAT_REV_MASK 0xff000000 + /* validity bits */ +#define SHR_MEM_VALIDITY_PCI_CFG 0x00100000 +#define SHR_MEM_VALIDITY_MB 0x00200000 +#define SHR_MEM_VALIDITY_DEV_INFO 0x00400000 +#define SHR_MEM_VALIDITY_RESERVED 0x00000007 /* One licensing bit should be set */ #define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038 #define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008 #define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010 #define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020 + /* Active MFW */ +#define SHR_MEM_VALIDITY_ACTIVE_MFW_UNKNOWN 0x00000000 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_IPMI 0x00000040 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_UMP 0x00000080 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_NCSI 0x000000c0 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0 +#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0 - struct drv_fw_mb drv_fw_mb[FUNC_MAX]; /* 0x8 (28 * 2 = 0x38) */ - - struct dev_info dev_info; /* 0x40 (0x438) */ + struct dev_info dev_info; /* 0x8 (0x438) */ -#ifdef _LICENSE_H - license_key_t drv_lic_key[FUNC_MAX]; /* 0x478 (52 * 2 = 0x68) */ -#else /* Linux! */ - u8 reserved[52*FUNC_MAX]; -#endif + u8 reserved[52*PORT_MAX]; /* FW information (for internal FW use) */ - u32 fw_info_fio_offset; /* 0x4e0 (0x4) */ - struct mgmtfw_state mgmtfw_state; /* 0x4e4 (0x140) */ + u32 fw_info_fio_offset; /* 0x4a8 (0x4) */ + struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */ + + struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */ + struct drv_func_mb func_mb[FUNC_MAX]; /* 0x684 (44*2=0x58) */ -}; /* 0x624 */ +}; /* 0x6dc */ #define BCM_5710_FW_MAJOR_VERSION 4 diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h index 86055297ab02..5a1aa0b55044 100644 --- a/drivers/net/bnx2x_reg.h +++ b/drivers/net/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * 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 @@ -24,6 +24,8 @@ #define BRB1_REG_BRB1_INT_STS 0x6011c /* [RW 4] Parity mask register #0 read/write */ #define BRB1_REG_BRB1_PRTY_MASK 0x60138 +/* [R 4] Parity register #0 read */ +#define BRB1_REG_BRB1_PRTY_STS 0x6012c /* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */ @@ -281,6 +283,8 @@ #define CDU_REG_CDU_INT_STS 0x101030 /* [RW 5] Parity mask register #0 read/write */ #define CDU_REG_CDU_PRTY_MASK 0x10104c +/* [R 5] Parity register #0 read */ +#define CDU_REG_CDU_PRTY_STS 0x101040 /* [RC 32] logging of error data in case of a CDU load error: {expected_cid[15:0]; xpected_type[2:0]; xpected_region[2:0]; ctive_error; ype_error; ctual_active; ctual_compressed_context}; */ @@ -308,6 +312,8 @@ #define CFC_REG_CFC_INT_STS_CLR 0x104100 /* [RW 4] Parity mask register #0 read/write */ #define CFC_REG_CFC_PRTY_MASK 0x104118 +/* [R 4] Parity register #0 read */ +#define CFC_REG_CFC_PRTY_STS 0x10410c /* [RW 21] CID cam access (21:1 - Data; alid - 0) */ #define CFC_REG_CID_CAM 0x104800 #define CFC_REG_CONTROL0 0x104028 @@ -354,6 +360,8 @@ #define CSDM_REG_CSDM_INT_MASK_1 0xc22ac /* [RW 11] Parity mask register #0 read/write */ #define CSDM_REG_CSDM_PRTY_MASK 0xc22bc +/* [R 11] Parity register #0 read */ +#define CSDM_REG_CSDM_PRTY_STS 0xc22b0 #define CSDM_REG_ENABLE_IN1 0xc2238 #define CSDM_REG_ENABLE_IN2 0xc223c #define CSDM_REG_ENABLE_OUT1 0xc2240 @@ -438,6 +446,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define CSEM_REG_CSEM_PRTY_MASK_0 0x200130 #define CSEM_REG_CSEM_PRTY_MASK_1 0x200140 +/* [R 32] Parity register #0 read */ +#define CSEM_REG_CSEM_PRTY_STS_0 0x200124 +#define CSEM_REG_CSEM_PRTY_STS_1 0x200134 #define CSEM_REG_ENABLE_IN 0x2000a4 #define CSEM_REG_ENABLE_OUT 0x2000a8 /* [RW 32] This address space contains all registers and memories that are @@ -526,6 +537,8 @@ #define CSEM_REG_TS_9_AS 0x20005c /* [RW 1] Parity mask register #0 read/write */ #define DBG_REG_DBG_PRTY_MASK 0xc0a8 +/* [R 1] Parity register #0 read */ +#define DBG_REG_DBG_PRTY_STS 0xc09c /* [RW 2] debug only: These bits indicate the credit for PCI request type 4 interface; MUST be configured AFTER pci_ext_buffer_strt_addr_lsb/msb are configured */ @@ -543,6 +556,8 @@ #define DMAE_REG_DMAE_INT_MASK 0x102054 /* [RW 4] Parity mask register #0 read/write */ #define DMAE_REG_DMAE_PRTY_MASK 0x102064 +/* [R 4] Parity register #0 read */ +#define DMAE_REG_DMAE_PRTY_STS 0x102058 /* [RW 1] Command 0 go. */ #define DMAE_REG_GO_C0 0x102080 /* [RW 1] Command 1 go. */ @@ -623,6 +638,8 @@ #define DORQ_REG_DORQ_INT_STS_CLR 0x170178 /* [RW 2] Parity mask register #0 read/write */ #define DORQ_REG_DORQ_PRTY_MASK 0x170190 +/* [R 2] Parity register #0 read */ +#define DORQ_REG_DORQ_PRTY_STS 0x170184 /* [RW 8] The address to write the DPM CID to STORM. */ #define DORQ_REG_DPM_CID_ADDR 0x170044 /* [RW 5] The DPM mode CID extraction offset. */ @@ -692,6 +709,8 @@ #define HC_REG_CONFIG_1 0x108004 /* [RW 3] Parity mask register #0 read/write */ #define HC_REG_HC_PRTY_MASK 0x1080a0 +/* [R 3] Parity register #0 read */ +#define HC_REG_HC_PRTY_STS 0x108094 /* [RW 17] status block interrupt mask; one in each bit means unmask; zerow in each bit means mask; bit 0 - default SB; bit 1 - SB_0; bit 2 - SB_1... bit 16- SB_15; addr 0 - port 0; addr 1 - port 1 */ @@ -1127,6 +1146,7 @@ #define MISC_REG_AEU_GENERAL_ATTN_17 0xa044 #define MISC_REG_AEU_GENERAL_ATTN_18 0xa048 #define MISC_REG_AEU_GENERAL_ATTN_19 0xa04c +#define MISC_REG_AEU_GENERAL_ATTN_10 0xa028 #define MISC_REG_AEU_GENERAL_ATTN_11 0xa02c #define MISC_REG_AEU_GENERAL_ATTN_2 0xa008 #define MISC_REG_AEU_GENERAL_ATTN_20 0xa050 @@ -1135,6 +1155,9 @@ #define MISC_REG_AEU_GENERAL_ATTN_4 0xa010 #define MISC_REG_AEU_GENERAL_ATTN_5 0xa014 #define MISC_REG_AEU_GENERAL_ATTN_6 0xa018 +#define MISC_REG_AEU_GENERAL_ATTN_7 0xa01c +#define MISC_REG_AEU_GENERAL_ATTN_8 0xa020 +#define MISC_REG_AEU_GENERAL_ATTN_9 0xa024 /* [RW 32] first 32b for inverting the input for function 0; for each bit: 0= do not invert; 1= invert; mapped as follows: [0] NIG attention for function0; [1] NIG attention for function1; [2] GPIO1 mcp; [3] GPIO2 mcp; @@ -1183,6 +1206,40 @@ starts at 0x0 for the A0 tape-out and increments by one for each all-layer tape-out. */ #define MISC_REG_CHIP_REV 0xa40c +/* [RW 32] The following driver registers(1..6) represent 6 drivers and 32 + clients. Each client can be controlled by one driver only. One in each + bit represent that this driver control the appropriate client (Ex: bit 5 + is set means this driver control client number 5). addr1 = set; addr0 = + clear; read from both addresses will give the same result = status. write + to address 1 will set a request to control all the clients that their + appropriate bit (in the write command) is set. if the client is free (the + appropriate bit in all the other drivers is clear) one will be written to + that driver register; if the client isn't free the bit will remain zero. + if the appropriate bit is set (the driver request to gain control on a + client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW + interrupt will be asserted). write to address 0 will set a request to + free all the clients that their appropriate bit (in the write command) is + set. if the appropriate bit is clear (the driver request to free a client + it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will + be asserted). */ +#define MISC_REG_DRIVER_CONTROL_1 0xa510 +/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of + these bits is written as a '1'; the corresponding SPIO bit will turn off + it's drivers and become an input. This is the reset state of all GPIO + pins. The read value of these bits will be a '1' if that last command + (#SET; #CLR; or #FLOAT) for this bit was a #FLOAT. (reset value 0xff). + [23-20] CLR port 1; 19-16] CLR port 0; When any of these bits is written + as a '1'; the corresponding GPIO bit will drive low. The read value of + these bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for + this bit was a #CLR. (reset value 0). [15-12] SET port 1; 11-8] port 0; + SET When any of these bits is written as a '1'; the corresponding GPIO + bit will drive high (if it has that capability). The read value of these + bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for this + bit was a #SET. (reset value 0). [7-4] VALUE port 1; [3-0] VALUE port 0; + RO; These bits indicate the read value of each of the eight GPIO pins. + This is the result value of the pin; not the drive value. Writing these + bits will have not effect. */ +#define MISC_REG_GPIO 0xa490 /* [RW 1] Setting this bit enables a timer in the GRC block to timeout any access that does not finish within ~misc_registers_grc_timout_val.grc_timeout_val cycles. When this bit is @@ -1223,6 +1280,8 @@ #define MISC_REG_MISC_INT_MASK 0xa388 /* [RW 1] Parity mask register #0 read/write */ #define MISC_REG_MISC_PRTY_MASK 0xa398 +/* [R 1] Parity register #0 read */ +#define MISC_REG_MISC_PRTY_STS 0xa38c /* [RW 32] 32 LSB of storm PLL first register; reset val = 0x 071d2911. inside order of the bits is: [0] P1 divider[0] (reset value 1); [1] P1 divider[1] (reset value 0); [2] P1 divider[2] (reset value 0); [3] P1 @@ -1264,6 +1323,55 @@ /* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is shared with the driver resides */ #define MISC_REG_SHARED_MEM_ADDR 0xa2b4 +/* [RW 32] SPIO. [31-24] FLOAT When any of these bits is written as a '1'; + the corresponding SPIO bit will turn off it's drivers and become an + input. This is the reset state of all SPIO pins. The read value of these + bits will be a '1' if that last command (#SET; #CL; or #FLOAT) for this + bit was a #FLOAT. (reset value 0xff). [23-16] CLR When any of these bits + is written as a '1'; the corresponding SPIO bit will drive low. The read + value of these bits will be a '1' if that last command (#SET; #CLR; or +#FLOAT) for this bit was a #CLR. (reset value 0). [15-8] SET When any of + these bits is written as a '1'; the corresponding SPIO bit will drive + high (if it has that capability). The read value of these bits will be a + '1' if that last command (#SET; #CLR; or #FLOAT) for this bit was a #SET. + (reset value 0). [7-0] VALUE RO; These bits indicate the read value of + each of the eight SPIO pins. This is the result value of the pin; not the + drive value. Writing these bits will have not effect. Each 8 bits field + is divided as follows: [0] VAUX Enable; when pulsed low; enables supply + from VAUX. (This is an output pin only; the FLOAT field is not applicable + for this pin); [1] VAUX Disable; when pulsed low; disables supply form + VAUX. (This is an output pin only; FLOAT field is not applicable for this + pin); [2] SEL_VAUX_B - Control to power switching logic. Drive low to + select VAUX supply. (This is an output pin only; it is not controlled by + the SET and CLR fields; it is controlled by the Main Power SM; the FLOAT + field is not applicable for this pin; only the VALUE fields is relevant - + it reflects the output value); [3] reserved; [4] spio_4; [5] spio_5; [6] + Bit 0 of UMP device ID select; read by UMP firmware; [7] Bit 1 of UMP + device ID select; read by UMP firmware. */ +#define MISC_REG_SPIO 0xa4fc +/* [RW 8] These bits enable the SPIO_INTs to signals event to the IGU/MC. + according to the following map: [3:0] reserved; [4] spio_4 [5] spio_5; + [7:0] reserved */ +#define MISC_REG_SPIO_EVENT_EN 0xa2b8 +/* [RW 32] SPIO INT. [31-24] OLD_CLR Writing a '1' to these bit clears the + corresponding bit in the #OLD_VALUE register. This will acknowledge an + interrupt on the falling edge of corresponding SPIO input (reset value + 0). [23-16] OLD_SET Writing a '1' to these bit sets the corresponding bit + in the #OLD_VALUE register. This will acknowledge an interrupt on the + rising edge of corresponding SPIO input (reset value 0). [15-8] OLD_VALUE + RO; These bits indicate the old value of the SPIO input value. When the + ~INT_STATE bit is set; this bit indicates the OLD value of the pin such + that if ~INT_STATE is set and this bit is '0'; then the interrupt is due + to a low to high edge. If ~INT_STATE is set and this bit is '1'; then the + interrupt is due to a high to low edge (reset value 0). [7-0] INT_STATE + RO; These bits indicate the current SPIO interrupt state for each SPIO + pin. This bit is cleared when the appropriate #OLD_SET or #OLD_CLR + command bit is written. This bit is set when the SPIO input does not + match the current value in #OLD_VALUE (reset value 0). */ +#define MISC_REG_SPIO_INT 0xa500 +/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are + loaded; 0-prepare; -unprepare */ +#define MISC_REG_UNPREPARED 0xa424 #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15) @@ -1392,6 +1500,9 @@ #define NIG_REG_NIG_INGRESS_EMAC0_NO_CRC 0x10044 /* [RW 1] Input enable for RX PBF LP IF */ #define NIG_REG_PBF_LB_IN_EN 0x100b4 +/* [RW 1] Value of this register will be transmitted to port swap when + ~nig_registers_strap_override.strap_override =1 */ +#define NIG_REG_PORT_SWAP 0x10394 /* [RW 1] output enable for RX parser descriptor IF */ #define NIG_REG_PRS_EOP_OUT_EN 0x10104 /* [RW 1] Input enable for RX parser request IF */ @@ -1410,6 +1521,10 @@ #define NIG_REG_STAT2_BRB_OCTET 0x107e0 #define NIG_REG_STATUS_INTERRUPT_PORT0 0x10328 #define NIG_REG_STATUS_INTERRUPT_PORT1 0x1032c +/* [RW 1] port swap mux selection. If this register equal to 0 then port + swap is equal to SPIO pin that inputs from ifmux_serdes_swap. If 1 then + ort swap is equal to ~nig_registers_port_swap.port_swap */ +#define NIG_REG_STRAP_OVERRIDE 0x10398 /* [RW 1] output enable for RX_XCM0 IF */ #define NIG_REG_XCM0_OUT_EN 0x100f0 /* [RW 1] output enable for RX_XCM1 IF */ @@ -1499,6 +1614,8 @@ #define PB_REG_PB_INT_STS 0x1c /* [RW 4] Parity mask register #0 read/write */ #define PB_REG_PB_PRTY_MASK 0x38 +/* [R 4] Parity register #0 read */ +#define PB_REG_PB_PRTY_STS 0x2c #define PRS_REG_A_PRSU_20 0x40134 /* [R 8] debug only: CFC load request current credit. Transaction based. */ #define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164 @@ -1590,6 +1707,8 @@ #define PRS_REG_PRS_INT_STS 0x40188 /* [RW 8] Parity mask register #0 read/write */ #define PRS_REG_PRS_PRTY_MASK 0x401a4 +/* [R 8] Parity register #0 read */ +#define PRS_REG_PRS_PRTY_STS 0x40198 /* [RW 8] Context region for pure acknowledge packets. Used in CFC load request message */ #define PRS_REG_PURE_REGIONS 0x40024 @@ -1718,6 +1837,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define PXP2_REG_PXP2_PRTY_MASK_0 0x120588 #define PXP2_REG_PXP2_PRTY_MASK_1 0x120598 +/* [R 32] Parity register #0 read */ +#define PXP2_REG_PXP2_PRTY_STS_0 0x12057c +#define PXP2_REG_PXP2_PRTY_STS_1 0x12058c /* [R 1] Debug only: The 'almost full' indication from each fifo (gives indication about backpressure) */ #define PXP2_REG_RD_ALMOST_FULL_0 0x120424 @@ -1911,6 +2033,8 @@ #define PXP2_REG_RQ_HC_ENDIAN_M 0x1201a8 /* [WB 53] Onchip address table */ #define PXP2_REG_RQ_ONCHIP_AT 0x122000 +/* [RW 13] Pending read limiter threshold; in Dwords */ +#define PXP2_REG_RQ_PDR_LIMIT 0x12033c /* [RW 2] Endian mode for qm */ #define PXP2_REG_RQ_QM_ENDIAN_M 0x120194 /* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k; @@ -1921,6 +2045,9 @@ /* [RW 3] Max burst size filed for read requests port 0; 000 - 128B; 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */ #define PXP2_REG_RQ_RD_MBS0 0x120160 +/* [RW 3] Max burst size filed for read requests port 1; 000 - 128B; + 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */ +#define PXP2_REG_RQ_RD_MBS1 0x120168 /* [RW 2] Endian mode for src */ #define PXP2_REG_RQ_SRC_ENDIAN_M 0x12019c /* [RW 3] page size in L2P table for SRC module; -4k; -8k; -16k; -32k; -64k; @@ -2000,10 +2127,17 @@ /* [RW 3] Max burst size filed for write requests port 0; 000 - 128B; 001:256B; 010: 512B; */ #define PXP2_REG_RQ_WR_MBS0 0x12015c +/* [RW 3] Max burst size filed for write requests port 1; 000 - 128B; + 001:256B; 010: 512B; */ +#define PXP2_REG_RQ_WR_MBS1 0x120164 /* [RW 10] if Number of entries in dmae fifo will be higer than this threshold then has_payload indication will be asserted; the default value should be equal to > write MBS size! */ #define PXP2_REG_WR_DMAE_TH 0x120368 +/* [RW 10] if Number of entries in usdmdp fifo will be higer than this + threshold then has_payload indication will be asserted; the default value + should be equal to > write MBS size! */ +#define PXP2_REG_WR_USDMDP_TH 0x120348 /* [R 1] debug only: Indication if PSWHST arbiter is idle */ #define PXP_REG_HST_ARB_IS_IDLE 0x103004 /* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means @@ -2021,6 +2155,8 @@ #define PXP_REG_PXP_INT_STS_CLR_0 0x10306c /* [RW 26] Parity mask register #0 read/write */ #define PXP_REG_PXP_PRTY_MASK 0x103094 +/* [R 26] Parity register #0 read */ +#define PXP_REG_PXP_PRTY_STS 0x103088 /* [RW 4] The activity counter initial increment value sent in the load request */ #define QM_REG_ACTCTRINITVAL_0 0x168040 @@ -2127,6 +2263,8 @@ #define QM_REG_QM_INT_STS 0x168438 /* [RW 9] Parity mask register #0 read/write */ #define QM_REG_QM_PRTY_MASK 0x168454 +/* [R 9] Parity register #0 read */ +#define QM_REG_QM_PRTY_STS 0x168448 /* [R 32] Current queues in pipeline: Queues from 32 to 63 */ #define QM_REG_QSTATUS_HIGH 0x16802c /* [R 32] Current queues in pipeline: Queues from 0 to 31 */ @@ -2410,6 +2548,8 @@ #define SRC_REG_SRC_INT_STS 0x404ac /* [RW 3] Parity mask register #0 read/write */ #define SRC_REG_SRC_PRTY_MASK 0x404c8 +/* [R 3] Parity register #0 read */ +#define SRC_REG_SRC_PRTY_STS 0x404bc /* [R 4] Used to read the value of the XX protection CAM occupancy counter. */ #define TCM_REG_CAM_OCCUP 0x5017c /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -2730,6 +2870,8 @@ #define TSDM_REG_TSDM_INT_MASK_1 0x422ac /* [RW 11] Parity mask register #0 read/write */ #define TSDM_REG_TSDM_PRTY_MASK 0x422bc +/* [R 11] Parity register #0 read */ +#define TSDM_REG_TSDM_PRTY_STS 0x422b0 /* [RW 5] The number of time_slots in the arbitration cycle */ #define TSEM_REG_ARB_CYCLE_SIZE 0x180034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -2854,6 +2996,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define TSEM_REG_TSEM_PRTY_MASK_0 0x180120 #define TSEM_REG_TSEM_PRTY_MASK_1 0x180130 +/* [R 32] Parity register #0 read */ +#define TSEM_REG_TSEM_PRTY_STS_0 0x180114 +#define TSEM_REG_TSEM_PRTY_STS_1 0x180124 /* [R 5] Used to read the XX protection CAM occupancy counter. */ #define UCM_REG_CAM_OCCUP 0xe0170 /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -3155,6 +3300,8 @@ #define USDM_REG_USDM_INT_MASK_1 0xc42b0 /* [RW 11] Parity mask register #0 read/write */ #define USDM_REG_USDM_PRTY_MASK 0xc42c0 +/* [R 11] Parity register #0 read */ +#define USDM_REG_USDM_PRTY_STS 0xc42b4 /* [RW 5] The number of time_slots in the arbitration cycle */ #define USEM_REG_ARB_CYCLE_SIZE 0x300034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -3279,6 +3426,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define USEM_REG_USEM_PRTY_MASK_0 0x300130 #define USEM_REG_USEM_PRTY_MASK_1 0x300140 +/* [R 32] Parity register #0 read */ +#define USEM_REG_USEM_PRTY_STS_0 0x300124 +#define USEM_REG_USEM_PRTY_STS_1 0x300134 /* [RW 2] The queue index for registration on Aux1 counter flag. */ #define XCM_REG_AUX1_Q 0x20134 /* [RW 2] Per each decision rule the queue index to register to. */ @@ -3684,6 +3834,8 @@ #define XSDM_REG_XSDM_INT_MASK_1 0x1662ac /* [RW 11] Parity mask register #0 read/write */ #define XSDM_REG_XSDM_PRTY_MASK 0x1662bc +/* [R 11] Parity register #0 read */ +#define XSDM_REG_XSDM_PRTY_STS 0x1662b0 /* [RW 5] The number of time_slots in the arbitration cycle */ #define XSEM_REG_ARB_CYCLE_SIZE 0x280034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -3808,6 +3960,9 @@ /* [RW 32] Parity mask register #0 read/write */ #define XSEM_REG_XSEM_PRTY_MASK_0 0x280130 #define XSEM_REG_XSEM_PRTY_MASK_1 0x280140 +/* [R 32] Parity register #0 read */ +#define XSEM_REG_XSEM_PRTY_STS_0 0x280124 +#define XSEM_REG_XSEM_PRTY_STS_1 0x280134 #define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0) #define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1) #define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) @@ -3847,6 +4002,8 @@ #define EMAC_MDIO_COMM_START_BUSY (1L<<29) #define EMAC_MDIO_MODE_AUTO_POLL (1L<<4) #define EMAC_MDIO_MODE_CLAUSE_45 (1L<<31) +#define EMAC_MDIO_MODE_CLOCK_CNT (0x3fL<<16) +#define EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT 16 #define EMAC_MODE_25G_MODE (1L<<5) #define EMAC_MODE_ACPI_RCVD (1L<<20) #define EMAC_MODE_HALF_DUPLEX (1L<<1) @@ -3874,6 +4031,17 @@ #define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31) #define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3) #define EMAC_TX_MODE_RESET (1L<<0) +#define MISC_REGISTERS_GPIO_1 1 +#define MISC_REGISTERS_GPIO_2 2 +#define MISC_REGISTERS_GPIO_3 3 +#define MISC_REGISTERS_GPIO_CLR_POS 16 +#define MISC_REGISTERS_GPIO_FLOAT (0xffL<<24) +#define MISC_REGISTERS_GPIO_FLOAT_POS 24 +#define MISC_REGISTERS_GPIO_INPUT_HI_Z 2 +#define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1 +#define MISC_REGISTERS_GPIO_OUTPUT_LOW 0 +#define MISC_REGISTERS_GPIO_PORT_SHIFT 4 +#define MISC_REGISTERS_GPIO_SET_POS 8 #define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 #define MISC_REGISTERS_RESET_REG_1_SET 0x584 #define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598 @@ -3891,6 +4059,25 @@ #define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW (0x1<<4) #define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB (0x1<<8) #define MISC_REGISTERS_RESET_REG_3_SET 0x5a4 +#define MISC_REGISTERS_SPIO_4 4 +#define MISC_REGISTERS_SPIO_5 5 +#define MISC_REGISTERS_SPIO_7 7 +#define MISC_REGISTERS_SPIO_CLR_POS 16 +#define MISC_REGISTERS_SPIO_FLOAT (0xffL<<24) +#define GRC_MISC_REGISTERS_SPIO_FLOAT7 0x80000000 +#define GRC_MISC_REGISTERS_SPIO_FLOAT6 0x40000000 +#define GRC_MISC_REGISTERS_SPIO_FLOAT5 0x20000000 +#define GRC_MISC_REGISTERS_SPIO_FLOAT4 0x10000000 +#define MISC_REGISTERS_SPIO_FLOAT_POS 24 +#define MISC_REGISTERS_SPIO_INPUT_HI_Z 2 +#define MISC_REGISTERS_SPIO_INT_OLD_SET_POS 16 +#define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1 +#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0 +#define MISC_REGISTERS_SPIO_SET_POS 8 +#define HW_LOCK_MAX_RESOURCE_VALUE 31 +#define HW_LOCK_RESOURCE_8072_MDIO 0 +#define HW_LOCK_RESOURCE_GPIO 1 +#define HW_LOCK_RESOURCE_SPIO 2 #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) #define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31) #define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9) @@ -3918,6 +4105,7 @@ #define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (1<<3) #define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (1<<2) #define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (1<<22) +#define AEU_INPUTS_ATTN_BITS_SPIO5 (1<<15) #define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (1<<27) #define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (1<<5) #define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (1<<25) @@ -4206,6 +4394,9 @@ #define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE 0x4000 #define MDIO_XGXS_BLOCK2_TX_LN_SWAP 0x11 #define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE 0x8000 +#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G 0x14 +#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS 0x0001 +#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS 0x0010 #define MDIO_XGXS_BLOCK2_TEST_MODE_LANE 0x15 #define MDIO_REG_BANK_GP_STATUS 0x8120 @@ -4362,11 +4553,13 @@ #define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE 0x0001 +#define EXT_PHY_AUTO_NEG_DEVAD 0x7 #define EXT_PHY_OPT_PMA_PMD_DEVAD 0x1 #define EXT_PHY_OPT_WIS_DEVAD 0x2 #define EXT_PHY_OPT_PCS_DEVAD 0x3 #define EXT_PHY_OPT_PHY_XS_DEVAD 0x4 #define EXT_PHY_OPT_CNTL 0x0 +#define EXT_PHY_OPT_CNTL2 0x7 #define EXT_PHY_OPT_PMD_RX_SD 0xa #define EXT_PHY_OPT_PMD_MISC_CNTL 0xca0a #define EXT_PHY_OPT_PHY_IDENTIFIER 0xc800 @@ -4378,11 +4571,24 @@ #define EXT_PHY_OPT_LASI_STATUS 0x9005 #define EXT_PHY_OPT_PCS_STATUS 0x0020 #define EXT_PHY_OPT_XGXS_LANE_STATUS 0x0018 +#define EXT_PHY_OPT_AN_LINK_STATUS 0x8304 +#define EXT_PHY_OPT_AN_CL37_CL73 0x8370 +#define EXT_PHY_OPT_AN_CL37_FD 0xffe4 +#define EXT_PHY_OPT_AN_CL37_AN 0xffe0 +#define EXT_PHY_OPT_AN_ADV 0x11 #define EXT_PHY_KR_PMA_PMD_DEVAD 0x1 #define EXT_PHY_KR_PCS_DEVAD 0x3 #define EXT_PHY_KR_AUTO_NEG_DEVAD 0x7 #define EXT_PHY_KR_CTRL 0x0000 +#define EXT_PHY_KR_STATUS 0x0001 +#define EXT_PHY_KR_AUTO_NEG_COMPLETE 0x0020 +#define EXT_PHY_KR_AUTO_NEG_ADVERT 0x0010 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE 0x0400 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC 0x0800 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH 0x0C00 +#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK 0x0C00 +#define EXT_PHY_KR_LP_AUTO_NEG 0x0013 #define EXT_PHY_KR_CTRL2 0x0007 #define EXT_PHY_KR_PCS_STATUS 0x0020 #define EXT_PHY_KR_PMD_CTRL 0x0096 @@ -4391,4 +4597,8 @@ #define EXT_PHY_KR_MISC_CTRL1 0xca85 #define EXT_PHY_KR_GEN_CTRL 0xca10 #define EXT_PHY_KR_ROM_CODE 0xca19 +#define EXT_PHY_KR_ROM_RESET_INTERNAL_MP 0x0188 +#define EXT_PHY_KR_ROM_MICRO_RESET 0x018a + +#define EXT_PHY_SFX7101_XGXS_TEST1 0xc00a From 49d66772112f40554ba18d037e0601ac3da0bf79 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:53:13 -0800 Subject: [PATCH 810/880] [BNX2X]: Correct RX filtering and MC configuration The configuration of RX filtering needed the following corrections: Drop flags need to be set per Rx queue. Have to tell the microcode to collect drop stats, and properly wait for them to complete when going down. Sometimes we failed to detect proper completion due to a logical error in the wait loop. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 165 ++++++++++++++++++++++++-------------------- drivers/net/bnx2x.h | 5 +- 2 files changed, 92 insertions(+), 78 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 5cd785064ba3..103d3e0f24ba 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -298,8 +298,7 @@ static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) static int bnx2x_mc_assert(struct bnx2x *bp) { - int i, j; - int rc = 0; + int i, j, rc = 0; char last_idx; const char storm[] = {"XTCU"}; const u32 intmem_base[] = { @@ -313,8 +312,9 @@ static int bnx2x_mc_assert(struct bnx2x *bp) for (i = 0; i < 4; i++) { last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET + intmem_base[i]); - BNX2X_ERR("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n", - storm[i], last_idx); + if (last_idx) + BNX2X_LOG("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n", + storm[i], last_idx); /* print the asserts */ for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) { @@ -330,7 +330,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp) intmem_base[i]); if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) { - BNX2X_ERR("DATA %cSTORM_ASSERT_INDEX 0x%x =" + BNX2X_LOG("DATA %cSTORM_ASSERT_INDEX 0x%x =" " 0x%08x 0x%08x 0x%08x 0x%08x\n", storm[i], j, row3, row2, row1, row0); rc++; @@ -349,21 +349,22 @@ static void bnx2x_fw_dump(struct bnx2x *bp) int word; mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104); - printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark); + mark = ((mark + 0x3) & ~0x3); + printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark); for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + offset + 4*word)); data[8] = 0x0; - printk(KERN_ERR PFX "%s", (char *)data); + printk(KERN_CONT "%s", (char *)data); } for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + offset + 4*word)); data[8] = 0x0; - printk(KERN_ERR PFX "%s", (char *)data); + printk(KERN_CONT "%s", (char *)data); } printk("\n" KERN_ERR PFX "end of fw dump\n"); } @@ -428,10 +429,10 @@ static void bnx2x_panic_dump(struct bnx2x *bp) } } - BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_t_idx(%u)" - " def_x_idx(%u) def_att_idx(%u) attn_state(%u)" + BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)" + " def_t_idx(%u) def_att_idx(%u) attn_state(%u)" " spq_prod_idx(%u)\n", - bp->def_c_idx, bp->def_u_idx, bp->def_t_idx, bp->def_x_idx, + bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx, bp->def_att_idx, bp->attn_state, bp->spq_prod_idx); @@ -789,20 +790,20 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp, fp->state = BNX2X_FP_STATE_HALTED; break; - case (RAMROD_CMD_ID_ETH_PORT_DEL | BNX2X_STATE_CLOSING_WAIT4_DELETE): - DP(NETIF_MSG_IFDOWN, "got delete ramrod\n"); - bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; - break; - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid); - bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_DELETED; + DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", + cid); + bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; break; case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); break; + case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n"); + break; + default: BNX2X_ERR("unexpected ramrod (%d) state is %x\n", command, bp->state); @@ -5236,6 +5237,9 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, atten_status_block); def_sb->atten_status_block.status_block_id = id; + bp->def_att_idx = 0; + bp->attn_state = 0; + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); @@ -5270,6 +5274,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, u_def_status_block); def_sb->u_def_status_block.status_block_id = id; + bp->def_u_idx = 0; + REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_USTRORM_INTMEM + @@ -5287,6 +5293,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, c_def_status_block); def_sb->c_def_status_block.status_block_id = id; + bp->def_c_idx = 0; + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_CSTRORM_INTMEM + @@ -5304,6 +5312,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, t_def_status_block); def_sb->t_def_status_block.status_block_id = id; + bp->def_t_idx = 0; + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_TSTRORM_INTMEM + @@ -5321,6 +5331,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, x_def_status_block); def_sb->x_def_status_block.status_block_id = id; + bp->def_x_idx = 0; + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); REG_WR(bp, BAR_XSTRORM_INTMEM + @@ -5333,6 +5345,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp, REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1); + bp->stat_pending = 0; + bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); } @@ -5476,7 +5490,6 @@ static void bnx2x_init_sp_ring(struct bnx2x *bp) bp->spq_left = MAX_SPQ_PENDING; bp->spq_prod_idx = 0; - bp->dsb_sp_prod_idx = 0; bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; bp->spq_prod_bd = bp->spq; bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT; @@ -5553,6 +5566,42 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); } +static void bnx2x_set_client_config(struct bnx2x *bp) +{ +#ifdef BCM_VLAN + int mode = bp->rx_mode; +#endif + int i, port = bp->port; + struct tstorm_eth_client_config tstorm_client = {0}; + + tstorm_client.mtu = bp->dev->mtu; + tstorm_client.statistics_counter_id = 0; + tstorm_client.config_flags = + TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; +#ifdef BCM_VLAN + if (mode && bp->vlgrp) { + tstorm_client.config_flags |= + TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; + DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); + } +#endif + if (mode != BNX2X_RX_MODE_PROMISC) + tstorm_client.drop_flags = + TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR; + + for_each_queue(bp, i) { + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, i), + ((u32 *)&tstorm_client)[0]); + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, i) + 4, + ((u32 *)&tstorm_client)[1]); + } + +/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n", + ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */ +} + static void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { int mode = bp->rx_mode; @@ -5592,41 +5641,9 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp) /* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, ((u32 *)&tstorm_mac_filter)[i]); */ } -} -static void bnx2x_set_client_config(struct bnx2x *bp, int client_id) -{ -#ifdef BCM_VLAN - int mode = bp->rx_mode; -#endif - int port = bp->port; - struct tstorm_eth_client_config tstorm_client = {0}; - - tstorm_client.mtu = bp->dev->mtu; - tstorm_client.statistics_counter_id = 0; - tstorm_client.config_flags = - TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; -#ifdef BCM_VLAN - if (mode && bp->vlgrp) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; - DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); - } -#endif - tstorm_client.drop_flags = (TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR | - TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR | - TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR | - TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, client_id), - ((u32 *)&tstorm_client)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) + 4, - ((u32 *)&tstorm_client)[1]); - -/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n", - ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */ + if (mode != BNX2X_RX_MODE_NONE) + bnx2x_set_client_config(bp); } static void bnx2x_init_internal(struct bnx2x *bp) @@ -5634,7 +5651,6 @@ static void bnx2x_init_internal(struct bnx2x *bp) int port = bp->port; struct tstorm_eth_function_common_config tstorm_config = {0}; struct stats_indication_flags stats_flags = {0}; - int i; if (is_multi(bp)) { tstorm_config.config_flags = MULTI_FLAGS; @@ -5651,10 +5667,6 @@ static void bnx2x_init_internal(struct bnx2x *bp) bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ bnx2x_set_storm_rx_mode(bp); - for_each_queue(bp, i) - bnx2x_set_client_config(bp, i); - - stats_flags.collect_eth = cpu_to_le32(1); REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), @@ -6961,7 +6973,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, mb(); /* state is changed by bnx2x_sp_event()*/ - if (*state_p != state) + if (*state_p == state) return 0; timeout--; @@ -6970,9 +6982,10 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, } /* timeout! */ - BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx); - return -EBUSY; + BNX2X_ERR("timeout %s for state %x on IDX [%d]\n", + poll ? "polling" : "waiting", state, idx); + return -EBUSY; } static int bnx2x_setup_leading(struct bnx2x *bp) @@ -7239,7 +7252,7 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index) /* delete cfc entry */ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); - return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_DELETED, index, + return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index, &(bp->fp[index].state), 1); } @@ -7247,7 +7260,7 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index) static void bnx2x_stop_leading(struct bnx2x *bp) { - + u16 dsb_sp_prod_idx; /* if the other port is handling traffic, this can take a lot of time */ int timeout = 500; @@ -7262,23 +7275,29 @@ static void bnx2x_stop_leading(struct bnx2x *bp) &(bp->fp[0].state), 1)) return; - bp->dsb_sp_prod_idx = *bp->dsb_sp_prod; + dsb_sp_prod_idx = *bp->dsb_sp_prod; /* Send CFC_DELETE ramrod */ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); - /* - Wait for completion. + /* Wait for completion to arrive on default status block we are going to reset the chip anyway so there is not much to do if this times out */ - while (bp->dsb_sp_prod_idx == *bp->dsb_sp_prod && timeout) { - timeout--; - msleep(1); + while ((dsb_sp_prod_idx == *bp->dsb_sp_prod) && timeout) { + timeout--; + msleep(1); } - + if (!timeout) { + DP(NETIF_MSG_IFDOWN, "timeout polling for completion " + "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", + *bp->dsb_sp_prod, dsb_sp_prod_idx); + } + bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + bp->fp[0].state = BNX2X_FP_STATE_CLOSED; } + static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) { u32 reset_code = 0; @@ -8968,9 +8987,7 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) * net_device service functions */ -/* Called with rtnl_lock from vlan functions and also netif_tx_lock - * from set_multicast. - */ +/* called with netif_tx_lock from set_multicast */ static void bnx2x_set_rx_mode(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); @@ -9496,7 +9513,7 @@ static void bnx2x_vlan_rx_register(struct net_device *dev, bp->vlgrp = vlgrp; if (netif_running(dev)) - bnx2x_set_rx_mode(dev); + bnx2x_set_client_config(bp); } #endif diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index dc423e58dad8..d0e5ab1af444 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -1,6 +1,6 @@ /* bnx2x.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * 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 @@ -431,8 +431,6 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_OPEN 0xa0000 #define BNX2X_FP_STATE_HALTING 0xb0000 #define BNX2X_FP_STATE_HALTED 0xc0000 -#define BNX2X_FP_STATE_DELETED 0xd0000 -#define BNX2X_FP_STATE_CLOSE_IRQ 0xe0000 int index; @@ -513,7 +511,6 @@ struct bnx2x { struct eth_spe *spq; dma_addr_t spq_mapping; u16 spq_prod_idx; - u16 dsb_sp_prod_idx; struct eth_spe *spq_prod_bd; struct eth_spe *spq_last_bd; u16 *dsb_sp_prod; From 0e39e645b3e83873d59b865df2b671c822e2182c Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:54:03 -0800 Subject: [PATCH 811/880] [BNX2X]: correct statistics Errors were summed improperly, some stats were missing. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 164 ++++++++++++++++++++++---------------------- drivers/net/bnx2x.h | 4 +- 2 files changed, 83 insertions(+), 85 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 103d3e0f24ba..a35feee513db 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -4972,39 +4972,37 @@ static void bnx2x_update_net_stats(struct bnx2x *bp) nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); - nstats->tx_bytes = - bnx2x_hilo(&estats->total_bytes_transmitted_hi); + nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); - nstats->rx_dropped = estats->checksum_discard + - estats->mac_discard; + nstats->rx_dropped = estats->checksum_discard + estats->mac_discard; nstats->tx_dropped = 0; nstats->multicast = bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi); - nstats->collisions = - estats->single_collision_transmit_frames + - estats->multiple_collision_transmit_frames + - estats->late_collision_frames + - estats->excessive_collision_frames; + nstats->collisions = estats->single_collision_transmit_frames + + estats->multiple_collision_transmit_frames + + estats->late_collision_frames + + estats->excessive_collision_frames; nstats->rx_length_errors = estats->runt_packets_received + estats->jabber_packets_received; - nstats->rx_over_errors = estats->no_buff_discard; + nstats->rx_over_errors = estats->brb_discard + + estats->brb_truncate_discard; nstats->rx_crc_errors = estats->crc_receive_errors; nstats->rx_frame_errors = estats->alignment_errors; - nstats->rx_fifo_errors = estats->brb_discard + - estats->brb_truncate_discard; + nstats->rx_fifo_errors = estats->no_buff_discard; nstats->rx_missed_errors = estats->xxoverflow_discard; nstats->rx_errors = nstats->rx_length_errors + nstats->rx_over_errors + nstats->rx_crc_errors + nstats->rx_frame_errors + - nstats->rx_fifo_errors; + nstats->rx_fifo_errors + + nstats->rx_missed_errors; nstats->tx_aborted_errors = estats->late_collision_frames + - estats->excessive_collision_frames; + estats->excessive_collision_frames; nstats->tx_carrier_errors = estats->false_carrier_detections; nstats->tx_fifo_errors = 0; nstats->tx_heartbeat_errors = 0; @@ -8755,81 +8753,87 @@ static void bnx2x_self_test(struct net_device *dev, static struct { char string[ETH_GSTRING_LEN]; } bnx2x_stats_str_arr[BNX2X_NUM_STATS] = { - { "rx_bytes"}, /* 0 */ - { "rx_error_bytes"}, /* 1 */ - { "tx_bytes"}, /* 2 */ - { "tx_error_bytes"}, /* 3 */ - { "rx_ucast_packets"}, /* 4 */ - { "rx_mcast_packets"}, /* 5 */ - { "rx_bcast_packets"}, /* 6 */ - { "tx_ucast_packets"}, /* 7 */ - { "tx_mcast_packets"}, /* 8 */ - { "tx_bcast_packets"}, /* 9 */ - { "tx_mac_errors"}, /* 10 */ - { "tx_carrier_errors"}, /* 11 */ - { "rx_crc_errors"}, /* 12 */ - { "rx_align_errors"}, /* 13 */ - { "tx_single_collisions"}, /* 14 */ - { "tx_multi_collisions"}, /* 15 */ - { "tx_deferred"}, /* 16 */ - { "tx_excess_collisions"}, /* 17 */ - { "tx_late_collisions"}, /* 18 */ - { "tx_total_collisions"}, /* 19 */ - { "rx_fragments"}, /* 20 */ - { "rx_jabbers"}, /* 21 */ - { "rx_undersize_packets"}, /* 22 */ - { "rx_oversize_packets"}, /* 23 */ - { "rx_xon_frames"}, /* 24 */ - { "rx_xoff_frames"}, /* 25 */ - { "tx_xon_frames"}, /* 26 */ - { "tx_xoff_frames"}, /* 27 */ - { "rx_mac_ctrl_frames"}, /* 28 */ - { "rx_filtered_packets"}, /* 29 */ - { "rx_discards"}, /* 30 */ + { "rx_bytes"}, + { "rx_error_bytes"}, + { "tx_bytes"}, + { "tx_error_bytes"}, + { "rx_ucast_packets"}, + { "rx_mcast_packets"}, + { "rx_bcast_packets"}, + { "tx_ucast_packets"}, + { "tx_mcast_packets"}, + { "tx_bcast_packets"}, + { "tx_mac_errors"}, /* 10 */ + { "tx_carrier_errors"}, + { "rx_crc_errors"}, + { "rx_align_errors"}, + { "tx_single_collisions"}, + { "tx_multi_collisions"}, + { "tx_deferred"}, + { "tx_excess_collisions"}, + { "tx_late_collisions"}, + { "tx_total_collisions"}, + { "rx_fragments"}, /* 20 */ + { "rx_jabbers"}, + { "rx_undersize_packets"}, + { "rx_oversize_packets"}, + { "rx_xon_frames"}, + { "rx_xoff_frames"}, + { "tx_xon_frames"}, + { "tx_xoff_frames"}, + { "rx_mac_ctrl_frames"}, + { "rx_filtered_packets"}, + { "rx_discards"}, /* 30 */ + { "brb_discard"}, + { "brb_truncate"}, + { "xxoverflow"} }; #define STATS_OFFSET32(offset_name) \ (offsetof(struct bnx2x_eth_stats, offset_name) / 4) static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = { - STATS_OFFSET32(total_bytes_received_hi), /* 0 */ - STATS_OFFSET32(stat_IfHCInBadOctets_hi), /* 1 */ - STATS_OFFSET32(total_bytes_transmitted_hi), /* 2 */ - STATS_OFFSET32(stat_IfHCOutBadOctets_hi), /* 3 */ - STATS_OFFSET32(total_unicast_packets_received_hi), /* 4 */ - STATS_OFFSET32(total_multicast_packets_received_hi), /* 5 */ - STATS_OFFSET32(total_broadcast_packets_received_hi), /* 6 */ - STATS_OFFSET32(total_unicast_packets_transmitted_hi), /* 7 */ - STATS_OFFSET32(total_multicast_packets_transmitted_hi), /* 8 */ - STATS_OFFSET32(total_broadcast_packets_transmitted_hi), /* 9 */ - STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */ - STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), /* 11 */ - STATS_OFFSET32(crc_receive_errors), /* 12 */ - STATS_OFFSET32(alignment_errors), /* 13 */ - STATS_OFFSET32(single_collision_transmit_frames), /* 14 */ - STATS_OFFSET32(multiple_collision_transmit_frames), /* 15 */ - STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), /* 16 */ - STATS_OFFSET32(excessive_collision_frames), /* 17 */ - STATS_OFFSET32(late_collision_frames), /* 18 */ - STATS_OFFSET32(number_of_bugs_found_in_stats_spec), /* 19 */ - STATS_OFFSET32(runt_packets_received), /* 20 */ - STATS_OFFSET32(jabber_packets_received), /* 21 */ - STATS_OFFSET32(error_runt_packets_received), /* 22 */ - STATS_OFFSET32(error_jabber_packets_received), /* 23 */ - STATS_OFFSET32(pause_xon_frames_received), /* 24 */ - STATS_OFFSET32(pause_xoff_frames_received), /* 25 */ - STATS_OFFSET32(pause_xon_frames_transmitted), /* 26 */ - STATS_OFFSET32(pause_xoff_frames_transmitted), /* 27 */ - STATS_OFFSET32(control_frames_received), /* 28 */ - STATS_OFFSET32(mac_filter_discard), /* 29 */ - STATS_OFFSET32(no_buff_discard), /* 30 */ + STATS_OFFSET32(total_bytes_received_hi), + STATS_OFFSET32(stat_IfHCInBadOctets_hi), + STATS_OFFSET32(total_bytes_transmitted_hi), + STATS_OFFSET32(stat_IfHCOutBadOctets_hi), + STATS_OFFSET32(total_unicast_packets_received_hi), + STATS_OFFSET32(total_multicast_packets_received_hi), + STATS_OFFSET32(total_broadcast_packets_received_hi), + STATS_OFFSET32(total_unicast_packets_transmitted_hi), + STATS_OFFSET32(total_multicast_packets_transmitted_hi), + STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */ + STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), + STATS_OFFSET32(crc_receive_errors), + STATS_OFFSET32(alignment_errors), + STATS_OFFSET32(single_collision_transmit_frames), + STATS_OFFSET32(multiple_collision_transmit_frames), + STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), + STATS_OFFSET32(excessive_collision_frames), + STATS_OFFSET32(late_collision_frames), + STATS_OFFSET32(number_of_bugs_found_in_stats_spec), + STATS_OFFSET32(runt_packets_received), /* 20 */ + STATS_OFFSET32(jabber_packets_received), + STATS_OFFSET32(error_runt_packets_received), + STATS_OFFSET32(error_jabber_packets_received), + STATS_OFFSET32(pause_xon_frames_received), + STATS_OFFSET32(pause_xoff_frames_received), + STATS_OFFSET32(pause_xon_frames_transmitted), + STATS_OFFSET32(pause_xoff_frames_transmitted), + STATS_OFFSET32(control_frames_received), + STATS_OFFSET32(mac_filter_discard), + STATS_OFFSET32(no_buff_discard), /* 30 */ + STATS_OFFSET32(brb_discard), + STATS_OFFSET32(brb_truncate_discard), + STATS_OFFSET32(xxoverflow_discard) }; static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = { 8, 0, 8, 0, 8, 8, 8, 8, 8, 8, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, + 4, 4, 4, 4 }; static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) @@ -9372,11 +9376,6 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static struct net_device_stats *bnx2x_get_stats(struct net_device *dev) -{ - return &dev->stats; -} - /* Called with rtnl_lock */ static int bnx2x_open(struct net_device *dev) { @@ -9784,7 +9783,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, dev->hard_start_xmit = bnx2x_start_xmit; dev->watchdog_timeo = TX_TIMEOUT; - dev->get_stats = bnx2x_get_stats; dev->ethtool_ops = &bnx2x_ethtool_ops; dev->open = bnx2x_open; dev->stop = bnx2x_close; diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index d0e5ab1af444..e2a36e850fc2 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -854,8 +854,8 @@ struct bnx2x { #define MAX_SPQ_PENDING 8 -#define BNX2X_NUM_STATS 31 -#define BNX2X_NUM_TESTS 2 +#define BNX2X_NUM_STATS 34 +#define BNX2X_NUM_TESTS 1 #define DPM_TRIGER_TYPE 0x40 From 615f8fd9c2ab475c420d5baa7def37c5cb0d50d3 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:54:54 -0800 Subject: [PATCH 812/880] [BNX2X]: fix MSI-X/INT#A errata Errata A0.158 workaround. Running in INT#A mode after running with MSI-X fails due to a PCI core bug. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index a35feee513db..6f987fa10a6d 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -443,7 +443,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); } -static void bnx2x_enable_int(struct bnx2x *bp) +static void bnx2x_int_enable(struct bnx2x *bp) { int port = bp->port; u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -456,18 +456,26 @@ static void bnx2x_enable_int(struct bnx2x *bp) HC_CONFIG_0_REG_ATTN_BIT_EN_0); } else { val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | + HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | HC_CONFIG_0_REG_INT_LINE_EN_0 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); + + /* Errata A0.158 workaround */ + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n", + val, port, addr, msix); + + REG_WR(bp, addr, val); + val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; } - DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) msi %d\n", + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n", val, port, addr, msix); REG_WR(bp, addr, val); } -static void bnx2x_disable_int(struct bnx2x *bp) +static void bnx2x_int_disable(struct bnx2x *bp) { int port = bp->port; u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -486,7 +494,7 @@ static void bnx2x_disable_int(struct bnx2x *bp) BNX2X_ERR("BUG! proper val not read from IGU!\n"); } -static void bnx2x_disable_int_sync(struct bnx2x *bp) +static void bnx2x_int_disable_sync(struct bnx2x *bp) { int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; @@ -494,7 +502,7 @@ static void bnx2x_disable_int_sync(struct bnx2x *bp) atomic_inc(&bp->intr_sem); /* prevent the HW from sending interrupts */ - bnx2x_disable_int(bp); + bnx2x_int_disable(bp); /* make sure all ISRs are done */ if (msix) { @@ -5710,7 +5718,7 @@ static void bnx2x_nic_init(struct bnx2x *bp) bnx2x_init_internal(bp); bnx2x_init_stats(bp); bnx2x_init_ind_table(bp); - bnx2x_enable_int(bp); + bnx2x_int_enable(bp); } @@ -7154,7 +7162,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) napi_disable(&bnx2x_fp(bp, i, napi)); int_disable: - bnx2x_disable_int_sync(bp); + bnx2x_int_disable_sync(bp); bnx2x_free_skbs(bp); bnx2x_free_irq(bp); @@ -7174,7 +7182,7 @@ static void bnx2x_netif_stop(struct bnx2x *bp) bp->rx_mode = BNX2X_RX_MODE_NONE; bnx2x_set_storm_rx_mode(bp); - bnx2x_disable_int_sync(bp); + bnx2x_int_disable_sync(bp); bnx2x_link_reset(bp); for_each_queue(bp, i) From 877e9aa4c31d8d1670b21824b819929435f46579 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:55:53 -0800 Subject: [PATCH 813/880] [BNX2X]: fix HW attentions and error handling Some of the HW attentions, used to indicate an error were not properly acked. This will cause the driver to endlessly receive interrupts when such an error happens. Had to break the code into smaller chunks because it got too nested. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 229 +++++++++++++++++++++++++++++--------------- 1 file changed, 150 insertions(+), 79 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 6f987fa10a6d..b99e3b72fac6 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -4089,8 +4089,8 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8; u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : MISC_REG_AEU_MASK_ATTN_FUNC_0; - u32 nig_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : - NIG_REG_MASK_INTERRUPT_PORT0; + u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : + NIG_REG_MASK_INTERRUPT_PORT0; if (~bp->aeu_mask & (asserted & 0xff)) BNX2X_ERR("IGU ERROR\n"); @@ -4108,15 +4108,11 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) if (asserted & ATTN_HARD_WIRED_MASK) { if (asserted & ATTN_NIG_FOR_FUNC) { - u32 nig_status_port; - u32 nig_int_addr = port ? - NIG_REG_STATUS_INTERRUPT_PORT1 : - NIG_REG_STATUS_INTERRUPT_PORT0; - bp->nig_mask = REG_RD(bp, nig_mask_addr); - REG_WR(bp, nig_mask_addr, 0); + /* save nig interrupt mask */ + bp->nig_mask = REG_RD(bp, nig_int_mask_addr); + REG_WR(bp, nig_int_mask_addr, 0); - nig_status_port = REG_RD(bp, nig_int_addr); bnx2x_link_update(bp); /* handle unicore attn? */ @@ -4169,15 +4165,132 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) /* now set back the mask */ if (asserted & ATTN_NIG_FOR_FUNC) - REG_WR(bp, nig_mask_addr, bp->nig_mask); + REG_WR(bp, nig_int_mask_addr, bp->nig_mask); } -static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) +static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) { int port = bp->port; - int index; + int reg_offset; + u32 val; + + if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) { + + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : + MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + + val = REG_RD(bp, reg_offset); + val &= ~AEU_INPUTS_ATTN_BITS_SPIO5; + REG_WR(bp, reg_offset, val); + + BNX2X_ERR("SPIO5 hw attention\n"); + + switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) { + case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G: + /* Fan failure attention */ + + /* The PHY reset is controled by GPIO 1 */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + /* Low power mode is controled by GPIO 2 */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW); + /* mark the failure */ + bp->ext_phy_config &= + ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; + bp->ext_phy_config |= + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; + SHMEM_WR(bp, + dev_info.port_hw_config[port]. + external_phy_config, + bp->ext_phy_config); + /* log the failure */ + printk(KERN_ERR PFX "Fan Failure on Network" + " Controller %s has caused the driver to" + " shutdown the card to prevent permanent" + " damage. Please contact Dell Support for" + " assistance\n", bp->dev->name); + break; + + default: + break; + } + } +} + +static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn) +{ + u32 val; + + if (attn & BNX2X_DOORQ_ASSERT) { + + val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR); + BNX2X_ERR("DB hw attention 0x%x\n", val); + /* DORQ discard attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from DORQ\n"); + } +} + +static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) +{ + u32 val; + + if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { + + val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR); + BNX2X_ERR("CFC hw attention 0x%x\n", val); + /* CFC error attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from CFC\n"); + } + + if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { + + val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); + BNX2X_ERR("PXP hw attention 0x%x\n", val); + /* RQ_USDMDP_FIFO_OVERFLOW */ + if (val & 0x18000) + BNX2X_ERR("FATAL error from PXP\n"); + } +} + +static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) +{ + if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) { + + if (attn & BNX2X_MC_ASSERT_BITS) { + + BNX2X_ERR("MC assert!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0); + bnx2x_panic(); + + } else if (attn & BNX2X_MCP_ASSERT) { + + BNX2X_ERR("MCP assert!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0); + bnx2x_mc_assert(bp); + + } else + BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn); + } + + if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) { + + REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff); + BNX2X_ERR("LATCHED attention 0x%x (masked)\n", attn); + } +} + +static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) +{ struct attn_route attn; struct attn_route group_mask; + int port = bp->port; + int index; u32 reg_addr; u32 val; @@ -4198,64 +4311,14 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) DP(NETIF_MSG_HW, "group[%d]: %llx\n", index, (unsigned long long)group_mask.sig[0]); - if (attn.sig[3] & group_mask.sig[3] & - EVEREST_GEN_ATTN_IN_USE_MASK) { - - if (attn.sig[3] & BNX2X_MC_ASSERT_BITS) { - - BNX2X_ERR("MC assert!\n"); - bnx2x_panic(); - - } else if (attn.sig[3] & BNX2X_MCP_ASSERT) { - - BNX2X_ERR("MCP assert!\n"); - REG_WR(bp, - MISC_REG_AEU_GENERAL_ATTN_11, 0); - bnx2x_mc_assert(bp); - - } else { - BNX2X_ERR("UNKOWEN HW ASSERT!\n"); - } - } - - if (attn.sig[1] & group_mask.sig[1] & - BNX2X_DOORQ_ASSERT) { - - val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR); - BNX2X_ERR("DB hw attention 0x%x\n", val); - /* DORQ discard attention */ - if (val & 0x2) - BNX2X_ERR("FATAL error from DORQ\n"); - } - - if (attn.sig[2] & group_mask.sig[2] & - AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { - - val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR); - BNX2X_ERR("CFC hw attention 0x%x\n", val); - /* CFC error attention */ - if (val & 0x2) - BNX2X_ERR("FATAL error from CFC\n"); - } - - if (attn.sig[2] & group_mask.sig[2] & - AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { - - val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); - BNX2X_ERR("PXP hw attention 0x%x\n", val); - /* RQ_USDMDP_FIFO_OVERFLOW */ - if (val & 0x18000) - BNX2X_ERR("FATAL error from PXP\n"); - } - - if (attn.sig[3] & group_mask.sig[3] & - EVEREST_LATCHED_ATTN_IN_USE_MASK) { - - REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, - 0x7ff); - DP(NETIF_MSG_HW, "got latched bits 0x%x\n", - attn.sig[3]); - } + bnx2x_attn_int_deasserted3(bp, + attn.sig[3] & group_mask.sig[3]); + bnx2x_attn_int_deasserted1(bp, + attn.sig[1] & group_mask.sig[1]); + bnx2x_attn_int_deasserted2(bp, + attn.sig[2] & group_mask.sig[2]); + bnx2x_attn_int_deasserted0(bp, + attn.sig[0] & group_mask.sig[0]); if ((attn.sig[0] & group_mask.sig[0] & HW_INTERRUT_ASSERT_SET_0) || @@ -4263,7 +4326,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) HW_INTERRUT_ASSERT_SET_1) || (attn.sig[2] & group_mask.sig[2] & HW_INTERRUT_ASSERT_SET_2)) - BNX2X_ERR("FATAL HW block attention\n"); + BNX2X_ERR("FATAL HW block attention" + " set0 0x%x set1 0x%x" + " set2 0x%x\n", + (attn.sig[0] & group_mask.sig[0] & + HW_INTERRUT_ASSERT_SET_0), + (attn.sig[1] & group_mask.sig[1] & + HW_INTERRUT_ASSERT_SET_1), + (attn.sig[2] & group_mask.sig[2] & + HW_INTERRUT_ASSERT_SET_2)); if ((attn.sig[0] & group_mask.sig[0] & HW_PRTY_ASSERT_SET_0) || @@ -4271,7 +4342,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) HW_PRTY_ASSERT_SET_1) || (attn.sig[2] & group_mask.sig[2] & HW_PRTY_ASSERT_SET_2)) - BNX2X_ERR("FATAL HW block parity attention\n"); + BNX2X_ERR("FATAL HW block parity attention\n"); } } @@ -4336,7 +4407,7 @@ static void bnx2x_sp_task(struct work_struct *work) /* Return here if interrupt is disabled */ if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n"); return; } @@ -4346,12 +4417,11 @@ static void bnx2x_sp_task(struct work_struct *work) DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status); - if (status & 0x1) { - /* HW attentions */ + /* HW attentions */ + if (status & 0x1) bnx2x_attn_int(bp); - } - /* CStorm events: query_stats, cfc delete ramrods */ + /* CStorm events: query_stats, port delete ramrod */ if (status & 0x2) bp->stat_pending = 0; @@ -4365,6 +4435,7 @@ static void bnx2x_sp_task(struct work_struct *work) IGU_INT_NOP, 1); bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx), IGU_INT_ENABLE, 1); + } static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) @@ -4374,11 +4445,11 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) /* Return here if interrupt is disabled */ if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n"); return IRQ_HANDLED; } - bnx2x_ack_sb(bp, 16, XSTORM_ID, 0, IGU_INT_DISABLE, 0); + bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) From 228241eb58ad13e7cf2ddd9c92eabb5c3055cf5c Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:56:57 -0800 Subject: [PATCH 814/880] [BNX2X]: fix slowpath races and locking Fixed locking between fastpath and slowpath operations. Corrected order of traffic disabling to prevent race when going down under traffic. - first have the microcode drop all incoming packets - then do the slowpath stuff - only then reset the MAC Got rid of in_reset_task. Remove_one() and friends would deference a null pointer if init_one failed. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 213 ++++++++++++++++++++++++-------------------- drivers/net/bnx2x.h | 3 - 2 files changed, 116 insertions(+), 100 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index b99e3b72fac6..d21599cfeb89 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -6881,14 +6881,11 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) "state(%x)\n", i, bp->msix_table[i + 1].vector, bnx2x_fp(bp, i, state)); - if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) { - - free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]); - bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_CLOSED; - - } else - DP(NETIF_MSG_IFDOWN, "irq not freed\n"); + if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) + BNX2X_ERR("IRQ of fp #%d being freed while " + "state != closed\n", i); + free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]); } } @@ -6918,7 +6915,7 @@ static int bnx2x_enable_msix(struct bnx2x *bp) if (pci_enable_msix(bp->pdev, &bp->msix_table[0], bp->num_queues + 1)){ - BNX2X_ERR("failed to enable msix\n"); + BNX2X_LOG("failed to enable MSI-X\n"); return -1; } @@ -6935,8 +6932,6 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) int i, rc; - DP(NETIF_MSG_IFUP, "about to request sp irq\n"); - rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0, bp->dev->name, bp->dev); @@ -6951,7 +6946,8 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) bp->dev->name, &bp->fp[i]); if (rc) { - BNX2X_ERR("request fp #%d irq failed\n", i); + BNX2X_ERR("request fp #%d irq failed " + "rc %d\n", i, rc); bnx2x_free_msix_irqs(bp); return -EBUSY; } @@ -7084,12 +7080,13 @@ static int bnx2x_setup_multi(struct bnx2x *bp, int index) /* reset IGU state */ bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + /* SETUP ramrod */ bp->fp[index].state = BNX2X_FP_STATE_OPENING; bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0); /* Wait for completion */ return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, - &(bp->fp[index].state), 1); + &(bp->fp[index].state), 0); } @@ -7099,8 +7096,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev); static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) { - int rc; - int i = 0; + u32 load_code; + int i; bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; @@ -7110,12 +7107,17 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) initialized, otherwise - not. */ if (!nomcp) { - rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); - if (rc == FW_MSG_CODE_DRV_LOAD_REFUSED) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); + if (!load_code) { + BNX2X_ERR("MCP response failure, unloading\n"); + return -EBUSY; + } + if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { + BNX2X_ERR("MCP refused load request, unloading\n"); return -EBUSY; /* other port in diagnostic mode */ } } else { - rc = FW_MSG_CODE_DRV_LOAD_COMMON; + load_code = FW_MSG_CODE_DRV_LOAD_COMMON; } /* if we can't use msix we only need one fp, @@ -7153,13 +7155,13 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) if (bp->flags & USING_MSIX_FLAG) { if (bnx2x_req_msix_irqs(bp)) { pci_disable_msix(bp->pdev); - goto out_error; + goto load_error; } } else { if (bnx2x_req_irq(bp)) { BNX2X_ERR("IRQ request failed, aborting\n"); - goto out_error; + goto load_error; } } } @@ -7170,9 +7172,10 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) /* Initialize HW */ - if (bnx2x_function_init(bp, (rc == FW_MSG_CODE_DRV_LOAD_COMMON))) { + if (bnx2x_function_init(bp, + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON))) { BNX2X_ERR("HW init failed, aborting\n"); - goto out_error; + goto load_error; } @@ -7184,11 +7187,10 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) /* Send LOAD_DONE command to MCP */ if (!nomcp) { - rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); - DP(NETIF_MSG_IFUP, "rc = 0x%x\n", rc); - if (!rc) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + if (!load_code) { BNX2X_ERR("MCP response failure, unloading\n"); - goto int_disable; + goto load_int_disable; } } @@ -7200,11 +7202,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) napi_enable(&bnx2x_fp(bp, i, napi)); if (bnx2x_setup_leading(bp)) - goto stop_netif; + goto load_stop_netif; for_each_nondefault_queue(bp, i) if (bnx2x_setup_multi(bp, i)) - goto stop_netif; + goto load_stop_netif; bnx2x_set_mac_addr(bp); @@ -7228,42 +7230,24 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) return 0; -stop_netif: +load_stop_netif: for_each_queue(bp, i) napi_disable(&bnx2x_fp(bp, i, napi)); -int_disable: +load_int_disable: bnx2x_int_disable_sync(bp); bnx2x_free_skbs(bp); bnx2x_free_irq(bp); -out_error: +load_error: bnx2x_free_mem(bp); /* TBD we really need to reset the chip if we want to recover from this */ - return rc; + return -EBUSY; } -static void bnx2x_netif_stop(struct bnx2x *bp) -{ - int i; - - bp->rx_mode = BNX2X_RX_MODE_NONE; - bnx2x_set_storm_rx_mode(bp); - - bnx2x_int_disable_sync(bp); - bnx2x_link_reset(bp); - - for_each_queue(bp, i) - napi_disable(&bnx2x_fp(bp, i, napi)); - - if (netif_running(bp->dev)) { - netif_tx_disable(bp->dev); - bp->dev->trans_start = jiffies; /* prevent tx timeout */ - } -} static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) { @@ -7354,7 +7338,7 @@ static void bnx2x_stop_leading(struct bnx2x *bp) dsb_sp_prod_idx = *bp->dsb_sp_prod; - /* Send CFC_DELETE ramrod */ + /* Send PORT_DELETE ramrod */ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); /* Wait for completion to arrive on default status block @@ -7375,35 +7359,48 @@ static void bnx2x_stop_leading(struct bnx2x *bp) } -static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) +static int bnx2x_nic_unload(struct bnx2x *bp, int free_irq) { u32 reset_code = 0; - int rc; - int i; + int i, timeout; bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; - /* Calling flush_scheduled_work() may deadlock because - * linkwatch_event() may be on the workqueue and it will try to get - * the rtnl_lock which we are holding. - */ + del_timer_sync(&bp->timer); - while (bp->in_reset_task) - msleep(1); + bp->rx_mode = BNX2X_RX_MODE_NONE; + bnx2x_set_storm_rx_mode(bp); - /* Delete the timer: do it before disabling interrupts, as it - may be still STAT_QUERY ramrod pending after stopping the timer */ - del_timer_sync(&bp->timer); + if (netif_running(bp->dev)) { + netif_tx_disable(bp->dev); + bp->dev->trans_start = jiffies; /* prevent tx timeout */ + } + + /* Wait until all fast path tasks complete */ + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + timeout = 1000; + while (bnx2x_has_work(fp) && (timeout--)) + msleep(1); + if (!timeout) + BNX2X_ERR("timeout waiting for queue[%d]\n", i); + } /* Wait until stat ramrod returns and all SP tasks complete */ - while (bp->stat_pending && (bp->spq_left != MAX_SPQ_PENDING)) + timeout = 1000; + while ((bp->stat_pending || (bp->spq_left != MAX_SPQ_PENDING)) && + (timeout--)) msleep(1); - /* Stop fast path, disable MAC, disable interrupts, disable napi */ - bnx2x_netif_stop(bp); + for_each_queue(bp, i) + napi_disable(&bnx2x_fp(bp, i, napi)); + /* Disable interrupts after Tx and Rx are disabled on stack level */ + bnx2x_int_disable_sync(bp); if (bp->flags & NO_WOL_FLAG) reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP; + else if (bp->wol) { u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1; u8 *mac_addr = bp->dev->dev_addr; @@ -7420,28 +7417,37 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val); reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN; + } else reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + /* Close multi and leading connections */ for_each_nondefault_queue(bp, i) if (bnx2x_stop_multi(bp, i)) - goto error; - + goto unload_error; bnx2x_stop_leading(bp); + if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) || + (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) { + DP(NETIF_MSG_IFDOWN, "failed to close leading properly!" + "state 0x%x fp[0].state 0x%x", + bp->state, bp->fp[0].state); + } + +unload_error: + bnx2x_link_reset(bp); -error: if (!nomcp) - rc = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code); else - rc = FW_MSG_CODE_DRV_UNLOAD_COMMON; + reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; /* Release IRQs */ - if (fre_irq) + if (free_irq) bnx2x_free_irq(bp); /* Reset the chip */ - bnx2x_reset_chip(bp, rc); + bnx2x_reset_chip(bp, reset_code); /* Report UNLOAD_DONE to MCP */ if (!nomcp) @@ -7452,8 +7458,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; - /* Set link down */ - bp->link_up = 0; + netif_carrier_off(bp->dev); return 0; @@ -9468,16 +9473,13 @@ static int bnx2x_open(struct net_device *dev) /* Called with rtnl_lock */ static int bnx2x_close(struct net_device *dev) { - int rc; struct bnx2x *bp = netdev_priv(dev); /* Unload the driver, release IRQs */ - rc = bnx2x_nic_unload(bp, 1); - if (rc) { - BNX2X_ERR("bnx2x_nic_unload failed: %d\n", rc); - return rc; - } - bnx2x_set_power_state(bp, PCI_D3hot); + bnx2x_nic_unload(bp, 1); + + if (!CHIP_REV_IS_SLOW(bp)) + bnx2x_set_power_state(bp, PCI_D3hot); return 0; } @@ -9620,14 +9622,18 @@ static void bnx2x_reset_task(struct work_struct *work) if (!netif_running(bp->dev)) return; - bp->in_reset_task = 1; + rtnl_lock(); - bnx2x_netif_stop(bp); + if (bp->state != BNX2X_STATE_OPEN) { + DP(NETIF_MSG_TX_ERR, "state is %x, returning\n", bp->state); + goto reset_task_exit; + } bnx2x_nic_unload(bp, 0); bnx2x_nic_load(bp, 0); - bp->in_reset_task = 0; +reset_task_exit: + rtnl_unlock(); } static int __devinit bnx2x_init_board(struct pci_dev *pdev, @@ -9708,8 +9714,6 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev, spin_lock_init(&bp->phy_lock); - bp->in_reset_task = 0; - INIT_WORK(&bp->reset_task, bnx2x_reset_task); INIT_WORK(&bp->sp_task, bnx2x_sp_task); @@ -9916,10 +9920,16 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, static void __devexit bnx2x_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp = netdev_priv(dev); + struct bnx2x *bp; + + if (!dev) { + /* we get here if init_one() fails */ + printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n"); + return; + } + + bp = netdev_priv(dev); - flush_scheduled_work(); - /*tasklet_kill(&bp->sp_task);*/ unregister_netdev(dev); if (bp->regview) @@ -9937,34 +9947,43 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp = netdev_priv(dev); - int rc; + struct bnx2x *bp; + + if (!dev) + return 0; if (!netif_running(dev)) return 0; - rc = bnx2x_nic_unload(bp, 0); - if (!rc) - return rc; + bp = netdev_priv(dev); + + bnx2x_nic_unload(bp, 0); netif_device_detach(dev); - pci_save_state(pdev); + pci_save_state(pdev); bnx2x_set_power_state(bp, pci_choose_state(pdev, state)); + return 0; } static int bnx2x_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp = netdev_priv(dev); + struct bnx2x *bp; int rc; + if (!dev) { + printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n"); + return -ENODEV; + } + if (!netif_running(dev)) return 0; - pci_restore_state(pdev); + bp = netdev_priv(dev); + pci_restore_state(pdev); bnx2x_set_power_state(bp, PCI_D0); netif_device_attach(dev); diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index e2a36e850fc2..6a86afbc7525 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -545,8 +545,6 @@ struct bnx2x { spinlock_t phy_lock; struct work_struct reset_task; - u16 in_reset_task; - struct work_struct sp_task; struct timer_list timer; @@ -560,7 +558,6 @@ struct bnx2x { #define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0) #define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000) -#define CHIP_NUM_5710 0x57100000 #define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000) #define CHIP_REV_Ax 0x00000000 From e8717a47266b1527e620ddf262613b9d010bbbe7 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:57:29 -0800 Subject: [PATCH 815/880] [BNX2X]: Prevent PCI queue overflow Limit traffic through an internal queue to prevent overflow. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x_init.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index 04f93bff2ef4..dcaecc53bdb1 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h @@ -1,6 +1,6 @@ /* bnx2x_init.h: Broadcom Everest network driver. * - * Copyright (c) 2007 Broadcom Corporation + * Copyright (c) 2007-2008 Broadcom Corporation * * 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 @@ -409,7 +409,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp) pci_read_config_word(bp->pdev, bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val); - DP(NETIF_MSG_HW, "read 0x%x from devctl\n", val); + DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val); w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5); r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12); @@ -472,10 +472,14 @@ static void bnx2x_init_pxp(struct bnx2x *bp) REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val); REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order); - REG_WR(bp, PXP2_REG_RQ_WR_MBS0 + 8, w_order); + REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order); REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); - REG_WR(bp, PXP2_REG_RQ_RD_MBS0 + 8, r_order); + REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); + if (r_order == MAX_RD_ORD) + REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); + + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16); } From 96fc1784007bf194399759e9b7d9c836c7bbda2a Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:57:55 -0800 Subject: [PATCH 816/880] [BNX2X]: Fix Xmit bugs Several endianity corrections in start_xmit() Fixed TSO bug where packets were missing the TCP flags. Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 12 +++++++----- drivers/net/bnx2x.h | 3 +++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index d21599cfeb89..2db0427b0c92 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -9269,7 +9269,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) /* for now NS flag is not used in Linux */ pbd->global_data = (len | - ((skb->protocol == ETH_P_8021Q) << + ((skb->protocol == ntohs(ETH_P_8021Q)) << ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); pbd->ip_hlen = ip_hdrlen(skb) / 2; pbd->total_hlen = cpu_to_le16(len + pbd->ip_hlen); @@ -9278,7 +9278,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_TCP_CSUM; - pbd->tcp_flags = htonl(tcp_flag_word(skb)) & 0xFFFF; + pbd->tcp_flags = pbd_tcp_flags(skb); pbd->total_hlen += cpu_to_le16(tcp_hdrlen(skb) / 2); pbd->tcp_pseudo_csum = swab16(th->check); @@ -9322,7 +9322,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb_shinfo(skb)->gso_size && (skb->len > (bp->dev->mtu + ETH_HLEN))) { - int hlen = 2 * le32_to_cpu(pbd->total_hlen); + int hlen = 2 * le16_to_cpu(pbd->total_hlen); DP(NETIF_MSG_TX_QUEUED, "TSO packet len %d hlen %d total len %d tso size %d\n", @@ -9439,9 +9439,11 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %u bd %d\n", nbd, bd_prod); - fp->hw_tx_prods->bds_prod += cpu_to_le16(nbd); + fp->hw_tx_prods->bds_prod = + cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd); mb(); /* FW restriction: must not reorder writing nbd and packets */ - fp->hw_tx_prods->packets_prod += cpu_to_le32(1); + fp->hw_tx_prods->packets_prod = + cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1); DOORBELL(bp, fp_index, 0); mmiowb(); diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 6a86afbc7525..4f0c0d31e7c1 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -869,6 +869,9 @@ struct bnx2x { #define PCICFG_LINK_SPEED_SHIFT 16 #define BMAC_CONTROL_RX_ENABLE 2 + +#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff) + /* stuff added to make the code fit 80Col */ #define TPA_TYPE_START ETH_FAST_PATH_RX_CQE_START_FLG From 8d84a44096a34a5015fef8293fe1bf70068bfdd0 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:58:49 -0800 Subject: [PATCH 817/880] [BNX2X]: update version, remove CVS strings Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- drivers/net/bnx2x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 2db0427b0c92..8af142ccf373 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -63,8 +63,8 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "0.40.15" -#define DRV_MODULE_RELDATE "$DateTime: 2007/11/15 07:28:37 $" +#define DRV_MODULE_VERSION "1.40.22" +#define DRV_MODULE_RELDATE "2007/11/27" #define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung. */ @@ -78,7 +78,6 @@ MODULE_AUTHOR("Eliezer Tamir "); MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); -MODULE_INFO(cvs_version, "$Revision: #404 $"); static int use_inta; static int poll; From 4d9d2cb026c756318965e2d9874d4695d9ebd4f6 Mon Sep 17 00:00:00 2001 From: Eliezer Tamir Date: Thu, 28 Feb 2008 11:59:10 -0800 Subject: [PATCH 818/880] [BNX2X]: add bnx2x to MAINTAINERS Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 2333255417f4..33d99dcac691 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -982,6 +982,12 @@ M: mchan@broadcom.com L: netdev@vger.kernel.org S: Supported +BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER +P: Eliezer Tamir +M: eliezert@broadcom.com +L: netdev@vger.kernel.org +S: Supported + BROADCOM TG3 GIGABIT ETHERNET DRIVER P: Michael Chan M: mchan@broadcom.com From ed2b5b474e853fe2f9a9988f2871051291779d90 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 12:53:32 -0800 Subject: [PATCH 819/880] [APPLETALK]: Use proc_create() to setup ->proc_fops first As Davem mentioned in his recently patch (d9595a7b9c777d45a74774f1428c263a0a47f4c0) that the procfs visibility should occur after the ->proc_fops are setup. And also, Alexey provide proc_create() to make sure that ->proc_fops is setup before gluing PDE to main tree. We use proc_create(). Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/appletalk/atalk_proc.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index 8e8dcfd532db..162199a2d74f 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c @@ -283,25 +283,24 @@ int __init atalk_proc_init(void) goto out; atalk_proc_dir->owner = THIS_MODULE; - p = create_proc_entry("interface", S_IRUGO, atalk_proc_dir); + p = proc_create("interface", S_IRUGO, atalk_proc_dir, + &atalk_seq_interface_fops); if (!p) goto out_interface; - p->proc_fops = &atalk_seq_interface_fops; - p = create_proc_entry("route", S_IRUGO, atalk_proc_dir); + p = proc_create("route", S_IRUGO, atalk_proc_dir, + &atalk_seq_route_fops); if (!p) goto out_route; - p->proc_fops = &atalk_seq_route_fops; - p = create_proc_entry("socket", S_IRUGO, atalk_proc_dir); + p = proc_create("socket", S_IRUGO, atalk_proc_dir, + &atalk_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &atalk_seq_socket_fops; - p = create_proc_entry("arp", S_IRUGO, atalk_proc_dir); + p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops); if (!p) goto out_arp; - p->proc_fops = &atalk_seq_arp_fops; rc = 0; out: From 15efbe763978d7cc327d824d9e8f8f9e525dd40d Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 15 Feb 2008 09:53:59 -0500 Subject: [PATCH 820/880] [SCTP]: Clean up naming conventions of sctp protocol/address family registration I noticed while looking into some odd behavior in sctp, that the variable name sctp_pf_inet6_specific was used twice to represent two different pieces of data (its both a structure name and a pointer to that type of structure), which is confusing to say the least, and potentially dangerous depending on the variable scope. This patch cleans that up, and makes the protocol and address family registration names in SCTP more regular, increasing readability. Signed-off-by: Neil Horman Signed-off-by: Vlad Yasevich ipv6.c | 12 ++++++------ protocol.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) --- net/sctp/ipv6.c | 12 ++++++------ net/sctp/protocol.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 4d7ec961ae1d..87f940587d5f 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -966,7 +966,7 @@ static struct inet6_protocol sctpv6_protocol = { .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, }; -static struct sctp_af sctp_ipv6_specific = { +static struct sctp_af sctp_af_inet6 = { .sa_family = AF_INET6, .sctp_xmit = sctp_v6_xmit, .setsockopt = ipv6_setsockopt, @@ -998,7 +998,7 @@ static struct sctp_af sctp_ipv6_specific = { #endif }; -static struct sctp_pf sctp_pf_inet6_specific = { +static struct sctp_pf sctp_pf_inet6 = { .event_msgname = sctp_inet6_event_msgname, .skb_msgname = sctp_inet6_skb_msgname, .af_supported = sctp_inet6_af_supported, @@ -1008,7 +1008,7 @@ static struct sctp_pf sctp_pf_inet6_specific = { .supported_addrs = sctp_inet6_supported_addrs, .create_accept_sk = sctp_v6_create_accept_sk, .addr_v4map = sctp_v6_addr_v4map, - .af = &sctp_ipv6_specific, + .af = &sctp_af_inet6, }; /* Initialize IPv6 support and register with socket layer. */ @@ -1017,10 +1017,10 @@ int sctp_v6_init(void) int rc; /* Register the SCTP specific PF_INET6 functions. */ - sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6); + sctp_register_pf(&sctp_pf_inet6, PF_INET6); /* Register the SCTP specific AF_INET6 functions. */ - sctp_register_af(&sctp_ipv6_specific); + sctp_register_af(&sctp_af_inet6); rc = proto_register(&sctpv6_prot, 1); if (rc) @@ -1051,7 +1051,7 @@ void sctp_v6_exit(void) inet6_unregister_protosw(&sctpv6_seqpacket_protosw); inet6_unregister_protosw(&sctpv6_stream_protosw); proto_unregister(&sctpv6_prot); - list_del(&sctp_ipv6_specific.list); + list_del(&sctp_af_inet6.list); } /* Unregister with inet6 layer. */ diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 22a16571499c..688546dccd82 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -832,7 +832,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, return ip_queue_xmit(skb, ipfragok); } -static struct sctp_af sctp_ipv4_specific; +static struct sctp_af sctp_af_inet; static struct sctp_pf sctp_pf_inet = { .event_msgname = sctp_inet_event_msgname, @@ -844,7 +844,7 @@ static struct sctp_pf sctp_pf_inet = { .supported_addrs = sctp_inet_supported_addrs, .create_accept_sk = sctp_v4_create_accept_sk, .addr_v4map = sctp_v4_addr_v4map, - .af = &sctp_ipv4_specific, + .af = &sctp_af_inet }; /* Notifier for inetaddr addition/deletion events. */ @@ -906,7 +906,7 @@ static struct net_protocol sctp_protocol = { }; /* IPv4 address related functions. */ -static struct sctp_af sctp_ipv4_specific = { +static struct sctp_af sctp_af_inet = { .sa_family = AF_INET, .sctp_xmit = sctp_v4_xmit, .setsockopt = ip_setsockopt, @@ -1192,7 +1192,7 @@ SCTP_STATIC __init int sctp_init(void) sctp_sysctl_register(); INIT_LIST_HEAD(&sctp_address_families); - sctp_register_af(&sctp_ipv4_specific); + sctp_register_af(&sctp_af_inet); status = proto_register(&sctp_prot, 1); if (status) @@ -1249,7 +1249,7 @@ SCTP_STATIC __init int sctp_init(void) proto_unregister(&sctp_prot); err_proto_register: sctp_sysctl_unregister(); - list_del(&sctp_ipv4_specific.list); + list_del(&sctp_af_inet.list); free_pages((unsigned long)sctp_port_hashtable, get_order(sctp_port_hashsize * sizeof(struct sctp_bind_hashbucket))); @@ -1299,7 +1299,7 @@ SCTP_STATIC __exit void sctp_exit(void) inet_unregister_protosw(&sctp_seqpacket_protosw); sctp_sysctl_unregister(); - list_del(&sctp_ipv4_specific.list); + list_del(&sctp_af_inet.list); free_pages((unsigned long)sctp_assoc_hashtable, get_order(sctp_assoc_hashsize * From b40db6846847e82daf175641987df29324c425fa Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 27 Feb 2008 14:40:37 -0500 Subject: [PATCH 821/880] [SCTP]: Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option The chunks are stored inside a parameter structure in the kernel and when we copy them to the user, we need to account for the parameter header. Signed-off-by: Vlad Yasevich --- net/sctp/socket.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 44797ad88a05..848df21dc6c1 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -5070,6 +5070,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks; char __user *to; if (len <= sizeof(struct sctp_authchunks)) @@ -5086,10 +5087,11 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, ch = asoc->peer.peer_chunks; /* See if the user provided enough room for all the data */ - if (len < ntohs(ch->param_hdr.length)) + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); + len = num_chunks; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(to, ch->chunks, len)) @@ -5105,6 +5107,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks; char __user *to; if (len <= sizeof(struct sctp_authchunks)) @@ -5123,10 +5126,11 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, else ch = sctp_sk(sk)->ep->auth_chunk_list; - if (len < ntohs(ch->param_hdr.length)) + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); + len = num_chunks; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(to, ch->chunks, len)) From 7e8616d8e7731b026019d9af7cc9914b8bb42bc7 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 27 Feb 2008 16:04:52 -0500 Subject: [PATCH 822/880] [SCTP]: Update AUTH structures to match declarations in draft-16. The new SCTP socket api (draft 16) updates the AUTH API structures. We never exported these since we knew they would change. Update the rest to match the draft. Signed-off-by: Vlad Yasevich --- include/net/sctp/user.h | 10 ++++++---- net/sctp/auth.c | 4 ++-- net/sctp/socket.c | 6 +++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index 9462d6ae2f37..9619b9d35c9e 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -411,6 +411,7 @@ struct sctp_event_subscribe { __u8 sctp_shutdown_event; __u8 sctp_partial_delivery_event; __u8 sctp_adaptation_layer_event; + __u8 sctp_authentication_event; }; /* @@ -587,7 +588,7 @@ struct sctp_authchunk { * endpoint requires the peer to use. */ struct sctp_hmacalgo { - __u16 shmac_num_idents; + __u32 shmac_num_idents; __u16 shmac_idents[]; }; @@ -600,7 +601,7 @@ struct sctp_hmacalgo { struct sctp_authkey { sctp_assoc_t sca_assoc_id; __u16 sca_keynumber; - __u16 sca_keylen; + __u16 sca_keylength; __u8 sca_key[]; }; @@ -693,8 +694,9 @@ struct sctp_status { * the peer requires to be received authenticated only. */ struct sctp_authchunks { - sctp_assoc_t gauth_assoc_id; - uint8_t gauth_chunks[]; + sctp_assoc_t gauth_assoc_id; + __u32 gauth_number_of_chunks; + uint8_t gauth_chunks[]; }; /* diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 8bb79f281774..675a5c3e68a6 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -838,11 +838,11 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, } /* Create a new key data based on the info passed in */ - key = sctp_auth_create_key(auth_key->sca_keylen, GFP_KERNEL); + key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL); if (!key) goto nomem; - memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylen); + memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength); /* If we are replacing, remove the old keys data from the * key id. If we are adding new key id, add it to the diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 848df21dc6c1..939892691a26 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1964,7 +1964,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, static int sctp_setsockopt_events(struct sock *sk, char __user *optval, int optlen) { - if (optlen != sizeof(struct sctp_event_subscribe)) + if (optlen > sizeof(struct sctp_event_subscribe)) return -EINVAL; if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) return -EFAULT; @@ -5094,6 +5094,8 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, len = num_chunks; if (put_user(len, optlen)) return -EFAULT; + if (put_user(num_chunks, &p->gauth_number_of_chunks)) + return -EFAULT; if (copy_to_user(to, ch->chunks, len)) return -EFAULT; @@ -5133,6 +5135,8 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, len = num_chunks; if (put_user(len, optlen)) return -EFAULT; + if (put_user(num_chunks, &p->gauth_number_of_chunks)) + return -EFAULT; if (copy_to_user(to, ch->chunks, len)) return -EFAULT; From 16e297b35811c53288b35e15a5823fd8534c6d21 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 13:55:45 -0800 Subject: [PATCH 823/880] [ATM]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/atm/br2684.c | 4 ++-- net/atm/clip.c | 4 +--- net/atm/lec.c | 4 +--- net/atm/mpoa_proc.c | 3 +-- net/atm/proc.c | 8 ++++---- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 574d9a964176..1b228065e745 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -742,9 +742,9 @@ static int __init br2684_init(void) { #ifdef CONFIG_PROC_FS struct proc_dir_entry *p; - if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL) + p = proc_create("br2684", 0, atm_proc_root, &br2684_proc_ops); + if (p == NULL) return -ENOMEM; - p->proc_fops = &br2684_proc_ops; #endif register_atm_ioctl(&br2684_ioctl_ops); return 0; diff --git a/net/atm/clip.c b/net/atm/clip.c index 86b885ec1cbd..d30167c0b48e 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -962,9 +962,7 @@ static int __init atm_clip_init(void) { struct proc_dir_entry *p; - p = create_proc_entry("arp", S_IRUGO, atm_proc_root); - if (p) - p->proc_fops = &arp_seq_fops; + p = proc_create("arp", S_IRUGO, atm_proc_root, &arp_seq_fops); } #endif diff --git a/net/atm/lec.c b/net/atm/lec.c index 1a8c4c6c0cd0..0e450d12f035 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -1249,9 +1249,7 @@ static int __init lane_module_init(void) #ifdef CONFIG_PROC_FS struct proc_dir_entry *p; - p = create_proc_entry("lec", S_IRUGO, atm_proc_root); - if (p) - p->proc_fops = &lec_seq_fops; + p = proc_create("lec", S_IRUGO, atm_proc_root, &lec_seq_fops); #endif register_atm_ioctl(&lane_ioctl_ops); diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index 91f3ffc90dbd..4990541ef5da 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -276,12 +276,11 @@ int mpc_proc_init(void) { struct proc_dir_entry *p; - p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root); + p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_file_operations); if (!p) { printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME); return -ENOMEM; } - p->proc_fops = &mpc_file_operations; p->owner = THIS_MODULE; return 0; } diff --git a/net/atm/proc.c b/net/atm/proc.c index 49125110bb8b..e9693aed7ef8 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c @@ -435,11 +435,11 @@ int atm_proc_dev_register(struct atm_dev *dev) goto err_out; sprintf(dev->proc_name,"%s:%d",dev->type, dev->number); - dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root); + dev->proc_entry = proc_create(dev->proc_name, 0, atm_proc_root, + &proc_atm_dev_ops); if (!dev->proc_entry) goto err_free_name; dev->proc_entry->data = dev; - dev->proc_entry->proc_fops = &proc_atm_dev_ops; dev->proc_entry->owner = THIS_MODULE; return 0; err_free_name: @@ -492,10 +492,10 @@ int __init atm_proc_init(void) for (e = atm_proc_ents; e->name; e++) { struct proc_dir_entry *dirent; - dirent = create_proc_entry(e->name, S_IRUGO, atm_proc_root); + dirent = proc_create(e->name, S_IRUGO, + atm_proc_root, e->proc_fops); if (!dirent) goto err_out_remove; - dirent->proc_fops = e->proc_fops; dirent->owner = THIS_MODULE; e->dirent = dirent; } From 2ce8f047d5f3c0d782838bd2ecb6e4c440268e6d Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:00:59 -0800 Subject: [PATCH 824/880] [SUNRPC]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/sunrpc/cache.c | 14 ++++++-------- net/sunrpc/stats.c | 3 +-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 636c8e04e0be..b5f2786251b9 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -316,31 +316,29 @@ static int create_cache_proc_entries(struct cache_detail *cd) cd->proc_ent->owner = cd->owner; cd->channel_ent = cd->content_ent = NULL; - p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); + p = proc_create("flush", S_IFREG|S_IRUSR|S_IWUSR, + cd->proc_ent, &cache_flush_operations); cd->flush_ent = p; if (p == NULL) goto out_nomem; - p->proc_fops = &cache_flush_operations; p->owner = cd->owner; p->data = cd; if (cd->cache_request || cd->cache_parse) { - p = create_proc_entry("channel", S_IFREG|S_IRUSR|S_IWUSR, - cd->proc_ent); + p = proc_create("channel", S_IFREG|S_IRUSR|S_IWUSR, + cd->proc_ent, &cache_file_operations); cd->channel_ent = p; if (p == NULL) goto out_nomem; - p->proc_fops = &cache_file_operations; p->owner = cd->owner; p->data = cd; } if (cd->cache_show) { - p = create_proc_entry("content", S_IFREG|S_IRUSR|S_IWUSR, - cd->proc_ent); + p = proc_create("content", S_IFREG|S_IRUSR|S_IWUSR, + cd->proc_ent, &content_file_operations); cd->content_ent = p; if (p == NULL) goto out_nomem; - p->proc_fops = &content_file_operations; p->owner = cd->owner; p->data = cd; } diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 5a16875f5ac8..c6061a4346c8 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -229,9 +229,8 @@ do_register(const char *name, void *data, const struct file_operations *fops) rpc_proc_init(); dprintk("RPC: registering /proc/net/rpc/%s\n", name); - ent = create_proc_entry(name, 0, proc_net_rpc); + ent = proc_create(name, 0, proc_net_rpc, fops); if (ent) { - ent->proc_fops = fops; ent->data = data; } return ent; From 1e15dc981deb39056fa846fe55e1a1dbb175a98e Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:06:14 -0800 Subject: [PATCH 825/880] [IPX]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/ipx/ipx_proc.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index d483a00dc427..5ed97ad0e2e3 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c @@ -358,22 +358,19 @@ int __init ipx_proc_init(void) if (!ipx_proc_dir) goto out; - p = create_proc_entry("interface", S_IRUGO, ipx_proc_dir); + p = proc_create("interface", S_IRUGO, + ipx_proc_dir, &ipx_seq_interface_fops); if (!p) goto out_interface; - p->proc_fops = &ipx_seq_interface_fops; - p = create_proc_entry("route", S_IRUGO, ipx_proc_dir); + p = proc_create("route", S_IRUGO, ipx_proc_dir, &ipx_seq_route_fops); if (!p) goto out_route; - p->proc_fops = &ipx_seq_route_fops; - p = create_proc_entry("socket", S_IRUGO, ipx_proc_dir); + p = proc_create("socket", S_IRUGO, ipx_proc_dir, &ipx_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &ipx_seq_socket_fops; - rc = 0; out: return rc; From 7e0218099832d954d107f48de9e81bd521e16f24 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:08:54 -0800 Subject: [PATCH 826/880] [LLC]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/llc/llc_proc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index cb34bc0518e8..48212c0a961c 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c @@ -239,18 +239,14 @@ int __init llc_proc_init(void) goto out; llc_proc_dir->owner = THIS_MODULE; - p = create_proc_entry("socket", S_IRUGO, llc_proc_dir); + p = proc_create("socket", S_IRUGO, llc_proc_dir, &llc_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &llc_seq_socket_fops; - - p = create_proc_entry("core", S_IRUGO, llc_proc_dir); + p = proc_create("core", S_IRUGO, llc_proc_dir, &llc_seq_core_fops); if (!p) goto out_core; - p->proc_fops = &llc_seq_core_fops; - rc = 0; out: return rc; From 46ecf0b994715589b9f5f620beca4d6aaaa02028 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:10:51 -0800 Subject: [PATCH 827/880] [NEIGHBOUR]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/core/neighbour.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 2328acbd16cd..aef01533dfb6 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1389,10 +1389,10 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) panic("cannot create neighbour cache statistics"); #ifdef CONFIG_PROC_FS - tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat); + tbl->pde = proc_create(tbl->id, 0, init_net.proc_net_stat, + &neigh_stat_seq_fops); if (!tbl->pde) panic("cannot create neighbour proc dir entry"); - tbl->pde->proc_fops = &neigh_stat_seq_fops; tbl->pde->data = tbl; #endif From 25296d599ccc7e06af217329729e4d7154fa79a2 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:11:49 -0800 Subject: [PATCH 828/880] [PKTGEN]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/core/pktgen.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index bfcdfaebca5c..20e63b302ba6 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -3570,14 +3570,14 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) if (err) goto out1; - pkt_dev->entry = create_proc_entry(ifname, 0600, pg_proc_dir); + pkt_dev->entry = proc_create(ifname, 0600, + pg_proc_dir, &pktgen_if_fops); if (!pkt_dev->entry) { printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, ifname); err = -EINVAL; goto out2; } - pkt_dev->entry->proc_fops = &pktgen_if_fops; pkt_dev->entry->data = pkt_dev; #ifdef CONFIG_XFRM pkt_dev->ipsmode = XFRM_MODE_TRANSPORT; @@ -3628,7 +3628,7 @@ static int __init pktgen_create_thread(int cpu) kthread_bind(p, cpu); t->tsk = p; - pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir); + pe = proc_create(t->tsk->comm, 0600, pg_proc_dir, &pktgen_thread_fops); if (!pe) { printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, t->tsk->comm); @@ -3638,7 +3638,6 @@ static int __init pktgen_create_thread(int cpu) return -EINVAL; } - pe->proc_fops = &pktgen_thread_fops; pe->data = t; wake_up_process(p); @@ -3709,7 +3708,7 @@ static int __init pg_init(void) return -ENODEV; pg_proc_dir->owner = THIS_MODULE; - pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir); + pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); if (pe == NULL) { printk(KERN_ERR "pktgen: ERROR: cannot create %s " "procfs entry.\n", PGCTRL); @@ -3717,7 +3716,6 @@ static int __init pg_init(void) return -EINVAL; } - pe->proc_fops = &pktgen_fops; pe->data = NULL; /* Register us to receive netdevice events */ From 160f17e345f5b50484d6cdc985b8686a05bf015d Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:13:16 -0800 Subject: [PATCH 829/880] [SCTP]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/sctp/objcnt.c | 5 ++--- net/sctp/proc.c | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c index 14e294e37626..cfeb07ea1b04 100644 --- a/net/sctp/objcnt.c +++ b/net/sctp/objcnt.c @@ -132,12 +132,11 @@ void sctp_dbg_objcnt_init(void) { struct proc_dir_entry *ent; - ent = create_proc_entry("sctp_dbg_objcnt", 0, proc_net_sctp); + ent = proc_create("sctp_dbg_objcnt", 0, + proc_net_sctp, &sctp_objcnt_ops); if (!ent) printk(KERN_WARNING "sctp_dbg_objcnt: Unable to create /proc entry.\n"); - else - ent->proc_fops = &sctp_objcnt_ops; } /* Cleanup the objcount entry in the proc filesystem. */ diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 69bb5a63fd8b..9e214da82d9e 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -108,12 +108,10 @@ int __init sctp_snmp_proc_init(void) { struct proc_dir_entry *p; - p = create_proc_entry("snmp", S_IRUGO, proc_net_sctp); + p = proc_create("snmp", S_IRUGO, proc_net_sctp, &sctp_snmp_seq_fops); if (!p) return -ENOMEM; - p->proc_fops = &sctp_snmp_seq_fops; - return 0; } From 4436f4cbfac15acea139863e322ed2f9efb118d3 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:13:46 -0800 Subject: [PATCH 830/880] [IPV6]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/ipv6/proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 35e502a72495..199ef379e501 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -217,12 +217,12 @@ int snmp6_register_dev(struct inet6_dev *idev) if (!proc_net_devsnmp6) return -ENOENT; - p = create_proc_entry(idev->dev->name, S_IRUGO, proc_net_devsnmp6); + p = proc_create(idev->dev->name, S_IRUGO, + proc_net_devsnmp6, &snmp6_seq_fops); if (!p) return -ENOMEM; p->data = idev; - p->proc_fops = &snmp6_seq_fops; idev->stats.proc_dir_entry = p; return 0; From 770207208e4374f013f6f49233d5c8c8df505e03 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:14:25 -0800 Subject: [PATCH 831/880] [IPV4]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/ipv4/route.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 525787b52b72..7b5e8e1d94be 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -542,12 +542,11 @@ static __init int ip_rt_proc_init(struct net *net) if (!pde) goto err1; - pde = create_proc_entry("rt_cache", S_IRUGO, net->proc_net_stat); + pde = proc_create("rt_cache", S_IRUGO, + net->proc_net_stat, &rt_cpu_seq_fops); if (!pde) goto err2; - pde->proc_fops = &rt_cpu_seq_fops; - #ifdef CONFIG_NET_CLS_ROUTE pde = create_proc_read_entry("rt_acct", 0, net->proc_net, ip_rt_acct_read, NULL); From d45fba3625249fada590a2eea09c38e755a3a2a7 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:14:58 -0800 Subject: [PATCH 832/880] [8021Q]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/8021q/vlanproc.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index a0ec47925597..146cfb0e9882 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -161,11 +161,10 @@ int __init vlan_proc_init(void) if (!proc_vlan_dir) goto err; - proc_vlan_conf = create_proc_entry(name_conf, S_IFREG|S_IRUSR|S_IWUSR, - proc_vlan_dir); + proc_vlan_conf = proc_create(name_conf, S_IFREG|S_IRUSR|S_IWUSR, + proc_vlan_dir, &vlan_fops); if (!proc_vlan_conf) goto err; - proc_vlan_conf->proc_fops = &vlan_fops; return 0; err: @@ -182,13 +181,11 @@ int vlan_proc_add_dev(struct net_device *vlandev) { struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); - dev_info->dent = create_proc_entry(vlandev->name, - S_IFREG|S_IRUSR|S_IWUSR, - proc_vlan_dir); + dev_info->dent = proc_create(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, + proc_vlan_dir, &vlandev_fops); if (!dev_info->dent) return -ENOBUFS; - dev_info->dent->proc_fops = &vlandev_fops; dev_info->dent->data = vlandev; return 0; } From 6d37a1581695fba42f4b51e3ff4c2871552cd6d7 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:15:56 -0800 Subject: [PATCH 833/880] [WANROUTER]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/wanrouter/wanproc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index f2e54c3f064e..5bebe40bf4e6 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -292,14 +292,12 @@ int __init wanrouter_proc_init(void) if (!proc_router) goto fail; - p = create_proc_entry("config", S_IRUGO, proc_router); + p = proc_create("config", S_IRUGO, proc_router, &config_fops); if (!p) goto fail_config; - p->proc_fops = &config_fops; - p = create_proc_entry("status", S_IRUGO, proc_router); + p = proc_create("status", S_IRUGO, proc_router, &status_fops); if (!p) goto fail_stat; - p->proc_fops = &status_fops; return 0; fail_stat: remove_proc_entry("config", proc_router); @@ -329,10 +327,10 @@ int wanrouter_proc_add(struct wan_device* wandev) if (wandev->magic != ROUTER_MAGIC) return -EINVAL; - wandev->dent = create_proc_entry(wandev->name, S_IRUGO, proc_router); + wandev->dent = proc_create(wandev->name, S_IRUGO, + proc_router, &wandev_fops); if (!wandev->dent) return -ENOMEM; - wandev->dent->proc_fops = &wandev_fops; wandev->dent->data = wandev; return 0; } From 2335f8ec27e125208d8d2d3e257a82862c4977d6 Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Thu, 28 Feb 2008 14:16:33 -0800 Subject: [PATCH 834/880] [X25]: Use proc_create() to setup ->proc_fops first Use proc_create() to make sure that ->proc_fops be setup before gluing PDE to main tree. Signed-off-by: Wang Chen Signed-off-by: David S. Miller --- net/x25/x25_proc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c index 3f52b09bed03..1afa44d25beb 100644 --- a/net/x25/x25_proc.c +++ b/net/x25/x25_proc.c @@ -312,20 +312,18 @@ int __init x25_proc_init(void) if (!x25_proc_dir) goto out; - p = create_proc_entry("route", S_IRUGO, x25_proc_dir); + p = proc_create("route", S_IRUGO, x25_proc_dir, &x25_seq_route_fops); if (!p) goto out_route; - p->proc_fops = &x25_seq_route_fops; - p = create_proc_entry("socket", S_IRUGO, x25_proc_dir); + p = proc_create("socket", S_IRUGO, x25_proc_dir, &x25_seq_socket_fops); if (!p) goto out_socket; - p->proc_fops = &x25_seq_socket_fops; - p = create_proc_entry("forward", S_IRUGO, x25_proc_dir); + p = proc_create("forward", S_IRUGO, x25_proc_dir, + &x25_seq_forward_fops); if (!p) goto out_forward; - p->proc_fops = &x25_seq_forward_fops; rc = 0; out: From 931506d3b2208362efc678ee863ee42a90755e89 Mon Sep 17 00:00:00 2001 From: Anantha Subramanyam Date: Thu, 28 Feb 2008 15:58:35 -0800 Subject: [PATCH 835/880] sata_svw: Add support for HT1100 SATA controller This patch adds support (including ATAPI DMA) for HT1100 (aka BCM11000) SATA controller. Signed-off-by: Anantha Subramanyam Signed-off-by: Jeff Garzik --- drivers/ata/sata_svw.c | 77 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 69f651e0bc98..840d1c4a7850 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #ifdef CONFIG_PPC_OF @@ -59,6 +61,7 @@ enum { /* ap->flags bits */ K2_FLAG_SATA_8_PORTS = (1 << 24), K2_FLAG_NO_ATAPI_DMA = (1 << 25), + K2_FLAG_BAR_POS_3 = (1 << 26), /* Taskfile registers offsets */ K2_SATA_TF_CMD_OFFSET = 0x00, @@ -88,8 +91,10 @@ enum { /* Port stride */ K2_SATA_PORT_OFFSET = 0x100, - board_svw4 = 0, - board_svw8 = 1, + chip_svw4 = 0, + chip_svw8 = 1, + chip_svw42 = 2, /* bar 3 */ + chip_svw43 = 3, /* bar 5 */ }; static u8 k2_stat_check_status(struct ata_port *ap); @@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap); static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) { + u8 cmnd = qc->scsicmd->cmnd[0]; + if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) return -1; /* ATAPI DMA not supported */ + else { + switch (cmnd) { + case READ_10: + case READ_12: + case READ_16: + case WRITE_10: + case WRITE_12: + case WRITE_16: + return 0; + + default: + return -1; + } - return 0; + } } static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) @@ -354,7 +374,7 @@ static const struct ata_port_operations k2_sata_ops = { }; static const struct ata_port_info k2_port_info[] = { - /* board_svw4 */ + /* chip_svw4 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, @@ -363,7 +383,7 @@ static const struct ata_port_info k2_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, - /* board_svw8 */ + /* chip_svw8 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | @@ -373,6 +393,24 @@ static const struct ata_port_info k2_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, + /* chip_svw42 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = ATA_UDMA6, + .port_ops = &k2_sata_ops, + }, + /* chip_svw43 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = ATA_UDMA6, + .port_ops = &k2_sata_ops, + }, }; static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) @@ -402,7 +440,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en { &k2_port_info[ent->driver_data], NULL }; struct ata_host *host; void __iomem *mmio_base; - int n_ports, i, rc; + int n_ports, i, rc, bar_pos; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); @@ -416,6 +454,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en if (!host) return -ENOMEM; + bar_pos = 5; + if (ppi[0]->flags & K2_FLAG_BAR_POS_3) + bar_pos = 3; /* * If this driver happens to only be useful on Apple's K2, then * we should check that here as it has a normal Serverworks ID @@ -428,17 +469,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en * Check if we have resources mapped at all (second function may * have been disabled by firmware) */ - if (pci_resource_len(pdev, 5) == 0) + if (pci_resource_len(pdev, bar_pos) == 0) { + /* In IDE mode we need to pin the device to ensure that + pcim_release does not clear the busmaster bit in config + space, clearing causes busmaster DMA to fail on + ports 3 & 4 */ + pcim_pin_device(pdev); return -ENODEV; + } /* Request and iomap PCI regions */ - rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); + rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); if (rc) return rc; host->iomap = pcim_iomap_table(pdev); - mmio_base = host->iomap[5]; + mmio_base = host->iomap[bar_pos]; /* different controllers have different number of ports - currently 4 or 8 */ /* All ports are on the same function. Multi-function device is no @@ -483,11 +530,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en * controller * */ static const struct pci_device_id k2_sata_pci_tbl[] = { - { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 }, - { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 }, + { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 }, + { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 }, { } }; From 0aef45645174525ee6aa7baed247a130e052740d Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 29 Feb 2008 12:08:42 +0800 Subject: [PATCH 836/880] Blackfin Serial Driver: Fix bug - Only insert UART rx char in timer task. http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3910 Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu --- drivers/serial/bfin_5xx.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 2a4117485799..0aa345b9a38b 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -48,7 +48,7 @@ #define DMA_RX_XCOUNT 512 #define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) -#define DMA_RX_FLUSH_JIFFIES 5 +#define DMA_RX_FLUSH_JIFFIES (HZ / 50) #ifdef CONFIG_SERIAL_BFIN_DMA static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); @@ -393,7 +393,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) { struct circ_buf *xmit = &uart->port.info->xmit; unsigned short ier; - int flags = 0; uart->tx_done = 0; @@ -491,9 +490,7 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) { int x_pos, pos; - int flags = 0; - spin_lock_irqsave(&uart->port.lock, flags); uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel); x_pos = get_dma_curr_xcount(uart->rx_dma_channel); uart->rx_dma_nrows = DMA_RX_YCOUNT - uart->rx_dma_nrows; @@ -509,7 +506,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) bfin_serial_dma_rx_chars(uart); uart->rx_dma_buf.tail = uart->rx_dma_buf.head; } - spin_unlock_irqrestore(&uart->port.lock, flags); + uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; add_timer(&(uart->rx_dma_timer)); } @@ -548,22 +545,16 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; unsigned short irqstat; - int pos; - - uart->rx_dma_nrows = DMA_RX_YCOUNT - - get_dma_curr_ycount(uart->rx_dma_channel); - pos = DMA_RX_XCOUNT * uart->rx_dma_nrows; - if (pos != uart->rx_dma_buf.tail) { - uart->rx_dma_buf.head = pos; - bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.tail = uart->rx_dma_buf.head; - } spin_lock(&uart->port.lock); irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); clear_dma_irqstat(uart->rx_dma_channel); - spin_unlock(&uart->port.lock); + + del_timer(&(uart->rx_dma_timer)); + uart->rx_dma_timer.expires = jiffies; + add_timer(&(uart->rx_dma_timer)); + return IRQ_HANDLED; } #endif From 1bd960ee2b1231759bd485aad0fa483c2f793a3b Mon Sep 17 00:00:00 2001 From: Josef Jeff Sipek Date: Fri, 29 Feb 2008 13:58:40 +1100 Subject: [PATCH 837/880] [XFS] If you mount an XFS filesystem with no mount options at all, then the "ikeep" option is set rather than "noikeep". This regression was introduced in 970451. With no mount options specified, xfs_parseargs() does the following: int ikeep = 0; args->flags |= XFSMNT_BARRIER; args->flags2 |= XFSMNT2_COMPAT_IOSIZE; if (!options) goto done; It only sets the above two options by default and before, it also used to set XFSMNT_IDELETE by default. If options are specified, then if (!(args->flags & XFSMNT_DMAPI) && !ikeep) args->flags |= XFSMNT_IDELETE; is executed later on which is skipped by the "goto done;" above. The solution is to invert the logic. SGI-PV: 977771 SGI-Modid: xfs-linux-melb:xfs-kern:30590a Signed-off-by: Niv Sardi Signed-off-by: Barry Naujok Signed-off-by: Josef 'Jeff' Sipek Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_super.c | 14 +++++++------- fs/xfs/xfs_clnt.h | 2 +- fs/xfs/xfs_ialloc.c | 2 +- fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_vfsops.c | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 21dfc9da235e..8831d9518790 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -171,7 +171,7 @@ xfs_parseargs( char *this_char, *value, *eov; int dsunit, dswidth, vol_dsunit, vol_dswidth; int iosize; - int ikeep = 0; + int dmapi_implies_ikeep = 1; args->flags |= XFSMNT_BARRIER; args->flags2 |= XFSMNT2_COMPAT_IOSIZE; @@ -302,10 +302,10 @@ xfs_parseargs( } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { args->flags &= ~XFSMNT_BARRIER; } else if (!strcmp(this_char, MNTOPT_IKEEP)) { - ikeep = 1; - args->flags &= ~XFSMNT_IDELETE; + args->flags |= XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { - args->flags |= XFSMNT_IDELETE; + dmapi_implies_ikeep = 0; + args->flags &= ~XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { @@ -410,8 +410,8 @@ xfs_parseargs( * Note that if "ikeep" or "noikeep" mount options are * supplied, then they are honored. */ - if (!(args->flags & XFSMNT_DMAPI) && !ikeep) - args->flags |= XFSMNT_IDELETE; + if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep) + args->flags |= XFSMNT_IKEEP; if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { if (dsunit) { @@ -446,6 +446,7 @@ xfs_showargs( { static struct proc_xfs_info xfs_info_set[] = { /* the few simple ones we can get from the mount struct */ + { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, @@ -461,7 +462,6 @@ xfs_showargs( }; static struct proc_xfs_info xfs_info_unset[] = { /* the few simple ones we can get from the mount struct */ - { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP }, { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h index d16c1b971074..d5d1e60ee224 100644 --- a/fs/xfs/xfs_clnt.h +++ b/fs/xfs/xfs_clnt.h @@ -86,7 +86,7 @@ struct xfs_mount_args { #define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */ #define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */ #define XFSMNT_BARRIER 0x04000000 /* use write barriers */ -#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ +#define XFSMNT_IKEEP 0x08000000 /* inode cluster delete */ #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width * allocation */ #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index c5836b951d0c..db9d5fa600af 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -1053,7 +1053,7 @@ xfs_difree( /* * When an inode cluster is free, it becomes eligible for removal */ - if ((mp->m_flags & XFS_MOUNT_IDELETE) && + if (!(mp->m_flags & XFS_MOUNT_IKEEP) && (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { *delete = 1; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index f7c620ec6e69..1d8a4728d847 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -366,7 +366,7 @@ typedef struct xfs_mount { #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ #define XFS_MOUNT_BARRIER (1ULL << 17) -#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ +#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width * allocation */ #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 413587f02155..7321304a69cc 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -281,8 +281,8 @@ xfs_start_flags( mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; } - if (ap->flags & XFSMNT_IDELETE) - mp->m_flags |= XFS_MOUNT_IDELETE; + if (ap->flags & XFSMNT_IKEEP) + mp->m_flags |= XFS_MOUNT_IKEEP; if (ap->flags & XFSMNT_DIRSYNC) mp->m_flags |= XFS_MOUNT_DIRSYNC; if (ap->flags & XFSMNT_ATTR2) From be71716e464f4ea38f08034dc666f2feb55535d9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Feb 2008 20:38:15 -0800 Subject: [PATCH 838/880] [SPARC64]: Adjust kernel PC validation test in fault handler. Because of the new futex validation init handler, we have to accept faults in init section text as well as the normal kernel text. Thanks to Tom Callaway for the bug report. Signed-off-by: David S. Miller --- arch/sparc64/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 918363360280..2650d0d33ac2 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -286,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) unsigned long tpc = regs->tpc; /* Sanity check the PC. */ - if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) || + if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) || (tpc >= MODULES_VADDR && tpc < MODULES_END)) { /* Valid, no problems... */ } else { From b84f08d49188a18d965fab8463c9cb679785eb39 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Feb 2008 12:36:11 +0100 Subject: [PATCH 839/880] [ALSA] hda-codec - Fix Master volume on HP dv8000 HP dv8000 laptop has a problem with Master volume. It's due to the connection of the widget 0x13. When it's connected from the analog amp mixer (0x19), it works as expected mysteriously (ALSA bug#3775): https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3775 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f7cd3a804b11..7206b30cbf94 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1230,6 +1230,11 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { static struct hda_verb cxt5047_hp_init_verbs[] = { /* pin sensing on HP jack */ {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, + /* 0x13 is actually shared by both HP and speaker; + * setting the connection to 0 (=0x19) makes the master volume control + * working mysteriouslly... + */ + {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Record selector: Ext Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, From ee47fd12d73706edb2a10efd05d5eed15b4d1e08 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Wed, 20 Feb 2008 17:13:15 +0100 Subject: [PATCH 840/880] [ALSA] ASoC: Fix TLV320AIC3X PLL divider table for 64 kHz rate Signed-off-by: Jarkko Nikula Signed-off-by: Takashi Iwai --- sound/soc/codecs/tlv320aic3x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 710e0287ef8c..569ecaca0e8b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -681,8 +681,8 @@ static const struct aic3x_rate_divs aic3x_divs[] = { {22579200, 48000, 48000, 0x0, 8, 7075}, {33868800, 48000, 48000, 0x0, 5, 8049}, /* 64k */ - {22579200, 96000, 96000, 0x1, 8, 7075}, - {33868800, 96000, 96000, 0x1, 5, 8049}, + {22579200, 64000, 96000, 0x1, 8, 7075}, + {33868800, 64000, 96000, 0x1, 5, 8049}, /* 88.2k */ {22579200, 88200, 88200, 0x0, 8, 0}, {33868800, 88200, 88200, 0x0, 5, 3333}, From d513202efd5bb9974545ef1c7f951467b21eb3a5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 25 Feb 2008 11:01:00 +0100 Subject: [PATCH 841/880] [ALSA] usb-audio: add workaround for broken E-Mu frequency feedback Add a workaround for the feedback pipe of E-Mu 0202/0404 USB devices that reports the number of samples per packet instead of the number of samples per microframe. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/usb/usbaudio.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8fa935665702..675672f313be 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -479,6 +479,33 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, return 0; } +/* + * process after E-Mu 0202/0404 high speed playback sync complete + * + * These devices return the number of samples per packet instead of the number + * of samples per microframe. + */ +static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs, + struct snd_pcm_runtime *runtime, + struct urb *urb) +{ + unsigned int f; + unsigned long flags; + + if (urb->iso_frame_desc[0].status == 0 && + urb->iso_frame_desc[0].actual_length == 4) { + f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff; + f >>= subs->datainterval; + if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) { + spin_lock_irqsave(&subs->lock, flags); + subs->freqm = f; + spin_unlock_irqrestore(&subs->lock, flags); + } + } + + return 0; +} + /* determine the number of frames in the next packet */ static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) { @@ -2219,10 +2246,17 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo subs->stream = as; subs->direction = stream; subs->dev = as->chip->dev; - if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) + if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { subs->ops = audio_urb_ops[stream]; - else + } else { subs->ops = audio_urb_ops_high_speed[stream]; + switch (as->chip->usb_id) { + case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ + case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ + subs->ops.retire_sync = retire_playback_sync_urb_hs_emu; + break; + } + } snd_pcm_set_ops(as->pcm, stream, stream == SNDRV_PCM_STREAM_PLAYBACK ? &snd_usb_playback_ops : &snd_usb_capture_ops); From 20cde9e8f83711dca532c49605914d50292d9ce5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 25 Feb 2008 11:04:41 +0100 Subject: [PATCH 842/880] [ALSA] sb8: fix SB 1.0 capture DMA programming Fix a wrong version check that would cause an invalid command to be sent to SB 1.0 chips. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/isa/sb/sb8_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 6304c3a89ba0..fe03bb820532 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -277,7 +277,7 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) } else { snd_sbdsp_command(chip, 256 - runtime->rate_den); } - if (chip->capture_format != SB_DSP_OUTPUT) { + if (chip->capture_format != SB_DSP_INPUT) { count--; snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); snd_sbdsp_command(chip, count & 0xff); From fb304ce53afbb653bfa67cc81ee9cf06edcbf68e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 25 Feb 2008 15:32:01 +0100 Subject: [PATCH 843/880] [ALSA] hda-codec - Fix AD1988 capture elements The some indices of capture elements of AD1988 are wrongly assigned. This patch fixes it. See ALSA bug#3795 https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3795 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 19f08846d6fc..c8649282c2cf 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1778,9 +1778,9 @@ static hda_nid_t ad1988_capsrc_nids[3] = { static struct hda_input_mux ad1988_6stack_capture_source = { .num_items = 5, .items = { - { "Front Mic", 0x0 }, - { "Line", 0x1 }, - { "Mic", 0x4 }, + { "Front Mic", 0x1 }, /* port-B */ + { "Line", 0x2 }, /* port-C */ + { "Mic", 0x4 }, /* port-E */ { "CD", 0x5 }, { "Mix", 0x9 }, }, @@ -1789,7 +1789,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = { static struct hda_input_mux ad1988_laptop_capture_source = { .num_items = 3, .items = { - { "Mic/Line", 0x0 }, + { "Mic/Line", 0x1 }, /* port-B */ { "CD", 0x5 }, { "Mix", 0x9 }, }, From 3f1eeaed2c0dc6c787a47ae7a6c774589a04a3a2 Mon Sep 17 00:00:00 2001 From: Tony Vroon Date: Mon, 25 Feb 2008 16:44:13 +0100 Subject: [PATCH 844/880] [ALSA] hda-codec - Add Fujitsu Lifebook E8410 to quirk table Add the proper model entry for Fujitsu Lifebook E8410 with ALC262 codec. From: Tony Vroon Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 777f8c01ca7a..1534f0866f76 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9238,6 +9238,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), + SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), From b930b9f41d5e9eadd9041f273c4d6d18e7061d05 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 26 Feb 2008 08:40:57 +0100 Subject: [PATCH 845/880] [ALSA] oxygen: add owner field I forgot to set the module owner for the HiFier/Xonar models. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/hifier.c | 1 + sound/pci/oxygen/virtuoso.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 3ea1f05228a1..666f69a3312e 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -150,6 +150,7 @@ static const struct oxygen_model model_hifier = { .shortname = "C-Media CMI8787", .longname = "C-Media Oxygen HD Audio", .chip = "CMI8788", + .owner = THIS_MODULE, .init = hifier_init, .control_filter = hifier_control_filter, .mixer_init = hifier_mixer_init, diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 40e92f5cd69c..d163397b85cc 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -389,6 +389,7 @@ static const struct oxygen_model model_xonar = { .shortname = "Asus AV200", .longname = "Asus Virtuoso 200", .chip = "AV200", + .owner = THIS_MODULE, .init = xonar_init, .control_filter = xonar_control_filter, .mixer_init = xonar_mixer_init, From 0b167bf456d4af58103e2072bc4bd5733e7e7579 Mon Sep 17 00:00:00 2001 From: Andrew Paprocki Date: Sun, 3 Feb 2008 10:15:44 +0100 Subject: [PATCH 846/880] [ALSA] hda_intel - Add model quirk for Albatron KI690-AM2 motherboard This adds a quirk to the Realtek ALC883 table for the Albatron KI690-AM2 motherboard to use the 6stack-dig model. Signed-off-by: Andrew Paprocki Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1534f0866f76..b092bd47e56e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7639,6 +7639,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), + SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), {} From b6a370b6fb3114f9f7fc8a393c3ffc2236d7cbf1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 4 Feb 2008 14:00:53 +0100 Subject: [PATCH 847/880] [ALSA] intel8x0 - Add quirk for Acer Travelmate 2310 Added ac97_quirk=hp-only for Acer Travelmate 2310. ALSA bug#3656 https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3656 Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 061072c7db03..c5ef12ae3c55 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1738,6 +1738,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .name = "IBM NetVista A30p", /* AD1981B */ .type = AC97_TUNE_HP_ONLY }, + { + .subvendor = 0x1025, + .subdevice = 0x0082, + .name = "Acer Travelmate 2310", + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x1025, .subdevice = 0x0083, From 31bffaa9435f14b35a8e23ed2005925f65ec6d9b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 27 Feb 2008 16:10:44 +0100 Subject: [PATCH 848/880] [ALSA] hda-codec - Fix mixer names of realtek codecs to adapt mater controls Some models like eeepc ep20 have invalid mixer names that aren't handled properly by virtual master controls. Rename them to the proper names. Also fixed some typos in the mixer names but they are not compiled in right now. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b092bd47e56e..51871c684571 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3973,8 +3973,8 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), { } /* end */ }; @@ -4005,9 +4005,9 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), - HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, + HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, + HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), @@ -8103,7 +8103,7 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ + HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), @@ -8125,7 +8125,7 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ + HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), { } /* end */ @@ -13009,8 +13009,8 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { }; static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { - HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), From 338c7ed070bb1e068c3ae8ef14dc577e75d8aecc Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 28 Feb 2008 12:34:48 +0100 Subject: [PATCH 849/880] [ALSA] ASoC: Fix DAPM widget function types in pxa machine drivers Add kcontrol argument to functions since the API was changed by the commit 9af6d9562414568ecadf96aaef5b88e7e8b19821. Signed-off-by: Jarkko Nikula Signed-off-by: Takashi Iwai --- sound/soc/pxa/corgi.c | 6 ++++-- sound/soc/pxa/poodle.c | 3 ++- sound/soc/pxa/spitz.c | 3 ++- sound/soc/pxa/tosa.c | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 3f34e531bebf..1a70a6ac98ce 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -215,7 +215,8 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) +static int corgi_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); @@ -225,7 +226,8 @@ static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) return 0; } -static int corgi_mic_event(struct snd_soc_dapm_widget *w, int event) +static int corgi_mic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 5ae59bd309a3..4fbf8bba9627 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -196,7 +196,8 @@ static int poodle_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int poodle_amp_event(struct snd_soc_dapm_widget *w, int event) +static int poodle_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) locomo_gpio_write(&poodle_locomo_device.dev, diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index d56709e15435..ecca39033fcc 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -215,7 +215,8 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int spitz_mic_bias(struct snd_soc_dapm_widget *w, int event) +static int spitz_mic_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (machine_is_borzoi() || machine_is_spitz()) { if (SND_SOC_DAPM_EVENT_ON(event)) diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index e4d40b528ca4..7346d7e5d066 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -135,7 +135,8 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol, } /* tosa dapm event handlers */ -static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event) +static int tosa_hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); From 3fffe871b93f957bea443e85f6b221c50bbf9f97 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 28 Feb 2008 12:35:25 +0100 Subject: [PATCH 850/880] [ALSA] ASoC: Fix WM9712 mixer_event DAPM widget function type Add kcontrol argument to function since the API was changed by the commit 9af6d9562414568ecadf96aaef5b88e7e8b19821. Signed-off-by: Jarkko Nikula Signed-off-by: Takashi Iwai --- sound/soc/codecs/wm9712.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 590baea3c4c3..524f7450804f 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -176,7 +176,8 @@ static int wm9712_add_controls(struct snd_soc_codec *codec) * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path. */ -static int mixer_event (struct snd_soc_dapm_widget *w, int event) +static int mixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { u16 l, r, beep, line, phone, mic, pcm, aux; From 008f3599ef97438900d62fe05d75535d114780fc Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 29 Feb 2008 11:46:32 +0100 Subject: [PATCH 851/880] [ALSA] sound: ice1712: unused structs Don't need to declare a struct when defining a structure layout. Both of these structs are unused. sound/pci/ice1712/revo.c:39:3: warning: symbol 'revo51' was not declared. Should it be static? sound/pci/ice1712/phase.c:54:3: warning: symbol 'phase28' was not declared. Should it be static? Signed-off-by: Harvey Harrison Signed-off-by: Takashi Iwai --- sound/pci/ice1712/phase.c | 2 +- sound/pci/ice1712/revo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 9ab4a9f383cb..5a158b73dcaa 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -51,7 +51,7 @@ struct phase28_spec { unsigned short master[2]; unsigned short vol[8]; -} phase28; +}; /* WM8770 registers */ #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index ddd5fc8d4fe1..301bf929acd9 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -36,7 +36,7 @@ struct revo51_spec { struct snd_i2c_device *dev; struct snd_pt2258 *pt2258; -} revo51; +}; static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) { From b4818494edddfe382de4f5d072cb527b60315a46 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Sat, 23 Feb 2008 11:34:12 +0100 Subject: [PATCH 852/880] [ALSA] hda-codec - Adapt eeepc p701 mixer for virtual master control Fix the line-out volume control of eeepc p701 to be a proper slave of the virtual master control. Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 51871c684571..33282f9c01c7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12995,8 +12995,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), From 0d9ac27afa469dbb20940ad7f25502785af1cbe3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 27 Feb 2008 16:40:18 +0100 Subject: [PATCH 853/880] [ALSA] intel8x0 - Add quirk for Compaq Deskpro EN Added the ac97_quirk hp_only for Compaq Deskpro EN. Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index c5ef12ae3c55..c52abd0bf22e 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1708,6 +1708,12 @@ static struct ac97_pcm ac97_pcm_defs[] __devinitdata = { }; static struct ac97_quirk ac97_quirks[] __devinitdata = { + { + .subvendor = 0x0e11, + .subdevice = 0x000e, + .name = "Compaq Deskpro EN", /* AD1885 */ + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x0e11, .subdevice = 0x008a, From b59931649256685f294d2d163a4f6d6286fbff05 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 26 Feb 2008 13:20:58 -0800 Subject: [PATCH 854/880] elfcore-compat fix uid/gid types I overlooked the difference between __kernel_uid_t and uid_t when defining struct compat_elf_prpsinfo. The result is a regression in 32-bit core dumps on x86_64, where the NT_PRPSINFO note has the wrong size and layout. This patch fixes it. Signed-off-by: Roland McGrath Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds --- include/linux/elfcore-compat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/elfcore-compat.h b/include/linux/elfcore-compat.h index 532d13adabc4..0a90e1c3a422 100644 --- a/include/linux/elfcore-compat.h +++ b/include/linux/elfcore-compat.h @@ -45,8 +45,8 @@ struct compat_elf_prpsinfo char pr_zomb; char pr_nice; compat_ulong_t pr_flag; - compat_uid_t pr_uid; - compat_gid_t pr_gid; + __compat_uid_t pr_uid; + __compat_gid_t pr_gid; compat_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; char pr_fname[16]; char pr_psargs[ELF_PRARGSZ]; From 32fa458688fa2e68bc433929b2d4941eef7efe39 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 28 Feb 2008 13:29:43 +0000 Subject: [PATCH 855/880] Fix hpet_(un)register_irq_handler() for emulation Fix hpet_(un)register_irq_handler() for when CONFIG_HPET_EMULATE_RTC=n. They are provided macros that substitute value 0, but if they are called as functions and the return value isn't checked, the following warnings appear: drivers/char/rtc.c: In function `rtc_init': drivers/char/rtc.c:1063: warning: statement with no effect drivers/char/rtc.c: In function `rtc_exit': drivers/char/rtc.c:1157: warning: statement with no effect Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- drivers/char/rtc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 78b151c4d20f..5c3142b6f1fc 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -110,8 +110,8 @@ static int rtc_has_irq = 1; #define hpet_set_rtc_irq_bit(arg) 0 #define hpet_rtc_timer_init() do { } while (0) #define hpet_rtc_dropped_irq() 0 -#define hpet_register_irq_handler(h) 0 -#define hpet_unregister_irq_handler(h) 0 +#define hpet_register_irq_handler(h) ({ 0; }) +#define hpet_unregister_irq_handler(h) ({ 0; }) #ifdef RTC_IRQ static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) { From 57ce36feb4d1281247755bc445bae77728298955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 25 Feb 2008 16:45:03 +0100 Subject: [PATCH 856/880] let __dec_zone_page_state use __dec_zone_state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes code duplication and makes __dec_zone_page_state look like __inc_zone_page_state. Signed-off-by: Uwe Kleine-König Acked-by: Christoph Lameter Signed-off-by: Linus Torvalds --- include/linux/vmstat.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 75370ec0923e..9f1b4b46151e 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -246,8 +246,7 @@ static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) static inline void __dec_zone_page_state(struct page *page, enum zone_stat_item item) { - atomic_long_dec(&page_zone(page)->vm_stat[item]); - atomic_long_dec(&vm_stat[item]); + __dec_zone_state(page_zone(page), item); } /* From 2232c2d8e0a6a31061dec311f3d1cf7624bc14f1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 29 Feb 2008 18:46:50 +0100 Subject: [PATCH 857/880] rcu: add support for dynamic ticks and preempt rcu The PREEMPT-RCU can get stuck if a CPU goes idle and NO_HZ is set. The idle CPU will not progress the RCU through its grace period and a synchronize_rcu my get stuck. Without this patch I have a box that will not boot when PREEMPT_RCU and NO_HZ are set. That same box boots fine with this patch. This patch comes from the -rt kernel where it has been tested for several months. Signed-off-by: Steven Rostedt Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/hardirq.h | 10 ++ include/linux/rcuclassic.h | 3 + include/linux/rcupreempt.h | 22 ++++ kernel/rcupreempt.c | 224 ++++++++++++++++++++++++++++++++++++- kernel/softirq.c | 1 + kernel/time/tick-sched.c | 3 + 6 files changed, 259 insertions(+), 4 deletions(-) diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 2961ec788046..49829988bfa0 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -109,6 +109,14 @@ static inline void account_system_vtime(struct task_struct *tsk) } #endif +#if defined(CONFIG_PREEMPT_RCU) && defined(CONFIG_NO_HZ) +extern void rcu_irq_enter(void); +extern void rcu_irq_exit(void); +#else +# define rcu_irq_enter() do { } while (0) +# define rcu_irq_exit() do { } while (0) +#endif /* CONFIG_PREEMPT_RCU */ + /* * It is safe to do non-atomic ops on ->hardirq_context, * because NMI handlers may not preempt and the ops are @@ -117,6 +125,7 @@ static inline void account_system_vtime(struct task_struct *tsk) */ #define __irq_enter() \ do { \ + rcu_irq_enter(); \ account_system_vtime(current); \ add_preempt_count(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ @@ -135,6 +144,7 @@ extern void irq_enter(void); trace_hardirq_exit(); \ account_system_vtime(current); \ sub_preempt_count(HARDIRQ_OFFSET); \ + rcu_irq_exit(); \ } while (0) /* diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 4d6624260b4c..b3dccd68629e 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -160,5 +160,8 @@ extern void rcu_restart_cpu(int cpu); extern long rcu_batches_completed(void); extern long rcu_batches_completed_bh(void); +#define rcu_enter_nohz() do { } while (0) +#define rcu_exit_nohz() do { } while (0) + #endif /* __KERNEL__ */ #endif /* __LINUX_RCUCLASSIC_H */ diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 60c2a033b19e..01152ed532c8 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h @@ -82,5 +82,27 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); struct softirq_action; +#ifdef CONFIG_NO_HZ +DECLARE_PER_CPU(long, dynticks_progress_counter); + +static inline void rcu_enter_nohz(void) +{ + __get_cpu_var(dynticks_progress_counter)++; + WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1); + mb(); +} + +static inline void rcu_exit_nohz(void) +{ + mb(); + __get_cpu_var(dynticks_progress_counter)++; + WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1)); +} + +#else /* CONFIG_NO_HZ */ +#define rcu_enter_nohz() do { } while (0) +#define rcu_exit_nohz() do { } while (0) +#endif /* CONFIG_NO_HZ */ + #endif /* __KERNEL__ */ #endif /* __LINUX_RCUPREEMPT_H */ diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 987cfb7ade89..c7c52096df48 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -23,6 +23,10 @@ * to Suparna Bhattacharya for pushing me completely away * from atomic instructions on the read side. * + * - Added handling of Dynamic Ticks + * Copyright 2007 - Paul E. Mckenney + * - Steven Rostedt + * * Papers: http://www.rdrop.com/users/paulmck/RCU * * Design Document: http://lwn.net/Articles/253651/ @@ -409,6 +413,212 @@ static void __rcu_advance_callbacks(struct rcu_data *rdp) } } +#ifdef CONFIG_NO_HZ + +DEFINE_PER_CPU(long, dynticks_progress_counter) = 1; +static DEFINE_PER_CPU(long, rcu_dyntick_snapshot); +static DEFINE_PER_CPU(int, rcu_update_flag); + +/** + * rcu_irq_enter - Called from Hard irq handlers and NMI/SMI. + * + * If the CPU was idle with dynamic ticks active, this updates the + * dynticks_progress_counter to let the RCU handling know that the + * CPU is active. + */ +void rcu_irq_enter(void) +{ + int cpu = smp_processor_id(); + + if (per_cpu(rcu_update_flag, cpu)) + per_cpu(rcu_update_flag, cpu)++; + + /* + * Only update if we are coming from a stopped ticks mode + * (dynticks_progress_counter is even). + */ + if (!in_interrupt() && + (per_cpu(dynticks_progress_counter, cpu) & 0x1) == 0) { + /* + * The following might seem like we could have a race + * with NMI/SMIs. But this really isn't a problem. + * Here we do a read/modify/write, and the race happens + * when an NMI/SMI comes in after the read and before + * the write. But NMI/SMIs will increment this counter + * twice before returning, so the zero bit will not + * be corrupted by the NMI/SMI which is the most important + * part. + * + * The only thing is that we would bring back the counter + * to a postion that it was in during the NMI/SMI. + * But the zero bit would be set, so the rest of the + * counter would again be ignored. + * + * On return from the IRQ, the counter may have the zero + * bit be 0 and the counter the same as the return from + * the NMI/SMI. If the state machine was so unlucky to + * see that, it still doesn't matter, since all + * RCU read-side critical sections on this CPU would + * have already completed. + */ + per_cpu(dynticks_progress_counter, cpu)++; + /* + * The following memory barrier ensures that any + * rcu_read_lock() primitives in the irq handler + * are seen by other CPUs to follow the above + * increment to dynticks_progress_counter. This is + * required in order for other CPUs to correctly + * determine when it is safe to advance the RCU + * grace-period state machine. + */ + smp_mb(); /* see above block comment. */ + /* + * Since we can't determine the dynamic tick mode from + * the dynticks_progress_counter after this routine, + * we use a second flag to acknowledge that we came + * from an idle state with ticks stopped. + */ + per_cpu(rcu_update_flag, cpu)++; + /* + * If we take an NMI/SMI now, they will also increment + * the rcu_update_flag, and will not update the + * dynticks_progress_counter on exit. That is for + * this IRQ to do. + */ + } +} + +/** + * rcu_irq_exit - Called from exiting Hard irq context. + * + * If the CPU was idle with dynamic ticks active, update the + * dynticks_progress_counter to put let the RCU handling be + * aware that the CPU is going back to idle with no ticks. + */ +void rcu_irq_exit(void) +{ + int cpu = smp_processor_id(); + + /* + * rcu_update_flag is set if we interrupted the CPU + * when it was idle with ticks stopped. + * Once this occurs, we keep track of interrupt nesting + * because a NMI/SMI could also come in, and we still + * only want the IRQ that started the increment of the + * dynticks_progress_counter to be the one that modifies + * it on exit. + */ + if (per_cpu(rcu_update_flag, cpu)) { + if (--per_cpu(rcu_update_flag, cpu)) + return; + + /* This must match the interrupt nesting */ + WARN_ON(in_interrupt()); + + /* + * If an NMI/SMI happens now we are still + * protected by the dynticks_progress_counter being odd. + */ + + /* + * The following memory barrier ensures that any + * rcu_read_unlock() primitives in the irq handler + * are seen by other CPUs to preceed the following + * increment to dynticks_progress_counter. This + * is required in order for other CPUs to determine + * when it is safe to advance the RCU grace-period + * state machine. + */ + smp_mb(); /* see above block comment. */ + per_cpu(dynticks_progress_counter, cpu)++; + WARN_ON(per_cpu(dynticks_progress_counter, cpu) & 0x1); + } +} + +static void dyntick_save_progress_counter(int cpu) +{ + per_cpu(rcu_dyntick_snapshot, cpu) = + per_cpu(dynticks_progress_counter, cpu); +} + +static inline int +rcu_try_flip_waitack_needed(int cpu) +{ + long curr; + long snap; + + curr = per_cpu(dynticks_progress_counter, cpu); + snap = per_cpu(rcu_dyntick_snapshot, cpu); + smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ + + /* + * If the CPU remained in dynticks mode for the entire time + * and didn't take any interrupts, NMIs, SMIs, or whatever, + * then it cannot be in the middle of an rcu_read_lock(), so + * the next rcu_read_lock() it executes must use the new value + * of the counter. So we can safely pretend that this CPU + * already acknowledged the counter. + */ + + if ((curr == snap) && ((curr & 0x1) == 0)) + return 0; + + /* + * If the CPU passed through or entered a dynticks idle phase with + * no active irq handlers, then, as above, we can safely pretend + * that this CPU already acknowledged the counter. + */ + + if ((curr - snap) > 2 || (snap & 0x1) == 0) + return 0; + + /* We need this CPU to explicitly acknowledge the counter flip. */ + + return 1; +} + +static inline int +rcu_try_flip_waitmb_needed(int cpu) +{ + long curr; + long snap; + + curr = per_cpu(dynticks_progress_counter, cpu); + snap = per_cpu(rcu_dyntick_snapshot, cpu); + smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ + + /* + * If the CPU remained in dynticks mode for the entire time + * and didn't take any interrupts, NMIs, SMIs, or whatever, + * then it cannot have executed an RCU read-side critical section + * during that time, so there is no need for it to execute a + * memory barrier. + */ + + if ((curr == snap) && ((curr & 0x1) == 0)) + return 0; + + /* + * If the CPU either entered or exited an outermost interrupt, + * SMI, NMI, or whatever handler, then we know that it executed + * a memory barrier when doing so. So we don't need another one. + */ + if (curr != snap) + return 0; + + /* We need the CPU to execute a memory barrier. */ + + return 1; +} + +#else /* !CONFIG_NO_HZ */ + +# define dyntick_save_progress_counter(cpu) do { } while (0) +# define rcu_try_flip_waitack_needed(cpu) (1) +# define rcu_try_flip_waitmb_needed(cpu) (1) + +#endif /* CONFIG_NO_HZ */ + /* * Get here when RCU is idle. Decide whether we need to * move out of idle state, and return non-zero if so. @@ -447,8 +657,10 @@ rcu_try_flip_idle(void) /* Now ask each CPU for acknowledgement of the flip. */ - for_each_cpu_mask(cpu, rcu_cpu_online_map) + for_each_cpu_mask(cpu, rcu_cpu_online_map) { per_cpu(rcu_flip_flag, cpu) = rcu_flipped; + dyntick_save_progress_counter(cpu); + } return 1; } @@ -464,7 +676,8 @@ rcu_try_flip_waitack(void) RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); for_each_cpu_mask(cpu, rcu_cpu_online_map) - if (per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { + if (rcu_try_flip_waitack_needed(cpu) && + per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); return 0; } @@ -509,8 +722,10 @@ rcu_try_flip_waitzero(void) smp_mb(); /* ^^^^^^^^^^^^ */ /* Call for a memory barrier from each CPU. */ - for_each_cpu_mask(cpu, rcu_cpu_online_map) + for_each_cpu_mask(cpu, rcu_cpu_online_map) { per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; + dyntick_save_progress_counter(cpu); + } RCU_TRACE_ME(rcupreempt_trace_try_flip_z2); return 1; @@ -528,7 +743,8 @@ rcu_try_flip_waitmb(void) RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); for_each_cpu_mask(cpu, rcu_cpu_online_map) - if (per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { + if (rcu_try_flip_waitmb_needed(cpu) && + per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); return 0; } diff --git a/kernel/softirq.c b/kernel/softirq.c index 5b3aea5f471e..31e9f2a47928 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -313,6 +313,7 @@ void irq_exit(void) /* Make sure that timer wheel updates are propagated */ if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched()) tick_nohz_stop_sched_tick(); + rcu_irq_exit(); #endif preempt_enable_no_resched(); } diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index fa9bb73dbdb4..2968298f8f36 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -282,6 +282,7 @@ void tick_nohz_stop_sched_tick(void) ts->idle_tick = ts->sched_timer.expires; ts->tick_stopped = 1; ts->idle_jiffies = last_jiffies; + rcu_enter_nohz(); } /* @@ -375,6 +376,8 @@ void tick_nohz_restart_sched_tick(void) return; } + rcu_exit_nohz(); + /* Update jiffies first */ select_nohz_load_balancer(0); now = ktime_get(); From 7be2a03e3174cee3a3cdcdf17db357470f51caff Mon Sep 17 00:00:00 2001 From: Dmitry Adamushko Date: Fri, 8 Feb 2008 15:41:13 +0100 Subject: [PATCH 858/880] softlockup: fix task state setting kthread_stop() can be called when a 'watchdog' thread is executing after kthread_should_stop() but before set_task_state(TASK_INTERRUPTIBLE). Signed-off-by: Dmitry Adamushko Signed-off-by: Ingo Molnar --- kernel/softlockup.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 7c2da88db4ed..01b6522fd92b 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -216,26 +216,27 @@ static int watchdog(void *__bind_cpu) /* initialize timestamp */ touch_softlockup_watchdog(); + set_current_state(TASK_INTERRUPTIBLE); /* * Run briefly once per second to reset the softlockup timestamp. * If this gets delayed for more than 60 seconds then the * debug-printout triggers in softlockup_tick(). */ while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); touch_softlockup_watchdog(); schedule(); if (kthread_should_stop()) break; - if (this_cpu != check_cpu) - continue; - - if (sysctl_hung_task_timeout_secs) - check_hung_uninterruptible_tasks(this_cpu); + if (this_cpu == check_cpu) { + if (sysctl_hung_task_timeout_secs) + check_hung_uninterruptible_tasks(this_cpu); + } + set_current_state(TASK_INTERRUPTIBLE); } + __set_current_state(TASK_RUNNING); return 0; } From 3d00daf44654dc75629caf42816ac4e293658724 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 26 Feb 2008 13:00:18 -0800 Subject: [PATCH 859/880] x86: tls prevent_tail_call Fix a kernel bug (vmware boot problem) reported by Tomasz Grobelny, which occurs with certain .config variants and gccs. The x86 TLS cleanup in commit efd1ca52d04d2f6df337a3332cee56cd60e6d4c4 made the sys_set_thread_area and sys_get_thread_area functions ripe for tail call optimization. If the compiler chooses to use it for them, it can clobber the user trap frame because these are asmlinkage functions. Reported-by: Tomasz Grobelny Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar --- arch/x86/kernel/tls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 6dfd4e76661a..022bcaa3b42e 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -91,7 +91,9 @@ int do_set_thread_area(struct task_struct *p, int idx, asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) { - return do_set_thread_area(current, -1, u_info, 1); + int ret = do_set_thread_area(current, -1, u_info, 1); + prevent_tail_call(ret); + return ret; } @@ -139,7 +141,9 @@ int do_get_thread_area(struct task_struct *p, int idx, asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) { - return do_get_thread_area(current, -1, u_info); + int ret = do_get_thread_area(current, -1, u_info); + prevent_tail_call(ret); + return ret; } int regset_tls_active(struct task_struct *target, From cded932b75ab0a5f9181ee3da34a0a488d1a14fd Mon Sep 17 00:00:00 2001 From: Hans Rosenfeld Date: Mon, 18 Feb 2008 18:10:47 +0100 Subject: [PATCH 860/880] x86: fix pmd_bad and pud_bad to support huge pages I recently stumbled upon a problem in the support for huge pages. If a program using huge pages does not explicitly unmap them, they remain mapped (and therefore, are lost) after the program exits. I observed that the free huge page count in /proc/meminfo decreased when running my program, and it did not increase after the program exited. After running the program a few times, no more huge pages could be allocated. The reason for this seems to be that the x86 pmd_bad and pud_bad consider pmd/pud entries having the PSE bit set invalid. I think there is nothing wrong with this bit being set, it just indicates that the lowest level of translation has been reached. This bit has to be (and is) checked after the basic validity of the entry has been checked, like in this fragment from follow_page() in mm/memory.c: if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) goto no_page_table; if (pmd_huge(*pmd)) { BUG_ON(flags & FOLL_GET); page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE); goto out; } Note that this code currently doesn't work as intended if the pmd refers to a huge page, the pmd_huge() check can not be reached if the page is huge. Extending pmd_bad() (and, for future 1GB page support, pud_bad()) to allow for the PSE bit being set fixes this. For similar reasons, allowing the NX bit being set is necessary, too. I have seen huge pages having the NX bit set in their pmd entry, which would cause the same problem. Signed-Off-By: Hans Rosenfeld Signed-off-by: Ingo Molnar --- include/asm-x86/pgtable_32.h | 4 +++- include/asm-x86/pgtable_64.h | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index a842c7222b1e..b478efa971e0 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -91,7 +91,9 @@ extern unsigned long pg0[]; /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ #define pmd_none(x) (!(unsigned long)pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) +#define pmd_bad(x) ((pmd_val(x) \ + & ~(PAGE_MASK | _PAGE_USER | _PAGE_PSE | _PAGE_NX)) \ + != _KERNPG_TABLE) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index 0a0b77bc736a..0a9258333cbd 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h @@ -153,12 +153,14 @@ static inline unsigned long pgd_bad(pgd_t pgd) static inline unsigned long pud_bad(pud_t pud) { - return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); + return pud_val(pud) & + ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); } static inline unsigned long pmd_bad(pmd_t pmd) { - return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); + return pmd_val(pmd) & + ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); } #define pte_none(x) (!pte_val(x)) From d67bbacb4b557ece3b41abdcb616354ac0ce00e1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 27 Feb 2008 09:39:52 +0100 Subject: [PATCH 861/880] x86: restore vsyscall64 prochandler a recent fix: commit ce28b9864b853803320c3f1d8de1b81aa4120b14 Author: Thomas Gleixner Date: Wed Feb 20 23:57:30 2008 +0100 x86: fix vsyscall wreckage removed the broken /kernel/vsyscall64 handler completely. This triggers the following debug check: sysctl table check failed: /kernel/vsyscall64 No proc_handler Restore the sane part of the proc handler. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/kernel/vsyscall_64.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index b6be812fac05..edff4c985485 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -222,10 +222,19 @@ long __vsyscall(3) venosys_1(void) } #ifdef CONFIG_SYSCTL + +static int +vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return proc_dointvec(ctl, write, filp, buffer, lenp, ppos); +} + static ctl_table kernel_table2[] = { { .procname = "vsyscall64", .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), - .mode = 0644 }, + .mode = 0644, + .proc_handler = vsyscall_sysctl_change }, {} }; From f2dbe03dccc95f41429d60e4221b02fc0f112cc4 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 27 Feb 2008 11:42:15 -0800 Subject: [PATCH 862/880] x86 vdso: fix build locale dependency Priit Laes discovered that the sed command processing nm output was sensitive to locale settings. This was addressed in commit 03994f01e8b72b3d01fd3d09d1cc7c9f421a727c by using [:alnum:] in place of [a-zA-Z0-9]. But that solution too is locale-dependent and may not always match the identifiers it needs to. The better fix is just to run sed et al with a fixed locale setting in all builds. Signed-off-by: Roland McGrath CC: Priit Laes Signed-off-by: Ingo Molnar --- arch/x86/vdso/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index b8bd0c4aa02e..0a8f4742ef51 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -48,9 +48,11 @@ obj-$(VDSO64-y) += vdso-syms.lds # Match symbols in the DSO that look like VDSO*; produce a file of constants. # sed-vdsosym := -e 's/^00*/0/' \ - -e 's/^\([[:xdigit:]]*\) . \(VDSO[[:alnum:]_]*\)$$/\2 = 0x\1;/p' + -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' quiet_cmd_vdsosym = VDSOSYM $@ - cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +define cmd_vdsosym + $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +endef $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE $(call if_changed,vdsosym) From b16bf712f491808a8c926dd481c696fe7d73ee5a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 28 Feb 2008 14:02:08 +0100 Subject: [PATCH 863/880] x86: fix leak un ioremap_page_range() failure Jan Beulich noticed it during code review that if a driver's ioremap() fails (say due to -ENOMEM) then we might leak the struct vm_area. Free it properly. Signed-off-by: Ingo Molnar --- arch/x86/mm/ioremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 882328efc3db..ac3c959e271d 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -162,7 +162,7 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, area->phys_addr = phys_addr; vaddr = (unsigned long) area->addr; if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) { - remove_vm_area((void *)(vaddr & PAGE_MASK)); + free_vm_area(area); return NULL; } From 757265b8c57bb8fd91785d3d1a87fb483c86c9c2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 28 Feb 2008 20:19:06 +0100 Subject: [PATCH 864/880] x86: delay the export removal of init_mm delay the removal of this symbol export by one more kernel release, giving external modules such as VirtualBox a chance to stop using it. Signed-off-by: Ingo Molnar --- Documentation/feature-removal-schedule.txt | 12 ++++++++++++ arch/x86/kernel/init_task.c | 1 + 2 files changed, 13 insertions(+) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index ba899ff2a8f9..c1d1fd0c299b 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -316,3 +316,15 @@ Why: Largely unmaintained and almost entirely unused. File system is largely pointless as without a lot of work only the most trivial of Solaris binaries can work with the emulation code. Who: David S. Miller + +--------------------------- + +What: init_mm export +When: 2.6.26 +Why: Not used in-tree. The current out-of-tree users used it to + work around problems in the CPA code which should be resolved + by now. One usecase was described to provide verification code + of the CPA operation. That's a good idea in general, but such + code / infrastructure should be in the kernel and not in some + out-of-tree driver. +Who: Thomas Gleixner diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index 5b3ce7934363..3d01e47777db 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c @@ -15,6 +15,7 @@ static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); +EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */ /* * Initial thread structure. From 8be8f54bae3453588011cad06363813a5293af53 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 23 Feb 2008 20:43:21 +0100 Subject: [PATCH 865/880] x86: CPA: avoid split of alias mappings avoid over-eager large page splitup. When the target area needs to be split or is split already (ioremap) then the current code enforces the split of large mappings in the alias regions even if we could avoid it. Use a separate variable processed in the cpa_data structure to carry the number of pages which have been processed instead of reusing the numpages variable. This keeps numpages intact and gives the alias code a chance to keep large mappings intact. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 14e48b5a94ba..7049294fb469 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -26,6 +26,7 @@ struct cpa_data { pgprot_t mask_set; pgprot_t mask_clr; int numpages; + int processed; int flushtlb; unsigned long pfn; }; @@ -290,8 +291,8 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, */ nextpage_addr = (address + psize) & pmask; numpages = (nextpage_addr - address) >> PAGE_SHIFT; - if (numpages < cpa->numpages) - cpa->numpages = numpages; + if (numpages < cpa->processed) + cpa->processed = numpages; /* * We are safe now. Check whether the new pgprot is the same: @@ -318,7 +319,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, */ addr = address + PAGE_SIZE; pfn++; - for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE, pfn++) { + for (i = 1; i < cpa->processed; i++, addr += PAGE_SIZE, pfn++) { pgprot_t chk_prot = static_protections(new_prot, addr, pfn); if (pgprot_val(chk_prot) != pgprot_val(new_prot)) @@ -342,7 +343,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, * that we limited the number of possible pages already to * the number of pages in the large page. */ - if (address == (nextpage_addr - psize) && cpa->numpages == numpages) { + if (address == (nextpage_addr - psize) && cpa->processed == numpages) { /* * The address is aligned and the number of pages * covers the full page. @@ -572,7 +573,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) set_pte_atomic(kpte, new_pte); cpa->flushtlb = 1; } - cpa->numpages = 1; + cpa->processed = 1; return 0; } @@ -583,7 +584,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) do_split = try_preserve_large_page(kpte, address, cpa); /* * When the range fits into the existing large page, - * return. cp->numpages and cpa->tlbflush have been updated in + * return. cp->processed and cpa->tlbflush have been updated in * try_large_page: */ if (do_split <= 0) @@ -662,7 +663,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) * Store the remaining nr of pages for the large page * preservation check. */ - cpa->numpages = numpages; + cpa->numpages = cpa->processed = numpages; ret = __change_page_attr(cpa, checkalias); if (ret) @@ -679,9 +680,9 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) * CPA operation. Either a large page has been * preserved or a single page update happened. */ - BUG_ON(cpa->numpages > numpages); - numpages -= cpa->numpages; - cpa->vaddr += cpa->numpages * PAGE_SIZE; + BUG_ON(cpa->processed > numpages); + numpages -= cpa->processed; + cpa->vaddr += cpa->processed * PAGE_SIZE; } return 0; } From b4ef95de00be4c2c30feccf607a45093c8c118b7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 26 Feb 2008 09:40:27 +0100 Subject: [PATCH 866/880] x86: disable BTS ptrace extensions for now revert the BTS ptrace extension for now. based on general objections from Roland McGrath: http://lkml.org/lkml/2008/2/21/323 we'll let the BTS functionality cook some more and re-enable it in v2.6.26. We'll leave the dead code around to help the development of this code. (X86_BTS is not defined at the moment) Signed-off-by: Ingo Molnar --- arch/x86/kernel/process_32.c | 2 ++ arch/x86/kernel/process_64.c | 2 ++ arch/x86/kernel/ptrace.c | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index a7d50a547dc2..be3c7a299f02 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -603,11 +603,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, } #endif +#ifdef X86_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); +#endif if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 43f287744f9f..3baf9b9f4c87 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -604,11 +604,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); } +#ifdef X86_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); +#endif } /* diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index d862e396b099..f41fdc98efb1 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -544,6 +544,8 @@ static int ptrace_set_debugreg(struct task_struct *child, return 0; } +#ifdef X86_BTS + static int ptrace_bts_get_size(struct task_struct *child) { if (!child->thread.ds_area_msr) @@ -826,6 +828,7 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk, ptrace_bts_write_record(tsk, &rec); } +#endif /* X86_BTS */ /* * Called by kernel/ptrace.c when detaching.. @@ -839,7 +842,9 @@ void ptrace_disable(struct task_struct *child) clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); #endif if (child->thread.ds_area_msr) { +#ifdef X86_BTS ptrace_bts_realloc(child, 0, 0); +#endif child->thread.debugctlmsr &= ~ds_debugctl_mask(); if (!child->thread.debugctlmsr) clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); @@ -961,6 +966,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; #endif + /* + * These bits need more cooking - not enabled yet: + */ +#ifdef X86_BTS case PTRACE_BTS_CONFIG: ret = ptrace_bts_config (child, data, (struct ptrace_bts_config __user *)addr); @@ -988,6 +997,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = ptrace_bts_drain (child, data, (struct bts_struct __user *) addr); break; +#endif default: ret = ptrace_request(child, request, addr, data); @@ -1226,12 +1236,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_SETOPTIONS: case PTRACE_SET_THREAD_AREA: case PTRACE_GET_THREAD_AREA: +#ifdef X86_BTS case PTRACE_BTS_CONFIG: case PTRACE_BTS_STATUS: case PTRACE_BTS_SIZE: case PTRACE_BTS_GET: case PTRACE_BTS_CLEAR: case PTRACE_BTS_DRAIN: +#endif return sys_ptrace(request, pid, addr, data); default: From 53c58588107973c0e240a1ed4fb8295f274c409d Mon Sep 17 00:00:00 2001 From: Dave Anderson Date: Thu, 21 Feb 2008 11:45:38 -0500 Subject: [PATCH 867/880] x86 ptrace: fix ptrace_bts_config structure declaration The 2.6.25 ptrace_bts_config structure in asm-x86/ptrace-abi.h is defined with u32 types: #include /* configuration/status structure used in PTRACE_BTS_CONFIG and PTRACE_BTS_STATUS commands. */ struct ptrace_bts_config { /* requested or actual size of BTS buffer in bytes */ u32 size; /* bitmask of below flags */ u32 flags; /* buffer overflow signal */ u32 signal; /* actual size of bts_struct in bytes */ u32 bts_size; }; #endif But u32 is only accessible in asm-x86/types.h if __KERNEL__, leading to compile errors when ptrace.h is included from user-space. The double-underscore versions that are exported to user-space in asm-x86/types.h should be used instead. Signed-off-by: Dave Anderson Signed-off-by: Ingo Molnar --- include/asm-x86/ptrace-abi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 81a8ee4c55fc..f224eb3c3157 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -89,13 +89,13 @@ */ struct ptrace_bts_config { /* requested or actual size of BTS buffer in bytes */ - u32 size; + __u32 size; /* bitmask of below flags */ - u32 flags; + __u32 flags; /* buffer overflow signal */ - u32 signal; + __u32 signal; /* actual size of bts_struct in bytes */ - u32 bts_size; + __u32 bts_size; }; #endif From d40e705903397445c6861a0a56c23e5b2e8f9b9a Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 29 Feb 2008 18:55:43 +0100 Subject: [PATCH 868/880] xen: mask out SEP from CPUID Fix 32-on-64 pvops kernel: we don't want userspace using syscall/sysenter, even if the hypervisor supports it, so mask it out from CPUID. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/x86/xen/enlighten.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 49e5358f481a..8b9ee27805fd 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -153,6 +153,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, if (*ax == 1) maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ (1 << X86_FEATURE_ACPI) | /* disable ACPI */ + (1 << X86_FEATURE_SEP) | /* disable SEP */ (1 << X86_FEATURE_ACC)); /* thermal monitoring */ asm(XEN_EMULATE_PREFIX "cpuid" From ae778869ae4549628b9e83efe958c3aaa63ed1b9 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 27 Feb 2008 16:21:10 -0800 Subject: [PATCH 869/880] rcupreempt: fix hibernate/resume in presence of PREEMPT_RCU and hotplug This fixes a oops encountered when doing hibernate/resume in presence of PREEMPT_RCU. The problem was that the code failed to disable preemption when accessing a per-CPU variable. This is OK when called from code that already has preemption disabled, but such is not the case from the suspend/resume code path. Reported-by: Dave Young Tested-by: Dave Young Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- kernel/rcupreempt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index c7c52096df48..845abcd472b0 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -918,8 +918,9 @@ void rcu_offline_cpu(int cpu) * fix. */ + local_irq_save(flags); rdp = RCU_DATA_ME(); - spin_lock_irqsave(&rdp->lock, flags); + spin_lock(&rdp->lock); *rdp->nexttail = list; if (list) rdp->nexttail = tail; From c9e71002aacc9821e99531dcc130db88bbc8ad05 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 28 Feb 2008 11:51:07 -0800 Subject: [PATCH 870/880] rcupreempt: remove never-migrates assumption from rcu_process_callbacks() This patch fixes a potentially invalid access to a per-CPU variable in rcu_process_callbacks(). This per-CPU access needs to be done in such a way as to guarantee that the code using it cannot move to some other CPU before all uses of the value accessed have completed. Even though this code is currently only invoked from softirq context, which currrently cannot migrate to some other CPU, life would be better if this code did not silently make such an assumption. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- kernel/rcupreempt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 845abcd472b0..e9517014b57c 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -952,9 +952,11 @@ static void rcu_process_callbacks(struct softirq_action *unused) { unsigned long flags; struct rcu_head *next, *list; - struct rcu_data *rdp = RCU_DATA_ME(); + struct rcu_data *rdp; - spin_lock_irqsave(&rdp->lock, flags); + local_irq_save(flags); + rdp = RCU_DATA_ME(); + spin_lock(&rdp->lock); list = rdp->donelist; if (list == NULL) { spin_unlock_irqrestore(&rdp->lock, flags); From b98d7291883f7ed27e3f4b59bc12dc963c9f72a6 Mon Sep 17 00:00:00 2001 From: Uli Luckas Date: Fri, 22 Feb 2008 16:45:18 +0100 Subject: [PATCH 871/880] [ARM] 4836/1: Make ATAGS_PROC depend on KEXEC On Wed, Feb 20, 2008 at 11:50:33AM +0100, Guennadi Liakhovetski wrote: > arch/arm/kernel/atags.c uses for some reason the > KEXEC_BOOT_PARAMS_SIZE macro, which is only defined if CONFIG_KEXEC > is set. So, either this macro should be defined always, or another > macro should be used, or ATAGS_PROC should depend on KEXEC. As the procfs export of ATAGS is not meant as a stable, general purpose ABI it shouldn't be an independent, general configuration option. This patch make ATAGS_PROC depend on KEXEC Signed-off-by: Uli Luckas Signed-off-by: Russell King --- arch/arm/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9619c43783ff..16b82e1272b0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -939,7 +939,8 @@ config KEXEC config ATAGS_PROC bool "Export atags in procfs" - default n + depends on KEXEC + default y help Should the atags used to boot the kernel be exported in an "atags" file in procfs. Useful with kexec. From 94a3f78566ef98a48814d82892f28bb741624cb8 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 23 Feb 2008 00:23:48 +0100 Subject: [PATCH 872/880] [ARM] 4837/1: make __get_unaligned_*() return unsigned types Eric Sandeen tracked an XFS on ARM corruption bug down to a function under fs/xfs/ involving some get_unaligned() calls on u64 pointers. As it turns out, calling ARM's get_unaligned() on a u64 pointer pointing to the following byte sequence: 80 81 82 83 84 85 86 87 would return ffffffff83828180 (LE mode.) This turns out to be because of implicit u8 -> int promotion in ARM's implementation of various helpers for get_unaligned(), causing them to accidentally return signed instead of unsigned values, which in turn caused the subsequent casts to unsigned long long in __get_unaligned_8_[bl]e() to sign-extend the lower words. Fix by casting the return values of __get_unaligned_[24]_[bl]e() to unsigned int. Cc: Eric Sandeen Cc: Rabeeh Khoury Cc: Nicolas Pitre Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- include/asm-arm/unaligned.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h index 8431f6eed5c6..5db03cf3b905 100644 --- a/include/asm-arm/unaligned.h +++ b/include/asm-arm/unaligned.h @@ -40,16 +40,16 @@ extern int __bug_unaligned_x(const void *ptr); */ #define __get_unaligned_2_le(__p) \ - (__p[0] | __p[1] << 8) + (unsigned int)(__p[0] | __p[1] << 8) #define __get_unaligned_2_be(__p) \ - (__p[0] << 8 | __p[1]) + (unsigned int)(__p[0] << 8 | __p[1]) #define __get_unaligned_4_le(__p) \ - (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) + (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) #define __get_unaligned_4_be(__p) \ - (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) + (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) #define __get_unaligned_8_le(__p) \ ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ From 5ce94e9e8b469a17fbd3efa1b940c19b5e43449a Mon Sep 17 00:00:00 2001 From: Thomas Kunze Date: Sun, 24 Feb 2008 17:59:34 +0100 Subject: [PATCH 873/880] [ARM] 4838/1: Fix kexec for SA1100 machines This patch sets KEXEC_CONTROL_MEMORY_LIMIT to (-1)UL. As the value is compared with physical addresses TASK_SIZE makes no sense. Machines where the RAM addresses start above TASK_SIZE kexecs eats all memory and crashes the kernel without this patch. Signed-off-by: Thomas Kunze Acked-by: Richard Purdie Signed-off-by: Russell King --- include/asm-arm/kexec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h index 1ee17b6951d0..47fe34d692da 100644 --- a/include/asm-arm/kexec.h +++ b/include/asm-arm/kexec.h @@ -8,7 +8,7 @@ /* Maximum address we can reach in physical address mode */ #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) /* Maximum address we can use for the control code buffer */ -#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE +#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) #define KEXEC_CONTROL_CODE_SIZE 4096 From c710e39cbec4f3d60acd07f5356404a61bc1959a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 27 Feb 2008 12:11:16 -0800 Subject: [PATCH 874/880] [ARM] eliminate MODULE_PARM() usage Convert debug-only (and removed) MODULE_PARM() to module_param(). Compiles cleanly (with DEBUG=1). Signed-off-by: Randy Dunlap Signed-off-by: Russell King --- arch/arm/mach-pxa/cpu-pxa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c index 939a3867f77c..4b21479332ae 100644 --- a/arch/arm/mach-pxa/cpu-pxa.c +++ b/arch/arm/mach-pxa/cpu-pxa.c @@ -43,7 +43,7 @@ #ifdef DEBUG static unsigned int freq_debug; -MODULE_PARM(freq_debug, "i"); +module_param(freq_debug, uint, 0); MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); #else #define freq_debug 0 From 9ae3ae0bebb9a3a348dc233229008b126014889d Mon Sep 17 00:00:00 2001 From: Alexandre Rusev Date: Tue, 26 Feb 2008 18:42:10 +0100 Subject: [PATCH 875/880] [ARM] 4839/1: fixes kernel Oops in /dev/mem device driver for memory map with PHYS_OFF "cat /dev/mem" may cause kernel Oops for boards with PHYS_OFFSET != 0 because character device is mapped to addresses starting from zero and there is no protection against such situation. Patch just add this. Signed-off-by: Alexandre Rusev Signed-off-by: Russell King --- arch/arm/mm/mmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 2728b0e7d2bb..3f6dc40b8353 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -120,6 +120,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, */ int valid_phys_addr_range(unsigned long addr, size_t size) { + if (addr < PHYS_OFFSET) + return 0; if (addr + size > __pa(high_memory)) return 0; From a3359e21c06cb5b366fb47307b3d2fd23386a774 Mon Sep 17 00:00:00 2001 From: eric miao Date: Wed, 27 Feb 2008 01:59:28 +0100 Subject: [PATCH 876/880] [ARM] 4840/1: pxa: fix the typo in get_irqnr_and_base This typo causes the incorrect calculation of the IRQ numbers in the ICIP2 registers. Signed-off-by: eric miao Signed-off-by: Russell King --- include/asm-arm/arch-pxa/entry-macro.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-arm/arch-pxa/entry-macro.S b/include/asm-arm/arch-pxa/entry-macro.S index b7e730851461..c145bb01bc8f 100644 --- a/include/asm-arm/arch-pxa/entry-macro.S +++ b/include/asm-arm/arch-pxa/entry-macro.S @@ -35,7 +35,7 @@ 1004: mrc p6, 0, \irqstat, c6, c0, 0 @ ICIP2 mrc p6, 0, \irqnr, c7, c0, 0 @ ICMR2 - ands \irqstat, \irqstat, \irqnr + ands \irqnr, \irqstat, \irqnr beq 1003f rsb \irqstat, \irqnr, #0 and \irqstat, \irqstat, \irqnr From 7a987e82cd9175215dec6339d383d64e551c8899 Mon Sep 17 00:00:00 2001 From: eric miao Date: Wed, 27 Feb 2008 02:00:26 +0100 Subject: [PATCH 877/880] [ARM] 4841/1: pxa: fix typo in LCD platform data definition code for zylonite Signed-off-by: eric miao Signed-off-by: Russell King --- arch/arm/mach-pxa/zylonite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 7731d50dd86c..afd2cbfca0d9 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -58,7 +58,7 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES) +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) static void zylonite_backlight_power(int on) { gpio_set_value(gpio_backlight, on); From ceee4f98f73bb7a1f6ee6710b9ebffd0ecb8c0ca Mon Sep 17 00:00:00 2001 From: eric miao Date: Wed, 27 Feb 2008 02:01:11 +0100 Subject: [PATCH 878/880] [ARM] 4842/1: pxa: remove redundant IRQ saving/restoring in clk_pxa3xx_cken_* This is unnecessary since it is already protected by spin_lock_irq{save, restore} in clock.c. Signed-off-by: eric miao Signed-off-by: Russell King --- arch/arm/mach-pxa/pxa3xx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 7cd9ef8deb02..35f25fdaeba3 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -129,28 +129,20 @@ static void clk_pxa3xx_cken_enable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); - local_irq_disable(); - if (clk->cken < 32) CKENA |= mask; else CKENB |= mask; - - local_irq_enable(); } static void clk_pxa3xx_cken_disable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); - local_irq_disable(); - if (clk->cken < 32) CKENA &= ~mask; else CKENB &= ~mask; - - local_irq_enable(); } static const struct clkops clk_pxa3xx_cken_ops = { From d862ccc570c875e1454fc57ed00f5a1081985b26 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 27 Feb 2008 15:34:56 +0100 Subject: [PATCH 879/880] [ARM] 4843/1: Add GCR_CLKBPB for PXA3xx The PXA3xx AC97 controller has an additional control bit GCR_CLKBPB which must be used during cold reset. Signed-off-by: Mark Brown Acked-by: eric miao Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa-regs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index ac175b4d10cb..2357a73340d4 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -520,6 +520,9 @@ #define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ #define GCR __REG(0x4050000C) /* Global Control Register */ +#ifdef CONFIG_PXA3xx +#define GCR_CLKBPB (1 << 31) /* Internal clock enable */ +#endif #define GCR_nDMAEN (1 << 24) /* non DMA Enable */ #define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */ #define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */ From b445c56815d84b9fce40707f99811bdc354458e0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 29 Feb 2008 19:10:51 -0500 Subject: [PATCH 880/880] [libata] wrap kmap_atomic(KM_IRQ0) with local_irq_save/restore() Interrupts must be disabled if using kmap_atomic(KM_IRQ0), but that was not the case in a few code paths coming directly from ATA driver interrupt handlers (which use spin_lock rather than spin_lock_irqsave). Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0562b0a49f3b..7b1f1ee8131d 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1694,12 +1694,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, u8 *rbuf; unsigned int buflen, rc; struct scsi_cmnd *cmd = args->cmd; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &rbuf); memset(rbuf, 0, buflen); rc = actor(args, rbuf, buflen); ata_scsi_rbuf_put(cmd, rbuf); + local_irq_restore(flags); + if (rc == 0) cmd->result = SAM_STAT_GOOD; args->done(cmd); @@ -2473,6 +2478,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { u8 *buf = NULL; unsigned int buflen; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &buf); @@ -2490,6 +2498,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) } ata_scsi_rbuf_put(cmd, buf); + + local_irq_restore(flags); } cmd->result = SAM_STAT_GOOD;